From: vsr Date: Mon, 16 Feb 2009 15:30:38 +0000 (+0000) Subject: Merge from BR_V5_DEV 16Feb09 X-Git-Tag: V5_1_1a1~11 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=06cd64a37be247aaaebb00247ef7c732b350dcee;p=modules%2Fmed.git Merge from BR_V5_DEV 16Feb09 --- diff --git a/MED_version.h.in b/MED_version.h.in index 2f744d09b..3ed058e0e 100644 --- a/MED_version.h.in +++ b/MED_version.h.in @@ -1,26 +1,28 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ +// 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. +// +// 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 // // File : MED_version.h // Author : Vadim SANDLER // Module : SALOME - +// #if !defined(__MED_VERSION_H__) #define __MED_VERSION_H__ diff --git a/Makefile.am b/Makefile.am index f964a3459..a4831248a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,56 +1,78 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# -# -* Makefile *- +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +# -* Makefile *- # Author : Patrick GOLDBRONN (CEA) # Date : 28/06/2001 # $Header$ # - include $(top_srcdir)/adm_local/unix/make_common_starter.am -SUBDIRS = adm_local +if MED_ENABLE_KERNEL +if MED_ENABLE_GUI + ACLOCAL_AMFLAGS = -I adm_local/unix/config_files \ + -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files \ + -I ${GUI_ROOT_DIR}/adm_local/unix/config_files +else !MED_ENABLE_GUI + ACLOCAL_AMFLAGS = -I adm_local/unix/config_files \ + -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files +endif +else !MED_ENABLE_KERNEL +if MED_ENABLE_GUI + ACLOCAL_AMFLAGS = -I adm_local/unix/config_files \ + -I adm_local_without_kernel/unix/config_files \ + -I ${GUI_ROOT_DIR}/adm_local/unix/config_files +else !MED_ENABLE_GUI + ACLOCAL_AMFLAGS = -I adm_local/unix/config_files \ + -I adm_local_without_kernel/unix/config_files +endif +endif if MED_ENABLE_KERNEL - SUBDIRS+= idl + IDLDIR = idl endif -SUBDIRS+= src +SUBDIRS = adm_local -if MED_ENABLE_GUI - SUBDIRS+= doc +if !MED_ENABLE_KERNEL +SUBDIRS += adm_local_without_kernel endif -SUBDIRS+= resources bin -DIST_SUBDIRS= adm_local adm_local_without_kernel idl src doc resources bin +SUBDIRS += $(IDLDIR) src doc resources bin + +DIST_SUBDIRS = adm_local adm_local_without_kernel idl src doc resources bin -DISTCLEANFILES= a.out aclocal.m4 configure +DISTCLEANFILES = a.out aclocal.m4 configure -EXTRA_DIST+= build_configure clean_configure LICENCE INSTALL README +salomeinclude_DATA = MED_version.h + +EXTRA_DIST += build_configure clean_configure LICENCE INSTALL README dist-hook: - rm -rf `find . -name CVS` + rm -rf `find $(distdir) -name CVS` if MED_ENABLE_SSTREAM install-data-local: $(pkgincludedir)/SALOMEconfig.h else !MED_ENABLE_SSTREAM - install-data-local: $(pkgincludedir)/SALOMEconfig.h $(pkgincludedir)/sstream $(pkgincludedir)/MED_version.h + install-data-local: $(pkgincludedir)/SALOMEconfig.h $(pkgincludedir)/sstream endif $(pkgincludedir)/SALOMEconfig.h: ./salome_adm/unix/SALOMEconfig.h @@ -59,5 +81,5 @@ $(pkgincludedir)/SALOMEconfig.h: ./salome_adm/unix/SALOMEconfig.h $(pkgincludedir)/sstream: ./include/salome/sstream cp -f $^ $(pkgincludedir) -$(pkgincludedir)/MED_version.h: MED_version.h - cp -f $^ $(pkgincludedir) +dev_docs: + (cd doc && $(MAKE) $(AM_MAKEFLAGS) dev_docs) diff --git a/README b/README index 975c66396..28f828b51 100644 --- a/README +++ b/README @@ -1,4 +1,5 @@ -This is the Med Memory package V3.2.0 +Documentation for the MEDMEM library and related tools is given in +$(prefix)/doc/user/html/index.html I : Major evolution of the Med Memory package between V2.2.x and V3.2.x : ========================================================================= diff --git a/adm_local/Makefile.am b/adm_local/Makefile.am index 76fe0fa5f..0b7954458 100644 --- a/adm_local/Makefile.am +++ b/adm_local/Makefile.am @@ -1,22 +1,24 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# - +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# include $(top_srcdir)/adm_local/unix/make_common_starter.am -SUBDIRS= unix \ No newline at end of file +SUBDIRS = unix cmake_files diff --git a/adm_local/cmake_files/FindMED.cmake b/adm_local/cmake_files/FindMED.cmake new file mode 100644 index 000000000..6106bba9b --- /dev/null +++ b/adm_local/cmake_files/FindMED.cmake @@ -0,0 +1,32 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# + +SET(MED_CXXFLAGS -I${MED_ROOT_DIR}/include/salome) + +FIND_LIBRARY(interpkernel interpkernel ${MED_ROOT_DIR}/lib/salome) +FIND_LIBRARY(medmem medmem ${MED_ROOT_DIR}/lib/salome) +FIND_LIBRARY(med_V2_1 med_V2_1 ${MED_ROOT_DIR}/lib/salome) +FIND_LIBRARY(MEDWrapperBase MEDWrapperBase ${MED_ROOT_DIR}/lib/salome) +FIND_LIBRARY(MEDWrapper MEDWrapper ${MED_ROOT_DIR}/lib/salome) +FIND_LIBRARY(MEDWrapper_V2_1 MEDWrapper_V2_1 ${MED_ROOT_DIR}/lib/salome) +FIND_LIBRARY(MEDWrapper_V2_2 MEDWrapper_V2_2 ${MED_ROOT_DIR}/lib/salome) +FIND_LIBRARY(SalomeIDLMED SalomeIDLMED ${MED_ROOT_DIR}/lib/salome) diff --git a/adm_local/cmake_files/FindMEDFILE.cmake b/adm_local/cmake_files/FindMEDFILE.cmake new file mode 100644 index 000000000..ac6b8e457 --- /dev/null +++ b/adm_local/cmake_files/FindMEDFILE.cmake @@ -0,0 +1,10 @@ + +SET(MED2HOME $ENV{MED2HOME}) + +FIND_PATH(MED2_INCLUDE_DIR med.h ${MED2HOME}/include) +FIND_LIBRARY(MEDC_LIB medC ${MED2HOME}/lib) +FIND_LIBRARY(MED_LIB med ${MED2HOME}/lib) +FIND_LIBRARY(MEDIMPORTCXX_LIB medimportcxx ${MED2HOME}/lib) + +SET(MED2_INCLUDES ${HDF5_INCLUDES} -I${MED2_INCLUDE_DIR} -D${MACHINE}) +SET(MED2_LIBS ${MEDC_LIB} ${MED_LIB} ${MEDIMPORTCXX_LIB}) diff --git a/adm_local/cmake_files/Makefile.am b/adm_local/cmake_files/Makefile.am new file mode 100644 index 000000000..f47f7194d --- /dev/null +++ b/adm_local/cmake_files/Makefile.am @@ -0,0 +1,28 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +admlocal_cmakedir = $(admlocaldir)/cmake_files + +dist_admlocal_cmake_DATA = \ +FindMEDFILE.cmake \ +FindMED.cmake diff --git a/adm_local/unix/Makefile.am b/adm_local/unix/Makefile.am index facd4e6f4..5f6d5f753 100644 --- a/adm_local/unix/Makefile.am +++ b/adm_local/unix/Makefile.am @@ -1,22 +1,24 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# - +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# include $(top_srcdir)/adm_local/unix/make_common_starter.am SUBDIRS = config_files diff --git a/adm_local/unix/config_files/Makefile.am b/adm_local/unix/config_files/Makefile.am index d46d738d0..bf7fe9589 100644 --- a/adm_local/unix/config_files/Makefile.am +++ b/adm_local/unix/config_files/Makefile.am @@ -1,30 +1,35 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# include $(top_srcdir)/adm_local/unix/make_common_starter.am -dist_admlocalm4_DATA=\ - check_Med2.m4 \ - check_Med.m4 \ - check_metis.m4 \ - check_scotch.m4 \ - splitter.m4 \ - with_Kernel.m4 \ - ac_check_sizeof_fortran.m4 \ - med_check_sizeof_medint.m4 \ - README +dist_admlocalm4_DATA = \ + check_Med2.m4 \ + check_Med.m4 \ + check_metis.m4 \ + check_scotch.m4 \ + splitter.m4 \ + with_Kernel.m4 \ + ac_check_sizeof_fortran.m4 \ + med_check_sizeof_medint.m4 \ + check_bft.m4 \ + check_fvm.m4 \ + check_libxml.m4 diff --git a/adm_local/unix/config_files/README b/adm_local/unix/config_files/README deleted file mode 100644 index feb997b16..000000000 --- a/adm_local/unix/config_files/README +++ /dev/null @@ -1,3 +0,0 @@ -This file is only here for CVS: -CVS does not always create empty directory, and adm_local/unix/config_file -is needed by build_configure. diff --git a/adm_local/unix/config_files/ac_check_sizeof_fortran.m4 b/adm_local/unix/config_files/ac_check_sizeof_fortran.m4 index 57346a614..c72b579c2 100644 --- a/adm_local/unix/config_files/ac_check_sizeof_fortran.m4 +++ b/adm_local/unix/config_files/ac_check_sizeof_fortran.m4 @@ -1,3 +1,24 @@ +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl AC_DEFUN([AC_CHECK_SIZEOF_FORTRAN], [ AC_REQUIRE([AC_F77_WRAPPERS]) AC_CACHE_CHECK([size of Fortran [$1]], [ac_cv_sizeof_fortran_[]translit($1, [A-Z *], [a-z_p])],[ diff --git a/adm_local/unix/config_files/check_Med.m4 b/adm_local/unix/config_files/check_Med.m4 index 803d1fca6..576db978e 100644 --- a/adm_local/unix/config_files/check_Med.m4 +++ b/adm_local/unix/config_files/check_Med.m4 @@ -1,3 +1,24 @@ +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl # Check availability of Med binary distribution # # Author : Nicolas REJNERI (OPEN CASCADE, 2003) diff --git a/adm_local/unix/config_files/check_Med2.m4 b/adm_local/unix/config_files/check_Med2.m4 index 1e58bbd29..c5cc625a5 100644 --- a/adm_local/unix/config_files/check_Med2.m4 +++ b/adm_local/unix/config_files/check_Med2.m4 @@ -1,25 +1,24 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl - AC_DEFUN([CHECK_MED2],[ AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_CPP])dnl diff --git a/adm_local/unix/config_files/check_bft.m4 b/adm_local/unix/config_files/check_bft.m4 new file mode 100644 index 000000000..c1f647646 --- /dev/null +++ b/adm_local/unix/config_files/check_bft.m4 @@ -0,0 +1,109 @@ +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl +AC_DEFUN([CHECK_BFT],[ + +AC_CHECKING(for BFT Library) + +AC_LANG_SAVE +AC_LANG(C++) + +BFT_INCLUDES="" +BFT_LIBSUFFIX="" +BFT_LIBS="" + +AC_CHECKING(for BFT location) +AC_ARG_WITH(bft, + [ --with-bft=DIR root directory path to BFT library installation ], + [BFTDIR="$withval" + AC_MSG_RESULT("select $withval as path to BFT library")]) + +AC_MSG_RESULT(\$BFTDIR = ${BFTDIR}) + +CPPFLAGS_old="${CPPFLAGS}" +LIBS_old=$LIBS + +if test "x${BFTDIR}" != "x" ; then + BFT_INCLUDES="-I${BFTDIR}/include" + BFT_LIBS="-L${BFTDIR}/lib -lbft" +fi + +bft_ok=no +bft_headers_ok=no +bft_binaries_ok=no + +dnl BFT headers +AC_CHECKING(for BFT headers) +CPPFLAGS="${CPPFLAGS_old} ${BFT_INCLUDES} ${MPI_CPPFLAGS} ${MED_CPPFLAGS}" + +bft_include_dir_ok=yes +if test "x${BFTDIR}" != "x" ; then + AC_CHECK_FILE(${BFTDIR}/include/bft_mem.h, + bft_include_dir_ok=yes, + bft_include_dir_ok=no) +fi + +if test "x${bft_include_dir_ok}" = "xyes" ; then + AC_TRY_COMPILE([ #include "bft_mem.h"], + [bft_mem_init("")], + bft_headers_ok=yes, + bft_headers_ok=no) +fi + +if test "x${bft_headers_ok}" = "xno" ; then + BFT_INCLUDES="BFT_INCLUDES_NOT_DEFINED" +else + AC_MSG_RESULT(\$BFT_INCLUDES = ${BFT_INCLUDES}) +fi +AC_MSG_RESULT(for bft headers: $bft_headers_ok) + +if test "x${bft_headers_ok}" = "xyes" ; then + dnl BFT binaries + AC_CHECKING(for BFT binaries) + bft_lib_dir_ok=yes + if test "x${BFTDIR}" != "x" ; then + AC_CHECK_FILE(${BFTDIR}/lib/libbft.so, + bft_lib_dir_ok=yes, + bft_lib_dir_ok=no) + fi + +fi + +CPPFLAGS="${CPPFLAGS_old}" +LIBS="${LIBS_old}" + +if test "x${bft_headers_ok}" = "xyes" ; then + if test "x${bft_lib_dir_ok}" = "xyes" ; then + bft_ok=yes + fi +fi + +AC_MSG_RESULT(for bft: $bft_ok) + +AC_SUBST(BFT_INCLUDES) +AC_SUBST(BFT_LIBSUFFIX) +AC_SUBST(BFT_LIBS) + +AC_LANG_RESTORE + +])dnl + + diff --git a/adm_local/unix/config_files/check_fvm.m4 b/adm_local/unix/config_files/check_fvm.m4 new file mode 100644 index 000000000..e8ee969d9 --- /dev/null +++ b/adm_local/unix/config_files/check_fvm.m4 @@ -0,0 +1,121 @@ +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl +AC_DEFUN([CHECK_FVM],[ + +AC_CHECKING(for FVM Library) + +AC_LANG_SAVE +AC_LANG(C++) + +FVM_INCLUDES="" +FVM_LIBSUFFIX="" +FVM_LIBS="" +ENABLE_FVM="no" + +AC_CHECKING(for FVM location) +AC_ARG_WITH(fvm, + [ --with-fvm=DIR root directory path to FVM library installation ], + [FVMDIR="$withval" + AC_MSG_RESULT("select $withval as path to FVM library")]) + +AC_MSG_RESULT(\$FVMDIR = ${FVMDIR}) + +CPPFLAGS_old="${CPPFLAGS}" +LIBS_old=$LIBS + +if test "x${FVMDIR}" != "x" ; then + + CHECK_BFT + fvm_ok=no + + + + if test "x${bft_ok}" = "xyes"; then + fvm_headers_ok=no + fvm_binaries_ok=no + FVM_INCLUDES="-I${FVMDIR}/include" + FVM_LIBS="-L${FVMDIR}/lib -lfvm ${BFT_LIBS} ${MPI_LIBS}" + + + dnl FVM headers + AC_CHECKING(for FVM headers) + CPPFLAGS="${CPPFLAGS_old} ${FVM_INCLUDES} ${MPI_CPPFLAGS} ${MED_CPPFLAGS}" + + fvm_include_dir_ok=yes + if test "x${FVMDIR}" != "x" ; then + AC_CHECK_FILE(${FVMDIR}/include/fvm_nodal.h, + fvm_include_dir_ok=yes, + fvm_include_dir_ok=no) + fi + + if test "x${fvm_include_dir_ok}" = "xyes" ; then + AC_TRY_COMPILE([#include + #include "fvm_nodal.h"], + [fvm_nodal_create("",2)], + fvm_headers_ok=yes, + fvm_headers_ok=no) + fi + + if test "x${fvm_headers_ok}" = "xno" ; then + FVM_INCLUDES="FVM_INCLUDES_NOT_DEFINED" + else + AC_MSG_RESULT(\$FVM_INCLUDES = ${FVM_INCLUDES}) + fi + AC_MSG_RESULT(for fvm headers: $fvm_headers_ok) + + if test "x${fvm_headers_ok}" = "xyes" ; then + dnl FVM binaries + AC_CHECKING(for FVM binaries) + fvm_lib_dir_ok=yes + if test "x${FVMDIR}" != "x" ; then + AC_CHECK_FILE(${FVMDIR}/lib/libfvm.so, + fvm_lib_dir_ok=yes, + fvm_lib_dir_ok=no) + fi + + fi + + CPPFLAGS="${CPPFLAGS_old}" + LIBS="${LIBS_old}" + + if test "x${fvm_headers_ok}" = "xyes" ; then + if test "x${fvm_lib_dir_ok}" = "xyes" ; then + fvm_ok=yes + ENABLE_FVM="yes" + fi + fi + + + AC_SUBST(FVM_INCLUDES) + AC_SUBST(FVM_LIBSUFFIX) + AC_SUBST(FVM_LIBS) + AC_SUBST(ENABLE_FVM) + fi + AC_MSG_RESULT(for fvm: $fvm_ok) + +fi + +AC_LANG_RESTORE + +])dnl + + diff --git a/adm_local/unix/config_files/check_libxml.m4 b/adm_local/unix/config_files/check_libxml.m4 index e7370fb2b..06dcb02dd 100644 --- a/adm_local/unix/config_files/check_libxml.m4 +++ b/adm_local/unix/config_files/check_libxml.m4 @@ -1,23 +1,23 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl AC_DEFUN([CHECK_LIBXML],[ @@ -44,6 +44,12 @@ LIBS_old=$LIBS if test "x${LIBXML_DIR}" != "x" ; then LIBXML_CPPFLAGS="-I${LIBXML_DIR}/include/libxml2" LIBXML_LIBS="-L${LIBXML_DIR}/lib -lxml2" +else + if test -f /usr/include/libxml2/libxml/tree.h ; then + LIBXML_DIR="/usr" + LIBXML_CPPFLAGS="-I${LIBXML_DIR}/include/libxml2" + LIBXML_LIBS="-lxml2" + fi fi libxml_ok=no diff --git a/adm_local/unix/config_files/check_metis.m4 b/adm_local/unix/config_files/check_metis.m4 index 0127d0c49..caa4d48b6 100644 --- a/adm_local/unix/config_files/check_metis.m4 +++ b/adm_local/unix/config_files/check_metis.m4 @@ -1,23 +1,23 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl AC_DEFUN([CHECK_METIS],[ diff --git a/adm_local/unix/config_files/check_scotch.m4 b/adm_local/unix/config_files/check_scotch.m4 index 63c32752f..5822cb69d 100644 --- a/adm_local/unix/config_files/check_scotch.m4 +++ b/adm_local/unix/config_files/check_scotch.m4 @@ -1,23 +1,23 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl AC_DEFUN([CHECK_SCOTCH],[ diff --git a/adm_local/unix/config_files/med_check_sizeof_medint.m4 b/adm_local/unix/config_files/med_check_sizeof_medint.m4 index 722479c82..97572a42c 100644 --- a/adm_local/unix/config_files/med_check_sizeof_medint.m4 +++ b/adm_local/unix/config_files/med_check_sizeof_medint.m4 @@ -1,3 +1,24 @@ +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl AC_DEFUN([MED_CHECK_SIZEOF_MEDINT], [ ## Guess the fortran int size diff --git a/adm_local/unix/config_files/splitter.m4 b/adm_local/unix/config_files/splitter.m4 index 85f6517bc..aa66e7ff4 100644 --- a/adm_local/unix/config_files/splitter.m4 +++ b/adm_local/unix/config_files/splitter.m4 @@ -1,30 +1,28 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl dnl define macros : dnl AC_ENABLE_SPLITTER AC_DISABLE_SPLITTER -dnl dnl author Vincent BERGEAUD dnl - # AC_ENABLE_SPLITTER AC_DEFUN([AC_ENABLE_SPLITTER], [dnl define([AC_ENABLE_SPLITTER_DEFAULT], ifelse($1, yes, yes, no))dnl diff --git a/adm_local/unix/config_files/with_Kernel.m4 b/adm_local/unix/config_files/with_Kernel.m4 index 246e18f5a..6663c44bf 100644 --- a/adm_local/unix/config_files/with_Kernel.m4 +++ b/adm_local/unix/config_files/with_Kernel.m4 @@ -1,3 +1,24 @@ +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl # # Check configure option --with-kernel=[yes|no|DIR] taking into account that # MED_WITH_KERNEL may be already set during build_configure, diff --git a/adm_local/unix/make_common_starter.am b/adm_local/unix/make_common_starter.am index 6a4c36d23..01bbf29ad 100644 --- a/adm_local/unix/make_common_starter.am +++ b/adm_local/unix/make_common_starter.am @@ -1,51 +1,73 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 # # ============================================================ # This file defines the common definitions used in several # Makefile. This file must be included, if needed, by the file # Makefile.am. # ============================================================ -# - # Standard directory for installation -salomeincludedir = $(includedir)/@PACKAGE@ -libdir = $(prefix)/lib@LIB_LOCATION_SUFFIX@/@PACKAGE@ -bindir = $(prefix)/bin/@PACKAGE@ +# +salomeincludedir = $(includedir)/salome +libdir = $(prefix)/lib@LIB_LOCATION_SUFFIX@/salome +bindir = $(prefix)/bin/salome purebindir = $(prefix)/bin salomescriptdir = $(bindir) +salomepythondir = $(pythondir)/salome +salomepyexecdir = $(pyexecdir)/salome # Tests environment folders testsenvirondir = $(prefix)/Tests/environ testsenvironcshdir = $(prefix)/Tests/environ/csh # Directory for installing idl files -salomeidldir = $(prefix)/idl/@PACKAGE@ +salomeidldir = $(prefix)/idl/salome # Directory for installing resource files -salomeresdir = $(prefix)/share/@PACKAGE@/resources/@MODULE_NAME@ +salomeresdir = $(prefix)/share/salome/resources/@MODULE_NAME@ # Directories for installing admin files -admlocaldir = $(prefix)/adm_local -admlocalunixdir = $(admlocaldir)/unix -admlocalm4dir = $(admlocaldir)/unix/config_files +admlocaldir = $(prefix)/adm_local +admlocalunixdir = $(admlocaldir)/unix +admlocalm4dir = $(admlocaldir)/unix/config_files # Shared modules installation directory -sharedpkgpythondir =$(pkgpythondir)/shared_modules +sharedpkgpythondir = $(salomepythondir)/shared_modules # Documentation directory -docdir = $(datadir)/doc/@PACKAGE@ +docdir = $(datadir)/doc/salome # common rules -# moc-files generation +# meta object implementation files generation (moc) %_moc.cxx: %.h $(MOC) $< -o $@ -# qm-files generation -%.qm: %.po - $(MSG2QM) $< $@ +# translation (*.qm) files generation (lrelease) +%.qm: %.ts + $(LRELEASE) $< -qm $@ -EXTRA_DIST=$(MOC_FILES:%_moc.cxx=%.h) $(nodist_salomeres_DATA:%.qm=%.po) +EXTRA_DIST = $(MOC_FILES:%_moc.cxx=%.h) $(nodist_salomeres_DATA:%.qm=%.ts) +# customize clean operation mostlyclean-local: rm -f @builddir@/*_moc.cxx rm -f @builddir@/*.qm @@ -57,3 +79,9 @@ unittest: $(UNIT_TEST_PROG) @if test "x$(UNIT_TEST_PROG)" != "x"; then \ $(UNIT_TEST_PROG); \ fi; + +# documentation +html-local: $(DOX_INPUT_FILE) + @if test "x$(DOX_INPUT_FILE)" != "x"; then \ + doxygen $(DOX_INPUT_FILE); \ + fi; diff --git a/adm_local_without_kernel/Makefile.am b/adm_local_without_kernel/Makefile.am index 5fc3e2c7a..f35273fac 100644 --- a/adm_local_without_kernel/Makefile.am +++ b/adm_local_without_kernel/Makefile.am @@ -1,22 +1,24 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# - +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# include $(top_srcdir)/adm_local/unix/make_common_starter.am -SUBDIRS= unix +SUBDIRS = unix diff --git a/adm_local_without_kernel/unix/Makefile.am b/adm_local_without_kernel/unix/Makefile.am index facd4e6f4..8a8630081 100644 --- a/adm_local_without_kernel/unix/Makefile.am +++ b/adm_local_without_kernel/unix/Makefile.am @@ -1,22 +1,29 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# - +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# include $(top_srcdir)/adm_local/unix/make_common_starter.am SUBDIRS = config_files + +################################## +# not-used (obsolete?) files +################################## +# SALOMEconfig.h.in depend.in make_module.in \ No newline at end of file diff --git a/adm_local_without_kernel/unix/SALOMEconfig.h.in b/adm_local_without_kernel/unix/SALOMEconfig.h.in index c1be35bd0..939d91909 100644 --- a/adm_local_without_kernel/unix/SALOMEconfig.h.in +++ b/adm_local_without_kernel/unix/SALOMEconfig.h.in @@ -1,23 +1,24 @@ -/*---------------------------------------------------------------------------------- - Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, - CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS - - 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. - - 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org -------------------------------------------------------------------------------------*/ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #ifndef SALOME_CONFIG_H #define SALOME_CONFIG_H diff --git a/adm_local_without_kernel/unix/config_files/Makefile.am b/adm_local_without_kernel/unix/config_files/Makefile.am index 86e4051e0..858dc935d 100644 --- a/adm_local_without_kernel/unix/config_files/Makefile.am +++ b/adm_local_without_kernel/unix/config_files/Makefile.am @@ -1,27 +1,30 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# include $(top_srcdir)/adm_local/unix/make_common_starter.am -admlocalwithoutkerneldir = $(prefix)/adm_local_without_kernel +admlocalwithoutkerneldir = $(prefix)/adm_local_without_kernel admlocalwithoutkernelm4dir = $(prefix)/adm_local_without_kernel/unix/config_files -dist_admlocalwithoutkernelm4_DATA=\ +dist_admlocalwithoutkernelm4_DATA = \ ac_cxx_depend_flag.m4 \ ac_cxx_have_sstream.m4 \ ac_cxx_namespaces.m4 \ @@ -43,4 +46,8 @@ dist_admlocalwithoutkernelm4_DATA=\ ltconfig \ ltmain.sh \ production.m4 \ - python.m4 + python.m4 \ + check_lam.m4 \ + check_mpi.m4 \ + check_mpich.m4 \ + check_openmpi.m4 diff --git a/adm_local_without_kernel/unix/config_files/ac_cxx_depend_flag.m4 b/adm_local_without_kernel/unix/config_files/ac_cxx_depend_flag.m4 index 9dc8b0fd3..7ac8c42a9 100644 --- a/adm_local_without_kernel/unix/config_files/ac_cxx_depend_flag.m4 +++ b/adm_local_without_kernel/unix/config_files/ac_cxx_depend_flag.m4 @@ -1,29 +1,27 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. dnl -dnl @synopsis AC_C_DEPEND_FLAG +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl +dnl @synopsis AC_C_DEPEND_FLAG dnl define C_DEPEND_FLAG dnl define CXX_DEPEND_FLAG -dnl dnl @version $Id$ dnl @author Marc Tajchman dnl diff --git a/adm_local_without_kernel/unix/config_files/ac_cxx_have_sstream.m4 b/adm_local_without_kernel/unix/config_files/ac_cxx_have_sstream.m4 index b3b009f3a..de84d16e9 100644 --- a/adm_local_without_kernel/unix/config_files/ac_cxx_have_sstream.m4 +++ b/adm_local_without_kernel/unix/config_files/ac_cxx_have_sstream.m4 @@ -1,33 +1,29 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. dnl -dnl @synopsis AC_CXX_HAVE_SSTREAM +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. dnl -dnl If the C++ library has a working stringstream, define HAVE_SSTREAM. +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl +dnl @synopsis AC_CXX_HAVE_SSTREAM +dnl If the C++ library has a working stringstream, define HAVE_SSTREAM. dnl @author Ben Stanley dnl @version $Id$ dnl -dnl modified by Marc Tajchman (CEA) - 10/10/2002 -dnl AC_DEFUN([AC_CXX_HAVE_SSTREAM], [AC_CACHE_CHECK(whether the compiler has stringstream, HAVE_SSTREAM, diff --git a/adm_local_without_kernel/unix/config_files/ac_cxx_namespaces.m4 b/adm_local_without_kernel/unix/config_files/ac_cxx_namespaces.m4 index 76b815ace..f82d8d5c8 100644 --- a/adm_local_without_kernel/unix/config_files/ac_cxx_namespaces.m4 +++ b/adm_local_without_kernel/unix/config_files/ac_cxx_namespaces.m4 @@ -1,29 +1,27 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. dnl -dnl @synopsis AC_CXX_NAMESPACES +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl +dnl @synopsis AC_CXX_NAMESPACES dnl If the compiler can prevent names clashes using namespaces, define dnl HAVE_NAMESPACES. -dnl dnl @version $Id$ dnl @author Luc Maisonobe dnl diff --git a/adm_local_without_kernel/unix/config_files/ac_cxx_option.m4 b/adm_local_without_kernel/unix/config_files/ac_cxx_option.m4 index 72ea0ab11..698af6170 100644 --- a/adm_local_without_kernel/unix/config_files/ac_cxx_option.m4 +++ b/adm_local_without_kernel/unix/config_files/ac_cxx_option.m4 @@ -1,28 +1,26 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. dnl -dnl @synopsis AC_CXX_OPTION(-option,variable where we add option if ok,action if ok; action if not ok) +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. dnl -dnl Check options for C++ compiler +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl +dnl @synopsis AC_CXX_OPTION(-option,variable where we add option if ok,action if ok; action if not ok) +dnl Check options for C++ compiler dnl @author Bernard Secher - 15/01/2004 dnl AC_DEFUN([AC_CXX_OPTION], [ diff --git a/adm_local_without_kernel/unix/config_files/ac_cxx_template_options.m4 b/adm_local_without_kernel/unix/config_files/ac_cxx_template_options.m4 index d9dd8b49b..725be4e1d 100644 --- a/adm_local_without_kernel/unix/config_files/ac_cxx_template_options.m4 +++ b/adm_local_without_kernel/unix/config_files/ac_cxx_template_options.m4 @@ -1,29 +1,26 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. dnl -dnl @synopsis AC_CXX_TEMPLATE_OPTIONS +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. dnl -dnl Check template options for C++ compiler +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl -dnl @author Bernard Secher (CEA) - 04/12/2003 +dnl @synopsis AC_CXX_TEMPLATE_OPTIONS +dnl Check template options for C++ compiler dnl AC_DEFUN([AC_CXX_TEMPLATE_OPTIONS],[ dnl diff --git a/adm_local_without_kernel/unix/config_files/ac_cxx_use_std_iostream.m4 b/adm_local_without_kernel/unix/config_files/ac_cxx_use_std_iostream.m4 index 8e44db9ac..665482d83 100644 --- a/adm_local_without_kernel/unix/config_files/ac_cxx_use_std_iostream.m4 +++ b/adm_local_without_kernel/unix/config_files/ac_cxx_use_std_iostream.m4 @@ -1,29 +1,26 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. dnl -dnl @synopsis AC_CXX_USE_STD_IOSTREAM +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. dnl -dnl If the C++ library use std iostream +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl -dnl @author Bernard Secher (CEA) - 05/12/2003 +dnl @synopsis AC_CXX_USE_STD_IOSTREAM +dnl If the C++ library use std iostream dnl AC_DEFUN([AC_CXX_USE_STD_IOSTREAM], [ diff --git a/adm_local_without_kernel/unix/config_files/ac_cxx_warnings.m4 b/adm_local_without_kernel/unix/config_files/ac_cxx_warnings.m4 index b23ca3bd2..14d2cafa8 100644 --- a/adm_local_without_kernel/unix/config_files/ac_cxx_warnings.m4 +++ b/adm_local_without_kernel/unix/config_files/ac_cxx_warnings.m4 @@ -1,29 +1,26 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. dnl -dnl @synopsis AC_CXX_WARNINGS +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. dnl -dnl Check warning flags for C++ compiler to control warning messages +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl -dnl @author Bernard Secher (CEA) - 04/12/2003 +dnl @synopsis AC_CXX_WARNINGS +dnl Check warning flags for C++ compiler to control warning messages dnl AC_DEFUN([AC_CXX_WARNINGS],[ AC_CXX_OPTION(-Wno-deprecated,CXXFLAGS) diff --git a/adm_local_without_kernel/unix/config_files/ac_linker_options.m4 b/adm_local_without_kernel/unix/config_files/ac_linker_options.m4 index 9006a46fe..dd2abdbf4 100644 --- a/adm_local_without_kernel/unix/config_files/ac_linker_options.m4 +++ b/adm_local_without_kernel/unix/config_files/ac_linker_options.m4 @@ -1,38 +1,31 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. dnl -dnl @synopsis AC_LINKER_OPTIONS +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. dnl -dnl Check warning flags for C++ compiler to control warning messages +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl -dnl @author Bernard Secher (CEA) - 04/12/2003 +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl +dnl @synopsis AC_LINKER_OPTIONS +dnl Check warning flags for C++ compiler to control warning messages dnl AC_DEFUN([AC_LINKER_OPTIONS],[ AC_CHECKING(for LIB_LOCATION_SUFFIX) LIB_LOCATION_SUFFIX="" - case "$build_cpu" in - x86_64*) LIB_LOCATION_SUFFIX="64" ;; - *) LIB_LOCATION_SUFFIX="" ;; - esac AC_SUBST(LIB_LOCATION_SUFFIX) AC_MSG_RESULT(LIB_LOCATION_SUFFIX is $LIB_LOCATION_SUFFIX) diff --git a/adm_local_without_kernel/unix/config_files/check_boost.m4 b/adm_local_without_kernel/unix/config_files/check_boost.m4 index 12cd2a864..90b222d37 100644 --- a/adm_local_without_kernel/unix/config_files/check_boost.m4 +++ b/adm_local_without_kernel/unix/config_files/check_boost.m4 @@ -1,23 +1,23 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl AC_DEFUN([CHECK_BOOST],[ diff --git a/adm_local_without_kernel/unix/config_files/check_cppunit.m4 b/adm_local_without_kernel/unix/config_files/check_cppunit.m4 index e78b4fa24..c2c679f40 100644 --- a/adm_local_without_kernel/unix/config_files/check_cppunit.m4 +++ b/adm_local_without_kernel/unix/config_files/check_cppunit.m4 @@ -1,4 +1,24 @@ - +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl AC_DEFUN([CHECK_CPPUNIT],[ AC_CHECKING(for cppunit) diff --git a/adm_local_without_kernel/unix/config_files/check_hdf5.m4 b/adm_local_without_kernel/unix/config_files/check_hdf5.m4 index b20db13ac..5eecd8119 100644 --- a/adm_local_without_kernel/unix/config_files/check_hdf5.m4 +++ b/adm_local_without_kernel/unix/config_files/check_hdf5.m4 @@ -1,23 +1,24 @@ -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org -# -# +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl AC_DEFUN([CHECK_HDF5],[ AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_CPP])dnl diff --git a/adm_local_without_kernel/unix/config_files/check_lam.m4 b/adm_local_without_kernel/unix/config_files/check_lam.m4 new file mode 100644 index 000000000..30ff09b41 --- /dev/null +++ b/adm_local_without_kernel/unix/config_files/check_lam.m4 @@ -0,0 +1,130 @@ +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl +AC_DEFUN([CHECK_LAM],[ + +AC_REQUIRE([AC_PROG_CC])dnl + +AC_ARG_WITH(lam, + [AC_HELP_STRING([--with-lam=DIR],[root directory path of LAM installation])], + WITHLAM="yes",WITHLAM="no") + +MPI_INCLUDES="" +MPI_LIBS="" +if test "$WITHLAM" = yes; then + + MPIREQUESTED="yes" + echo + echo --------------------------------------------- + echo testing lam + echo --------------------------------------------- + echo + LAM_HOME=$withval + + if test "$LAM_HOME"; then + MPI_INCLUDES="-I$LAM_HOME/include" + if test "x$LAM_HOME" = "x/usr" + then + MPI_LIBS="" + else + MPI_LIBS="-L$LAM_HOME/lib" + fi + fi + + CPPFLAGS_old="$CPPFLAGS" + CPPFLAGS="$MPI_INCLUDES $CPPFLAGS" + AC_CHECK_HEADER(mpi.h,WITHLAM="yes",WITHLAM="no") + + if test "$WITHLAM" = "yes";then + AC_CHECK_LIB(util,openpty,,WITHLAM="no") + LIBS_old="$LIBS" + LDFLAGS_old="$LDFLAGS" + LDFLAGS="$MPI_LIBS $LDFLAGS" + fi + + if test "$WITHLAM" = "yes";then + + LIBS="$LIBS -lmpi++" + AC_MSG_CHECKING(for MPI_Init in -lmpi++) + AC_TRY_LINK([ + #include + ], [int argc=0; char **argv=0; MPI_Init(&argc,&argv);], + WITHLAM="yes",WITHLAM="no") + + if test "$WITHLAM" = "yes";then + + AC_MSG_RESULT(yes) + MPI_LIBS="$MPI_LIBS -lmpi++" + AC_CHECK_LIB(mpi++,MPI_Publish_name,WITHMPI2="yes",WITHMPI2="no") + + else + AC_MSG_RESULT(no) + + LIBS="$LIBS_old" + AC_CHECK_LIB(lam,lam_mp_init,WITHLAM="yes",WITHLAM="no") + if test "$WITHLAM" = "yes";then + MPI_LIBS="$MPI_LIBS -llam" + LIBS="$LIBS -llam" + fi + + AC_CHECK_LIB(mpi,MPI_Init,WITHLAM="yes",WITHLAM="no") + if test "$WITHLAM" = "yes";then + MPI_LIBS="-lmpi $MPI_LIBS" + LIBS="-lmpi $LIBS" + fi + + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + LIBS="-llammpi++ $LIBS" + AC_MSG_CHECKING(for MPI_Init in -llammpi++) + AC_TRY_LINK([ + #include + ], [MPI::Init();], + WITHLAM="yes",WITHLAM="no") + if test "$WITHLAM" = "yes";then + AC_MSG_RESULT(yes) + MPI_LIBS="-llammpi++ $MPI_LIBS" + else + AC_MSG_RESULT(no) + fi + AC_LANG_RESTORE + + AC_CHECK_LIB(mpi,MPI_Publish_name,WITHMPI2="yes",WITHMPI2="no") + + fi + fi + + CPPFLAGS="$CPPFLAGS_old" + LDFLAGS="$LDFLAGS_old" + LIBS="$LIBS_old" + + if test "$WITHLAM" = "yes";then + WITHMPI="yes" + mpi_ok=yes + CPPFLAGS="-DWITHLAM $CPPFLAGS" + else + mpi_ok=no + fi + +fi + + +])dnl diff --git a/adm_local_without_kernel/unix/config_files/check_mpi.m4 b/adm_local_without_kernel/unix/config_files/check_mpi.m4 new file mode 100644 index 000000000..57bedb985 --- /dev/null +++ b/adm_local_without_kernel/unix/config_files/check_mpi.m4 @@ -0,0 +1,130 @@ +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl +AC_DEFUN([CHECK_MPI],[ + +AC_REQUIRE([AC_PROG_CC])dnl + +AC_ARG_WITH(mpi_lib, + [AC_HELP_STRING([--with-mpi_lib=DIR],[directory path of MPICH lib installation])], + MPILIBREQUESTED="$withval") + +AC_ARG_WITH(mpi, + [AC_HELP_STRING([--with-mpi=DIR],[root directory path of MPICH installation])], + MPIREQUESTED="yes",MPIREQUESTED="no") + +MPI_INCLUDES="" +MPI_LIBS="" +WITHMPI=no +mpi_ok=no +if test x"$MPIREQUESTED" = xyes; then + + echo + echo --------------------------------------------- + echo testing mpi + echo --------------------------------------------- + echo + + if test "x$withval" != "xyes"; then + MPI_HOME=$withval + MPI_INCLUDES="-I$MPI_HOME/include" + if test "x$MPI_HOME" = "x/usr" + then + MPI_LIBS="" + else + MPI_LIBS="-L$MPI_HOME/lib" + fi + fi + + if test x"$MPILIBREQUESTED" != x; then + MPI_LIBS="-L$MPILIBREQUESTED" + fi + + CPPFLAGS_old="$CPPFLAGS" + CPPFLAGS="$MPI_INCLUDES $CPPFLAGS" + AC_CHECK_HEADER(mpi.h,WITHMPI="yes",WITHMPI="no") + CPPFLAGS="$CPPFLAGS_old" + + if test "$WITHMPI" = "yes";then + LIBS_old="$LIBS" + LDFLAGS_old="$LDFLAGS" + LDFLAGS="$MPI_LIBS $LDFLAGS" + AC_CHECK_LIB(elan,elan_init,MPI_LIBS="$MPI_LIBS -lelan") + AC_CHECK_LIB(mpi,MPI_Init,WITHMPI="yes",WITHMPI="no") + AC_CHECK_LIB(mpi,MPI_Publish_name,WITHMPI2="yes",WITHMPI2="no") + LDFLAGS="$LDFLAGS_old" + LIBS="$LIBS_old" + fi + + if test "$WITHMPI" = "yes";then + mpi_ok=yes + MPI_LIBS="$MPI_LIBS -lmpi -lmpio -lmpiCC" + else + mpi_ok=no + fi + +fi + +if test "$WITHMPI" = no; then +dnl +dnl --------------------------------------------- +dnl testing MPICH +dnl --------------------------------------------- +dnl + + CHECK_MPICH + + if test "$WITHMPICH" = no; then +dnl +dnl --------------------------------------------- +dnl testing LAM +dnl --------------------------------------------- +dnl + + CHECK_LAM + + fi + + if test "$WITHLAM" = no; then +dnl +dnl --------------------------------------------- +dnl testing OPENMPI +dnl --------------------------------------------- +dnl + + CHECK_OPENMPI + + fi + +fi + +if test x$WITHMPI2 = xyes; then + CPPFLAGS="-DHAVE_MPI2 $CPPFLAGS" + CORBA_IDLCXXFLAGS="-DHAVE_MPI2 $CORBA_IDLCXXFLAGS" + CORBA_IDLPYFLAGS="-DHAVE_MPI2 $CORBA_IDLPYFLAGS" +fi + +AC_SUBST(WITHMPI) +AC_SUBST(MPI_INCLUDES) +AC_SUBST(MPI_LIBS) +AC_SUBST(mpi_ok) +AM_CONDITIONAL(MPI_IS_OK, [test x"$mpi_ok" = xyes]) +])dnl diff --git a/adm_local_without_kernel/unix/config_files/check_mpich.m4 b/adm_local_without_kernel/unix/config_files/check_mpich.m4 new file mode 100644 index 000000000..c581cecec --- /dev/null +++ b/adm_local_without_kernel/unix/config_files/check_mpich.m4 @@ -0,0 +1,78 @@ +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl +AC_DEFUN([CHECK_MPICH],[ + +AC_REQUIRE([AC_PROG_CC])dnl + +AC_ARG_WITH(mpich, + [AC_HELP_STRING([--with-mpich=DIR],[root directory path of MPICH installation])], + WITHMPICH="yes",WITHMPICH="no") + +MPI_INCLUDES="" +MPI_LIBS="" +if test "$WITHMPICH" = yes; then + + MPIREQUESTED="yes" + echo + echo --------------------------------------------- + echo testing mpich + echo --------------------------------------------- + echo + MPICH_HOME=$withval + + if test "$MPICH_HOME"; then + MPI_INCLUDES="-I$MPICH_HOME/include -DMPICH_IGNORE_CXX_SEEK" + if test "x$MPICH_HOME" = "x/usr" + then + MPI_LIBS="" + else + MPI_LIBS="-L$MPICH_HOME/lib" + fi + fi + + CPPFLAGS_old="$CPPFLAGS" + CPPFLAGS="$MPI_INCLUDES $CPPFLAGS" + AC_CHECK_HEADER(mpi.h,WITHMPICH="yes",WITHMPICH="no") + CPPFLAGS="$CPPFLAGS_old" + + if test "$WITHMPICH" = "yes";then + MPI_LIBS="$MPI_LIBS -lmpich -lpmpich" + fi + + if test "$WITHMPICH" = "yes";then + LDFLAGS_old="$LDFLAGS" + LDFLAGS="$MPI_LIBS $LDFLAGS" + AC_CHECK_LIB(mpich,MPI_Init,WITHMPICH="yes",WITHMPICH="no") + AC_CHECK_LIB(mpich,MPI_Publish_name,WITHMPI2="yes",WITHMPI2="no") + LDFLAGS="$LDFLAGS_old" + fi + + if test "$WITHMPICH" = "yes";then + WITHMPI="yes" + mpi_ok=yes + else + mpi_ok=no + fi + +fi + +])dnl diff --git a/adm_local_without_kernel/unix/config_files/check_openmpi.m4 b/adm_local_without_kernel/unix/config_files/check_openmpi.m4 new file mode 100644 index 000000000..cbbe91f4d --- /dev/null +++ b/adm_local_without_kernel/unix/config_files/check_openmpi.m4 @@ -0,0 +1,55 @@ +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl +AC_DEFUN([CHECK_OPENMPI],[ +AC_ARG_WITH(openmpi, + AC_HELP_STRING([--with-openmpi=DIR],[root directory path of openmpi installation]), + WITHOPENMPI="yes",WITHOPENMPI="no") + +MPI_INCLUDES="" +MPI_LIBS="" +mpi_ok=no + +if test "$WITHOPENMPI" = yes; then + + OPENMPI_HOME=$withval + + if test "$OPENMPI_HOME"; then + MPI_INCLUDES=`$OPENMPI_HOME/bin/mpicxx --showme:compile` + MPI_LIBS=`$OPENMPI_HOME/bin/mpicxx --showme:link` + fi + + CPPFLAGS_old="$CPPFLAGS" + CPPFLAGS="$MPI_INCLUDES $CPPFLAGS" + AC_CHECK_HEADER(mpi.h,WITHOPENMPI="yes",WITHOPENMPI="no") + CPPFLAGS="$CPPFLAGS_old" + + AC_MSG_CHECKING(for openmpi) + if test "$WITHOPENMPI" = "yes";then + mpi_ok=yes + AC_MSG_RESULT(yes) + else + mpi_ok=no + AC_MSG_RESULT(no) + fi +fi +])dnl + diff --git a/adm_local_without_kernel/unix/config_files/check_pthreads.m4 b/adm_local_without_kernel/unix/config_files/check_pthreads.m4 index 80aef2aad..768baca2f 100644 --- a/adm_local_without_kernel/unix/config_files/check_pthreads.m4 +++ b/adm_local_without_kernel/unix/config_files/check_pthreads.m4 @@ -1,23 +1,23 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl #@synonpsis CHECK_PTHREADS dnl check for pthreads system interfaces. diff --git a/adm_local_without_kernel/unix/config_files/check_swig.m4 b/adm_local_without_kernel/unix/config_files/check_swig.m4 index 10408c009..7ad472c81 100644 --- a/adm_local_without_kernel/unix/config_files/check_swig.m4 +++ b/adm_local_without_kernel/unix/config_files/check_swig.m4 @@ -1,25 +1,24 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl - AC_DEFUN([CHECK_SWIG],[ AC_REQUIRE([CHECK_PYTHON])dnl diff --git a/adm_local_without_kernel/unix/config_files/enable_pthreads.m4 b/adm_local_without_kernel/unix/config_files/enable_pthreads.m4 index 45652fbb5..cb2eb58a8 100644 --- a/adm_local_without_kernel/unix/config_files/enable_pthreads.m4 +++ b/adm_local_without_kernel/unix/config_files/enable_pthreads.m4 @@ -1,32 +1,28 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org -dnl -dnl -dnl -dnl@synopsis ENABLE_PTHREADS +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl -dnl modify CFLAGS, CXXFLAGS and LIBS for compiling pthread-based programs. +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl +dnl modify CFLAGS, CXXFLAGS and LIBS for compiling pthread-based programs. dnl@author (C) Ruslan Shevchenko , 1998, 2000 dnl@id $Id$ dnl -dnl AC_DEFUN([ENABLE_PTHREADS],[ AC_REQUIRE([CHECK_PTHREADS]) diff --git a/adm_local_without_kernel/unix/config_files/install-sh b/adm_local_without_kernel/unix/config_files/install-sh index 56ccb7b5f..530a200d0 100755 --- a/adm_local_without_kernel/unix/config_files/install-sh +++ b/adm_local_without_kernel/unix/config_files/install-sh @@ -1,4 +1,25 @@ #! /bin/sh +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# chmodParams="" dirParams="" diff --git a/adm_local_without_kernel/unix/config_files/production.m4 b/adm_local_without_kernel/unix/config_files/production.m4 index e4a61870b..5c7f1d0f6 100644 --- a/adm_local_without_kernel/unix/config_files/production.m4 +++ b/adm_local_without_kernel/unix/config_files/production.m4 @@ -1,33 +1,30 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl dnl define macros : dnl AC_ENABLE_PRODUCTION AC_DISABLE_PRODUCTION -dnl and dnl AC_ENABLE_DEBUG AC_DISABLE_DEBUG -dnl dnl version $Id$ dnl author Patrick GOLDBRONN dnl - # AC_ENABLE_PRODUCTION AC_DEFUN([AC_ENABLE_PRODUCTION], [dnl define([AC_ENABLE_PRODUCTION_DEFAULT], ifelse($1, no, no, yes))dnl diff --git a/adm_local_without_kernel/unix/config_files/python.m4 b/adm_local_without_kernel/unix/config_files/python.m4 index 84263a6e9..ebce3393e 100644 --- a/adm_local_without_kernel/unix/config_files/python.m4 +++ b/adm_local_without_kernel/unix/config_files/python.m4 @@ -1,23 +1,23 @@ -dnl Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl -dnl See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE dnl +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl ## ------------------------ ## Python file handling diff --git a/adm_local_without_kernel/unix/make_module.in b/adm_local_without_kernel/unix/make_module.in index 843465d13..cdefed130 100644 --- a/adm_local_without_kernel/unix/make_module.in +++ b/adm_local_without_kernel/unix/make_module.in @@ -1,7 +1,28 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# # generic rule to put in top module Makefile # (for example with module SALOME, SALOME/Makefile.in and SALOME/src/Makefile.in) - # build all lib in all subdir +# lib:$(SUBDIRS:%=lib_%) $(SUBDIRS:%=lib_%):lib_%:% diff --git a/bin/Makefile.am b/bin/Makefile.am index e81b2089a..15df8dbd0 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -1,22 +1,28 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 - +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# include $(top_srcdir)/adm_local/unix/make_common_starter.am -nodist_salomescript_DATA= VERSION -EXTRA_DIST+= VERSION.in +# non-distributed files +nodist_salomescript_DATA = VERSION + +# distributed files +dist_salomescript_SCRIPTS = diff --git a/build_cmake b/build_cmake new file mode 100755 index 000000000..048e8ead5 --- /dev/null +++ b/build_cmake @@ -0,0 +1,30 @@ +#!/bin/sh +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# + +CURRENT_DIR=`pwd` +CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` +cd ${CONF_DIR} +python $KERNEL_ROOT_DIR/salome_adm/cmake_files/am2cmake.py --med +status=$? +cd ${CURRENT_DIR} +exit $status diff --git a/build_cmake.bat b/build_cmake.bat new file mode 100644 index 000000000..0160bfd50 --- /dev/null +++ b/build_cmake.bat @@ -0,0 +1,2 @@ + +%PYTHONBIN% %KERNEL_ROOT_DIR%\salome_adm\cmake_files\am2cmake.py --med diff --git a/build_configure b/build_configure index e928e0d10..90567e876 100755 --- a/build_configure +++ b/build_configure @@ -1,19 +1,35 @@ #!/bin/sh - +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 # # Tool for updating list of .in file for the SALOME project # and regenerating configure script -# # It may be called with --with-kernel[=yes,no] or --without-kernel # option, default is --with-kernel=yes -# # Author : Marc Tajchman - CEA # Date : 10/10/2002 # $Header$ -# # 14/03/2007: Mikhail PONIKAROV - OCN # Reorganization for uage of autotools - +# ORIG_DIR=`pwd` CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` @@ -40,10 +56,10 @@ done for option do case $option in - -with-ihm | --with-ihm) + -with-gui | --with-gui) MED_WITH_GUI="yes" break;; - -without-ihm | --without-ihm | -with-ihm=no | --with-ihm=no) + -without-gui | --without-gui | -with-gui=no | --with-gui=no) MED_WITH_GUI="no" break;; esac @@ -73,6 +89,7 @@ ABS_CONF_DIR=`pwd` ####################################################################### # Update configure.ac script: to set MED_WITH_KERNEL and MED_WITH_GUI variables +chmod +w configure.ac sed -e s/MED_WITH_KERNEL=[a-z]*/MED_WITH_KERNEL=${MED_WITH_KERNEL}/g configure.ac > configure.tmp sed -e s/MED_WITH_GUI=[a-z]*/MED_WITH_GUI=${MED_WITH_GUI}/g configure.tmp > configure.ac rm configure.tmp @@ -163,4 +180,4 @@ autoconf # Makefile.in (from Makefile.am) echo "====================================================== automake" -automake --copy --gnu --add-missing +automake --copy --gnu --add-missing --warnings=no-portability diff --git a/clean_configure b/clean_configure index be0b5427f..f57f7b3bf 100755 --- a/clean_configure +++ b/clean_configure @@ -1,5 +1,25 @@ #!/bin/sh - +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# rm -rf autom4te.cache aclocal.m4 configure make_config find . -name "*~" -print -exec rm {} \; find . -name "*.pyc" -print -exec rm {} \; diff --git a/configure.ac b/configure.ac index cb4879c02..8e2100f5e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,15 +1,35 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# # Author : Marc Tajchman (CEA) # Date : 28/06/2001 # Modified by : Patrick GOLDBRONN (CEA) # Modified by : Marc Tajchman (CEA) # Modified by : Mikhail PONIKAROV (OCN) # - -AC_INIT([Salome2 Project MED module], [4.1.1], [webmaster.salome@opencascade.com], [salome]) +AC_INIT([Salome2 Project MED module], [5.1.0], [webmaster.salome@opencascade.com], [SalomeMED]) AC_CONFIG_AUX_DIR(salome_adm/unix/config_files) AC_CANONICAL_HOST AC_CANONICAL_TARGET -AM_INIT_AUTOMAKE +AM_INIT_AUTOMAKE([tar-pax]) XVERSION=`echo $VERSION | awk -F. '{printf("0x%02x%02x%02x",$1,$2,$3)}'` AC_SUBST(XVERSION) @@ -208,7 +228,6 @@ echo CHECK_HDF5 - echo echo --------------------------------------------- echo BOOST Library @@ -217,7 +236,6 @@ echo CHECK_BOOST - echo echo --------------------------------------------- echo testing MED2 @@ -233,40 +251,25 @@ echo "MED_WITH_GUI : ${MED_WITH_GUI}" echo --------------------------------------------- openpbs_ok=no -# CHECK_OPENPBS ONLY if MED_WITH_KERNEL=yes -# echo -# echo --------------------------------------------- -# echo testing OpenPBS -# echo --------------------------------------------- -# echo - -# CHECK_OPENPBS -# dnl openpbs_ok is set to yes by CHECK_OPENPBS - -# CHECK_LSF ONLY if MED_WITH_KERNEL=yes -# echo -# echo --------------------------------------------- -# echo testing LSF -# echo --------------------------------------------- -# echo +# CHECK_OPENPBS ONLY if MED_WITH_KERNEL is yes lsf_ok=no -# CHECK_LSF -# dnl lsf_ok is set to yes by CHECK_LSF +# CHECK_LSF ONLY if MED_WITH_KERNEL is yes echo echo ---------------------------------------------- echo testing CPPUNIT only required for unit testing echo ---------------------------------------------- echo + CHECK_CPPUNIT -#AM_CONDITIONAL(CPPUNIT_IS_OK, test) echo echo --------------------------------------------- echo checking SPLITTER echo --------------------------------------------- echo + AC_ENABLE_SPLITTER(yes) AM_CONDITIONAL(MED_ENABLE_SPLITTER, [test "$ENABLE_SPLITTER" = yes]) @@ -303,11 +306,35 @@ fi AM_CONDITIONAL(MED_ENABLE_METIS, [test "$ENABLE_METIS" = yes]) AM_CONDITIONAL(MED_ENABLE_SCOTCH, [test "$ENABLE_SCOTCH" = yes]) +dnl +dnl --------------------------------------------- +dnl testing MPI +dnl --------------------------------------------- +dnl -if test "${MED_WITH_KERNEL}" = "yes"; then -{ +CHECK_MPI +#CHECK_MPICH +AM_CONDITIONAL(MED_WITHMPI, [test "$WITHMPI" = yes]) + +echo +echo --------------------------------------------- +echo Testing FVM library generators +echo --------------------------------------------- +echo + +CHECK_FVM +AM_CONDITIONAL(MED_ENABLE_FVM, [test "$ENABLE_FVM" = yes]) +echo +echo --------------------------------------------- +echo Testing html generators +echo --------------------------------------------- +echo +CHECK_HTML_GENERATORS + +if test "${MED_WITH_KERNEL}" = "yes"; then +{ echo echo --------------------------------------------- echo testing OpenPBS @@ -355,23 +382,6 @@ if test "${MED_WITH_KERNEL}" = "yes"; then lex_yacc_ok=yes fi - dnl - dnl --------------------------------------------- - dnl testing MPI - dnl --------------------------------------------- - dnl - - CHECK_MPI - CHECK_MPICH - - dnl echo - dnl echo --------------------------------------------- - dnl echo testing java - dnl echo --------------------------------------------- - dnl echo - - dnl CHECK_JAVA - echo echo --------------------------------------------- echo testing omniORB @@ -418,15 +428,15 @@ if test "${MED_WITH_KERNEL}" = "yes"; then echo CHECK_VTK - fi - echo - echo --------------------------------------------- - echo Testing OpenCascade - echo --------------------------------------------- - echo + echo + echo --------------------------------------------- + echo Testing OpenCascade + echo --------------------------------------------- + echo - CHECK_CAS + CHECK_CAS + fi echo echo --------------------------------------------- @@ -443,24 +453,6 @@ if test "${MED_WITH_KERNEL}" = "yes"; then dnl echo dnl CHECK_MICO - - if test "${MED_WITH_GUI}" = "yes"; then - echo - echo --------------------------------------------- - echo testing MSG2QM - echo --------------------------------------------- - echo - - CHECK_MSG2QM - fi - - echo - echo --------------------------------------------- - echo Testing html generators - echo --------------------------------------------- - echo - - CHECK_HTML_GENERATORS } else { @@ -469,7 +461,6 @@ else AC_SUBST(WITHIHM) AC_SUBST(WITHOPENPBS) - CPPFLAGS="$CPPFLAGS -DMED_WITHOUT_KERNEL" } fi # MED_WITH_KERNEL @@ -509,14 +500,14 @@ else echo Configure fi -#variables="cc_ok lex_yacc_ok python_ok swig_ok threads_ok hdf5_ok med2_ok boost_ok doxygen_ok graphviz_ok OpenGL_ok qt_ok vtk_ok omniORB_ok occ_ok Kernel_ok" - if test "${MED_WITH_GUI}" = "yes"; then -variables="cc_ok lex_yacc_ok mpi_ok python_ok swig_ok threads_ok OpenGL_ok qt_ok vtk_ok hdf5_ok med2_ok omniORB_ok occ_ok sip_ok pyqt_ok qwt_ok Kernel_ok cppunit_ok" + variables="cc_ok lex_yacc_ok python_ok swig_ok threads_ok OpenGL_ok qt_ok vtk_ok hdf5_ok med2_ok omniORB_ok sip_ok pyqt_ok qwt_ok occ_ok doxygen_ok Kernel_ok SalomeGUI_ok" +else + variables="cc_ok python_ok swig_ok threads_ok hdf5_ok med2_ok omniORB_ok doxygen_ok Kernel_ok" fi -if test "${MED_WITH_GUI}" = "no"; then -variables="cc_ok mpi_ok python_ok swig_ok threads_ok hdf5_ok med2_ok omniORB_ok occ_ok Kernel_ok cppunit_ok" +if test "x$ENABLE_SPLITTER" = "xyes"; then + variables="$variables metis_ok scotch_ok libxml_ok" fi for var in $variables @@ -531,31 +522,21 @@ done dnl optional variables echo "---Optional:" -variables="metis_ok scotch_ok libxml_ok" -for var in $variables - do - eval toto=\$$var - if test x$toto != "x"; then - printf " %10s : " `echo \$var | sed -e "s,_ok,,"` - eval echo \$$var - fi - done +variables="mpi_ok fvm_ok cppunit_ok" if test "${MED_WITH_KERNEL}" = "yes"; then -{ - variables="openpbs_ok lsf_ok doxygen_ok graphviz_ok" - - for var in $variables - do - eval toto=\$$var - if test x$toto != "x"; then - printf " %10s : " `echo \$var | sed -e "s,_ok,,"` - eval echo \$$var - fi - done -} + variables="$variables openpbs_ok lsf_ok graphviz_ok" fi +for var in $variables +do + eval toto=\$$var + if test x$toto != "x"; then + printf " %10s : " `echo \$var | sed -e "s,_ok,,"` + eval echo \$$var + fi +done + echo echo "Default ORB : $DEFAULT_ORB" echo @@ -568,6 +549,10 @@ else AC_SUBST(SETX) SETX="set -x" fi +if test -n "${NO_MED_TRACE+X}"; then + CPPFLAGS="${CPPFLAGS} -D_NO_MED_TRACE_" +fi + echo echo --------------------------------------------- echo generating Makefiles and configure files @@ -580,11 +565,12 @@ AC_OUTPUT_COMMANDS([ \ AC_OUTPUT([ \ ./salome_adm/unix/SALOMEconfig.h \ - ./adm_local_without_kernel/unix/sstream \ + ./adm_local_without_kernel/unix/SALOMEconfig.h \ Makefile \ ./MED_version.h \ ./adm_local/unix/config_files/Makefile \ ./adm_local/unix/Makefile \ + ./adm_local/cmake_files/Makefile \ ./adm_local/Makefile \ ./adm_local_without_kernel/unix/config_files/Makefile \ ./adm_local_without_kernel/unix/Makefile \ @@ -605,12 +591,24 @@ AC_OUTPUT([ \ ./src/MEDMEM/Doxyfile_med_devel \ ./src/MEDMEM/Doxyfile_med_user \ ./src/MEDMEM/Makefile \ - ./src/MEDMEM/Test/Makefile \ ./src/INTERPOLATION/Makefile \ ./src/MEDMEM_SWIG/Makefile \ + ./src/MEDMEMBinTest/Makefile \ + ./src/MEDMEMCppTest/Makefile \ + ./src/INTERP_KERNEL/Makefile \ + ./src/INTERP_KERNEL/Bases/Makefile \ + ./src/INTERP_KERNEL/Geometric2D/Makefile \ + ./src/INTERP_KERNELTest/Makefile \ + ./src/MEDCoupling/Makefile \ + ./src/MEDCoupling/Test/Makefile \ ./src/MEDSPLITTER/Makefile \ ./src/MEDSPLITTER/Test/Makefile \ + ./src/MEDSPLITTER_Swig/Makefile \ ./src/MULTIPR/Makefile \ + ./src/ParaMEDMEM/Makefile \ + ./src/ParaMEDMEM/MEDLoader/Makefile \ + ./src/ParaMEDMEM/Test/Makefile \ + ./src/ParaMEDMEM_Swig/Makefile \ ./src/MEDMEM_I/Makefile \ ./src/MED/Makefile \ ./src/MedCorba_Swig/Makefile \ @@ -641,11 +639,9 @@ AC_OUTPUT([ \ ./doc/MEDMEM/MEDMEM_UsersGuide.tex \ ./doc/salome/Makefile \ ./doc/salome/tui/Makefile \ - ./doc/salome/tui/MED/Makefile \ - ./doc/salome/tui/MED/sources/Makefile \ - ./doc/salome/tui/MED/sources/static/Makefile \ - ./doc/salome/tui/MED/doxyfile \ - ./doc/salome/tui/MED/sources/static/tree.js + ./doc/salome/tui/doxyfile \ + ./doc/doxygen/Makefile \ + ./doc/doxygen/Doxyfile_med_user \ ]) dnl To avoid recompiling half of the sources because of SALOMEconfig.h recreating diff --git a/doc/MEDMEM/FIELDcreate.cxx b/doc/MEDMEM/FIELDcreate.cxx index d7535213d..cb0518d00 100644 --- a/doc/MEDMEM/FIELDcreate.cxx +++ b/doc/MEDMEM/FIELDcreate.cxx @@ -1,5 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 // using namespace std; #include "MEDMEM_Mesh.hxx" diff --git a/doc/MEDMEM/FIELDcreate.py b/doc/MEDMEM/FIELDcreate.py index 908aac180..3108caf7b 100644 --- a/doc/MEDMEM/FIELDcreate.py +++ b/doc/MEDMEM/FIELDcreate.py @@ -1,13 +1,30 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# ###################################################################### -# # # This Python script should be executed when the shared library is # # generated using SWIG 1.3 (or higher) due to the fact that older # # version could not handle the wrapping of several class constructor # -# # ###################################################################### +# from libMEDMEM_Swig import * MedFile = "pointe.med" diff --git a/doc/MEDMEM/FIELDgeneral.cxx b/doc/MEDMEM/FIELDgeneral.cxx index 6a546ee3b..99a809c9a 100644 --- a/doc/MEDMEM/FIELDgeneral.cxx +++ b/doc/MEDMEM/FIELDgeneral.cxx @@ -1,5 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 // using namespace std; #include "MEDMEM_Mesh.hxx" diff --git a/doc/MEDMEM/FIELDgeneral.py b/doc/MEDMEM/FIELDgeneral.py index 5daf18bda..0c3ae3274 100644 --- a/doc/MEDMEM/FIELDgeneral.py +++ b/doc/MEDMEM/FIELDgeneral.py @@ -1,13 +1,30 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# ###################################################################### -# # # This Python script should be executed when the shared library is # # generated using SWIG 1.3 (or higher) due to the fact that older # # version could not handle the wrapping of several class constructor # -# # ###################################################################### +# from libMEDMEM_Swig import * MedFile = "pointe.med" diff --git a/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.cxx b/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.cxx index 91c8ee465..6f868fba3 100644 --- a/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.cxx +++ b/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.cxx @@ -1,6 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #include "MEDMEM_Exception.hxx" #include "MEDMEM_define.hxx" diff --git a/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.py b/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.py index 06573aea1..ed8bdd260 100644 --- a/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.py +++ b/doc/MEDMEM/MEDMEM_InvokingDriverAtObjectCreationTime.py @@ -1,13 +1,30 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 # ###################################################################### -# # # This Python script should be executed when the shared library is # # generated using SWIG 1.3 (or higher) due to the fact that older # # version could not handle the wrapping of several class constructor # -# # ###################################################################### +# from libMEDMEM_Swig import * medFile = "pointe.med" diff --git a/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.cxx b/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.cxx index 657a7e8ae..9e421598d 100644 --- a/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.cxx +++ b/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.cxx @@ -1,6 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #include "MEDMEM_Exception.hxx" #include "MEDMEM_define.hxx" diff --git a/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.py b/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.py index 78aa1eeee..53b60d7fc 100644 --- a/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.py +++ b/doc/MEDMEM/MEDMEM_InvokingDriverByAttachingItToAnObject.py @@ -1,13 +1,30 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# ###################################################################### -# # # This Python script should be executed when the shared library is # # generated using SWIG 1.3 (or higher) due to the fact that older # # version could not handle the wrapping of several class constructor # -# # ###################################################################### +# from libMEDMEM_Swig import * medFile = "pointe.med" diff --git a/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.cxx b/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.cxx index ba8afff00..1f63266a6 100644 --- a/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.cxx +++ b/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.cxx @@ -1,6 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #include "MEDMEM_Exception.hxx" #include "MEDMEM_define.hxx" diff --git a/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.py b/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.py index 1b1804df1..988ddef66 100644 --- a/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.py +++ b/doc/MEDMEM/MEDMEM_InvokingDriverFromStandardObjectMethod.py @@ -1,13 +1,30 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# ###################################################################### -# # # This Python script should be executed when the shared library is # # generated using SWIG 1.3 (or higher) due to the fact that older # # version could not handle the wrapping of several class constructor # -# # ###################################################################### +# from libMEDMEM_Swig import * medFile = "pointe.med" diff --git a/doc/MEDMEM/MEDMEM_MedAddingAnExistingObject.cxx b/doc/MEDMEM/MEDMEM_MedAddingAnExistingObject.cxx index b36fef10b..e806d3ca0 100644 --- a/doc/MEDMEM/MEDMEM_MedAddingAnExistingObject.cxx +++ b/doc/MEDMEM/MEDMEM_MedAddingAnExistingObject.cxx @@ -1,6 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #include "MEDMEM_Exception.hxx" #include "MEDMEM_define.hxx" diff --git a/doc/MEDMEM/MESHINGexample.cxx b/doc/MEDMEM/MESHINGexample.cxx index e40c27b35..ab2349c69 100644 --- a/doc/MEDMEM/MESHINGexample.cxx +++ b/doc/MEDMEM/MESHINGexample.cxx @@ -1,6 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #include "MEDMEM_Meshing.hxx" #include "MEDMEM_Group.hxx" diff --git a/doc/MEDMEM/MESHINGexample.py b/doc/MEDMEM/MESHINGexample.py index 9d88636d6..d042c0d8d 100644 --- a/doc/MEDMEM/MESHINGexample.py +++ b/doc/MEDMEM/MESHINGexample.py @@ -1,12 +1,31 @@ -################################################################################### +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +################################################################################### # This Python script uses the wrapped C++ class MESHING to buid a mesh from only # primitive data like coordinates (Pythoin double array) and connectivity (Python # integer arrays). It is the Python equivalent of the C++ program # test_MEDMEM_Meshing.cxx in the ../MEDMEM directory of the SALOME distribution -# ################################################################################### - +# from libMEDMEM_Swig import * # files name to save the generated MESH(ING) in different format diff --git a/doc/MEDMEM/MESHconnectivities.cxx b/doc/MEDMEM/MESHconnectivities.cxx index 1580d640f..e1f57b05d 100644 --- a/doc/MEDMEM/MESHconnectivities.cxx +++ b/doc/MEDMEM/MESHconnectivities.cxx @@ -1,6 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #include "MEDMEM_Mesh.hxx" using namespace MEDMEM ; diff --git a/doc/MEDMEM/MESHconnectivities.py b/doc/MEDMEM/MESHconnectivities.py index 19bf5c4a4..c1ce770c5 100644 --- a/doc/MEDMEM/MESHconnectivities.py +++ b/doc/MEDMEM/MESHconnectivities.py @@ -1,6 +1,24 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# from libMEDMEM_Swig import * MedFile = "pointe.med" diff --git a/doc/MEDMEM/MESHcoordinates.cxx b/doc/MEDMEM/MESHcoordinates.cxx index fca22a17c..dddacf740 100644 --- a/doc/MEDMEM/MESHcoordinates.cxx +++ b/doc/MEDMEM/MESHcoordinates.cxx @@ -1,6 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #include "MEDMEM_Mesh.hxx" using namespace MEDMEM ; diff --git a/doc/MEDMEM/MESHcoordinates.py b/doc/MEDMEM/MESHcoordinates.py index b082a1a3f..7e79fd655 100644 --- a/doc/MEDMEM/MESHcoordinates.py +++ b/doc/MEDMEM/MESHcoordinates.py @@ -1,6 +1,24 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# from libMEDMEM_Swig import * MedFile = "pointe.med" diff --git a/doc/MEDMEM/MESHgeneral.cxx b/doc/MEDMEM/MESHgeneral.cxx index a577966e7..74836e211 100644 --- a/doc/MEDMEM/MESHgeneral.cxx +++ b/doc/MEDMEM/MESHgeneral.cxx @@ -1,6 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// using namespace std; #include "MEDMEM_Mesh.hxx" diff --git a/doc/MEDMEM/MESHgeneral.py b/doc/MEDMEM/MESHgeneral.py index 95fc03868..3a85c09d0 100644 --- a/doc/MEDMEM/MESHgeneral.py +++ b/doc/MEDMEM/MESHgeneral.py @@ -1,6 +1,24 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# from libMEDMEM_Swig import * MedFile = "pointe.med" diff --git a/doc/MEDMEM/Makefile.am b/doc/MEDMEM/Makefile.am index daf99a22e..2ff2c5127 100644 --- a/doc/MEDMEM/Makefile.am +++ b/doc/MEDMEM/Makefile.am @@ -1,21 +1,24 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# include $(top_srcdir)/adm_local/unix/make_common_starter.am EXTRA_DIST += \ diff --git a/doc/Makefile.am b/doc/Makefile.am index 735b5fa53..7eca88d88 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,22 +1,26 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +SUBDIRS = MEDMEM salome doxygen -SUBDIRS= MEDMEM salome +dev_docs: + (cd salome && $(MAKE) $(AM_MAKEFLAGS) dev_docs) -EXTRA_DIST= html diff --git a/doc/doxygen/Doxyfile_med_user.in b/doc/doxygen/Doxyfile_med_user.in new file mode 100644 index 000000000..bbd06e6d3 --- /dev/null +++ b/doc/doxygen/Doxyfile_med_user.in @@ -0,0 +1,228 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +# Doxyfile 0.1 +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- +# +PROJECT_NAME = "Med Memory Users' Guide" +PROJECT_NUMBER = @VERSION@ +OUTPUT_DIRECTORY = doc_ref_user +OUTPUT_LANGUAGE = English +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +BRIEF_MEMBER_DESC = NO +REPEAT_BRIEF = YES +ALWAYS_DETAILED_SEC = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +INTERNAL_DOCS = NO +STRIP_CODE_COMMENTS = YES +CASE_SENSE_NAMES = YES +SHORT_NAMES = NO +HIDE_SCOPE_NAMES = NO +VERBATIM_HEADERS = NO +SHOW_INCLUDE_FILES = NO +JAVADOC_AUTOBRIEF = NO +INHERIT_DOCS = YES +INLINE_INFO = NO +SORT_MEMBER_DOCS = NO +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 8 +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +ALIASES = +ENABLED_SECTIONS = user MEDMEM_ug +MAX_INITIALIZER_LINES = 30 +OPTIMIZE_OUTPUT_FOR_C = NO +SHOW_USED_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = log_user +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = @srcdir@ \ + @srcdir@/../../src/ParaMEDMEM \ + @srcdir@/../../src/INTERP_KERNEL \ + @srcdir@/../../src/INTERP_KERNEL/Geometric2D \ + @srcdir@/../../src/MEDMEM + +FILE_PATTERNS = MEDMEM_Mesh.* \ + MEDMEM_Grid.* \ + MEDMEM_Meshing.* \ + MEDMEM_Support.* \ + MEDMEM_Field.* \ + MEDMEM_Med.* \ + IntersectionDEC.* \ + DEC.* \ + MPIProcessorGroup.* \ + StructuredCoincidentDEC.* \ + ExplicitCoincidentDEC.* \ + NonCoincidentDEC.* \ + CommInterface.* \ + Interpolation2D.* \ + Interpolation3D.* \ + Interpolation3DSurf.* \ + InterpolationMatrix.* \ + PlanarIntersector.* \ + TargetIntersector.* \ + Interpolation.* \ + AbstractEdge.* \ + Edge.* \ + EdgeArcCircle.* \ + EdgeLin.* \ + ComposedEdge.* \ + ElementaryEdge.* \ + Node.* \ + QuadraticPolygon.* \ + ParaFIELD.* \ + *.dox +RECURSIVE = NO +EXCLUDE = CVS +EXCLUDE_PATTERNS = *~ +EXAMPLE_PATH = @srcdir@/../../src/ParaMEDMEM/ \ + @srcdir@/../../doc/MEDMEM \ + @srcdir@/../../src/MEDMEM +EXAMPLE_PATTERNS = *.cxx *.py +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = @srcdir@/figures +INPUT_FILTER = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = YES +GENERATE_CHI = YES +BINARY_TOC = NO +TOC_EXPAND = YES +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = YES +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +COMPACT_LATEX = YES +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +TEMPLATE_RELATIONS = YES +HIDE_UNDOC_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +GRAPHICAL_HIERARCHY = YES +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO +CGI_NAME = search.cgi +CGI_URL = +DOC_URL = +DOC_ABSPATH = +BIN_ABSPATH = /usr/local/bin/ +EXT_DOC_PATHS = diff --git a/doc/doxygen/Geometric2D.dox b/doc/doxygen/Geometric2D.dox new file mode 100644 index 000000000..5f1f51dd7 --- /dev/null +++ b/doc/doxygen/Geometric2D.dox @@ -0,0 +1,237 @@ +/*! +\page interpkernelGeo2D Geometric2D Intersector + +Like other intersectors the aim of this intersector is to compute intersection between 2 +polygons.\n +The specificity of this intersector is to deal with \b any \b type of +polygons even those with \b quadratic \b edges. +Its quite generic architecture allows him to deal with some other +patentially usefull functions.\n +This page described Geometric2D intersector basic principles and +specific usage. + +\section interpkernelGeo2DIntro Introduction + +The principle used in this intersector to perform boolean operation on geometry is geometric-modeler like. +The data structure used to describe polygons is boundary description. That is to say the internal +representation of a polygon is its edges composing it. + +\subsection interpkernelGeo2DNamingConv Naming conventions + + - An \ref INTERP_KERNEL::AbstractEdge "edge" is defined by a start + node, a end node and a curve equation (linear or arc of + circle). \b WARNING : start node and end node \b HAVE \b TO \b BE + different and distant at least equal to precision set. + - An \ref INTERP_KERNEL::ElementaryEdge "elementary edge" is an edge \b NOT \b splittable \b without \b applying + \b mathematical \b intersection \b computation. + - A \ref INTERP_KERNEL::ComposedEdge "composed edge" is a collection of consecutive edges hierarchically \b splittable + \b without \b any \b mathematical \b intersection \b computation. + +Consecutive means that in a composed edge if edge \a e2 follows edge +\a e1, the end node of \a e1 is geometrically equal to start node of +\a e2. + +\subsection interpkernelGeo2DBasicConcepts Basic concepts + +A \ref INTERP_KERNEL::QuadraticPolygon "quadratic polygon" is a +specialization of a +\ref INTERP_KERNEL::ComposedEdge "composed edge" in that it is +closed. Closed means that the start node of first edge is equal to end +node of last edge.\n +A \ref INTERP_KERNEL::ComposedEdge "composed edge" is considered as a +collection of \ref INTERP_KERNEL::AbstractEdge "abstract edges". An +\ref INTERP_KERNEL::AbstractEdge "abstract edge" is either an \ref +INTERP_KERNEL::ElementaryEdge "elementary edge" or itself a \ref +INTERP_KERNEL::ComposedEdge "composed edge".\n A composite pattern has +been used here. + +Each \ref INTERP_KERNEL::ElementaryEdge " elementary edge" and each +\ref INTERP_KERNEL::Node "nodes" have a flag that states if during +the split process if it is \b out, \b on, \b in or \b unknown. + +\section interpkernelGeo2DBoolOp Boolean operation algorithm + +\subsection interpkernelGeo2DBoolOpPrinc Basics + +The boolean operation (intersection) between two polygons is used in P0 P0 interpolation. + +The process of boolean operations between two polygons P1 and P2 is done in three steps : + + -# \ref interpkernelGeo2DBoolOpStep1 "splitting". + -# \ref interpkernelGeo2DBoolOpStep2 "edges localization". + -# \ref interpkernelGeo2DBoolOpStep3 "result polygons building". + +\subsection interpkernelGeo2DBoolOpStep1 Step1 : splitting. + +The principle used to do boolean operations between 2 polygons P1 and +P2 is to intersect each edge of P1 with each edge of P2. \n After this +edge-splitting, polygon P1 is splitted, so that each +\ref INTERP_KERNEL::ElementaryEdge "elementary edge" constituting P1 +is either \b in, \b out or \b on polygon P2. And inversely, polygon P2 is splitted so that each +\ref INTERP_KERNEL::ElementaryEdge "elementary edge" constituting P2 +is either \b in, \b out or \b on polygon P1. + +During split process, when, without any CPU overhead, the location can be +deduced, the nodes and edges are localized. + +This step of splitting is common to all boolean operations.\n +The method in charge of that is INTERP_KERNEL::QuadraticPolygon::splitPolygonsEachOther. + +\subsection interpkernelGeo2DBoolOpStep2 Step2 : Edges localization. + +Perform localization of each splitted edge. As \ref interpkernelGeo2DBoolOpStep1 "split process" it + is common to all boolean operations. + +When the location of edges has \b not been +already deduced in previous computation and there is no predecessor, the +\ref interpkernelGeo2DAlgLoc "localization is done in absolute". +After it deduces the localization relatively to the previous edge +thanks to node localization.\n The relative localization is done +following these rules : + + * + * + * + * + * + * + * + * + * + * + *
Previous Edge LocCurrent start node Loc Current edge Loc
UNKNOWN ANY UNKNOWN -> \ref interpkernelGeo2DAlgLoc "Absolute search"
OUT ON IN
OUT ON_TANGENT OUT
IN ON OUT
IN ON_TANGENT IN
OUT OUT OUT
IN IN IN
ON ANY UNKNOWN -> \ref interpkernelGeo2DAlgLoc "Absolute search"
+ +The method in charge of that is INTERP_KERNEL::QuadraticPolygon::performLocatingOperation. + +\subsection interpkernelGeo2DBoolOpStep3 Step3 : Result polygon building. + +This stage links each edge with wanted loc. \b Contrary to last 2 steps it is obviously boolean +operation dependant. Let's take the case of the intersection that is used in +P0->P0 interpolation. \n The principle of result polygon building is to build polygon by taking +edges localized as \b in or \b on. + +Generally, the principle is to take an edge in \a P1 with wanted loc and linking +direct neighbour-edges (with correct loc) until closing a polygon. If +not, using \a P2 edges to try to close polygon. The process is +repeated until all edges with correct loc have been consumed. + +The method in charge of that is INTERP_KERNEL::QuadraticPolygon::buildIntersectionPolygons. + +\section interpkernelGeo2DAlg underneath algorithms. + +\subsection interpkernelGeo2DAlgLoc Absolute localization algorithm. + +This algorithm is called when splitting process has been done, and +that we are sure that the edge is either \b fully \b in ,or \b fully \b on or \b fully +\b out. + +The principle chosen to know if an edge \a E is completely included in an +any polygon \a P is to see if its barycenter \a B is inside this any +polygon \a P. +After, for each nodes \f$ P_i \f$ of polygon \a P we store angle in \f$ [-\pi/2,\pi/2 ] \f$ +that represents the slope of line \f$ (BP_i) \f$.\n +Then a line \a L going through \a B with a slope being as far as +possible from all slopes found above. Then the algorithm goes along \a L +and number of times \a N it intersects \b non-tangentally the any polygon \a P. + +If \a N is odd \a B (and then \a E) is IN. +If \a N is even \a B (and then \a E) is OUT. + +This computation is \b very \b expensive, that why some tricks as described in +\ref interpkernelGeo2DBoolOpStep2 "localization techniques" are used to call as few as possible +during intersecting process. + +\subsection interpkernelGeo2DAlgIntsect Intersection algorithms. + +The only mathematical intersections performed are edges intersections. +The algorithms used are : + + -# Lin-Lin intersection : http://mathworld.wolfram.com/Line-LineIntersection.html + -# Lin-Arc intersection : http://mathworld.wolfram.com/Circle-LineIntersection.html + -# Arc-Arc intersection : http://mathworld.wolfram.com/Circle-CircleIntersection.html + +\subsection interpkernelGeo2DAlgOthers Other algorithms. + +As internal architecture is quite general, it is possible to have more than classical intersection on any polygons : + + - \ref INTERP_KERNEL::ComposedEdge::getAreaOfZone "area" computation is available. + - \ref INTERP_KERNEL::QuadraticPolygon::getPerimeterFast "perimeter" computation. + - \ref INTERP_KERNEL::QuadraticPolygon::getHydraulicDiameter "Hydraulic diameter" computation. + +\section interpkernelGeo2DUsage Usage. + +This intersector is usable standalone. To use a set of user friendly methods have been implemented. + + - INTERP_KERNEL::QuadraticPolygon::buildArcCirclePolygon method builds from a \c std::vector of INTERP_KERNEL::Node* \a V, an instance of QuadraticPolygon \a P. + \a P will have \f$ N_{edges} = V.size()/2 \f$ edges. Quadratic edge \f$ Edge_i i \in [0,N_{edges}-1] \f$ starts with node V[i], ends with node V[i+1] and has a middle in + \f$ V[i+N_{edge}] \f$. \n If start, end and middle nodes of edge \f$ Edge_i \f$ are aligned by a precision specified by INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision. + - INTERP_KERNEL::QuadraticPolygon::buildLinearPolygon method builds from a \c std::vector of INTERP_KERNEL::Node* \a V, an instance of QuadraticPolygon \a + P. \a P will have \f$ N_edges = V.size() \f$ edges. Linear edge \f$ Edge_i i \in [0,N_{edges}-1] \f$ starts with node V[i] and ends with node V[i+1]. + +The orientation of polygons (clockwise, inverse clockwise) impact computation only on the sign of areas. During intersection of 2 polygons their orientation can be different. + +The usage is simple : + +\code +... +// defining a precision +INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-5); +INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); +// +INTERP_KERNEL::QuadraticPolygon *polygon1=...; +bool isQuadratic=...//Depends on the nature of your cell. If your cell is MED_QUAD8 or MED_TRIA6 for example isQuadratic=true. +const double *externalTabXCoords=...; +const double *externalTabYCoords=...; +std::vector nodes; +INTERP_KERNEL::QuadraticPolygon *polygon2=0; +for(int i=0;iintersectWith(*polygon2); +double dhydPol1=polygon1->getHydraulicDiameter(); +double areaPol1=polygon1->getAreaOfZone(); +//clean-up +delete polygon1; +delete polygon2; +... +\endcode + +\section interpkernelGeo2DExample Example of result. + +Here an example of 2 polygons. The left one \a P1 has 4 edges and the +right one \a P2 has 4 edges too. + +\anchor interpkernelGeo2DEx1 +\image html SampGeo2D1.png "An example of intersection of 2 polygons." +\image latex SampGeo2D1.eps "An example of intersection of 2 polygons." + +After \ref interpkernelGeo2DBoolOpStep1 "spliting process" \a P1 has 6 edges and \a P2 has 6 edges too. + +\anchor interpkernelGeo2DEx2 +\image html SampGeo2D2.png "After spliting process two edges of P1 have been located has out." +\image latex SampGeo2D2.eps "After spliting process two edges of P1 have been located has out." + +\note BLUE is for OUT, GREEN for IN and RED for ON. + +For each 6 edges \ref interpkernelGeo2DBoolOpStep2 "locate" them. + +\anchor interpkernelGeo2DEx3 +\image html SampGeo2D3.png "Result after locating phase." +\image latex SampGeo2D3.eps "Result after locating phase." + +Too finish \ref interpkernelGeo2DBoolOpStep3 "closing" polygons. + +\anchor interpkernelGeo2DEx4 +\image html SampGeo2D4.png "Close-up of final result after close polygons phase." +\image latex SampGeo2D4.eps "Close-up of final result after close polygons phase." + +\note The result polygon is constitued from 2 sub-edges coming from \a P1 +and 1 sub-edge from \a P2 closing the polygon. For the 2 edges of \a P1 +they are green because they are fully included in \a P2. Inversely, +the only sub-edge coming from \a P2 is fully included in \a P1. + +*/ diff --git a/doc/doxygen/MED_class.dox b/doc/doxygen/MED_class.dox new file mode 100644 index 000000000..fa348a573 --- /dev/null +++ b/doc/doxygen/MED_class.dox @@ -0,0 +1,24 @@ + +/*! +\page MED_class MED object + +\section MED_general General Information + +This object is used to give information about the different +meshes/supports/fields that are contained in a file. +This enables the user to know about the file content without +loading the meshes in memory. Also, it can be useful for +memory management since meshes, supports and fields accessed through a MED +object are destroyed when the MED object is destroyed. + +\section MED_object_outline +The methods are described in the following sections : +- constructors : \ref MED_constructors +- query methods : \ref MED_query + +For an example using these methods, one may see the Python scripts in the +directory \c $MED_ROOT_DIR/bin/salome/,\c testMedObj.py, or C++ +example program in the directory \c $MED_SRC_DIR/src/MEDMEM, +\c duplicateMED.cxx. + +*/ \ No newline at end of file diff --git a/doc/doxygen/Makefile.am b/doc/doxygen/Makefile.am new file mode 100644 index 000000000..8b430be28 --- /dev/null +++ b/doc/doxygen/Makefile.am @@ -0,0 +1,52 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +# MED MEDMEM : MED files in memory +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +DOX_INPUT_FILE = Doxyfile_med_user + +userdocdir = $(prefix)/doc/user + +install-data-local : html-local + $(INSTALL) -d $(DESTDIR)$(userdocdir) + cp -rp doc_ref_user/html $(DESTDIR)$(userdocdir) + +uninstall-local: + rm -rf $(DESTDIR)$(userdocdir) + +clean-local: + rm -rf doc_ref_user log_user + +EXTRA_DIST += figures \ + main.dox \ + MED_class.dox \ + biblio.dox \ + field.dox \ + grid.dox \ + medsplitter.dox \ + mesh.dox \ + meshing.dox \ + polygon.dox \ + remapping.dox \ + support.dox \ + tools.dox diff --git a/doc/doxygen/barycoords.dox b/doc/doxygen/barycoords.dox new file mode 100644 index 000000000..e55c64887 --- /dev/null +++ b/doc/doxygen/barycoords.dox @@ -0,0 +1,39 @@ +/*! +\page barycoords Barycentric coordinates algorithm + +Computation of barycentric coordinates is used to fill interpolation +matrix in case of P1 an P1d types of interpolation. Computation of +barycentric coordinates consists in finding weights of vertices +bearing values within the cell. The cell is triangle in 2D space and +tetrahedron in 3D space. + +Input of the algorithm includes +- coordinates of cell vertices (p1...pn), +- coordinates of a barycentre of cells intersection (b), +
where n is number of vertices which is either 3 or 4. + +Purpose is to find coefficients a1...an so that +- (a1*p1+...+an*pn)=b and +- (a1+...+an)=1.0 + +Combining the last two expressions we get an equation in matrix form +a * T = ( b - pn ) +where +- a is a vector of coefficients a1...an +- b is a vector of cartesian coordinates of barycentre +- T is a matrix expressed via cartesian coordinates of vertices as +
in 2D case
+| x1-x3 x2-x3 |
+| y1-y3 y2-y3 |
+in 3D case
+| x1-x4 x2-x4 x3-x4 |
+| y1-y4 y2-y4 y3-y4 |
+| z1-z4 z2-z4 z3-z4 |
+ +In 2D case solution is found by inversing T which is trivial: a = T^(-1) * ( b - pn ) + +In 3D case we use Gaussian elimination algorithm. First we use elementary +row operations to transform T into upper triangular form and +then perform back substitution to find coeficients a. + +*/ diff --git a/doc/doxygen/biblio.dox b/doc/doxygen/biblio.dox new file mode 100644 index 000000000..1f258eadf --- /dev/null +++ b/doc/doxygen/biblio.dox @@ -0,0 +1,12 @@ +/*! +\defgroup references References + +Here follows a list of useful references : + +-# Reference Manual for Med File, V. Lefebvre, E. Fayolle, Projet PAL: Définition du modèle d'échange de données MED V2.2, Note technique EDF/SINETICS, HI-26-03-012/A, https://hammi.extra.cea.fr/static/MED/web_med/index.html \anchor RefManualMedFile +-# VTK home page: \c http://public.kitware.com/VTK +-# Med File Data Model : V. Lefebvre, E. Fayolle, Définition du modèle d'échange de données MED v2.2, https://hammi.extra.cea.fr/static/MED/web_med/pdf/NOTE_HI_26_03_012_A.pdf +-# Jeffrey Grandy, Conservative remapping and region overlays by intersecting arbitrary polyhedra, Journal of Computational Physics, vol 148, 433-466 (1999) +-# F. Preparata and M. Shamos Computational Geometry. Springer-Verlag, New York, 1985 +*/ + diff --git a/doc/doxygen/dualmesh.dox b/doc/doxygen/dualmesh.dox new file mode 100644 index 000000000..f4d462b30 --- /dev/null +++ b/doc/doxygen/dualmesh.dox @@ -0,0 +1,42 @@ +/*! +\page dualmesh DualMESH + +The \ref INTERP_KERNEL::DualMESH "DualMESH" class is an auxiliary class used to perform P0->P1 +interpolation in \ref interpkernel. It takes place of target mesh in +interpolation process and is initialized by the target mesh. + +DualMESH inherits from MEDMEM::MESH. It's API consists of only a +constructor with one argument of the input target MEDMEM::MESH. + +The dual mesh is a polygonal mesh in 2D space or polyhedral mesh in 3D space +consisting of dual cells built around each node of input target mesh. + +In 2D the dual cell is bound by edges connecting barycentres of cells +sharing the input node with middles of cell edges ending at the input node. + +In 3D the dual polyhedron is bound by triangle faces. Each triangle is built +on three following points: +- barycentre of a cell sharing the input node; +- barycentre of a face bounding the cell and sharing the input node; +- middle of an edge bounding the face and ending at the input node. + +\section DualMESHUsage DualMESH usage + +An exemple of DualMESH usage to perform P0->P1 interpolation with INTERP_KERNEL::Remapper : + +\code +... +std::string sourceFileName("source.med"); +MEDMEM::MESH med_source_mesh(MED_DRIVER,sourceFileName,"Source_Mesh"); +std::string targetFileName("target.med"); +MEDMEM::MESH med_target_mesh(MED_DRIVER,targetFileName,"Target_Mesh"); +FIELD sourceField(MED_DRIVER,sourceFileName,"Density",0,0); +FIELD targetField; +Remapper mapper; +mapper.prepare(med_source_mesh, DualMESH(med_target_mesh), "P0P1"); //<--- DualMESH +mapper.transfer(sourceField,targetField); +//use targetField +... +\endcode + +*/ diff --git a/doc/doxygen/extractor.dox b/doc/doxygen/extractor.dox new file mode 100644 index 000000000..386542713 --- /dev/null +++ b/doc/doxygen/extractor.dox @@ -0,0 +1,58 @@ +/*! +\page extractor Extractor + +MEDMEM::Extractor is a tool taking an input field and making a field +of lower dimension by cutting the given field by a plane or a +line. The following extractions are possible: +- 3D -> 2D (3D mesh cut by plane) +- 3D -> 1D (3D mesh cut by line) +- 2D -> 1D (2D mesh cut by line in 2D space or by plane in 3D space) + +The input field is supposed to comply with following conditions +- it is constant by element (i.e. has 1 gauss point), +- it's support mesh does not contain poly elements, +- volumic elements have planar faces, +- surfasic elements have linear edges. + +The result field is a field constant by element on triangles, +quadrangles, polygons or edges. It holds ownership of its +support, which in its turn holds ownership of its mesh. + +\section ExtractorAlgo1 Algorithm to cut mesh in 3D space by plane and in 2D by line + +-# Calculate a normal normalized vector to the plane in 3D space +or the line in 2D space. +-# For each node of input mesh calculate its distance to the +plane/line as scalar product of the normal vector and a vector +node -> coords (coords is the arg of extractPlane() and +extractLine()). The distance has a sign. +-# Store the distances of all nodes in a vector. +-# Analyse edges of each cell. If extremities of an edge have +different sign, we consider the edge to be cut by plane/line. If at +least one cut edge of the cell has intersection point not closer than +a certain precision from edge extremities, we consider the cell to be +cut and we make a new cell in the new mesh. Also we consider a cell to +be cut if 3D cell has three intersections at nodes and 2D cell has two +intersections at nodes. +-# Calculate an intersection points using ratio of node +distances. If the intersection point is too close to the edge +extremity, we take coordinates of a corresponding node. +-# Make new nodes of intersection points and set them in proper +order to make an element. For 2D elements we sort nodes by angle with the +first edge of the new element. + +\section ExtractorAlgo2 Algorithm to cut 3D mesh by the line +-# Use descending connectivity to find outer faces. Outer face is +bound to only one cell. +-# Find any outer face intersecting with the line. +-# Use the reverse descending connectivity or the reverse nodal +connectivity to get cells to try next intersection. +-# Find another intersected face among faces of the got cells and so on. +-# Try to find the next outer face intersecting with the line. This is +for the case if the input mesh has several domains. To avoid +unnecessary outer face-line intersection searches, we classify outer +faces along the line. So we won't try to intersect outer faces that +are between the first and the last intersected outer faces we have +already found. + +*/ diff --git a/doc/doxygen/field.dox b/doc/doxygen/field.dox new file mode 100644 index 000000000..c70616e1f --- /dev/null +++ b/doc/doxygen/field.dox @@ -0,0 +1,96 @@ + +/*! +\page field FIELD + +\section FIELD_introduction Introduction + +MEDMEM fields are used to represent variables over a particular +set of elements of the mesh. The region on which the variable is defined +is determined through a support object (which can be +retrieved by \a getSupport() +method). Each field has a number of components, that could + for instance be the different +coordinates of a vector. All these components have a name, a +description and a unit. Elements can also contain several +Gauss points, in which case, values are defined on each +Gauss point of the element. + +The fields can contain integer values or floating point values. +In C++, this is reflected by the fact that FIELD is a class template +that can be either a \c FIELD or \c FIELD. In Python, +two classes \c FIELDINT and \c FIELDDOUBLE exist. +In the present section, the methods of the FIELD template +will be described as methods of a class \c FIELD_ (from +which the template classes actually inherit). The template +parameter is \c T. + +In MEDMEM, a field is characterized by its name (\c getName) and an optional description (\c getDescription). + +It is also characterized by its computation time : + +- an iteration number (time step number) +- an order number (used if there are internal iterations inside a time step) +- the time that corresponds to this iteration number. + +By default, there are no iteration and order number defined (value +MED_NOPDT and MED_NONOR). + +\section field_interlacing Interlacing modes +As for the coordinates in the mesh definition, there are two ways to store +fields : one consists in interlacing the different components, + grouping the data elementwise (MED_FULL_INTERLACE mode), the other one consists in grouping the data componentwise (MED_NO_INTERLACE). + +The situation is further complicated by the introduction of Gauss points. +If the field is defined on several Gauss points, the MEDMEM convention +is that the Gauss points are always grouped together. Let us denote +\f$V_{ijk}\f$ the value of the field on the \f$i\f$-th element, for the \f$j\f$-th component +on its \f$k\f$-th Gauss point. In {\c MED_FULL_INTERLACE, +elements are nested in a \f$ijk\f$ order, while in \c MED_NO_INTERLACE +elements are nested in \f$jik\f$ order. \\ + +For instance, \c MED_FULL_INTERLACE will result in the following ordering (for four Gauss points and two components): +\f$V_{111} V_{112} V_{113} V_{114} V_{121} V_{122} V_{123} V_{124} V_{211} V_{212} ... \f$ + +\c MED_NO_INTERLACE will result in the following ordering : +\f$ V_{111} V_{112} V_{113} V_{114} V_{211} V_{212} V_{213} V_{214} V_{311} V_{312} ... V_{121} V_{122} V_{123} \f$ + +In this document, only the methods enabling the retrieval of +values on fields defined on several Gauss points are presented. +For further information on defining the location of the Gauss points +in a reference element, +the reader should consult MED file Web Page : https://hammi.extra.cea.fr/static/MED/web_med/ + +\section field_outline Outline + +The following sections describe the FIELD methods : +- This section describes how to create a FIELD lying on a support and +fill it : \ref FIELD_getset +- This section describes I/O methods :\ref FIELD_io +- This section details methods for setting and accessing the values: \ref FIELD_value +- This section details arithmetic operations performed on fields : +\ref FIELD_algo, +- This section treats the specific case of fields with several Gauss +points : \ref FIELD_gauss. + +\subsection field_io_example Example for I/O routines +This program gives an example of creation +of a file containing a mesh and fields. This program +is a tool that reads a mesh in an input file, creates a field +with the inverse of the cell volume, and creates an output file +with the mesh and the field. + + The reader should note that the mesh name + passed as an argument to the +\c addDriver() method has to be coherent with the +mesh name (as obtained by \c getName() ). +\verbinclude FIELDwrite.cxx + + +\subsection FIELD_example Example +The following example reviews most of the notions seen +in this section. +\verbinclude FIELDgeneral.cxx + + +*/ + diff --git a/doc/doxygen/figures/MED.png b/doc/doxygen/figures/MED.png new file mode 100644 index 000000000..6ba6047e0 Binary files /dev/null and b/doc/doxygen/figures/MED.png differ diff --git a/doc/doxygen/figures/MED_small.eps b/doc/doxygen/figures/MED_small.eps new file mode 100644 index 000000000..bf0b75825 --- /dev/null +++ b/doc/doxygen/figures/MED_small.eps @@ -0,0 +1,13779 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: (ImageMagick) +%%Title: (MED_small.eps) +%%CreationDate: (Fri Nov 30 12:59:05 2007) +%%BoundingBox: 0 0 500 324 +%%HiResBoundingBox: 0 0 500 324 +%%DocumentData: Clean7Bit +%%LanguageLevel: 1 +%%Pages: 1 +%%EndComments + +%%BeginDefaults +%%EndDefaults + +%%BeginProlog +% +% Display a color image. The image is displayed in color on +% Postscript viewers or printers that support color, otherwise +% it is displayed as grayscale. +% +/DirectClassPacket +{ + % + % Get a DirectClass packet. + % + % Parameters: + % red. + % green. + % blue. + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + compression 0 eq + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/DirectClassImage +{ + % + % Display a DirectClass image. + % + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { DirectClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayDirectClassPacket } image + } ifelse +} bind def + +/GrayDirectClassPacket +{ + % + % Get a DirectClass packet; convert to grayscale. + % + % Parameters: + % red + % green + % blue + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 eq + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/GrayPseudoClassPacket +{ + % + % Get a PseudoClass packet; convert to grayscale. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 eq + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassPacket +{ + % + % Get a PseudoClass packet. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + compression 0 eq + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassImage +{ + % + % Display a PseudoClass image. + % + % Parameters: + % class: 0-PseudoClass or 1-Grayscale. + % + currentfile buffer readline pop + token pop /class exch def pop + class 0 gt + { + currentfile buffer readline pop + token pop /depth exch def pop + /grays columns 8 add depth sub depth mul 8 idiv string def + columns rows depth + [ + columns 0 0 + rows neg 0 rows + ] + { currentfile grays readhexstring pop } image + } + { + % + % Parameters: + % colors: number of colors in the colormap. + % colormap: red, green, blue color packets. + % + currentfile buffer readline pop + token pop /colors exch def pop + /colors colors 3 mul def + /colormap colors string def + currentfile colormap readhexstring pop pop + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { PseudoClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayPseudoClassPacket } image + } ifelse + } ifelse +} bind def + +/DisplayImage +{ + % + % Display a DirectClass or PseudoClass image. + % + % Parameters: + % x & y translation. + % x & y scale. + % label pointsize. + % image label. + % image columns & rows. + % class: 0-DirectClass or 1-PseudoClass. + % compression: 0-none or 1-RunlengthEncoded. + % hex color packets. + % + gsave + /buffer 512 string def + /byte 1 string def + /color_packet 3 string def + /pixels 768 string def + + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + x y translate + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + currentfile buffer readline pop + token pop /pointsize exch def pop + /Times-Roman findfont pointsize scalefont setfont + x y scale + currentfile buffer readline pop + token pop /columns exch def + token pop /rows exch def pop + currentfile buffer readline pop + token pop /class exch def pop + currentfile buffer readline pop + token pop /compression exch def pop + class 0 gt { PseudoClassImage } { DirectClassImage } ifelse + grestore +} bind def +%%EndProlog +%%Page: 1 1 +%%PageBoundingBox: 0 0 500 324 +userdict begin +DisplayImage +0 0 +500 324 +12.000000 +500 324 +0 +0 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000030000000000370000 +760000000000010000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000030000000000350000780000050000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000050000 +0000003700007A0000010000010000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000030000000000340000790000030000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000080000630000720000070000000000010000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000100000000000900007500005D0000 +070000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000100000000000600007C00002E0000000000030000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000010000020000 +7C0000310000000000040000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000100000000000700007D0000310000000000030000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000010000 +0000000700007C00002D0000000000030000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000100000300007B0000300000000000 +030000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000100000000000600007C0000320000000000030000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000100000000000700007D0000 +2F0000000000030000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000200000000000500007C00002F0000000000030000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000020000000000 +0400007C0000320000000000030000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000010101040404040404040404000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000200000000002C00007B0000310000000000030000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000020202010102 +000000000000000000000000000000000000000000000000000000010102030302020202 +020202020202000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0300000000004600008B0000280000000000030000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000101010303030202020000002B2C2B7273716565646E6F6D +0D0E0D000000000100000000000000000000000000000000000000000000030303030304 +030303030303040304020202000000010101010101010101000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000400000000004B00006A0000000000 +000000020000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000010101040404 +0000000000003030287E7F8D827DB2B2ADD18170825A4F9E938FB0A29DA19F9AA49F999F +A39FB664667C42443B494B48484946484A46080807000000000000000000000000000000 +000000000000000000000000010101050505040404040404040404040404000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000400000000004F00006A0000000000040000010000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000303030000000000000304032527248685868682B54A3C7B +0D002B6453706F687D09001F3018442E17432D1643311941200B4B5B4E8B8F8194847792 +867893867893908D93929193929094908E909998A34A4C551D1F18262825242522272924 +1A1A10000000000000000000000000000000000000000000000000000000010101030303 +030303030303030303030303000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000300000000004F0000 +680000000000030000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000020202010102 +020200020300242523838284978DA0503B621E073B260E3529133C4B395D8F859B2F1943 +2C16402C17402C17402C16402F193E230B3118012F1A03301A022F1A022F3F2953453059 +442E584731543723667067A4A298A2988EA39990A19B91AB8281B8767770787879777777 +7A7B7A6D6E70080A08070805070806080906040504000000000000000000000000000000 +030303030303030203030303020203010102010101010101010101010101000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000300000000004C0000690000000000020000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000003030303030300000011110D5C5E609897B5948A98533F67 +1D0533250F392F19412E1843301B441C0431998FA338244B29123D2D17412C17412D1740 +2C16412E1943301B44301A44301A44301A4428123C26103B27113B26103B281238220A31 +1B03321D05321E06331700302E1A586653755F4C70604D73604C6C584DA19D99ACA19BA5 +9F99A5A6A0AC8682884F514D575855555653595B5851524B000000000000000000000000 +000000000000000000000000000000000000020202050505040404040404040404030303 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000040000 +0000004E00006A0000000000020000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000020202040404010101 +0000001415115B5D609292B3675C9A23104C250D38210B37301B442D17412C16412D1741 +2E1842240D396758777D708A1F08342F1A432C16402D17412D17412D17412D17412D1741 +2D17412C17412D17412D17412D17412D17412C17412F1944301B44301B44301A44311C44 +2C163B1F0834200A35200935200935210A3327103C27103D29113E210937463158847592 +7E6E8C796989766581584FA3A8A8B0B9BAB7A09EA3A3A1A19493A744474E2D2F28323431 +30322F363831191911000000010100000000000000000000000000000000000000000000 +000000030303040404040404040404040404010101000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000300000000004F0000690000000000030000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000202020101020000000101010809076263629A949B6B5E9324114E +1E062F30193E2E18422E18422C16402D16412D16412D17412D1741240E3948355A988DA2 +1D0633301B442D17412D17412D17412D17412D17412D16412D16412D17412D17412D1741 +2D17412D16412D16412D16412D17412D17412D17412C16402D17422E18422E18422E1842 +2E18422E18432E18422E18412E1842311C4429123D16012C0C022326103A432F538D839D +ACA0B47C6D8A432D58B1A5B12C1B677C71A0998D9E92869E94889A9085AE7F7FB183837B +83838581818189898966676E0B0C0913141111131012130E141404010100000000000000 +000000000000000001010101010101010101010002010102020202020202020202020202 +020202000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000300000000004D0000680000000000020000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000010101040404010101 +0000004243406869679A94A071607F2E18441E052E2E183E2F1A432C16412D17402C1741 +2D16412D16412D16412D16412D17412F1A43200935948A9F513F62220B372E18422D1741 +2D17412D17412D16412D16412D16412D16412D17412D17412D16412D16412D16412D1641 +2D16412D17412D17412D16412D16412D16412D16412D17412C16402D17412D1741301B44 +2E1842200835260F3A3C2950897C94AAA0B192869C544263331E451C053119012E7C708A +6F61770D001F1C05331B03301C04301400303522585B476A544067564368503C65574EA2 +A49DA99E96A6A098A49E97AF8C8ED966676B62635F6364626162606B6C671F201E000000 +010101000000000000000000000000000000000000000000000000040404040404040404 +040404040405030303000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000600000000004C00006A0000 +000000020000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000202020303030000000404033739378B8C9D7670AB6D5C832C1640 +1F07342B153F301A442C16412D17402C16412D17412D17412D16412D16412D16412D1641 +2C1640301A441C043281758D685977220A372E18422D17412D17412D17412D16412D1641 +2D16412D16412D17412D17412D16412D16412D16412D16412D16412D17412D17412D1641 +2D16412D16412D17412C1640301B442A133E260F3A1C053227103B655674A49BAD9F95A9 +675876250E39210A36220B372A143E301A442F194320093581769063547429123D331D46 +301A44321C442A133A210A36230C37220C37230C37240C33220A38220A38230B3620093D +1606636B5B7F74648272618274637E5751C78682B2A4A09FA19DA79994989593B75F5F82 +282923393A392E2F2F3F413A3A3A2D000000000000000000000000000000000000000000 +000000000000000000000000040404040404040404040404040404010101000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000100000300000000004F00006A0000000000030000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000010101020202000000000000 +0505043435328F8E918D829937286C2008351B04312D18412F19422D17412C16402D1741 +2D16412D17412D17412D17412D17412D16412D16412D16412D17412C16402B153F331D46 +A59BAD260F3A2E18422D17412D17412D17412D16412D16412D16412D17412D17412D1741 +2D17412D16412D16412D16412D17412D17412D17412C16402D1741301A432D17412D1741 +1A023037224A4A365A94889EA095A8877B9338234B2A143E1E06332F19432F19432E1841 +2D17412C16402D17412D1741250E3AB2A9B92C164029133E2E18422C16402D17412E1841 +2E18412E18412D18412E18432F1A432F19432F1943301A41321B391E07321C04311E0733 +2009341B04332C15412B13401C0334442E4F433587C1C1FBFFFFFFBAB4C5F8F6F2988FBF +7170D68E8D8C8C8B8E8D8B8C8788968C8EA76D6F7E1618131D1F1D1E1F1721200F1F1F0F +020201000000000000000000000000000000000000000000000001000001000001020202 +030303030303030303030303010101000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000020000000000140000 +8D0000600000000000030000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000303030101020303010000003839378B8A8E90849B442E571C0531 +2A12372F19422F19432D17412C16402D17412D17412D17412D17412D17412D17412D1741 +2D17412D17412D17412D17412D17412D17412A133E38234BA499AC220B372F19432C1640 +2D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D1741 +2C16402D17412D17412F1A432B153F1B033129133D2E19427769859D92A5A097A9544264 +3E29501B02302A143E2D17412F19432D17412C16402D17412D17412D17412C16402E1842 +27103C4E3B5E94879D28113C2A133E2D18412C16402D17412D17412D17412D17412D1741 +2D17412D17412C16402D17412D1743301B44341E4727103B1D063329133D29133D5C4B6B +8F839995899FACA3AA867887230C3949375A998FA10900271E0A484C375E4A355F4D3758 +3D2F892B23AB4C43A4A39AA69D93A19691B68789E58889DC7172776F706C70706F6D6E6F +77787A232523000000040503050500060500070700010100000000000000000000000000 +010101030303030304030304030304030303010101010101010101010101000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000100000000001300007F0000290000030000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000040404020202000000 +202018656772A2A1B6887B8E48335D1A033027113B301A442D17422C16402D17412D1741 +2D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D1741 +2D17412D17412F194220093583768E6858761E07342F19432C17402D17412D17412D1741 +2D17412D17412D17412D17412D17412C16402D17412C16402F19432D1741240D381E0633 +37224A6C5C7A8E839AAEA6B5736682331D4619012F250F3A28113C301B442D17412C1640 +2D17412D17412D17412D17412D17412D17412D17412C16402F19431F08345542648F8298 +2A133E2D18412D17412D17412D17412D17412C16402D17412C16402E1842311C4529133D +230C38240D391A0230503E61756682C3BDC9AEA7B6867890625171311B4417002F1F0837 +2C1640250E3990859C53416228103726103A250F39250F3A27103429112F260E311D0635 +1F07321B053F110059150357614F766A577765547D4F4AC24843CA8A86B2A9A5A698929B +8B8BBB8788C78A8AC94C4D5847484146474240413E57584A24241F000000010101000000 +000000000000000000000000000000000000020202050505040404040404040405030303 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000020000 +0000001700008200001C0000000000030000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000001010103030300000000000017191772726C8F8DB45B4E8D210C46260E37 +230D38311B452D17412D17412C16402D17412D17412D17412D17412D17412D17412D1741 +2D17412D17412D17412D17412D17412D17412D17412D17412D17412C1740301A431C0432 +6E607C7F718A1F07342F19432D17412D17412D17412D17412D17412D17412D17412C1640 +2D1741301A432E18422B153F2008352A133E503D60756681CCC7D1AAA1B2443157250E39 +210A362A143E311C452D17412D17412D17412D17412D17412D17412D17412D17412D1741 +2D17412D17412D17412D17412C1640331D4614002A8C80976A5B791A022F301A432C1640 +2C16402E1842301B442E18422B143F230C3816002C3A254C4E3B5F6D5F7CADA6B58A7F96 +83758E695977250E39260F3A1D06332C1640311C452F1943311C4519012F8C7F975C4B6C +210A362F19422D17412D17412D17422C17432D1843301A43301A44311B41331C3A341D3D +240D372009351B04301D053017042A15002B1A01324C375943368A41379C8582D9F5F4FF +A399BAAFADE4E1E0F75957DE8381B798968F8E8EA98A8DAD9395B58E909221231F2C2D23 +2C2C1A30301E13130C000000000000000000000000000000000000000000000000000000 +000000030303030303030303030303020202000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000020000000000170000820000180000000000 +020000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0302036A696B9E96A5675476271143210934331C422F1943301A432E18422E18422E1842 +2D17412C16402D17412D17412D17412D17412D16412D16412D16412D17412D17412D1741 +2D17412D16412D16412D17412D17412D17412C16402E184227103BA499AC2F1A432B153F +2C16402D17412D17412D16412C16412D16402E18422E19422E18421B0431230C38321C45 +5F4F6F9C91A49E93A76B5B78311C451E0633250E3A2F19432E18422D17412C16402D1741 +2D16412D17412D17412D17412D17412D17412D16412D16412D17412D17412D17412D1741 +2D17412C16402F19432B153F8E849B4C3A5E27113C301A43311C45260F3B1A0230250E39 +321C45655473978DA1CFCAD4A399AC75678239254C2A143E17002D2109362E19422E1841 +2F19422D17412C16402D1741301B441B033190849B5C4A6B210A362E18422D16412D1641 +2D17412C16402E18422E18422E18422E18422F1A45240D3A1A0330240D383C284F341F48 +5240639A90A391879C978CA29D909B988C9347324A341F440B002584799657466906002D +2F194B462F532F2188291F9C271C989186AD9E929C8D87C18081E58383E97E7FA97B7B73 +7B7C7F77798180818A5C5D620304020E0E060E0D000F0F00060500000000000000000000 +000000010101040404030303040404020203030303020202010101010101020202010101 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000100000000001400008200001A0000000000020000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000101010000001111126D706BF0F5EA8A7E9315022A17032B +240E35251138220C36230A38230A39230A39230A39220A382E1842311B45301B44301B44 +311B442F19422D17412D17412D17412D17412D17412C16402D17412D16412D16412D1641 +2D17412D17412C16402E1942240D3990839A52406226103B2D18412D17412D17412D1741 +2D1741301B44230B3820093529123D72637F82768FADA4B5857A92422E5418002E230C38 +2A143E2F19432E18422C16402D17412D17412D17412D17412D17412D17412D17412D1741 +2D17412E1842311B44301B44301B44301B44301B44301B44301A44311C4527113C1D0633 +200E35A59DAF250F3A210A3613002948355A72647F84778FB3ABBA85768F5847684B395C +1C0532240D392D17412F1942311B442F1A432D17412D17412D17412D17412D17412D1741 +301B441B033090849B574567210A362E19422D17412F1A43301B44311B44240D38200835 +230C3828113C1E07345442657E718A82748DA79DAFAAA1B293869C544264594869220B37 +1902311C043428113F230C394B385B9A90A3240D38341E432C163E26103C2A13332B1330 +2B14311B042F1C042F17023F1301500C004A3B296064506D56457D433CBE3D36BB5B54B6 +A9A1A19694C09092DB8D8FD9C4C6E06D6F66575956504F4955544E393934000000010101 +000000000000000000000000000000000000000000010101040404040404040404040405 +020202000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000020000000000150000820000 +1C0000000000020000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +040404000000575954FFF8FFA06AD7AA88CBB4A6C0B5A5C5B2A2C1B6A6C5A797B554465F +554861554860544760574A6225103919012F1C05311C05311A022F2109372A133F29113E +29123E29113E2F1943301B44301A44301A44301B442E18422C16402D17412D17412E1842 +210A37534264877B9218002E311B442E1942311B4429133D260F3A1D05325240626B5B78 +A69CAE7C6F89645473200935250E3929133D352048321C45301A44301B44301A44301B44 +2F194328123D27113C27113C27113C27113C27113C27113C28123D230C371B03311C0532 +1C04321C04321C04321C04321D063318002E4734595F4F6F4735598C7F9593879C6F617E +E2DFE5E7E4E9ADA4B45747670E002414012A10002716002C2109361F08341A022F210A36 +29123D27113C27113C27113C27113C27113C27113C2D1741341F47200935887A92695876 +250E392C164028123D1E07341C04321A02305341635948687E728CACA3B4AAA0B28A7F96 +766883675775200935250E3A230C38210A37220B372F1943311B44301A442E1842240D39 +503E61968CA01B0330301B442D17412D17412C16432C16432C1643301A44301B44311B41 +321C3C341D3E2912391F0835240E37260F33260F33250E36230A3417044D120169000057 +392D676F5B746A5E938B8DFF9092FF9899E8BFBFB7C9CBCACED0C99B9CBFA8AAB940423C +34352F3939293C3C2C1C1C1A000000000000000000000000000000000000000000000000 +000000030303040404040404040404030303000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000200000000001700008200001A0000000000020000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000040304000000585855B78BE5 +8E55C67A31C29150D28C4ACF8D4BCF8B48CE9355D2C09DE3BF9CE3BF9CE3BF9CE2C19DE5 +A393B19B90A49D91A89A8DA5A89EB06C60753120413C2C4B3A2A493B2B4A2009351A0231 +1C04321C04321A0230260F3B2F19432D17422E17422E18432B143F3C284F978A9F39244C +2D1841250E391B03303A254D4B395D9A8EA3968B9F83768E331D461D06331F0835311C45 +26103B1A02301B03311B03301B03301B03301B03301A02301E06333C274E422E54402D53 +412D53412D53412D53422F543A254C665776A298AB998EA29B90A49A8FA49B90A49C92A6 +9C91A5978BA18478919D93A6C2BCC7EDECEF9B91A4CBC4CF93889D887C93AFA6B6A9A0B2 +978CA19D92A69C91A59C91A59B90A4988CA1A89EB06D5C7A38234B432F54412D53412D53 +412D53412D53412E5329123D1B03311A0230220C379E95A816002C321D463A264D877A92 +9F95A99A8FA492869B9990A36656752F19433B274E2A133E19012F2009352F1A432E1942 +2E19422E18422E18422D17412C16402D17412D1841240D39503E60998EA21C0532301B44 +2D17412D16412D16412D17412C16402E18422F19422E19432F19442D17422D17422F1A43 +2009351B03321B03322009363E2A51473251402A43978A939B8F9E7F728CABA2B3A9A2B9 +5A4B71B2AABDFAFAFA968AA3A599A933288E6559999D919B8A80AD7676E48181E8CACAD6 +81807E8887897E808F92939F4749450B0C09161816191A0C0E0D05000000000000000000 +000000000000000001000001000000000002020202020202020202020202020202000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000010000000000 +160000820000180000000000020000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000010001000000190F249467C3B895DCA272D37933BF8241C3 +803EC2803EC27F3CC27730BF7830BF7830BF7830BF762EBE975AD49F64DA9E62D99A5DD7 +AB75E0D2BBE9BEA5D8C2A9DBC1A8DBC3A9DD897C957D72858075897D7287877D8F4B3C5A +200C3329153B2713392814392A153D0A00238C849749355B0E00265745687E708A968CA1 +9E94A8503E612008351B03312B153F2F1943301A44240D395441638B7F9682758E84768F +84768F84768F8578917C6E88A59CAEC7C2CC9A91A4A49BACA299ABA299ABA299ABA197AA +A9A1B17D718A473358503D604E3C5F503E614E3C5F412D534733586353728B7E9590859A +7C6E88311C451F083591869D23153815002B2C1540503D604E3B5F4E3B5F4E3B5F4E3B5F +4F3D60483459675876B4ADBB9E95A8A39AACA299ABA299ABA39AACA097A9B4ACBAC3BDC9 +6B5B797E708A8B7F96C4BEC98B7F96FAFAFBADA6B55F4E6D48355A503D611F0A35080020 +15022B1E05331C0431200835321D45321D46301A43301A43301A442E18422D17412D1741 +2D17412D17412D1741240D3949375B998FA21D0532311C452D17412E1942301B44301A43 +301B44230C381E06331F08341D063328113C2D174127103B70627E8A7D957A6C87AAA1B2 +C5BFCA9A90A5A69DB1A79FB24E3B605544654532572D17407768827A6A832F194219012E +16002D2B1332210A3019012E1902351300471200433E2A54554065523E66332AA45952B7 +B5ADB69A92A4A39AA38A88CBC0C2EC7E7F756162626768666D6E6B4F4F4E000000010101 +000000000000000000000000000000000000000000030303040404040304040404040404 +000000000000000000010101000000000000000000000000000000000000000000000000 +0000000000000000000000000000000200000000001200008200001B0000000000020000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000020102000000A99DB4823FC6A374D18442C67F3BC38342C58240C48341C58544C6 +8544C68544C68544C58544C67D3AC17C38BF7C38C07C39C07A36BF7931C07E37C47D36C4 +7D36C47C34C3A771DCB07FE2AE7CE0AF7DE0AE78E2B496D4BAABC8B9A7CBB8A7C9BFADD0 +9F90AF54485F877D8D9E94A5BEBCBFB9B5BE8E8298695A768E839790869AA49AADA69CB0 +A298ACA298ACA399ADB1AAB992869B69597870617E6D5D7B6B5B796B5B796B5B796B5B79 +6D5D7B351F481B04312109362008352008352008352008351F0835210A36260F3A27103B +1E063318002E210B366252719E95A793899F61507027103B230D392B153F2A143E3B274E +ACA4B527103C2E1842240D39240D39240D39240D39240D39240D39250E3A210A361C0431 +2109361F0835200935240D391C043217002D0F0025695977C2BAC7FBFCFCADA4B4B1A7B7 +7767835B4A6B968CA0A097A99F96A8A39AAC9B91A46858766A5A78675775685876665574 +240D391D05331F07341F07341E0733230C38250F3A250E3A250E3A250F3A311B4527113C +6251708D81971A023027113C260F3B2009351C05312008351C04315241636D5D7A5D4C6D +92869CC1BBC7A299ABACA4B4C1BAC66858766B5C796C5D7A321C461C0431210A361D0532 +1E0633100027635271AAA2B36F607D2E184227113C311B45311B442C17432E1943311B44 +311B43321C3E321C3F28113B230C37230D38270F31220A2E1C0432210A38230B34110050 +3A296974627E6D5C80715E7863569EBBB8DCA19D9E9E9AA49A959CACACCC888B89373834 +4647444446423F403E070707000000000000000000000000000000000000000000000000 +020202050505040404040404040404010101000000000000000000000000000000000000 +0300000000001700008200001B0000000000020000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000020102000000A99EB3 +8240C68D59C3BF9EE08545C68240C48341C58341C58341C58341C58341C58341C58240C4 +8341C58341C58341C58341C58342C58444C58443C58443C58443C58443C57A35BF7832BE +7833BE7933BE7731BD813DC68945CD8743CB8845CC843FCA965AD2C099E6B68DDEE2D1F2 +B88CE3DDCAEFFAF9FCE7E2EBA599B1A99EB54F415D42324F4535524738543C2B4B1B0231 +15022C0B00230B002215022C1F06351D05331E05341D05342008352D1841331E47321D46 +321C452F1A432F1A43301A44321D462E1942260F3B210936463257665776A69CAD83758E +35204829133E1F08342F1A432F19432D1741301A432009367D6E886A5A77240D39301A44 +2D17412D18412D18412D18412D18412D17412E1842321C45321D462F19432C16401D0532 +3A264D5D4C6DA79FB0877C947D6F8A422F5508001F6A5B786F617E120028321D462F1A43 +2F1A432A133E4430558C8097867991877A92877A92887B93A095A8A198AAA097A99F96A8 +A79FAF6656744431564D3A5D4E3B5F4B385C1F07340B00229A90A429163D351F484F3D60 +412D53756782B1A9B89C92A5A49BADD0CBD484768F8679928D819845325728123C301A43 +220B371D06331E07331D06332C1640331E472D184129123D4E3C5FA299AB7C6D87260F3B +1F08352D17412E18422C16402D17412D17412C17412D17402C16412C16412C16412D1741 +2D18412D18412D17432E1843301A432F1A432F1944331C3D2912371C05321D06321D0632 +1C0531220B37311A463019462D16403121718B7D9A897B948B7D977F708CBDB5C6ABABAB +88878A8F8E919391948F908E1E201C21221F20221F20221F080808000000000000000000 +0000000101010000000000000000000000000303030103030403032B03038203031A0202 +000000020000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000020103000000ABA0B48A4BCA712FB59866CA9F6CD2 +7932C08544C58240C48341C58340C58340C58340C58341C58341C58341C58340C58340C5 +8340C58340C58341C58341C58341C58240C48442C58443C58443C58443C58443C58241C4 +8140C38140C38140C38241C37F3DC27229BC9157CBE0D0EF9158CA7A34C0894AC7894AC9 +985AD69658D5BD9BDEC3A6DFC1A3DEC4A5E2B79CCF887E908C82968B8195958C9E5C4E6A +281539321F42301D40301E41230C391E06351E06341E0534210837301A44311B452D1741 +210A372F19434B385B948A9FA298AB83768F37234A1B04312B153F2D17412F19432D1741 +2C16402D17412C1640301A4319022FAAA1B2422E54230C382E18422C16402D17412C1640 +2D17412D1841301A44250E3A1B03312D17413C274E93889DD6D2DA897C9445325737224A +18002E29133D321C4528123DA79FAF38234A2B153F2C16402C16402D174128113C19012F +1B03301A03301A02301B0431412D534531564430554532573E2A5083758EA69DAF988DA2 +8B7F968D8198948A9F8C8097CBC5CF988EA3D2CED69A8FA49A8FA4ABA2B35F4E6E3D294F +4734592F1A4318002E1B033119012F27113C2D17412C16402E18422F19432F1942311B44 +2D17411E06332A143E7D6E889E94A748355A250E392C16402F19432D17412C16402D1741 +2D16412D16412D16412D17412D17412D17412D16412D16412D16412D16412D17412D1741 +2D17412C16412D17402C16412D18422F19432F19432F19432F19432E18422C163F2C163F +2C17402C14371A022F1A02301A033018002E230D3846315949345C4A355D422D56988BA3 +A39AAB9D93A5998FA1B1A9B9B6B5B65857596867696463646F6E6F191919000000040503 +0405030405030100000000004B00007A00000C0000000000050303020303030303030303 +030303020202010101010101010101010101010101000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000002010200000082758D813EC57E42BC722EB7AB83D69D68D17D39C28442C58240C4 +8340C58340C58340C58340C58341C58341C58340C58340C58340C58340C58341C58341C5 +8341C58340C58340C58340C58340C58341C58341C58341C58340C58340C58341C58240C4 +8545C67B35C1BF9EE19A64D0C7A9E5803CC38240C4803DC37D3AC07E3BC17B34C17A33C2 +7B34C27830C08440C8AB76DFA872DEA974DEA66EDFB38ED8BFADD0BDA7D2BDA8D1C1ABD5 +7B6E86685D716C61766E647861556C1F09331A012F28123D6D5F789E93A791839C4C395E +15002C17012E220A38341F48311B44301B44301B44311B442F1A432C16402D17412E1842 +28113C4735598C82992D18412D17412D17412E1842321C4529123D230C381D05324F3C5F +766782A196A9A297AA635372412D531A023027113C2A143E311C452E18412E1842200936 +6A59777F718B1A0230311B442C16402C16402D1741301B44301A44301A44301B44301A44 +27113C27113C2B143F2B143F1F083516012D0D00242D1B41675876655573DBD7DEBCB5C2 +695A77B0A9B8321D451C05321E07341A0330230C3728113C260F3B2B153F311B44301A44 +301B442D18412C16402D17412D17412C16402F1943220B372B153F71637FA9A0B2695876 +16002D27113C2E18422D17412C16402D17412D17412D16412D16412D16412D16412D1641 +2D17412D17412D16412D16412D16412D16412D17412D17412D17412D16412D16412D1641 +2D16412D17412D17412D16412D17412C16402D17412D17412D17402D1742301B44341E47 +341F47341F47321D4626103B1B03301C05311C053211002712002913002A14002B0E0026 +756683B3A9BC9E92A9988CA4C1B8C7FBFDF8B4B1B8B6B2B8AFAAB399929C46545086524F +A7534F33524E535653434240000000000000000000000000000000000000000000000000 +000000000000000000040404040404040404040404040404030304000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000101020000002A2A2A +A87CD77433B77E41BD7D40BCBA99DD8848C8803DC38342C58240C48340C58340C58340C5 +8341C58341C58340C58340C58340C58340C58341C58341C58341C58340C58340C58340C5 +8340C58341C58341C58340C58340C58340C58340C58341C58442C57D38C2C3A3E38C4FC9 +AF83D9A373D47A34C18544C58341C58341C58443C58444C58443C58544C68240C47934BE +7A35BF7A35BF7934BE7E39C4843EC9833DC8833EC9813AC7AE7EDEBA90E4B78CE3B88CE5 +B68EDEAFA1BCB8B0BECBC7D0FFF6FF8677903C2E4A45355251445D52455E4636531A012F +1B04311B03311B03311A02301F08352B14402A133F2A133F2F184314002B887A93776883 +1A0230331E4628113C15002B3C284E5645678D8299D3CED7887D94331D46230D39200835 +27113C311B442D17412D17412C16402D17412E1842250F3A463257D5D0D9341F482A143E +2D17412D16412D17412D17412D17412C16402F1943301A432B153F250F3A1A022F1B0331 +4A375B615271ABA2B39A90A57E728B7E708A210A3619012F250E3A84758E4834592C1640 +311C45301B442E18422D17412D17412D17412C16402D17412D16412D16412D17412C1640 +2F1A432D1741220B374633588C7E9581748D2E1842220B37311B442D17412D17412C1640 +2D17412D17412D17412D16412D16412D16412D16412D16412D17412D17412D16412D1641 +2D16412D16412D17412D17412D17412D16412D16412D16412D17412C16402F1943301A44 +301A43301B442B153F28123D29133D29133D29123D1C04321B03301C043118002E2A143E +594869554465524063645473AAA1B3AAA0B2AAA0B2A99FB17C6D876B5C78968CA0C1BAC5 +F2F1F29C90A5321C4780728D6F607E1D05338374907E718E75718D84728E80708D847890 +9796999694999794999592979E9BA07574752527232F302D2D2E2B2E302D2B2C22010100 +000000000000000000000000000000000000000000000000000000000000030303040404 +030303030303040404030303000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000020202000000373C31BB98E1702DB57F43BE7A3ABB +7F40BEAD81D87D38C28341C58341C58341C58340C58341C58341C58341C58341C58340C5 +8340C58341C58341C58341C58341C58341C58340C58340C58341C58341C58341C58341C5 +8340C58340C58340C58342C57C36C19E6BD1BF9CE17125BC9D69D1DAC6ED803CC38341C5 +8341C58341C58340C58340C58341C58240C48341C58442C58442C58442C58442C58342C4 +8241C48341C48241C48342C47933BF772FBE7731BE762FBD7B35C19252D2F8F3FCDFCCF3 +945DCE9E68D7C8ACE7C1A0E4C0A0E3C2A1E6BA9DD9958A9D968AA0968A9F94899E9C91A5 +7A6E862E1C3E36254535234435244436254516002D81728C4D395E14002A4C395E9E93A8 +9489A09C92A6513F632D16411D05332D1741301B44301A44301A432E18422E18422D1741 +2C16402D17412D1741301B441C0532978DA1503E61250E392D17412C16402E18422E1942 +2E18422F19432009351C0432331E47524062A095A992879D988EA28B7F963C284F301B44 +19002E1C05322E1942311B4428123C352048B1A9B82009352D18412D17412D17412D1641 +2D17412D17412D17412D17412D17412C16402D1741301A431E073327103B635372A49BAD +523F6215002B2D17412E19422C16402D17412D16412D16412D17412D17412D17412D1741 +2D16412D16412D16412D17412D17412D17412D17412C16402D17412E19422E18422E1842 +2E19422E18422E18422E18422E18412F19432008351A02301C043219012F301A433D294F +3A264D3A264D3D284F8F8299978CA1958A9F968AA0948AA0958BA0958A9F9B91A4887D94 +3B264E341E47301A434633586455748B7D958D8198574566250E3A20093527103B27113C +8A7F9651406313002A1D05321C03301B033019012E210A373F29533D27513E28523F2953 +38214C5B486B9C93A694899E958BA0988C9D8783C07E7E867F7F7D7F7F7F7E7E7D838387 +686972090B070F100D0E0F0D0E0F0B121102020200000000000000000000000000000000 +010102010102010102010103010103010102020202020202010101000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000002020200000033382EB895DE712EB67F42BD7E40BD7838BAA379D0B58DDC7B36C1 +8443C58240C48341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58342C5 +7C37C19B66D0BE9BE07931C0813DC4CAAEE68B4EC9803DC48341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58240C4 +8443C58544C58443C58748C77931C0B28BD9CEB6E7955DCDB48CDC9864D07127BF7A35C3 +7932C27730C17F3BC6A36BDDA169DCA26ADCA26ADCA066DCAA7BDBC2AED9C0A8D9C0A9D9 +C1AADABEA8D670647B9991A0A096A99E95A4FFFFFF81758C210E341000241E0931230E36 +271339230B38210938220A38220A38220938220A382F1A43311B44301B44301B44311B45 +2A133E49365A9A90A41D0633331E47311C45230C381F0734250E3A220B3766557484778F +9D93A6B8B1BF8377904D3A5E250F3A1B033029133D2B153F301B44301A432D17412C1640 +2F1943250E396050707F738D230C382E18422C16402D17412D17412D17412D17412D1741 +2C1640311B4428113C1E0733675776A297A98478911B0331250E3A311C452D17412C1640 +2D17412D17412D17412D17412D17412D17412C17402D17412D17412D17412D17412D1741 +301A43301B44301A44311B442E18422008352009352009351F0835230C3828113C27113C +29123D220B3768587782748E7D6F897A6B86968CA1A89FB0A49BADA59DAEA49AAC5C4A6B +53416455436558476846335818002E2008350F00261303291E0634432F54867B93A79FAF +82768F422E541B033026103B2D17412F19432F19422C1540240D39AFA6B7341F472C1740 +301B44301A43301A442E194228123C28123C28123C28123C29133D240D391A02301B0331 +1B03311A022E1B074357436C59456A58456C5C47654B3C844E49B5A49DA59F99A7A19AA5 +9E99AB8F91D764656C5D5E595F605E5E5F5D61625C595A54030302000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000020202000000353A2F +BA97E0702DB57F42BE7C3EBC7E41BD6F2BB6AE85D6B289DB762EBF8645C68240C48341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58342C57C37C2A575D5B58EDC7A33C1 +7E38C2A06DD2B892DD7831C08544C68240C48341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58240C48442C57E3AC3 +9C67D0B690DD8D50C9C3A3E3782FBFC9ACE6955ECF7F3DC58647C88545C88343C67B37C1 +7B38C17B38C17B38C17B37C17C38C37F3AC87F3AC87F3AC87E39C7813DC9B282E3AE7FE0 +E9DCF4D7C0EE9961D3A78FC1B4A6C2BAABCBB6A6C6B5A5C5B8A8C9685A73554860594C64 +584B63594C645649621F09341B03301C05311C05311B04301F09341B023291849B554365 +13002A1A02305A496A604F6F867890B5AEBC82748D6D5D7B2A133E1E06331F0734230C38 +2E1842301B442D17412D17412C16402D17412D17412D17412C16402F19431C0432A298AA +46325728123C2D17412D17412D17412D17412C16402F1943301A431A02303C274E80748D +887C943D284F1D0532301A442E19422C16402D17412D17412D17412D17412C16402F1943 +301B44301A44301B44301A4427113C26103B27103B27103B1E07341C05321D06331A0230 +27103C625171604F6F6150705A486A81738CAEA6B5A69DAFA79EAFAAA3B37E718B70607D +71627F796A853E2A501D0532240D39220B37220B37220B37220B37250E3A260F3A220B37 +2A143E210A365A486970617DADA5B4988DA15D4C6C200835230C3826103B321C452E1842 +2C16402D17412C16402F1943240D395D4B6B8B7D94210A362E18422C16402D17412D1741 +2D17412D17412D17412D17412C16402E1842311B44301B44301B44301B45301A3F220B36 +210B36220B36210B37220B34240C31240C3A240C39240C38220B3D1403626A5981796886 +7564857766815F59BF5F5CCE9A97A09D9A9E9B98A39092BC989BC68182A72A2A2830322E +222322000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000010150B7B5AA07E3BC27C3FBB7D3FBD +7D3FBD7C3DBC7E42BEC1A3E18C4FC97D39C28442C58240C48341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58342C57F3BC3CAAFE68645C6813EC48340C5803CC3C6A9E48D50C9 +7F3BC38342C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C57D38C2D1B9E98544C67C37C2CBB0E7 +7E39C39A63CFBE9CE17C38C38241C68342C78342C78343C78343C78343C78343C78343C7 +8343C78344C68343C68343C68444C68545C76F25BC9B67D1B48FDDAD85DA8648C88643CD +8D4CD28B49D08B49D08B4AD08A47D0B68DE1C09DE4BE99E3BE9AE3BF9AE4BD99E2A194AE +9F94AAA094AB9F94AAA398AE9589A13523435C4F6A8E8499796F83AAA5B0776886847690 +513D611A01302008361E05342E1843301A452F1944301A442F19432F19432F19432E1842 +2C16402D17412D17412D17412D17412E1842240D395441649B90A415002C311C452C1640 +2C16402D17412F1A43220B371F0835877C94A196A8695A7818002E29123D311C452F1943 +2F19432F19432E18422C16402C16402C16402E184221093619012F1B03301A02301B0331 +402C53453157443156412D538F8399A097A99C92A59E94A79990A48C80988D81988C7F96 +95899F6554732B153F341F48321D46341F47220B371B04311D06331B033129123D301B44 +2F19422F1943301B44301B442F1A43230B371A012F3C284E4E3C609C92A594879D7E708A +321C452A133E1F0734301B442E18422D17412C16402D17412D17412D17412D17412C1640 +2F19431C04326756758A7D931D0532301A442C16402D17412D17412D17412D17412D1741 +2D17412D17412D17412D17412D17412C16402C17412E18422E18422E18422E18422D1842 +2D18432F19422F19422F19432F1941321B391E07321B04311C05311C05311A04331C0636 +341D493620493520522215840C0074332885E0DFDEF1E6FDAFA8B7000000020202000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000404040000008A858E985CD47637B77D3FBD7C3EBC7E40BD7939BB8246BF +C3A3E38A4BC8813EC48341C58341C58341C58340C58340C58340C58340C58341C58341C5 +8341C58340C58340C58340C58340C58341C58341C58341C58340C58340C58240C48443C5 +7C36C1C9ACE58949C8813DC48442C57A33C1A574D4B48DDC7D38C28342C58341C58340C5 +8340C58341C58341C58341C58340C58340C58340C58340C58341C58341C58341C58341C5 +8240C48342C57D38C2B994DE9D68D17E3AC38442C5CBAFE68544C67A32C19E69D1BD99E0 +7D39C48241C68342C78241C68342C78342C78342C78342C68342C68342C68342C68342C7 +8342C78342C7803EC5B894E09C68D28748C9D1BAEB7832C18241C58140C48040C48040C4 +8140C47933C17730C17731C17731C17730C17933C2995DD89C61DA9B60DA9B60DA9A5DD9 +A16ADBC1A5DDC9B5DDE9E1F2EAD8FCC4B2D8756C7D6F627A786D82897F92433252271338 +2B173C29163B29153A2007361F07362007361E0635250D3A311B45301A44301A44301A44 +2E18422D17412F1943250E3A776A856C5D7B200935301A432F1A432D1741210A36594868 +9A91A56657762C1640210936341E47321C4527113C1C05321E07341D0532230C382F1943 +2D17412F1A4326103B6758768E8298867991877B92887C939F94A8A197AAA095A9A499AC +5947684734584B385C4C3A5D43305519012F1B03301B033019012F220B372C16402B143F +2B153F2B153F2E18422F1A432F19432F1A432D17412D17412D1741301B4426103B1D0633 +230C386556748C81979C92A6988DA24A385C1F07341C04312B15402D17412F19432C1640 +2D17412D16412D16412D16412D17412D17412D17412D17412C16402F1942230D389D94A8 +3F2B5228123D2E18422D17412D17412D17412D17412D17412D17412D16412D16412D1641 +2D17412D17412D17412D16412D16412D16412D16412D17412D17412D17412C16412D1740 +2C16412C16422F19432F1A432F19432F1A43301A422F1A422E184129133E1D05312D1732 +7A6C75B2A0B47851A19B7ABCC5BCCE191919000000010101000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000040404000000 +908D92985DD47637B77D3FBD7D3FBD7C3EBC7F43BE712EB7A67AD1B893DE762EBF8443C5 +8240C48240C48340C58340C58340C58340C58341C58341C58341C58340C58340C58340C5 +8340C58341C58341C58340C58340C58340C58443C57B35C1A676D5B48CDC7C35C18441C5 +823FC48340C5823EC4C4A5E37D38C28443C58240C48340C58340C58341C58341C58341C5 +8340C58340C58340C58340C58341C58341C58340C58341C58342C57F3BC3955CCDC5A6E3 +7831C08544C5813FC4CBAFE68442C58443C57931C09E6AD1BD99E07D39C48241C68342C7 +8241C68342C78342C68342C68342C68342C68342C68342C78241C68342C7813FC6C5A7E3 +7F3CC57E3BC5AB7ED8AB7ED87D39C48444C78241C68342C78241C68444C78545C78545C7 +8545C78545C88445C77D3BC27C3AC27C3AC27C3AC27C3AC27F3DC37126C1B58BDFB58DDC +AB7FD6823FC5B483E5B07DE3AF7CE1AB76E1B79CD2BBAACCBAA7CDBCA9CFB4A2C7665B71 +63586D63576D695E724D3E5B18012D1F09331E08321D0731230C38260E3C260E3B230B39 +28113DAFA5B62E19422A143E240D3927113C93889E8A7C94422F5415002B200936230C38 +2109361A022F412E5371637F6B5B7966577580728BADA4B5A79DAFA79DAFADA4B57D708A +635371685977685876665674250E391D05321F08341E0734240D39250E3A250E3A250E39 +27103B311B44301B44301B44311B442F19422C16402D17412D17412D17412D17412D1741 +2C16402D1741321C452A143F250E3A1B033049365A6F607C988BA0C7C1CD72637F27113C +1D0532260F3A2F1943301A442C16402D17412C16402D17412D16412D16412D16412D1641 +2D17412D17412D16412D16412D17412D17412A143E311C45ABA3B4250E3A2D17412C1640 +2D17412D16412D17412D17412D16412D16412D16412D16412D17412D17412D17412D1641 +2D16412D16412D16412D17412D17412D17412D16412D16412D16412D16412D17412D1741 +2C16402E1842311C452B143F1E06332E1B41756880B1A2C39875BE68379D4D14869170B2 +BDA2D9585859000000040404000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000404040000008D8A8F995ED57637B77D3FBD +7C3EBD7D3FBD7C3EBC7F42BE7433B8AE85D5A879D67D39C28443C58240C48341C58340C5 +8340C58340C58341C58341C58341C58340C58340C58340C58340C58341C58341C58341C5 +8340C58340C58443C57931C0B085DAAB7ED87830C08442C58340C58341C57E38C2BA95DE +9E6AD17B36C18443C58341C58340C58341C58341C58341C58340C58340C58340C58340C5 +8341C58341C58341C58240C48544C6762DBFC6A7E4965FCE7E39C28342C58240C4C9ABE5 +7F3AC38340C58543C67931C09E6AD1BC99E07D39C48241C68342C78342C78342C78342C6 +8342C68342C68342C68342C78444C77C37C3A678D7B189DC7E3AC48444C77934C2CEB5EA +8B4ECA7F3CC58343C78241C68342C68342C78342C78342C68342C68241C68342C78342C7 +8342C78342C78342C78546C87832C2B189DAB188DB6F25BEC6AAE6955ECC732BBC7934BE +7933BE7832BD823EC78742CB8642CA8540CA8947CCB990E3BB93E4BA92E3BC91E7B596D4 +A79CB1A99BB6A799B3B1A3BD695B7640314D483A55493A5640314E3B2D4C8E7F98230D39 +625170B5AEBD6959783F2A52422D545C4B6DA398ADA59AADA59BADA79EB0998DA1847890 +8477908A7E95675775240E392D17412B153F2C1640230C381E06331F07341E07341F0734 +2E1842301B44301A43301A442E18422D17412D17412D17412D17412C16402D17412D1741 +2D17412D16412D16412D16412D17412C16402D1741301A432E184227113C15002C341F48 +4C395D8B8097978BA0847890412D531E07341E06332D1741301B442D17412D17412C1640 +2D17412D17412D17412D17412D16412D16412D16412D16412D17412D17412D17412D1641 +2D16412C16402F1A43210A367464807A6A851C05322F1A432C16402D17412D17412D1741 +2D17412D16412D16412D16412D17412D17412D17412D16412D16412D16412D16412D1741 +2D17412D17412D16412D16412D16412D17412C16402F19422E1843260E3B17002E301D42 +766981AF9FBF9C7ABF63309757228C5E2C916C3E9BA489C0A27EC55F615D000000040404 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000404040000008E8A90985CD47637B77D3FBD7D3FBD7D3FBD7D3FBD7D3EBD +7E42BD712DB7CBB2E68F53CB7D39C28342C58240C48341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58340C58443C57931C0 +AE82D9AF85DA7930C08442C58340C58441C57D37C29359CCC4A4E37D39C28342C58240C4 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58240C48443C5 +7A34C1AE82D9AB7ED77D38C28442C58342C57E3AC3BA96DE9B66D07E38C28341C58543C6 +7931C09F6BD2B994DE7E3BC48444C78241C68342C78342C78342C68342C68342C78342C7 +8545C87831C2B893E09E6BD37B36C38444C7813FC68D52CCC2A3E48242C78241C68241C7 +8342C78342C78342C78342C78342C68342C68342C78342C78342C78342C78342C78140C6 +884ACAC8ACE78546C87E3AC4945DCEC4A5E37B35C18646C68442C58443C58241C48240C3 +8240C38241C3813FC37730BE7730BE7730BE752DBD813CC59759D69455D39657D4914FD3 +B288DCC5A9E1C1A2E0C1A3E0C5A8E18A7B98BCB6C3D8D5DBE2DFE4C8C4CC968F9DA09AA6 +A39DA8908897413050331E47311A45351E49210F3707001F19052F1D0433230C38311B45 +2F19432F19432E18422F1A43301B44301A44301A442F19422D17412C16402D17412D1741 +2D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412C16402D1741 +2E18422F19432C16401A0330210A364C3A5D94889E91879DA198AA5C4C6C27103B18002E +29133E2F19432F19422D17412C16402D17412D17412D17412D17412D17412D17412D1741 +2D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412C16402F1943 +1C04327C6E8773637F1F0734301B442C16402D17412D17412D17412D17412D17412D1741 +2D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412C1640 +2D17412E1842301B44220A37210A3556476592889BA797B89C7ABE663399541F89623093 +6332955D2A917549A1A58AC08B60B7666A62000000040404000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000010101000000 +252921B89BD67633BB7E41BD7D3FBD7D3FBD7D3FBD7C3EBC7D40BD7A3BBB8B55C4BE9DE0 +823FC48240C48341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C5813FC48748C7C6A7E48543C6823FC48340C5 +8340C5823FC48543C67931C0BD9AE09963CF7D38C28342C58240C48341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C5823FC48544C6CBB0E6823FC4823FC4 +8341C58442C57A34C19F6CD2B892DE782FC08543C6823FC48544C6762CBFAC80D8B690DF +752DC08647C88241C68342C78342C78342C78342C78342C7803DC58D51CBC5A7E4803EC6 +8343C78342C78545C8772FC1B892DFA778D67A34C38444C78241C68342C78342C78342C7 +8342C78342C78342C78342C78342C78241C68546C8762EC1D8C3EDB48CDE7730C18647C8 +7A35C2C1A0E29B66CF7A34C18443C58240C48341C58341C58341C58240C48341C58544C5 +8544C58444C58544C68241C47E3BC17E3BC17E3BC17E3CC17B35C17931C17932C17B34C2 +762CBFAC79E0E7D6F7CBAEE9975DD29D6DCDB19CC5AE97C5AE97C4B19AC7B7A2CD6F637B +695D736A5E746D61777A70823C2A4D200A33251038210B34210C34220C36230B3A230B39 +230B39230B39250D3B311B44301B44301B44301B44311B442D17412D17412D17412D1741 +2D17412D17412C16402D17412D17412D1741301B442F1942220B371F0834341E46746581 +8F8298978EA25C4B6C3F2B5116002C250E392D1741311B442D17412C16402D17412D1741 +2D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D1741 +2D17412D17412D17412D17412D17412D17412C16402D17412C16402C1640A79FB1311C45 +27103B2E18422C16402D17412D17412D17412D17412D17412D17412D17412D17412D1741 +2D17412D17412D17412D17412D17412D17412C16402E18422F1943240C391E0733554763 +A093ABA88EC38960B36A399B541F8A602E92643395612F9364329558238DAC92C67F57A7 +5E2994A799B60A0D07000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000014180FBCA5D67632BB7E41BD +7D3FBD7D3FBD7D3FBD7D3FBD7C3EBC7E41BD7533B9915EC7C5A5E37932C08544C68240C4 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58240C4823FC48443C5C7A9E47D37C28442C5823FC48340C58340C58340C57E39C3 +9359CCC7A9E47C37C28443C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58240C48443C57C36C1C7AAE58E53CA7F3BC38342C58341C58442C57A34C1A677D5 +B791DD782FC08543C58340C58340C58240C58340C5BF9EE2935CCE7B36C38545C88241C6 +8342C78342C78342C78342C77E3BC59965D1C09FE17933C28545C78241C68241C68545C8 +7A34C2C3A3E3965ED07C38C38443C78241C78342C78342C78342C78342C78342C78342C7 +8241C78444C77A35C39E6BD3BC98E07932C28545C88342C77E3BC5935BCEBD9BE08544C6 +823FC48341C58341C58341C58341C58341C58341C58341C58341C58341C58240C48341C5 +8341C58341C58341C58341C58443C58544C58545C6813EC4894AC7BC9ADE7933C3BE9CE2 +8748C57C35C28641CB8540CB8540CB843FCA833EC8B384E1B78BE4B689E3B689E2B687E6 +B29BCAB0A4BCB1A2BFAFA1BDB8AAC68A7C98493B5553455F51435D53465F4A3B571A0230 +1B04311B03311B04311B033027103C2A133F29123F2A133F29123E2D1741301B44301A44 +2F1A432D17411E0633230C38544164736682A49AAC7D6F895947681E0633210A3628123D +321C452E18412C16402D17412D17412D17412D17412D17412D17412D17412D17412D1741 +2D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D1741 +2D17412D17412D17412D17412E184227103B402C5291889E311B452C16402D17412D1741 +2D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D17412D1741 +2C16402F19432E1842240C39200935534360A296ADAA90C57A4DA857218D57238B602E92 +643395612F93623094612F93653496531C89AF96C8774DA2531B8CB19EC312160E000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000014190FBBA3D47633BB7E41BD7D3FBD7D3EBD7D3EBD7D3FBD +7D3FBD7C3EBC7E42BE7533B9B998DB9F6CD27A33C08443C58240C48341C58341C58341C5 +8341C58341C58340C58340C58341C58341C58341C58341C58341C58442C57C37C2A576D5 +B38ADB7D37C28341C58340C58340C58340C58340C5823FC48442C5DCCAEF9157CB7E3AC3 +8341C58341C58341C58341C58341C58340C58340C58341C58241C58443C57B36C19F6DD2 +BB96DF7A33C08443C58240C48341C58442C57A34C1A475D4B993DE782FC08543C58340C5 +823FC48341C5803BC38340C4C2A2E3935BCE7B36C38545C88241C68342C78241C68545C8 +7831C1C2A2E4925ACE7F3CC58342C78342C78342C78443C77D39C49964D1C2A3E47F3CC5 +8343C78241C68342C78342C78342C68342C68342C78342C78241C68443C7803EC5BF9FE3 +945CCF7E3BC48343C78241C68545C8762EC1AC80DAB48DDC7932C08443C58341C58341C5 +8340C58340C58340C58341C58341C58341C58341C58340C58340C58341C58341C58341C5 +8240C48341C58240C48240C4E7DAF3945CD07329C2D0B7EAB58EDC7B36C18444C58342C4 +8342C48342C48341C47832BE7730BE7731BE7831BE752EBC8845CB904FD18E4DD0904FD1 +8B47CFA26DD7C4A4E4BF9CE2C09DE2C19EE4BA9BDA988EA2998EA3998EA3988EA39C92A6 +4737563422433827473726463A294828133B1A01311D05331F073429123E7F728C9B92A6 +998EA47768852E17421D0532250F3A321C45301A432F1A432E18422C16402D17412D1641 +2D16412D16412D17412D17412D17412D17412D16412D16412D17412D17412D17412D1741 +2D17412D16412D16412D17412D17412D17412D17412D17412D16412D16412D17412D1741 +2C1640301B441A012F6859778F849A14002A311C452C16402D17412D16412D16412D1741 +2D17412D17412D17412D17412D17412C16402E18412E1942301A44220A37210B36544461 +A094ABAD94C77749A558228D5B278E643395633194623094612F93623094623094623094 +5E2B9171449EAE94C76737975A2390B3A1C40F130C000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +14190FBAA1D57430BA7E42BD7C3EBC7D3EBD7D3EBD7C3EBD7C3FBD7D3FBD7D3FBD7D3FBD +7736B9BA99DC9A66D07D38C28443C58240C48341C58341C58341C58340C58340C58340C5 +8340C58341C58341C58340C58240C48544C6772FBFBB97DF9860CE7C36C28341C58340C5 +8340C58340C5823FC48543C57931C0A97BD7AD82D87A34C18443C58240C48341C58341C5 +8340C58340C58340C58341C58240C48443C57D37C2C5A6E39157CB7E3AC38342C58341C5 +8341C58442C57A34C1A576D5B48CDC772EBF8543C6823FC48340C5823FC48441C5803CC3 +823FC4C2A2E3935BCE7B36C38545C88241C68342C78140C6894BC9C1A1E4894CCA813FC6 +8342C78342C68342C78241C68545C8762EC1D7C2EBB28ADD7832C28545C88241C68342C6 +8342C68342C68342C68241C68546C8742CC0BC99E1A678D77831C18545C78241C68342C7 +8241C68444C7803DC5C9ACE68747C7823FC48240C48341C58340C58340C58340C58340C5 +8341C58341C58340C58340C58340C58340C58341C58341C58240C48544C6772FBFB28ADB +B792E17C38C67F3DC79A65D2C4A5E37830BF8544C68240C48341C58240C48341C58443C5 +8443C58443C58443C58544C6813FC37F3DC2803DC27F3DC2803EC27D38C1772FBF7831BF +7831C0762FBF7D38C3A066DA9F65DA9F66DAA066DA9E63DABB9DD9C2ABD9C1A7D9C0A7D8 +C7ADE19989AA776F7F7567817F7389F6F8F496909F3B294C14002819042C25113826103A +220A3921083721093720083627103B311C45301A44301A44301B442E18422D17412D1741 +2D17412D17412D17412C16402D17412D17412D17412D17412D16412D16412D16412D1641 +2D17412D17412D16412D16412D16412D16412D16412D17412D17412C16402F194226103B +85768F5E4D6C220B372F19432C16402D17412D16412D16412D17412D17412D17412D1741 +2D1741311B4428113D2008361F09345647639D91AAAE94C7794BA7551F8B5D2A90633294 +633194612F9362309462309462309462309462309463319458238D845EABA284BF541D8A +5D2991A287BD383A36000000010101000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000010000005B48708949CC793CB9 +7D3FBD7D3EBD7D3EBD7C3EBD7C3FBD7C3FBD7C3EBC7E40BD7837BA8851C2CAAFE67B34C1 +8341C58341C58240C48341C58341C58340C58340C58340C58340C58341C58341C58340C5 +8341C58443C57C36C1CAAEE69D68D17C36C28341C58340C58340C58340C58340C5823FC4 +823FC48442C5CAADE68544C6823FC48341C58341C58341C58340C58340C58340C58240C4 +8545C67830BFBC99DFA170D37A34C18443C58240C48341C58341C58442C57D38C29862CF +E3D4F28442C5823EC48340C58340C58340C5823FC48441C5803CC3823FC4C2A2E3935BCF +7C37C38443C78443C77B36C39D6BD2B48DDC772FC18545C88241C68342C68342C78342C7 +8342C78342C77E3BC5C9ADE58646C7803EC68342C78241C68342C68342C68241C68343C7 +7F3CC59761CFBA95DE813FC68342C78342C68342C78342C78241C68443C77B36C3A87AD8 +B58EDC7830BF8544C68240C48340C58340C58340C58340C58341C58341C58340C58340C5 +8340C58340C58341C58240C48444C67831C0AD82D8B088DE7730C38444C9803DC78C51CD +C1A0E2823FC48341C58341C58341C58341C58340C58340C58340C58340C58341C58240C4 +8341C58341C58341C58341C58240C48342C58544C68544C58544C58544C68342C57B37BF +7B37BF7B37BF7B37BF7B37BF7D37C47E37C57E37C57F39C57931C29C62D5AB78E0EFE4F9 +DAC0F2A26BD7A87FD0B0A0BEBBAACBB8A7C7BFADCF83748F5549605E52695B4F6660546A +45335518012E1D07321D06321B0530230C3828113E27103D27103D27103D2F1943311B44 +301B44301B44311B442E18422C16402D17412D17412D17412D17412D17412D17412D1641 +2D16412D16412D16412D17412D17412C16402D1741260F3B3A264DA9A1B2220B372C1640 +2D17412C16402D16412D16412D17412C16402D1741301B442A133F1A0230402E515F526B +9D91AAAC91C57B4EA9551F8B5C298F643395623094612F93623094623094623094623094 +6230946230946230946230945E2B91AF96C97549A15F2C925A288D7D4CAD858386000000 +040404000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000404040000006A6C67AB78DE7131B57E40BD7D3EBD7D3EBD7C3EBD +7C3FBD7C3FBD7D3FBD7C3EBC7E41BD7736BA9969CBB690DC7F3AC38443C58240C48341C5 +8341C58340C58340C58340C58340C58341C58341C58341C58341C57E3AC2945CCDDBC8EE +8441C5823FC48340C58340C58340C58340C58340C58340C58442C57931C0AD81D8AF85D9 +7A33C08443C58341C58341C58340C58340C58341C58341C57F3BC38E52CAC5A7E47F3BC3 +8342C58240C48341C58341C58341C58240C48544C67932C0C5A6E49156CB7F3AC38340C5 +8340C58340C58340C5823FC48441C5803CC38340C5C1A0E29057CD803EC58444C77F3CC5 +BA96E09A66D27E3BC58343C78342C68342C68342C78342C78241C68444C77C37C3A87CD8 +B087DC7D39C48444C78241C68342C78342C78342C78443C77934C2CFB6EA8A4DCA7E3BC5 +8342C78241C68342C78342C78342C78342C78241C68241C7C7A9E5894AC7803DC38341C5 +8341C58340C58340C58341C58341C58341C58341C58340C58340C58240C48240C48444C6 +7831C0AC81D8B18ADE7933C48444C98342C98545CA7831C4B893E09D69D07B35C18442C5 +8341C58341C58341C58340C58340C58340C58341C58341C58341C58341C58340C58340C5 +8340C58341C58341C58341C58341C58240C48341C58341C58341C58341C58341C58341C5 +8443C58443C58443C58342C48646C67832BF9864CDA578D3BE9CE08240C27C35C08B47CC +8945CA8A47CB853EC8A875D9C19DE5BC95E3BC95E2C29CE8DCD3E49E92A9A497AFA194AC +AB9FB666587339294742335040314E41314E1F08341A01301B03311B03311A0130260F3B +2E17432C16412D16412D16412F19432F19432F19432F19432F1A432D17412C16402D1741 +2D17412D17412C16402F1943240D39534265887D9527113C2F19422C16402D17412C1640 +2E18412F19432B143F1C0432372447877B90AA96BFAC8FCA784BA558228D5A278E653496 +623094623094612F93623094623094623094623094623094623094623094612F93633295 +5A258EB7A1CE62319462309459268C8457B1848385000000040404000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000040404 +0000006A6C68AB78DE7231B57E40BD7D3FBD7D3FBD7D3FBD7D3FBD7C3FBD7D3FBD7D3FBD +7C3EBC7F43BE6E29B5B490D8AC7FD8762DBF8545C68240C48341C58341C58341C58341C5 +8341C58341C58341C58341C58341C57D39C2945CCDBD9AE0772DBF8544C6823FC48340C5 +8340C58340C58340C58340C58340C58340C5823FC4CBAFE68341C58240C48240C48341C5 +8341C58341C58240C48544C57A34C1B791DDA473D47A34C18443C58240C48341C58341C5 +8341C58341C58443C57B34C1C6A8E49055CB7F3AC38340C58340C58340C58340C58340C5 +823FC48441C57F3AC38949C8D0B7E97933C28545C8803DC5C7AAE7813FC68342C78241C6 +8342C68342C78342C78342C78342C78241C68546C8742CC0C3A4E39E6CD37933C28444C7 +8241C68241C68444C77C38C4B691DFA171D57E3AC48444C78241C68342C78342C78342C7 +8342C78241C68445C77934C2A97DD9B289DB7B35C18443C58240C48341C58341C58341C5 +8341C58341C58341C58341C58341C58240C48443C57A33C0AC81D8B18ADE7933C48444C9 +8342C98241C88443C97C38C6A575D7B38ADB7E3AC28342C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58240C48342C5 +7E39C28D50C9D1B8E97328BDB690DDA777D47B35BF8240C1813EC1813EC18240C17B35BE +762DBC772FBC772FBC762DBB8A4AC79B5DD5995BD49A5CD49655D3B289D9C5ABDEC1A4DD +C2A6DEC2A6DE8E8199857B8E877C91857A8F8E84974D3D5B2411362D1A3E2B183C2B183C +2008361E06351F07351F07351E06342B143F311B452F1943301A44301A442E18422D1741 +321C4517002D7E718B7B6D8716002C321C452C1640301B4428123D1E063336224784788F +B2A0C49069B6622E95501A875E2B90633294633194612F93623094623094623094623094 +6230946230946230946230946230946230946231945D2A91794EA3AB91C6602E93623194 +59268C8456B1868587000000040404000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000404040000006A6C67A975DE7131B5 +7E40BD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7C3EBC7F42BE +BE9EDE9054CB7E3AC28442C58240C48341C58341C58341C58341C58341C58341C58341C5 +8342C57D38C2A372D4B791DD7B34C18442C58340C58340C58340C58340C58340C58340C5 +823FC48441C57D38C2C2A2E2935ACC7E3AC38342C58240C48341C58240C48544C6772FBF +AB7ED7B690DD762EBF8545C68240C48341C58341C58341C58341C58341C58443C57A34C1 +C6A7E49257CC7F3AC38340C58340C58340C58340C58340C58340C5823FC48442C57D38C2 +A778D6B48DDC7025BEAB80D9B38CDC7D39C48343C78342C78342C78342C78342C78342C7 +8342C78342C78342C7813FC68B4ECABE9BE1894BC98140C68342C78343C77F3DC58B4FCA +C8AAE67B36C38443C78241C68241C78342C78342C78342C78342C78342C78241C68546C8 +762EC1BC9AE0A270D37B35C18443C58341C58341C58341C58341C58341C58341C58341C5 +8240C48544C67A33C0A678D6B28BDF7933C48444C98342C98241C88342C98241C88342C8 +8140C8C5A7E57D38C28443C58240C48341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C5823FC4BB96DF965FCE7C37C1 +8B4FC9C6A7E2823FC28340C38340C38340C3823FC28441C38543C48543C48543C48543C4 +803CC17D38BE7D39BE7D39BE7D39BE7C35C07B32C07B33C07B32C07B32C0A56EDAAC77DE +AA75DDAB76DDA971DEB696D5BDADCEBCA8D0BDA9D0BBA8CE6F637B665A70685C72675B71 +6B5F763521471A042F200A341F09331F0933240D3A250D3B250E3B240D3A29123E988CA0 +4C395D26103B2B15401C043239264981758DB4A2C5906AB75E2A9358238C612F93653496 +623094612F93623094623094623094623094623094623094623094623094623094623094 +623094612F93643395531D8A9877B88E6AB2551F8B6432956231945C2891A791BE232720 +000000010101000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000404040000005F625CAB7CDC7332B67E40BD7D3FBD7D3FBD7D3FBD +7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7C3EBC7D40BD793ABB7E41BDC8AEE48645C6813EC4 +8341C58240C48341C58341C58341C58341C58341C58341C58443C57C36C1C7AAE58A4AC8 +803CC38340C58340C58340C58340C58340C58340C58340C58340C58341C57C36C19A64CF +C09FE17A33C08443C58341C58341C58341C5813EC48A4CC8BF9EE1894BC8813EC48341C5 +8341C58341C58341C58341C58341C58341C58443C57B34C1C5A7E48B4DC8803BC38340C5 +8340C58340C58340C58340C58340C58340C58340C58341C57A32C1AF83D9A97BD8B28ADB +9862D0742CC08342C7803EC68241C68444C78444C78445C78343C78241C68241C68545C7 +7730C2A87AD7BB97E0752DC08546C88342C77D39C4E7DBF49964D07D39C48443C78342C7 +8342C78342C78342C78342C78342C78342C78342C78342C7803EC68E53CBC6A8E47D39C2 +8442C58240C48341C58341C58341C58341C58341C58240C48544C67932C0A676D5E3D5F2 +762FC38444C98342C98342C98342C98342C98342C98342C9803EC7DDCCF0A16FD27D37C2 +8442C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58240C48544C6772FBFA87AD6BA96DF742BBE8848C77830BFB892DE9A63CE7C35BF +8341C38340C38340C38340C38340C38340C38340C3823FC38340C38340C38340C38340C3 +8340C38442C38443C38442C38443C38443C37A34BD7932BC7933BC7933BD7832BB803AC3 +853FC8843EC7843EC7853FC8B487DFBA90E2BA8FE2B487DED0AFEECBC4D2A596B3ADA0BA +AC9FB9AA9CB652435E4839554A3B574E405A3A2B4A15002C978A9F301B44331F4484798F +B19EC3936DB95D289257238C623194633295612F94612F93623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094602E93663596 +AF96C96F419C5F2C92623094653496531C89AB8FC732362E000000010101000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000001000000B0A3C08140C47C3EBB7D3EBD7D3EBD7D3FBD7C3FBD7C3FBD7C3FBD7D3FBD +7D3EBD7D3FBD7C3EBC7F42BE7331B8A57BD1B38BDC7931C08442C58240C58341C58340C5 +8341C58341C58341C58240C48443C57B35C1C8ABE58E52CA803BC38340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58543C57A33C1C4A4E3945CCD7F3BC38341C5 +8240C48545C67831C0C2A1E29B66D07A33C08443C58240C48340C58340C58341C58341C5 +8341C58341C58442C57C37C1AF84D9AA7CD77C36C28441C58340C58340C58340C58340C5 +8340C5823FC4823FC48442C5823FC46F22BCB48CDBE5D8F4C1A1E4A475D68444C78B4FCA +8241C67831C17933C27831C17F3CC58444C78343C78444C78546C87D3AC4B690DFA475D6 +7D39C47C37C3AA7FD9B590DE7C37C48444C78342C78342C68342C68342C68342C78342C7 +8342C78342C68342C68241C68444C77933C3BA97E0A170D27B35C18443C58240C48341C5 +8341C58341C58240C48442C5803CC38240C4C6A7E49259CF803DC78343C98241C88342C9 +8342C98342C98342C98444C97933C4AC81DBAF84D97830BF8544C58240C48341C58340C5 +8340C58340C58341C58341C58341C58341C58340C58340C58341C58341C58341C58341C5 +8341C58340C58340C58341C58341C58341C58341C58341C58341C58442C57E39C2955DCD +BF9DE1803CC38442C58442C57D38C2A372D4B38ADA7E38C08341C38340C38340C38340C3 +8340C28340C28340C28340C38340C38340C38340C38340C28340C28340C28340C38340C3 +833FC3823FC28441C38441C38441C38441C38441C38340C28240C18240C28240C28240C1 +7830BC772EBC772FBC772EBC7831BC8D4CCC9453D29352D19251D19454D1BE9BDEC2A2DF +C0A0DEC4A2E3B89ED0847A8EC0BBC7A49CACAA96BC926CB8602C9455208A633294633194 +623094612F93623094623094623094623094623094623094623094623094623094623094 +623094623094623094623094623094612F935F2D92693998B59ECC56218C643395612F93 +643395541E8AAF95CA2F332B000000010101000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000001000000B1A4C08140C5 +7C3EBB7D3EBD7D3EBD7C3EBD7C3FBD7C3FBD7C3FBD7C3EBD7D3EBD7D3EBD7D3FBD7C3EBC +7F42BE7330B8A981D3AC80D87C37C28443C58240C48341C58340C58341C58341C58442C5 +7B35C1A373D4B791DD7B33C18442C58340C58340C58340C58340C58340C58340C58340C5 +8340C5823FC48340C57E39C29860CEC09FE17831C08544C68442C57C36C1955DCDC4A5E3 +7B35C18544C68240C48341C58340C58340C58340C58341C58341C58340C58341C57F3BC3 +8E53CAC4A4E37A32C08543C58340C58340C58340C58340C5823FC48341C58543C57A33C1 +8B4DC9B892DDC3A3E3FBF9FDC09EE1D0B7E8CAAEE6C9ACE5E2D2F0B48DDDAE84DBB38CDD +935BCE7B35C3803DC57A35C37B37C37832C28545C7C8AAE57F3CC58342C7CBB0E68546C7 +813FC68342C78241C68342C68342C68342C68342C78342C78342C68342C68342C68342C7 +8342C77F3CC58F55CCC5A5E37E39C28442C58240C48341C58341C58240C48442C5803CC3 +8341C5C2A2E29158CF7B37C68444C98241C88342C98342C98342C98342C98342C98443C9 +7D38C69C68D4B893DE7F3BC38341C58341C58340C58340C58340C58340C58340C58341C5 +8341C58340C58340C58340C58340C58341C58341C58341C58340C58340C58340C58340C5 +8341C58341C58341C58341C58240C48544C67932C0C09EE19C67D07B35C18443C58240C4 +8240C48341C5C5A7E27C36BF8442C3823FC28340C38340C28340C28340C28340C28340C2 +8340C38340C38340C28340C28340C28340C28340C28340C38340C38340C28340C28340C2 +8340C28340C38340C38340C38340C28340C2823FC28340C38442C38543C38443C38543C3 +8442C3803CC07E3BBF7F3BBF7F3BBF7E3BBF7931BE7930BE7931BF762DBD8643C69D5FD8 +D5B9F1E1D9EA541C8D59258D613093643395612F93623094623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +6230946231945D29908158A9A88CC45B278F63319462309464329557228C9C7ABE515250 +000000020202000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000001000000AFA2BD8241C57B3EBB7D3FBD7D3EBD7C3EBD +7C3FBD7C3FBD7C3FBD7C3EBD7D3EBD7D3EBD7C3EBD7D3FBD7C3EBC7E41BD7533B8CDB4E6 +894BC87E3AC28342C58240C48340C58341C58341C58443C57A33C0A87BD6B38ADB782FBF +8543C5823FC48340C58340C58340C58340C58340C58340C58340C58340C58340C5813EC4 +8442C5E6D8F3955CCD7E3AC28443C58241C4BB97DF965ECE7E39C28342C58240C48340C5 +8340C58340C58340C58341C58341C58340C58341C57E3AC2955DCDC4A4E37931C08543C5 +8340C58340C5823FC48442C58341C57E38C2772EBFB38BDBC9ACE5A371D48746C6D2BBEA +B289DB813DC47C35C17A33C19A64D0B188DAAA7CD7BC98DFE0D0F0C7AAE5CAAFE6D8C3EC +A373D69F6DD49A65D2A06ED4B28ADBB791DD8F54CC7B37C3803EC58342C78545C88444C7 +8241C68342C78342C68342C78342C68342C68342C68342C68241C68546C87730C1BE9DE2 +A06ED27A33C08443C58240C48240C48442C5803CC38341C5C2A1E29259CF7B37C68545C9 +8241C88342C98342C98342C98342C98342C98342C98241C88545C97A34C5C4A5E48747C6 +813EC48240C48340C58340C58340C58340C58340C58341C58341C58340C58340C58340C5 +8340C58341C58341C58341C58340C58340C58340C58340C58341C58341C58341C58240C4 +8544C6772FBFB38ADBAC80D87932C08544C58240C48341C58342C57E39C2B58EDBA271D2 +7B34BF8442C38340C38340C28340C28340C28340C28340C28340C38340C38340C28340C2 +8340C28340C28340C28340C38340C38340C28340C28340C28340C28340C28340C38340C2 +8340C28340C28340C28340C28340C38340C38340C2823FC28340C38340C38340C38340C3 +8340C38340C38443C38543C38543C38644C47F3BC18140BFC9ABE6B69BD2613092643395 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094623094623094623094623094623094623094623094612F93653496521B89A98EC4 +794FA45B268F623094623094612F935F2E9169359E9E97A6000000020203000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000001000000AEA0BE7D3AC37C3FBB7C3EBC7D3EBD7D3EBD7C3FBD7C3FBD7C3FBD7D3EBD +7D3EBD7D3EBD7C3FBD7C3FBD7C3FBD7D3FBD7A3BBC874FC2BF9EE08545C68240C48341C5 +8341C58341C58341C58443C57A33C0A97CD7B48BDC7830C08443C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58543C6782FC0B68EDCA778D67D39C2 +762EBFB28ADBB289DB752CBE8545C68240C48341C58340C58340C58340C58341C58341C5 +8341C58341C58341C57E3AC2945BCDC5A6E47A32C08543C5823FC48340C58442C57B34C1 +7D37C29B65D0CAADE6A675D57F3AC3772FBF9053CBC1A2E18647C3C9ACE6823FC48543C5 +7D37C27830C07931C07930C08341C5894AC8833FC5AC7FD8C2A2E3B994DECCB0E7DBC8EE +DCCAEEE8DDF4A476D68A4ECB9158CE803EC6762EC17B37C38343C78241C68342C78444C7 +8444C78343C78241C68342C78342C78241C68342C7803EC5C3A4E49055CB7F3AC38342C5 +8342C5803DC38342C5C2A1E29259CF7B37C68545C98241C88342C98342C98342C98342C9 +8342C98342C98342C98342C98343C97D3AC6AE84DCA97BD67C37C28442C58341C58340C5 +8340C58340C58341C58341C58341C58341C58340C58340C58340C58341C58341C58341C5 +8340C58340C58340C58340C58341C58341C58240C48341C5813FC48A4DC8C2A3E28544C6 +823FC48341C58341C58240C58443C57931C0A97BD7B288DA7931BE8442C38340C38340C3 +8340C28340C28340C28340C38340C38340C38340C38340C28340C28340C28340C38340C3 +8340C38340C28340C28340C28340C28340C38340C38340C38340C28340C28340C28340C2 +8340C38340C38340C38340C28340C28340C28340C38340C38340C38340C38340C28340C2 +823FC28543C37931BEBB96DD9A64CFAB7BD99575B456208C643295623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +6230946230946230946230946230945F2C916D3F9CAE95C8693998602D92623094623094 +6230945E2C90703DA29F98A6000000020203000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000010102000000898290955DCF +7738B97D40BD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD +7D3FBD7C3EBC7E41BD7431B89565C9C4A6E4752BBE8646C68240C48341C58341C58240C4 +8443C5C8ABE58543C6823FC48340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C5823EC48746C7CBAFE67A33C09B66D0BB97DF813EC48443C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C57E3AC2 +945CCDC2A2E2782FC08543C68443C5823EC47B34C19E6AD1C3A4E3BF9CE19055CB7D37C2 +8340C5813EC48D50CAC8ACE46C20B7B58FDAAB7DD7782FC08543C68442C58442C58442C5 +823FC4813DC4823FC47B33C1782FC0782FBF6D1EBAA778D6EADFF5EADFF5AC80D9CDB3E8 +C8ABE6BC99E0B893DEA87AD67E3BC58343C77F3DC57A34C37A34C37E3BC58546C88444C7 +8443C78342C78545C87A34C3A272D5B994DE7A33C18443C58241C5823FC4C09FE1925ACF +7B37C68545C98241C88342C98342C98342C98342C98342C98342C98342C98342C98342C9 +8342C97D3AC6945CD0BD9BE0772FBF8544C68240C48341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58240C48443C57730BFCCB1E78F54CB7D38C28442C58240C48341C58341C5 +8341C58342C5813FC4C9ADE58645C4813EC2823FC28340C38340C38340C38340C38340C3 +8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 +8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 +8340C38340C38340C38340C38340C38340C38340C38340C38340C3803CC28B4DC7C9ACE6 +752BBEB48ADE9373B457218C633295623094623094623094623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +6231945A258E7D54A7A88DC4521B89653496612F936230946230945E2C906F3CA2A19AA8 +000000020203000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000002020200000043483EB990E2702DB57F42BE7D3FBD7D3FBD +7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7C3EBC7E40BD +7838BAB28DD8A270D47A34C18544C58240C48240C48341C5803CC3C8AAE5813DC48340C5 +823FC48340C58340C58340C58340C58340C58340C58340C58340C5833FC58340C5823FC4 +8544C67D37C2B58DDCA372D4B791DD9258CC7730BF7F3BC38443C58544C68544C68544C6 +8544C68544C68544C68544C68544C68442C58341C57F3CC38E53CAC3A3E38341C5823EC4 +7A32C08443C5C7AAE5BC98DF9359CC7830C07F3BC38441C5823FC48441C57C36C2B992DE +A16FD07228B9B590DAA26FD37D38C28442C5823FC48340C58340C58340C5823FC48544C6 +8340C5823FC4DDCBEFB086DAA16FD3D5BEEBA06ED27125BC7A32C09860CEA87AD6B187DA +CDB3E9CEB4E9BE9CE2A171D4A97DD8935BCE7730C17B36C37C38C47E3BC57F3CC58748C8 +7F3CC5C9ADE68D51CA8342C5742ABED4BDEABC9AE3742CC28647CA8241C88342C98342C9 +8342C98342C98342C98342C98342C98342C98342C98342C98342C9803DC78E52CDE3D5F2 +8F54CA7F3CC38341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58240C48443C57D38C2 +A779D6AE83D97D38C28443C58240C48341C58341C58341C58240C48443C57C36C2C2A2E1 +945BCA7E39C18341C3823FC38340C38340C38340C38340C38340C38340C38340C38340C3 +8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 +8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 +8340C38340C38340C3823FC28441C37E39C1CBAFE78A4BC8762CBEB58BDE8B68AE56208C +643295612F94623094623094623094623094623094623094623094623094623094623094 +6230946230946230946230946230946230946230946230946231945B278F8B66B0A284BF +57228D64329562309462309462309463319459258EA183BE3F423C000000020202000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +02020200000044493FB78DE0702EB57F42BE7D3FBD7D3FBD7D3FBD7C3FBD7D3FBD7D3FBD +7D3FBD7D3FBD7D3FBD7C3FBD7C3FBD7D3FBD7C3EBC7D3FBD7D3EBD7432B8BD9EDE9B66D0 +7B36C18443C58442C57C36C1A575D4B38ADB7D38C28341C58340C58340C58340C58340C5 +8340C58340C58340C5823FC48340C58442C58340C5823FC47D37C27328BD823FC4DECDF0 +C9ACE58C4EC99760CE945BCD7B34C1772FBF7830C07830BF7830BF7830BF7830BF7830C0 +772FBF7D38C28240C48443C5762DBFB893DE9962CF7F3AC3B187DAC9ADE69054CB7A33C1 +7E38C28543C68340C58340C5823FC48543C6782FBFB186DAA97CD47730BC7F3CBFD2B9E9 +813EC4813DC48340C5833FC58340C5823FC48441C5803BC38341C5BF9CE1B68EDC762CBE +B48CDCB085DAB993DE8F53CA8341C57E39C27930C07D37C28543C57F3AC3955CCDBC99DF +B68EDCBE9BE0C7AAE6CBB0E8AE84DA9158CD9158CD7832C27026BE9862D1BC99E07125BC +A270D3BA97E27D3AC68444C98241C88342C98342C98342C98342C98342C98342C98342C9 +8342C98342C98342C98342C98241C88545CA7730C4BC99E1965ECD7D38C28342C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58240C48341C5803CC38748C7D0B7E97B35C18341C58341C5 +8341C58341C58341C58341C58341C58342C57D38C29861CEC1A0E17A33BE8442C38340C3 +8340C38340C28340C38340C38340C38340C38340C38340C38340C28340C38340C38340C3 +8340C38340C38340C28340C28340C38340C38340C38340C38340C38340C28340C28340C3 +8340C38340C38340C38340C38340C28340C28340C38340C38340C38340C3823FC28442C3 +7A32BEA777D3B58DDC7B33C1813DC3955ACFB296CE5F2C91623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094623094623094612F9364339556218CB69ECD6939995F2D92623094623094623094 +612F93643395531E889C76C1575A53000000030303000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000002020200000043483EBB92E3 +702EB57F42BE7D3FBD7D3EBD7C3FBD7C3FBD7C3FBD7D3EBD7D3EBD7D3EBD7C3FBD7C3FBD +7C3FBD7C3FBD7D3FBD7C3EBC7E41BD7736BA905AC6C3A4E27E38C2813FC48544C67830C0 +BA96DF9E6AD17B33C18441C58340C58340C58340C5823FC48340C58341C58341C58442C5 +8340C57830C07E39C38340C5A473D5C2A1E3B38CDBE8DEF3ECE1F6B995DDC5A8E3C3A4E1 +BC99DFBC98DFBC99DFBC99DFBC99DFBC99DFBC99DFBB97DFC0A0E19F6CD2823FC4894BC8 +7C37C2C19DE0C5A9E4BE9DE1AF84D98341C57F39C38442C58341C5823FC48340C58340C5 +8340C58443C57830C0B48CDCA87AD37832BD7F3CC0955DCBBC98E07F3BC38441C5823FC4 +823FC48543C6803CC38340C5C2A1E29359CC7429BE8645C6E4D5F28D50CA9054CBC8AAE5 +7931C08645C68442C58341C5823FC48340C57F3AC3772EBF762CBF823FC49359CC8B4DC8 +AA7CD6CAADE5C2A2E3BB98E1C09FE3AD83DABF9EE1A474D4B995E17F3BC78241C88342C9 +8342C98342C98342C98342C98342C98342C98342C98342C98342C98342C98342C98342C9 +8342C98443C97C38C6A87BD8AF84D97E39C28342C58341C58340C58340C58341C58341C5 +8341C58341C58340C58340C58340C58341C58341C58341C58340C58340C58340C58341C5 +8240C48341C5813EC4C09FE19157CB803DC38342C58240C48341C58341C58340C58340C5 +8340C58341C58544C57A33C1C3A3E2945BCA7D38C08340C38340C28340C28340C28340C3 +8340C38340C38340C38340C28340C28340C28340C38340C38340C38340C28340C28340C2 +8340C28340C38340C38340C38340C28340C28340C28340C28340C38340C38340C38340C2 +8340C28340C28340C38340C38340C38340C38340C3823FC2803CC2C6A8E48C4EC97F3BC3 +8442C57D36C3C3A8DD653594612E93623094623094623094623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094623194 +5D2A917448A0AD94C7623194612F93623094623094623094623094643295541E89A17EC5 +545851000000030303000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000002020200000030352A996DC47432BA7E41BD7C3EBC7C3EBD +7C3FBD7C3FBD7C3FBD7C3EBD7D3EBD7D3EBD7C3EBD7C3FBD7C3FBD7C3EBD7C3EBD7D3EBD +7C3EBC7E41BD7533B99764C9BA97DE803CC38646C6772EBFB48DDCA676D57A33C18441C5 +8340C5823FC48441C58544C68341C57C36C17D37C27B34C1823FC4AA7CD7B58DDCD0B8E7 +B189D89E6ECE8E57C7BC9BDEB18DD89B65CE6D20B77934BD9B67CDA16FD09F6DCFA06ECF +A06ECFA06ECFA06ECFA16FD09C68CDB791DCCDB4E7C9AFE5CDAAE5B2B4E7D5BFEA904BCA +6E25BC8442C58442C5823FC48340C58340C58340C58340C58340C58543C5782FC0B48CDC +A97BD47730BC8443C2762EBBA374D2BD99E0752ABE8645C68442C57931C0813EC4C2A2E2 +9258CC7B34C18441C58C4EC9C5A6E47B34C17C36C2BF9CE19C67D17A32C08442C5823FC4 +8340C5823FC48341C58543C68543C6823FC47E39C3803BC37D36C2772EBF7F3AC3A270D3 +A16ED3A06DD2EADFF5E4D6F47C38C77933C48546CA8241C88342C98342C98342C98342C9 +8342C98342C98342C98342C98342C98342C98342C98342C98342C98241C88140C88546CA +C4A6E47A34C18544C58240C48340C58340C58340C58341C58341C58340C58340C58340C5 +8340C58341C58341C58341C58340C58340C58340C58240C48443C57A34C1A372D4BB97DF +762EBF8544C68240C48341C58341C58340C58340C58340C58340C58240C48443C57A33C1 +B48CDBA575D47D38C08341C38340C38340C28340C28340C28340C38340C38340C28340C2 +8340C28340C28340C28340C38340C38340C28340C28340C28340C28340C28340C38340C2 +8340C28340C28340C28340C28340C38340C38340C28340C28340C28340C28340C28340C3 +8340C3823FC28442C37C35BFA372D2B892DE782FBF8543C68340C4823DC5C4ABDE653694 +612E93623094623094623094623094623094623094623094623094623094623094623094 +623094623094623094623094623094623094623094643295551F8B9473B69574B7541D8A +643395612F9362309462309462309463329557238B9067B86C6B6D000000020202000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000302040000008171938D4FCE783AB87D3FBD7C3EBD7C3FBD7C3FBD7C3FBD7C3EBD +7D3EBD7D3EBD7C3EBD7C3FBD7C3FBD7C3EBD7D3EBD7D3EBD7D3FBD7C3EBC8044BE6E28B5 +BB9CDCA371D4762EBF8C4EC9C1A0E28747C7813EC48543C68340C5813DC47C36C2762CBF +803BC39961CFAE82D9CEB4E7C5A6E3B38ED99F70CF7834BB7A37BC7733BB742EB9A377D1 +A67ED2AC86D6AA7DD67932BC7C38BF7832BD7933BD7933BD7933BD7933BD7933BD7933BD +7933BD7B36BE7C3BBF883BC04120BC0049A76EB5CED4C6EDA25DD07C35C17C39C28544C6 +823FC4823FC48340C58340C58340C58543C5782FC0B48CDCA97BD47730BC8241C1813FC1 +7E3BBFBC9ADD975FCF7D37C27930C0B289DBD5BFEB8E51CA7C36C28543C6803CC38B4CC8 +CAAEE67E39C2803BC39358CCBD9AE08543C68340C58340C58340C58340C58340C58340C5 +823FC48340C58340C58340C58441C58544C68340C57D38C27226BD955BCDC7A9E5CBB0E6 +CBAFE7B188DC7730C48545CA8241C88342C98342C98342C98342C98342C98342C98342C9 +8342C98342C98342C98342C98342C98342C98342C97F3CC7B791DE9D68D17D37C28442C5 +8340C58340C58340C58341C58341C58340C58340C58340C58340C58341C58341C58341C5 +8340C58340C58240C58342C57D38C2945ACCC4A5E37B36C18443C58240C48341C58341C5 +8341C58340C58340C58340C58340C58341C58240C4813EC4894AC8C3A3E37931BE8543C4 +823FC28340C28340C28340C28340C38340C38340C28340C28340C28340C28340C28340C3 +8340C38340C28340C28340C28340C28340C38340C38340C38340C28340C28340C28340C2 +8340C38340C38340C28340C28340C28340C28340C28340C38340C38340C38441C37B34BF +CCB1E6894AC8813DC4823FC48340C4823DC6C3A9DC5E2C8F623094612F93623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +62309462309462309463319559248D9978B99775B857218C643295623094623094623094 +623094612F936332945B2592AC9DBC060A03000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000303040000009A96A0 +9154D07839B87D3FBD7D3FBD7C3FBD7C3FBD7C3FBD7D3FBD7D3EBD7D3EBD7D3FBD7C3FBD +7C3FBD7C3FBD7D3EBD7D3EBD7D3EBD7D3FBD7C3EBC7D40BD7B3DBCBB9BDD8F54CB8A4CC8 +C3A2E27931C08543C6772EBF7F3AC38847C7A878D6C5A6E4BE9CDFC3A6E1A67BD38345C0 +864AC2732EB97734BB8041BF7F40BF8041BF7B39BD8E55C6C0A3DF6722B3B492D9A678D4 +7730BC8444C28140C18240C18240C18240C18240C18240C18140C17F41C18D42C24124BD +005BAE057CAB0067A71280B27EB8D5C1A7E39F59CF722BBE8341C58441C5823FC48340C5 +8340C58543C5782FC0B48CDCA97BD47730BC8241C1813FC17F3CC07D3ABFC4A5E19054CB +A271D3CEB4E89359CC7B34C18543C6823FC4803CC38B4DC9CAADE67C36C28645C6762DBF +AA7DD7B48BDB7328BD8644C6823FC48340C58340C58340C58340C58340C58340C58340C5 +8340C5823FC48543C67A33C1A06DD2BC98DF8340C5B68FDBA270D2CAAEE6A373D67934C5 +8546CA8342C98241C88342C98342C98342C98342C98342C98342C98342C98342C98342C9 +8342C98241C88545C97831C4AC81DBAD81D87932C08443C58340C58340C58341C58341C5 +8341C58341C58340C58340C58341C58341C58341C58341C58341C58341C58240C48443C5 +7D38C2BA96DF9D69D17C37C18443C58341C58341C58341C58341C58341C58340C58340C5 +8340C58341C58341C58240C48341C5BD9AE0935ACA7F3AC18341C38340C28340C28340C3 +8340C38340C38340C38340C28340C28340C28340C38340C38340C38340C38340C28340C2 +8340C28340C38340C38340C38340C28340C28340C28340C38340C38340C38340C38340C2 +8340C28340C28340C38340C3823FC28442C37B33BFBB96DE9D69D27E38C28341C58340C5 +8341C57E38C3B58EDB8661AB5A268F633194623094623094623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094612F93612F93 +623094BBA5D05E2B91623194622F94623094623094623094623094623094623193602A95 +AE9FBD070A04000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000004030400000095919B9256D07739B87D3FBD7D3FBD +7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD +7D3FBD7D3FBD7C3EBC7D3FBD7A3BBB7E42BDCCB1E6A270D4B288DB7830C08644C6B085DA +B992DECEB6E8AE85D6945FC8915BC7722BB87834BB7D3CBE7D3CBE8142C08041BF7E3EBE +7F3FBF7F3FBF7937BC945FC9BEA0DE702EB77434B9B28ED8A778D4762FBB8342C2803EC0 +813FC1813FC1813FC1803EC17E3FC08C40C14123BD005AAE0179AB006FAC0274AC016EAA +0068A43580BA9FA2DABA87DC823BC47B36C18442C5823FC48340C58443C57830C0B38ADB +A97CD47731BC8241C1803EC08443C27730BC9359C9C9ACE6A778D67227BD803CC48442C5 +823FC48340C5803CC38B4DC9CAADE67C36C28442C58442C57D37C2D2BAEAA16FD37B35C1 +8441C5823FC48340C58340C58340C58340C58340C58340C5823FC48543C67931C09F6BD2 +BC98DF7F3AC3762CBFB892DE9C67CF6E21B9B790DBA87BD9742CC28140C88443C98241C8 +8342C98342C98342C98342C98342C98342C98342C98342C98342C98342C98443C97D39C6 +9F6DD6DECEF0813EC48240C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58240C48544C6752DBEB188DAB188DA762DBF8545C6 +8240C48341C58341C58341C58341C58341C58341C58341C58341C58341C58240C48544C6 +772FBFAE83D9A575D37A33BF8442C38340C38340C38340C38340C38340C38340C38340C3 +8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 +8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3823FC3 +8341C37E39C19258CAC5A6E37B34C18441C5823FC48340C58441C57B34C09E66D4A88EC3 +541E8B643395623094623094623094623094623094623094623094623094623094623094 +6230946230946230946230946230946230946231945C29907C53A6AC92C65C288F633194 +612F936230946230946230946230946230946231935F2994B0A1BE060902000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000004030400000097929E8B4CCD783AB87D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD +7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7C3EBC7D3FBD +8044BE7634B9925EC7E0D0F0AF85D9CBB0E6C8ABE4AC83D49B69CC7530BA7937BC7835BC +7A38BC8143C08040BF7E3EBE7F3FBF7F3FBF7F3FBF7F3FBF7F3FBF7F3FBF7B39BD8E55C6 +C0A2DF7738BB7C40BE7130B8B28ED8A778D4762FBB8342C2803EC0813FC1803EC17F3FC0 +8B40C14123BD005AAE027AAB006FAC0072AB0071AB0072AC0574AD0069A70476AA779BCD +B897DE9A5ACF7935C18240C48341C58442C5782FC0B48CDCA272D17730BC8241C18241C1 +7D38BF8344C2AA7DD5E7DAF4C9ADE5975FCE7A32C08341C58340C5823FC4803CC48A4BC8 +C8ABE57D36C28442C58441C57B34C1A575D5CBB0E77C36C18442C5823FC48340C58340C5 +8340C58340C5823FC48340C58341C5782FC09F6BD2BC98DF7C36C28442C57931C0BB97DF +A16FD27D38C07B34BFB188D8DDCCF1884BCC7E3AC68444C98241C88342C98342C98342C9 +8342C98342C98342C98342C98342C98342C98241C88444C97C37C6C5A7E58341C48240C4 +8240C48341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8240C48341C5803DC38F54CBBD9BE08544C68240C48341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C5813EC48E53CAC5A6E47E38C0 +8341C3823FC28340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 +8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 +8340C38340C38340C38340C38340C38340C38340C3823FC28543C47A32BEBD99DF9D68D1 +7C35C18441C58340C58340C58441C57A34C0A572D7A78CC2541E8A643395612F93623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094612F93643395541D8AA98EC48058A859248E633194623094623094623094623094 +62309462309463319459258D9571B95C5D5A000000030303000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000020202000000545553 +AB80D77534B87E41BD7D3FBD7C3FBD7C3FBD7C3FBD7D3FBD7D3FBD7D3FBD7D3FBD7C3FBD +7C3FBD7D3FBD7D3FBD7D3FBD7C3EBC7D3FBD7E41BD7B3CBC722FB7864DC2AB83D4F2EBF7 +D3BEE88041BF7E3EBE7632BB7834BB8142C07F40BF7F40BF7F3FBF7E3EBE7F3FBF7F3FBF +7F3FBF7F3FBF7F3FBE7F3FBE7F3FBF7E3EBF8142C0732DB9B996DD996BCC7333B97D40BE +7130B8B18ED8A778D4762FBB8342C2803EC07F3FC08B40C14223BD005AAE027AAB006FAC +0072AB0071AC0072AC0071AC0071AB0173AC0571AC0061A3278CB9B8ADDFAB72D6813EC4 +7E3CC38544C67F3AC3975FCEBC99DD7D3ABF8443C27C38BE8444C2E6D9F2B48EDCC3A5E2 +894FC3B997DCA06CD37F3AC3813DC48442C5803CC38D50CACAAEE67C36C28442C5823FC4 +8644C67327BDBB96DFA371D4782FC08443C5823FC48340C58340C5823FC48441C5813DC4 +803BC3A574D4BB96DF7D36C2823FC48544C6782FBFBC98E09B65CF7C35BF8442C37B34BF +B086D7C4A5E5894CCC7E3AC68545CA8241C88241C88342C98342C98342C98342C98342C9 +8342C98342C98342C98343C97E3AC6B28BDEA576D57C37C28442C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58240C48544C6762DBFCAADE6 +955CCD7B36C18442C58240C48341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58240C48443C57A34C1B68EDDA473D27C36C08441C38340C38340C3 +8340C38340C38340C38340C28340C28340C28340C38340C38340C38340C38340C28340C2 +8340C38340C38340C38340C38340C38340C28340C28340C38340C38340C38340C38340C3 +8340C28340C2823FC28441C37D36C09156C9C8ABE47A32C18543C6823FC48340C58340C5 +8441C57B34C0A26ED6A98FC4551F8B643395623094623094623094623094623094623094 +62309462309462309462309462309462309462309462309462309462309464339556218C +A98EC48660AD59248E63319462309462309462309462309462309462309463319458248B +8659B47A7B7A000000040404000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000101010000001F241ABFA1DB7330B87F42BD7C3EBD +7C3FBD7C3FBD7C3FBD7D3EBD7D3EBD7D3EBD7C3FBD7C3FBD7C3FBD7D3FBD7C3EBD7D3FBD +7F42BE793ABB7331B8844AC1B591D9C7ADE29666CBAB86D5C1A4DCC4A8E08E57C77936BB +8244C07E3EBE7F3EBE7F3FBE7F3FBE7F3FBE7F3EBF7F3EBF7F3EBF7F3FBE7F3FBE7F3FBE +7F3FBE7F3FBF8142C0742FB9BA97DD996BCC7333B97C40BD7C3FBD7130B8B18ED8A778D4 +742DBB7F41C18C40C14123BD005AAE027AAB006FAC0072AB0071AC0072AC0072AC0072AC +0072AC0071AB0072AC0375AD016BA90064A66EACCFCDA1E39048C97A32C17F3DC37F39C3 +C7AAE48545C2752EBB8C4FC6C0A1DF8F55CA762FBDC9AFE58142C07A38BCBE9EDDBD99DF +8340C5803CC37931C0C2A2E2C4A5E37931C08442C58340C58340C58340C58543C6BF9DE1 +9054CB7F3AC38341C58340C5823FC48441C5803BC3823FC4C3A2E2BB96DF7D36C2823FC4 +8341C58442C57C35C1A778D6B187D97D37C08341C38443C3762DBD8A4BC6C3A4E58A4DCD +7832C48444C98342C98241C88342C98342C98342C98342C98342C98342C98342C98343C9 +7C37C59A66D3B994DE772FBF8544C68240C48341C58341C58341C58341C58340C58340C5 +8340C58341C58341C58240C48443C57B35C1AD82D9AA7DD77D38C28443C58240C48341C5 +8340C58340C58341C58341C58341C58341C58340C58340C58340C58341C58341C58341C5 +8342C57C36C19D69D1B790DB772EBD8543C4823FC28340C28340C38340C38340C28340C2 +8340C28340C28340C38340C38340C38340C28340C28340C28340C28340C38340C38340C3 +8340C28340C28340C28340C28340C38340C38340C38340C28340C28340C28340C3813DC2 +8644C3C09FE18D50C9813DC48340C58340C58340C58340C58340C58442C57C35C2C2A4E0 +73489D5D2991623094623094623094623094623094623094623094623094623094623094 +6230946230946230946230946230946230945C29907347A0B8A1CE58238D643295623094 +62309462309462309462309462309462309463319457238B8D62B8797A78000000040404 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000001010100000021261CBE9FDB7330B87F42BD7C3EBD7C3FBD7C3FBD7C3FBD7C3EBD +7D3EBD7D3EBD7C3EBD7C3FBD7C3EBC7D3FBD7F42BE7A3BBB722FB7874DC2B48FD8C5AAE2 +9E72CE7638BA702EB7854CC2B99BD96B29AEBDA1DB925CC9742EB97F40BF7F3FBF7E3EBE +7F3FBE7F3FBE7F3EBE7F3EBF7F3EBF7F3EBE7F3FBE7F3FBE7F3EBE7F3EBE8142C0742EB9 +BA98DD9261C87333B97B3FBD7B3EBD7C3FBD7230B8AF8DD8AC7FD58A3BBF4224BD005AAE +027AAB006FAC0072AB0071AC0071AC0071AC0072AC0072AC0071AC0071AC0072AC0071AB +0273AC0175AD0063A52077B3A2BFDFB88FDD924FCB7832C0C8ACE57D39BFA06DCFBF9FDF +8648C67B37C07E3CC1C8ADE48548C27E3EBE722CB8945DC9D1B8E8A372D46E20BBBF9CE1 +975FCE7E38C28340C58340C5823FC48442C57931C0A271D3BA95DE7A33C18543C5823FC4 +8441C5803BC38340C5C2A1E29358CC772DBF8441C58340C5823FC4823FC4823FC4823EC4 +C9ABE4803BC18341C3823FC28644C47E39C08644C4D7C2ECC09FE37730C48444C98342C9 +8241C88342C98342C98342C98342C98342C98342C98342C98342C98240C9C0A0E38E52C9 +7F3CC38341C58340C58341C58341C58340C58340C58340C58340C58341C58341C58341C5 +813EC48645C6CDB2E77F3BC38240C48240C48240C48340C58340C58340C58340C58341C5 +8341C58340C58340C58340C58340C58340C58341C58341C58341C58341C58240C4C4A4E2 +8C4FC7803BC18340C38340C28340C38340C38340C28340C28340C28340C28340C28340C3 +8340C38340C28340C28340C28340C28340C28340C38340C28340C28340C28340C28340C2 +8340C38340C38340C28340C28340C2823FC28441C37A33BFAC7FD7B289DB762DBF8543C6 +823FC48340C58340C58340C5823FC48543C57931C0C3A4E1754C9F5C2891623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +6230946231945B268F8761ADA78BC356218C643395612F93623094623094623094623094 +6230946230946231945A278D8052AE85818A000000010102000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000101010000001F241A +BEA1DB7330B97F42BD7D3FBD7C3FBD7C3FBD7C3FBD7C3EBD7D3EBD7D3EBD7C3FBD7C3EBC +7D40BD7B3DBC712EB7864CC1B591D9C3A7E1A075CF7636BA7332B97C40BD783ABB8953C4 +C1A6DD6E2FAF763BB3B89AD99E6DCE7B3ABD7D3DBE7F40BF7E3EBE7F3FBE7F3EBE7F3EBF +7F3EBF7F3FBE7F3FBE7F3FBE7F3FBE7F3EBF7F40BF7A37BC9764CBB795DA7536BA7C3FBD +7A3DBC7B3EBD783CBD7E3DBA885ACF2413BD015DAE0179AB006FAC0072AB0071AC0071AC +0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0071AB0275AD0270AA +006DA64C99C3BBA4DFA064D1C8AFE5BB99DEE3D5F2803FC27D3BC18344C47D3AC1C7ABE4 +7F3FBF7E3EBE8142C07B39BD7936BBB693DAA06DD3C6A7E49155CB7931C08340C4813DC4 +8441C58442C58644C67A33C1CAAEE68D50C97E38C28543C5803BC38340C5C2A1E29258CC +7B35C18644C6823FC4823FC58340C58340C5813EC48747C7C9ADE47F3BC18341C38340C3 +823FC28442C37D38C08A4AC6BF9CE0B086DA7A35C58343C98443C98241C88342C98342C9 +8342C98342C98342C98241C88545CA7730C4C2A3E49B66D07D38C28341C58341C58341C5 +8341C58341C58340C58340C58340C58341C58240C48341C57E39C2C7A8E48D51CA803CC3 +8342C58341C58341C58340C58340C58340C58341C58341C58341C58341C58340C58340C5 +8340C58341C58341C58341C58240C48544C67831C0C2A1E39860CD7E39C08340C38340C3 +8340C38340C38340C28340C28340C28340C28340C28340C38340C38340C28340C28340C2 +8340C28340C38340C38340C38340C28340C28340C28340C28340C38340C38340C28340C2 +8340C28340C38340C38340C2CAAEE68441C58340C5823FC48340C58340C58340C58340C5 +8340C58443C57A32C1C3A5E2754B9F5D2891623094623094623094623094623094623094 +62309462309462309462309462309462309462309462309462309464339558238DB8A1CE +6E409C5E2B91623094623094623094623094623094623094623094623094612F93653495 +541D8BAE95C6252921000000010101000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000101010000001F251ABD9FDB722FB87F42BD7C3EBC +7C3FBD7C3FBD7C3FBD7D3FBD7C3EBC7D3FBD7D40BD7E41BD7737BA8449C0B592D9C4A8E1 +9F73CF7839BB7130B87C40BD7C3FBD7B3EBD7D41BE702EB7B491D99C70C86C2BAE763AB3 +BB9DDBBB96DE7A38BC7E3DBE8040BF7E3EBE7F3FBF7F3FBF7F3FBF7F3FBF7F3FBE7F3FBE +7F3FBF7F3FBF7E3EBE7E3EBE7F3FBEC6ACE27739BB7B3FBD7B3EBD783CBC8242BC6A31BE +061FB30059AE027AAA006FAC0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0071AB0172AC0273AD0064A60474AB92ADD8 +F2DDF7A477D5742DBC8140C38242C38141C37B37C0B590DC9C6CCD7936BC7F40BF7F40BF +8142C07531BAAC83D6E7DBF4CBAFE69358CC8543C68949C87C35C1772EBF7E39C28340C5 +8E51CAC3A3E38543C67F3AC38340C5C2A1E29258CC7B35C18543C6823FC48340C58340C5 +8340C58340C5813EC48746C7CAAEE57E39C08441C3823FC28340C3823FC28441C3813DC2 +7429BBAA7CD4B58DDD7A35C57F3CC78444C98241C88342C98342C98342C98342C98342C9 +8444C97B36C5B28ADDD0B6E87932C08443C58341C58341C58341C58341C58341C58341C5 +8341C58240C48443C57D38C2A170D3B893DE7933C08544C58240C48341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C57F3BC3945BCDC3A2E1782FBD8543C4823FC28340C38340C38340C38340C2 +8340C28340C28340C38340C38340C38340C38340C28340C28340C38340C38340C38340C3 +8340C38340C28340C28340C38340C38340C38340C38340C3823FC28442C37931BEAD81D7 +AF84D97A32C08442C58340C58340C58340C58340C58340C58340C58543C57A32C1C3A5E2 +73499D5D2991623094623094623094623094623094623094623094623094623094623094 +623094623094623094623094612F9364339557218CB7A0CE7447A05D2A90623094623094 +62309462309462309462309462309462309462309464339556208CAF98C721251D000000 +010101000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000020203000000827F859D66D67535B67D40BD7D3FBD7D3FBD7D3FBD7C3EBC +7D40BD7E41BD7736BA7230B7A174CFCAB1E49D70CE7738BB7232B87B3EBD7C40BD7A3DBC +7B3EBD7A3DBD7D41BE6F2DB7B491DA9566C46F2FAF793DB46824AC9464C4BD9BDC7937BD +7936BC8041BF7E3EBE7F3FBF7F3FBF7F3FBF7F3FBF7F3FBF7F3FBF7F3FBF7F3FBF7D3CBE +8548C1C4A9E17535BA7C40BD783CBC8243BC692CBE0A3AB4007DAA0276AB0070AC0072AB +0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0071AB0274AD0274AC005BA399BCDDDDC5EB9562CD7731BF +803FC28242C37A35BF9862CEBB99DC742EB98142C08041BF7733BB8649C2B491DAE0D0F1 +A97ED3BB98DDCCB3E7CAB0E6B389DBB186DA9860CF7C35C17328BDB085DAA473D47F3BC3 +C4A4E39258CC7B35C18543C6823FC48340C58340C58340C58340C58340C58341C57D37C2 +DBC8EEA87AD67A33BE8442C38340C38340C3823FC28340C38644C47931BEA473D1E9DEF6 +945DD17B36C58545CA8241C88342C98342C98342C98342C98342C9803EC78B4ECCC2A2E3 +7831C08544C68240C48341C58341C58341C58341C58341C58240C48342C57D39C28F54CA +CBAFE67932C08443C58240C48341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5803DC38A4CC8 +C5A6E28442C3823EC28340C38340C38340C38340C38340C38340C38340C38340C38340C3 +8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 +8340C38340C38340C3823FC28340C3813DC28340C3CBB0E78442C5823FC48340C58340C5 +8340C58340C58340C58340C58340C58340C57E39C29A62D2B096CA57228C643295623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +63319558248D855EACA98EC558238D633295623094623094623094623094623094623094 +623094623094623094643395541E8AB7A0CF4A4E46000000020202000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000040404000000 +777977A36EDB7333B57D40BD7D3FBD7C3EBC7E41BD7D40BD7736B97534B99665CAC6ACE2 +AC85D57332B97333B97B3EBD7C40BD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3FBD7738BB +8D58C6BA9BD97436B2773BB47A40B56C2CAE9362C2BD9BDD8D55C67835BB8041C07E3EBE +7F3FBF7F3FBF7F3FBF7F3FBF7F3FBF7F3FBF7F3FBF7D3DBE8244C0CEB7E67D41BE773CBC +8243BC692CBE0A3AB40079AA0170AC0070AC0072AB0071AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0071AB0373AC006BA73997BEB189CDA581CBC8AAE5803FC37D3AC07B37C09F6CD2 +BA98DC7530BA8041BF7530BAAE84D6CBB3E57E3FC0BA97DE8B51C5742EB97B3ABD7835BB +A476D1AD85D5B996DCCBB0E7CDB3E7B48DDCC8ABE5AF85DA8E52CA7B35C18646C6823FC4 +8340C58340C58340C58340C58340C5823FC58442C57930C0A778D6B288DA7830BD8442C3 +8340C38340C38340C38340C3823FC28442C37B34BF9D67CEC3A3E4955ED27A34C48545CA +8342C98241C88342C98342C98342C98342C9803EC7BC99E19963CF7D38C28342C58341C5 +8341C58341C58341C58341C58341C58342C5803DC4B994DE9A63CF7E39C28442C58240C4 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58240C48544C6772FBFB289DBAB7ED67C35BF8441C3 +8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 +8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 +8341C37E39C0B086D8A677D67C35C18441C5823FC48340C58340C58340C58340C58340C5 +8340C58340C57F3AC29153CEB9A2D157228C643395623094623094623094623094623094 +62309462309462309462309462309462309462309462309463329558238D9675B79B7CBB +551E8B643395612F93623094623094623094623094623094623094623094623094633194 +59258C8E65B8A09EA2000000040404000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000040404000000777876A36FDB7333B57D40BD +7D40BD7F42BE7533B97635B99766CAC2A5E0BA9BDC8953C47535BA7B3FBD7C3FBD7B3EBD +7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7B3EBD793BBCC2A7DE7233B0783CB4 +763AB3793EB56D2DAE8F5DC0C6ACE19B6ACD7530B98143C07F3FBF7E3EBE7F3FBF7F3FBE +7F3FBF7F3EBF7F3FBF8040BF7733BACEB6E6A781D47834B76B2FBF083AB40079AA0171AC +0071AC0072AB0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC +0072AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC0071AC0071AC0273AC0068A6 +3B9CC2B38DD06020A18B5EB9BD9CDD8D51CA742DBC9E6CD1BD9CDD7029B78041BFB28AD8 +AB80D77B3ABF7631BCA476D3B28BD97937BC8142C08041BF7733BB722CB97C3BBD894EC4 +7B39BDAC84D5FFFFFFD7C1EC9D68D1823EC47932C08442C58441C58340C5823FC48340C5 +8340C58340C58442C57931C0AD80D8B188DA7930BE8442C38340C38340C38340C28340C2 +8340C3823FC28443C37B33BF813CC1C09FE29964D37933C48342C98342C98241C88342C9 +8241C88545CA7730C3B28BDEA87AD67A34C18442C58341C58341C58341C58341C58240C4 +8544C6762DBFAC80D8B892DD742BBE8545C68240C48341C58341C58341C58341C58341C5 +8340C58340C58341C58341C58341C58341C58340C58340C58340C58341C58341C58341C5 +8341C58341C58240C48240C48444C6C8ABE47E38C08441C3823FC28340C38340C38340C2 +8340C28340C28340C38340C38340C38340C38340C28340C28340C38340C38340C38340C3 +8340C38340C28340C28340C38340C38340C38340C38340C37E38C09861CDC5A5E3752BBE +8543C6823FC48340C58340C58340C58340C58340C58340C58340C58340C57E3AC29356CF +BAA2D157228C643395623094623094623094623094623094623094623094623094623094 +623094623094623094623094612F93623094BDA9D2612F93623094612F93623094623094 +6230946230946230946230946230946230946230946230945D2B8F703DA3948F99000000 +030303000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000040404000000777876A06ADA7434B67F43BE7635B97533B99A69CBC0A2DF +BA9CDD8B55C5702EB77739BB7B3FBD7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBC793CBCBA9BDB8854BD7335B2773CB4763AB3793DB57133B1 +6C2BAEB292D5A071D0712AB87E3EBE7F40BF7E3EBE7F3FBE7F3EBE7F3EBF7E3EBF8041BF +752FB9A175D2B289D45F1CB90B3DB50079AA0171AC0071AC0072AB0071AC0071AC0072AC +0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC +0072AC0072AC0072AC0071AC0071AC0071AC0072AC0373AC006DA899BBDA8A48B46428A4 +824FB4CAB3E09E6DD19A65D0B894DA8447C1CDB6E5A779D4742FBB7F3FC17E3EC08244C2 +C6AAE27936BC8041BF7E3EBE8041BF8142C08142C0732DB8A678D2C4A6E08B52C5CCB2E6 +B695DAC5A7E3A675D57E38C27B34C18341C58441C5823FC48340C58340C58442C57931C0 +AD80D8AD81D8782FBD8543C4823FC38340C28340C28340C28340C28340C3823FC28543C4 +813EC27D37C0D0B7E9D2BAEB7A34C58342C98343C98241C88342C98342C98240C8884ACB +C4A5E4803CC38341C58240C48341C58340C58341C58342C57F3BC3945BCCBD9AE08241C4 +8341C58341C58341C58340C58341C58341C58341C58340C58340C58340C58340C58341C5 +8341C58340C58340C58340C58340C58340C58341C58341C58340C58340C58341C58341C5 +813EC4BF9DE09359CB803BC18340C38340C38340C28340C28340C28340C28340C28340C3 +8340C38340C28340C28340C28340C28340C38340C38340C38340C28340C28340C28340C2 +8340C38340C3823FC28543C47A32BEC5A5E29258CC803BC38340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C57E3AC29457CFB69DCF541E8A653496612F93 +623094623094623094623094623094623094623094623094623094623094623094612F93 +6231945E2A91BBA6D1633194612F93623094623094623094623094623094623094623094 +6230946230946230946230945C2A8F7847A898949C000000030304000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000030303000000 +636562A677D86F2CB57534B99867CAC1A5E0B899DB8C57C5702EB77738BB7D41BE7B3EBD +7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7C40BD +712FB89D70CEAC88D16B2AAD793EB5773BB4763AB3783DB4773CB46F2FAFAE8DD3AE86D7 +8142C07B39BC8041BF7E3EBE7F3FBE7F3EBE7E3EBF8041BF732FB9B087D69672D6012BAF +007BAB0171AC0071AC0072AB0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC +0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC +0071AC0071AC0071AB0374AD0068A67BB3D2945EBC6E34AA7036AB6829A5A079C7D1BDE7 +E0CFEFB18CD87D3DC07835BE8041C17F3FC17C3BBF884DC6C7ACE27835BB8041BF7E3EBE +7F40BF7E3EBE732EB9AB80D5B188D87531BA7B39BDC5A9E26D2AB6854DC2B28FD8C8ABE4 +A472D47E39C37D37C28544C68340C5823FC48340C5813EC48848C7C4A4E28645C4813EC2 +8340C38340C28340C28340C28340C28340C28340C3823FC28441C3803CC1813DC2AD81D7 +BA96DE7E3BC7803DC78444C98241C88241C98342C9803DC8D1B9EA8C4FC9813EC48341C5 +8341C58341C58240C48544C6772FBFC4A4E39A64CF7B34C18443C58240C48340C58340C5 +8341C58341C58341C58340C58340C58340C58340C58341C58341C58340C58340C58340C5 +8340C58340C58341C58341C58340C58340C58340C58443C57932C0A473D4AF83D8772EBD +8543C4823FC28340C28340C28340C28340C28340C28340C38340C38340C28340C28340C2 +8340C28340C28340C38340C28340C28340C28340C28340C28340C3823FC28442C37A33BE +9C67CFBF9CE07B33C18442C5823FC48340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58341C57E38C3BA97DC7E57A55B268F633194623094623094623094623094 +623094623094623094623094623094623094612F9364329557228D916FB49A7ABA5A258E +633194623094623094623094623094623094623094623094623094623094623094623094 +6231945B2790A389BD31352E000000020202000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000020600BBA9CB965FCEC2A8E0 +B99ADC8A54C47231B87536BA7D41BE7B3EBD7B3EBD7A3DBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7C40BD7231B8A277D1AE8AD26C2CAE +783DB5773BB4773BB4763AB3773BB4773BB47031AFAA86D2C1A0E18243C17B39BC8142C0 +7E3EBE7E3FBF7F3FBF7C3EBF823EBC7F47CA1D57BE0072A80272AC0071AC0072AB0071AC +0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC +0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC +006CA91886B5B49FD56726A4773FAE7339AC692BA6AC8BCDC2A6DDB089D98345C47B3ABE +8040C18040C17C3BBF874CC5C8ADE37936BC8040BF8041BF7B39BD7F3FBFAE84D6B087D7 +7430B98143C07A38BCB08AD8A075CF712FB87332B9834AC0B391D9C8ACE59D68D1742ABE +823FC48442C58340C58442C57B33C1C7A9E48B4CC6803CC28340C38340C38340C28340C2 +8340C28340C28340C38340C3823FC28340C38341C3762CBC9D67CEBD9BE08545CA7D39C6 +8444C98241C88443C97A35C5C4A6E6B792DD7830C08544C58341C58240C48544C67931C0 +B288DBAA7DD77B35C18443C58240C48341C58340C58340C58341C58341C58341C58340C5 +8340C58340C58341C58341C58341C58341C58340C58340C58340C58341C58341C58341C5 +8341C58340C58340C58341C5803DC38F53CABF9DE08543C3823EC28340C38340C28340C2 +8340C28340C28340C38340C38340C38340C28340C28340C28340C28340C38340C38340C3 +8340C28340C28340C28340C28340C38340C38340C3823FC2BE9BE0945ACD7E38C28441C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C5823FC48543C6772EBF +B68DDE8C6AAE58228D633295623094623094623094623094623094623094623094623094 +623094623094623094643395551F8BA88CC38A65AF57218C633295623094623094623094 +623094623094623094623094623094623094623094612F93643395521C88A280C4484D44 +000000020202000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000CCC6D3BD9AE28954C37130B87738BB7C40BD7B3FBD +7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7C3FBD7536BAC3A8E0824CB97436B2773BB4773BB4773BB4 +763AB3773BB4783DB46926AD854FBBC1A2DE8243C17430B98041BF7E3EBE7C3DBE8644BE +6E2DC10A35B30073A80172AC0071AB0072AB0071AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC006FAA067AAF99ABD58144B1 +6F35AA6C30A8B597D39164BE6D31A89C74C3C8B0E09761CE7733BD7835BD7E3EC0884DC5 +C5A9E17631BA8345C17936BC874CC2C6ACE3AD83D67530BA8041BF8041BF7632BB9B6ACC +B28ED86F2DB77F43BF793BBC702EB7844CC1B490D9BC97E08949C87A32C0803BC38645C6 +7E38C2C9ACE58B4DC6803CC28340C38340C38340C38340C28340C38340C38340C38340C3 +8340C3823FC28340C38644C47B33BF965DCBEDE4F7A273D87832C48545CA8444C97A34C5 +A170D6B48DDC7830BF8544C68341C58341C5823FC48748C7C7A9E48342C5823FC48341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58240C4 +8544C67932C0C4A5E28B4DC6803CC28340C38340C38340C38340C28340C38340C38340C3 +8340C38340C38340C28340C28340C38340C38340C38340C38340C38340C28340C28340C3 +8340C38543C4782FBDB790DDA97AD7772DBF8543C6823FC48340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58543C5782FBFBA94E08561AA58228D633295 +6230946230946230946230946230946230946230946230946230946230946230945F2C92 +6A3B99DACEE67448A05D2A91633194623094623094623094623094623094623094623094 +623094623094623094623094643395531E89A888C8464A42000000030303000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000100C9C2D19F70D26D2BB57E42BE7B3FBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC +7C40BD7332B9C2A7E07D44B67437B2773BB4773BB4773BB4773BB4773BB4763AB37A40B5 +6F30B0844EBBC0A0DE9D6DCE7734BB7D3FBE8845BE6D2CC00B3AB5007AAA0272AC0071AB +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0071AB0474AD0063A36DADCD9E64C06427A4B89BD59469C06B2EA7 +763EAE6D30A86D31A8B99BD6BFA0DE9964CF742FBB8244C2C6A8E28548C1742FB98A50C4 +BFA2E08345C07530BA8041BF7E3EBE7F3FBF7F3FBF7E3EBEBFA0DF8750C37739BB7B3EBD +7D41BE7637BA783ABB9E72CEC7ACE3B68EDC8C4DC97A32C07B34C1C9ACE58544C3813EC2 +823FC2823FC38340C38340C38340C38340C38340C38340C38340C38340C38340C3823FC2 +8543C37D36C08C4DC6BC99E0A273D87730C38443C98342C98343C9C6A8E58A4CC8803DC4 +8341C58442C57A33C0CBB0E78D51CA7E3AC38342C58240C48341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C57D39C2A16FD3B993DE +7931BE8543C4823FC38340C38340C38340C38340C38340C38340C38340C38340C38340C3 +8340C38340C38340C38340C38340C38340C38340C38340C3823FC3813DC2894AC5C8AAE4 +803BC38441C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58442C57A33C0AD80DA9878B859258E633194623094623094623094623094 +6230946230946230946230946230946230946230945E2B916C3D9BB299CA541E8A653496 +612F93623094623094623094623094623094623094623094623094623094623094623094 +63329556228B9772BC5E5E5D000000020202000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000101020000006C6771C9AEE4A57ED0 +7230B87C40BD7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3FBD7535B9A277D0A883CF +6F30AF783DB4773BB4773BB4773BB4773BB4773BB4763AB3793EB57031B0834BB9BA9BDB +A981D4803ABD6727C00D3CB50079AA0171AC0071AC0072AB0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0374AD0067A565AECE9E6AC29D79C68857B85C199E692BA66627A46829A56F34AA6729A5 +8553B5B899D5AA7ED7742FBCA273D2A97DD48F58C7BEA0DF8446C17B39BD8143C07E3EBE +7F3FBF7E3EBE8142C0752FBAC0A1E0854DC27739BB7B3EBD7A3DBC7B3EBD7B3EBD7332B9 +7536BAA076CFC5A9E2B891DE8543C6A26FD3AE82D87931BE8543C48543C48442C38443C3 +8340C3823FC28340C38340C38340C38340C38340C38340C3823FC28442C37F3AC17A33BE +B893DEA97CDB7E3AC68342C97A35C5C3A4E5955DCD7E3AC38443C57E39C2A473D4B38ADB +7C37C28443C58240C48341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C57E3AC29359CCC4A5E37C35BF8442C38340C38340C3 +8340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 +8340C38340C38340C3823FC28543C47830BEB68EDCA777D57B33C18442C5823FC48340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5823FC48340C4 +823DC6C2A9DB5F2E91623094623094623094623094623094623094623094623094623094 +62309462309463329559248E9D7EBC906DB35B278F623194623094623094623094623094 +623094623094623094623094623094623094623094623094612F93623193602A96A99DB5 +000100000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000003030300000054584F9C6CCC946ABDAF8AD7702FB87C40BD7B3EBD +7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7536BA8D58C6B898D86A28AD793FB5763AB3773BB4 +773BB4773BB4773BB4773BB4763AB3783DB47336B26A2AACA775CC3433BE003FB00277AB +0071AC0071AC0072AB0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC +0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC +0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC0173AC006BA8D8EEF4 +D7C0E5AA8BCDBA9ED6B699D4B699D4BA9ED68756B87942B0763DAE6F34A9B395D1BC9DDB +D3BDEACCB1E6B692D9864AC27B39BD8041BF7E3EBE7F3FBF7F3FBE7F3FBF8040BF7835BB +AB80D5A57CD17535BA7C3FBD7B3EBD7A3DBC7B3EBD7C3FBD7C40BD7130B87739BBA075CF +C1A3E1C4A5E3C2A2E2813DC27F3AC1772FBD7931BE772FBD803BC18442C38341C38341C3 +8341C38341C38341C38341C38341C38340C38441C38341C37830BEC4A4E2DFCFF1803EC8 +7C37C69761D2C3A4E37A34C1803DC48A4CC8CFB6E87933C08442C58341C58341C58341C5 +8341C58340C58340C58341C58341C58341C58341C58341C58340C58340C58341C58341C5 +8341C58341C58340C58340C58340C58341C58341C58341C58341C58340C58340C58341C5 +8341C58544C67931C0BF9DE09C66CE7C36C08341C38340C38340C28340C28340C38340C3 +8340C38340C28340C28340C28340C28340C38340C38340C38340C28340C28340C38340C3 +803CC28A4BC5C7A9E4813DC4823FC4823FC48340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C5823FC48643C8C3ABDB5F2E91623094 +623094623094623094623094623094623094623094623094623094612F93653496531D8A +AE95C87448A05C2890623094623094623094623094623094623094623094623094623094 +623094623094623094623094623094612F92653099AA9EB6000100000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000020202 +000000373A34AB8CC96321A3A27DC6AD87D6702FB87C40BD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7739BB8851C4BC9DDA783DB4763AB3773BB4773BB4773BB4773BB4773AB4763AB4 +773BB4753AB4773EB47F3BB52319B30064AC017DAA0070AC0071AC0072AB0071AC0071AC +0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC +0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC +0071AC0071AC0071AC0071AC0072AB0272AC006BA83C9BC1C7B4DF8E57B98E62BD9063BD +9063BD8D5EBBB89BD5C6AEDDC7AFDDC0A6DAAE8CCFD8C8E8FFFFFFD4BEEB8244C2752FB9 +7B39BC8142C07F3FBF7E3EBE7F3FBE7F3EBE7F3FBF7B39BD8A50C4BD9EDD6F2DB77D41BE +7A3DBC7B3EBD7B3EBD7B3EBD7A3DBC7C40BD7C40BD712FB86C29B5C5ABE1E3D6F1C3A7E0 +B892DDAF83D9B085D9B58CDC9054CA7B34BF7F3AC17F3AC17D37C07B34BF7C35BF7C35BF +7B34BF8340C38543C48543C48543C47D37C09B65CFC1A0E18240C88E53CEC1A0E27830BF +8443C5BC99DF945CCD7F3CC38342C58240C48341C58341C58340C58340C58340C58340C5 +8341C58341C58341C58340C58340C58340C58340C58341C58341C58340C58340C58340C5 +8340C58340C58341C58341C58340C58340C58340C58340C58240C58341C5803CC39055CB +C6A7E37C35BF8442C3823FC28340C28340C28340C28340C38340C38340C28340C28340C2 +8340C28340C38340C38340C38340C28340C2823FC28543C47830BEB48CDBA97BD67931C0 +8543C5823FC48340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C5823FC48542C8C3AADB5D2A8F633195612F93623094623094623094 +623094623094623094623094623094623094612F93653496AF96C870429D5E2B91623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094613092642F99ACA0B7000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000030203000000A29BAA8248BC +6425A1A27CC7AD87D6702FB87C40BD7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7D42BE6E2BB6B593DA +9465C36F30B0773CB4773BB4773BB4773BB4763AB4773BB3763AB4773DB37D38B42A23B7 +0069AE0278AB006EAC0072AB0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC +0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC +0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC +0071AC0072AB0274AD0067A53D94BE9C81C86728A56C30A86B2EA76C30A86E32A9692BA6 +6221A2814DB4B79AD4A581C9B99DD6BB9FD6B595D3BE9DDF8F57C9732EB97E3EBE8142C0 +7E3EBE7F3FBF7F3FBF7F3FBF7D3BBDBA97DD915FC87536BA7B3FBD7B3EBD7B3EBD7A3DBC +7B3EBD7C40BD7333B98249C0C2A6E0BD9DDEB897DB6C28B59D70CEAB85D5A881D3A57DD2 +BE9FDECCB2E5C8ACE3CDB4E6B38BDA9C65D0A06CD29F6BD1A16DD27F3AC1772EBD7931BE +7930BE7F3BC1772DBD8D4FC7BE9BE09259CFBD9AE18A4CC8A271D3BC98DF752CBE8545C6 +8240C48341C58341C58341C58340C58340C58340C58340C58341C58341C58341C58340C5 +8340C58340C58340C58341C58341C58340C58340C58340C58340C58340C58341C58341C5 +8340C58340C58340C58340C58341C58240C4823FC48544C6C7A9E58543C4823FC28340C3 +8340C28340C28340C28340C38340C38340C28340C28340C28340C28340C28340C38340C2 +8340C28340C28442C37A33BFA473D2B993DE782FC08543C6823FC48340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5823FC4 +833FC6C1A5DC683A97602D93623094623094623094623094623094623094623094623094 +62309463319459248E7F56A8A588C1521B89653496612F93623094623094623094623094 +6230946230946230946230946230946230946230946230946230946231945A258E9B7ABB +4D4F4B000000030303000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000020203000000A098A88147BB7138A96728A5A17CC7AD87D6 +702EB77C40BD7B3FBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7D41BE702EB7B999DC9466C37030B0773CB4773BB4 +773BB4763AB4773BB3763AB4763DB37D38B42A23B70067AD0277AB006FAC0072AB0071AC +0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC +0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC +0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0073AC0072AB0676AE +0063A27EBED6A260BF642BA5783FAE6E32A96B2EA78755B7BA9ED6BCA1D78F62BC5F1F9F +9F7BC59B70C4611FA19265BDBCA0D8BF9EDF8142C1742FB98041BF8040BF7F3FBF8142C0 +722CB8B48EDA9768CB7232B87C3FBD7B3EBD7A3DBC7B3EBD7B3EBD7536BA8C57C5BC9FDD +8C58C56924B4BB9CDD9666CA6D29B6702FB7712FB86F2DB77A3DBC8147C08047BF7A3EBD +9E72CEBEA0DEB897DBB999DCB999DCC2A1E0C4A4E1C2A2E1C7A9E39D68CF8E51C98A4AC7 +9A63CEDECCEFD7C2EEB186DAB690DD813EC48544C68240C48341C58341C58341C58341C5 +8340C58340C58340C58340C58341C58341C58341C58340C58340C58340C58341C58341C5 +8341C58341C58340C58340C58340C58341C58341C58341C58341C58340C58340C58340C5 +8341C58341C58443C57931C0AE84D9A97BD47830BE8442C3823FC28340C28340C38340C3 +8340C38340C28340C28340C28340C28340C38340C38340C38340C3823FC28340C37F3AC1 +C6A7E28E51CA803BC38340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58442C57932C0A978D9A184BD551E8B +6433956230946230946230946230946230946230946230946230946331945C2890A386C0 +8660AD5B278F633194623094623094623094623094623094623094623094623094623094 +62309462309462309462309462309463319556218A8E64B96D6F6B000000040404000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +010101000000353931B392D2682AA5773FAE6728A5A17BC7AD88D66E2BB67739BB7C40BD +7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD783ABB854DC2C1A6DE7234B1783CB4773BB4763BB4773BB3763AB4773DB3 +7D37B42923B70067AD0277AB006FAC0072AB0071AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0071AC0072AC0072AC0072AC0073AC0072AC0072AC0073AC0072AB0577AE96ABD58B48B4 +642AA58959B9B698D4BDA2D88A5BB9682CA46A2FA67239AA733BABC3AADB773DAE6B2CA7 +6C2EA78F61BBBE9FDCA477D27A37BD7733BB7F3FBF8041BF7834BBA477D2AB84D57636BA +7B3FBD7A3DBC7B3FBD7D41BE7231B8AA83D4C7AEE38249C07638BA7230B8BD9FDE8F5CC7 +7637BA7D41BE7C40BD7D41BE7A3DBC793BBC793BBC7A3DBC7434B96E2CB66F2DB76F2DB7 +6E2BB68954C4905EC78F5DC78B57C5B795DBC8AEE4C6ABE3C5AAE3B690DADECEF1FFFFFF +A473D5752CBE7F3BC28545C68341C58341C58240C48341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58442C57D37C2 +9E6AD1B891DB7F3BC18340C38340C38340C38340C38340C38340C38340C38340C38340C3 +8340C38340C38340C38340C3823FC28442C37C35BFA16ED1BA95DF7830C08543C6823FC4 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58442C57932C0AA79D9A185BE551F8B643395623094623094623094 +623094623094623094623094612F936332955B268FB8A1CE623094612F93612F93623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +62309463329555218A956DBE6C6E6A000000040404000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000101010000002E3329B290D3 +6425A3753DAD753CAD682AA59B73C4E2D5F18B55C67332B87D41BE7A3DBC7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD793BBC8147C0 +C1A5DE6D2DAE793EB5763AB3773BB3763AB4773DB37D37B42A23B70067AD0277AB0070AC +0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0071AC0071AC0071AC +0071AC0071AC0072AC0073AB0074AC006EA90D7EAF91A5D2BA8AD0B194D2875BB8692DA5 +6B30A6723AAA7139AA7139AA6C31A7C4ABDC763DAE7338AC753AAD692AA67D48B1AC8BCE +C6ABE1A272D07B39BD7A38BC8143C07D3DBEC2A6E07435BA7C3FBD7C3FBD7839BB6E2CB6 +B08AD7A57BD26D2AB6793CBC7C40BD7637BA905DC7BB9CDD7535BA7C3FBD7B3EBD7A3DBC +7B3EBD7B3EBD7B3EBD7A3DBC7C3FBD7D41BE7D41BE7D41BE7D41BE7738BB7535BA7536BA +7636BA7333B97333B9702FB7631BB0A57CD2EFE9F6E6D9F4C1A1DFBB97DE955CCE7831C0 +7E3AC2813EC48544C68240C48341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58240C48443C57B35C1C4A4E38442C3823FC2 +823FC28340C38340C38340C38340C38340C38340C38340C38340C38340C38340C38340C3 +823FC28442C37B33BFCAADE48D50CA803BC38340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58442C5 +7932BFAB7BDA997AB8531C8A643396612F93623094623094623094623094623094623094 +623094602E936A3A99B49CCB653596602E93623094623094623094623094623094623094 +62309462309462309462309462309462309462309462309462309463319458258C885DB4 +79777C000000020202000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000050703978AA3834BBA6F34A87339AC753BAD +692BA69970C1BFA3DB8B54C67333B87D41BE7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7738BBB593D99363C27032B0783CB4 +763AB4763DB37D37B42A23B70067AD0277AB006FAC0072AB0071AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0071AC0072AC0073AC0072AC0071AC0072AC0072AC0072AC +0071AB0173AC006CA90677AD9AB6D9AE84CC7734A9652BA46E37A9723AAB7138AA7138AA +6D33A8C4ABDC773EAE7136AB7237AB743AAD6F32AA692AA67A43AFB293D0B18DD7894CC5 +742FB97937BCB38FD99B6CCD7637BA7333B98B57C5CAB2E49F72CF712FB87E42BE7B3EBD +7A3DBC783BBB8248C0C1A4E0712FB87D41BE7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7C3FBD7D41BE7738BB8953C4 +BFA1DFB38FD97535BAA77ED3B594D7976AC4BB9DDABF9DE1955CCE894AC77730BF8341C4 +8443C58341C58240C48341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58342C57D38C2B289DBA87AD47931BE8543C3823FC28340C38340C3 +8340C38340C38340C28340C28340C38340C38340C3823FC28543C47931BEBC98DE9E6AD2 +7D36C28441C5823FC48340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C5803CC38E4FCBB79BD3643494 +612E93623094623094623094623094623094623094612F93643395541E8A9573B69472B6 +551F8B643295612F94623094623094623094623094623094623094623094623094623094 +623094623094623094623094623094612F93643395561F8DAF9AC4171B13000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000404040000008483868F58C56B30A57339AC7238AB753CAD6829A67238AABC9ED9 +8C56C67333B87D41BE7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7A3DBC7D40BE6F2DB7A47AD2A883CF6C2BAE773DB5773DB37D37B42923B70067AD +0277AB006FAC0072AB0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC +0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC +0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0071AC0071AC +0072AC0072AC0073AC0072AC0072AC0071AC0071AC0072AC0072AC0071AB0173AC016DAA +0170AA3F9DC3A0BADAB289CE7D3EAE652AA36C35A8733CAB6E34A8C3A9DB7238AB7237AB +7237AB7237AB7339AC743AAD7236AB6322A39468BFC5AADEB894DD7C3BBE9E6DCFA982D4 +6823B39464C9BB9CDD864EC27536BA7C3FBD7A3DBC7A3DBD7B3EBD7A3DBC7C40BDBB9BDD +8953C47739BB7B3FBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7A3DBC7A3DBC7D41BE793BBC7535BA9F72CFC7ADE39869CB6D29B6B795DB8D58C5 +8349C2B897D97233B09362C1C1A6DEC3A4E3B085DA8340C57A33C08240C48443C58341C5 +8341C58240C48341C58340C58340C58340C58341C58341C58341C58341C58340C58340C5 +8340C58341C58341C58341C58341C58340C58340C58340C58341C58341C58341C58341C5 +7F3CC38B4EC8C3A3E38544C4823EC28340C38340C38340C38340C38340C28340C28340C2 +8340C28340C38340C38341C37F39C09055CAC5A6E37D37C28341C5823FC48340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C5823FC48543C57930C1C2A3DF6F439A5E2B92623094623094623094 +6230946230946230946230946230945F2C92A98DC47E55A75B288F633194623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +62309462309464329559238FB19CC5181C14000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000030303000000676768 +9C70C86B2FA6733AAC7339AC7238AB753DAD7034AA7339ABBC9ED98C56C67333B87D41BE +7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7C40BD702EB7 +AC86D6A178CA6A2AAE7B40B47D36B42A24B70067AD0277AB0070AC0072AB0071AC0071AC +0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC +0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC +0071AC0071AC0071AC0071AC0072AC0071AC0072AC0072AC0072AC0073AC0072AC0072AC +0073AC0072AC0072AC0071AC0071AB0072AC0071AB0171AC0270AB0067A6086FAA3E9CC3 +A1BADAAE86CC8141AF662AA3672EA5BA9FD58553B76F32A9753BAD753BAD753BAD753BAD +743AAC6F32A96523A36828A59266BDB797D6CAADE5BEA1DEAA83D4C3A8E17A3DBC7536BA +7C40BD7A3DBC7B3EBD7B3EBD7A3DBC7D41BE6F2CB7A77FD3A47AD1702FB77C40BD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7B3FBD7D41BE7130B8 +8046BFC7AEE3AF89D76F2DB77739BB702EB7BA9ADC9E72CE651FB2B391DAA67DCC6823AA +6D2BAE7E42B7A880CDC8ADE3AD81D98341C57B35C17D38C28443C58342C58240C48341C5 +8340C58340C58340C58341C58341C58340C58340C58340C58340C58340C58341C58341C5 +8340C58340C58340C58340C58340C58341C58341C58240C48545C6772FBFBC99E09258CA +7E38C08340C38340C28340C38340C38340C28340C28340C28340C28340C2823FC28442C3 +7A33BEBA96DEA06ED37B34C18442C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8442C57D36C2C4A7E06F439B5E2B92623094623094623094623094623094623094623094 +5F2D92693A99B69FCD56218C643395612F93623094623094623094623094623094623094 +62309462309462309462309462309462309462309462309462309462309464339558228E +B29EC6171A13000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000E1209B8A3CC6D2EAB743BAC7238AC +7339AC7238AB743AAC6F34AA7339ABBC9ED98C56C67333B87D41BE7A3DBC7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD783ABB874FC3BA9DDB7B3DB37235B4 +2C2BB60065AD0277AB0070AC0072AB0071AC0071AC0071AC0071AC0072AC0072AC0072AC +0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC +0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC +0071AC0072AC0073AC0073AC0073AC0072AC0073AC0073AC0072AC0073AC0072AC0072AB +0071AC0072AC0071AC0070AC0070AC0272AD0471AC0067A7006EA9449FC59EB7DAAF89CD +7A35AB8051B3B393D26524A36B2DA76726A46727A56625A46C2EA88E5EBC8F60BC8F60BD +814CB59E76C5EFEAF4FAF7FCAF8AD86924B47536BA7E43BE7A3DBC7A3DBC7B3EBD7B3EBD +7B3EBD7C40BD7130B8A881D3A881D37231B87C40BD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7A3DBC7B3EBD7C40BD7637BA6E2BB6AD87D6C6ADE2834AC17231B87C40BD +7E43BE6F2CB7AC85D59767CB7536BA7535BAB390D89869C57739B3783BB36F2EAF7A3EB4 +AA84CEC6AAE2C3A4E29A63D07B35C17E39C2813EC48443C58341C58240C48341C58341C5 +8341C58340C58340C58340C58340C58340C58341C58341C58340C58340C58340C58340C5 +8340C58341C58341C58341C58342C57E3AC29F6DD2B892DC7C35BF8442C3823FC28340C3 +8340C38340C28340C28340C28340C28340C38340C3813DC28E51C8C7A9E47B35C18543C5 +823FC48340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58442C57C35C2C3A7E0673995 +5F2C926230946230946230946230946230946230946230945F2C9271459EB59DCC5C2890 +633194623094623094623094623094623094623094623094623094623094623094623094 +6230946230946230946230946230946230946331945A268E8F68B5676768000000030303 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000F130BB7A2CC6D2EAB743BAC7339AC7339AC7339AC7238AB743AAC +6F34AA7339ABBC9ED98C55C67333B87D41BE7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7A3DBC7C40BD7032B9C8AAE05D2DBA0046B10077AB0173AB0070AC0072AB +0071AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC +0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC +0071AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC0073AC0072AC0072AC +0072AC0073AC0073AC0073AC0073AC0072AC0073AB0072AB0072AB0071AB0070AB0070AB +0070AB0070AB0071AB0271AC0272AC0165A50070AA429FC496ABD5D1BAE1AE90D06D31A9 +B08FD0BB9FD6B89AD4B89BD5B89BD5B89BD5B89BD5B79AD4BEA4D8A27CC86325A1C6AEDD +BCA0D6C0A4DF905DC86C28B57B3FBD7C3FBD7A3DBC7B3EBD7B3EBD7B3EBD7B3FBD7839BB +C7AEE37F43BF7A3CBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7C3FBD7B3EBD +702EB78F5CC7C5AAE2A176D07839BB7839BB7C40BD7B3EBD783ABB844CC19D71CE7536BA +7C40BD7B3EBC7535BACFB8E5793CB3773AB37A3EB5783BB46E2CAE7C42B58955BCBC9ED9 +C3A3E29760CF8748C77932C0813EC48443C58341C58240C48341C58341C58340C58340C5 +8340C58341C58341C58341C58341C58340C58340C58341C58341C58341C58341C58341C5 +8341C5803DC38A4CC8C6A8E37C35BF8442C3823FC38340C38340C38340C38340C28340C2 +8340C3823FC28544C4742ABCC09FE19E6AD17C36C28341C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58441C57C36C2AF85DA916FB35A258E633295623094623094 +623094623094612F93653496521B89A98EC4835BAA59258E633194623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +6230946230946230945B298E7847A98D8A8F000000040404000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000030303000000 +6A6A69A172CF682BA3743BAC7339AC7339AC7339AC7238AB743BAC6F34AA7339ABBC9ED9 +8C55C67333B87D41BE7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBD7B3EBD783EBD +823FBB8D72D7054DB30079AA0171AC0071AC0072AB0071AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0071AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC +0072AC0072AB0072AB0073AC0071A9006FA9006FA9006FA9006FA9006FA9006FA9006FA9 +006FA90371AA026FAA0065A4086FA8399BC0DDE2EFCBABDE926ABF895CB88B5EB98C60BA +8657B66426A26427A26427A26426A26A2FA6672BA4BFA4D87238A87F4DB0B292D1AF8AD8 +7A3EBD7535BA7D41BE7B3EBD7B3EBD7A3DBC7B3EBD783ABBC6ABE27A3DBC7A3DBC7A3DBC +7B3EBD7B3EBD7B3EBD7A3DBC7B3EBD7D41BE7637BA7332B9CFB8E7CBB4E58952C47535BA +7A3DBC7B3FBD7A3DBC7B3EBD7536BA8F5BC7C0A4DF702FB77D41BE7C3FBD7738BA9260C9 +B595D77434B17A3DB4793CB47B3FB5773AB37536B26E2DAE8B58BDBB9DD9CAAEE5B58CDD +8849C87A33C0803DC38645C68341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58341C58341C58341C58341C58341C58443C57B35C1B994DE +A16FD27B33BF8442C38340C38340C38340C38340C38340C3823FC28442C37C35BFA372D2 +B38ADB7F3AC38340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C57D38C29357CFB39BCC55208B643395623094623094623094623094623094612F93 +623094AF96C97347A05D2A90623094623094623094623094623094623094623094623094 +6230946230946230946230946230946230946230946230946230946230946230945A278D +8051AE8E8C90000000040404000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000004040400000061645DA679D26629A2743BAC +7339AC7339AC7339AC7339AC7238AB743AAC6F34AA7339ABBC9ED98C55C67333B87D41BE +7A3DBC7B3EBD7B3EBD7B3EBD7A3DBD7B3EBD783DBC8442BC5927BE023FAF007AAA0070AC +0071AC0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0071AC0072AC0073AC +0072AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0072AB0073AC0072AC0070A9 +006FAA0070AA0070AA0070AA0070AA0070AA0070AA0070AA0070AA0070AA006FA90272AB +0570AA0060A02C89B5A391CD6A25A3622AA36B30A7692DA56B30A6733BAB733BAB733BAB +733CAB723AAA7138AABFA4D97B45AE6729A27037A7A07AC4C8B0E09D6FCE6D29B67739BB +7B3FBD7B3EBD7B3FBD7434B9A67DD2A880D37232B87C40BD7B3EBD7B3EBD7A3DBC7D41BE +7B3EBD6C28B59A6CCCCAB2E4A67DD27A3DBC7433B97C40BD7A3DBC7B3EBD7B3EBD7B3EBD +7636BA8E5AC6C0A3DF702FB77D41BE7A3DBC7C40BD702EB79E70CFB797D66B28AC7C41B6 +783BB3793CB4793CB47B3FB57334B17130AF7637B4A076CAC7ACE1B48BDC8B4DC9762EBF +7E39C28341C48443C58240C48341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58341C58341C58341C58240C48443C57932C0AD82D9AF84D87A33BF8442C3823FC3 +8340C38340C38340C38340C38340C38340C3813DC2CAAEE68746C7803BC38340C5823FC4 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C57D37C19A62D2B39ACB +551F8B643396612F936230946230946230946231945A268F7E55A7AB91C6521B89653496 +612F93623094623094623094623094623094623094623094623094623094623094623094 +6230946230946230946230946230946230946230945C298F7747A8928C99000000010101 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000403040000005D615AA77BD2672AA3743BAC7339AC7339AC7339AC7339AC +7339AC7238AB743AAC6F34AA7339ABBC9ED98B56C67333B87D41BE7A3DBC7B3EBD7A3EBC +7B3DBD783DBC8443BC5927BE0047B2027DAB0070AC0071AB0072AC0071AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0071AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC +0073AC0073AC0072AC0072AB0073AC0071AB006FA9006FAA0070AA0070AA0070A90070A9 +0070AA0070AA0070AA0070AA0070AA0070A90070A9006FAA0070A80473A90066A22D93B9 +AC9BD18340AF6A32A6733BAB7138AA7038AA7038A97038A9723AAB6629A39D77C4A582C8 +6425A0743BAA7036A76729A26F35A5A885CAC1A4E08B55C67636BA7A3DBC7D41BE7332B9 +9868CBB18DD86E2BB67D42BE7A3DBC7B3EBD7D41BE702EB77C40BDC2A5E0B08DD77A3DBC +7231B87A3DBC7C3FBD7A3DBC7A3DBD7B3EBD7B3EBD7B3EBD783ABB864EC2996BCC7637BA +7C3FBD7B3EBD7A3DBC7B3FBD7739BBBD9EDC8D59BE7030AF7A3EB5783BB3793BB4793CB4 +793CB47A3EB5793DB3702EAF7637B1A279CAC1A2DEC8ABE5A16ED37F3BC37A34C08443C5 +8443C58342C58240C48341C58341C58341C58341C58341C58341C58341C58341C58341C5 +8341C58240C48342C5803DC4CAAFE58644C3823FC28340C38340C38340C38340C2823FC2 +8442C37B33BFA97BD4B38ADB7830C08543C6823FC48340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C57D38C1985ED1B49CCD56218C643395623094623094 +6230946230946230945B278F7F56A7AF95C856208C643395623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094623094612F93643396531C89A98BC7383D34000000020202000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000001 +000100A89BB57A3EB57137A97339AC7339AC7338AC7338AC7338AC7339AC7238AB743BAC +6F34AA7339ABBC9ED98B56C67333B87D41BE7A3DBC7B3EBD783DBC8543BC5927BE0147B2 +007BAA0070AC0071AB0072AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC +0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC +0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0071AC +0072AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0072AB0073AC +0071AB006FAA0070A90070AA0070AA0070AA0070AA0070AA006FA90070AA0070AA0070AA +006FA9006FA9006FA9006FAA0070A8006FA70372A90065A22E8BB5A2C3DD9563BE6529A3 +733BAB7037A97038AA7038A9723AAB6629A39D77C4A885CA6526A0723AA97137A87239A9 +6F34A76C30A48858B5C0A7D9A77FD27637BB7332B87738BB8C58C5BA9BDC7B3EBD7A3DBC +7D41BE7839BB6F2DB7A379D1BEA0DE9462C97637BA793BBC7C40BD7B3EBD7A3DBC7B3EBD +7B3EBD7B3EBD7B3EBD7C40BD7333B9BEA0DE8248C0783ABB7B3EBD7B3EBD7A3DBC7B3EBD +793BBB793BBCBDA0DD8A53BC7436B17A3DB4783BB3793CB4793CB4783BB3793CB47A3EB4 +793DB46E2CAE7C41B58A55BCB392D5C3A6E2A472D57E38C37933C07F3BC38544C68341C5 +8341C58340C58340C58340C58341C58341C58341C58340C58340C58341C58442C57B34C1 +A97CD6B48CDB772EBD8543C4823FC28340C2823FC28340C3823FC27F3AC1CDB2E78544C6 +823FC48340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58442C57A32C1BE9BE07F59A65A258F633194623094623094612F9364339556218C +B8A2CF7347A05D2A91623094623094623094623094623094623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094643395 +541E8AAB8DC83A3E36000000020202000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000010102000000A89BB37537B37239AA +7238AB7339AC7338AC7338AC7338AC7338AC7339AC7238AB743BAC6F34AA7339ABBC9ED9 +8B56C67333B87D41BE773CBC8543BD5926BE0247B2007BAA0070AC0072AB0072AC0071AC +0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC +0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC +0072AC0071AC0071AC0071AC0071AC0072AC0071AC0072AC0072AC0073AC0072AC0073AC +0073AC0073AC0073AC0073AC0072AC0072AC0073AB0071AC0070AA006FA9006FA9006FA9 +006FA9006FA9006FA9006FA90070AA0070A90070AA0070AA006FA9006FA9006FAA006FA8 +0070A70070A8006FA70271A9016AA50067A173AECF9F67C16428A3723BAB7037A97038AA +723AAB6629A39D77C4A885CA6526A0723AA97036A87036A77037A87137A86C30A562239F +9D75C1C7AFE1A175D17B3EBD6924B3BD9FDE8D59C6783ABB702EB7854DC2B391D9B18ED8 +844BC17231B87C3FBD7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7C40BD +7332B9C5ABE28953C47738BB7B3EBD7B3EBD7B3EBD7A3DBC7D41BE7231B89565CBBEA0DA +6C2AAD7A3DB4793CB4783BB3783CB4783CB4783CB4793CB4783BB37B3FB5773AB37435B1 +6E2CAD854FBAB491D4C3A6E2A97BD8945BCE7830BF7F3CC38544C68341C58240C48341C5 +8341C58341C58341C58340C58340C58340C58442C57C37C29B66D0BB97DF7E38C08341C3 +8340C38340C28340C38341C37E39C1B289DAA473D47D37C28341C5823FC48340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C5823FC48543C6772FBFBD99E1 +825DA759248F633194623094623094623094612E93663596B69FCD673797602D92623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094623094623094623094623094623094623094643395531D89AC8FC9383C34000000 +020202000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000201020000006261639F73CA6A2DA6743BAC7339AC7338AC7338AC +7338AC7338AC7339AC7339AC7238AB743AAC6F34AA7339ABBC9ED98C56C67031B88645BD +5926BD0147B2007BAA0070AC0071AB0072AC0071AC0071AC0071AC0071AC0072AC0072AC +0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC +0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC +0071AC0072AC0072AC0073AC0073AC0072AC0073AC0073AC0073AC0073AC0072AC0072AC +0072AC0073AC0071AB0070AC0070AB0070AA0070AA0070AA0070AA0070AA0070AA0070AA +006FA9006FA9006FA9006FA9006FA9006FAA006FA7006FA80070A80070A70070A8006FA7 +0171A80570A80068A272AECF9F67C06428A3723CAB7037A9723AAB6629A39D77C4A885CA +6526A0723AA97036A87037A87036A77037A87137A8733AA9692CA3753EAAAF8FCCB593D8 +8146C2B390D98B56C56E2BB6B593DAC2A6E0A074CF702DB7783ABB7C40BD7A3DBC7A3DBC +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7D41BE6F2DB7BFA2DF8953C47738BB +7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7D40BE7332B9A176D0A983CF7334B17A3EB4783BB3 +793CB4783CB4783CB4783CB4793CB4783BB3793CB4793CB47B3FB57536B26F2EAE844DBA +B08DD2BC9DDBBD9AE08F54CB7831C0803DC38240C48443C58341C58240C48341C58340C5 +8340C58340C58240C48544C67932C0C2A3E28C4EC6803BC18340C38340C28340C37F39C0 +955CCCC6A8E5762DBF8543C6823FC48340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58543C6782FBFBE9BE1825DA75A258F633194623094 +62309463329556208C9473B69B7BBA541E8A643395623094623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +6230946230946230946331945B288E8257AE7E7A82000000020102000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000020202 +0000003B4036B08CD46425A2753CAD7238AB7339AC7339AC7339AC7339AC7339AC7339AC +7339AC7238AB743AAC6F34AA7339ABB89DD8985EC75521BC0148B2017BAA0070AC0071AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0072AC0072AC0073AC0072AC +0073AC0073AC0073AC0073AC0073AC0072AC0073AC0073AC0073AC0071AC0070AC0071AB +0071AC0071AC0071AC0071AC0071AC0071AC0071AC0070AB006FA90070AA0070AA0070AA +0070AA0070A80070A80070A7006FA7006FA7006FA8006FA8006FA70070A8036FA80068A2 +71AED09F67C06428A3733CAB723AAB6629A39E78C5A784C96526A0723AA97037A87037A8 +7037A87036A77137A87138A8733AA97138A861219F8555B3B291D2C1A4E0DAC8ECB18ED8 +A176D07738BB7130B87D41BE7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7739BB8750C3BC9EDD7D41BE7A3CBC7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7A3DBC7D42BE6C28B5C1A4E09464C26F2DAE7A3EB4783BB3783CB4783CB4793CB4 +793CB4793CB4793CB4793CB4783BB3793DB47A3EB47739B36B28AC7436B19768C3C3A6DE +BC98E08E52CB8442C67932C08342C58442C58342C58341C58240C48341C58341C58442C5 +7D37C2AF85D9A879D47D37C08341C3823FC38543C47931BEC3A2E1965DCE7F3AC38340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58543C6782FBFBE9BE1805AA65A258F63319462309462309463329556218C916EB4 +A183BF541E8B643395623094623094623094623094623094623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094612F93 +602F9265309AA39AAD000000010102000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000010101000000272A23AA8FC47034AC +7339AB7339AC7339AC7339AC7339AC7339AC7339AC7339AC7339AC7339AC7238AB743AAC +6B32AA8042AC8F76D60146B2007BAA0070AC0071AB0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0071AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC +0072AC0073AB0072AB0072AB0071AC0070AB0071AC0070AC0070AB0070AB0070AB0070AB +0070AB0070AB0070AB0071AB0071AC0071AC0071AC0071AC006FA9006FA7006FA80070A8 +0070A80070A80070A70070A70070A7006FA70070A8036FA80068A273AED09F68C16524A2 +703AAA672AA4976EC0A886CA6426A0733AA97037A87137A8733AA9743BAA6D32A6682BA3 +692DA36A2EA46E33A5956BBE9871C0DBCCE9EFE6F7AD88D66A26B47E42BE7D41BE7A3DBC +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7C40BD7130B8 +A176D0AC86D56E2BB67D41BE7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD793BBC +834AC1BB9BDA8046B77739B3793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4 +793CB4793CB4783BB3793CB47B3FB5793CB47231B07232B09768C3C5A9DFC6A9E1AB7ED9 +803DC47B36C17D38C28544C58341C58240C48341C58341C57F3BC38F53CABF9DE1772EBD +8544C48341C37D37C0975FCDC1A0E27B34C18442C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C57F3BC39154CD +B89FD25B278E633195623094612F93623094602E93B9A3CF683898602E93623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +6230946230946230946230946230946230946230946230945F2D916C389FA69EAD000000 +020102000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000040404000000918E948C54C36C32A67339AC7339AC7339AC +7339AC7339AC7339AC7339AC7238AC7339AB7238AC723AAB8241AA5120B10040AE017BAA +0070AC0072AB0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0071AC0072AC +0073AC0072AC0073AC0073AC0073AC0073AC0073AB0072AC0072AB0073AC0071AC0070AC +0070AB0071AB0070AB0070AB0070AB0070AB0070AB0071AC0071AB0070AB0070AB0071AC +0071AC0070AC006FA8006FA6006EA5006EA6006EA5006FA5006FA5006FA6006FA8006FA8 +006FA80070A8006FA80070A8046FA80069A26FAACDBDA9D97639AB6A31A7BC9FD7804DB2 +7036A77238A86D32A66D32A66628A161219E7F4BB08C60B89C73C2C9B0DEC3AADAAC88D1 +AB85D1905FC2C9B2DFA885CFAA82D46C28B5793BBB7C3FBD7A3DBC7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7C40BD7231B8A176D0B390D9702EB77D41BE +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7D41BE6E2BB6A379D2B392D46A27AB +7B3FB5783BB3793BB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4 +793CB4783BB37A3DB47A3DB47231B07131AF7D42B5AB87D0C9AEE3A777D69860D07932C0 +7E3AC28442C58442C58240C48341C5813EC4BD9BE0955CCB7E38C08543C47931BEC3A3E1 +975FCE7E38C28341C5823FC48340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C5823FC4813EC38845C9C0A9D85B288E633195623094 +6230945F2C926D3F9CB9A3CF5C288F633194612F93623094623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094623094623094623094602E9167349C9893B6040601000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +040304000000918D948C55C26C32A67339AC7339AC7338AC7338AC7339AC7339AC7238AC +7339AB7138AC763CAB6E31AD3513B6054BB2007CAB0070AC0071AC0072AC0071AC0072AC +0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC +0072AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC +0071AC0071AC0072AC0071AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC +0073AC0073AC0072AC0072AB0073AC0070AB006FA90070AA0071AC0071AC0071AC0071AC +0071AC0071AC0071AC0070AB0070AC0071AC0071AC0070A9006FA8006FA6006EA5006EA5 +006FA6006FA6006FA6006EA6006EA6006EA6006EA6006EA6006EA6006FA6006FA5006FA7 +0070A8036FA80069A4168AB3A3A6D37E3EAEBDA4D86426A06324A06B30A47C48AE7D48AF +B697D2BC9FD5B89AD5BC9FDBAA85D07D41B68147B9702FAF6824AA8650BBBEA2DA5F1AA5 +A681CDC5AAE2854DC27434B97D41BE7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7C40BD7231B89B6CCDB28ED86F2DB77D41BE7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7A3DBC7C40BD7434B9AE87D69C70C77333B07A3EB4783BB3793CB4 +793CB4793CB4793CB4783CB4783CB4793CB4793CB4793CB4793CB4793CB4783BB3793CB4 +793DB47A3EB5773AB36F2DAE7C41B5AF8BD2BD9FDAC2A2E2965DCE7B35C17D38C28443C5 +8646C6772FBFB791DDA270D17C36C07F3BC19A63CEBD99E07C36C18441C5823FC48340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C5813DC38A49CAC1A9D85C298F633195623094643395541E8AA98EC48863AE +58238D633194623094623094623094623094623094623094623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094612F94 +643295531F897F67CD5E615A000000040404000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000001010100000023261FB499CE +6B2DA8743BAC7339AC7338AC7338AC7338AC7238AC7339AB7138AC753CAB7333AC1A1EB6 +0045B3017BAA006FAC0071AC0072AB0071AC0071AC0071AC0072AC0072AC0071AC0071AC +0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC +0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC +0071AC0072AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0072AC0073AB0073AC +0071AB0070AA0070A9006FAA0070AA0070AA0070AA0070AA0070AA0070AA0070AA0071AC +0071AB0070A8006FA6006FA6006EA5006EA5006FA6006FA6006EA5006FA6006EA6006FA5 +006FA5006FA5006FA5006FA5006FA5006EA5006EA5006EA6006EA6006FA60371A70065A1 +1781AFA7AED7CAA8DB8F64BBAF8ECDAF8FCEC5ADDFC1A7DC9463C39361C37B3FB56A26AB +702FAF773AB37639B27A3EB57739B38953BDC2A7DC6C2EAD7134B08B59BDBA9CD98A53C5 +7231B87C40BD7C3FBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3CBC +986ACB8045BF793CBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7C40BD6F2DB7C8AFE38751BB7233B07A3DB4783BB3793CB4793CB4783CB4783CB4 +783CB4783CB4793CB4793CB4793CB4783CB4783CB4783CB4793CB4783BB3793CB47A3EB5 +773AB36E2CAE702FAF8E5BBFBEA1DBC09FE1975FCF7E38C37C37C17F3BC38E52CAC8ABE4 +7C36C08645C4CEB3E77E38C38340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5813DC38B4ACB +BEA6D658238C643295612F93653496531C8AA386C08B66B058228D633194623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +6230946230946230946230946230946230946230946230946332955520899F77BF5E625D +000000030303000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000191E15B49ACE6727A6753DAD7238AB7338AC +7338AC7238AC7339AB7138AC753CAB7230AD1B29B40072AC037AAA0070AC0072AB0071AC +0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC +0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC +0072AC0072AC0071AC0071AC0071AC0071AC0071AC0071AC0072AC0073AC0073AC0072AC +0073AC0073AC0073AC0073AC0072AC0073AB0073AC0071AB0070AA0071A90070AA0070A9 +006FA9006FA9006FA9006FA9006FA9006FA9006FA90070AB0070AA006EA5006EA5006EA5 +006FA6006FA6006EA5006FA5006FA5006FA6006FA6006FA5006FA5006FA5006FA5006FA6 +006EA6006FA5006FA6006FA5006FA5006FA5006EA50271A60067A2167AACE6F5F7B992D6 +9A6BC79767C56E2CAE7232B07233B07232B0783AB37C40B57A3EB4783BB3793CB4793CB4 +7536B18852BDC1A6DB6B2CAC783FB46C2EAD783EB3C2A8DEB290D8702FB87637BA7C40BD +7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7B3EBDC7AEE3793CBC7B3EBD7A3DBC +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7C3FBD7738BA8E5AC6 +BA9BD97637B1783BB3793CB4793CB4793CB4783CB4783CB4783CB4783CB4783CB4793CB4 +783CB4783CB4783CB4783CB4783CB4793CB4793CB4793CB4783BB37B3FB57A3EB57434B1 +6E2DAE9260C0BA9AD9CDB4E6AE84DA894AC87125BCB690DD9C66CEAC80D7AA7CD77B34C1 +8442C5823FC48340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58341C57C36C2B58DDC8A66AD59238E643295 +5E2B916D3F9BB49CCC623194612F93623094623094623094623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094623094623094623094633295541F899B76C25E615A000000040404000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000008C83948A54BF6D32A7733AAC7338AC7238AC7339AB7138AC753DAB +7230AD1A29B40071AC0274AB006FAC0072AB0071AC0071AC0071AC0071AC0071AC0072AC +0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC +0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC +0071AC0071AC0072AC0072AC0073AC0072AC0072AC0073AC0073AC0073AC0073AC0072AC +0073AB0073AB0071AB0070A90071A90070AA0071A90071AA0070AA0070AA0070AA0070AA +0070AA006FA90070AA006FA8006EA7006FA8006FA6006FA6006FA6006FA5006FA5006FA5 +006FA6006FA6006FA6006FA5006FA5006FA5006FA5006FA6006FA6006FA5006FA6006FA6 +006EA5006EA5006EA6006FA60273A90070A7BEC7E3C09DD99A6EC76924AA7D42B67A3EB4 +793DB4793DB4793CB4783BB3793CB4783CB4783CB4793CB47536B18852BDC1A6DB6B2CAC +773CB3763CB27338B16D2FAD976BC5CAB2E3915EC87130B87D41BD7B3EBD7A3DBC7B3EBD +7B3EBD7B3EBD7A3DBC7B3EBDC7ADE37B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7C40BD7231B89361C9BD9FDA702FAF7B3FB5 +783BB3793CB4783CB4783CB4783CB4783CB4793CB4793CB4793CB4783CB4783CB4783CB4 +783CB4793CB4793CB4793CB4783CB4783BB3793CB4793CB47B3FB57131B07537B1783CB3 +A57DCBC7ACE1A97BD7AA7CD8BB97DDBA96DF8443C5813EC48442C58442C58340C5823FC4 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C5823FC58442C57830BFAD7EDB9A7BB8551F8C6433955C28907B51A5B49CCB541D8A +653496612F93623094623094623094623094623094623094623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094612F93633295 +643396602B8D6741AE7E81A3040300000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000404040000006F716D +9B69CD682CA3743AAC7238AC7339AB7138AC753DAB732FAD1929B40071AC0274AB0070AC +0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0072AC0072AC0073AC +0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AC0073AB0071AC0070A90071AA +0070AA0071AA0070AA0070AA0071AA0070AA0070AA0070A90070AA006FA90070AA006FA9 +006EA7006FA8006FA8006FA8006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6 +006FA5006FA5006FA6006FA6006FA6006FA6006EA5006EA5006FA60071A70072A90073AC +0072AC007AADACB0D97735ABA886CBAB84D06E2CAE7B3FB5793CB4783BB3793CB4793CB4 +783CB4783CB4793CB4793CB47536B18852BDC1A6DB6B2CAC773DB37439B1753AB2763BB2 +6F31AE7E48B6B696D69767CC7232B87A3DBC7C40BD7A3DBC7B3EBD7A3DBC7B3EBD783ABB +C7ADE37B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7A3DBC7D41BE7130B8BA9CDD9464C26F2EAE7A3EB4783BB3793CB4783CB4 +783CB4793CB4793CB4793CB4793CB4793CB4783CB4783CB4793CB4793CB4793CB4793CB4 +793CB4783CB4793CB4793CB4783BB37A3DB4793CB4793CB46E2CAE783CB3A57ECCBB99DB +F1EAF9C1A0E27A31C28644C77931C07931C0823FC48443C58340C58341C58340C5823FC4 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58442C57830BF +B286DD9373B4551F8B66369758238DB39BCB774CA25D2A90623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094623094612F9362309462309463319464339659248E58238D5C288E8560B3E1E4E8 +020100000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000030303000000565854A37ACB6B2EA7733AAC7339AB +7138AC753DAB722FAD1B2AB40071AC0274AB0070AC0072AB0071AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0071AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC +0073AC0072AC0073AC0073AC0071AB0070AC0071A90070A90071A90071A90071A90071A9 +0070AA0071AA0070AA006FAA0070A90070AA006FA9006FA8006EA7006FA8006FA7006FA7 +006FA8006FA8006FA7006FA5006FA5006FA6006FA6006FA6006FA5006FA6006FA6006EA5 +006EA5006EA50070A60071A80073AC0074AC0074AC0376AD0068A55BABCBD5BBE3682BA6 +682AA5A47EC8AB84D06C29AD7738B27A3DB4783BB3793CB4793CB4793CB4793CB4793CB4 +7536B18852BDBEA2DA6A2BAC773DB37439B1753AB27439B1763CB27033AF6F33AEB899D7 +BEA0DE7739BB7434B97C40BD7A3DBC7C40BD7130B8A880D3A87FD37333B97C3FBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBC7637BBB998DB8E5CC07435B17A3DB4783BB3793CB4793CB4793CB4793CB4793CB4 +793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4 +793CB4793CB4793CB4783BB37B3FB57A3DB46620A9A077CAFFFFFFE0D2EFC1A5DDC5A8E1 +A97AD8AD80DA8543C67A32C17D38C27C36C1823FC48544C68340C58340C58340C5823FC4 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C58340C58340C58340C58340C58442C57B34C0A572D7A385C15A258E663697 +531D8AB199CA7549A15D2990623094623094623094623094623094623094623094623094 +623094623094623094623094623094623094612F93623094612F936332956534965E2A91 +5A268F5B268F56208B855EAC9877B9BDA9D2B8A0CFCEC3D7262825000000010101000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000200B1A3BF7537B17239AA7138AC753CAB7230AD1B29B40070AC +0274AB0070AC0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC +0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AC0073AC0071AC +0070AC0071AC0070AB0071AB0071AB0071AB0071AC0071AB0071A90070A90071A90070A9 +006FA9006FA9006FA8006EA7006FA8006EA7006FA7006FA8006FA7006FA7006FA7006FA8 +006FA7006FA5006FA5006FA6006FA6006EA5006EA5006FA50070A70072AA0074AB0074AC +0074AC0073AB0073AB0476AD0067A46EB4D19C60BE682EA7763DAE682AA59E76C5CAB2E1 +854EBB7231AF7C40B5783BB3783BB3793CB4793CB4793CB47536B18751BCC6AEDE6E31AE +763BB2753AB2753AB27439B27439B1753BB2753AB26B2CAC8957BCCBB4E49F72CF702EB7 +7B3FBD7D42BE6F2DB7B391D99D70CE7230B87C40BD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7B3FBD7637BA854EC3CAB1E1 +6E2CAD7A3DB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4 +793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4783BB3793CB4 +7A3EB56E2CADAB87D0A376CABD9DD9BB9DD87D4AB6763FB0AC8CCFA885CDC2A6E0C5A7E3 +9A62D19C65D2823EC5762CBE803CC3803DC38340C58543C68442C5823FC48340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C5 +8340C58340C5823FC48442C57C35C3C3A8DF693B975A258F794FA4AC92C65F2D92623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +612F93623094643395623094602D9258248D521B8971449E7A4FA49D7EBCC1ADD5A68AC2 +9D7EBC59248E7950A2FFFFFF807F81000000040404000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000300 +B2A3C07436B17138AB753CAB7330AD1929B40071AC0274AB0070AC0072AB0071AC0071AC +0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC +0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC +0072AC0071AC0071AC0072AC0072AC0072AC0071AC0072AC0072AC0073AC0073AC0073AC +0073AC0073AC0073AC0072AC0073AC0073AC0071AC0070AC0071AC0070AC0071AB0071AB +0071AB0071AB0071AB0071AB0071AB0071AB0070AB0071AB0070AB006EA7006EA8006FA8 +006EA7006FA8006FA8006FA8006FA8006FA8006FA7006FA7006FA7006EA7006FA7006FA6 +006EA5006FA60071AA0074AB0074AB0074AC0073AB0073AB0073AB0074AC0073AC0476AD +0067A46DB3D0A168C1682DA6743AAC743AAC6D31A87E49B2BA9CD68954BD6B28AC7A3EB4 +793CB4783BB3793CB4793CB4793CB47537B2D9C8E99468C46D2EAD763BB2743AB2743AB2 +753AB27439B1753AB2773CB37033AF753AB2AC8AD0A57AD27636BB7B3EBC702FB7AD88D6 +A277D07130B87C40BD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7C40BD7535BA9B6DCDB08BD27233B07A3EB5783BB3 +793CB4783CB4793CB4793CB4793CB4783CB4783CB4783CB4783CB4793CB4793CB4793CB4 +783CB4783CB4783CB4793CB4793CB4793CB4783BB37A3DB46E2DAEA881CEAC84D06820A9 +CFB8E3AD85D0C3A9DD682BAA682BAA6628A97741B18251B8B99CD8BA9FD8BE9DDEBF9CE1 +8F51CB8A4AC9803BC3762DBE7B34C18442C58341C58341C58341C5823FC48340C58340C5 +8340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58340C58341C5 +7F39C4C5ABDF693B9756208C8B66B0A183BF531C89653496612F93623094623094623094 +623094623094623094623094623094612F93623194633194633295612F93531C895F2C91 +6636979573B6B7A0CDDBD0E7B59ECD8E6BB26A3B995B278F541E8A612F939C7EBBE4D9F1 +A499A90B0D07000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000020202000000565853A67ED2692EA27532AE +1A29B40071AC0274AB0070AC0072AB0071AC0071AC0071AC0071AC0072AC0072AC0071AC +0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC +0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0072AC0071AC +0071AC0071AC0072AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0072AC0073AC +0073AB0071AB0070AB0071AB0070AB0070AB0070AB0071AC0071AC0071AC0071AB0071AC +0070AC0070AB0071AC0070AB0070A9006FA6006FA7006FA8006FA7006FA8006FA8006FA8 +006FA8006FA8006FA8006FA8006FA8006FA8006FA8006EA60072AA0074AB0074AC0073AC +0073AC0073AB0073AB0074AC0074AC0073AC0073AC0476AD0067A46EB4D1A067C1682DA6 +743AAC7339AC743BAC6D30A8753CADB89AD6A67CCD7434B1783BB3793CB4783BB3783BB3 +7B3FB56B29ACAD88D19A70C76C2CAC763BB2743AB2743AB2743AB1753AB1753AB27439B1 +763BB27338B16B2CACAA86CFC5ADE18248C16E2BB6B99ADC9463C97535BA7C3FBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7A3DBD7A3DBC7D41BE6D29B5B28ED9A57ECC6B28AC7B3FB5783BB3783CB4793CB4793CB4 +793CB4783CB4783CB4783CB4783CB4793CB4793CB4783CB4783CB4783CB4783CB4783CB4 +793CB4783BB37A3EB57232B0A47BCCAA82CF712DAE7534B19E70C8B796D69562C2A986CD +6D31AC763FB27137AF6F34AE682BA96425A78351B89267C0BFA4DCC9B1E1B894DDB287DC +A675D67C35C27E38C37B34C07D37C28543C68442C58340C58340C58340C5823FC58340C5 +8340C58340C58340C58340C58340C58340C58340C58341C57F39C4C5ABDF6536945F2C92 +B69FCD6C3D9B602D92623094623094623094623094623094623094612F93623094623094 +6331946535965C299059248D5A258E6737979A7BBAA78BC3C4B1D79674B78158A96F429D +511A885B268F5F2C92623194643395633194B198CAA88BC09C86D0484C50000000010102 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000030303000000474D44B98DD5661AA41D2DB60071AC0274AB0070AC0072AB +0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC +0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC +0071AC0072AC0072AC0072AC0071AC0072AC0071AC0072AC0072AC0072AC0073AC0073AC +0072AC0073AC0073AC0073AC0073AC0072AC0073AC0073AB0071AC0070AC0071AC0071AC +0071AC0071AC0071AC0071AB0071AB0071AB0071AC0070AB0071AC0071AC0070AA006EA6 +006EA5006FA5006EA7006FA8006FA7006FA8006FA8006FA8006FA8006FA8006FA8006FA7 +006FA8006EA7006FA70071AB0072AC0073AC0074AB0073AC0074AB0073AC0073AC0074AC +0074AC0073AC0073AB0476AD0067A46DB2D0A066C1682DA6743AAC7238AC7238AB743BAC +7035AA7035AAD9CAE8BA9AD8702FAF793CB47A3EB4783BB37B3FB56D2BADB593D5996FC7 +6C2DAC763BB2743AB2743AB2743AB1743AB1753AB1743AB17439B1753AB2763CB36D30AD +8049B7B594D7A075D0BB9CDD6925B47E43BE7D41BE7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD793CBC +8045BFB99ADA834BB97739B3793CB4783CB4783CB4793CB4783CB4783CB4783CB4783CB4 +783CB4793CB4793CB4783CB4783CB4783CB4783CB4793CB4783BB37A3EB47436B17E43B7 +CBB3E27431AF7C3EB57533B0915CC0BC9DD9671EA8CAB2E18352B97035AE733AB0733AB0 +753DB1763EB16E34AD6B2FAB6D33AC682BA98D5FBEA481CBAA86CECEB6E6B48DDB9E68D3 +9B64D1782FBF7B35C1803BC37F3BC38442C58543C68340C5823FC48340C58340C58340C5 +8340C58340C58340C58341C57E38C3C0A2DE73489E57218DB9A3CF623194612F93612F93 +623094623094623094612F936230946433956331945E2B915B278F511A88764BA28863AE +B8A2CEB7A1CE9C7CBB8058A956208C5B278F59248D5E2B91653496633194623094643295 +57228C9877B88E6BB2B59CC96740AA908CA0000000030203000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000030203000000 +4C4A448878DB0937A7006FAE0275AB0070AC0072AB0071AC0072AC0071AC0071AC0071AC +0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC +0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC +0072AC0071AC0072AC0072AC0073AC0073AC0072AC0072AC0073AC0073AC0073AC0073AC +0072AC0073AC0073AB0071AC0070AB0070A90070AA0070A90070AB0070AC0070AB0070AC +0071AC0071AC0070AB0071AC0070AA006FA8006FA5006EA5006FA6006EA5006FA7006FA7 +006FA8006FA7006FA8006FA8006FA8006FA8006FA8006EA8006FA8006EA70070AA0072AC +0071AB0072AB0073AC0074AC0073AC0074AC0074AC0074AC0074AC0074AC0074AC0476AD +0068A571B6D2A067C1682DA6743AAC7339AC7339AC7238AB743AAC7238AB6626A4966BC0 +B695D66F2EAE7232B07B3FB57B3EB56D2BADB491D4996FC76C2DAC763BB2743AB2743AB2 +753AB27439B1753AB2763CB2763BB2753BB27438B16A2AAC6C2DAD8654BBEAE0F3F3EDF9 +8C58C67738BB6E2BB6793CBC7B3FBD7C3FBD7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7C40BD7231B89260C9C2A7DD6A26AB +7B40B5783BB3793CB4793CB4793CB4783CB4783CB4783CB4783CB4793CB4793CB4793CB4 +783CB4783CB4793CB4783BB37A3EB47536B17B3FB5BEA0DA864CBA7838B27C3EB47432B0 +9461C2BD9ED96D28AC8951BC966DC5692CAA743CB17239AF733AB07239AF733AB0743BB0 +743BB0753DB16D31AC6628A96D31AC733BAF946AC2B99ED7B596D6C7AAE5B086DA8C4CCA +8F52CB7931C0772DBF7F3BC38341C58341C58442C58340C5823FC48340C58340C58341C5 +7B35C1A069D5A68BC2764BA2A88CC45D2990623094612F93623094633295633295623194 +623094541D8A5B278F6D3E9B8E6AB2BAA4D0AD93C7AB91C670429D633295541E8A5B278F +643395623194633194623194612F93623094623094643395551F8BAB91C67D54A6B098C9 +73419E9D85B1252823000000010101000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000104000000060B57075CBD007BA80172AB +0071AC0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0073AC +0072AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0072AC0073AC0071AB0070AB +0071AC0070A9006FA7006FA7006FA8006FA8006FA80070AA0071AA0070AA0071AC0070A8 +006EA5006EA5006FA6006FA6006EA5006FA6006FA5006FA6006FA8006FA7006FA8006FA7 +006FA8006FA8006EA8006FA8006EA7006FA80072AC0071AB0072AC0071AB0072AC0073AC +0074AC0073AC0074AC0074AC0074AC0074AC0074AC0070AA0D7EB1D7DAED824BB46F34A9 +733AAC7339AC7339AC7339AC7238AB7339AC753DAD6829A59265BDC0A4DB905EC1702FAE +7D43B66D2AADB491D5996FC76C2DAC763BB27439B1753AB2753AB2773DB3753BB26C2DAD +6C2CAD7034AF7A42B4AA88CFB596D7C9ADE3A277CFE5D9F1EAE2F2B18ED6B38FDA834AC1 +7738BB7231B87B3FBD7D41BE7B3EBD7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7A3DBC7C40BD7536BAA981D3A379CB7030AF7B3FB5783BB3793CB4 +793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4793CB4783BB37A3EB4 +7536B17A3FB5BFA1DA8951BC7432B07C3EB47B3CB47432B09360C2BE9FDA722FAF7331AF +A378CA9A71C56B2EAB743CB17239AF733AB0733AB0733AB0733AB07239AF743BB0753DB1 +733BB07239AF6C31AC6426A86C31AC8453B89D76C8C7AFE0C0A5DCB68EDDBB95E09358CD +7F39C37C35C17931C0803CC38544C68340C58340C58441C57B35C1A26CD79F81BE906CB3 +8E6AB256218C64339564339563319457228D56218C5D2A916332959D7EBCA78CC3BFABD4 +9D7EBC784DA3612F93511A895F2C92612F93643395633194612F93623094623094623094 +6230946230946230945D2A9172469FAD93C78963AEA689C2470E819D79C250544C000000 +030303000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000030000000005510057BB0179A9016FAC0071AC0072AB0071AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC +0073AC0073AC0073AC0072AC0072AC0073AC0071AC0070AB0070AB0071AC0070A9006FA7 +0070A80070A70070A7006FA7006FA7006FA7006FA8006EA8006EA6006FA5006FA5006FA6 +006FA6006FA6006FA6006FA5006FA6006FA8006FA7006FA8006FA8006FA8006FA7006FA8 +006FA70070AA0072AC0071AB0071AB0072AC0071AC0071AC0073AC0073AC0073AC0073AC +0074AC0074AC0074AC006EA9198CB7B49FD56725A4753DAD7238AB7339AC7339AC7339AC +7339AC7339AC7238AB753CAD6B2DA78756B7B89AD59565C47130AF7130AFB491D5996FC7 +6C2CAC773DB3783EB37236B07032AF6A2BAC7135B0986EC5996EC5C2A6DEC6ABE1A67CD3 +9563C96E29B58951C4BB9BD98F5ABFC3ABDA9469BFC2A8DEC4AAE09F72D07637BB7130B8 +7536BA793BBB7D41BE7A3DBC7B3EBD7A3DBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC +7B3EBD7C3FBD6E2BB6BC9DDD9969C46F2DAE7B3FB5783BB3793CB4793CB4793CB4793CB4 +793CB4793CB4793CB4793CB4793CB4783BB37A3EB47536B17A3FB5BFA1DA8950BC7431B0 +7D3FB57A3BB37B3DB47432B09562C2B795D66D28AC7C3EB48245B8C7B0E06E33AD733AB0 +733AB0733AB0733AB0733AB0733AB0733AB0733AB07239B0733AB07239AF743BB0763EB1 +743BB06D32AD6C30AC682CAA6D32AC9A72C59870C3BA9CDACBB3E4A979D7A979D88E50CA +772DBF7E39C27D38C2823FC47E3AC2A16BD5AE94C7A386C06D3F9C5F2C915C289057218C +5D2A918660ADAD92C7D1C3E0B8A1CE9776B8845DAB551F8B5A268E5B278F612F93653496 +623094612F93623094623094623094623094623094623094623094612F9364339557218C +AC92C7784DA38D69B19F80BD521C887141A19A91A3000100000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000300000000034F0059BD +007AA9006FAB0072AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC +0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0072AB0072AB +0073AB0071AB0070AC0071AB0071AC0070AB0071AC0070A9006FA70070A8006FA80070A8 +006FA80070A8006EA7006FA7006FA7006FA8006FA7006FA5006FA5006FA6006FA6006FA6 +006FA6006FA6006FA8006FA7006FA8006FA8006FA8006EA70071AA0072AC0071AB0072AC +0072AC0071AC0072AC0072AC0071AC0073AC0074AC0074AC0073AC0074AC0074AC006EA9 +178AB6BAA8D96B2AA6743CAD7339AC7339AC7339AC7339AC7339AC7339AC7339AC7238AB +753BAD6C2FA86B2EA7B595D3996BC65E15A5B592D59A70C76C2CAC7034AF6524A97E48B6 +8B5ABDB999D8D4C1E7D3BEE9B08BD78950C37A3BBC7331B87736BA7C3EBC8B54C4C5ABDF +6A23AAA174CAA079C86527A57B46B2AF90CFC3A9E0BA9BDD8F5AC88147C16F2DB67A3DBC +7B3EBD7C40BD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3FBD7739BB8851C4 +BDA0DB783CB37638B2793DB4783BB3793CB4783CB4783CB4793CB4793CB4793CB4793CB4 +783BB37A3EB47536B17B3FB5BFA1DA8950BC7431B07D3FB57A3BB37B3CB47B3DB47635B1 +8B54BDE1D3EE8044B77A3BB37635B1905BC0BA9ED9692DAA743CB17239AF733AB0733AB0 +733AB0733AB0733AB0733AB0733AB0733AB0733AB07239AF733AB0733AB0743BB0753DB1 +743BB06A2DAB682BAA6F36AD733BAFA886CEAE8ED0BB9CDACAAEE69E69D2965BCF8948C8 +7429BD7B34C2C9B1E2BDA9D042057E6D3F9C784DA3AD93C7B9A3CFA487C1AA8FC57549A1 +5E2B9158238D59248E653496633194623094623094612F93623094623094623094623094 +6230946230946230946230946230946230946332955A268FBBA5D0643295906DB39F81BE +56208B5F2A95AFA0BD0B0E08000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000010400000000034F0059BD007AA9006FAB0072AC0071AB0071AC +0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC +0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC +0072AC0071AC0071AC0071AC0072AC0072AC0071AC0072AC0072AC0073AC0073AC0073AC +0073AC0073AC0073AC0073AC0073AC0072AB0073AC0073AC0071AC0070AC0071AB0070AB +0070AB0070AB0071AB0070AC0070A9006FA70070A8006FA7006FA8006FA7006FA8006FA8 +006FA8006FA8006FA7006FA7006FA7006FA5006FA5006FA5006FA5006FA6006FA8006FA7 +006FA8006FA8006EA70070AA0072AC0071AB0072AC0071AC0071AC0071AC0071AC0072AC +0072AC0071AC0072AC0073AC0074AC0073AC0074AC006EA9188BB7B9A6D96A29A6743CAD +7339AC7339AC7339AC7339AC7338AC7338AC7339AC7339AC7339AC753CAD7339AC6E33A9 +B596D3A67DCDB28DD3966BC56B2CAB9568C3B99AD8BC9EDCC0A4DF905BC78A51C37736BA +702CB67B3CBB7D3FBD7E41BD7E40BD7939BB8952C4C4A9DE7533B07230AFA67BCCAB89CE +6628A76324A57E4AB48C5EBCBFA6D9BEA3DBAA82D57D41BF783ABC7232B87D41BE7B3FBD +7B3FBD7B3EBD7A3DBC7B3EBD7B3EBD7A3DBC7C40BD7433B98B56C6BD9FDB7639B2793CB4 +783BB3793CB4783CB4783CB4783CB4793CB4793CB4783BB37A3EB47536B17B3FB5BFA1DA +8950BC7431B07D3FB57A3BB37B3CB47B3CB47B3CB47D3FB5702DAEBFA0DA9461C27432B0 +7D3FB57330AFBB9BD88A5ABC6E33AD743BB07239AF733AB0733AB0733AB0733AB0733AB0 +733AB0733AB0733AB0733AB0733AB0733AB0733AB07239AF733AB0743CB0743CB0733AB0 +7239B0682BAA6425A8763FB1804EB6B292D3C1A8DCBC9CDDC19EE3A878D6BD9AE0CBBDD9 +A486C1B198CAB9A2CF7F56A86D3F9B551F8B531C8A5E2A91623094633295633194612F93 +623094623094623094623094623094623094623094623094623094623094623094623094 +62309463319558228D8660ACAB90C54A10839776B89F81BE56208B5A278D9168BA747672 +000000040404000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000103000000 +0004500059BD007AA9006FAB0072AC0071AB0071AC0071AC0071AC0071AC0072AC0072AC +0072AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC +0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0072AC +0071AC0071AC0072AC0073AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC +0072AB0073AC0072AB0071AA0070AA0070AB0071AC0071AC0071AC0071AC0071AC0071AC +0071AC0070A9006FA70070A8006FA7006EA8006FA8006FA8006FA8006FA7006FA8006FA8 +006FA8006FA7006FA7006FA6006FA5006FA5006FA6006FA8006FA8006FA7006FA80072AC +0071AB0072AC0072AC0071AC0071AC0071AC0071AC0071AC0071AC0072AC0071AC0072AC +0073AC0074AC0074AC006EA91788B5B8A4D76A2AA6743CAD7338AC7339AC7238AB7339AC +7339AC7339AC753CAD753CAD6D31A96C2EA86D30A86B2FA76525A3AE8ECEFCFBFCB494D7 +C6AEE1B391D89D6DCD8043BE702CB67939BB7939BB7D40BD7F42BE7D3FBD7C3EBC7D3FBD +7D3FBD7939BB8B54C5BFA2DB6F2AAD7F43B6712DAE9E70C7E5DBF08859BB6729A77137AC +6526A57740B0A27DC9CAB3E0BA9ADB9665CB7130B87536BA7333B97B3EBD7C40BD7A3DBC +7B3EBD7B3EBD7A3DBC7E43BE6D2AB6B594DAA074C96D2BAD7A3EB4783BB3783CB4783CB4 +783CB4793CB4783BB37A3EB47536B17B3FB5BFA1DA8950BC7331B07D3FB57A3BB37B3CB4 +7B3CB47B3CB47A3BB37D3FB56F2BADBB9AD89461C27432B07B3DB47B3CB47634B1CAB2E0 +763FB17035AE733AB07239AF733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 +733AB0733AB0733AB0733AB0733AB0733AB0733AB07239AF733AB0753CB1763EB17138AF +6F34AE6A2EAB6425A77C48B5946BC19B73C6FAF7FDA285BF8761AD6B3C9A521B895D2990 +5E2B91643395643395623094612F93623094623094623094623094623094623094623094 +6230946230946230946230946230946230946230946230946230946331945B268F9878B9 +9776B84B12849675B79F81BD551F8B5C2A8F8052AE88848C000000010101000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000300000000044F0059BD007AA9006FAB0072AC +0071AB0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC +0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC +0071AC0071AC0071AC0072AC0072AC0071AC0072AC0071AC0072AC0072AC0073AC0072AC +0073AC0073AC0073AC0073AC0073AC0073AC0073AC0072AB0073AC0072AB0070AA006FA9 +006FA90070AA0070AB0070AB0070AB0070AB0070AB0070AB0070AB0071AC0070A90070A7 +0070A8006EA7006FA8006FA8006FA8006FA8006FA8006FA7006FA7006FA8006FA8006FA7 +006FA6006FA6006FA5006FA7006FA8006EA70070A90072AC0072AC0072AC0072AC0072AB +0071AC0071AC0071AC0072AC0072AC0071AC0072AC0071AC0072AC0074AC0174AC006DA8 +2793BBBDA8DA6929A5743CAD743AAC753CAD753CAD7238AB7035AA6E33A96728A46627A4 +8756B78E60BB8D5EBABEA2D9C9B2DFA57DD0C8AEE4EFE6F67533B97634B97533B87C3DBC +7F43BE7D3FBD7D3FBD7D3FBD7C3EBC7C3FBD7C3FBD7C3EBD7D3FBD7B3CBC8045BFE2D5F0 +8D57BE7635B17D40B5722FAF9967C5BFA2DA8656B96B2EA97842B17036AC6C30A96B2FA9 +8757B9B496D5CBB3E3AA84D49360CA783ABB7332B9793BBC7C3FBD7B3FBD7A3DBC7A3DBC +7C40BD7535BAB594D99463C27435B17A3DB4783BB3783CB4783CB4783BB3793DB47537B2 +7B3FB5BEA0DA8950BC7331B07D3FB57A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47D3FB5 +702BADBD9DD99461C27432B07B3DB47C3EB47432B09D6EC7AA87D06E33AD743CB07239AF +733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 +733AB0733AB0733AB0733AB0733AB0733AB07239AF733AB0733AB0743CB1763EB17138AF +6323A78A5BBCD3C1E89976BB511B88612F93653496623094623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094623094623094623094612F936331945B278FB7A0CE62309456218C9472B69F81BD +541E8B673797541D8AAF94C72E322B000000010101000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000400000000024E0059BD007AA9006FAB0072AC0071AB0072AC0072AC0072AC0071AC +0071AC0072AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC +0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC +0072AC0072AC0071AC0072AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC +0073AC0073AC0072AB0072AB0073AB0070A9006FA90070AA0070AA006FA9006FA9006FA9 +006FA9006FA9006FA9006FA9006FA90070AB0071AC006FA9006FA7006FA8006FA8006FA8 +006FA8006FA8006FA8006FA8006FA8006FA7006FA7006FA8006FA8006FA8006EA6006FA5 +006EA70070A90072AC0071AB0071AB0071AB0071AB0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0071AC0072AC0476AD0067A49AC9DEB484CD682DA6763DAE +6D31A96627A46626A47339AB7A44AF8757B7BC9FD7B89AD4BC9DDCBD9FDEBC9EDD8952C5 +8449C27C3EBEB08BD59867C3BB9BDB7E41BE7B3CBC7E41BD7C3EBC7D3FBD7D3EBD7D3EBD +7C3FBD7C3FBD7C3FBD7D3FBD7D3EBD7F42BE712EB7B48FD9A074C8722EAF7C3DB47D3FB5 +722FAE7938B3BC9ED98757BA6A2DA8763EAF733AAE753DAF6C31AA6D32AA7842AF9C74C5 +BCA2D9BFA4DE9A6BCD8046C07332B97738BA7C40BD7B3FBD7C3FBD7A3CBC783ABCCFB8E5 +7537B1783BB3793CB4793CB4793CB4793CB4793CB47A3EB4BC9DD98A51BC7331B07D3FB5 +7A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47D3FB5702BADBC9CD99563C37432B0 +7B3DB47A3BB37D40B56B25ABBE9FDA9368C2672AA9753CB17239AF733AB0733AB0733AB0 +733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 +733AB0733AB0733AB0733AB0733AB0733AB07239AF753CB16F35AEC1A7DC864FBEB59CCE +57228C653496612F93623094623094623094623094623094623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +6331945B288F8159A9A68AC2602D9256218C9472B69F81BD541E8B6433955D2A8F7848A8 +939097000000040304000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000010001050000000004500059BD007AA9 +006FAB0072AC0071AB0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC +0073AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0072AB0072AB0073AB +0070A9006FAA0070AA006FA90070A90070AA0070AA0070AA0070AA0070AA0070AA0070AA +0070AA006FA9006FA9006FA9006EA7006FA8006FA8006FA8006FA8006FA8006FA8006FA8 +006FA8006FA8006FA8006FA7006FA7006EA7006FA8006EA7006FA90072AE0072AD0072AD +0072AD0072AD0072AC0071AB0071AB0071AB0071AB0071AB0071AB0071AB0071AB0071AB +0071AB0072AB0474AD006CA791BBD87F3AAE6930A76A2DA68A5AB9AD8BCDA47FC8B899D6 +CAB3E3BB9CDC925ECA9664CB7534BA6E2AB6702DB77838BB7433B98B55C5C0A3DC671FA8 +8F5ABFBFA0DD7D3EBD7A3BBB7E40BD7C3EBC7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD +7D3FBD7F42BE712EB7B38ED8A073C8722EAF7C3EB47A3BB37D3FB57838B27939B3BC9ED9 +8757B96A2DA9753DAF7239AD743BAE733BAE7137AD6C30AA6527A6804DB4B08FD2C7B0E0 +B492D98852C47434BA7433B97434B97E43BE7738BA9665CAB391D57232B07A3EB4783BB3 +783BB37C41B66A26ABC1A4DC9461C2712DAE7D3FB57A3BB37B3CB47B3CB47B3CB47B3CB4 +7B3CB47B3CB47B3CB47D3FB5702BADBC9CD98F5ABF7533B07B3DB47B3CB47B3CB47A3BB3 +8043B7B999D67D48B57036AE733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 +733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 +733AB0733AB0743CB1692CAA9B73C6AE8AD27334B2B99ED36A3C99602D92623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094623094623094623094623094623094623094612F93643395531D8A9C7CBB8B66AF +58238D58238D9472B69F81BD541E8B6433955E2C906D3B9F9A8DA60A0C08000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000010001020000000004500058BD007AA9006FAB0072AC0071AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC +0073AC0073AC0073AB0072AC0072AB0073AC0073AB0070A9006FAA0070AA006FAA0070AA +0070AA0070AA0070AA0070AA0070AA0070AA0070AA0070AA006FA90070AA006FA9006FA8 +006EA7006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8 +006EA7006FA8006EA7006FA90072AC0073AF0075B00075B00075B00075B00075AF0074AE +0074AF0074AE0074AE0074AE0074AF0072AC0072AC0072AC0072AC0072AC0475AD0066A4 +92B7D6A571C5B89DD7CBB5E1B695D9A377D2AC84D68B54C5702DB87535BA7433B97433B9 +7C3EBD7D41BE7D40BE7B3DBD7737BB8952C4C3A7DD7533B07533B08C55BDBFA1DD7C3EBD +7A3BBB7E40BD7C3EBC7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7D3FBD7F42BE712EB7B490D9 +A074C8722EAF7C3EB47B3CB47A3BB37C3DB47838B27939B3BC9ED98757B96A2DA9753DAF +7239AD733AAE7239AD743BAE763EAF6E33AB6C30AA6B2EA9956ABFBCA1DAC9B1E3A176D1 +9461CA702EB7783ABB6D2AB5A57BD3B492D46B28AC7C40B57B3FB56E2CAE996DC6B28DD3 +7635B17C3DB47A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47D3FB5 +702BADB897D7C8AFE0702DAE7C3EB57B3CB47A3BB37D3FB56F2BADA073C9B294D46425A7 +763EB17239AF733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 +733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB07239AF733BB06F34AD +C1A7DB814ABA6825ABA982D1906FB256218C633295623094623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094623094623094623094602D92683898B39BCB68389862319456218C9472B69F81BD +541E8B643395643396521C88A280C342463D000000020202000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000200010000001A000477 +0058B5007AAA006FAB0072AC0071AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0071AC0072AC0072AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC0072AB0072AB +0073AC0071AB0070A9006FAA0070AA0070AA0070AA0070A90070A90070AA0070AA0070AA +0070AA0070AA0070A9006FA90070AA006FA9006FA8006EA7006FA8006EA7006FA8006FA8 +006FA8006FA8006FA8006FA8006FA8006FA8006FA8006EA7006FA8006EA7006FA90072AC +0073AB0072AB0074AE0075B00074AF0074AF0074B00075B00075B00075B00075B00075B0 +0075B00074B00074B00074B00075B00175B00072AD1379B1DEF2F5EFE1F67E43C07F42BF +7839BC6F2CB7702DB77737BA7D40BE7C3EBD7B3EBD7B3EBD7B3DBD7A3CBC7B3DBD7B3DBD +7636BA8C56C6C1A4DC712EAE7F42B67330AF8C55BDBFA0DD7C3EBD7A3ABB7E40BD7C3EBC +7D3FBD7C3FBD7C3FBD7D3FBD7D3FBD7F42BE712EB7B490D9A074C8722EAF7C3EB47B3CB4 +7B3CB47A3BB37C3DB47838B27939B3BC9ED98757B96A2DA9753DAF7239AD733AAE733AAE +7239AD733AAE743BAE753DAF692CA87137AC7740B0AB89CEB79AD5BFA1DF8F5AC7844AC2 +6C28B5B897DA8A55BC7335B1702FAE996CC6B693D57432B07A3BB37B3CB47A3BB37B3CB4 +7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47939B28145B7C5AADE7433B0 +7C3EB47B3CB47B3CB47A3BB37D3FB5722FAFAE88D19C75C8692CAA753DB17239AF733AB0 +733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 +733AB0733AB0733AB0733AB07239AF753CB1692CAA9B73C7B08CD36F2FAF6E2EAEAC87D2 +916FB358238D633295623094623094623094623094623094623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +5E2B9173469FB7A0CE56208B66369756208C9573B69E80BD551E8B6433956331945B288F +8258AD7B777F000000010101000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000020002000000170030A20072BE0075A80070AB0072AC0071AB +0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC +0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC +0072AC0072AC0072AC0071AC0071AC0072AC0072AC0071AC0072AC0072AC0073AC0072AC +0073AC0073AC0073AC0073AC0073AC0072AB0073AC0073AC0070AB006FAA006FA90070AA +006FAA0070AA006FA9006FA9006FA9006FA90070AA0070AA0070AA006FA9006FA9006FA9 +0070AA006FA8006EA7006FA8006EA7006FA8006FA8006FA8006FA8006FA8006FA8006FA8 +006FA8006FA8006EA7006FA8006EA7006FA90072AC0073AB0072AC0072AB0073AC0075B0 +0075AF0074B00075AF0074AF0074AF0074AF0074AF0074AF0074AF0075AF0075AF0075AF +0074AF0377B1006BAA6DAFD0AC74CC9163C2AA81D47230B87D40BE7C3FBD7C3FBD7B3EBD +7A3CBC7B3DBD7B3CBD7B3DBD7B3DBD7B3DBD7B3DBD7D40BE712FB8BE9FDE905BBF7634B1 +7B3CB47D3FB57330AF8C56BDBFA0DD7C3EBD7A3ABB7E40BD7C3EBC7D3FBD7C3FBD7C3EBD +7D3EBD7F42BE712EB7B490D9A074C8722EAF7C3EB47B3CB47B3CB47B3CB47A3BB37C3DB4 +7838B27939B3BC9ED98757B96A2DA8753DAF7239AD733AAE733AAE733AAE733AAE7239AD +743CAE733AAE7238AD6729A76A2EA98859B9BDA2D8BFA3DBB592DA9D6FCFBA9BDC8045B7 +986BC6B796D67331AF7B3CB47B3CB47A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 +7B3CB47B3CB47B3CB47B3CB47838B28349B9C5AADE7432B07C3EB47B3CB47B3CB47B3CB4 +7B3CB47737B28448B9C0A5DB7037AE733AB07239AF733AB0733AB0733AB0733AB0733AB0 +733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 +733AB0733AB06F34ADBEA4DA8049B97436B2763BB3793EB6C1ABD85E2C91623094612F93 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094623094623094623094623094623094612F93653496531D8AAE95C8825AA95B278F +64339556208B8F6CB39F81BE541E8B643395612F93623093612B97A69BB2000000010001 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000002000200 +0000180030A3007AB40073A60070AC0072AC0071AC0071AC0071AC0071AC0071AC0071AC +0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC +0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC +0072AC0071AC0071AC0072AC0073AC0073AC0072AC0073AC0073AC0073AC0073AC0072AB +0072AB0073AC0072AA0070AB006FAA006FA90070AA006FA90070AA0070A9006FA9006FA9 +006FA9006FA90070A90070AA0070A9006FA9006FA90070AA006FA8006EA7006EA8006FA8 +006FA8006FA8006FA8006FA8006FA7006FA8006FA8006FA8006FA8006EA7006FA8006EA7 +006FA90072AC0073AB0072AB0073AC0073AB0072AC0073AF0075B00074AF0074B00075B0 +0075B00075B00075B00075B00075B00075AF0075B00074AF0377B10067A850A7C8B889D3 +6927AC6E2CAEB491D4A378D26F2BB67D41BE7A3CBC7B3DBD7B3CBD7B3CBD7B3CBD7B3CBD +7B3DBD7B3DBD7B3DBD7D40BE712FB8C2A6E08B54BC7635B17B3CB47A3BB37D3FB57330AF +8C56BDBFA0DD7C3EBD7A3ABB7E40BD7C3EBC7C3FBD7C3EBD7D3EBD7F42BE712EB7B490D9 +A074C8722EAF7C3EB47B3CB47B3CB47B3CB47B3CB47A3BB37C3DB47838B27939B3BC9ED9 +8757BA6A2DA8753DAF7239AD733AAE733AAE733AAD733AAD733AAD733AAD7239AD753DAF +743CAE6E33AB672AA7733BAE9C75C5A580CBD3C0E7C1A5DCA176CA702CAE7B3DB47C3EB5 +7A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 +7838B28348B8C6ABDF7432B07C3EB47B3CB47B3CB47B3CB47A3BB37C3DB47534B18953BB +8C5EBE6B2FAC743CB17239AF733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 +733AB0733AB0733AB0733AB0733AB0733AB0733AB07239AF743BB06E33AD8F62C08854BE +7132B0783CB4773BB47335B2BBA0D771459D5E2B92623094623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094623094623094623094602D92B199CA73469F5D299063329559248E9D7EBC916EB4 +57228D63329562309462319459258D9A78BB535650000000030303000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000002000200000016002FA3007AB40071A80071AC +0072AB0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC +0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC +0071AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0072AC0073AC +0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AC0073AB0072AB0070A9006FA9 +0070A90070AA006FA90070AA0070AA0070AA006FA9006FA9006FA9006FA90070AA0070AA +0070A9006FA90070AA006EA8006FA7006FA7006FA7006EA7006EA7006EA7006EA7006EA7 +006FA8006FA8006FA8006FA8006FA8006FA8006EA7006FA90072AC0073AB0072AB0073AC +0073AB0073AC0072AB0073AB0075AF0074B00075AF0075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00073AF097CB49BABD98644B8763AB37738B38046B7BEA0DD +8145C07636BA7C3FBD7A3CBC7B3DBD7B3CBD7B3CBD7B3DBD7B3DBD7B3DBD7A3CBC7D41BE +6E2AB6BD9DDD8E58BE7634B17B3CB47B3CB47A3BB37D3FB57330AF8C56BDBFA0DD7C3EBD +7A3CBB7D3FBD7C3EBC7C3EBD7D3EBD7F42BE712EB7B490D9A074C8722EAF7C3EB47B3CB4 +7B3CB47B3CB47B3CB47B3CB47A3BB37C3DB47838B27939B3BC9ED98757BA6A2DA8753EAF +733AAE7239AD733AAE733AAD733AAD733AAD733AAD7239AD733AAE733AAE763EAF753EAF +5E1CA26C30AAC9B4DFFEFEFEC2A5DC9460C27635B17331AF7C3DB47B3CB47A3BB37B3CB4 +7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47838B28348B8C5AADE7433B0 +7C3EB47B3CB47B3CB47B3CB47B3CB47A3BB37C3EB47431B0BD9FDA8859BC6C30AC743BB0 +733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 +733AB0733AB0733AB0733AB0733AB06E34AD9D72C8773BB4773BB4763AB3783CB46E2EAE +9869C8A68BC2541E8B643395623094623094623094623094623094623094623094623094 +62309462309462309462309462309462309462309462309462309462309462319459258E +7D53A6A88DC4531D8A653496612E93663596BBA5D05B278F633194612F93623094633295 +55218A9167BA71726F000000030303000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000002000200000015002FA4007AB30071A80071AC0072AB0071AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC +0073AC0072AC0073AC0072AC0071AB0070A9006FAA0070AA0070AA0070AA0070AA0070AA +0070AA0070AA0070AA0070A90070A90070AA0070AA0070A90070AA0070AA006FA80070A7 +0071A90070A90071A9006FA9006FA9006FA90070A9006FA8006EA7006EA7006EA7006EA7 +006EA7006EA7006FA90072AC0073AB0072AB0073AC0073AC0073AC0073AB0073AC0072AB +0073AB0075AF0074B00075AF0075B00075B00075B00075B00075B00075B00074AF0577B1 +0066A787C1DAA059C26C2FAE7A3DB47A3CB47333B18249B8BFA1DD8045C07636BA7C3FBD +7A3CBC7B3DBD7B3DBD7B3DBD7B3DBD7B3DBD7B3DBD7839BB844BC2BD9DDB7F42B67939B3 +7B3CB47B3CB47B3CB47A3BB37D3FB57330AF8D56BDBFA0DD7A3ABB7D40BD7C3EBC7D3FBD +7D3FBD7F42BE712EB7B490D9A074C8722EAF7C3EB47B3CB47B3CB47B3CB47B3CB47B3CB4 +7B3CB47A3BB37C3DB47838B27A39B3BC9ED9895ABB6628A7733BAE733AAE7239AD733AAE +733AAD733AAD733AAE733AAE7239AD743CAE7035AC6527A6A079C7C1A9DB7D47B2CBB6E0 +D1BFE3B596D3BFA1DA9968C57533B0793AB37C3EB57B3CB47A3BB37B3CB47B3CB47B3CB4 +7B3CB47B3CB47B3CB47B3CB47838B28349B9C5AADE7331AF7C3EB47A3BB37B3CB47B3CB4 +7B3CB47B3CB47C3EB47331B09562C2B495D46C30AB743CB17239AF733AB0733AB0733AB0 +733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB07239AF743CB0 +6A2EABB091D28D5CC07031B0783CB4773BB4783CB46D2EAE9E71CBA589C1541E8B643395 +623094623094623094623094623094623094623094623094623094623094623094623094 +6230946230946230946230946230946230946331945B278F9C7DBC8E6AB25A258E633295 +612E93653496BDA8D25F2C926230946230946230946230936332945B2590B19FC313170F +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000020002000000180030A30079B4 +0071A80071AC0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC +0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AC0072AC0071AB +0070AC0071AC0071AC0071AC0070AA006FA9006FA9006FA90070AA0070AA0070AA0070AA +006FA90070AA0070A90070AA0070A90070A80070A7006FA70070A80071A90070AA0071AA +0071AA0071AA0071AA0070A90070A90070A90070A9006FA9006FA9006FA90072AC0073AB +0072AB0072AC0073AC0073AC0073AC0073AC0073AB0073AC0072AB0073AF0075B00074AF +0075B00075B00075B00075B00075B00074AF0276B0006DAC469CC4A586CF7434B17A3DB4 +783AB3783AB37A3DB57332B08248B8BFA1DD8145C07636BA7C3FBD7A3CBC7B3DBD7B3DBD +7B3DBD7B3DBD7C3EBD7230B89D6FCEB18BD26E28AC7D40B57A3BB37B3CB47B3CB47B3CB4 +7A3BB37E41B56D28ACB794D69F73CF712EB77F42BE7C3EBC7D3FBD7F42BE712EB7B490D9 +A174C8722EAF7C3EB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37C3DB4 +7939B27635B1CAB1E1CBB6E0692CA7733AAE733BAE7239AD733AAE733AAE733AAE7239AD +763FB06C30AA7E4AB4B293D2A985CC7C46B1682AA6B79BD4B090D09061BD7A43B0B697D3 +BFA2DA7C3DB4722EAE7839B27D3FB57A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 +7B3CB47737B2DDCCEB9C6DC67330AF7C3EB47B3CB47B3CB47B3CB47B3CB47A3BB37D3FB5 +6E29ACA980CEAA88CE6425A7753EB17239AF733AB0733AB0733AB0733AB0733AB0733AB0 +733AB0733AB0733AB0733AB0733AB07239AF733BB06E33AD8453BAC1A5DC7031B0783DB4 +763AB3773BB4773BB4773BB47537B3BA9FD66C3E995E2B92623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094612F9364339559248EB49DCC643395612E93612F93612E93653496BEA9D25E2B91 +623094623094623094612F9362319459258D895FB47B7C7B000000040404000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000002000100000017002FA3007AB40071A80071AC0072AB0071AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC +0073AC0073AC0073AC0072AB0073AB0072AC0071AC0070AC0071AB0070AB0070AB0070AB +0071AC0071AC0071AC0070AB006FA9006FA9006FA9006FA90070AA006FA90070AA0070A9 +0070A80070A7006FA80070A80070A7006FA80071A90070AA0070A90070AA0070A90071AA +0071AA0071AA0071AA0071AA0071A90071AA0072AC0072AB0073AC0073AC0072AC0072AC +0072AC0073AC0073AC0073AC0072AB0073AC0075AF0074B00075AF0075B00075B00075B0 +0074AF0075B00072AE0077AFB3C0E28136B47539B3793BB4783AB3793BB4783AB37A3DB5 +7332B08248B8BFA2DD8044C07635BA7C3EBD7A3CBC7B3DBD7B3DBD7B3DBD7C3EBD7331B8 +9B6CCDB795D6702BAD7D3FB57B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37C3DB47533B0 +B795D69969CC7330B77F42BE7C3EBC7F42BE712EB7B38ED89F72C8722EAF7C3EB47B3CB4 +7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37C3DB47838B27A3AB3AE87D1 +B291D26D33AA7238AD733BAE7239AD7239AD743BAE753DAF6426A5814EB6BBA0D8986DC2 +692BA67137AB6E32A9C2A9DA7E49B3C8B1DE692AA66829A5824FB5C8AFDFAB83CF8044B7 +6F2BAD7B3DB47C3DB47A3BB37B3CB47B3CB47B3CB47A3BB37D3FB56F2BADA87ECDA77DCD +702DAE7C3EB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37D3FB5B899D8814FB8 +7036AE733AB07239AF733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 +733AB0733AB0743CB1692CAAB597D59363C36F30AF783CB4773BB4773BB4763AB3793EB5 +6B2AAEC0A5DB7E57A65B2790623194623094623094623094623094623094623094623094 +623094623094623094623094623094623094623094623094612F9363329558228D845DAB +A88DC45B278F623194623094612E93653496BEA9D25E2B91623094623094623094623094 +6230945B298E7A49AA918C96000000020202000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000002000200000014 +002EA4007AB30071A80071AC0072AB0071AC0071AC0071AC0072AC0072AC0072AC0072AC +0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC +0072AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0072AC +0072AC0071AC0072AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC0072AB0073AC +0072AB0071AB0070AB0071AB0070AB0071AC0071AB0071AC0070AB0070AB0070AB0070AB +0070AB0070AB0071AB0070AA006FA90070AA006FAA006FA8006FA70070A8006FA7006FA7 +0070A80070A70070A80071AA0071A90070A90071AA0070A90070A90070A90070AA0070A9 +0070AA0071AC0072AB0072AB0072AC0072AC0073AC0073AC0072AC0072AC0072AC0073AB +0073AC0072AB0074AC0075B00074AF0075B00075B00075B00074AF0275B00073AF87AFD6 +9154BF7336B17A3CB4783AB3793BB4793BB4793BB4783AB37A3DB57332B18248B8C2A6DF +8146C0793BBC7B3DBD7B3DBD7B3DBD7B3DBD7C3EBD7331B89C6ECEB694D56F2BAD7D3FB5 +7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37533B0B897D79968CC7330B7 +7F42BE7E41BD712EB7B490D9A175C9722EAF7C3EB47B3CB47B3CB47B3CB47B3CB47B3CB4 +7B3CB47B3CB47B3CB47B3CB47A3BB37B3CB47B3CB46C26AB9765C4B697D46D31AA7238AD +733BAE753DAF6C31AA692CA7AD8CD0BBA0D8753CAD6729A5753CAD743BAD6D31A8C2AADB +7136AB8A5AB9B798D46D30A87135AA7035AAA17AC7C2A7DBAF88D17736B17634B17C3EB5 +7B3DB47A3BB37B3CB47B3CB47C3EB5702CADAE87D1A67CCC712DAE7C3EB47B3CB47B3CB4 +7B3CB47B3CB47B3CB47A3BB37C3DB47432B08B53BDC5AEDE6526A8753DB17239AF733AB0 +733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB06F34AE8351B9 +BFA4DB6E2EAF793EB5763AB3773AB4773AB4773BB4783DB46E2EAEAC87D3C0ACD4551E8B +643395623094623094623094623094623094623094623094623094623094623094623094 +6230946230946230946230946230946230945F2D92AF96C8774CA25B278F633194623094 +612E93653496BEA9D25E2B91623094623094623094623094623094643395541E8AAC8FC8 +33382F000000020202000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000040002000000170030A3007AB40071A80071AC0072AB +0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC +0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC +0071AC0072AC0072AC0071AC0071AC0072AC0071AC0071AC0071AC0072AC0072AC0073AC +0072AC0073AC0073AC0073AC0073AB0072AC0073AC0072AA0071AC0071AC0071AC0071AC +0071AC0070AB0071AB0070AB0070AB0070AB0071AB0071AB0071AB0070AB0071AC0071AC +0070AB006FA80070A80070A8006FA8006FA8006FA7006FA8006FA70070A8006FA70070A8 +0070AA0071A90070A90071A90071AA0071AA0071AA0070A90071AA0072AC0071AB0071AC +0071AC0072AC0072AC0072AC0073AC0073AC0073AC0072AC0073AC0073AB0072AC0074B0 +0075B00074AF0075B00074AF0477B10065A771B9D4AD6DCA6A2AAD7B3EB5783AB3783AB4 +783AB4783AB4793BB4793BB4783AB37C3FB56B26ACB492D4D2BBE96A24B47E42BE7A3CBC +7B3DBD7B3DBD7B3EBD7738BBC4A8E08348B87939B37B3CB47B3CB47B3CB47B3CB47B3CB4 +7B3CB47B3CB47A3BB37B3DB47A3BB37532B0B897D79968CC7330B78044BE7533B9A174CF +DAC9EA7533B07B3DB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 +7B3CB47A3BB37B3CB47E41B6712EAE9764C4B698D46F35AC7138AD6628A68B5CBCBA9DD6 +9D74C47339AC6F34AA753CAD7238AB743AAC6C2FA8B192D19164BE6323A2BB9FD78A59B9 +6D30A8743AAD6828A57439AC9C73C4E9DEF29460C2712DAE7533B07D3FB57B3CB47A3BB3 +7D3FB5702BADAD86D0A77DCD702DAE7C3EB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 +7A3BB37C3EB47534B0A478CAA37DCA6B2FAB743CB17239AF733AB0733AB0733AB0733AB0 +733AB0733AB0733AB0733AB07239AF753EB16729A9B79BD79261C27132B0773BB4773AB4 +773AB4773AB4773AB4773BB47235B1854DBDB298CB541E8A653496612F93623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +612F93602E93663596B59ECC58238D643395612F93623094612E93653496BEA9D25E2B91 +62309462309462309462309462309463329557238C9773BB595959000000010101000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000002 +000100000018002FA3007AB40071A80071AC0072AB0071AC0071AC0071AC0071AC0071AC +0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC +0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC +0072AC0071AC0072AC0072AC0072AC0073AC0072AC0072AC0073AC0073AC0073AC0073AB +0072AC0073AB0072AB0071A90070AB0070AB0070AB0070AB0070AB0071AC0071AC0071AC +0071AC0071AC0070AC0071AC0071AC0071AC0070AA006FA7006FA8006EA5006EA6006EA7 +006FA70070A70070A8006FA8006FA8006FA80070A8006FA80070A70070AA0071A90070A9 +0071AA0070A90071AA0070A90071AA0072AC0071AB0071AC0071AC0071AC0071AC0071AC +0072AC0072AC0072AC0073AC0072AC0073AC0072AB0074AC0075B00074AF0074AF0176B0 +0070AD288DBCA699D47937B3783CB4793BB4793BB4783AB4783AB4783AB4793BB4793BB4 +793BB4783AB37A3EB5702DAEAC85D0A276D1702CB77D40BE7A3CBC7B3DBD7B3DBD793ABC +C8AEE27C3EB47A3BB37A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB3 +7B3CB47A3BB37533B0B897D79968CC7330B78043BE7838BBC5ABE07B3CB37A3BB47B3CB4 +7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37B3CB47D3FB57D3FB57D40B57939B3 +7838B26D28AC925EC2AB87CD7137ADA07AC9B698D38B5CBA682AA57238AB733AAC7238AB +7339AC733AAC6C2FA88958B9B89AD4611FA18D5EBBB99CD56A2CA77439AC753BAD7237AB +6929A68755B8B99CD6BD9ED9915CC1702CAD793AB37D3FB57C3EB4702CADAC85D0A57ACB +712DAE7C3EB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37A3BB37B3CB47533B0 +C9B2E17741B37036AE733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0733AB0 +733BB06D32AD8858BBBDA1DA6F31B0783CB4773BB4773AB4773AB4773AB4773AB4773BB4 +773BB47336B2B495D47D55A55B278F633194623094623094623094623094623094623094 +623094623094623094623094623094623094623094612F9364339556218C9C7DBC916FB4 +5B278F623194623094623094612E93653496BEA9D25E2B91623094623094623094623094 +623094612F93602E9167329CA098A9000000020202000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000002000100000054002FA3007AB40071A8 +0071AC0072AB0071AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC +0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC +0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0072AC0072AC0073AC +0073AC0072AC0073AC0073AC0073AC0073AC0072AB0072AC0073AB0072AB0071A90071AA +0070A9006FA9006FA9006FA9006FA90070AB0070AB0070AB0070AB0070AB0071AB0071AB +0070AA006FA8006FA5006EA5006EA5006FA6006FA5006FA5006FA5006FA5006EA70070A7 +0070A70070A70070A80070A8006FA80070A70070AA0071AA0070A90071AA0070A90071AA +0072AB0072AC0071AB0071AC0071AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC +0073AC0073AB0073AC0073AB0074AD0075B00075AF0375B0006DAAA3C5E18C41B97235B1 +793BB4783AB3783AB4783AB4783AB4793BB4793BB4793BB4783AB4793BB4793BB47A3CB4 +702FAFB28DD3A175D0702DB77D40BE7A3CBC7C3FBD7432B9C5A9E07F42B57A3AB37B3CB4 +7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37B3CB47A3BB37533B0 +B997D79868CC7330B78044BFC8AFE27A3BB37B3CB47B3CB47A3BB37B3DB47C3EB47C3EB4 +7C3EB47A3BB37A3BB47939B36F2BAD702BAD6D27AC7E41B58D57BD8C56BC844BB8DBCAEA +D7C6E7A783CB6E32A96C2FA7753CAD7339AC7238AB7339AC7338AC733AAC6B2FA79062BD +B698D46A2CA66A2DA7BB9ED68856B86E32A97338AC7338AC753BAD6D2FA86A2CA68A5AB9 +B99CD5C1A3DB8144B76F2AAD7E40B5712EAEAD86D0AA82CF712DAE7C3EB47B3CB47B3CB4 +7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3DB47838B2854BBAC0A5DC6F35AE733AB0 +7239AF733AB0733AB0733AB0733AB0733AB0733AB07239AF753CB1692CAAAD8AD19363C3 +7031B0783DB4763AB3773AB4773AB4773AB4773AB4763AB3793EB56A28ACB08DD4825BA8 +58238E633194623094623094623094623094623094623094623094623094623094623094 +62309462309462309462309464339556218CB096C97F56A759258E633194623094623094 +612E93653496BEA9D25E2B916230946230946230946230946230946230946130935F2B93 +9E85B630332E000000020202000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000103000000000E6A0062C30076AE0071A90071AC0072AB0071AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0071AC0072AC0073AC0072AC0072AC0073AC0073AC0073AC +0073AC0072AC0073AB0073AC0072AB0071A90070AA0070A90071AA0070AA006FAA0070AA +0070AA006FA9006FA9006FA9006FA90070AB0070A8006EA5006FA5006EA5006EA6006FA6 +006FA6006EA5006FA6006FA6006EA6006EA6006EA5006FA5006FA5006FA7006FA80070A7 +0070A7006FA70070A80071A90070AA0071AA0070A90071AB0072AC0071AB0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0073AC0072AC0072AC0072AB +0072AD0074B00276B0006DAB6FACD19D6AC67134B07A3DB4783AB3793BB4793BB4783BB4 +793BB4793BB4793BB4793BB4793BB4793BB4783AB3793BB47A3CB46F2DAEB28ED3A075D0 +702DB77E41BE7636BA8E59C7BA99D97838B27B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 +7B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37B3DB47A3BB37433B0B997D79969CC7432B8 +CAB3E37B3CB37C3EB57C3EB47D40B57736B1702CAE712DAE712EAF7C3EB47B3DB38146B7 +B491D4B693D5B390D3BE9EDCC7A9E4C6A8E3C4A6E28B50C8D9C6ECA57FC96A2DA7733AAC +7339AC7238AB7339AC7339AC7339AC733AAC6B2FA78F61BDB799D46728A57136AA8756B8 +C0A5D96524A3753BAD7237AB7237AB7439AC743AAD6C2FA86A2BA68958B8BC9ED8A87DCD +793AB36C26AB9664C3DFD0ED7838B27B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 +7B3CB47B3CB47A3BB37D3FB5702CAEB48FD3966BC36A2EAB743CB07239AF733AB0733AB0 +733AB0733AB0733AB0733BB06E33AD8554B99262C26D2DAF783DB5763AB3773BB4773BB4 +773BB4773BB4773BB4773BB4783CB46F30AF9D71C99F7FBE5C2890623194623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +5C288F764BA2B59ECC58228D643395623094623094623094612E93653496BEA9D25E2B91 +623094623094623094623094623094612F93643295531E889770BE5A5D56000000030303 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000102000000000E6B0066BE +0078A60070AA0071AC0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC +0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AB0072AC0071AA +0071A90070AA0071AA0071AA0070AA0071AA0070AA006FAA0070AA0070AA0070AA0070AA +0070AA006FA8006EA8006EA6006FA5006FA6006FA6006FA6006FA6006FA6006FA6006FA6 +006FA6006FA6006FA6006EA6006EA6006EA5006FA5006FA6006FA8006FA80070A70070A8 +0071A90070AA0070A90071AB0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0071AC0071AC0073AC0073AC0072AB0075AE006FAE1C8AB7 +BEB2DF772FB07B41B6793BB4793BB4793BB4793BB4793BB4793BB4793BB4793BB4793BB4 +793AB3793BB4793BB4783AB3793BB47A3CB46F2DAEB28FD39F71CF7433B9722FB8AE88D7 +9F71C8702DAE7C3EB47B3BB47B3CB47B3CB47A3BB37B3CB47B3CB47B3CB47B3CB47A3BB3 +7C3DB47D3FB57D3FB57E40B57D3FB57634B0B38FD49360C9BFA3DD7736B17330AF7432AF +6F2BAD8C56BDA87FCCA277C9A57BCBC8ACE2CCB1E5C6AAE2A273D3A170D3A577D58B50C8 +742DBD7A36C06F24BAAE85D89969C79A6AC9C8B1DD6C2FA8743BAD7238AB7339AC7339AC +7339AC733AAC6B2FA78F61BDB799D46728A5763DAD6D31A8A682CA9B71C36C2EA87439AC +7237AB7338AC7237AB7439AC753BAD6A2CA77942AFA783CBC5ABDDA67BCC722FAFC0A2DB +7E41B67D3FB57B3CB47A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB3 +7B3DB47736B19C71C7753EB17239AF733AB0733AB0733AB0733AB0733AB07239AF743CB0 +6D32AC976DC67F47B87539B3773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4 +763AB3763BB37638B4BAA1D45A268D633295612F93623094623094623094623094623094 +6230946230946230946230946230946230946230946231945B278F8A65AFA386C057218C +643395612F93623094623094602E93663697BDA8D25E2B91623194623094623094623094 +623094623094623094612F9269369BA69DB0050702000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000102000000000D6A0067BE0077A7006FAC0072AC0072AB0071AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0072AC0072AC0073AC0073AC +0073AC0073AC0072AC0072AC0073AC0072AC0070AB0070AC0070AB0071A90070A90071A9 +0071AA0070AA0071AA0070AA006FAA0070AA0070AA0070A90070AA006EA7006FA7006FA8 +006FA6006FA5006FA5006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6 +006FA5006FA6006EA6006EA6006EA6006EA6006FA5006FA7006FA90071A90070AB0071AB +0071AB0071AB0071AB0071AB0071AB0071AB0071AB0071AB0071AB0071AB0071AB0071AB +0071AB0071AB0071AB0071AB0072AB0072AA0577AD9FA7D7752CAF6B2AAD6D29AD7535B2 +7739B37738B37738B37738B37738B37738B37738B37A3DB47B3EB57A3DB57B3DB57B3DB5 +7A3DB57B3EB57C40B56E2BAEBA9BD89A6ACD6720B3AF8AD7A67CCC712DAE7E41B57C3EB5 +7C3EB57C3EB57D3FB57A3AB37939B37939B37939B37A3AB37533B06E2AAD6F2BAD6F2BAD +6F2AAD7432B08C56BCD0BBE4DFD1ED8B54BDC7ACE0C6AAE0C8ADE0BD9BDEB189DAB48EDB +B089DA8241C47E3CC27F3CC27934BF7934BF7832BE7E3CC18344C48546C47832BEBB98DE +996AC86D29B1D7C3EB9266BD6728A5753DAD7238AB7339AC7339AC733AAC6B2FA78F61BD +B799D46728A4753CAD7237AB6F34A9C6AFDD763CAE7237AB7338AC7338AC7338AC7237AB +7237AB743AAC7034AA692AA6773EAEAB88CDBFA2D9DECFEC8043B76C26AB7737B27B3DB4 +7D3FB57B3CB47A3BB37B3CB47B3CB47B3CB47B3CB47A3BB37C3DB47533B09663C3A886CF +682BAA753CB17239AF733AB0733AB07239AF753DB1672AA9A581CCA880CF6C2CAE783DB5 +763AB3773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB47234B1AD88D0 +8964AD5A258E633295623094623094623094623094623094623094623094623094623094 +623094623094612F93653496551F8BB39BCB6C3D9B5F2C91623094623094623094612F93 +6230945F2C92BAA5D05F2D92623094623094623094623094623094623094612F93633295 +57228C9B77BE565855000000030303000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000103000000 +000B6A0067BE0077A7006FAC0072AB0071AB0072AC0071AC0071AC0072AC0072AC0072AC +0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC +0072AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC +0072AC0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0073AC0073AC +0072AC0070AC0070AC0071AC0071AB0070AB0071AB0071AB0071A90071A90071A90070A9 +0070AA006FAA0070AA006FA9006FA9006EA7006FA8006FA8006FA7006FA7006FA7006FA5 +006FA6006FA5006FA5006FA5006FA5006FA6006FA6006FA6006FA5006EA5006FA5006FA6 +006FA6006FA6006EA6006EA5006FA40070A70073B00074AF0073AF0073AF0073AF0073AF +0073AF0073AF0073AF0073AF0073AF0073AF0073AF0073AF0073AF0073AF0073AF0073AF +0376B10064A752A5CBDCCDECB08CD2BC9DD9BFA1DA8953BC7D41B68045B77F45B77F45B7 +7F45B78045B77D42B66F2DAF6D2AAD6E2BAE6E2BAE6E2BAE6E2BAE6E2BAE6E2BAE6F2CAE +8B56BDC2A6E06D28B6AA83D5A77ECC712EAE722FAF702CAE702CAE702CAE6F2AAD7C3EB4 +8248B78146B78247B77D3FB49A69C5C0A2DBBA99D7BB9BD8BB9AD8BC9CD9C0A1E0B792DB +FAF7FCD8C6EC8443C58D52C98D52CA813FC3742DBC7630BE7630BE803FC28140C38140C3 +8241C38241C38241C38140C3803FC28343C4742DBDB590DB9D70CA712EB37535B6BA9BDA +8756B76A2CA7753CAD7238AB7339AC733AAC6B2FA78F61BDB799D46728A4753CAD743BAD +692CA69E76C5A985CC6728A5753BAD7237AB7338AC7338AC7338AC7237AB7338AC743AAC +7338AC621FA28D5DBBEBE4F2B799D4BE9FDA8F59BF7431B06F2AAD7A3BB37C3EB47B3DB4 +7B3CB47A3BB37B3CB47B3CB47A3BB37C3EB5712EAE9364C28858BB6E33AD743BB07239AF +733AB0733AB07138AF753DB0C0A6DB7A3FB67538B3773BB4773BB4773BB4773BB4773BB4 +773AB4773AB4773BB4773BB4773BB4783DB46C2BAD9E73CB9979B8541D8A643395612F93 +6230946230946230946230946230946230946230946230946230946230946231945E2A91 +7448A0AD92C7643295612E936230946230946230946331945B268F855FACA588C15B278F +63319462309462309462309462309462309462309462309459268C8254B07C7C7C000000 +040404000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000102000000000D6B0067BE0077A7006FAC0072AB +0071AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC +0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC +0071AC0071AC0072AC0072AC0072AC0071AC0072AC0071AC0071AC0072AC0073AC0073AC +0073AC0073AC0073AC0073AC0073AC0073AC0072AC0071AC0071AC0070AC0071AC0070AB +0071AC0071AC0071AC0071AC0071AB0071AB0070AB0071AA0070A90070A9006FA9006FA9 +006EA7006FA8006FA7006FA7006FA8006FA8006FA7006FA7006FA5006FA6006FA6006FA5 +006FA5006FA5006FA6006FA6006FA5006FA5006FA6006FA6006EA5006EA5006EA50071AA +0072AD0076B20076B40076B40076B40076B40076B40076B40076B40076B40076B40076B4 +0076B40076B40076B40076B40076B40076B40076B40378B5006BAF59B1D1CBADE0C5A8DF +9E73D08F5BC7BA9BDDD0BCE7C4A9E0C6ADE2C6ADE2C6ADE2C7ADE2C2A7DFD8C6EBC7ACDE +A47ACBAB84CFAA82CEAA82CEAA82CEA981CEAE88D0915FC16823AA8953BCBC9DDDC2A5DE +7330AF793AB2A87ECCAB84CFAA83CEAB83CEA880CDBFA0DCCAB0E4C8ACE2C7ACE2CBB2E5 +B690DA9861CD9D69CF9C67CE9D69CF9760CC732ABA8647C3B997DAAC85D49A66CE742EBD +803EC2803FC28343C48242C38242C38140C3803FC28040C28040C28140C38140C38040C2 +8140C38140C27E3CC2BD9BDF8E5AC27737B67A3CB77A3BB8BC9EDB8756B76B2EA7753CAD +7238AB733AAC6B2EA78F61BDB799D46728A4753CAD7339AC7339AC7036AAC4ADDC773EAE +6F33AA7338AC7237AB7338AC7338AC7338AC7338AC7237AB753BAD6D30A8AC89CEBB9ED6 +AA8BCB8152B2BBA2D6B795D6AA81CF7F41B67432B07330AF7635B17E40B57C3DB47A3BB3 +7B3CB47B3CB47A3BB38143B7CBB4E17037AE7138AF733AB07239AF743CB0692CAAA27DCB +AA83D06B2AAD793EB5763AB3773BB4773BB4773BB4773AB4773AB4773AB4773AB4773BB4 +773BB4783CB47031B09465C5A78BC45C2990623194623094623094623094623094623094 +62309462309462309462309462309462309463329556218C8C67B09A7ABA531C8A643395 +612F93623094623094643395541E8AA88DC4825AA958238D633194623094623094623094 +6230946230946230946230946332945C2790AB97BF20241C000000010101000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000102000000000D6B0067BE0077A7006FAC0072AB0071AC0072AC0072AC0071AC0071AC +0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC +0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC +0071AC0072AC0071AC0072AC0072AC0073AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0070AC0071AC0071AC0071AC0070AC0071AC0071AB0071AB0071AC0071AB +0071AC0071AC0071AC0071AB0070AA0071AA0070AB0070AA006EA7006EA8006FA8006FA8 +006FA7006FA7006FA7006FA8006FA6006FA6006FA5006FA5006FA6006FA5006EA5006FA6 +006FA6006EA5006EA5006EA4006FA80071A90075B00077B40077B40077B40076B30075B3 +0075B30075B30075B30075B30075B30075B30075B30075B30075B30075B30075B30075B3 +0075B30075B30076B40072B20476B2C6D1EA863FB6A279CAA67CD36721B27333B97433B9 +7636BA7536BA7536BA7536BA7637BA7332B98045BFAA83D5A981D4A981D4A981D4A981D4 +A982D4A67ED3B28FD9DED0EEC6ACE0BEA0DCDFD1EEF4EFF7C4A8DFC6ABE0AF85D7AD81D7 +AE82D7AD81D7B188D98A4CC57832BD7C38BF7B37BE7C37BE7B36BE7A34BD7A34BD7A35BD +7934BD7D3ABF7832BCB791DB996AC96E2AB4BA9ADB9C69D07732BE8343C4803FC28140C3 +8040C28040C28040C28040C28040C28140C38140C38040C28140C37C39C0935BCCBE9EDC +6E2BB17D40B97C3EB97839B67A3BB8BB9DDB7F4BB36C30A8743BAC733AAC6B2EA78F61BD +B799D46728A4753CAD7238AB743AAC6C2FA7956AC0AB87CD6F32A97338AC7338AC7338AC +7338AC7338AC7237AB7439AC6C2EA88552B7BFA4D96728A5C1A7DA6D34A76125A08C60B9 +A381C7C1A6DBC1A5DB9C6BC78C54BE6C26AB7331AF7A3BB37D3FB57B3CB47C3DB47330AF +A073C9A682CE6D32AD743CB0733AB07239B0733AAFC3AADD783DB5763AB3763AB3773BB4 +773BB4773BB4773BB4773AB4773AB4773AB4773AB4773BB4773BB4763AB3793EB56D2CAF +BEA3D96D3F9A5F2B92623094623094623094623094623094623094623094623094623094 +623094612F936230945F2D92B198CA73469F5F2C92623094623094623094623094643395 +541E8AA78BC38A65AF58238D633194623094623094623094623094623094623094612F93 +643395541E8AA98CC6393B36000000010101000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000103000000000C6A0067BE0077A7 +006FAC0072AB0071AB0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC +0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC +0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0072AC0072AC +0073AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0070AC +0070AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AB0071AB0070AB0070AB +0071AC0070AC0070AB006FA8006FA7006FA8006EA8006EA8006EA8006EA8006EA8006EA7 +006FA8006FA6006FA6006FA6006FA5006FA6006FA6006EA5006EA5006EA6006FA80073AD +0076B30077B40077B40076B30076B30076B30076B40076B40076B40076B40075B40075B4 +0075B40076B40076B40076B40076B40075B40075B40075B40076B40076B40175B40078B4 +97BADC8B4ABA7233B07737B2B38FD49869CC7738BB7D42BE7C3FBD7C3FBD7C3FBD7C3FBD +7C3FBD7C40BD793CBC702EB7702EB7702EB7702EB7702EB7702EB7702EB7702EB77A3DBC +834AC1793BBCB999DCA880D1BF9EDF7F3BC07934BD762FBB762FBB7730BC762EBB7F3CC0 +8241C18240C18240C18240C18240C18140C18140C18140C18140C18343C2772FBCB58FDB +A075CD712FB67636B8B898DA9C69D07731BE8343C4803FC28140C38040C28040C28040C2 +8140C38140C38140C38140C38140C37C39C0935ACCC1A3DE712FB37D40B97A3CB87C3EB9 +7637B68044BBE7DDF17A44B07035AA743BAD6B2FA78F60BCB799D46728A5753CAD7339AC +7238AB763DAD6322A2B89CD59163BE6C2EA87339AC7338AC7338AC7338AC7338AC7135AA +773FAEBEA2D87840AF6829A5A078C6A585C9652AA26A31A56225A06F38A87C4AB0B296D0 +B697D3C8AEE0A77CCD7938B36D28AC7737B27B3DB47E41B66D28ACC4A8DD8A5BBD6A2DAB +763EB1682BAAA27DCAA881CF6C2CAE793DB5773BB4773AB4773BB4773BB4773BB4773AB4 +773AB4773AB4773AB4773BB4773BB4773BB4783DB47132B1C0A6DA6E409B5F2C92623094 +623094623094623094623094623094623094623094623094623094612F93612F93653596 +BBA6D15C2890633194612F93623094623094623094643395541E8AA98DC48964AF58238D +6331946230946230946230946230946230946230946230946230945E2C907240A49A949F +000000030303000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000103000000000D6B0066BE0077A7006FAC0072AC0071AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0071AC0072AC0073AC0072AC0072AC0073AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0070AC0070AC0071AC +0071AC0071AC0071AC0071AC0070AB0070AB0071AC0071AC0070AA006FA7006EA8006FA7 +0070A80070A7006FA8006FA8006FA8006FA8006FA8006FA8006EA7006EA8006EA8006EA7 +006EA5006EA5006EA50070A90072AA0075B20076B40077B50077B30076B30076B30076B3 +0077B40076B40077B40077B40075B40076B40076B40076B40076B40076B40076B40076B4 +0076B40076B40076B40076B40075B30679B60065AB81C6DCD3A3DE6A28AC7E41B67B3CB4 +7230AECCB4E38046C07739BB7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7A3DBC7B3EBD7C40BD +7C40BD7C40BD7C40BD7C40BD7C40BD7C40BD7C40BD7B3EBD7434B98D58C6C0A3DF6821B1 +BE9FDE9964CD7933BC8545C38241C18241C18241C1813FC1803EC0813FC1813FC1813FC1 +813FC1813FC1813FC1813FC1813FC17D3ABF8E52C7C3A5E17535B77C3FBB7A3CBA7533B7 +B998DA9C69D07731BE8343C4803FC28140C38140C38140C38140C38140C38140C38140C3 +8140C37C3AC08F54CAC1A3DE712FB37D40B97B3DB87A3CB87C3FB97332B4A980D0B191D0 +6628A4753CAD6B2FA79062BDB494D26526A4753DAD7238AB7339AC7339AC7136AA7F4AB3 +C0A6DA6B2CA7753BAD7237AB7338AC7237AB753AAD692AA6A47EC9A47EC96727A5753BAD +7237ACC1A7DA743FAB6D35A7713AA96E36A76C33A660239F6A30A5966FBFCCB9E0B698D4 +B692D68E57BF7735B27431AF722FAE8449B9BB9CD77943B37036AE7740B2C7AFE0783CB4 +763BB3773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4 +773BB4773BB4773CB47031AF9767C7AC92C6531D8A653496612F93623094623094623094 +623094623094623094623094612F93643395541D8AA081BE9270B558238D633194623094 +623094623094623094643395541E8AA98DC48964AF58238D633194623094623094623094 +6230946230946230946230946230945F2E9169369C9D8DAC121410000000010101000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000002000201000000000E6B +0066BE0077A7006FAC0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0071AC0072AC0073AC0072AC0073AC0073AC0072AC0073AC0072AC0071AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0071AC0071AC0070AC0070AC0071AC0070AB0070AB +0071AC0071AC006FA9006FA8006EA7006EA7006EA7006FA8006FA70070A80070A80070A8 +0070A80070A80070A80070A7006FA8006FA7006FA7006FA8006FA70070A70074B00077B4 +0077B50077B40077B40076B30076B30077B40077B40077B40077B40077B40076B40076B4 +0075B40076B40076B40076B40076B40076B40076B40076B40076B40076B40076B40075B3 +0177B5006DAF3290C1A793D4742FAF7B3EB47A3BB37C3DB47635B19360C1B797DA7535BA +7B3FBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7A3DBC7D41BE6F2DB7C0A2DE915DC57636B87738B8BC9CDE9862CD7832BC +8241C1803EC0813FC1813FC1813FC1813FC1813FC1813FC1813FC1813FC1813FC1813FC1 +813FC17E3BBF894BC5C2A4E07130B67D3FBB7B3DBB7A3CBA7433B7B998DA9C69D07731BE +8343C4803FC28140C38140C38140C38140C38140C38140C38242C37934BFBA98DD9664C6 +7535B57B3EB87B3DB87A3DB87A3CB87C3FB96E2BB2A377CDAB88CC682AA5753BAD7035AA +B99DD58451B66E32A97339AC7339AC7238AB743BAC692BA6B292D19468C06A2BA6743AAC +7338AC7338AC7236AB7237ABC6AEDD7237AB7338AC753AAD6828A5A179C7A381C76429A1 +7039A86E36A76E37A8713BA96E37A8672CA35F219E7B49AF9972C1B497D2C9B2DFA67BCC +9B6AC7651CA7A276CAA987CF5E1CA4976DC49B70C87031B0783CB4763AB3773BB4773BB4 +773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB47234B1 +8853BFB59CCE5D2A90623194623094623094623094623094623094623094623094623094 +62309463319559248EAC92C68159A95A258E633194623094623094623094623094643395 +541E8AA98DC48964AF58238D633194623094623094623094623094623094623094623094 +612F93643395521C889D7AC14C5048000000020202000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000001000102000002000C690067BE0077A7006FAC0072AB0071AB +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0071AC0072AC0072AC0071AC0072AC0072AC0072AC0073AC +0073AC0073AC0073AC0072AC0073AC0072AC0071AB0071AB0071AB0071AB0071AB0071AB +0071AB0072AB0071AB0071AB0071AB0070AB0070AB0071AC006FA9006FA9006EA7006EA7 +006FA8006FA8006FA8006EA7006EA80070A8006FA8006FA8006FA8006FA8006FA8006FA8 +0070A80070A80070A8006FA70071AA0073AD0076B30077B40076B30076B30076B30077B4 +0077B40077B40077B40077B40077B40077B40076B40077B40075B40076B40076B40076B4 +0076B40076B40076B40076B40076B40076B40075B30277B40070B1278BBEE1E2F27D36B2 +783BB37B3CB47A3BB37A3BB37C3EB4712DAE9A6AC5B999DC702EB77D42BE7A3DBC7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3FBD7637BA +9565CAB594D97534B77C3FBB793ABA7737B8BC9BDD945CCB7D39BF8140C1803EC0813FC1 +813FC1813FC1803FC1813FC1813FC1813FC1813FC1813FC18241C17A34BDAE84D6A377CE +7434B77C3EBB7A3CBA7B3DBB7A3CBA7434B7B998DA9C69D07731BE8343C4803FC28140C3 +8140C38140C38140C38140C38242C37933BFC4A8E2864EBE7738B67B3DB87B3DB87B3DB8 +7B3DB87A3CB87D40B9702DB3A579CEAA87CC6B2EA76728A5B699D48C5DBB6C2FA8733AAC +7339AC7339AC733AAC6E32A9824EB4BEA3D86C2FA87339AC7237AB743AAC6B2DA7BCA1D7 +8450B66F32A97339AC7237AB7339AC7034AAC2AADB723CAA6D36A76E37A86E37A86E36A7 +6E37A86F38A8713BAA6B33A66226A16B33A66E38A7A380C7B193CFC3A8DD8C53BEBD9EDA +9B73C7966AC57031B0783DB4763AB3773BB4773BB4773BB4773BB4773BB4773BB4773BB4 +773BB4773BB4773BB4773BB4773BB4773BB4763AB3793EB56A29ADB696D7815BA75A258F +6331946230946230946230946230946230946230946230946230945D2990794FA4B49CCC +551F8B643396612F93623094623094623094623094643395541E8AA98DC48964AF58238D +6331946230946230946230946230946230946230946230946230946231945D2A8F7C4FA9 +8D8990000000010001000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000003000100 +00012C0028AD0064B50078A9006FAC0072AB0071AB0071AC0071AC0071AC0071AC0072AC +0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC +0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC +0072AC0071AC0071AC0072AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC0072AC +0073AC0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0071AC0070AC0071AC006FA9006EA7006EA7006FA8006FA8006FA8006FA7006FA8006FA8 +006FA8006FA8006FA80070A80070A80070A8006FA8006FA8006FA80070A8006FA8006FA7 +0073AA0072AC0072AB0074AF0077B40077B40076B30076B30077B40077B40077B40077B4 +0077B40077B40077B40076B40076B40076B40075B40075B40075B40076B40076B40076B4 +0076B40075B30076B40276B40069AD81B3D7A468C67234B07C3EB47A3BB37B3CB47B3CB4 +7A3BB37C3EB57432B0BFA1DB8F5BC77332B87C40BD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBC7B3EBC7C3FBDCBB4E47737B87A3CBA7B3DBA +7B3EBB7839B97B3EBACFB8E77B35BE813FC1813FC1803EC0813FC1803EC1803EC1803EC1 +813FC1813FC1813FC1803EC08342C2752DBBBE9DDE8953C17636B87B3DBA7B3DBA7A3CBA +7B3EBB7A3CBA7434B7B998DA9C69D07731BE8343C4803FC28140C38140C38140C3803FC2 +8343C47731BEC3A6E18B55C07637B67B3DB87B3DB87B3DB87B3DB87A3CB87A3CB87D40B9 +702DB2A67BCEAB88CC601EA1BCA1D78B5BBA6C30A8733AAC7339AC7339AC7238AB753CAD +682AA5B291D19366BF6C2EA8753BAD6C2EA79061BDB596D36829A5753BAD7237AB7338AC +743AAC692AA69F76C6A785CA6327A1703AA96E37A86E36A86E37A86E37A86E36A76F37A8 +7039A96E37A86E37A86226A1642AA28050B2B496D2C5AEDCCFBBE3793CB56E2FAF793EB5 +763AB3773BB4773AB4773AB4773BB4773BB4773BB4773AB4773AB4773AB4773AB4773BB4 +773BB4773BB4773BB4793EB56B2AADBA9BD97D55A55A258F623194623094623094623094 +623094623094623094612F93653496541D8AB29ACA7B51A55C2890623094623094623094 +623094623094623094643395541E8AA98DC48964AF58238D633194623094623094623094 +623094623094623094623094623094612F9363329458228EA88EC2323430000000010101 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000300010000002D0040B2007FB00073A80070AC +0072AB0071AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC +0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC +0071AC0071AC0071AC0071AC0072AC0072AC0071AC0072AC0071AC0072AC0072AC0073AC +0072AC0073AC0073AC0073AC0073AC0073AC0073AC0072AB0073AB0073AC0071AA0071AA +0071AB0071AA0071AB0070A90070A80070A80070A80070A80070A80070A8006FA8006EA7 +006FA8006FA8006EA7006FA8006FA8006FA8006FA8006FA8006FA8006EA8006FA80070A8 +0070A80070A8006FA8006FA80070A7006FA80070A70072AA0072AC0073AB0072AB0072AB +0073AD0076B20077B40076B30076B30077B40077B40077B40077B40077B40077B40076B4 +0077B40076B40075B40075B40075B40075B40076B40076B40076B40075B30378B5006CAF +8ACADFAD74CB6B29AC7D3FB57A3BB37B3BB47B3CB47B3CB47B3CB47B3CB4793AB3793AB2 +BC9CDA8B55C57739BB7B3FBD7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD +7A3DBC7D41BE6F2DB7AD88D6A479D07331B67C3FBB7A3CBA7A3CBA7C3FBB7635B89B6DCB +B58FD97933BD813EC0813FC1803EC0803EC1803EC1803EC1803EC1813FC1813FC1813FC1 +803EC08240C1BF9FDF874FC07738B97B3DBA7B3CBA7B3DBA7A3CBA7B3EBB7A3CBA7434B7 +B998DA9C69D07731BE8343C4803FC28140C38140C38241C37A35BF9D6AD1B694D77332B4 +7C3EB97B3DB87B3CB87B3DB87B3DB87B3CB87B3DB87A3CB87D40B96F2BB2E6DAF38E60BB +AE8DCF9063BD6F33A9763DAD7339AC7339AC7339AC7339AC743BAD692BA6C4ABDC7E48B2 +7236AB692AA6BEA3D98551B66E31A97339AC7338AC7338AC7338AC7338AC7236ABBDA4D7 +723CAA6C34A76E37A86E36A86E37A86E37A86E36A86E36A86E36A86E36A86E36A7703AA9 +703AA96E36A758189A926ABDF0ECF5B395D39565C56E2EAF7A3FB5773BB4763AB3773BB4 +773BB4773BB4773BB4773AB4773AB4773AB4773AB4773BB4773BB4773BB4773AB4773BB4 +7335B18853BFB49BCE5B288F633195623094623094623094623094623094623094623094 +612F93643395B29ACA6E3F9C5E2B91623094623094623094623094623094623094643395 +541E8AA98DC48964AF58238D633194623094623094623094623094623094623094623094 +62309462309463319457248B885CB46F716D000000040404000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000300010000002B0040B2007CAE006EA90071AC0072AB0071AC0072AC0072AC0071AC +0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC +0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC +0072AC0072AC0072AC0071AC0072AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC +0073AC0073AB0072AC0073AC0072AB0072AB0070A9006FA9006FA7006FA7006FA7006FA7 +006FA7006FA7006FA7006FA70070A7006FA7006EA7006FA8006EA7006FA8006FA8006FA8 +006FA8006FA8006FA8006FA8006FA8006EA8006FA80070A80070A80070A8006FA8006FA7 +006FA80070A70072AA0073AC0072AB0073AC0073AC0073AC0072AB0073AC0076B20077B4 +0077B40076B30077B40077B40077B40077B40077B40076B40077B40076B40075B40075B4 +0075B40075B40076B40076B40075B30177B4006BAE2B92C0D9C3E87838B27B3DB47B3CB4 +7B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37C3EB47331B08F59BEC4AAE26E2BB67C40BD +7A3DBD7A3DBD7B3EBD7B3EBD7B3EBD7B3EBD7B3EBD7A3DBD7B3EBD783ABB7E43BEC5ABE1 +7B3EBB7A3BBA7B3DBA7B3DBA7B3DBA7A3CBA7C3FBB712EB5A075CDB088D77C38BE8241C1 +803EC0813FC1803EC1803EC1803EC1813FC1813FC18240C17933BDA06DD0B490D96E2AB4 +7D40BC7A3CBA7B3CBA7B3DBA7B3DBA7A3CBA7B3DBB7A3CBA7534B7B898DA9C69D07731BE +8343C4803FC28140C38241C37833BEA676D5B18CD56F2BB27D40B97A3CB87B3CB87B3DB8 +7B3DB87B3CB87B3DB87A3CB87B3EB87B3DB88247BDAB87D0C1A9DA7F4BB3611FA16728A4 +6F34A97035AA7035AA7035AA7137AB6B2EA7966CC1B799D45B169DB494D2976BC16A2BA6 +743AAD7237AB7338AC7338AC7237AB753BAD6524A3C9B2DFB090CF6327A17039A96E36A7 +6E37A86E37A86E36A86E36A86E36A86E37A86E36A76F38A86C34A65E209EA280C69E7BC3 +8557B4B9A1D0AD90CBA175CB6724AB7539B3783CB4763AB3773BB4773BB4773BB4773AB4 +773AB4773AB4773AB4773BB4773BB4773BB4773AB4773AB47438B27E44B9B9A0D156218B +643396612F9362309462309462309462309462309463319458238D825AAAA386C0531C89 +653496612F93623094623094623094623094623094643395541E8AA98DC48964AF58238D +633194623094623094623094623094623094623094623094623094623094623094602E92 +6B399C9B8DA80B0E08000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000030002000000290040B3007CAE +006FA90071AC0072AB0071AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC +0072AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC +0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC +0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0072AC0073AB0072AB +0070AB006FA9006FAA0070A90070A90070A70070A70070A70070A80070A80070A8006FA8 +0070A8006FA8006EA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8 +006FA8006EA80070A80070A8006FA80070A8006FA70070A8006FA70070AA0073AC0072AB +0073AC0073AC0073AC0073AB0073AC0072AB0072AB0074AE0077B40077B40076B30076B3 +0077B40077B40077B40076B40077B40076B40076B40075B40075B40076B40076B40075B3 +0176B40071B21889BCABACDB7833B17739B27B3DB47A3BB37B3CB47B3CB47B3CB47B3CB4 +7B3CB47B3CB47A3BB37C3EB47432B0A175C9AB84D47434B97C40BD7A3DBC7B3EBD7B3EBD +7B3EBD7B3EBD7B3EBD7A3DBC7C40BD7333B9AF8AD7A67CD0712FB57D3FBB7A3CBA7B3CBA +7B3CBA7B3DBA7A3CBA7E42BC6B25B2BEA1DC9E6ACF762FBB8342C2803EC0813FC1803EC1 +813FC1813FC1813FC18240C17934BD9F6BCFB997DB702CB57D40BB7B3DBA7B3DBA7B3DBA +7B3DBA7B3DBA7A3CBA7B3EBB7A3CBA7534B7B898DA9C69D07731BE8343C4803FC28241C3 +7833BE9F6CD2B591D76F2CB27D40B97B3DB87B3DB87B3DB87A3CB87B3DB87C3EB97C3EB9 +7A3CB8712FB37A3BB79563C6FFFFFFBEA3D8B89AD5BB9FD7814CB47B45B17C47B27C46B1 +7D48B27339AC6222A2B08FD08C5CBBB799D47237AB7439AC7237AB7338AC7338AC7338AC +7338AC7338AC6D30A88957B9B99ED56428A1713AA96E37A86E37A86E37A86E37A86E37A8 +6E37A86E36A7703AA9672DA37945AEBDA4D79E7BC360229D8251B1AE91CB4F118EA585C7 +C0A4DD7D45B87133B0793EB5763AB3763AB3773BB4773BB4773AB4773AB4773BB4773BB4 +773BB4773BB4773BB4773BB4763AB3763AB4B495D2794FA35D2990633194623094623094 +6230946230946230946231945C2890A284BF8761AD5B278F633194623094623094623094 +623094623094623094643395541E8BA98DC48963AE58238D633194623094623094623094 +623094623094623094623094623094623094612F93653495551E8CAD97C31C2017000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000300010000002C0041B2007BAE006FA90071AC0072AB0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC +0073AC0073AC0073AC0072AC0073AB0073AC0072AB006FA9006FA90070AA0070AA0070AA +0070AA0070A90070A90070A80070A70070A80070A7006FA80070A8006FA8006EA8006FA8 +006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006EA8006FA8006FA8 +0070A8006FA80070A8006FA70070AA0073AC0073AB0072AC0073AC0073AC0073AC0073AC +0072AB0073AC0073AC0072AB0073AC0075B10077B40077B40076B30077B40077B40077B4 +0076B40077B40076B40075B40076B40076B40076B40075B30578B5006AADC3E3EEAB6EC9 +6F2FAE7D3FB57A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3BB47A3BB3 +7D3FB56C26ABBA9AD79D70CF702DB77D41BE7A3DBC7B3EBD7B3EBD7B3EBD7B3EBD7C3FBD +7535BA9361C8E6DBF37433B87B3EBB7A3CBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA +7A3CBA8044BDBF9FE08B4EC67B36BD8241C1803EC0813FC1813FC1813FC1813FC18140C1 +7E3ABFC3A6E0854CBF7839B97B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7A3CBA +7B3EBB7A3CBA7533B7B998DA9C69D07731BE8343C48141C37A36BFB087DAA277CE7331B4 +7C3FB97A3CB87B3DB87B3DB87D40B97738B67230B37535B57C3EB9AA83D1C8AFE2B18ED7 +C9AFE5E1D8EB703CA6BAA2D4C9B4DDBFA7D7C1A9D9C2AAD9C0A8D8DFD3ECA47EC9BFA3D9 +DED1EB9E75C5611FA16F33A9753CAD7338AC7338AC7237AB7338AC7338AC743AAD692AA6 +B89BD58659B6682EA46F38A86E37A86E37A86E37A86E37A86E36A7703AA9672DA37B48B0 +B99CD4885AB4692FA26C34A47946ACB79CD36E3BA3632B9B865CB0B69AD3824ABB6E2EAF +783CB4773BB4763AB3773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4763AB3 +793EB56A29ADA47ACE916FB2551F8B643295612F93623094623094623094612F93633295 +5B278FB7A0CE602E93623094612F93623094623094623094623094623094612F93653496 +531C89A386C08A65AF58238D633194623094623094623094623094623094623094623094 +6230946230946230946230945B288E8255AE868587000000040304000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000300010000002C +0041B2007CAE006FA90071AC0072AB0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AB +0072AC0071AA006FA9006FA9006FA90070AA0070AA0070AA0070AA0070AA0070AA0070A9 +0070A80070A7006FA80070A7006FA8006FA8006EA8006FA8006FA8006FA8006FA8006FA8 +006FA8006FA8006FA8006FA8006EA8006FA8006EA8006FA80070A80070A8006FA70070A9 +0073AC0073AB0072AC0073AB0073AC0073AC0073AC0073AC0073AC0073AC0073AB0073AC +0072AB0072AB0074AE0076B30077B40076B30076B30077B40076B40077B40076B40075B4 +0076B40076B40075B30278B5006AAD57A2CCA376CA712FAE7D3FB57A3BB37B3CB47B3CB4 +7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47939B38348B8BD9EDC +8045C07739BB7B3FBD7B3EBD7B3EBD7B3EBD7A3DBC7C40BD7333B9C2A7E1854CBF7737B9 +7B3EBB7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7A3CBA7C3EBB7636B88045BDC2A3E1 +894CC57C38BE8240C1803EC0813FC1813FC1803EC08241C17933BDC4A7E17E42BC7A3BBA +7A3CBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7A3CBA7B3DBB7A3CBA7434B7 +B998DA9B69D07731BE8343C4803EC3C6ACE27738B67B3DB87B3DB87D41BA7A3BB87738B7 +6F2BB28851C09C6DCABFA1DEC7AEE2A981D47738BB864EC3B392D3A17AC68C61B85B1F9A +652D9F652C9F652C9F652D9F61279D895FB69772BEBCA5D6EBE4F3B59AD2B597D38552B7 +6727A56F32A97135AA753BAD7237AB7337AC7339AC6D30A88958B9B89DD46428A1713AA9 +6E36A76E37A86E37A86E36A7703AA9672DA37A47AFBCA0D6743FA96429A07039A7713BA7 +60239DAB8ACC8D66B6622B9B61299A703EA3C2ACD9AC87D16D2CAE7538B2783CB4763AB3 +773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB4773BB47538B2824ABAB69BD0 +633394612F93623094623094623094622F9463329558238D8E6AB29F80BD5B278F633194 +6230946230946230946230946230946230946230945E2B916E409CB39BCB633295612F93 +623094623094623094623094623094623094623094623094623094623094623094623094 +5D2A8F7443A6978F9E000000010101000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000300020000002A0040B3007CAE006FA90071AC0072AB +0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0071AC0072AC0072AC0072AC0071AC0072AC0072AC0072AC +0073AC0073AC0073AC0073AC0073AC0072AC0073AC0072AB0070AC0070AB0070AB0070AB +0070AB006FA9006FA9006FA9006FA9006FA9006FA9006FAA0070A90070A8006FA70070A8 +006EA8006EA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8 +006FA8006FA8006EA8006FA8006FA70070A8006FA70072A90073AC0072AB0073AC0073AC +0073AC0073AC0073AC0073AC0073AC0073AC0073AC0072AB0073AC0073AC0072AB0073AD +0076B30077B40076B30076B30076B40077B40076B40075B40076B40075B30479B50069AD +5FB1D1D8BCE66D25AB7D40B57A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 +7B3CB47B3CB47B3CB47B3CB47A3BB37C3EB47533B0854AB8C3A7DF793CBC7B3EBC7B3EBD +7B3EBD7B3EBD7C40BD7332B99969CBB896D97230B67C3FBB7A3CBA7B3DBA7B3DBA7B3DBA +7B3DBA7B3DBA7B3DBA7B3DBA7A3CBA7C3FBB7636B87F44BCC6A9E38443C27F3DC0813FC1 +813EC0813FC18240C17B36BE9B66CEB592D97738B87B3DBB7B3DBA7B3DBA7B3DBA7B3DBA +7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7A3CBA7B3DBB7A3CBA7434B7B998DA9C69D07732BE +8242C4C8AEE37E42BA7B3EB97839B76C27B17D40B9884FBFB38FD5BEA1DFB898DC8A55C5 +7B3DBD7231B87434B99361CAB292D1601DA0CDBAE1703CA66B34A36E39A56E38A56D38A4 +6E39A5662DA05F239BA989CA9C79C2A282C67E52B0BBA2D5B698D48550B67940B06626A4 +7338AC743AAC7338AC7439AC6A2CA7B99BD5885AB7672DA36F38A86E37A86E36A7713BA9 +672DA37A47B0BCA0D6743EA96930A2703AA76E36A5703AA763279EAE90CE8E67B661299A +6D39A167329E622A9A9874BDB08CD37A3EB67234B1793EB5773BB4763AB3773BB4773BB4 +773BB4773BB4773BB4773BB4763AB3783DB47132B1BDA4D7613092612F94612F93623094 +62309462309464329556208BA183BF8F6CB356208B643295623094623094623094623094 +6230946230946230945C2890774CA2B29ACA541D8A653496612F93623094623094623094 +623094623094623094623094623094623094623094623093643395531D89A788C63D4239 +000000020202000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000003 +00010000002B0041B2007CAE006FA90071AC0072AB0072AC0072AC0071AC0071AC0071AC +0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC +0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC +0072AC0071AC0071AC0071AC0072AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC +0072AC0073AC0072AC0070AC0070AB0071AC0071AC0071AC0071AC0070AB0070AB0070AB +0070AB0070AB0070AB0070AB006FA9006FA9006FA70070A8006FA8006FA8006FA8006FA8 +006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006EA8006FA8006EA7 +006FA80070A70072A90073AC0073AB0073AC0073AC0072AC0073AC0073AC0073AC0073AC +0073AC0073AC0073AC0073AC0072AB0073AC0073AC0072AB0072AB0075B00077B40077B4 +0076B30077B40076B40076B40075B30077B40071B10575B2AABADF8E4CBB7639B27B3CB4 +7A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 +7B3CB47A3BB37E40B56F2BADAF89D1A67DD36F2DB77C40BD7A3DBC7A3DBC7C3FBD7535BA +BFA3DF8B55C27635B87B3EBB7B3DBA7B3DBA7B3DBA7B3CBA7B3CBA7B3CBA7B3DBA7B3DBA +7B3DBA7A3CBA7D41BC702CB5A981D1AF86D7752DBB8342C1803EC0813FC18342C1762EBB +AD82D7A176CF702DB57C3FBB7A3CBA7B3CBA7B3DBA7B3DBA7B3DBA7B3DBA7B3CBA7B3CBA +7B3CBA7B3DBA7A3CBA7B3EBB7A3CBA7535B7B998DA9E6CD1752EBDC7ADE27331B37230B4 +8A54C0B593D7BA99DAC8AEE39E71CE793CBC6D2AB6783ABB7A3DBC7D41BE7535BAA880D3 +A179C76829A58858B9B497D06932A16C36A46C36A46C35A36D38A4652C9F966FBDAF91CD +591C98C3ACD96D3AA65F279D875EB5BCA5D6BBA1D6A57ECA7236AB692AA67237AB763DAE +6C2FA88B5BBAB59AD2652BA26F38A86E37A87039A961249F7B48B0BC9FD6743EA96930A2 +7039A76E36A56E37A66E37A66C34A47642AABDA6D566309E6A35A06A35A06B37A15E2598 +936DBAC5AFDB8956BF6927AC773CB4773BB4763AB3773BB4773BB4773BB4773AB4773AB4 +773BB4773CB47234B1B090D3825BA95C28906331946230946230946230945F2D92683898 +BCA6D15E2B916331946230946230946230946230946230946230946230946230945C2990 +764BA1B69FCD57218C643395623094623094623094623094623094623094623094623094 +62309462309462309462309463329558248C916BB76A6A69000000020202000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000500010000002C0041B2007CAE006FA9 +0071AC0072AB0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC +0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC +0071AC0071AC0071AC0071AC0071AC0072AC0071AC0072AC0071AC0072AC0072AC0072AC +0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AB0073AC0072AC0070AC0070AB +0071AC0070AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC +0070AB0070AB0070AA006EA7006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8 +006FA8006FA8006FA8006FA8006FA8006FA7006FA8006FA8006FA70071A90073AC0072AB +0072AB0072AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0072AC +0073AC0073AC0072AB0073AC0072AB0072AB0073AD0076B20077B40076B30077B30076B4 +0076B40075B3077AB5AFD0E68F4ABB7132AF7C3DB47A3BB37B3CB47B3CB47B3CB47B3CB4 +7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB37C3EB5 +722FAFB18CD29D70CE7535BA7C40BD7C40BD7332B99665CABC9CDC6F2CB47D41BC7A3CBA +7B3DBA7B3DBA7B3CBA7B3CBA7B3CBA7B3CBA7B3DBA7B3DBA7B3DBA7B3DBA7A3CBA7D3FBB +712FB5AC86D3A87BD37831BC8342C2803EC08240C17A35BEB58DD99D6FCC7332B67C3EBB +7B3CBA7B3CBA7B3CBA7B3DBA7B3DBA7B3CBA7B3CBA7A3CBA7B3DBA7A3CBA7B3DBB7D40BB +7E41BC7635B8712FB5A980D2C2A3E2A57BCE9969C8B796D9C0A3DFA074D08A53C46E2BB6 +7535BA7A3DBC7E42BE7B3EBD7A3DBC7C3FBD7737BBC4AAE0743BAC743BAD6525A3B596D3 +8D63B8652C9F6D37A46C36A4672FA07F4FAFBEA5D662299E642B9FB194CE8A62B8642EA0 +652FA15D249C6E3CA69E7DC4C2AADAA17AC77338AC6828A57034AA6A2BA6BC9FD78556B6 +6930A46F38A8682FA4966EC0B89AD4743FA96930A27039A76E36A56E37A66E36A56E36A5 +6D35A5723CA8BDA5D561299A6B37A169349F69349F6C38A161299A67329DB194CEA57CCF +7537B27539B3793DB5763AB3773BB4773BB4773AB4773AB4773AB4773CB46F2FAF9260C5 +A487C0521B89653496612F936230946230945D2A917C52A5AE94C859248E633295612F93 +6230946230946230946230946230946230946230945C2990764BA2B69FCD56208C643395 +623094623094623094623094623094623094623094623094623094623094623094623094 +612F936231935F2995AC9BBD11130F000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000010200010000002B0040B2007CAE006FA90071AC0072AB0071AC0072AC0072AC +0072AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC +0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC +0072AC0072AC0072AC0071AC0072AC0072AC0073AC0073AC0072AC0073AC0073AC0073AC +0073AC0073AB0072AC0073AC0072AC0070AC0071AC0071AC0071AC0071AC0071AC0071AC +0071AC0070AB0070AB0070AB0070AB0070AB0070AB0071AC0070AA006FA9006FA8006EA7 +006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8 +006EA7006FA8006FA8006EA70071AB0073AC0074AB0073AC0073AC0074AC0073AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0073AC0073AC0073AC0073AC0073AB +0073AC0073AC0072AB0073AC0076B20077B40077B40076B30378B50066AB65B3D3D1A2DE +6D2EAE7D3FB57A3BB37B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB4 +7B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47B3CB47A3BB47736B1CEB7E47A3DBD +793CBC7839BB864EC2C2A6E07737B87B3EBB7A3CBA7B3DBA7B3DBA7B3DBA7B3DBA7B3CBA +7B3CBA7B3CBA7B3DBA7B3DBA7B3DBA7B3CBA7B3DBA7A3CBA7C3FBB6F2BB4B593D8A372D1 +7730BC8342C27E3BBF894BC5C4A9E07230B67C3FBB7A3CBA7B3CBA7B3CBA7B3DBA7B3DBA +7A3CBA7B3DBA7C3FBB7D40BB7A3CBA793BBA7737B86F2BB46F2BB48D58C48B56C4A67CD0 +FAF7FBD7C4EBB390D9915FC87637BB7231B87738BB7E42BE7B3FBD7B3EBD7A3DBC7B3EBD +7A3DBC7D41BE7130B8C2A7DF7C47B07035AA7035AA7D48B2C4ACDA60269C6D38A56E39A5 +60269CB196D0895DB6662DA06932A27A4AADBAA3D5622B9F6C39A56D3AA66833A360289D +6B38A4A282C6BEA4D8BDA2D88C5BBB6524A38450B6B99FD46429A1682EA4A484C8B296D0 +743FA9692FA27039A76E36A56E37A56E37A56E36A66E37A66F38A66930A2AB8ACC8C64B6 +622B9B6B36A06A35A069349F6C38A167319E69349EA88BC6B492D47132B16E2FAE793EB5 +763AB3773BB4773AB4773AB4773AB4773CB47132B08F5CC1D9CCE5663596602E93623094 +612F93653496521B89AA8FC57B51A55B268F623094623094623094623094623094623094 +6230946230946230945C2990764BA2B69FCD56208C643395623094623094623094623094 +62309462309462309462309462309462309462309462309462309463329556218A936BBB +61645F000000040404000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000010001000001090000550041AB +007BB0006FA90071AC0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC +0072AC0073AC0072AC0072AC0073AC0073AC0073AC0073AC0073AC0072AB0073AB0072AB +0070AB0070AB0070AB0070AB0070AB0070AB0070AB0070AB0070AB0070AB0071AB0070AB +0070AB0071AC0071AC0070AA006EA7006EA7006EA7006FA8006FA8006FA8006FA8006FA8 +006FA8006FA8006FA8006FA8006FA8006FA8006FA8006EA7006FA8006FA7006EA70072AB +0074AE0074AD0073AC0074AB0073AC0074AC0073AC0073AC0073AC0073AC0073AC0073AC +0073AC0073AC0073AC0072AC0072AC0072AC0072AC0072AC0072AB0072AC0072AC0072AB +0072AB0074AE0077B40278B5006EB03F9FC8AD92D4702CAD7D3FB57C3DB47C3EB47C3DB4 +7C3DB47C3DB47C3DB47C3DB47C3DB47C3DB47C3DB47B3DB47B3DB47B3DB47B3DB47B3DB4 +7B3DB47B3DB47B3DB47B3DB47C3EB57838B28F5ABFB998DB7B3DBD7231B8B492D99F73CE +7331B67D40BC7A3CBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA +7B3DBA7B3DBA7B3DBA7A3CBA7B3EBB7738B8854CC0C5A7E3803CC07E3BBF803EC08748C4 +C7ADE27535B77C3EBB7B3DBA7A3CBA7B3DBB7B3EBB7B3EBB7C3FBB7C3EBB7230B66F2BB4 +7A3CBA7E42BC8C57C4BC9DDBB897DAC0A0DFC6ABE2A679D2B48ED6E6DBF1B593DA9A6CCD +6F2CB77A3CBC7D42BE7B3EBD7A3DBC7B3EBD7B3EBD7B3EBD7B3FBD7738BA8C57C6B799D6 +7137AB7238AC743AAC6D30A8966BC1A98AC9642A9E6A33A28051B0B79DD2652C9F6D37A4 +6E39A560269CB093CE8C64B9612A9E6B37A46A36A46B38A46A35A45D249C703FA87D51AF +B59BD2BDA2D7834EB6B597D38151B3A585C89771BF5D1E9B6D35A56F38A66E36A56E37A6 +6E37A56E37A66E37A66E36A67039A763279E9971C19D7BC05D23976C38A169349F6A35A0 +69349F6A36A06A36A0591D958459B0C4ABDE986BC86C2CAE793FB5773BB4763AB3773BB4 +773BB4773BB4793EB56D2DAFBEA3DA72479E5C2990623094623094602D926A3A99AE95C8 +6C3E9B5F2C926230946230946230946230946230946230946230946230946230945C2990 +764BA2B69FCD56208C643395623094623094623094623094623094623094623094623094 +6230946230946230946230946230946231945B288E7D50AB847D8B000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000001000200000004001C830064C50075AB0071AA0071AC0072AB0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0071AC0073AC0073AC0072AC0073AC0073AC +0073AC0073AC0073AC0073AC0072AB0073AC0072AA0070A90070A9006FA90070A9006FA9 +0070AB0071AC0071AC0071AC0071AC0071AC0070AB0071AC0071AC006FA9006FA8006FA7 +006EA7006FA8006FA8006FA7006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8 +006FA8006FA8006EA7006FA8006FA7006EA70072AB0074AE0073AD0073AE0074AC0074AB +0074AC0073AB0074AC0074AC0074AC0074AC0074AC0074AC0074AC0074AC0073AC0073AC +0073AC0073AC0073AC0073AC0073AC0073AC0073AB0073AC0072AC0072AB0173AC0072B0 +1180B8DFDCF0813CB47231AF7634B17533B07533B07533B07533B07533B07533B07533B0 +7533B07533B07533B07432B07431B07431B07431B07431B07431B07431B07431B07431B0 +7431B07634B16921AA9867C3B08CD87738BBC0A3DE6F2CB47433B77535B87D41BC7D40BB +7D40BC7D40BC7D40BC7D40BC7D40BC7D40BC7C3FBB7A3CBA7B3DBA7B3DBA7B3DBA7B3DBA +7B3DBA7C3FBB7534B78B55C3C1A1E18342C2752DBAB993DC9B6DCB7434B77C3EBB7D40BB +7E41BC7738B97331B77433B77534B77535B8A479CFA77ED0BB9ADCCEB6E6BD9EDE9966CA +9D6CCC7A37BA712AB58141BEBDA0DBB594D6874EBFB18DD4B592DA844CC1712FB8793BBC +7C40BD7A3DBC7B3EBD7B3EBD7C40BD702EB7AB83D69F77C56728A5753CAD7238AB733AAC +6B2EA7C2A9DA7848AB672FA1C6B2DC6B34A36B34A36C36A46E38A561279DA17DC4D0C1E2 +5E269D6C38A56935A36935A36A36A46C39A56733A2652FA160299E8055B1AA8CCBBDA2D8 +D8CAE88A5FB7652AA0723BA86E37A66E36A56E37A66E37A66E37A66E37A66E37A66E37A6 +6F38A6672DA18F65BBA98BC8642C9C6A36A06A35A06A35A06A35A069349F6A35A06E3BA2 +5E24988961B4D8CBE69364C46B29AD763AB3783CB4763AB3773BB4763AB3783DB46E2EAF +AD89D18A66AE5B268F6331946231945A268E7B51A5A88CC3521B89653496612F93623094 +6230946230946230946230946230946230946230945C2990764BA2B69FCD56208C643395 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094612F93643395571F8EAC99BF10140C000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000001000100000003 +0019840071BC0077A50070AB0071AC0072AB0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC +0072AC0071AC0073AC0072AC0072AC0073AC0073AC0073AC0073AC0073AC0073AB0072AB +0073AC0072AA0070A90070AA0071AA0070AA006FAA0070AA006FA9006FA9006FA9006FA9 +0070AA006FA90071AC006FA9006FA9006EA7006EA7006FA8006FA8006FA8006FA8006FA8 +006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006EA8006FA8006FA7 +006EA70071AA0074AE0073AD0074AD0074AE0074AD0074AC0074AB0074AC0074AC0074AC +0074AC0074AC0073AC0073AC0074AC0073AC0074AC0074AC0074AC0074AC0074AC0074AC +0074AC0074AC0074AC0074AC0073AB0073AC0375AC0068A571B9D5E2CDEDBBA0DBCAB1E2 +C7ACE0C7ADE0C7ADE0C7ADE0C7ADE0C7ADE0C7ADE0C7ADE0C7ADE0C8AEE0C6AADF9969C4 +9563C29664C39664C29664C29664C29664C29664C29664C29664C29664C29765C39664C2 +C8AFE0C3A8E1B38ED78F5AC49969C98E5AC46E2AB4702DB5702DB5702DB5702DB5702DB5 +702DB56F2BB4712FB6793AB97838B97839B97839B97839B97839B97738B97B3DBB7534B8 +8E5BC4C2A2E2772FBCB994DC9361C7712FB57839B9712FB56C28B38851C19665C7A377CF +CBB3E5C6ACE2AF87D6B18AD79058C57632B87B39BA7734B97734B98244BE7632B8B48ED8 +996CC6A57CCDA175CD6A25AFA175CCC4A8E1B28FD87F44BF7434B97C3FBD7C40BD7A3DBC +7C40BD702EB7A277D1A884CA6729A5753BAD7238AB753BAD7239AB763DAEB192CFA17DC4 +9772BF642B9F703CA66C35A36C35A36C36A46932A2BEA6D66E3CA66934A36A36A46A36A4 +6A36A46935A36A37A46A37A4622C9F612A9E875DB5DBCFE8F0ECF68558B5662BA0713AA7 +6E36A56E37A66E37A66E37A66E37A66E37A66E37A66E37A66E36A5703AA764299FBCA4D5 +7442A667319E6A35A06A35A06A35A06A35A06A35A069349F6C37A1642D9C5E2497A98AC7 +A67ECF793DB57335B1793FB5763AB3773BB4773BB47336B18148BBB9A1D157238C643395 +6332955A268EA98EC58057A85D2990623094623094623094623094623094623094623094 +6230946230946230945C2990764BA2B69FCD56208C643395623094623094623094623094 +6230946230946230946230946230946230946230946230946230946230946231945B278E +906BB5616261000000030303000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000010002010000000018840072BB0074A7006FAC0072AB +0072AB0071AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC +0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC0071AC +0071AC0072AC0072AC0072AC0072AC0071AC0072AC0071AC0071AC0073AC0072AC0072AC +0073AC0073AC0073AC0073AC0073AC0072AB0072AB0073AC0072AA0070AA0070AA0071A9 +0070A90070AA0070AA006FAA0070AA0070AA0070AA0070AA0070AA0070AA006FA9006EA7 +006EA7006FA8006FA8006FA8006FA7006FA8006FA8006FA8006FA8006FA8006FA8006FA8 +006FA8006FA8006FA8006FA8006EA8006FA7006FA8006EA70071AB0074AE0073AD0073AE +0074AE0074AD0074AE0073AC0073AB0074AC0074AC0074AC0074AC0074AC0073AC0073AC +0074AC0074AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0073AB +0074AC0074AC0074AB0075B20B84BDA1B7DF9C56C77C41BD884DC28649C18649C18649C1 +8649C18649C18649C18649C18649C18548C0884CC2BA97DBBE9DDDBD9CDDBD9CDDBD9CDD +BD9CDDBD9CDDBD9CDDBD9CDDBD9CDDBD9CDDBD9DDDBC9ADCBA98DBFDFDFECAB2E4B897DB +BC9DDDBC9CDDBFA0DEBEA0DEBFA0DEBFA0DEBFA0DEBFA0DEBD9EDDC4A9E1AE88D48044BC +874EC0854CBF854CBF854CBF854CBF864EC08146BD7230B66219AE9869C9B792DCAD84D3 +8044BD854CBF874EC1BA9BDCBFA3DFBC9BDDC0A0DEAF86D58244BE864AC07632B8732DB6 +7B39BB8041BE7F40BD7F40BD8041BD7C3BBB894EC2BFA3DD6E2FAF9567C4B592D8722FB3 +7433B57535B5A276CCEBE2F49261C97536BA7332B97D41BE7B3EBD793BBCB796D98958B8 +6F34AA743BAD743BAD6B2EA76D30A8733AACC2AADAE4D9EC895DB661279D5F249B6C35A3 +6E38A56F3AA562289D9C77C1A383C75E269C6C39A56935A36A36A46C39A56631A26732A2 +9470BEBDA6D6A889CA794AADB79CD3A07EC2966FBF63269E713AA76E36A56E37A66E37A5 +6E37A56E37A66E36A66E36A66E37A66F39A6682EA2C0A8D77342A667319E6A35A06A35A0 +6A34A06A34A06A34A06A35A069349F6B36A06B36A0622A9AA484C3BB9FD87B40B66B2AAD +793EB5763AB3773BB47335B18650BEB9A1D158248D6432956332955C2890BAA4D0663697 +602D92612F936230946230946230946230946230946230946230946230946230945C2990 +764BA2B69FCD56208C643395623094623094623094623094623094623094623094623094 +6230946230946230946230946230946230946230945A278D7E4FAE858386000000040404 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000001 +000201000003001A850071BB0074A70070AC0072AB0071AC0072AC0071AC0071AC0071AC +0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC +0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC +0071AC0072AC0071AC0072AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC +0072AB0073AC0073AC0072AA0070A90070A90071A90070AA0071AA0070AA0071AA0070AA +006FA9006FA90070A9006FA9006FA90070AA006FA9006EA7006FA8006FA7006FA8006FA8 +006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006EA8 +006FA7006FA8006EA70071AB0074AE0073AD0074AE0074AD0074AD0074AD0073AE0073AC +0073AB0073AC0074AB0074AC0074AC0073AC0073AC0073AC0073AC0074AC0074AC0073AC +0073AC0073AC0073AC0073AC0074AC0074AC0073AB0074AC0073AB0073AA0078B5007EBF +0075B90B81B59CB0DB9348C26D2DB57E3EBC7D3CBC7D3CBB7D3CBB7D3CBB7D3CBB7D3CBB +7D3CBB7D3CBC7C3BBB742FB7732EB7742EB7742EB7742EB7742EB7742EB7742EB7742EB7 +742EB7742EB77632B86A20B2A67BD2B998DBA87ED2661BB1712CB77937BA9662C9945FC8 +945FC8945FC8945FC89460C8935DC79967CBD0B9E6C5AAE1C6ABE1C5ABE1C5ABE1C5ABE1 +C5AAE1C6ACE2C1A5DFAE89D6B18DD7AA82D3EAE0F4D6C4EAA479D1CAAFE3C6A9E19865CA +9763C98042BE712AB57733B87D3DBC7D3CBC8041BD8142BE7F40BD7E3EBC7F3FBD7F3FBD +7F40BD7834B99864CAB18ED46B2AAD7538B2C2A7DE854DBE793BB77B3DB87433B48349BC +BB9BDBC0A2DE996ACC6E2CB6793BBB8045C0C0A6DC6C2FA76C2FA86D30A86D31A88C5CBA +D0BDE3D4C2E59F77C7D1C0E1B69CD0B193CEA482C66F3AA661279D632A9E6E39A56C35A4 +BFA8D86F3DA76833A36D3AA56630A15F289D7241A9BCA4D6A789C97342AA5B219B6D3AA6 +B59AD26B37A2A889C8946CBD63279F713AA76E36A56E37A66E37A56E36A56E36A66E36A6 +6E36A66F38A6672DA18F63BBAE92CC5F26986C38A16A35A06A34A06A34A06A34A06A34A0 +6A35A069349F6A35A06C37A15B20967648A7BCA0D89E74CB6E2EAF793EB5773BB4783DB4 +6C2CAEB493D68762AB5A258F58228D8F6BB2A385C057228C633295623094623094623094 +6230946230946230946230946230946230946230945C2890774BA2B69FCD56208C643395 +623094623094623094623094623094623094623094623094623094623094623094623094 +62309462309462309463329558238EAC95C42A2E26000000010101000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000001000200000004001A840071BB0074A7 +0070AC0072AB0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC +0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC +0072AC0072AC0071AC0071AC0071AC0071AC0072AC0071AC0072AC0071AC0072AC0072AC +0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AB0073AC0072AB0072AA0070A9 +0070AB0071AB0070AA0071A90071A90071A90070A90071AA0070A90070A9006FA9006FA9 +0070AA006FA8006EA7006FA8006EA7006FA8006FA8006FA8006FA8006FA8006FA8006FA8 +006FA8006FA8006FA8006FA8006FA8006FA8006EA7006FA8006FA8006EA70071AB0074AE +0073AD0074AE0073AD0073AD0074AD0074AD0073AD0073AE0073AD0073AB0074AC0074AB +0074AC0073AC0073AC0073AC0073AC0074AC0074AC0073AC0073AC0073AC0073AC0074AC +0073AB0074AC0074AC0073AA0075AF007AB9007CBD007BBC017DBC0073B10D83B69BAEDB +AF69CF7A38BA7E3FBC7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD8142BE +8142BE8142BE8142BE8142BE8142BE8142BE8142BE8142BE8142BE8142BE8244BE7B39BB +C4A7E08248BEA479D0C2A5E17836BA7F42BE7634B97735BA7735BA7735BA7735BA7735BA +7735BA7634B9722EB77634B97533B97533B97533B97533B97634B97330B87E40BEA87ED3 +A67AD1A375D0E3D5F1F9F6FBBE9EDD7632B87531B87A38BA7835B97E3DBC8243BE8041BD +7E3EBC7F3FBD7F3FBD7E3EBD7F3FBD7F3EBD7F3EBD7E3EBC8040BD7936BABC9DDC8A58BE +7639B36D2DAEB898D79360C67535B57B3DB87C3FB97839B7702CB28C56C0B796D9AC86D6 +7B3EBD844BC2B89BD6682AA59163BDA783CACBB6E0AE8CCF9C72C46F32AAA07BC5C2B0D4 +865BB28054AE9E7CC1BEA9D7D2C1E28E64B9652CA0591C98B298D08155B2612B9F5E269C +7747ACA88BCAC0A9D87240A95E259C6731A26F3CA75C229B9F7DC49A76BF551995AC8FCB +946CBD63279F713AA76E36A56E37A66E36A56E36A56E36A66E36A56F38A6672DA1895CB7 +AD91CB5B20966D39A269349F6A34A06A34A06A34A06A34A06A35A06A35A06A35A069349F +6D3AA2632C9B7343A6AB8EC8A57FCE6927AD7437B27A3FB56C2BADA67ECF9878B858238D +633194B6A0CD6B3D9A5F2C92623094612F93623094623094623094623094623094623094 +6230946230946230945C2990754AA1B69FCD56218C643395623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094612F93643395 +541F8AA585C4464843000000020202000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000010002010000020019840071BB0074A70070AC0072AB0071AC0071AC0072AC +0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC +0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC +0071AC0071AC0072AC0072AC0071AC0072AC0072AC0073AC0072AC0073AC0073AC0073AC +0073AC0073AC0072AC0073AC0072AB0070AA0070A90070AA0071AB0070AC0071AB0071AA +0071AA0071AA0071AA0070A90071A90070A90070A9006FA90070AA006FA9006EA7006FA8 +006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8 +006FA8006EA7006FA8006FA8006EA70072AB0074AE0073AD0074AD0073AE0073AE0074AD +0074AD0074AD0073AE0073AD0073AE0073AD0074AB0074AC0074AC0073AC0073AC0073AC +0074AC0074AC0074AC0074AC0073AC0073AC0073AC0073AB0074AC0073AB0073AB0075AF +007BBC007CBE007BBC007CBD007BBB017AB40073B10E7FB673BFD8AA8BD67B32B97D40BD +7F3FBD7E3EBC7F3FBD7F3EBD7F3FBD7F3FBD7F3FBD7F3EBD7F3EBD7F3EBD7F3FBD7F3FBD +7F3FBD7F3FBD7F3EBD7F3EBD7F3FBD7F3FBD7936BA9A66CBBB9BDA6F2CB47C3EBCDFCFEE +905AC67533B97F41BE7D3EBD7D3EBD7D3EBD7D3EBD7D3EBD7D3EBD7D3FBD7F40BE7E40BD +7E40BD7E40BD7E40BD7E40BD7E40BD7F41BE7C3CBC7432B86B25B4B390D98F5AC7B38FD7 +B593D8BD9CDC8142BE7C3ABB8142BE7F3FBD7E3EBC7F3FBD7F3EBD7F3EBD7F3FBD7F3FBD +7F3FBD7F3EBD7F3EBD7F3FBD7F40BD7C3CBCC7AEE2793EB4763AB37235B18651BCC3A7DE +7332B47C3FB97B3DB87B3DB87D40B97635B67230B3AC86D3BA9ADAD6C4EA9E75C5CBB5E0 +DBCBE9966AC17338AC6E32A96A2CA66829A6BA9FD56D409ABEA7D460279960279968329E +A07EC1AF93CCBDA6D6A789C98F64B9B297CF6C39A5AE92CDBBA2D5926CBC632BA06732A2 +6C38A56A35A46C38A55D249CA586C89874BE5F279B622B9DAA8DCA946BBC63279F713AA7 +6E36A56E37A66E36A66E36A66E36A66E37A66D35A5733DA9B499CF7645A766309E6A35A0 +6A34A06A34A06A34A06A35A06A35A06A35A06A35A06A35A069349F6B37A167319E5B2196 +9874BCC7ADDF854FBC6E2FAF793EB57538B4C1A9D8602F926B3C9ABBA6D15A258E633295 +612F936230946230946230946230946230946230946230946230946230946230945C2890 +7A4FA4B39BCB56218C643395623094623094623094623094623094623094623094623094 +623094623094623094623094623094623094623094612F935F2D916B389FA29BA9000000 +020202000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000001000201000002001985 +0071BB0074A70070AC0072AB0071AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AB0072AC0073AB0072AC +0070AA0071A90071AA0071AA0070A90071AB0071AC0071AC0071AC0071AC0071AC0071AA +0070AA0071AA0070A90070AA006FA8006FA8006EA7006FA7006FA7006FA7006FA7006FA7 +006FA7006FA7006FA7006FA7006FA7006FA7006FA7006FA7006EA7006FA8006EA7006EA7 +0072AB0074AE0073AD0073AD0074AE0074AE0074AE0074AE0074AD0074AE0074AE0074AE +0074AE0074AD0074AB0074AC0074AB0074AC0074AC0074AC0074AC0074AC0074AC0074AC +0074AC0074AC0073AB0074AC0073AB0073AB0079B7007CBD007CBD007BBC007BBC007CBD +007BBC0079B5017AB40377B30068AA41A3C8B390D97931B87D40BD7F3FBD7E3EBC7F3FBD +7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD +7E3EBC8142BE7531B8C5A9E18851C2783AB97838B97A3BBABFA1DE8549C07A3ABB7D3EBD +7D3EBD7D3EBD7D3EBD7C3EBD7C3EBD7D3EBD7D3EBD7D3EBD7D3EBD7D3EBD7C3EBD7C3EBD +7D3EBD7C3DBC7F42BE7431B89B6BCCBEA1DE651DB2B998DC8951C2864EC1C0A0DE8345BF +7936BA8040BD7E3EBC7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD8041BD +742FB7AA7FD3A984CF6D2CAE793DB5763AB3763AB3E0D2ED925FC57433B47C3EB97B3DB8 +7A3CB87B3EB87E41BA6D28B07C3EB9E8DDF4E3D8EE763DAE7035AA692BA67338AC7439AC +7136AB814BB5B49ACE59248D9D7EBC9B77C05F27996C38A15E25985F27997B4CAA8458AF +B79ED2D5C7E5CDBBE1875DB66731A260279E6B37A46A35A46934A36A35A46C38A55D249C +A484C79975BF5F279B6C38A360289BAA8DCA946BBD63279F713AA76E36A56E37A66E37A6 +6E37A66E36A5713BA760239DB093CE8256AF632B9B6A36A06A35A06A35A06A35A06A35A0 +6A35A06A35A06A35A06A35A06A35A069349F6A36A06B37A1642C9C794BA8B69AD38C58C0 +6E2FAF783CB5C5AFDB4F1886A78AC38C67B059248E633194623094623094623094623094 +62309462309462309462309462309462309464339557228CB49DCC784DA35C2990623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094623094623094623094643295551F8AA382C452564D000000030303000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000003000201000004001A850071BB0074A70070AC0072AB0071AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0073AC0073AC0072AC0073AC +0073AC0073AC0073AC0073AC0072AB0073AC0072A90070A90070AA0071AA0071AA0071AA +0071A90071AC0071AB0071AB0071AB0071AB0071AB0070AC0070AC0071AC0071AC0070AB +006EA5006EA6006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8006FA8 +006FA8006FA8006FA8006FA8006FA8006EA70070A90072AB0074AE0073AD0074AD0074AE +0074AE0074AE0074AE0074AE0074AE0074AE0074AE0074AE0074AE0074AD0074AC0074AB +0074AC0074AC0074AC0074AC0074AC0074AC0074AC0074AC0073AB0074AC0074AC0073AB +0075AE0079B7007CBE007BBC007BBC007CBD007CBD007BBC007CBD007BB90078B30079B4 +067CB6006DAD43A3C8B390D97931B87E40BD7F3FBD7E3EBC7F3FBD7F3FBD7F3FBD7F3FBD +7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7E3DBC8446BFC1A3E0 +7F43BD793AB97D41BC702DB5A57BCFB28CD8702CB67F41BE7C3DBC7D3EBD7D3EBD7D3EBD +7D3EBD7D3EBD7D3EBD7D3EBD7D3EBD7D3EBD7D3EBD7D3EBD7C3DBC7F41BE732FB89765CA +BA99DC7738BB702EB7BD9DDE9766C96D28B38A54C2CEB6E6A376D07530B78243BE7F3FBD +7E3EBC7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7E3FBD7F3FBD7A38BAE1D2EF9669C56F30AF +783DB4793EB56C2BAEA078CBA67DCF7434B57B3EB87B3DB87A3CB87C3EB97738B68044BC +AF8BD3C3ACDAB49AD19C73C4692AA67439AC7339AC743AAC6829A59E74C79A7BB94A1084 +8E6AB1A889C76028996B36A06F3CA368339F581D94865AB2AE92CCF3EFF7C3ADD8916ABB +5E259D6A35A46B36A46934A36A35A46A35A46C38A55D239CA586C8916BBA5E259B6C38A3 +6A35A260289CAA8DCA946BBD63279E713AA76E36A56E37A66E37A66E37A67039A7652AA0 +A887C9936CBB632B9B6B36A06A35A06A35A06A35A06A35A06A35A06A35A06A35A06A35A0 +6A35A06A35A06A35A069349F6B37A1632B9B6A35A0BDA4D5B292D46826ACA177CB9473B5 +A284BF7D54A65B278F623194623094623094623094623094623094623094623094623094 +62309462309464339557218CB7A0CE7347A05D2990623094623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +63329557238B9067B86D6C6E000000020202000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000002000100 +0000030019840071BB0074A70070AC0072AB0071AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC +0072AC0072AC0071AC0073AC0072AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC +0073AB0072AC0071A90071A90071A90070A90070A90070AA0070AA0070A90071AB0071AC +0071AB0070AB0070AB0071AC0071AC006FAA006FA7006EA5006EA6006FA6006FA5006FA6 +006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6006EA6006FA6006FA6 +006EA50070A80074AD0074AD0073AE0074AE0074AE0074AE0074AE0074AE0074AE0074AE +0074AE0074AE0074AE0074AE0074AE0074AE0074AE0074AB0074AC0074AC0074AC0074AC +0074AC0074AC0074AC0073AB0074AC0073AB0073A90076B1007CBD007CBD007BBC007CBC +007CBD007CBD007CBD007BBC007CBD007AB80078B30079B40078B3047BB5006DAE41A3C8 +B390D97930B87E40BD7F3FBD7E3EBC7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD +7F3FBD7F3FBD7F3FBD7F3FBD8041BD7530B7A273CFAA83D26F2BB57D40BB7A3CBA7D40BB +712EB5B38FD6A172CF7431B87F41BE7C3DBC7D3EBD7D3EBD7D3EBD7D3EBD7D3EBD7D3EBD +7D3EBD7D3EBD7D3EBD7C3DBC7F41BE7431B89664CABB9ADC7535BA7C3FBD712EB8B694DB +996ACB7535B8793ABA7230B6AD88D4A87FD36F27B47C3CBB8041BD7E3EBC7F3FBD7F3FBD +7F3FBD7F3FBD7F3FBD7C3BBB8C51C3C2A6DD6E2FAF793DB5763AB3763AB3773BB4783DB4 +C1A5DD7433B57C3FB97A3CB87C3EB97838B67B3CB9C0A3DE7540ABAA8ACC8257B2916CBC +AD8ACE7236AB6E31A9763CAE692AA6A27AC89A7BBA58238E5A268EBBA4D17848AA66309D +5A20967B4CACCDBCDFB093CA6F3B9FA585C3865CAF9672B9A686C96F3BA7632C9F6B37A5 +6A35A46934A36A36A4662FA17C4EAFB399D16732A06A35A26A35A26A35A260289CAA8DC9 +946BBD63279E713AA76E36A56E37A66E37A66E37A66C34A4743EAABEA6D6632B9B6B37A1 +6A35A06A35A06A35A06A35A06A35A06A35A06A35A06A35A06A35A06A35A06A35A069349F +69349F6B36A069349F5E25988F68B5A986CFA77ED0B49DCBA284C057218C653496612F93 +62309462309462309462309462309462309462309462309462309462309464339557218C +B7A1CE7549A05D2990623094623094623094623094623094623094623094623094623094 +623094623094623094623094623094623094623094623094612F93633294602B94AC9EBA +040701000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000300020000003300188C0071B90074A70070AC +0072AB0071AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC +0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC +0071AC0071AC0072AC0072AC0072AC0072AC0071AC0072AC0071AC0071AC0072AC0072AC +0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AC0072AB0070AC0071AB0072AB +0071AB0071AB0071AB0071A90071A90071A90071A90071AB0070AC0070AC0071AC0070A9 +006FA7006EA5006EA5006FA6006FA6006FA5006FA6006FA6006FA6006FA6006FA6006FA6 +006FA6006FA6006FA6006FA6006EA6006FA6006FA5006EA50070A80074AE0073AC0073AB +0074AE0074AD0074AD0074AD0073AD0073AD0074AD0074AE0074AD0074AD0074AE0073AE +0073AE0074AD0074AD0074AC0074AC0074AC0073AC0073AC0074AC0074AB0073AB0074AC +0073AB0074AD0078B5007CBD007CBD007BBC007CBD007BBD007BBD007CBD007CBD007BBC +007CBD007AB80078B30079B40079B40078B3037BB5006DAE3FA2C8B490D97930B87D41BD +8040BD7E3EBC7F3FBD7F3EBD7F3EBD7F3EBD7F3FBD7F3FBD7F3FBD7F3FBD7F3EBD7F3FBD +7F3FBD7C3BBBB792D99563C77535B87C3EBB7B3DBA7B3EBB7737B9864EC0C2A3DF7635B9 +7B3BBC7D3EBD7C3DBC7C3EBD7C3EBD7C3EBD7D3EBD7D3EBD7D3EBD7D3EBD7C3DBC7E40BD +7735BA925DC7BD9EDE7434BA7A3BBC7B3EBD7839BB8349C1C6ACE17534B77D40BB7C3EBB +7230B6A87FD1C7ACE28A4EC27835B98142BE7E3EBC7F3FBD7F3FBD7E3EBC8143BE722CB6 +B894DA9567C47031B0773CB4773BB4773BB4773BB47437B2B493D5925FC47636B67D40B9 +7838B67B3CB9BD9FDC8454B4591A9BB599D28E67BA5519979C7AC2EAE1F2804AB36B2CA7 +793FB0C0A9D6602F926534965C2890835CAAAB8EC9632B9BA687C6BEA8D6A17FC05A1E91 +642C987645A4BEA9D5561B909A77BCBBA4D47F51B1632B9F6A35A36B36A46934A36B37A4 +632C9FBEA6D76D39A46933A16934A16A35A26A35A260289CAA8DC9936BBD63279E713AA7 +6E36A56E37A66E37A66B33A47946ADBEA8D6612A9A6B37A169349F6A34A06A34A06A35A0 +6A35A06A35A06A35A06A34A06A34A06A34A06A35A06A35A06A35A069349F6A35A06D39A2 +61289A875CB1C7B2DCCEBFDE8A65AF5C2990633195623094623094623094623094623094 +62309462309462309462309462309462309464339557218CB7A1CE7448A05D2990623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094623094623094612F936534964F1885A782CB535750000000030303000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000003000000000244004DBE0074B50073A80070AC0072AB0071AC0072AC0072AC0071AC +0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC +0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC +0072AC0071AC0072AC0071AC0072AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC +0073AC0072AC0073AC0072AC0070AC0071AB0070AC0071AC0072AC0072AC0072AB0072AB +0072AB0071AB0070AB0070AA0071AB0071AB006FA8006EA5006EA5006FA6006FA6006FA6 +006FA5006FA5006FA5006FA5006FA6006FA6006FA5006FA5006FA5006FA5006FA5006FA6 +006FA6006EA5006EA60072AB0074AE0073AE0073AC0074AB0073AB0074AB0074AB0073AD +0073AE0073AE0073AE0074AD0074AD0074AD0073AD0073AE0073AE0073AD0074AD0074AE +0074AC0073AC0073AB0073AC0073AB0074AC0074AC0073AA0074AC007ABA007CBE007BBC +007BBC007CBD007BBC007BBD007BBD007BBD007BBD007BBC007CBD007AB80078B30079B4 +0079B40079B40078B3047BB5006DAE42A2C8B391D97D30B9793ABB8041BD7E3EBC7F3FBD +7F3EBD7F3EBD7F3EBD7F3FBD7F3FBD7F3EBD7F3FBD7E3EBC7F3FBD7E3EBCC2A5E07433B7 +7C3FBB7A3CBA7B3DBA7A3CBA7C3FBB7230B69261C7D6C3EA7939BB7D3FBD7D3EBD7D3EBD +7C3EBD7C3EBD7D3EBD7D3EBD7D3EBD7C3DBC7D3EBD7D3FBD732EB7C1A3DF905CC87432B9 +7C3FBD7A3CBC783ABB8348C1C5AAE07331B67C3FBB7B3DBA7D3FBB6F2BB4B796D9D1B9E6 +8548C07937BA8243BE7E3EBC7F3FBD7F3FBD7E3EBC7F3EBDBD9BDB8753BD7234B1773BB4 +773AB4773AB4783DB46C2BAE9C71C8A981D1702DB27A3CB77B3CB9BD9FDC8151B2682FA4 +6429A2B295D08C64B8632DA0632DA0794CADB59AD28753B86828A6BEA6D556218B57228C +5A258E623094CEBDDDC4AFD89068B56C379D5C22936D389E68319A7340A1BDA7D4642F99 +5E279568349CBBA4D3AA8BCA61299E642DA06B37A56A35A46833A3C0AAD96C38A36934A1 +6A35A16934A16A35A26A35A260289CAA8DC9936CBD63279F713AA76E36A56E37A67039A6 +652AA0A787C8946EBA60289A6B37A16A34A06A34A06A34A06A35A06A35A06A34A06A34A0 +6A34A06A34A06A34A06A35A06A35A069349F6B36A06A36A0642D9C5B21978B61B3D8CAE4 +5E2B91612F93612F93623094623094623094623094623094623094623094623094623094 +62309462309464339557218CB7A1CE7448A05D2990623094623094623094623094623094 +623094623094623094623094623094623094623094623094623094623094612F93633194 +5A278D8053AD817B88000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000030000000001440051BB007CAA +0071A80071AC0072AB0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC +0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC +0071AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0071AC0072AC0071AC0072AC +0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AB0073AB0072AB0070AB +0071AC0071AC0070AB0071AB0072AB0071AB0071AC0071AC0071AC0072AC0072AC0072AA +0070A7006FA7006EA5006FA6006FA6006EA5006FA6006FA5006FA5006FA5006FA5006FA5 +006FA6006FA6006FA5006FA5006FA5006EA5006FA6006FA6006EA50071A90073AD0074AE +0073AD0073AE0073AD0073AB0073AC0074AC0074AC0073AB0073AB0073AB0073AC0074AE +0074AE0074AE0073AD0073AD0073AD0073AD0074AD0074AE0074AB0073AB0073AC0073AB +0074AC0074AC0073AA0077B3007BBB007CBD007BBC007BBC007CBD007CBD007BBD007BBD +007BBD007BBD007BBD007BBC007CBD007AB80078B30079B40079B40079B40079B40078B3 +047BB5006FAE409AC6C0BEE5985BC77533B88142BE7E3EBC7F3FBD7F3EBD7F3EBD7F3FBD +7F3FBD7F3EBD7E3EBC8142BE742FB7A97CD2AC85D47433B77B3EBB7B3DBA7B3DBA7B3DBA +7A3CBA7C3FBB7331B6CAB1E3A377D0722DB77F41BE7C3DBC7C3EBD7C3EBD7C3EBD7D3EBD +7C3DBC7D3EBD7C3DBC7633B9B693DA9A6BCC7331B97C3FBD7A3CBC7B3DBD793ABC8044BF +C3A7E07C3FBB7A3CBA7B3DBA7A3CBA7D40BB6F2BB47F44BDC2A3DF894DC2732DB78041BD +7F3FBD7F3FBD7A38BA8F57C5B797D76A28AC793FB5763AB3773AB4773AB4773BB47538B3 +7E47B8C0A4DC7A3CB87A3BB8BD9FDC8151B2662BA3733EAB6125A0B295D18C64B8612A9E +6D3AA6622C9F6C39A5AE8FCDB696D49A79BA7A4FA5B299CBCABBDAAB95C4D5CDE1B79CCF +723FA16128966E3A9F69339B67309A7542A3B9A1D15C24946D3A9F67339C5921928E66B4 +AF93CE794AAE61299E6B36A46832A2C1AAD96C37A36934A16934A16A35A16934A16A35A2 +6A35A260289CAA8DCA946BBC63279F713AA76E36A5703AA762259EA481C6936DBA5E2598 +6C37A16934A06A34A06A34A06A35A06A35A06A34A06A34A06A34A06A34A06A35A069349F +6A35A06A35A061299A642D9B8E66B7BFA9D6A182C29F80C1A184BF541E8A653496612F93 +62309462309462309462309462309462309462309462309462309462309464339557218C +B7A1CE7448A05D2990623094623094623094623094623094623094623094623094623094 +623094623094623094623094623094623094612F9364339558238DAF99C4272C23000000 +010101000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000030001000000430051BB007BAA006FAB0071AC0072AB0071AC0071AC +0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC +0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC +0071AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC0073AC0072AC0073AC0073AC +0073AC0073AC0073AC0072AB0073AC0072AC0070AC0071AB0071AB0071AB0071AB0070AB +0071AB0072AB0071AB0072AC0072AC0072AB0070A9006FA6006EA5006EA5006FA6006EA5 +006FA5006FA6006FA6006FA6006FA5006FA5006FA5006FA6006FA6006FA6006FA6006EA5 +006FA5006FA6006EA5006EA50071A90074AE0074AE0073AD0073AD0073AE0073AC0073AB +0074AC0074AB0074AB0074AC0073AC0073AC0073AC0074AC0074AC0074AB0073AD0073AE +0073AE0073AE0074AD0074AD0074AE0073AC0074AB0074AC0073AB0073AB0077B4007CBE +007CBD007BBC007CBD007BBC007CBD007CBD007CBD007BBD007BBD007BBD007CBD007BBC +007CBD007AB80078B30079B40078B30079B40079B40079B40078B3027AB40273B10081B5 +86B4D8A25DC97333B88142BE7E3EBC7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7D3DBC +8345BFBFA2DF8248BD7838B97B3DBB7B3DBA7B3DBA7B3DBA7A3CBA7B3DBA7B3DBA6F2CB4 +BB9ADB935FC87634B97E3FBD7D3EBD7C3EBD7D3EBD7D3EBD7C3DBC7E40BD7836BAB18BD7 +9E70CE702DB77D40BE7A3CBC7B3DBD7A3CBD7D3FBE702DB7AA82D5A87FD2702EB57C3FBB +7B3DBA7A3CBA7D41BC7636B87F44BDC3A6E0B089D67733B87F40BD8243BE7530B7B28AD7 +9F75C97031B0783CB4783DB4783DB4783CB4763AB37A3FB56A28ACB99AD88D57C3BA9BDB +8353B3652BA2713AA9703AA96225A0B295D18C64B8612A9E6A37A46E3BA6652FA05F289D +D4C5E5B8A3CC9F88B9AB97C1613A8B714D95F4F0F7926BB7BAA2D18E65B45E24946C379D +6A349C67309AAE93CA8054AB622C9869359C6B389E5C25948960B1BCA4D38C63B96630A2 +652FA1C2ACDA6D3AA46933A16A35A26A35A16A35A26934A16A35A26A35A260289BAA8DCA +936BBC63279F713AA76F38A66930A28657B5B092CE67329E6A35A06A35A06A34A06A35A0 +6A35A06A35A06A35A06A34A06A35A069349F6A35A06C37A167319E662F9D8E66B8BAA3D3 +AB90C87243A35A2494612C98B69DCE70439D5E2B91623094623094623094623094623094 +62309462309462309462309462309462309464339557218CB7A1CE7448A05D2990623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094612F936432955420898B5CB9878787000000050505000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000004000000000144 +0052BB007BAA006FAB0072AC0071AB0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AC +0072AB0070AA0071AA0070AC0070AC0070AC0070AC0070AC0071AC0071AC0072AC0071AB +0070A9006FA5006EA5006EA5006FA6006FA6006EA5006FA6006FA6006FA6006FA6006FA6 +006FA6006FA6006FA6006FA6006FA6006FA6006EA6006FA6006EA6006EA5006FA60073AC +0074AE0073AD0073AD0074AE0074AD0074AE0074AD0074AC0074AB0074AC0074AC0074AC +0074AC0074AC0074AB0074AB0074AB0074AB0074AC0074AC0074AC0074AC0074AE0074AE +0073AE0074AC0074AB0073AA0075AE007BBB007CBD007BBC007BBC007CBD007BBC007CBD +007CBD007CBD007CBD007CBD007CBD007CBD007CBD007BBC007CBD007BBA0078B30079B4 +0079B40079B40079B40079B40079B40078B3027AB40074B20077B187B6D9A25CC97333B8 +8142BE7E3EBC7F3FBD7F3FBD7F3FBD7F3FBD7F3FBD7B39BB8D54C4BC9CDD6F2CB47D41BC +7A3CBA7B3DBA7B3DBA7B3DBA7B3DBA7A3CBA7C3FBB7534B7925FC7BD9EDE7532B87E40BE +7C3DBC7D3EBD7D3EBD7C3DBC8042BE6F2AB6A87DD2B390D96B26B57E41BE7A3CBC7B3DBD +7B3DBD7B3DBD7C3FBD702DB7AB83D5A87FD2712EB57C3FBB7B3DBA7B3DBA7A3CBA7C3FBB +7738B97B3DBAA77ED0B28DD87531B87835B98A50C3BFA3DD773BB4793DB5773BB46D2DAE +6D2DAE6F30AF773BB47235B1824AB9C0A5DDDDCFEC7641AC5F229E733EAB6E37A8713AA9 +6225A0B295D18C64B8612A9E6D3AA660299E6C38A5D9CCE8FEFDFFA790BD3D0C714B1D7A +4D1F7EA18DB5B2A7BA7B49AB54198EAA8DC8936BB75F25946B359C5E23949B77BC9B79BD +5C24946A369D67339B6A379D6029975E2896AF94CAB79DD261299F8C63B9A98BC95E259B +6C39A36A35A26934A16A35A26934A16A35A26A35A260289CAA8DCA936BBD63279F703AA7 +7039A6672CA1BCA4D66B37A069349F69349F6A35A06A35A06A35A06A35A06A35A06A35A0 +6A35A06C38A167319E5F27996D39A2B49ACEAD92CA7344A4592293632F9A6B399F582193 +A486C4825BA95A258E623194623094623094623094623094623094623094623094623094 +62309462309464339557218CB7A1CE7448A05D2990623094623094623094623094623094 +6230946230946230946230946230946230946230946230946230946230945E2C906F3DA0 +9689A20A0C08000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000030000000001450051BB007BAA006FAB0072AC0071AB +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0073AC0072AC0072AC +0073AC0073AC0073AC0073AC0073AC0072AC0073AC0072AB0070AC0070A9006FA7006FA8 +006FA8006FA8006FA80070AA0071AB0071AB0071A9006FA5006EA5006EA6006FA6006FA6 +006EA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6 +006FA6006FA6006FA6006EA5006EA50071AA0073AD0074AE0073AD0073AD0074AE0074AE +0074AE0074AD0074AE0074AD0074AB0074AC0074AC0074AC0074AC0074AC0074AC0074AC +0074AB0074AC0074AB0074AB0074AB0074AC0074AD0074AC0074AD0073AD0074AC0075B0 +007BBB007CBD007BBC007BBC007CBD007CBD007CBD007CBD007CBD007CBD007CBD007CBD +007CBD007CBD007CBD007CBD007CBC007BBD0079B50078B30079B40079B40079B40079B4 +0079B40079B40078B3007AB40276B30077B188B6D9A25CC97332B88142BE7E3EBC7F3FBD +7F3FBD7E3EBC8041BD7632B8B896DA9766C87636B87B3DBB7B3DBA7B3DBA7B3DBA7B3DBA +7B3DBA7B3DBA7A3CBA7D40BB702DB5A479CFB48FD9702BB68043BE7C3DBC7C3DBC7F41BE +7633B98A52C3BD9DDD7E42BE7A3CBC7B3DBD7B3DBD7B3DBD7B3DBD7B3DBD7C3FBD702DB7 +AC85D6A175CF702DB57C3FBB7A3CBA7B3DBA7B3DBA7A3CBA7B3EBB7A3CBA6F2BB49F72CC +BB9ADC8648C09D6CCDA47DCC621DA86E2FAF7437B29E73C99A6EC7A57DCDC9B0E0CAB2E1 +BB9AD8B292D4E2D8EDB599D28C60BA6429A2682FA4723CAA6327A1B294D08D65B9632DA0 +632C9F895EB8AB91C88C6DABC0B3CEB4A3C6592E854E227C8666AA7D6E8F9382A1885AB5 +622C975F2796A688C5BEA7D46E3A9F591E91A788C59874BB5C24946A369D67339B69359C +6C3A9E6D3B9F561C907A4CA7A483C5A686C9A687C6571B9666309F6934A16D39A46A35A2 +6934A16934A16A35A26A35A260289CAB8DC9936BBD63279E713BA86B32A4B79DD37A4AA9 +66309E6A35A06A35A06A35A06A35A069349F69349F6C38A167329E5D24987240A5A382C5 +C2AED8774BA7582093622E9968369D66339C66339C622E997B4FA9B39BCB58228D643395 +612F9362309462309462309462309462309462309462309462309462309464339557218C +B7A1CE7448A05D2990623094623094623094623094623094623094623094623094623094 +623094623094623094623094612F93653496511B88A887C953584E000000030303000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000003 +0000000000430051BB007BAA006FAB0072AC0071AB0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0071AC0072AC0071AC0071AC0073AC0072AC0072AC0073AC0073AC0073AC0073AC0073AC +0072AC0073AC0072AC0070AB0071AB0071AC0070A9006FA70070A70070A70070A70070A7 +0070A70070A7006FA8006FA6006FA5006FA5006EA5006EA6006FA6006FA6006FA5006FA5 +006FA6006FA6006FA6006FA6006FA6006EA6006EA6006EA6006EA6006EA5006FA5006FA5 +0071AA0074AE0074AE0073AD0074AE0074AE0074AD0074AD0074AE0074AD0074AE0074AD +0074AB0074AC0074AC0074AC0074AC0074AC0074AC0074AC0074AC0074AB0074AC0074AC +0074AC0074AB0073AB0074AC0074AB0073AC0077B4007CBE007CBD007BBC007BBC007CBD +007CBC007CBD007CBD007CBD007CBD007CBD007CBD007CBD007CBD007CBD007CBD007CBC +007CBD007BBD0079B50078B30079B40079B40079B40079B40079B40079B40079B40078B3 +007AB40376B30077B187B6D9A25CC97332B88244BE7F3FBD7E3EBC7F3FBD8041BD7835BA +C5A9E1864EC07737B97B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA +7A3CBA7B3DBBBD9DDC854AC17735BA7E3FBD7E3FBD7634B98951C3C0A2DF7E42BE7736BA +7C3EBD7A3CBC7B3DBD7B3DBD7B3DBD7B3DBD7B3EBD7737BB8B55C5BB9CDC793BB97A3CBA +7B3DBA7B3DBA7B3DBA7B3DBA7A3CBA7B3DBA7D40BB7231B69868C9B591D9C3A8E09D72C9 +C0A3DBC3A9DEC1A4DCB18ED3B493D5A780CE7739B27C40B57738B3AF8DCFB59BCDA178C8 +B08ED0BCA3D6875AB7692FA55B1C9CB497D2875EB5501394A686C9E2DBEA592C878B6CAE +7B6298AF9DC25B318750237FB3A0C43920529D8EAA8759B4632D986B379E6129977B4DA8 +BBA2D1642C98946DB89F7DC05F289668349C67339B5F28965A2193581F917749A67342A3 +A485C4FFFFFFD1C2E37C4DAE8356B16933A15A1F986732A06833A16A35A26C38A36A36A2 +6A35A260289CAB8DC9936BBD64289F682FA28E63B9AE91CB5D23976C38A16A35A06A35A0 +69349F6B37A16A36A05D2397713FA4A687C7BAA4D29672BA602C98622E9968369D66339C +66339C66339C65329B67359C5C2695AE94CB825AA958238D633295612F93623094623094 +62309462309462309462309462309462309464339557228DB7A1CE7448A05D2990623094 +623094623094623094623094623094623094623094623094623094623094623094612F93 +64339555208A936ABB70716F000000030303000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000040000000000430051BB007BAA006FAB +0072AC0071AB0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC +0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC +0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0072AC +0072AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AC0072AC0070AC0071AC +0071AB0071AB0070AC0070A9006FA70070A8006FA8006FA8006FA8006FA80070A80070A7 +0070A7006FA7006EA7006FA5006FA5006FA5006FA6006FA6006FA6006FA6006FA6006FA5 +006FA5006FA5006FA5006FA5006FA5006FA7006FA80073AD0074AE0073AD0073AD0074AE +0073AE0074AD0074AD0074AD0074AD0073AD0073AE0073AD0074AB0074AC0074AC0074AC +0073AC0073AC0073AC0074AC0074AC0074AC0073AC0073AC0073AB0074AC0074AC0073AB +0073AB0079B50079B4007AB6007BBB007CBD007CBC007BBC007CBD007BBD007BBD007CBD +007CBD007CBD007CBD007BBD007BBD007BBD007CBD007CBC007CBC007BBD0079B50078B3 +0079B40079B40079B40079B40079B40079B40079B40079B40078B3007AB40276B30077B1 +86B5D9A35ECA6D2BB57E40BD7F3FBD8040BD7733B99C6BCCB795DA702EB57D40BB7B3DBA +7B3DBA7B3DBA7B3DBA7B3DBA7B3CBA7B3CBA7B3CBA7A3CBA7B3EBB7637B88045BEE2D5F1 +8549C07B3BBC7B3BBC874DC2C0A1DF7D41BE7737BB7C3FBD7A3CBC7B3DBD7B3DBD7B3DBD +7B3CBD7B3CBD7A3CBC7C3FBD7331B9C5AAE18146BD793ABA7B3DBA7B3CBA7B3DBA7A3CBA +7B3DBA7B3EBB7C3FBB7738B87939B9AF8AD6FCFBFECBB3E1844CBA8A54BD844CBA6D2AAD +6D2AAD6F2EAE7A3FB56E2CADA278CD9976BDA98AC68A58BA6321A28652B7B99BD5BCA2D7 +7C4CB0AD8ECDA384C8B398D18E6FAD5527864A187EB29DC84E2C75B9ACC88D70AB734F9B +988CA61700369D8EAA7B4AAC541A8E5D24945E269654188F69359DAF92CA8C62B2B69DCF +622D996B389E67339B9771BAB398CDAD8FC8B299CDBEAAD4916FB88760B0B6A1CFA68BC5 +BAA4D1B195CDAF92CE7645A96E39A4662F9F5C22996933A16C38A36B36A261299DAB8DC9 +956DBE5A1A99966EBEAB8DC95C22976C38A16A35A06A35A06C39A160289A67309EA88AC8 +BBA4D39470B964319B5A239467349C66339C65329B66339C66339C66329C66339C67349C +5F2A977D51ABAF95C85E2C91623094623094623094623094623094623094623094623094 +623094612F93653496541E8AB39CCB7549A15D2990623094623094623094623094623094 +623094623094623094623094623094623094623094612F93623093612D95A796B81E211A +000000010101000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000050000000001450051BB007BAA006FAA0072AC0071AB0071AC0072AC0072AC +0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC +0072AC0071AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC +0071AC0071AC0072AC0071AC0071AC0072AC0072AC0073AC0072AC0073AC0073AC0073AC +0073AC0073AC0072AC0073AC0072AC0070AC0071AC0071AC0071AC0070AC0071AB0070AC +0070A9006FA70070A8006FA7006FA8006FA8006FA7006FA8006FA8006FA80070A80070A6 +006EA7006EA6006EA5006EA5006EA5006EA5006EA5006EA6006EA6006FA80070A90070A9 +0070A9006FAA0070AA0072AC0072AE0073AE0074AD0073AD0073AE0073AD0074AD0074AD +0073AD0073AD0073AE0073AD0073AB0074AC0074AB0073AC0073AC0073AC0073AC0074AC +0074AC0074AC0073AC0073AB0074AC0073AB0073AB0075AE0079B7007BB9007AB60078B3 +0079B4007BBA007BBD007CBD007BBC007BBC007BBD007BBD007CBD007CBD007BBD007BBD +007BBD007BBD007BBD007BBC007CBC007BBD0079B50078B30079B40079B40079B40079B4 +0079B40079B40079B40079B40079B40078B3017AB40276B30079B183AFD7BC7FD67F3CBC +7B3CBB8142BE7632B8AC84D4A77DD1722FB67C3FBB7A3CBA7B3CBA7B3DBA7B3CBA7B3DBA +7B3DBA7B3DBA7B3DBA7B3DBA7B3DBA7D3FBB7432B7B391D8B995DB722FB77A3ABBCCB4E5 +8045C07736BA7C3FBD7A3CBC7B3DBD7B3DBD7B3DBD7B3DBD7B3CBD7B3CBD7B3DBD7B3DBD +7839BCC6ACE17A3CBA7A3CBA7A3CBA7B3CBA7A3CBA7B3DBA7B3EBA7535B7702CB5A074CF +CBB4E29767C4E8DDF1B390D36A27AC7537B27637B27B3FB57B3FB57A3EB5793DB47333B0 +AE88D18E67B57441A4BA9DD66D2FA87034AA6727A58958B9AF8ECFD8C8E7D7CCE29578B1 +4C1C7F55268577529DD7CEE0431D6D775D959376B19C86B3422F5A220340BCB2C4A785C7 +9670B99C78BD9A76BC9D7ABE956EB9A482C2D6C6E3EBE4F2926CB7BCA7D3C3B1D89E7DBF +855DB08E69B667369C561F90521A8E8D67B4A286C148118755218F764DA58A67B1B69FCF +C4B0D8AA8ECA9C78C26F3CA660279B642C9E622A9D60289CAE92CC946DBD60229DBBA1D6 +794BA966309E6C38A1632C9C5F2699885DB2B296CE9571BA622F9A5B259565329B68369D +65329B66339C66339C66339C66329C66329C66329C65329B68369D5B2595B49CCD663697 +612E93612F93623094623094623094623094623094623094623094623094612F93643395 +B39BCB6C3D9B5F2C92623094623094623094623094623094623094623094623094623094 +623094623094612F93653496531D8AAE94C7383E32000000010101000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000010001020000000000440051BB +007BAA006FAB0072AC0071AB0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC +0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC +0071AC0071AC0072AC0072AC0071AC0071AC0071AC0071AC0071AC0072AC0071AC0072AC +0072AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0073AC0072AC +0070AC0071AC0071AC0071AC0071AC0071AC0070AB0071AB0071AC0070A90070A7006FA8 +006FA7006FA8006FA80070A70070A8006FA8006FA8006FA80070A80070A60070A60070A7 +0070A90070A80070A80070AA0070AA006FAA006FAA006FAA006FAA0070AA0071AA0071AC +0071AB0072AB0074AD0074AE0073AD0073AE0074AD0074AD0073AD0073AE0073AD0073AE +0073AD0074AB0074AC0073AC0073AC0073AC0073AC0074AC0074AC0074AC0073AB0074AC +0073AB0074AC0075AE007BB8007BB9007BB8007AB70078B30079B40078B30078B5007BBA +007CBE007BBD007BBC007CBC007CBD007CBD007BBD007BBD007BBD007BBD007BBD007BBC +007CBC007BBD0079B50078B30079B40079B40079B40079B40079B40079B40079B40079B4 +0079B40079B40078B3007AB40076B30777B256B4D0A99EDA8338BC7A3CBB8547C0C7ACE1 +7738B87C3EBB7D40BB7D3FBB7D3FBB7D3FBB7D40BB7C3FBB793AB97839B97839B97839B9 +7839B9793AB97635B86016ADA47BD19E6ECD9664CAA57AD27230B87A3CBC7C3EBD7D40BE +7C3FBD7B3DBD7A3CBC7B3DBD7B3CBD7B3CBD7B3CBD7C3EBD7433B9A880D3A67CD07231B6 +7C3FBB7B3DBA7D40BB7939B97636B89361C8C4A9E0AB84D07130AF7535B2BB9ED99870C3 +AC88D07435B17A3EB4783BB3793CB4783BB3793CB3793AB4BDA2D5612998703CA1C6B0DD +7236AB7338AC763DAE6B2EA7692AA6EFE5F7B19EC649177D5C2F8A5021827E5AA39783AE +3209616D508DE5DEEC998AA85B4471CFCDD3CCBCE0D2C6E39B7CBD9D7FBE9E81BF9D7FBE +9F82C09A7BBC9474B9E6E0F0D5C8E4582191602D975D2A965A25935A249363309968389D +5D29958760B0AA90C75A289367399B5C2B945724915E2D95582591815BACA084C1B79FD1 +BCA5D4885DB58A60B76B36A3511492AA8DCA8557B3AC8CCC794BA95F26996028998459B1 +B89FD2AF96CB7D52AA57209267349C67359D65329B66339C66339C66329C66339C66339C +66329C66329C66329C66339C67349C5E29979A78BD9979B9541E8B643395612F93623094 +62309462309462309462309462309463329557228C8D68B1A183BF531C89653496612F93 +623094623094623094623094623094623094623094623094623094612F9363319459268C +7D4CAD918D96000000020202000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000100000000001300006A0051B3007BAC006FAB0072AC0071AB0071AC +0072AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC0072AC +0071AC0071AC0072AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC +0072AC0071AC0071AC0071AC0072AC0072AC0072AC0072AC0073AC0073AC0072AC0073AC +0073AC0073AC0073AC0073AC0072AC0073AC0072AC0070AC0071AC0071AC0071AC0071AC +0071AC0071AC0071AC0070AB0070AB0071AC0070A90070A7006FA8006FA80070A80070A8 +0070A70070A7006FA7006FA7006FA9006FA9006FAA006FAA006FAA006FAA006FAA006FA9 +006FA90070A90070A90070A9006FA90070AB0072AC0071AB0072AC0072AC0072AB0073AD +0074AE0073AD0073AD0074AD0074AD0073AE0073AE0073AE0074AD0074AB0074AC0074AC +0073AC0073AC0074AC0074AC0074AC0073AB0074AC0073AB0074AC0079B6007BB9007BB8 +007AB8007BB8007AB70078B30079B40079B40078B30079B3007AB8007BBC007CBD007BBC +007BBC007CBD007CBD007BBD007BBD007CBD007CBD007CBC007CBD007BBD0078B40078B3 +0079B40079B40079B40079B40079B40079B40079B40079B40079B40079B40079B40078B3 +0079B40479B40068AB2596C0B2A6DE7626B5A781D3A57AD17332B67839B96F2BB4702DB5 +702DB5702DB5702CB5702DB58147BE834ABF8349BF834ABF844BBF7E42BCA175CEBFA1DD +C3A8DEE5D9F2E3D5F18850C38147C0844BC17231B86F2BB7702DB77A3CBC7C3EBD7B3EBD +7C3EBD7C3EBD7B3DBD7B3EBD7332B99462C9B997DB6F2CB47E42BC7B3DBA702EB57C3FBC +AC85D4BFA1DB8650BB7332B0793BB47B3EB5C9B2E16120A3BBA0D89767C56E2CAE7A3EB5 +783BB37A3EB4702FAF996AC7AC8DCA642D9A642C9ACBB9DCA077C7692AA6753CAD6D2EA9 +9E77C4D5CEDD997DB7A68DBF582B87512283A188BB6C4F8C340C62654588DCD5E49389A0 +918D96AF9CC6541E907951A89E81C14E188A541F8E55218F5723904912889270B78B68B3 +8058AA9F81C05B2694612E9867369C65339A64329A63319966359B592392B7A1D1754CA4 +5C2B946333986333986232986434995B2993531E8E66379A7147A2AE95CAB099CBB399CD +B59AD07442A8AF93CEC1ABD99670BB7E51AEB8A0D2B299CD7B4FA95C26955F2A9768369D +66339C65329B66339C66329C66329C66339C66339C66339C66339C66329C66329C66329C +66339C632F9A6A399FB49DCE6A3A995F2D92623094623094623094623094623094623094 +62309463329558228D8B66B0A78BC3541E8B643395623094623094623094623094623094 +623094623094623094623094623094612F936332945A268FA187BB3D4139000000020202 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000100000000000F +00179C0051C5007BA8006FAB0072AC0071AB0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC +0072AC0071AC0073AC0072AC0072AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC +0073AC0072AC0070AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC +0071AB0070AB0071AC0070A9006FA70070A70070A70070A70070A80070A90070A90070A9 +0070AA0070AA0070AA0070A90070A90070A90070A90070AA0070AA0070AA0070AA006FA9 +0071AB0072AC0071AB0072AC0072AB0072AC0072AB0071AC0073AD0074AE0074AE0073AD +0074AE0074AE0074AE0074AE0074AD0074AB0074AC0074AC0074AC0074AC0074AC0074AC +0073AB0074AC0073AB0074AC0079B7007BB9007AB8007AB8007AB8007BB8007AB70078B3 +0079B40078B30079B40078B40078B30079B4007AB8007CBD007CBD007BBC007CBC007CBC +007CBD007CBD007CBD007CBC007CBC007BBD0079B60078B30079B40079B40079B40079B4 +0079B40079B40079B40079B40079B40079B40079B40079B40078B30079B4057CB6006EAF +2895BFAD9DDAC094DB8C5CC66E2AB48E5AC4B18DD6AC85D3AD86D3AD86D3AC86D3AD87D4 +C7AAE4C9AEE4C9ADE4C9ADE4C8ACE4CDB3E6B189D9955DCB9A65CED8C4EBD0BAE6B590D9 +CCB4E5C7ACE2B08BD7AC86D6AC85D57C3EBD7637BA7534BA7331B87230B8793BBC7F42BF +7535BA9C6DCDB593D9712FB57636B8793ABAAA83D2C8AEE09F73C96924AB7637B2793CB4 +783AB37A3DB5C6AEDF7036AC7943B1B99BD78249B97638B2793DB4793CB47739B3BA9ED7 +7A4BA8662F9C5D23969A76BC9E74C6692AA66E31A99E77C59A88AFA28ABB4B1A8078539F +AE97C5572988AA96C1654788B9ABC9D0CAD9C4C0C93D314BD9D7DC8157AE5E2E955A2893 +8864B2AA91C95F2E9665369A63349967399BBEAAD36333985825919473B8E5DCEE7345A3 +5C279466359B63319964329A66359B592392B7A1D1754CA45C2B94623298623298623298 +6131976333986435996030975E2D95562290511C8D7247A28561AEAD93C9B299CDE8E1F1 +E8E2F1A486C47B50A95B2595612C9867359D67349C65329B66339C66339C66339C66339C +66339C66339C66339C66339C66339C66339C66339C66339C65329B69379E582092AA8EC8 +7A4FA35C289062309462309462309462309462309462309462309463329557228D8C67B0 +A78BC3541E8A643395623094623094623094623094623094623094623094623094623094 +612F93653496501A87A37DC762675B000000030303000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000010000000000238E007EBD0075A20070AC0072AB +0071AB0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0071AC0072AC0071AC0071AC0073AC0072AC0072AC +0073AC0073AC0073AC0073AC0073AC0073AB0072AB0073AB0072AC0070AC0071AC0071AC +0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0070AB0070AB0071AC +0070AA006FA90070A90070A80070A9006FAA0070AA0070AA0070AA0070AA0070AA0070AA +0070AA0070AA0070AA0070AA0070AA0070AA0070AA006FA90071AB0072AC0071AB0072AB +0072AC0072AB0072AC0072AB0071AC0072AD0073AD0074AE0073AD0074AE0074AE0074AE +0074AD0074AB0074AC0074AC0074AC0074AC0073AB0074AC0074AC0073AA0076AF007AB7 +007BB8007AB8007BB8007AB8007AB8007BB8007AB70078B30079B40079B40078B30079B4 +0079B40078B30078B30079B5007BBB007CBE007CBD007BBC007CBD007CBD007CBD007CBD +007BBC007CBD007BBA0078B30079B40079B40079B40079B40079B40079B40079B40079B4 +0079B40079B40078B30079B40079B40079B40078B3037AB4006FB02794C2DEE8F5CDA7E2 +C8B2E4BE9DDFA77AD4AB7FD6AA7ED6AA7ED5AB7FD6A97CD57E3BC07A34BD7B36BE7B35BE +7B35BE7B35BE7C37BE732AB9945CCBB491D4D4BFE7864CC2732FB77634B9A074CFA980D3 +A77ED3C5A9E1CDB6E5AD86D69665CB9F72CF7E42BF6F2BB76B25B58E59C6BA99DC6B26B2 +905CC5B795DAAA83CF783AB37130AF7B3FB5793BB4783AB3783AB37A3DB5C5ADDF733BAE +6729A79B73C5B493D56B28AC7C40B57435B1874FBDB396CD5D22956D39A067309C7645A5 +BA9FD46F33A98046B7B4A2C7583A7CB099C65121835627866F4898BFADD2E9E4EECBC4D3 +7E7192D1CADA545360D0D0D28C65B7491287562390602F964D168AB59ECD855FAE5B2993 +5724909E80C09474BA57249165369A592692825CACB39CCF764AA65B269466359B633199 +66359B592392B7A1D1754BA45C2B94623298623298623298623298623298623298623298 +62329867399B6232985825914E198B784FA6AA90C6AA90C6D4C7E28963B365319B64309A +6A389E65329B66339C66339C66339C66339C66339C66339C66339C66339C66339C66339C +66339C66339C66339C66339C66339C66339C612C98835AAFAD93C7551F8B643395612F93 +62309462309462309462309462309463329557228D8C67B0A78BC3541E8A643395623094 +623094623094623094623094623094623094623094612F936230945E2B907344A28D8397 +0A0C08000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000001000000001218006B9D0075B4006FA80072AC0072AB0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0071AC0072AC0071AC0072AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC +0073AB0072AC0073AC0072AC0070AB0071AB0070AB0070AB0070AB0071AC0071AC0071AC +0071AC0071AC0070AB0070AB0070AB0071AC0071AC0070AA006FA7006FA7006FA9006FAA +006FAA0070AA006FA90070A90070A90070A90070A90070AA0070AA0070A90070A90070AA +0070AA0070AA006FA90070AB0071AC0072AC0071AB0072AC0072AC0072AC0072AB0071AC +0072AB0071AB0072AB0073AD0074AD0073AE0073AE0074AE0074AD0074AB0074AC0074AC +0074AC0073AB0074AC0073AB0073AA0076B0007BB9007BB8007AB8007BB8007BB8007BB8 +007AB8007BB8007AB70078B30079B40079B40079B40079B40079B30079B40079B40078B3 +0079B4007BB8007BBC007CBD007BBC007BBC007CBC007CBD007BBC007CBD007BBA0078B3 +0079B40079B40079B40079B40079B40079B40079B40078B40079B40079B40079B40078B3 +0078B30078B3007BB7007CB90381BF0073BB2592C5B7AADF893EC27C3BBF772FBB7730BC +7730BC7730BC7730BC7730BC8140C18241C18241C18241C18241C18241C18241C17D39BF +BB97DD8A53BCAE88D1CAB0E5722DB78144BF7431B8722EB7732FB88043BE7C3CBCA275D0 +BC9DDDB694DABEA0DEC1A4E0C8AEE38C56C5BD9FDDCAB1E3BA9BD9915EC06A26AC793CB4 +7A3DB4783AB3793BB4793BB4783AB37B3EB5C5ADDF7137AC753DAF6A2DA8AA88CD9F74CA +702FAF7536B1A983CF956FB9632B996C369F6D38A0642C9ABBA1D47A40B1AF97C94F2D76 +5A397FB09AC6501F8262368F512383D4C5E0A097AD230A45968DA4A09BA5817B89DCCFE9 +A68CC4B8A2D0BDA9D47B54A97045A15A2792A082BE6B3D9D5F2E96BCA7D1653599623298 +623298643599572491623398B49CCF764AA65B269466359B66349B592392B7A1D1754BA4 +5C2B9462329862329862329862329861319762329863349961309754208E6C3F9F7C54A9 +B59FCEB199CA7A50A45C298FAC91C6B39BCBB095CA6B399F59219368369D65329B65329B +66339C66339C66339C66339C66339C66339C66339C66339C66339C66339C66339C66339C +66339C65329B66339C602A98B095CB7B52A55C2890633194623094623094623094623094 +62309463329557228D8C67B0A78BC3541E8A643395623094623094623094623094623094 +623094623094623094612F93643395521A8ABAA3D1242A1F000000010101000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000001000000 +000F16006BA20078B5006EA60071AC0072AC0072AC0071AC0071AB0072AC0072AC0072AC +0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC +0072AC0072AC0071AC0071AC0071AC0072AC0072AC0071AC0072AC0071AC0072AC0072AC +0073AC0072AC0073AC0073AC0073AC0073AC0073AC0072AB0072AC0073AB0072AA006FAA +0071AC0071AC0071AC0071AC0071AC0070AB0070AB0070AB0070AB0070AB0071AC0071AC +0071AC0070A90070A8006EA6006EA5006EA5006EA6006EA5006FA70070A9006FAA006FAA +006FAA006FAA006FAA006FA90070A9006FA9006FA9006FA9006FA90070AA006FA90071AB +0072AC0071AB0072AC0071AC0071AC0071AC0072AC0072AB0071AC0072AC0071AC0071AB +0072AD0074AD0074AD0073AD0073AD0074AB0074AC0073AC0073AB0074AC0073AB0074AE +0077B1007BB8007BB8007AB8007BB8007BB8007BB8007BB8007AB8007BB8007AB70078B3 +0079B40079B40079B40079B40079B40079B30079B30079B40078B30078B30079B4007ABA +007CBD007CBD007BBC007BBC007BBC007CBD007BBA0078B30079B40079B40079B40079B4 +0079B40079B40079B40079B40078B30078B30078B30079B5007BB7007CBB007FBF007FC0 +007EBE0381C10072B82695C5AD9FDB7F38BF8243C28241C18241C18241C18241C18241C1 +813FC1803EC0813FC1803EC1803EC1803EC08240C17D38BFC5A8E07939B27B3DB4DAC7EA +8B53C47837BA7F41BE7E40BD7E40BD7C3CBC7C3DBC7533B9712CB76F2AB6864BC1935EC7 +8B51C3BA99DCFFFFFFB895D66721AA7636B27C3FB5793BB4783AB3793BB4793BB4783AB3 +793BB47738B3C3ABDE7138AD733BAE6F35AB7C47B3C3A8DD7B3EB56C29ADBCA0D97645A5 +69339D632B995E2496602797A583C6D4C3E5624684350B638D78A6B8A3CC52228448167C +BFA9D3CECBD40C00326A5881CAC9C9AFA9B58157AAA68AC29270B46B3E9AA88CC3BCA8D2 +CBBBDCC6B4D9A589C4DBCFE6AC94C98A67B34B14885B299364359963339865369A5F2D95 +623399B39CCE764AA65B26946A3A9E582392B69FD0774DA55C2B94623298613197623298 +6232986435995F2E96572390673A9CA286C2B8A1CEB299CA784EA257238C5F2D92541F8A +A083BE8057A8653596B9A1D09471BA5C259568369D66339C65329B66339C66329C66329C +66329C66339C66339C66339C66339C66329C66329C66329C66339C66339C68369D592193 +9978BD906DB357218C63329562309462309462309462309462309463329557228D8C67B0 +A78BC3541E8A643395623094623094623094623094623094623094623094612F93633295 +57228C9977BC545454000000030303000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000102000000001018006CA2007FBF +0070AB0071AB0071AC0072AB0072AC0071AB0072AC0072AC0071AC0071AC0071AC0071AC +0072AC0072AC0072AC0071AC0071AC0071AC0071AC0072AC0072AC0071AC0071AC0071AC +0071AC0071AC0072AC0072AC0071AC0072AC0072AC0073AC0072AC0073AC0072AC0073AC +0073AC0073AC0072AB0073AC0073AB0072AA0070A9006FA90070AA0070AA0070AA0070AA +0070AB0071AC0071AC0071AC0071AC0071AC0071AB006FA7006FA7006EA6006EA5006FA5 +006FA6006FA6006FA5006FA5006EA5006EA5006EA7006EA60070A90070A80070A90070AA +006FAA006FAA006FA9006FA90070AA0070A90070AA0071AB0072AC0072AB0071AC0071AC +0071AC0071AC0071AC0072AC0072AC0071AC0072AB0071AC0072AB0072AD0073AE0074AE +0073AD0073AE0074AB0074AC0074AC0073AA0075AE007AB8007BB9007AB8007AB8007BB8 +007BB8007BB8007BB8007BB8007BB8007AB8007BB80079B50078B30079B40079B40079B4 +0079B40079B40079B40078B30079B40079B40079B30078B30079B6007BBB007BBD007BBD +007BBC007CBD007BBA0078B30079B40079B40078B30079B40079B40078B40078B30078B3 +0079B5007AB6007DBD007EBE007FC0007FBF007EBE007EBE007FBF007DBC057EBC006DB3 +7FBDDBAD67D17330BB8342C2803EC0813FC1803EC1803EC1803FC1813FC1803FC1803EC1 +803EC18241C17831BCA679D4AD85D07634B1722FAFAE88D0BFA1DF722EB77E40BD7C3DBC +7C3EBD7D3EBD7C3DBC7E40BD7F41BE7F42BE7A3ABB7A39BB702AB69765CAEEE9F4AB89CE +A276CB6D29AD7739B37A3CB4783AB3793BB4793BB4793BB47636B2874FBBBCA0D96F35AC +733AAE743CAE6D31AA8555B9B291D39765C5AC8EC95B20945E23968659B09872BD9F7CBF +C7B3DAC2B6D04620703F196AB4A5C6805DA64A187D8360A98F829D9389A3624D7A736E78 +C4C0C89A75C04E18867C53A5AF95C9511B885A268E541E8A5E2D91906EB38761ADD2C4E0 +FAF9FBAE96CB8D6AB48965B15623905A27925B29935E2C9560309766379BB49ECF764AA6 +541E905B2694B69FD06E42A05D2C956131976434996232985C2A945622906A3D9E9F81BF +BCA7D2906EB35F2D9256218B5C2A90643395653596541F8AA78CC38964AF5119886D3E9B +A488C19B7ABF572092632F9A67359C65329B66339C66329C66329C66329C66339C66339C +66329C66329C66329C66329C66329C66339C66339C64309A7041A2B9A2D05D2A90633194 +612F9362309462309462309462309463329557228D8C67B0A78BC3541E8A643395623094 +623094623094623094623094623094623094623094602F9269369BA79EB0030500000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000102000000000F16003F5F007BBA0072AC0072AB0071AC +0071AB0072AC0071AC0072AB0071AC0071AC0071AC0071AC0072AC0072AC0072AC0071AC +0071AC0071AC0071AC0072AC0072AC0072AC0071AC0071AC0071AC0072AC0072AC0072AC +0071AC0072AC0073AC0073AC0073AC0072AC0072AC0072AC0072AC0072AB0073AC0071AB +0071AA0070A90070AA0070AA006FA9006FA9006FA9006FA90070AA0070AB0070AB0070AB +0070AB006FA8006FA6006EA5006EA5006FA5006FA6006EA6006FA6006FA6006FA6006EA5 +006FA6006FA6006FA5006FA5006FA5006FA5006EA6006FA80070A90070A90070AA0070AA +0070AA006FA90072AC0071AC0072AB0072AC0072AC0071AC0071AC0071AC0072AC0072AC +0072AC0071AC0071AC0072AB0071AC0071AC0071AB0073AC0074AE0074AD0074AC0074AC +0073AB0076B1007AB8007BB8007AB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8 +007BB8007AB8007BB80079B50078B30079B40079B40079B40079B40079B40079B40079B4 +0079B40079B30079B40079B30078B30078B3007AB9007CBD007CBD007CBD007BBA0078B3 +0079B40079B40079B40078B30078B20079B3007BB8007DBC007EBE007FBF007FBF007FBF +007EBE007EBE007FBE007EBE007FBF007CBB007ABA017BBB0078B987B5DDA35CCD7633BC +8342C2803EC0813FC1803EC1813FC1813FC1813FC1803EC1813FC18241C17831BCB58FDB +A073C8722EAF7B3CB47D3FB5DAC7EA8A50C37A39BB7D3EBD7C3EBD7D3EBD7D3EBD7D3EBD +7D3EBD7C3DBC7E40BD7533B99A6ACDAB88D1B89AD6B08FD09C73C4C8AEE08045B87333B0 +7A3DB5783AB3793BB47B3EB56D29ADB491D49369C06A2DA9743BAE7239AD763EAF6628A6 +9E77C5DED0EC9068B7B69CCEC0AAD5AA8FC5A68BC28C68B19678B5C5BBD2674889391266 +AF9FC25E338C7A53A48C809A6457746E5A868D8796746F79A789C74A13825E2D915B288F +AF97C87F58A85B288F6636976535964B128458258DA285C0845EABD1C2DF9E7FBCA78BC2 +BFABD4A184C0764CA57950A75723914F198B5D2B95B5A0D0B9A3D1561F90916DB7A083C1 +5A289365369A572491602F96784FA79D7FBEB9A5D19371B55E2B9158248D623194643495 +6231946231946232945C2A907B52A5AC91C65F2C92602D92531D8A9270B5C2ADD77647A6 +5C269668359D66339C65329B66339C66339C66339C66339C66339C66329C66329C66329C +66339C66339C65329B67359D5A2494A487C4906DB356208B643395612F93623094623094 +62309463329557228D8C67B0A78BC3541E8A643395623094623094623094623094623094 +623094612F936534964F1986AA87CC555951000000030303000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000100020300000000344F007EBE0073AD0073AE0072AB0071AB0072AB0072AC +0072AC0072AB0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0071AC0071AC0072AC0071AC +0072AC0073AC0073AC0073AC0073AB0073AB0072AC0070AA0070A90071AA0070A90071AA +0070AA0070AA0070AA0070AA006FA9006FA9006FA9006FA9006EA7006EA5006EA6006FA6 +006FA6006FA6006FA5006FA6006FA6006FA6006FA6006FA5006FA5006FA6006FA6006FA6 +006FA6006FA6006EA5006FA5006FA6006FA6006FA8006FA9006FA90070AA0072AB0072AB +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AB0071AC0072AC0073AE0073AB0073AA0077B1007BB9007BB8007AB8 +007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007AB8007BB80079B5 +0078B30079B40079B40079B40079B40079B40079B40079B40079B40079B40079B30079B4 +0079B40079B40078B30079B5007BBB007CBE007BBA0078B20078B30078B30078B3007AB8 +007BB9007EBD007FBF007FBF007FBE007EBE007EBE007EBE007FBF007FBF007FBF007EBE +007FBF007CBB007ABA007BBB0278BA007AB887B7DEA35CCD7633BC8342C2803EC0813FC1 +813FC1813FC1813FC1813FC1803EC07F3CC08647C4C6AADF7534B07C3EB47D3FB56F2AAD +B491D4C5AAE2712CB77F41BE7C3DBC7D3EBD7D3EBD7D3EBD7D3EBD7C3DBC7E40BD7837BA +BE9FDD8451BA7F49B8C1A8DB6424A38755B7BA9DD88248B97332B07A3DB5783AB37B3EB5 +6D2AADB490D4986FC36A2DA9743BAE7239AD753DAF6A2EA98958BAF7F3FBC3B1D66D409B +73479F5E2B91531D8956208CB19DC65E3F81AF9FC12F065EAC9CBF6B3F98AD98C337274C +7C6F8CD6D1DCA9A4B18B64B1A588C2BAA4CF8159A94910837C54A6B39ACB59258E653696 +56218C9575B7BBA5D0774CA24E1786AD94C76F429D4F17876E409C8A65AFBAA4CFB29ACB +AB91C8B39BCD784FA666379BB39BCD9270B767359BB8A1CF4E188B5E2D958966B3B39ACB +B8A3CF916FB4602E9256218C633295633295623194613093623194623194613093623294 +5D2B91BCA6D16230946230946332955B278F70439DB096CA7E53AC5E289766339C67349C +65329B66339C66339C66339C66339C66339C66339C66339C66339C66339C66339C66339C +622D997243A4B49BCC643395612E9362309462309462309462309463329557228D8C67B0 +A78BC3541E8A643395623094623094623094623094623094612F9363329558248B8A60B4 +747177000000020202000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000101000203 +000000003450007EBD0074AE0074AE0073AF0071AC0071AB0072AB0072AC0071AB0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0071AC0071AC0070AC0070AC0071AC0071AC0071AC0072AC +0072AB0071AC0070A90070A90070AA0071AA0071AA0070AA0071AA0070AA006FAA006FA9 +0070AA0070AA0070AA006FA9006EA7006FA8006FA8006EA6006FA5006FA6006FA6006FA6 +006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA6006FA5006FA6006FA6 +006EA5006EA5006EA40070A70071A70073AB0073AC0072AB0071AC0072AC0071AC0071AC +0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AB0072AC +0071AC0072AC0074AE0078B2007BB9007AB8007AB8007BB8007AB8007BB8007BB8007BB8 +007BB8007BB8007BB8007BB8007BB8007AB8007BB80079B50078B30079B40079B40079B4 +0079B40079B40079B40079B40079B40079B40079B40079B40079B30079B40079B40078B3 +0079B40079B8007AB90079B4007AB7007CB9007EBD007FBE007FC0007FBF007EBE007EBE +007EBE007FBF007FBF007FBF007FBF007FBF007FBF007EBE007FBF007CBB007ABA007ABA +017CBB0278BA0079B789B8DE9D59CB7531BC8241C1803EC0813FC1813FC1813FC1803EC0 +8140C17B36BD9964CEBA98D87331AF7C3EB47B3CB47A3BB37B3CB4E3D6EF8B52C47939BB +7D3EBD7D3EBD7D3EBD7D3EBD7C3DBC8043BE6F2AB6B896DC9B72C76624A98450BBBFA4DA +6C2FA76D30A87A44B0BDA0D98147B97332B07A3DB57B3EB56D29ADB491D5986FC26A2DA9 +743BAE763FB0682BA79163C0A182C0E8E1EEB59ECD511B88602E9264349559268D9674B9 +907AA9340B62A18DB67459939E87B6A18BB7463A580A0026B9B2C0F8F1FEA789C556218C +511A889573B7CDBEDD9878B959258EAA90C57C53A5521B89916FB4D6CAE3754AA159258E +6130936F439DB098C96B3B9A5C28905B278F541D8A59248E855EAB8159A9AD94C7C0ADD4 +8965B1B9A4D1CCBBDCA78CC57951A8BCA7D1A78CC372459E521C895A278F613093643495 +613093623194623194623194623194623194623194613093653496BBA6D15C288F633194 +612F936332955B278F623094B8A2CEA78BC75D2896602B9867359D65329B66339C66339C +66339C66339C66339C66339C66339C66339C66339C65329B69379E582193AE94CA71459E +5E2A9162309462309462309462309463329558228D8D69B1A589C2541E8A643395623094 +623094623094623094623094612F936332945A2490B29FC521261D000000010101000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000203000000003551007DBD +0073AE0074AF0074AF0072AC0071AC0071AB0072AC0072AC0072AB0072AC0072AC0072AC +0072AC0072AC0072AC0072AC0072AC0072AC0071AC0072AC0072AC0072AC0072AC0072AC +0072AC0072AC0071AC0071AC0070AC0070AC0070AC0070AC0070AC0071AB0071AC0071AA +0071A90070A90070AA0070AA0071AA0070AA006FA90070AA006FA90070AA006FA9006FA8 +006EA7006FA7006FA7006FA8006FA6006FA5006FA5006FA6006FA6006FA6006FA6006FA6 +006FA6006FA6006EA6006FA6006FA6006EA6006EA5006EA5006FA60070A70072AB0073AC +0074AC0073AB0072AB0072AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC +0073AC0073AC0073AC0073AC0073AB0073AC0073AC0072AB0073AB0074AE0078B5007AB6 +007BB8007BB8007AB8007AB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8 +007BB8007AB8007BB80079B50078B30079B40079B40079B40079B40079B40079B40079B4 +0079B40079B40079B40079B40079B40079B40079B40079B40078B30078B2007AB7007EBD +007FC0007FBF007FBF007EBF007EBE007EBE007EBF007FBF007FBF007FBF007FBF007FBF +007FBF007FBF007FBF007EBE007FBF007DBB007ABA007BBA007ABA007CBB0378BA0078B6 +A1C3E4A460CE7939BE8240C1803EC0813FC1813FC1813FC18241C17B36BEC1A3E08B54BC +7634B17B3CB47A3BB37D3FB56F2AADB592D4C9AFE4702BB67F41BE7C3DBC7D3EBD7C3DBC +7E40BD7634B98B53C4B696D67338B17235B0834EBABFA4DA692CA6773EAE6D31A87A43AF +BDA1D98147B97332B07E43B76D29ADB491D5986EC26A2EA9753DAF6223A49061BFAE93C8 +623294B39FCACBBED9794FA45C2A9064349557228CA487C17B63983A136757367DD9D4E1 +BDA6D2A398B034214BB6B2BBDFD1EB4C1484BBA5D0683898673797551F8B5A268F9877B8 +B098C99F82BEAB91C68964AE9B7DBB511B88613093633395643495521D899675B79F80BD +57218C65349665349663329559248E59258E5E2A915B278F8964AE9F81BDE4DCECF9F8FC +B7A1CE6939985A268E5D2B91653696633294613093623194623194623194623194623194 +6231946231946231946332945A278E9E80BD8F6BB258238D633295612F93633194612F93 +541D8A8762ADAB91C97547A65E299768369D65329B66339C66339C66339C66339C66339C +66339C66339C66339C66339C66349C5F2A978E67B5A689C2541E8A643396612F93623094 +62309463319558228D845DABA68AC2541E8A643395623094623094623094623094612F93 +643395541D8AAC90C83F433B000000020202000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000204000000003450007EBE0073AD0073AE0075B0 +0074B00073AC0071AB0071AB0072AC0072AC0072AC0072AC0071AC0071AC0072AC0072AC +0072AC0071AC0072AC0071AC0071AC0072AC0072AC0072AC0072AC0071AC0072AC0071AC +0071AC0071AC0071AC0071AC0071AC0072AB0072AC0072AB0071AB0071AB0071A90070A9 +0070A90071A90070AA006FAA0070A90070AA006FA8006EA7006FA8006EA7006FA7006FA8 +006FA7006FA7006FA7006FA5006FA5006FA6006FA6006EA5006FA6006FA6006FA6006EA5 +006EA5006FA5006FA60071AA0074AB0074AB0074AC0074AB0074AB0073AB0072AC0073AC +0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AC0072AB +0073AC0072AB0072AB0074AE0078B2007AB70077B30077B30078B5007AB8007BB8007BB8 +007AB8007AB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007AB8007BB80079B5 +0078B30079B40079B40079B40079B40079B40079B40079B40079B40079B40078B30079B4 +0079B40079B40078B30079B3007AB6007DBB007DBC007ABB007EBD007FBF007EBE007EBE +007FBF007FBF007FBF007FBF007FBE007FBE007FBF007FBF007FBF007FBF007EBF007FBE +007EBF007BBB007ABA007BBA007BBA007ABA037DBB0070B644A4CCDAC9ED782BBB8041C1 +813FC1803EC0813FC18140C17A35BD965ECCBA99D8702CAE7D3FB57B3CB47B3CB47A3BB3 +7A3BB47B3CB4DFD0ED8B52C47838BA7D3FBD7D3EBD7D3FBD7938BB894FC3E6DBF2763DB3 +7235B07235B0824EBAC1A7DB6A2DA6743BAD743BAD6D31A97943AFBDA0D98147B96E2BAD +6F2CAEB491D49970C3672AA77239ADB79AD7AE92C84F1986A386C179599C8768A6C2AED5 +55208B6231936E409DB3A2C5421D6C4D2A753C1569AE9DC1FFFFFF787083ABA9B0B89DD2 +73479E9371B5B7A1CE5F2C92521B896C3D9B71449E5E2B91845CABEEE9F3FFFFFFC7B6D8 +613094623194531D89602F936232946434965E2C91C0ADD46635965E2B91623094623194 +653596602D92551F8B6B3D9AA88DC4D0C1DFB099C8DBD1E5A58AC18059A9521C89623194 +633395613093623194623194623194623194623094623094623194623194623194633395 +56228C8A67AFA487C1541E8A643395623094612F9362309465349656218C825BAABDA7D1 +855BAF5A249469379D66339C65329B66339C66329C66329C66339C66339C66339C66339C +66339C65329B632F9AB29ACD73479F5E2A916231946230946230946231945C2890A68AC2 +835CAB5B278F6331946230946230946230946230946230945D2B90784AA68F8995010300 +000001000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000102000000003450007EBE0077B30073AD0075B00075AF0074AD0072AD +0071AB0071AB0072AC0072AB0071AC0071AC0071AC0072AC0071AC0072AC0071AC0072AC +0072AC0071AC0071AC0071AC0071AC0072AC0071AC0072AC0071AC0070AC0071AC0071AC +0070AC0072AC0071AB0071AC0072AC0072AB0072AB0070AB0071AB0071A90070A90070A9 +0070AA006FA8006EA7006FA8006FA7006FA8006FA8006FA7006FA8006FA8006FA7006FA7 +006FA7006FA5006FA5006FA6006EA5006EA5006EA50070A80070A80073AA0074AB0074AC +0073AB0073AC0073AB0073AB0074AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC +0073AC0073AC0073AC0073AC0073AC0072AC0073AC0073AC0072AB0073AC0076B1007AB7 +007AB60079B60077B30078B40077B30078B40078B4007AB8007BB8007BB8007AB8007AB8 +007BB8007BB8007BB8007BB8007BB8007AB8007BB80079B50078B30079B40079B40079B4 +0079B40079B40079B40079B40079B40078B30079B40079B40078B30078B3007AB6007DBB +007EBD007EBD007CBB007ABA007BBA007EBD007FBF007EBE007FBE007FBF007FBF007FBE +007FBE007FBE007FBE007FBF007FBF007FBF007EBE007FBE007EBF007ABB007BBA007ABA +007BBA007BBA007ABA027DBB006FB53B99C9B691D97B30BD8040C1813FC1803FC18140C1 +7B37BEA97CD4A87FCD7330AF7C3EB47B3CB47B3CB47B3CB47C3EB4712DAEAE88D0C3A5E0 +722EB77E40BD7C3DBC7F41BE7330B8B895DAA37CCB6D2FAE773DB37439B17338B1DBCDEB +9164BE6B2EA7743AAC743BAD6D31A97A43B0BB9ED8A87ECE661FA9B694D6956BC1682BA9 +B599D38865AC613093531D89A386C1896BA7441576D9D1E47F57A84D1686AB8FC6775D95 +3710644722728A76A1DDD8E350485B211D2BCCC4D29D7DBD9573B6CBBBDCFFFFFFBFABD4 +9371B6B69FCDBBA6CFBFACD3A88EC16636939E81BAB39FC9B9A4CDAA90C4A183BF6A3C9A +5D2B915D2A91521C887B51A5AE94C75E2C916332955F2C92521C896B3C9AB39BCBDFD5E9 +B39DCA653595693C98AD94C64D1682A98EC4A68AC264339557238C643495623194613093 +62319462309462309462309462309462319462319463339556228C9371B59D7EBC531D8A +643395612F93623094623094612F936433955A258E57228CAC91C68A62B35A239465329B +67349C65329B65329B66329C66329C66339C66339C66329C66329C68369D582093A080C2 +8761AD58248D633194623094623094623094612E93BAA5D05E2A91623094612F93623094 +623094623094612F936332945F2A95B0A4BA0C1007000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000203 +00000000344F006EA50079B60072AC0075B00075B00074B00073AD0072AC0071AB0071AC +0072AC0071AC0071AC0071AC0072AC0071AC0072AC0072AC0072AC0072AC0072AC0072AC +0071AC0071AC0071AC0071AC0072AC0071AC0070AC0071AC0070AC0072AC0071AC0072AC +0071AB0071AC0071AC0072AC0072AC0072AB0071AB0070AB006EA7006EA8006EA8006EA7 +006EA8006EA8006EA8006EA8006EA8006EA7006EA8006EA8006EA8006EA7006EA6006EA5 +006FA6006FA80073AA0074AB0074AC0074AC0074AC0073AB0074AC0073AB0073AC0073AC +0074AC0073AC0072AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0073AC0072AB +0073AC0073AC0072AB0072AA0076B20079B5007AB60079B60079B6007AB60077B30078B4 +0078B40077B30077B30078B40078B4007AB8007BB8007BB8007AB8007BB8007BB8007BB8 +007BB8007AB8007BB8007AB60078B30079B40079B40079B40079B40079B40079B40078B3 +0079B40079B40078B30078B3007AB6007DBB007EBD007EBD007DBC007EBD007CBB007ABA +007ABA007ABA007EBE007FBE007EBF007FBE007FBF007FBE007FBE007FBE007FBE007FBE +007FBF007FBE007EBE007FBE007EBF007ABB007BBA007BBA007BBA007BBA007BBA007ABA +047DBC0072B543A4CDB590D97B30BD8040C1813FC18342C17831BDC1A3E07E41B5793AB3 +7A3BB37B3CB47B3CB47B3CB47B3CB47A3AB37D3FB5D6C3E88951C37939BB7F42BE702BB6 +AD83D5A984CE6523A9773DB37439B1773DB36727AAAA84CE9B73C3692BA6743BAC7238AB +743BAD6E31A97841AFB091D0A378CBAA81CE9B72C5AE90CF7B54A3541F8B65359655208B +A285C08B6EA93C0B70967BB1C9B7DA4D1586B5A0CB56367B64428A8D7BA3B2ACBBA3A1A7 +27212EAA93BF8D69B09071AD9374B18461A69A7CB6FCFCFCDCD2E75E2B8E4F198359268A +57238958258A623291B6A0CC4F1C8079529E9375B1B39DCAC3B0D5A387C08D6AB255208B +9F81BD855EAC541D8A6B3C9AB49CCCDED4E8B199C9683A98501C8758268C764EA1B7A2CD +541F875E2D8E9473B3AB91C48159A959258D602F93633294613093623194623094623094 +623094623194623194623194612F93653696B39BCB6B3C9A5F2C92623094623094623094 +623094612F936432956230945A268EAB8FC5B69FD064319B5F2A9767359D65329B66339C +66329C66339C66339C66329C66339C66339C632E99784BA8B49DCC59248E643395612F93 +623094623094602D92BDA8D2653496612F93623094623094623094612F93643396521D88 +9D76C3636461000000030203000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000203000000000507005E8D +007DBC0072AB0075B00075AF0075B00074B00072AD0072AB0071AB0072AC0072AC0072AC +0071AB0072AC0072AC0073AC0073AC0073AC0073AC0073AC0072AC0072AC0072AC0071AC +0071AC0072AC0071AC0070AC0071AC0072AB0071AB0071AB0071AB0071AB0072AC0072AC +0071AB0072AB0071AB006FA80070A7006FA7006FA8006FA7006FA8006FA8006FA8006FA8 +006FA8006FA8006FA7006FA7006FA7006FA8006FA60070A70073AB0074AC0074AC0073AC +0073AB0073AB0073AB0074AC0073AC0073AC0073AC0073AC0074AC0073AC0072AC0073AC +0073AC0073AC0073AC0073AC0073AC0072AB0073AC0073AC0072AB0072AB0074AD0077B3 +007AB6007AB60079B6007AB60079B6007AB60077B30078B40077B40078B40078B40077B3 +0077B30078B4007AB8007AB8007BB8007AB8007AB8007BB8007BB8007AB8007BB8007AB8 +0079B40078B30079B40079B40079B40078B30079B40079B40079B30078B3007BB6007DBB +007EBD007EBD007DBC007DBC007DBC007EBD007CBB007ABA007BBA007ABA007ABA007EBE +007FBE007EBF007FBF007FBE007FBE007FBE007FBE007FBF007FBF007FBF007EBE007FBE +007EBF007ABB007BBA007BBA007BBA007BBA007BBA007BBA007ABA047DBB0070B53FA4CD +B58FD97C31BD8142C17C37BE9862CCB693D67939B27B3CB47B3CB47B3CB47B3CB47B3CB4 +7A3BB37D3EB5702BADB28DD2C2A3DF722FB77E3FBD8348C0BB9DDB7A41B47338B1753AB2 +753AB2773DB36929ABB18FD29B73C3692BA6743BAC7238AB7238AB763DAD7338AC6221A1 +8A5AB9EBE1F4C2ADD86E429C5C2990653596643495541F8AA385C0876AA64B1D7B532881 +D1C4DD9F7FBF8C74A669498D948A9D91889CF7F6F9635C6BD1CDD76B3D974A167B552384 +53218349137B825DA5997CB663388FAE94C76E41995B288C623291633492531E869D7FBA +9577B24D197F5220825F318C5B2B88835FA5AA92C1B198C8C2AFD5C2AED56D3F9CE3DAEB +B29ACA683A97501C875D2C8F6334945B298E744B9FB49ECB552088633492501A8472489B +B49CCA9574B76333955D2B90653596613093613093623194623094623194623194613093 +64349556218CB49CCC6B3B9A5F2C92623094623094623094623094623094612F93623094 +62309458238D7B51A4AF96CB7648A75F2A9767359D66339C65329B66339C66339C66339C +66329C65329B67359D5B2595AE92CA855FAB58228D643295612F93623094602D92BEA9D2 +633295612F93623094623094623093623094602E926A389B9A8DA8131610000000010101 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000102000000000506005E8D007DBC0072AC0075B0 +0074AF0075AF0075B00074AD0072AD0071AB0071AB0072AB0071AC0073AB0073AC0072AC +0072AC0072AC0072AC0072AC0073AC0073AC0072AC0071AC0072AC0072AC0071AC0070AB +0070AB0072AB0072AC0072AC0072AB0072AC0070AA0070AA006FA7006FA5006FA5006EA5 +006FA5006FA70070A8006FA70070A80070A80070A80070A80070A80070A80070A80070A8 +0070A80070A70070A90071AC0071AC0072AB0073AB0074AB0074AC0073AC0073AC0074AC +0074AC0074AC0074AC0073AC0074AC0073AC0072AC0073AC0072AC0073AC0073AC0073AC +0072AB0073AC0072AB0072AA0074AE0077B3007AB5007AB60079B60079B6007AB6007AB6 +0079B6007AB60077B30078B40078B40078B40077B30078B40078B40077B30077B40078B3 +007AB7007BB8007BB8007AB8007AB8007AB8007BB8007AB70078B30078B30079B40079B4 +0079B40079B40078B30078B30079B4007CBB007EBD007EBD007DBC007DBC007EBC007DBD +007DBC007EBD007BBB007ABA007BBA007BBA007ABA007ABA007EBE007FBF007EBE007FBF +007FBE007FBE007FBF007FBF007FBF007FBF007EBF007FBE007EBF007ABB007BBA007BBA +007BBA007BBA007BBA007BBA007BBA007ABA037DBC006FB543A5CDB18CD97B36BE7833BD +A97CD5A67CCC6F2BAD7D3FB57B3CB47A3BB37B3CB47B3DB47B3DB47B3DB47A3BB37C3EB4 +E3D6EF8C55C56C25B5C9AEE28856BB6D2FAE763BB27439B1753AB1773DB36929ABAF8BD1 +956BC0692BA6743BAC743AAC743AAC682BA66A2DA78350B6A985CCDCCFE9CABAD970429D +541F8B633294663696531E8A9E7FBD896CA74D1F7C4F237E7F5FA1DBCEE7CBBFD97F718C +140728C7C1CCDEDFDE917BA770469DAB96C3673B925A2A8863368F5624858561A7A88FC1 +44117A7B57A1BEACD18561A95724895E2D8E613190623291B9A6CE5D2E8A61338D5D2E8A +5E2F8B5725864E1A7F65388F7A539EDDD4E6D1C3E05F2F914B15835F3091623293603192 +6030915B2A8E6F449CB49ECB5520876232916333915C298C4F19849A7BB8BBA5CF6D3F9C +531E8A6433956231946130936231946231946231946231946332945A278EA082BE8B67B0 +5A268F633194623094623094623094623094623094612F9362309464339558238D7448A0 +BFABD4946FB9561E92632F9A67359D65329B66339C66339C66339C66339C67349C602B98 +794DA9AF97CA602D92623094623094623094602D92BEA9D2633295612F93623094623094 +612F93643395521A8AB8A1CE2B3225000000010101000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000101000000000609005E8D007DBC0072AC0075B00074AF0074AF0075B0 +0075B00074AE0072AC0071AC0073AB0072AC0072AC0073AB0073AC0073AC0073AC0073AC +0072AC0072AC0073AC0073AC0073AC0073AB0071AB0071AB0071AC0072AB0070AB0071AB +0070A7006FA6006EA5006EA5006EA5006EA6006EA6006FA6006EA5006FA7006FA80070A7 +006FA80070A70070A80070A80070A80070A80070A80070A8006FA70070A80071AC0070AB +0070AB0070AC0071AC0071AC0073AC0074AC0074AC0074AC0073AC0074AC0074AC0073AC +0074AC0073AC0073AC0072AC0073AC0073AC0072AB0073AC0073AC0072AA0073AD0076B0 +007AB5007AB70079B60079B6007AB6007AB6007AB6007AB60079B6007AB60077B30078B4 +0078B40078B40078B40078B40078B30078B40078B30077B30077B30079B7007AB7007BB8 +007AB8007AB8007BB8007AB80079B40078B30079B40079B40078B30078B30079B4007BB8 +007DBC007EBD007DBC007DBC007EBD007EBC007EBD007EBD007DBC007EBD007BBB007ABA +007BBA007ABA007BBA007ABA007ABA007EBD007FBF007EBE007FBF007FBE007FBF007FBF +007FBF007FBF007EBE007FBF007CBB007ABA007BBA007BBA007BBA007BBA007BBA007BBA +007BBA007BBA007ABA047CBB0073B6A2C3E4994CC77736BDC7ABE18349B87C3EB47D3FB5 +7D3FB57D40B57B3CB47533B07533B07533B07737B26922AAAF8AD1C1A2DF9460C8A37BCC +6D2EAD7940B4773DB3773DB3773DB37940B46929ABB08DD2AE8CCE6B2EA7733AAC6A2CA6 +7035AA996DC2AE8CCFBDA6D78A61B8ECE4F5A084C3A487C49979B85F2D925B288F5E2C91 +A98EC47B5B9D4516764D207D7F5CA2D1C6DA5E516B17012C968F9FD7DAD5CAB7DD572888 +512283694195B09BC7653890552384552485CCBDDA9678B4522384592B884E1E82A187BB +BBA4CE6333925824895623899B7BB99576B2511E8160328D5D2E8A60328C5F318C572686 +A68DC06941957C57A2A890C3754BA057258C6233935F2F9161319259278D835EA9A58BBF +5622886231905F2E8F613090633391531E86663793AF96C68F6CB35B288F5D2A90633395 +6130936231946231946231946231945C29907348A0B49CCB56208C643395623094623094 +623094623094623094623094623094612F936332955E2B91531C899B7BBBA98CC76E3FA2 +5F2A9769389E65329B66339C66339C66339C65329B69379E5A2394B299CC6A3B99602D92 +612F93623094602D92BEA9D2633295612F93623094612F936332955A268D8D67B3666468 +000000020202000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000101 +000000000608005E8D007DBC0072AB0075B00074AF0074AF0074AF0075B00075B00073AF +0073AB0072AB0073AB0073AC0073AB0073AC0073AC0073AC0073AC0073AC0072AC0072AC +0072AB0073AC0073AC0072AC0070A80070A6006EA5006EA5006EA5006EA5006FA6006FA6 +006FA6006FA6006FA6006EA6006FA6006EA5006FA7006FA80070A7006FA80070A70070A8 +0070A80070A80070A70070A8006FA70070A80071AC0070AB0071AB0071AC0070AC0070AC +0070AC0072AC0072AC0074AC0074AC0073AC0073AC0074AC0073AC0074AC0073AC0072AC +0073AB0073AC0073AC0072AB0072AB0076AF0078B5007AB70079B60079B6007AB6007AB6 +007AB6007AB6007AB6007AB60079B6007AB60077B30078B40078B40078B40078B40078B4 +0078B40078B40078B40078B40078B30077B30077B30079B6007BB8007BB8007BB8007AB7 +0079B40079B40078B30078B30079B4007BB8007DBC007EBD007EBD007DBC007EBD007EBD +007EBD007EBD007EBD007EBD007DBC007EBD007BBB007ABA007BBA007BBA007ABA007BBA +007ABA007ABB007EBD007FBF007EBE007FBF007FBF007FBF007FBF007FBF007EBE007FBF +007CBA007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA +0078BA0C81BC9CAFDFA460CEB698D86922A9712DAE6F2BAD702CAD6E28AC7838B2915DC0 +925EC0925DC0925DC0925DC09360C0E7DBF2DFD0ED8958BC7D46B66625A9692AAB6929AB +6828AB6B2CAC6F31AE8753BCD3C2E66525A3743AAD9A70C3D1BFE3D1C2E38C63B85A1E9A +8861B4CFC9D77549A85B2796A083C3BEABD48560AB623195AB95C2401073825FA4A491B9 +BCB3C9E7E5E81B053149395BA9A9AAB9A6CD3D07744D1E7F5C308A512181653C90A993C2 +7B54A0582786B9A6CD5D318C5D308B5D308B5E318C5121836D4697AF97C77A51A2572389 +643492B7A4CC5E2F8B5D2E8A5F308B5C2C895A2A88AC96C477539F542585542585805EA5 +B69ECC7A51A355228A63339362329354218AB69FCC6F42995B298C602F8F602F8F602F8F +5F2E8F6333915A288C663693A98EC2A284BF6D3F9C5A278E633294623194613093623194 +6231945B288F7E56A7AD94C7521B89653496612F93623094623094623094623094623094 +623094623094612F9362319464339558238D916EB3B39CCD7142A4571F9268369D66339C +65329B66339C66339C66349C5F29979673BB9C7CBB541E8B643395623094602D92BEA9D2 +633295612F936230946230945F2D90652F9BB3A9BD000200000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000101000000000405005E8D +007DBC0071AA0074AF0075B00074AF0074AF0075AF0075B00075AF0073AD0072AC0072AB +0073AC0073AC0073AB0072AC0073AC0072AB0072AB0072AB0073AC0072AB0070A8006FA6 +006EA5006EA6006FA8006FA7006FA5006FA5006FA5006FA5006FA6006FA6006FA6006FA6 +006EA6006FA5006EA6006FA60070A8006FA7006FA80070A80070A80070A80070A8006FA7 +0070A80070AC0071AC0070AB0071AC0070AC0071AC0071AC0071AC0070AC0070AC0072AC +0073AC0074AC0074AC0073AC0073AC0074AC0073AB0072AC0073AC0073AC0072AB0073AD +0076B0007AB6007AB60079B60079B6007AB60079B60079B6007AB6007AB6007AB6007AB6 +0079B6007AB60077B30078B40077B40077B40078B40078B40078B40078B40078B40077B3 +0078B40078B40078B40077B30077B30079B5007BB9007BB80078B30078B30079B4007BB8 +007DBC007EBD007EBD007DBC007DBC007EBD007EBD007EBD007EBD007EBD007EBD007DBD +007DBC007EBD007BBB007ABA007BBA007BBA007BBA007ABA007BBA007ABA007ABB007EBD +007FBF007EBE007FBF007FBF007FBF007FBF007EBE007FBF007CBA007ABA007BBA007BBA +007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007CBB0177B9047DBAB8DDED +CFAFE0B797D7BB9BD8BB9BD8BC9CD9B592D5D8C6E9D0BBE8BA9ADCBFA1DFBEA0DEBFA2DF +BA9ADCD8C6EBF5F0F9B896D6BC9FDAB899D7B99AD8B899D7BB9DD9AF8CD27A43B47941B5 +BFA5DBA17AC7BFA5D8A484C7713FA8642DA05E269D7645ACCEC0DE7B6397A286C25E2B98 +58249468399F9F81C1B59ECCD7CCE2A691BC8F81A17A689070657C91899A39264CBAB6BE +DFE0DDCFC1DFA890C1A98EC56638976D419C643495734AA0AB97C38461A4AF9BC5502282 +5223835D318B5C2F8A5F338C5526856B4295B8A4CC997AB6521D869878B89677B3532183 +5E2F8B5A2988AC95C477529E5121835E328D5E328C512183572887AD96C57C53A5542289 +66379654218AB69FCD754A9D5A288B602F8F602F8F602F8F602F8F5F2E8F6130905E2D8E +4E17828864ACBAA6CF8058A85B288F612F93633395613093623194602E92683A98B097C9 +6C3D9B5F2C92623094623094623094623094623094623094623094623094623094612F93 +612F93643395541D8A683797B49DCDA181C25D279666349C67349C65329B66339C66339C +64309A69369EB69DCE6B3D9A5F2C92623194602D92BEA9D2633295612F93612F93623193 +5D2893A791BC222420000000010201000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000101000000000608005D8C0081C20074AE0074AF +0075B00074AF0074B00074AF0075B00075B00074AF0074AC0072AB0072AB0072AC0073AC +0072AB0072AC0073AC0073AC0072A9006FA6006EA5006FA5006FA5006FA6006FA8006FA8 +006FA7006FA7006FA7006FA6006FA5006FA5006FA6006FA6006FA6006FA6006EA5006FA6 +0070A7006FA8006FA7006FA80070A8006FA70070A8006FA70070A80071AC0070AB0071AC +0071AC0071AC0071AC0071AC0071AC0071AC0071AC0070AC0070AC0071AC0073AC0074AC +0074AC0074AC0073AC0072AC0072AB0072AB0077B1007AB6007AB70079B60079B6007AB6 +0079B60079B60079B60079B60079B6007AB6007AB6007AB60079B6007AB60077B30078B4 +0077B40077B40077B40078B40078B40078B40077B40077B40077B40077B40078B40078B4 +0077B40078B30079B60079B60079B4007AB8007DBC007EBD007EBD007DBC007DBC007EBD +007DBC007DBD007DBD007EBD007EBD007DBD007DBD007DBD007DBC007EBD007BBB007ABA +007BBA007BBA007BBA007BBA007ABA007BBA007ABA007ABA007EBE007FBF007EBE007FBE +007FBF007FBF007EBE007FBF007CBA007ABA007BBA007BBA007BBA007BBA007BBA007BBA +007BBA007BBA007BBA007BBA007ABA017CBB0075B90E85BFC0C3E8965CC89A69CC9866CB +9866CB9967CB9562C97634B9712CB7722EB7722EB7702AB67D3DBDB492D4B799D47F42B6 +7C3DB49B6BC69663C39765C49562C29D6FC7C8AFDFC3A8DCE4D9EF9D7BC37140A85D239C +6832A36B37A5632D9F895DB9A895BA3B1364BAA5CD64329D66369D61309A572393A889C9 +C5BDCE4B34682107469185A17A7382675975AEA4B6A1A2A01616172C2E29292E259B9D9A +A39EAA9D98A39B95A1B0ACB4B9A2D3CEB9DEF3EFF89F7FBF835DAB5422875B2B8C5A2A8C +5627884C1C7E400C758465A6B19DC774499DAE97C55B2B885C2D89AE99C67A56A0522283 +5F338D5C2F8B5C2F8B5F328D5A2C89582A88AD96C57C54A6531F8855228AB8A1CE74499D +5A288C602F8F5F2E8F602F8F602F8F602F8F5F2E8F602F8F63339257238958258AAF96C6 +AF97C95E2B9159268E643395613093653596521C89A589C28862AD59248D633194623094 +623094623094623094623094623094623094623094623094623094612F936534965D2A91 +6433959A79B9A586C45B2495612C9867359D65329B65329B69379E572092A689C57E55A6 +5A268F633194602D92BEA9D2633295612F936331955A278D8459B0868686000000030203 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000010100000000080C002E460077B30076B10073AE0075B00074AF0074B0 +0074AF0074AF0075B00075AF0074AF0073AC0073AB0072AB0073AC0073AB0071A9006FA7 +006EA5006EA5006FA6006FA6006FA5006FA6006FA8006FA7006FA8006FA8006FA8006FA7 +006FA6006FA6006FA5006FA5006FA5006FA5006FA6006EA5006FA50070A7006FA7006FA7 +0070A80070A8006FA70070A80070AB0071AC0070AB0071AC0071AC0071AC0071AC0071AC +0071AC0071AC0070AB0071AC0071AC0071AC0070AC0071AC0073AB0074AB0073AB0072AB +0075AF0079B5007AB6007AB60079B5007AB60079B6007AB6007AB60079B60079B60079B6 +0079B6007AB6007AB6007AB60079B6007AB60077B30078B40077B40077B40077B40078B4 +0078B40078B40077B40077B40077B40077B30078B40078B40077B30077B30078B4007AB7 +007CBB007EBE007DBD007DBC007DBC007EBD007EBD007DBD007DBD007DBD007DBD007EBD +007EBD007DBD007DBD007DBC007EBD007CBC007BBB007ABA007BBA007BBA007BBA007BBA +007BBA007ABA007BBA007ABA007ABA007EBE007FBE007EBF007FBE007FBE007EBE007FBF +007CBA007ABA007BBA007BBA007BBA007BBA007ABA007BBA007BBA007BBA007ABA007ABA +007CBB007DBB0380BE0072B56DAACEA15ECB6A27B47836BA7633B97533B97634B97E3FBD +7F41BE7F41BE7F41BE7C3EBC874CC3B798D58452B6C0A3DB702CAE7433B07432B07431B0 +7431B07635B16D27AC9662C3C0ADD4875CB55E259D6E3BA66934A36B37A561279FB49CD0 +5F3F8148236FBCA8CF63319C64339B67379E562292CCBBE2C4BECC0C00369E91AF4C4258 +463A54FFFFFF979796000000000000000000000000000000000000000000000000080908 +52554F4B4D4A4A4B4A4B504677737AB5A7C4ACA0B9A89BB6C4BAD0A989C8855EAE8056AA +9470B8AB8FC6AE96C79474B29477B46D449844107B572A87562985562985562985562885 +572A86542684542684AC94C49473B655228AB59DCC774D9F5C2A8D602F8F602F8F602F8F +602F8F5F2E8F5F2E8F602F8F5F2E8F623190613090511C857C54A3AE96C8794FA459258E +613093653596541F8BAD94C77D53A659258E633194623094623094623094623094623094 +623094623094623094623094623094623094612F93633194612E93521B898E6AB1AC8FC8 +7344A55E299769389E66339C66339C612C998157ADB096C956208B643396602D92BEA9D2 +633295612F93643394551E8DB8A3CD242920000000010101000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0002030000000023360079B70075B10073AE0075B00074AF0075B00074B00074AF0074B0 +0075B00075AF0074AE0072AD0072AB0070A8006EA5006EA5006FA6006FA6006EA6006FA6 +006FA5006FA6006FA7006FA8006FA7006FA7006FA7006FA8006FA8006FA7006FA6006FA6 +006FA6006FA6006FA5006FA6006FA6006FA50070A8006FA7006FA80070A7006FA80070AB +0071AC0070AB0071AC0071AB0071AC0071AC0071AC0071AC0071AC0071AC0071AC0071AC +0070AB0070AB0070AB0070AB0071AC0071AC0072AB0078B3007AB7007AB60079B50079B6 +0079B60079B6007AB6007AB6007AB60079B60079B60079B60079B6007AB6007AB6007AB6 +0079B6007AB60077B30078B40077B40077B40077B40078B40078B40078B40078B40077B3 +0078B40078B40077B30077B30078B4007AB8007DBC007DBC007ABA007CBC007EBC007EBC +007DBC007EBD007EBD007DBD007DBD007DBD007DBD007EBD007EBD007EBD007DBD007DBC +007EBD007CBA007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007BBA +007ABA007ABA007EBE007FBE007EBE007EBF007FBE007EBF007BBA007ABA007BBA007BBA +007BBA007BBA007BBA007ABA007ABB007ABB007CBB007DBB007EBD007DBD017FBE0072B4 +1D87B4ABA8DD803EBD7D40BD7D3FBD7D3FBD7D3FBD7D3EBD7C3DBC7D3EBD7E3FBD7634B9 +A57BD2A580CA6221A2BEA3D98D56BE7837B27C3DB47B3DB47B3DB47B3DB47C3CB5B699D2 +987BB7A788CA5F269D6C38A56B36A4632C9F8A60B99F8AB4411B6A4E2B74BBA7CE63319C +66369D5925957E54AEFFFFFF75628C442965A09AA900000A6E627BA8AAA7000000040404 +010101010101010101030303030203030203030203020203000000000000000000000000 +010300050802060903000000282B258283807475737B7C796E6F6C9C91A8FCFAFFFFFFFD +C8BBD7A38CBCB5A3C9815BA96F419E7347A07246A07246A07246A07549A26C3E9A49197C +9C80B88C6BAFB39BC96537924F1A8260308F5F2E8E5F2E8E5E2E8D60308F613190613190 +613190613190602F8F633392552188784EA0B8A2CC8E6BB2602E925F2D925D2A908762AD +A387C05B268F633194623094623094623094623094623094623094623094623094623094 +623094623094623094612F9362309465349656208C8862ADBAA4D17F55AD541B9066349C +66339C66349C5E2997AD93CA7E55A75C2890623094BDA9D263329564329556208BA385C2 +464843000000020202000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000001000203000000002336 +0079B70075B10073AE0075B00074AF0075B00075B00075AF0074AF0074AF0075B00074AF +0071A9006EA5006EA5006EA6006FA6006FA6006FA6006FA6006FA6006FA5006FA6006FA8 +006FA7006FA7006FA8006FA7006FA7006FA8006FA8006FA8006FA8006FA6006FA5006FA6 +006FA6006EA6006FA80070A70070A80070A7006FA80070AB0071AC0071AC0071AC0071AC +0071AC0070AB0070AB0070AB0070AB0070AB0070AB0070AB0073AE0073AE0072AE0075B1 +0076B30076B30076B30076B40078B40079B5007AB6007AB60079B60079B60079B6007AB6 +007AB6007AB6007AB6007AB6007AB6007AB6007AB6007AB60079B6007AB60077B30078B4 +0078B40078B40078B40078B40078B30078B40078B40078B40077B30077B30078B4007AB8 +007DBC007EBD007EBD007DBC007ABA007BBA007CBD007DBC007EBC007DBC007EBD007EBD +007EBD007EBD007EBD007EBD007EBD007EBD007EBD007DBC007EBD007CBB007ABA007BBA +007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007BBA007ABA007ABA007EBE +007FBF007EBE007FBE007DBF007ABA007BBA007BBA007BBA007BBA007ABA007ABA007BBA +007DBC007DBD007EBD007EBD007DBC007DBC007EBE027BB80066A6399DC0C19ADE6F27B5 +7F42BE7C3DBC7D3EBD7D3EBD7D3EBD7C3DBC7F41BE712CB7BA9BDC8451B56828A68B5BBA +BD9ED9702CAE7D40B57A3BB37C3EB4722FAEA172CAA58AC14E1786BDA8D37443AB6631A1 +6C38A55D249CA07DC67B60953F176A4E2B74BBA8CE64329D5F2D97794BAD907DA4A399AC +432963827297585264736880747276000000020202000000000000000000000000000000 +000000000000000000000000030303030303030303030303020202000000000000000000 +0000000000000000000000000000001214101616151110111C1E19242820191D14787679 +9D99A094919796929996929996929995929898919FA588C3916FB5C0ACD6FEFDFFAD91CA +9571B9602B93643196632F956531975B278C521F8454208553208555218660308F623290 +6434925C2B8D521D85A083BBB9A3CF6B3D9A59258E633395BBA6D15E2B91623194623094 +623094623094623094623094623094623094623094623094623094623094623094623094 +623094612F9364339558238D5C2990AA8FC6A688C664309A64309A6A389E5922949571BA +9472B657228C5F2C91BBA6D16534965D2B8F703EA1A099A7000300000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000002030000000024380079B60075B10073AE +0075B00074AF0075B00075B00075B00075AF0074AF0075B00075B00074AF0070A9006FA5 +006EA5006FA6006FA6006EA6006FA5006FA5006FA6006FA8006FA7006FA8006FA8006FA8 +006FA8006FA7006FA7006FA7006FA7006FA8006FA8006FA7006FA5006FA6006EA5006FA8 +006FA8006FA70070AB0070AC0070AB0070AB0070AB0070AB0070AB0072AD0072AD0071AD +0074B00075B20075B20075B20077B40077B40077B40077B40077B40077B40076B40075B3 +0075B30076B40076B50078B5007AB6007AB6007AB60079B60079B6007AB6007AB6007AB6 +007AB6007AB6007AB6007AB60079B60079B50077B40078B40078B40078B40078B40078B3 +0078B40077B30077B30077B30078B4007AB8007DBC007EBD007EBD007DBC007EBD007DBC +007ABA007BBA007ABA007BBA007DBC007EBD007DBC007EBD007EBC007EBD007EBD007EBD +007EBD007EBD007EBD007DBC007EBD007CBB007ABA007BBA007BBA007BBA007BBA007BBA +007BBA007BBA007BBA007BBA007ABA007BBA007ABA007ABA007EBD007FBF007FBE007DBF +007ABA007BBA007ABA007ABA007ABA007BBA007DBD007DBD007EBC007EBC007EBC007DBC +007EBD007DBC007EBD0078B50274AD0071AB78A9D19C63CB7636BA7D3FBD7C3DBC7D3EBD +7D3EBD7D3FBD7736BA915AC7B899D66F33A9753AAD6B2DA7BB9ED78F59BF7534B07B3DB4 +7B3CB47837B3C1A6D96D419A541F8BAE94C8875CB6632C9F6A35A36E38A8B6A2CC512D75 +4B25724D2972BAA6CD64339D582594AC90CB4F3F5E746384998AAC6F657B6F6778575955 +090909000000010101000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000010101050505040404040404 +050505010101000000000000000000000000000000000000000000000000000000000000 +000000000000080807444841474C423F423C3939393D42395C5D5CB1A5BBAA9FB3AA9FB5 +ADA5B49D83B79268BB946DBA956DBB8D67B45C298E55208957228A58238B5B298B4C1680 +61328FB8A3CC9372B3623294B9A4CF59248E673797633295612F93623094623094623094 +623094612F94623094623094623094623094623094623094623094623094612F93643395 +602D92602D929776B7AD91C9622D995E299767349C6D3DA1BAA4D1551F8B9472B69B7BBB +58248C612B97B2A4C113170E000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000002030000000024370079B60075B10073AE0075B00074AF0075B0 +0075B00075B00075B00074AF0074AF0075B00075B00074AE0070AA006FA5006EA5006FA6 +006FA6006FA6006EA6006FA6006FA8006FA7006FA8006FA8006FA8006FA8006FA8006FA7 +006FA8006FA7006EA7006FA7006FA7006FA7006FA8006EA5006FA60071AB0071AC0071AC +0071AC0073AF0074B10074B00074B10077B40077B40077B40077B40077B40077B40077B4 +0076B30076B30076B30076B30077B30076B30075B30076B40076B40075B30075B30075B3 +0076B50078B50079B5007AB6007AB60079B60079B60079B6007AB6007AB6007AB6007AB6 +0079B60077B30078B40078B30077B30078B40078B40078B40077B30078B40078B4007AB8 +007DBC007EBD007EBD007DBC007DBC007DBC007EBD007DBC007ABA007BBA007BBA007ABA +007BBA007DBC007EBD007DBC007EBD007DBC007EBD007EBD007EBD007EBD007EBD007DBC +007EBD007CBB007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA +007BBA007ABA007BBA007ABA007ABB007EBD007FBF007DBE007ABA007ABA007BBA007BBB +007CBD007EBC007EBC007EBC007DBC007DBD007EBD007EBD007DBC007EBD007DBB0074AD +0074AE006FAC087EAFB6B7E17B36BB7D40BD7C3DBC7D3EBD7D3EBD7D3FBD7533B99E6FCF +B292D06525A4773DAE6C2EA88D5DBBBB9BD8712EAE7E40B57230AFA071CAA488C055208B +602E9273499FB9A1D3642CA060289E9873C18770A13F18694E29744B2771B9A5CC602E99 +7445ABADA1BA2C1441DEDAE2C5BCCF8E88942A2B2A000000040404000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000010101010101 +010101010101000000030303040404040304040304040304040304040404030303000000 +000000000000000000000000000000000000000000020202000000393A3872746F696C67 +5D5F5BA8ABA5C9B9D8AD99BFB29EC4B6A4C58B64B17D4FAB7C4EA97544A5AE90CB8D6AB0 +A68BC2794FA34B128359258D602F915F2D915F2D915F2D90623194643395633295643295 +643295633194612F93623094623094623094623094612F93623094623194521B897A4FA4 +C2AED68C67B65C25955C2695A687C58660AC9573B7916EB44F1887926FB6626361000000 +020202000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0002030000000023350079B70075B10073AE0075B00074AF0075B00075B00075B00075B0 +0075B00074AF0074AF0075B00075B00074AE0070AA006EA5006EA5006FA5006FA6006FA6 +006FA8006FA7006FA8006FA8006FA8006FA8006FA7006FA8006FA8006FA8006FA8006EA7 +006EA7006EA7006EA7006FA70071A90072AC0077B40077B40076B30077B40077B40077B4 +0077B40076B30076B30076B30076B30076B30076B30076B30076B40077B40077B40076B4 +0077B40076B40075B40076B40076B30076B40076B40076B40075B30075B30076B30077B5 +0079B6007AB6007AB6007AB60079B60079B60079B6007AB60079B60077B30078B40078B4 +0078B40077B40077B30077B3007AB6007DBB007DBC007EBD007EBD007DBC007DBC007EBD +007DBD007DBC007EBD007DBC007ABA007BBA007ABA007BBA007ABA007BBA007DBB007EBD +007DBC007EBD007DBD007EBD007EBD007EBD007DBD007DBC007EBD007CBB007ABA007BBA +007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007BBA +007ABA007ABB007EBD007EBF007AB9007BBC007DBC007EBC007EBD007DBC007DBD007DBD +007EBD007EBD007EBD007EBD007DBC007EBD007DBB0074AE0073AD0476AF0068A760AECE +B576D46D2BB67F41BE7C3DBC7D3EBD7D3FBD7938BBC3A9DF7B43B07135AB7237AB743AAD +6A2CA7BB9FD78F59BF7636B17736B2C2A9DA693C98602F9364349556218BAD93C7875CB7 +632C9FD3C4E35D3C7F46206F4E2A7541196B81699BA386C9A289BC2F19443C2652FFFFFF +9E9F9E252525000000040404000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000020202020202020202020202020302 +020202000001000001000001000001000000000000000000000000020203131610151911 +161A130D11096D6D6E918F948A898C8C8C8D827A89D7CAE2FFFFFFC3AED7AC8FC99773BB +66319C6D3AA06B389F6E3AA15C2790521D87541F89541F89531E8859268D643395623194 +6332946332946331946231946231946231946635965D2990653496A487C19370BA5B2495 +6F3FA2A88DC5A588C18C69AF6D3AA1979797000000040304000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000203000000002437 +0079B70075B10073AE0075B00074AF0075B00075B00075B00075B00075AF0075B00074AF +0074AF0075B00075B00074AE0071AA006EA6006EA5006FA5006FA7006EA7006FA8006FA8 +006EA8006FA8006FA8006EA7006EA7006EA7006EA7006FA9006FA90070A80072AB0072AB +0073AC0071AC0071AD0075B10077B40077B40076B30076B30076B30076B40077B40077B4 +0077B40077B40077B40077B40077B40077B40077B40076B40077B40076B40075B40076B4 +0076B40076B40075B40075B40076B40075B40075B40075B30076B30076B40078B6007AB6 +007AB6007AB60079B60079B60079B60077B30078B40077B40077B30077B3007AB6007DBB +007EBD007EBD007EBD007DBC007DBC007EBD007DBC007DBD007DBD007DBC007EBD007DBC +007ABA007BBA007BBA007ABA007BBA007ABA007ABA007DBC007EBD007DBC007EBD007EBD +007EBD007DBD007DBD007EBC007DBD007BBB007ABA007BBA007BBA007BBA007BBA007BBA +007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007ABA007BBB007BBB +007DBB007EBC007EBD007DBD007DBC007DBD007DBD007DBD007DBD007EBD007EBD007DBD +007DBC007EBD007DBB0074AE0073AD0074AE0072AD0579AF8FAAD69250C57738BA7D3FBD +7C3DBC7E40BD7431B9C2A7DF7941AE7135AB7338AC7439AC6B2DA78E5FBBBC9CD96921A9 +A477CCA285BF57228C64339564349557238C9A7AB9936DBD7947AFB2A3C347216F512D77 +512D773A116571568FCEBFE36D5C7E48325BD6D0DC717271000000030303020202000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000020202040404040404040404020202000000000000000000000000000000000000 +0000000000000404042D2F2C2929283235302F34295C5C5CADA4B6A29BAAA49CADA59FAB +A084BB9D75C49D79C29C77C2A27EC6855AB157208F5E28935D27925D27935A258E58258B +58258C58258C57238B5E2C906331955A258EA386C0C4B0D8612C999876BBBAA5CF7D53A8 +A88BC42F332B000000010101000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000002030000000024380079B60075B10073AE +0075B00074AF0075B00075B00075B00075B00075B00075B00074B00074AF0074AF0075B0 +0075B10073AE0071A9006EA6006EA4006FA8006FA8006EA7006FA8006EA7006EA7006FA8 +006FA80070AA0071AA0072AC0073AC0073AC0073AC0073AC0073AB0071AB0070AB0070AB +0072AD0074B10077B40077B40076B30076B30076B30077B40077B40077B40077B40077B4 +0077B40077B40077B40076B40077B40076B40075B40076B40076B40076B40075B40075B4 +0075B40076B40076B30076B40075B40075B40075B40076B30078B60079B6007AB6007AB6 +0079B60077B30077B30077B3007AB6007CBB007EBD007EBD007DBC007DBC007DBC007DBC +007EBD007DBD007DBD007DBD007DBD007DBC007EBD007CBC007ABA007BBA007BBA007BBA +007ABA007BBA007BBA007ABA007CBC007EBD007DBC007DBC007EBD007DBD007DBD007EBC +007DBD007BBB007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA +007BBA007ABA007ABA007ABB007BBB007DBC007DBC0078B6007EBD007DBD007DBC007EBC +007EBD007DBD007DBD007DBD007DBD007EBD007EBD007DBD007DBC007EBD007DBA0074AD +0073AE0073AD0275AE0069A82F96BDBB9EDD7330B87F41BE7E3FBD7634B99B6ACDAF8ED0 +6D30A87339AC7338AC7237AB753BAD692AA6BFA4D98950BDBB9FD5683B975C2990602E92 +5F2D925E2C91613193B197CEAC8ECC6141813309603E17683F17685C397F8871A3FDFEFC +887D94C2C0C87E807D000000060607010101000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000030303040404040404040404040404000000 +0000000000000000000000000000000000000101010000003C3E3A61655E595D565C5F59 +5459507B777FB8A7CAAFA0BFB0A0C1B4A6C29571B88557B4895DB5875AB48C60B87443A4 +511A8857218D4B1184633294A98CC49574B9DDD5E6AA8DC7706A77000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000002030000000022350079B70075B10073AD0075B00075B00075AF +0075B00075B00075B00075B00075B00075B00074B00074AF0074AF0075B00075B00073AE +0071A8006EA7006EA7006FA8006EA70070A80071AA0072AA0073AC0073AC0073AC0073AB +0072AB0072AB0072AB0072AB0073AC0071AC0070AC0071AC0070AB0070AB0072AD0074B1 +0077B40077B40076B30076B30077B40077B40077B40077B40077B40077B40077B40076B4 +0077B40076B40075B40076B40076B40076B40076B40075B40075B40075B40076B40076B4 +0076B40076B40076B40075B40075B40076B40077B40078B40079B60077B3007AB6007CBB +007EBD007EBD007DBC007DBC007DBC007EBD007EBD007EBD007EBD007EBD007DBD007DBD +007DBD007DBC007EBD007CBC007ABA007BBA007BBA007BBA007BBA007ABA007BBA007BBA +007ABA007CBC007EBC007DBD007DBD007EBD007DBD007EBC007DBD007BBB007ABA007BBA +007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007ABB007BBB007CBA007DBC +007DBD007EBE007CB90077B2007DBA007EBD007DBC007EBD007EBD007EBD007DBD007DBD +007EBD007EBD007EBD007EBD007DBC007EBE0077B40073AC0074AE0074AE0073AD0576AF +0069A890BDD99D53C87234B88042BE722FB7AC83D59F77C56727A5753BAD7237AB7338AC +753BAD6C2EA77941AFE3D6F09F80BE6434956E429C6C3E9B6C3F9B6C3F9B6B3E9AAB8EC8 +A691BD81669BAE9EC19F8CB4B0A0C2D4CCDCD1CCD66E68796E68795B5B5C000000040405 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000020202020202020202020202020202 +0201020201020201020202030000000000000000000000000000000305020B0F070A0D06 +0C0F090105005B5C598787877D7D7D8080807B7D7992899CB499CFAF97C8B29ACBAD94C7 +916AB7B99ED5FFFFFFD4D6D2000000020202000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0002030000000024370079B60079B60073AD0075B00074AF0074AF0075B00075B00075B0 +0075B00075B00075B00075AF0075B00074AF0074AF0075B00075B10072A9006FA90072AB +0072AB0073AB0073AC0073AC0072AB0072AB0072AB0072AC0073AC0073AC0073AC0072AC +0073AC0071AC0070AC0071AB0071AC0071AC0070AB0070AB0072AD0075B10077B40077B4 +0076B30076B30077B40077B40077B40077B40077B40076B40077B40076B40075B40076B4 +0076B40076B40076B40076B40076B40076B40076B40076B40076B40076B40075B40075B3 +0075B30075B30075B40078B70078B7007CBB007EBD007EBD007DBC007DBC007EBD007EBD +007EBD007EBD007EBD007EBD007EBD007EBD007EBD007EBD007EBD007DBC007EBD007CBC +007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007CBC007EBD +007EBC007DBD007DBD007EBC007EBD007BBB007ABA007BBA007BBA007BBA007BBA007BBA +007ABA007ABA007ABA007CBB007DBD007DBD007EBD007EBD007EBC007DBD007AB70077B2 +007BB8007EBD007DBC007EBC007EBD007EBD007EBD007EBD007EBD007EBD007EBD007EBC +007DBC007EBE0077B40073AC0074AE0074AE0074AE0074AE0070AC1382B4A2A5D98441BF +7A3CBB7F41BFC4AADE7439AC7338AC7439AC763DAE6F32A96829A57E48B3AB87CDDFD4EB +BDA8D2BAA5D0BCA7D1BCA7D1BBA6D1BDA8D2B49DCCE8E1F0BFB3CBBAAEC6705B88644C7E +4F346C9580AA9190993A364A6B6A6B000000020202000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +020202040404030303030303040404020202000000000000000000000000000000000000 +00000000000000000010110E2C3027282C232A2E2621271C78757C958C9FB2B1B3383837 +000000020202000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000020300000000263A +006AA00079B60073AD0075B00074AF0075B00075B00075B00075B00075B00075B00075B0 +0075B00074B00075B00074AF0074AF0075B00074B00074AD0073AC0072AB0072AB0073AB +0072AC0072AB0073AC0073AC0073AC0073AC0073AC0072AC0073AC0071AC0070AC0071AC +0071AC0070AB0071AC0071AC0070AB0070AB0072AD0076B20077B40077B40076B30076B3 +0077B40076B30076B40077B40076B40075B40076B40076B40076B40076B40075B30076B4 +0076B40076B40075B30075B30075B30075B30076B40076B50078B8007ABA007ABB007CBD +007BBC007AB9007BB9007DBC007EBD007DBC007EBD007EBD007EBD007EBD007EBD007EBD +007EBD007EBD007EBD007EBD007EBD007DBC007EBD007CBC007ABA007BBA007BBA007BBA +007BBA007BBA007BBA007BBA007BBA007BBA007ABA007CBC007EBD007EBC007DBC007EBD +007CBA007ABA007BBA007BBA007BBA007ABA007ABA007ABA007BBA007CBC007DBD007EBD +007EBC007EBC007DBC007DBC007EBD007DBC0077B30078B30077B4007DBD007EBC007EBD +007EBD007EBD007EBD007EBD007EBD007EBD007EBD007EBD007DBC007FBE0077B50073AC +0074AE0074AE0074AE0073AD0376AF0064A65DAECBB680D76B27B48F59C7BCA1D96E30A8 +7439AC6C2FA86524A37F49B3AF8DCFBBA2D69976C1DBCEE77A52A3521E8859278D58258C +58268C56238A5E2E90EFEAF56F578724024A39185B2A074E543773958CA0554E62707070 +000000030303000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000030303050505040404040404050505020202 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000102000000000000004E74007FBF0072AC +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00074AF0074AF0075B00074B00074AE0073AB0072AB0073AB0073AC0072AC0073AB +0073AC0073AC0073AC0072AC0073AC0071AC0070AC0071AC0071AC0071AC0071AB0071AC +0071AC0071AC0070AB0071AC0073AF0076B30077B40077B40076B30076B30076B40077B4 +0076B40075B40076B30076B40076B40076B40076B40075B30075B30075B30076B40075B3 +0078B70079B9007ABA007CBD007CBD007CBD007CBD007CBD007ABA0079B70079B8007AB8 +007DBC007EBD007DBC007DBC007EBD007EBD007EBD007EBD007EBD007EBD007EBD007EBD +007EBD007DBC007EBD007CBC007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA +007BBA007BBA007BBA007ABA007CBC007DBD007EBD007EBD007BBA007ABA007BBA007ABA +007ABA007BBA007BBA007CBC007EBC007EBC007EBC007DBC007DBD007DBD007EBD007DBC +007EBD007BB90077B30078B40077B4007CBA007EBD007DBC007EBD007EBD007EBD007EBD +007EBD007EBD007EBD007DBC007EBD007DBB0075B00073AD0074AE0074AE0074AE0074AE +0073AD0375AF006CA97EB5D49753C6B28FD89163BC611FA27136AB996FC3C1A8DAB89DD4 +936DBD5D259B7E4FB2AF9DC0AA94C15F2E92633493613293643594532088B69DCED4D0D9 +2E0C524628663E1F5F50356ED0CCD6A5A3AB5C5B5D000000030303000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000010101010101010101010101 +020203030303040404010101000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000101000001000000004D74007FBF0072AC0075B00074AF0074AF +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0074AF +0075AF0075B00075AF0073AE0072AB0072AB0073AB0073AC0072AC0073AB0073AC0072AC +0073AC0071AC0070AC0071AC0071AC0071AC0071AC0071AC0071AC0070AB0071AC0070AB +0070AB0071AC0074B00076B30077B40077B40076B30077B40076B40076B40076B40075B3 +0075B30075B30075B30076B40078B70078B7007BBC007BBC007CBD007CBD007CBD007BBC +007BBC007BBC007BBC007CBC007AB90079B8007AB80079B80079B8007CBC007EBD007EBD +007DBC007EBD007EBD007EBD007EBD007EBD007DBD007DBD007DBD007DBC007EBD007CBC +007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA +007ABA007BBB007DBB007EBD007BBA007ABA007ABA007BBB007BBC007DBC007EBC007EBD +007DBD007DBD007DBC007EBD007DBD007DBD007EBD007DBC007EBD007AB60077B30078B4 +0077B3007BB8007EBD007DBC007EBD007DBD007DBD007DBD007EBD007EBD007EBD007DBC +007EBD007CB80073AC0073AD0073AD0073AD0073AD0073AD0073AD0174AE006CAA278FB7 +AB95D7B78FD98E61BB9567C0C0A6D9A687C87C4EAE6A36A461299E61299FB8A2D0684A87 +B29DC857248B6232936030915A2A8D7448A2A196A89B8FA73E1E6044266426044ACCC3D5 +CBCACE4E4D51010100010102000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000001000101000000004E74007FBF0071AA0074AF0075B00074AF0075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075AF0074B00074AF0075B00074B0 +0074AE0073AC0072AC0072AB0073AB0073AC0073AB0072AC0073AC0071AC0070AC0071AC +0071AC0071AC0071AC0071AC0071AC0071AC0070AB0071AC0071AC0070AB0070AB0071AC +0074B00076B30077B40077B30076B30075B30075B30076B40077B5007AB9007ABB007BBC +007CBD007CBD007CBD007CBD007BBC007BBC007BBC007CBD007BBC007CBC007BBD007CBC +007AB80079B80079B8007AB80079B80079B8007AB9007DBB007EBD007DBC007DBD007EBC +007EBD007DBD007DBD007DBD007DBD007DBC007EBD007CBC007ABA007BBA007BBA007BBA +007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007DBB +007BBA007ABB007CBB007EBC007EBD007DBD007DBD007DBD007DBD007EBD007EBD007DBD +007DBD007DBD007DBC007EBD007CBB0078B40077B30078B40077B30078B5007DBC007EBD +007DBC007DBD007DBD007DBD007DBD007EBD007EBD007DBC007EBD007DBA0074AF0074B0 +0074AF0074AF0074AF0074AF0074AF0074AF0478B10065A791C5DEE5C5EBB69ED4A88ACA +7343A95E259C652EA16A35A46B36A46F3AA8B5A0CA48216F947EAC8B67B056238A643594 +54208BA187BBA19AA5715A8A38185A2F0D528C78A1FFFFFF727272000000040404000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000101000000 +004D730083C50075B00073AE0075B00074AF0075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075AF0074B00075AF0075B00075B00074AF0074AC +0072AC0072AB0073AC0072AC0073AB0071AC0070AC0071AC0071AC0071AC0071AC0070AB +0071AC0071AC0071AC0071AC0071AC0071AC0071AC0070AA006FAA0070AB0074B00077B4 +0076B50078B80079B9007ABB007CBD007CBD007CBD007CBD007BBC007BBC007BBC007BBC +007BBC007CBD007CBD007CBD007CBD007BBC007CBD007ABA007AB80079B80079B80079B8 +007AB8007AB80079B8007AB8007CBB007EBD007EBC007DBC007EBC007EBD007DBD007DBD +007DBC007DBD007EBC007CBB007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA +007ABA007BBA007BBA007BBA007ABA007ABA007BBB007BBA007DBA007EBC007EBD007EBD +007DBC007DBC007DBC007DBD007EBD007EBD007EBD007EBD007DBD007DBC007DBC007EBD +007BBA0077B30078B40077B30078B40077B3007BB8007EBD007DBC007DBD007DBD007DBD +007EBD007EBC007EBC007DBC007DBC0078B40077B30078B40078B40078B40078B40078B4 +0078B40078B40077B4017AB6006EACA4CCD99660BA5219976A35A46C38A56A35A46C37A5 +5E259C9D78C58E77A630025E8D75A49878BA5420895C2C8F835AAC7D6D8A84798C6C5388 +2E0D527A668FCECFCE757675000000050505000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000001000203003752006DA50079B6 +0073AD0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00074B00074AF0074AF0075B00075AF0074AF0073AC0072AB0072AB +0073AC0071AC0070AC0071AC0071AC0071AC0071AC0071AC0070AB0070AB0070AB0070AB +0070AB0070AB0071AC0075B20075B10075B10078B70079B60079B7007CBD007CBE007CBD +007BBC007BBC007BBC007BBC007CBD007CBD007CBD007CBD007CBD007CBD007CBD007CBD +007CBD007BBC007CBD0079BA0079B8007AB80079B8007AB8007AB8007AB8007AB80079B8 +0079B8007BBB007EBD007EBD007DBC007DBD007EBD007DBD007DBC007EBD007CBB007ABA +007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007ABA +007BBB007CBD007EBF007EBF007ABA007DBC007EBC007DBC007EBD007EBD007EBD007EBD +007EBD007EBD007EBD007EBD007EBD007EBD007DBC007EBD0079B60077B30078B40078B4 +0078B40077B3007AB6007EBD007DBC007EBD007EBD007EBD007EBD007EBD007DBC007FBE +007AB70070A90075B10078B40077B30077B30077B30077B30077B30077B30078B40078B4 +026091005E9288AED28D52B358229B6A37A46A35A46B37A55E269C9974C3957FAB31035F +937CA99674B8532088623095BAADC710001F8B7F93684E833F205EFFFFFF5B5A5B000000 +050505000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000001020000000015210070AA0078B50073AD0075B00074AF +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00074AF0074AF0075B00075AF0074AC0072AC0072AB0072AB0070AB0070AB +0070AB0070AB0070AB0070AA0073AE0074AF0073AF0077B60078B60078B60078B7007AB9 +007AB9007AB9007AB90079B60077B20078B5007BBB007CBD007CBD007BBC007CBD007CBD +007CBD007CBD007CBD007CBD007CBD007CBD007CBD007CBD007CBD007BBC007CBD007ABA +007AB8007AB8007AB8007AB8007AB8007AB8007AB8007AB8007AB80079B8007AB8007DBA +007EBD007DBC007DBC007EBD007DBC007EBD007CBB007ABA007BBA007BBA007BBA007BBA +007BBA007BBA007BBA007ABA007ABA007ABA007CBB007EBD007EBF007FBF007FBE007EBF +007ABA007BBA007DBB007EBD007DBC007EBC007EBD007EBD007EBD007EBD007EBD007EBD +007EBD007DBC007EBD007DBC0079B50077B30078B40078B40078B40078B40078B4007CBB +007EBD007DBC007EBD007EBD007EBD007DBC007EBD007CBA0073AD0071AB0075B10078B4 +0077B30078B40078B40078B30078B40077B30079B5006DA5015C880163980470A587AACE +A673C2662FA16733A36A35A36A34A5B8A3CD542F784C2473522C77B4A1C857258B9979BC +6B5E753723459B8DAA321155DCD4E5727371000000040404000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000003040000000016220070AA0078B50073AD0075B00074AF0075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0074AF0074B00075B00074B00074AC0072AC0072AE0072AD0073AE0077B50076B40076B4 +0079B8007AB9007AB9007AB8007AB8007AB8007AB80079B80079B80079B80079B80079B5 +0077B30077B30077B3007AB8007BBC007CBD007BBC007BBC007CBD007CBC007CBD007CBD +007CBD007CBD007CBD007CBD007CBC007BBD007CBC007AB8007AB8007AB8007AB8007AB8 +007AB8007AB8007AB8007AB8007AB8007AB80079B8007AB7007BBA007EBD007EBD007DBC +007DBC007EBD007CBB007ABA007BBA007ABA007BBA007BBA007BBA007ABA007ABA007BBB +007DBE007EBD007FBF007FBF007FBF007EBE007FBE007EBF007ABA007ABA007CBC007EBD +007EBC007DBD007EBC007EBD007EBD007EBD007EBD007EBD007EBD007DBC007EBD007AB9 +0077B30078B40078B30078B40078B30078B40077B3007BBA007EBD007DBC007EBD007DBC +007EBD007DBC007FBE0076B20070AA0071AC0073AD0078B40077B40077B30078B40078B3 +0077B30078B40078B5006191005D8A016699026BA500659FA6D9E3BBA2D564289E6532A1 +7846AEB29FC6461E6E542E7A492271B09EC4653399B3A3C12915373C2A4AA194B0CCC2D8 +81847E000000050505000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000203000000 +00141E0071AB0078B50072AB0075B00075B00074AF0075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075AF0074AF0075B0 +0075B00075B00079B6007AB9007AB8007AB9007AB9007AB9007AB80079B80079B80079B8 +0079B80079B80079B8007AB80079B8007AB80079B70077B30078B40078B40078B40077B3 +0078B4007BBB007CBD007CBD007BBC007BBC007CBD007BBD007BBD007CBD007CBD007CBD +007CBC007BBD007CBB007AB8007AB80079B80079B8007AB8007AB8007AB8007AB8007AB8 +0079B80079B8007AB8007AB80079B8007ABA007CBA007EBD007EBC007EBD007CBB007ABA +007BBA007BBA007ABA007ABA007ABA007CBB007DBD007EBF007FBF007FBF007EBE007EBE +007EBE007EBF007FBE007EBF007ABA007BBA007ABA007CBC007EBD007DBC007EBD007DBD +007EBD007EBD007EBD007EBD007DBC007DBC007EBD0079B60077B30078B40078B40078B4 +0078B40078B40077B30079B5007EBD007DBC007DBD007EBD007DBC007EBE0078B50071AB +0072AC0071AB0072AC0078B30077B40077B30077B30078B40077B30079B500679A005E8C +005E8B006598006EA6046BA3005E9C2D90B7AD9CD1591696A386C9795E9542196C41196B +370D6381649DBFA8D45A516701001362516FE5DDED797B76000000050505000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000001020000000015200070AA007DBC +0073AD0074AF0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00074AF0074B00074AF0074AF0077B2 +007AB8007AB80079B80079B80079B8007AB80079B8007AB8007AB80079B80079B80079B8 +0079B8007AB80079B70077B30078B40077B30078B40078B40077B30077B30079B7007BBB +007CBD007BBC007BBC007BBD007BBD007BBD007CBD007CBD007CBC007BBD007AB9007AB8 +0079B80079B80079B80079B8007AB8007AB80079B80079B80079B80079B80079B8007AB8 +007AB80079B80079B7007CBA007DBD007EBD007CBB007ABA007ABA007ABA007ABA007CBB +007EBD007FBF007FBF007EBE007EBE007EBE007FBE007FBF007FBF007EBF007FBE007BBA +007ABA007BBA007BBA007ABA007CBB007EBD007DBC007EBD007DBD007EBD007EBD007DBD +007DBC007DBD007EBC0078B40077B30078B40077B40078B40078B40078B40078B40077B3 +007BB9007EBD007DBC007DBC007EBD007DBC0073AD0071AB0072AC0072AC0071AB0074AF +0078B40077B30078B40077B30079B50072AB005D8A005F8D005D8B006598006CA5006CA3 +036EA500609D308EB5A898D2B896CD633C824F2374977BAD9879AC977FADF9F9FA81748B +6C5D76CEC8D3636165000000030303000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000102000000000C12003E5D007EBE0073AD0074AF0075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00074AF0075B00075B00074AF0075B10078B5007AB90079B8 +0079B8007AB80079B8007AB8007AB80079B80079B80079B80079B8007AB80079B70077B3 +0078B40078B40078B40077B30078B40077B30077B30078B4007ABA007CBD007CBD007BBC +007BBC007CBD007CBC007CBD007CBC007BBD0079B9007AB80079B80079B80079B80079B8 +007AB8007AB80079B80079B80079B80079B80079B8007AB8007AB8007AB8007AB80079B7 +007AB9007DBD007CBB007ABA007BBC007DBE007EBD007FBF007FBF007EBF007EBE007EBF +007FBE007FBE007FBE007FBF007FBF007EBF007FBE007BBA007ABA007BBA007BBA007BBA +007ABA007CBC007EBD007DBC007EBD007EBD007EBD007EBD007DBC007EBD007BB90077B3 +0078B40078B40077B40078B40078B40077B30078B40077B3007AB8007EBD007DBC007DBC +007EBE0074B00071AA0072AC0071AB0072AC0071AB0073AF0078B40077B30077B30078B5 +0076B1005F8E005E8C005F8D005D8B006598006DA5006BA3006BA3036EA5005F9D388EB2 +C0CBD59C9DBABBBCD09ABCC62F738AAEBCC75E4D6750455EAEA8B67B7C79000000050505 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000101000102000000003C5A007EBE0073AD0073AE0075B00074AF0075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00074AF0075AF0076B3007AB8007AB80079B80079B8007AB8 +007AB80079B80079B80079B80079B8007AB80079B70077B30078B40078B40078B40077B4 +0077B40078B40078B40078B40077B30079B6007BBC007CBD007CBD007BBC007CBD007CBC +007BBD007BBC0079B9007AB80079B80079B80079B8007AB8007AB8007AB8007AB8007AB8 +007AB8007AB8007AB80079B80079B70079B7007AB7007AB8007AB7007BBA007DBD007DBD +007FBF007FBF007FBF007EBE007EBE007EBE007FBF007FBE007FBE007FBE007FBE007FBF +007FBF007EBF007FBE007BBA007ABA007BBA007BBA007BBA007BBA007ABA007CBC007EBC +007DBD007EBD007EBD007DBC007DBD007DBC0078B50077B30078B40077B40078B40078B4 +0078B40078B40078B40077B30078B4007EBC007DBC007EBE007AB70071AB0072AC0072AC +0072AC0072AC0071AB0072AD0077B30077B40077B30079B5006A9F005D8A005F8D005F8D +005D8B006598006DA5006BA3006CA4006AA20174AD01436F003D60004E6F024A6C002F56 +345D82807E9300000C5248615D5B5E000000040304000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000101000203 +000000003B58007FBF0076B20073AD0075B00074AF0075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF +0075B00075B00074AF0075B1007AB8007AB90079B80079B8007AB8007AB8007AB8007AB8 +0079B8007AB80079B40077B30078B40078B40078B40078B40078B40078B40077B30078B4 +0078B40077B30078B40079B8007BBC007CBD007BBC007BBC007CBD007CBB0079B7007AB8 +007AB8007AB8007AB8007AB8007AB8007AB80079B70079B70079B70079B80079B7007AB9 +007BBC007BBB007DBB007FBE007EBE007EBE007BBC007DBC007FBF007EBE007EBE007FBE +007FBF007FBF007FBF007FBF007FBE007FBE007FBF007FBF007FBF007EBF007FBE007BBA +007ABA007BBA007BBA007BBA007BBA007BBA007ABA007DBC007EBC007DBC007EBD007DBC +007EBD007DBB0077B30078B40077B30078B40078B40078B40078B40078B40078B40077B3 +0078B4007CBA007EBE007AB80071AB0071AB0072AC0072AB0072AC0071AB0072AC0071AB +0077B20077B30079B60070A7005C89005F8D005F8D005F8D005D8B006598006DA5006BA3 +006BA2006EA8005684013D5B01476B0043690047670C3A70B4A0CF332D3B594D69707070 +000000030203000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000020400141E006295 +007CBA0072AC0075B00074AF0075AF0075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B00075B00074AF +0075B00077B4007AB9007AB80079B8007AB8007AB8007AB80079B8007AB80079B50077B3 +0078B40078B40078B40078B40078B40078B40078B40078B40078B30078B40077B30077B3 +0078B5007BBB007CBD007CBD007BBC007BBA0079B8007AB80079B80079B80079B80079B8 +0079B70079B8007ABA007ABA007CBA007EBD007EBD007EBD007FBF007FBF007FBF007EBF +007EBF007FC0007BBC007ABA007CBC007FBF007EBE007EBF007FBF007FBF007FBF007FBF +007FBF007FBF007FBF007FBF007EBF007FBF007EBE007BBA007ABA007BBA007BBA007BBA +007BBA007BBA007BBA007BBA007DBC007EBD007DBC007DBC007EBD0079B70077B30078B4 +0078B40078B40078B40078B40078B40078B40078B40078B40077B30079B7007FBE0074AE +0071AB0072AC0072AC0072AC0072AC0072AC0072AC0071AB0073AF0078B40079B6006495 +005E8B005F8D005E8D005F8D005D8B006598006DA5006AA1006FA900619200344F004163 +00476B03476B003E636762AC8D80924D495C717071000000030203000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000203000000000A0F006498007CBA0072AC0074AF +0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00074AF0075B00074AF0074AF0076B20079B7 +007AB90079B80079B8007AB80079B8007AB80078B40077B30078B40078B40078B40078B4 +0078B40078B40078B40078B40078B30078B40078B40078B40078B30077B30079B8007CBD +007BBD0079B80079B70079B8007AB9007AB9007AB9007DBB007DBC007DBC007FBF007FBF +007FBF007FBF007FBF007FBF007EBE007EBE007EBE007EBE007FBF007DBC007BBB007BBA +007ABA007CBC007FBF007EBE007EBE007FBF007FBF007FBF007FBF007FBF007FBF007FBF +007EBF007FBF007DBE007ABA007BBA007ABA007BBA007BBA007BBA007ABA007BBA007ABA +007BBA007DBC007EBD007DBC007EBD0078B50077B30078B40078B40078B40078B40078B3 +0078B30078B30077B30077B30077B30079B80076B20071AB0072AC0071AB0071AB0071AB +0071AB0071AB0072AC0071AB0072AC0079B5006EA5005E8C005F8D005F8D005F8D005F8D +005D8B006598006CA5006CA4006CA500466A00375300416201476C0043652240619885A4 +5A50686D6D6D000000030304000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000010200000000080D006395007CBB0074AF0074AE0075B00074AF0075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00074AF0075B00075B00074AF0075B00078B40079B8007AB80079B8 +007AB80078B60077B30078B40078B30078B30078B40078B40078B40078B40078B40078B4 +0078B40077B30077B30077B30077B30078B40077B30078B4007CBB007DBB007CBA007CBB +007EBF007EBF007EBF007FBF007FBF007FBF007EBE007EBE007EBE007EBE007EBE007EBE +007FBF007FBF007FBE007EBE007FBF007DBB007ABA007BBA007BBA007ABA007CBC007FBF +007EBF007EBE007FBF007FBE007FBE007FBE007FBE007FBF007EBF007FBF007DBE007ABA +007BBA007BBA007BBA007BBA007BBA007BBA007ABA007BBA007ABA007BBA007DBB007EBE +007DBA0077B30078B40078B40077B30077B30077B30077B40077B40077B40079B60079B6 +007AB70077B50070AC0075B00074AE0073AD0073AD0073AD0073AE0072AC0071AB0071AB +0072AD0075AF005E8C005E8C005F8D005F8D005F8D005F8D005D8B006598006CA5006CA5 +00466A003652003957003F60024E7100214184689DA49EAB5C5B5D000000020202000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000101 +000000000305002C41007BB90074AF0073AD0075B00074AF0075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00074AF0075B00074AF0074AE0076B20079B7007AB8007AB80078B70077B30078B4 +0078B40078B40077B30077B30077B30077B30077B30077B30077B30079B50079B60079B6 +007AB7007DBB007DBB007DBB007BB9007CBA007FBF007FBF007FBE007FBE007FBE007EBE +007EBE007EBE007FBF007FBE007FBE007FBE007FBE007FBF007FBF007FBE007EBE007EBE +007FBF007CBB007ABA007BBA007BBA007BBA007ABA007CBD007FBE007EBF007EBE007FBE +007FBE007FBE007FBE007FBF007EBE007FBF007DBE007ABA007BBA007BBA007BBA007BBA +007BBA007BBA007BBA007ABA007BBA007ABA007BBA007DBC007BB80077B30077B30077B3 +0078B50079B50079B5007AB9007ABA007ABA007BBB007ABA007CBD0074AF006CA40076B1 +0074B00075B00075B00075B00075B00074AF0074AF0074AF0073AD006396005F8E005E8D +005E8C005E8D005F8D005F8D005D8B0064970071AD005C8C003552003B5900385602486C +003957312058E6D3F5616460000000020202000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000001000203000000002B3F +007DBC007AB80072AC0075B00074AF0075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B0 +0075B00074AF0074AF0078B6007AB90078B70077B20077B30077B30077B30078B40078B5 +0078B50079B5007CBA007CBA007CBA007DBC007EBD007EBD007EBD007EBD007EBD007EBD +007CBA007AB7007CB9007FBF007FBF007EBE007EBE007FBE007FBF007FBF007FBE007FBE +007FBE007FBE007FBE007FBF007FBF007FBE007EBE007FBE007EBF007ABB007ABA007BBA +007BBA007BBA007BBB007AB9007CBD007FBE007EBF007EBE007FBE007FBE007FBE007FBE +007EBF007FBE007DBE007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA +007ABA007BBA007ABA007BBA0079B50079B80079B90079B9007ABB007BBB007BBB007BBA +007BBA007BBA007ABA007BBA007ABA006EA7006DA50075AF0074AF0074AF0074AF0074AF +0074AF0075B00074AF0078B400699D005A87006294006091005F8F005F8D005E8D005F8D +005D8A00669A005F91003956003A58003856034263003155464E59B8A7C5727470000000 +050505000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000203000000001F2E005886007DBC0072AB +0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B00074AF0075B0 +0077B40078B6007AB7007BB9007BB8007BB8007DBB007EBD007EBD007EBD007EBD007EBD +007EBD007EBD007DBC007DBC007DBC007DBC007DBD007DBC007BB8007BB8007AB8007CB9 +007FBF007FBF007EBE007FBF007FBF007FBF007FBF007FBE007FBE007FBE007FBF007FBF +007FBF007FBF007EBE007FBE007EBF007BBB007ABA007BBA007BBA007BBA007BBA007BBA +007ABA007CBC007FBF007EBE007EBE007FBE007FBE007EBE007FBF007EBD007BB9007ABA +007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBB +0078B7007BBA007BBA007BBA007BBA007ABA007ABA007ABA007ABA007ABA007ABA007BBA +0079B9006CA5006BA20072AC0075B10074AF0075B00075B00075B00074AF0076B2006FA6 +005580005D8C00619200619100619100619100609100608F005D8B00689C003F5F003754 +003A58003A58003A56081E2AC0C1C1797B77000000050505000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000102000000000102005480007EBE0072AB0075B00074AF0075AF +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00074AF0075B00075B00074AE0076B2007DBD007FBE +007EBD007EBD007EBD007DBC007DBC007DBC007DBC007DBC007DBC007DBC007EBD007EBC +007EBD007DBC007EBD007DBC007BB8007AB8007BB8007AB8007BB9007DBD007FBF007EBE +007EBE007FBF007FBF007FBF007FBF007FBF007FBF007FBF007FBF007FBF007EBE007FBF +007CBB007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007CBC007FBF +007EBE007EBF007FBF007EBE007FBF007EBD007BBA007ABA007BBA007BBA007BBA007BBA +007BBA007BBA007BBA007BBA007BBA007ABA007BBB007AB80073AE0079B6007BBC007ABA +007ABA007BBA007BBA007BBA007BBA007BBA007ABA007CBC0073AE006BA2006BA30070A8 +0075B00074AF0074AF0074AF0075B00074AF0076B200609100527C005E8D006192006091 +00609100619100609100619200639500456400334D00355000334D023B5700153152504F +2E2E2E000000020202000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000203000001000203005581007EBE0072AD0075B00074B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00074AF0075B00075B00074AE0076B4007CBA007EBD007DBC007DBC007EBD +007EBC007EBC007EBD007EBD007EBD007EBD007EBD007EBD007EBD007DBC007EBD007DBC +007BB8007BB8007AB8007BB8007AB8007AB8007DBD007FBF007EBF007EBE007FBF007FBF +007FBF007FBF007FBF007FBF007FBF007FBF007EBE007FBF007CBA007ABA007BBA007BBA +007BBA007BBA007BBA007BBA007BBA007BBA007ABA007CBC007FBF007EBE007EBF007EBE +007FBF007EBD007BBA007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA +007BBA007ABA007BBC0077B20073AC0075B1007ABA007BBA007ABA007BBA007BBA007BBA +007BBA007ABA007BBB0079B9006CA5006BA3006BA3006CA40075B00075AF0075B00075B0 +0074AF0076B20070A800558000557F005D8C006192006091006191006091006091006497 +003F5C002E4400344E00324C003851002142000009000000000000020202000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000001000001000102 +00557F007DB30072AD0075B00074AF0075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0074AF0075B00074AF0074AE007AB6007EBE007DBC007DBC007EBD007EBD007EBD007EBD +007EBD007EBD007EBD007EBD007EBD007DBC007EBD007BB9007AB8007BB8007BB8007BB8 +007BB8007AB8007AB8007DBD007FBE007FBF007EBE007FBF007FBE007FBF007FBF007FBF +007FBF007EBF007EBE007FBF007CBA007ABA007BBA007BBA007BBA007BBA007BBA007BBA +007BBA007BBA007BBA007ABA007CBC007FBF007EBE007EBE007FBF007EBD007BBA007ABA +007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007BBC0077B2 +0073AD0073AC0078B3007BBB007ABA007BBA007BBA007BBA007BBA007ABA007BBB0077B5 +006AA2006CA4006CA4006BA30072AB0075B00074AF0074AF0075B00073AE005984005580 +005580005D8D006192006091006091006091006497003D5900263700355000324C003852 +00214000000B000000020202010101000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000100010000000B0056B4007AB20073AE +0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B00075B0 +0074AE007AB6007EBE007DBC007DBC007EBD007DBC007DBD007DBD007DBD007EBD007EBD +007EBD007DBC007EBD007BB9007AB8007BB8007BB8007BB8007AB8007BB8007AB8007AB8 +007BB9007EBE007FBF007EBE007FBF007FBE007FBF007FBF007FBF007EBF007FBE007EBF +007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA +007ABA007CBC007FBE007EBF007FBF007DBD007ABA007BBA007BBA007BBA007BBA007BBA +007BBA007BBA007BBA007BBA007BBA007ABA007BBC0077B20073AD0074AD0074AF007ABB +007BBA007ABA007BBA007BBA007BBA007ABA007CBB0070A9006BA3006CA4006CA4006BA2 +0070A90075B10074AF0074AF0076B200669A00537D005680005885006192006091006191 +006090006395003E5B002534002E4300324B003854002132000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000202000000002042007DB90074B00074AE0075B00074AF0075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00074AF0075B00075B00074AE007AB6007EBE +007EBD007DBC007EBD007DBC007DBD007DBD007DBD007EBD007EBD007DBC007EBD007BB9 +007AB8007BB8007BB8007BB8007BB8007AB8007BB8007BB8007AB8007BB9007EBE007FBF +007EBE007FBF007FBE007FBF007FBF007EBE007FBE007EBF007ABA007BBA007BBA007BBA +007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007AB9007CBD007FBE +007FBF007CBD007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA +007BBA007ABA007BBC0078B30073AD0074AE0073AD0077B2007BBB007ABA007ABA007ABA +007ABA007BBC0076B4006BA2006CA4006CA4006CA4006BA3006CA40074AF0074AF0076B2 +006CA400537D005681005580005885006192006091005F8F006497005885002636002C40 +003046003855002132000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000101000000002B40007BB90074AF0074AE0075B00074AF0075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00074AF0075B00075B00074AF0077B3007CBC007EBD007DBC007EBD +007DBC007DBD007DBD007EBD007DBC007EBD007DBB007AB8007BB8007BB8007BB8007BB8 +007BB8007BB8007BB8007AB8007BB8007AB8007BB8007EBE007FBF007EBE007FBF007FBF +007FBF007EBE007FBE007CBC007ABA007BBA007BBA007BBA007BBA007BBA007BBA007BBA +007BBA007BBA007BBA007BBA007BBA007BBB007AB9007CBD007FBF007CBD007ABA007BBA +007BBA007BBA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007BBA007ABA0075AF +0073AD0074AE0074AE0073AD0078B8007BBB007ABA007BBA007ABA007CBB0074B1006AA2 +006CA4006BA3006BA4006CA4006BA30073AD0075B00076B2005E8C00547F005681005580 +005885006193005F8F006496005A87002B3F00293B002C3F003650002134000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000020400000000293D +007CBA0074B00074AF0075B00074B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0074AF0075B00075B00074AE0075B1007CBC007EBD007DBC007EBD007DBC007EBD007EBD +007DBC007EBD007DBB007AB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8 +007AB8007BB8007AB8007BB8007DBC007FBF007EBE007EBF007FBF007EBE007FBE007BBA +007ABA007BBA007BBA007BBA007BBA007BBA007BBA007ABA007BBA007BBA007BBA007BBA +007BBA007BBA007ABA007AB9007DBD007DBF007AB9007BBA007BBA007BBA007BBA007BBA +007BBA007BBA007BBA007BBA007ABA007BBA0079BA0073AE0074AD0074AD0074AE0073AE +0074AE0079B9007BBB007ABA007BBA007ABA006DA5006BA3006CA4006CA4006CA4006CA4 +006BA3006EA60076B2006BA200547F005681005681005580005885006090006396005A87 +002B3F002535002C40003046001F2D000000000001000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000203000000002A40007BB50076AD0074B0 +0075AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00074B00075AF0075B0 +0074AF0075B1007CBC007EBD007DBC007EBD007EBD007EBC007EBD007DBC007BB8007AB8 +007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007AB8007BB8007AB8 +007AB8007DBC007FBF007EBE007EBE007FBF007EBE007BBA007ABA007BBA007BBA007BBA +007BBA007BBA007BBA007BBA007ABA007ABA007ABA007ABA007ABA007ABA007BBB007CBB +007CBC007BBA007BBA007BBB007ABA007BBA007ABA007BBA007BBA007BBA007BBA007BBA +007ABA007BBA007ABA0073AE0074AD0074AE0073AD0074AE0073AD0077B4007BBB007ABA +007CBC0073B1006BA2006CA4006BA3006BA3006BA3006CA3006BA20070A90073AC005580 +005580005681005681005580005784006598005A87002B3F002534002A3D003147001C29 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000204000000002C520075C20073AA0074B00074AF0075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00074AF0075B00074AF0075B1007CBC +007EBE007DBC007DBC007EBD007EBC007DBD007BB9007AB8007BB8007BB8007BB8007BB8 +007BB8007BB8007BB8007BB8007BB8007BB8007AB8007BB8007BB8007AB7007DBC007FBF +007FBF007FBE007DBE007ABA007BBA007BBA007BBA007ABA007ABA007ABA007ABA007ABA +007BBB007BBB007BBB007CBB007EBE007DBD007EBF007FC0007DBB0077B20079B6007AB8 +007BBB007ABA007ABA007ABA007BBA007BBA007BBA007BBA007ABA007BBA0079BA0073AE +0074AD0074AE0074AE0073AD0074AE0073AC0078B7007BBB007BBB0071AD006AA2006CA4 +006CA4006CA4006CA4006CA5006BA2006EA800619200547D00568100568100568100557F +005986005986002B3F00253400293A003045001D29000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000001 +00030000001100529B007FB90071AC0075B00074AF0075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00074AF0075B00074AF0075B2007AB6007EBD007DBD007DBC +007EBD007DBC007BB8007AB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8 +007BB8007BB8007AB8007BB8007BB8007BB8007AB8007CBB007EBD007FBF007DBE007ABA +007ABA007ABA007ABA007ABA007BBA007ABA007CBD007DBC007DBE007FBF007FBF007FBF +007FBF007FBF007EBE007FBF007AB70077B30079B30078B4007AB8007BBA007BBA007ABA +007ABA007BBA007BBA007BBA007ABA007BBA007ABB0073AE0074AD0074AE0074AE0074AE +0074AE0073AD0074B0007ABA0078B6006CA3006CA4006CA4006BA3006BA30069A000699F +00699F005F8F00517900557F00557F00558000558000537D005E8D003750002331002839 +003044001D2A000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000090E006498 +007BBA0072AC0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00074AF0075B00074AF0073AE0079B4007EBD007DBC007EBD007CBA007AB7007BB8 +007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007BB8007AB8 +007AB8007AB8007AB8007AB7007BB8007EBC007BBA007ABA007BBC007CBC007CBC007EBD +007EBF007EBE007FBF007FBF007FBF007EBE007EBE007EBE007EBE007EBE007FBF007EBE +0078B60078B30079B40078B30078B30079B40079B8007BBB007ABA007ABA007BBA007BBA +007ABA007BBB0078B60073AE0074AD0074AE0074AD0073AD0073AD0074AE0073AC0077B5 +0071AE006AA0006AA1006AA000679C00679C00669B00669A00689E004367004C73005681 +00547E00547E00547E00598500405D002737002738002D41001D29000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000002000000000A10006498007CBB0073AD0075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B0 +0075B00074AE0079B4007EBD007EBD007DBB007AB8007BB8007AB8007AB8007AB8007AB8 +007AB8007AB8007AB7007AB7007AB7007AB7007AB7007BB8007BBA007BBA007BBA007BBA +007BB9007EBF007EBE007EBD007EBF007FBF007FBF007FBF007FBF007FBF007EBE007EBE +007EBE007FBF007FBE007FBE007EBE007EBE007FBF007AB80077B20078B40078B30079B4 +0078B40079B40078B30079B5007BBB007BBB007ABA007ABA007ABA007BBB0076AF0073AD +0074AE0073AD0073AD0073AD0074AE0074AE0073AC0071AA00689F00669C00669B00669B +00669B00669B00669B006AA0005987003D5E00517900558000547E00547E005681003B56 +002332002839002B3D001C27000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000102000000000A100062940077B20073AE0075B00074AF0075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075AF0075B00074AE0079B4 +007DBD007BB9007AB6007AB7007BB8007BB8007BB8007BB8007AB8007CBB007EC0007EBF +007EBF007EBF007EBF007FC10080C30080C30080C30080C30080C4007DBE007AB7007EBE +007FBF007EBE007EBE007EBE007EBE007EBE007EBE007FBE007FBF007FBF007FBF007FBE +007FBE007EBE007FBF0078B50077B30077B40077B40079B40078B40079B40079B40078B3 +0079B50079B7007BBB007BBA007ABA007BBB0076B00073AD0074AE0074AE0074AE0074AE +0073AC006FA80070A700689E00609200689D00669B00679C00679C00669B00669B00689D +00456A00456800578200547E00547E005783004F7700202F00293A002C40001A26000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000102 +000000001723007EBE0074AE0074AF0075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075AF0075B00074AF0074AF007BBA007EBE007DBE +007FC2007FC2007FC2007FC2007FC2007FC20080C30080C30080C30080C30080C30080C3 +007FC2007FC2007FC2007FC20080C4007BBA0078B4007CBA007FBF007EBE007EBF007FBF +007FBF007FBE007FBE007FBF007FBF007FBF007FBF007FBF007EBE007FBF007DBB0078B4 +0077B30078B40078B40079B40078B40079B40078B30079B40078B30078B30079B5007BB9 +007BBB007BBB0076B00073AD0074AE0073AD0071AA0070A8006FA5006EA5006FA6006396 +005B8900679C00669B00679C00679C00669B0069A0005988003B5C00466B00568000547E +00557F00527C00273B002536002D41001A25000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000102000000003C59007AB8 +0073AE0074AF0075AF0075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00074B00075AF0075B00074AE0079B60081C50080C30080C30080C30080C30080C3 +0080C30080C3007FC2007FC2007FC2007FC2007FC2007FC20080C30080C3007FC2007FC2 +0080C3007BB90079B50079B5007CBA007FBF007EBE007FBF007FBF007FBF007FBF007FBF +007FBF007FBF007FBF007FBF007EBE007FC0007AB80077B20078B40077B30078B40079B4 +0078B40079B40079B40078B30079B40079B40078B30079B5007AB8007BBC0077B10071AB +0071AA006FA6006EA5006EA5006EA6006EA60070A6005C8A005B8900659900679C00669B +00669B00679C00679C00476C003C5D00466B00568100537C005B88002B41001C28002E42 +001A25000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000040600689D0077B40074AF0075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF +0075B00074AE007AB70080C3007FC3007FC2007FC2007FC2007FC20080C30080C30080C3 +0080C30080C30080C30080C30080C30080C3007FC20080C3007FC2007AB60079B6007AB6 +0079B5007CBB007FBF007EBE007FBF007FBE007FBF007FBF007FBF007FBF007FBF007EBE +007FBF007FBF0078B50077B30078B40078B40078B40077B40079B40078B40079B40079B4 +0079B40079B30079B40078B30079B40075B00070A6006FA6006EA5006EA5006FA6006FA6 +006EA50070A700689D005B8800598700619400689D00669B00669B00699F005988003D5E +003F6100466A00557F005885004363001B27002C3F001A26000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000203000000003048007DBC0072AC0074AF0075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B00073AE007AB7 +0080C4007FC2007FC20080C30080C30080C30080C30080C3007FC2007FC20080C30080C3 +0080C30080C3007FC20080C3007FC2007AB60079B6007AB60079B5007AB7007FBE007FBF +007EBE007FBF007FBE007FBF007FBF007FBF007FBF007EBE007FBF007BBA0077B30078B4 +0077B30077B40078B40077B40078B40078B40079B40079B40079B40078B30078B30079B4 +0077B1006EA200699D006FA6006FA6006FA6006EA5006FA6006EA50070A800659A005885 +005B89005E8D00669B00679C00669B00689D00466B003E60003F60004569005985004567 +001722002535001B27000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000101 +00679B0078B40074AE0074AF0075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00074B00075B00075B00073AE0079B70080C4007FC2007FC2 +0080C30080C30080C3007FC2007FC2007FC2007FC20080C30080C3007FC2007FC20080C3 +007BB90079B5007AB60079B6007AB60079B5007AB7007FBE007FBF007EBE007FBE007FBE +007FBF007FBF007FBF007EBE007FBF0079B60077B30078B40077B40077B40078B40077B4 +0079B40079B40078B30079B40078B30079B30079B40072AC0070A7006EA500689A006CA0 +006FA6006EA5006FA5006EA5006EA6006FA6006294005987005B89005A8800669A00669B +00699F005988003D5E004063003E5F00466A005A8600273C001F2D001D2A000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000102000000003048007EBE0072AC0075B0 +0074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075AF0075B00074AE0079B70081C4007FC2007FC20080C30080C2007FC2 +007FC2007FC2007FC20080C20080C30080C3007FC20080C3007BB80079B5007AB60079B6 +0079B6007AB60079B5007BB8007FBF007EBE007EBE007FBE007FBE007FBF007EBE007FBF +007EBE0078B40077B40078B40077B40077B40078B40077B40078B40078B40079B40078B3 +0079B40079B40072AC006FA60070A8006EA500689B006A9D006FA6006FA6006EA5006EA5 +006FA6006EA3005A87005A89005A89005B8800649700679C00689D00466B003E5F004062 +003E6000496F003149001A26001924000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000005080065980079B60073AE0074AF0075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00074AE0079B70080C4007FC2007FC20080C30080C2007FC2007FC2007FC20080C3 +0080C3007FC20080C3007FC1007AB60079B6007AB60079B60079B6007AB6007AB60079B5 +007DBC007FBF007EBE007FBF007FBF007EBF007EBE007FBF007AB70077B30078B40077B3 +0077B40077B40077B40078B30077B40078B30078B30079B50076AF0072AB006FA70070A8 +0070A8006EA400689B00689B006BA0006FA6006EA5006EA50070A700669A005A87005B89 +005B89005A87005E8F00699F005783003D5E004164004062004469003D5C000D1300090D +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000102 +00000000344F007BBA0073AD0075B00074AF0075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00074AF0075B00075B00074AE007AB7 +0080C3007FC20080C30080C30080C20080C20080C30080C30080C3007FC20080C3007FC0 +0079B5007AB60079B6007AB6007AB6007AB6007AB6007AB60079B5007DBC007FBF007EBE +007FBF007FBF007EBE007EBF0078B40077B30078B40078B40077B40078B40077B40078B4 +0077B30079B40079B50075AE006FA6006FA70070A8006FA70070A8006A9D00689B00699C +00689B006DA4006FA6006EA50070A8006194005986005B89005B89005987005E8F006194 +003E5F004063003957003B59002F46001018000103000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000609006A9F0078B5 +0073AE0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00074AF0075B00075B00074AF007EC00080C4007FC20080C3 +007FC20080C30080C30080C30080C3007FC20080C3007DBE0079B5007AB6007AB6007AB6 +007AB6007AB6007AB6007AB6007AB60079B5007DBD007FBF007EBE007EBE007FBF007CBC +0077B30078B40078B40078B40078B40077B40078B40078B30078B40077B20072AB006FA7 +0070A80070A8006FA7006FA70070A800699D00689B00699C00689B006A9E006EA5006FA7 +006BA0005B89005A88005A88005B89005B8A005B8900466A00355000304900304800283B +000F16000102000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000100000000131D0074AE0075B00074AF0074AF0075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075AF0075B00074AF0076B2007EC10080C3007FC20080C3007FC20080C30080C3 +0080C30080C3007FC20079B60079B6007AB6007AB6007AB6007AB6007AB6007AB6007AB6 +007AB60079B5007BB8007FBF007EBF007FBF007EBE0079B60077B30078B40078B30078B4 +0078B40078B40077B40077B30078B50072AB006CA30070A8006FA70070A70070A7006FA7 +0070A800699D00689B00699C00699C00689A006BA00070A800689C005986005D8C005B89 +005985005582004365002A3D002E44002E4400293D000F16000102000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000101000000004970007DBC0073AD0075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B0 +0074AE0075B2007EC10080C3007FC20080C3007FC20080C30080C20080C3007FC2007AB6 +0079B6007AB60079B60079B60079B6007AB6007AB6007AB6007AB6007AB60079B5007BB8 +007FBF007FBF007EBD0077B30078B40077B30077B40077B40077B40078B40077B40076B3 +0077B50072AC006CA30070A8006FA7006FA70070A7006FA70070A800699D00689B00699C +00699C00699C00689A006DA400609200598600527C004E76004668004669003147002D43 +002E4500324B000D13000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000101000000001722 +0074AE0075B10074AF0074AF0075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00074AF0075B00074AE0075B2007EC1 +0080C3007FC20080C3007FC2007FC20080C3007EBE0079B5007AB6007AB60079B60079B6 +0079B60079B6007AB6007AB60079B60079B6007AB60079B5007CBA0080C0007BB90077B3 +0078B40078B40077B40076B40076B40076B40076B40076B30077B50072AC006CA2006DA5 +0070A8006FA7006FA8006FA70070A800699E00689B00699C00689B00699C006A9D006A9F +00558200476A004567004466004B7100344F00213200304700324A001723000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000102000000004C73007BBA0073AD0075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00074AF0075B00074AF0075B1007FC20080C3007FC20080C3 +007FC20080C4007EBF0079B4007AB60079B60079B60079B60079B60079B6007AB60079B6 +007AB6007AB6007AB60079B50079B6007DBD007AB80076B30077B40076B40076B40077B4 +0077B40077B40077B40076B30077B50072AC006CA2006DA3006DA50070A80070A70070A8 +006DA300689B00689B00689B006A9D00679A00608E004D7500426300476A00476A00486C +004060002130002C4200334C001723000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000100000000111A0075B00074AF0074AF0074AF0075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00074AF0075B00074AF0075B1007EC10080C3007FC20080C3007FC2007BB90079B5 +007AB6007AB60079B60079B6007AB6007AB6007AB6007AB60079B50079B50079B6007AB7 +007BB90079B70076B40077B30076B40077B30077B40076B40077B40077B40077B40076B3 +0077B50072AC006CA2006DA4006CA3006DA5006FA80070A8006DA200679A006A9D006A9D +00649600527C00517A00406200436500486B00456800496E002739001D2A00344D001622 +000000000101000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000102 +00000000486C007DBC0072AC0074AF0075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B0 +0074AE0077B30080C4007FC20080C3007FC00079B5007AB6007AB6007AB6007AB6007AB6 +007AB60079B60079B60079B5007AB7007AB7007BBB007BBD007CBF0072AB0073AD0076B0 +0077B30077B40076B30077B30077B40077B40076B30076B30077B40070A9006CA3006DA4 +006DA4006CA3006DA50070A9006DA200699D00649600598600507900517C004C74003A58 +004467004669004A6F003E5B001C27002F44001825000000000001000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000100000000111B0075B00075B0 +0074AF0074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF007BBA0080C4 +0080C3007EC00079B5007AB60079B60079B60079B50079B50079B6007AB6007BBB007BBC +007CBD007CBD007CBD007CBD007BBB006EA50072AA0075B00076AF0076B30077B40076B4 +0077B30077B40076B30077B40075B2006CA3006DA4006CA3006DA4006CA3006CA2006EA7 +006DA200608F00507A004F7800517A00527C00406300395700446700476A004466002535 +00202E001825000000000001000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000010100000000486C007DBD0072AC0075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00074AF0075B00074B00074AE007BBA0081C5007CBB0079B40079B5 +007AB60079B6007ABA007BBB007BBB007CBD007CBD007CBD007BBC007BBC007BBC007DBF +0077B4006CA00073AC0075B00074AF0074B00075B30077B30076B40076B30076B30077B4 +0076B2006DA4006CA3006DA3006CA3006DA4006EA5006BA2005A88004E7700517B00517B +00517C004F76003A58003A59004365004C72003149001A27001E2E000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0001010000000016220073AE0075B10074AF0074AF0075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0074AF0075B00075B00073AE007CBC007DBC0079B6007BBA007BBC007BBC007CBD007CBD +007CBD007BBC007BBC007BBC007BBC007BBC007CBC007CBD0073AD006CA10072AB0075B0 +0074AF0075AF0074B00075AF0077B30077B40076B30077B40076B2006DA4006CA3006CA3 +006EA6006AA1006193005986004C7100517A00517B00507A00527D00486E003A58003958 +004669003C5800202C000F1D000008000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000102000000004C71 +007CBA0073AD0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B00075B0 +0074AE007AB8007CBD007CBD007BBD007CBD007BBC007BBC007BBC007CBD007BBC007BBD +007BBD007BBC007CBD007BBC006DA4006DA20073AC0075B00074AF0074B00075AF0074AF +0075AF0076B30076B40077B40076B2006CA3006DA4006DA400689C005C8A005884005681 +00496E004F7900517B00517B00517A003C5D003A58003A5900496C002333000506000001 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000010000000015200074AF0074AF0074AF0074AF +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00074AF0075B00074AF0076B4007BBD007BBC +007BBC007BBC007BBD007CBD007CBD007BBD007BBD007BBD007BBD007BBC007CBE0076B3 +006DA3006DA3006FA70074B00075AF0074AF0074B00075B00074AF0074AF0075B30077B4 +0076B2006EA6006CA3006191005783005985005C8A004F7800486B004D7300517B00527C +00486D003856003B5B003D5C00243A000306000000000001000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000203000000004D74007EBD0072AC0075AF0075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00074AF0075B00074AE0078B6007DBE007BBC007CBD007CBD007CBD +007CBD007CBD007BBD007BBD007CBD007BBC007DBF0074AD006CA1006EA4006EA40074AF +0075B00074AF0075B00075AF0075B00075AF0074AF0076B30075B0006395005B89005885 +005A87005A87005885004C7200496D004C7100517B00517B003C5D003B5B003D59001C34 +00000C000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000102000000 +003550007CBB0073AD0075B00074AF0075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00074B00075AF007AB8007CBD007BBC007CBD007CBD007CBD007CBD007CBD007CBD +007BBC007CBD0079BA006EA4006EA4006DA3006EA50074AF0075B00074AF0075B00075AF +0075B00074AF0075B00075B1005F8D005782005A87005A87005986005A8800578200486C +004A6F00496D004F77004E77003F61002F44001122000011000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000050700689C0077B40074AF +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B00074AF0075B2 +007CBD007BBC007BBD007CBC007CBD007CBD007CBD007BBC007BBC007CBD0077B6006DA2 +006EA4006DA3006EA50074B00075B00074AF0075B00075AF0074AF0075B00075B100608F +00547C005884005A87005986005986005A88004F7700496D004A6E00486C00517B004366 +002B41000E12000005000001000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000010200000000324B007DBC0072AC0074AF0075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00074AF0075B00074AF007AB8007CBE007BBC007CBD +007CBD007CBD007CBD007CBD007BBC007DBF0072AA006CA2006EA4006EA3006DA40072AC +0075B00074AF0074AF0075B00074AF0076B200609000567F005882005580005986005A87 +005986005B89004C7300486C00496D004C7100476C001B26000B0E000001000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000010100689C0078B50074AE0074AF0075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00074AF0075B0007BBA007CBD007BBC007CBD007BBD007BBD007BBC +007CBD007ABA0070A7006DA3006EA4006EA4006DA20071A80075B10074AF0075B00074AE +0077B3006EA4005780005983005681005580005784005A87005A87005884004B70004A6E +004E7400364F00151D000D11000102000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000102000000002D43007DBC +0073AD0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B0 +0074AE0078B5007CBE007BBC007CBD007BBC007BBD007BBC007DBE0076B5006CA1006EA4 +006DA3006EA4006DA30071A90075B00074AF0074AE0077B3006EA5005882005982005883 +005581005680005580005883005B8900547D004A6E00476C003750001116000D11000102 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000102000000001C2A0079B50073AE0074AF0075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00074AF0075B00074AF0078B8007CBE +007BBC007CBD007BBC007BBC007CBD0072AC006DA3006EA4006EA4006EA4006DA20071A9 +0075B10074AE0077B3006EA5005882005882005983005783005581005681005580005580 +005987005077004263002639001A24000F14000101000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000010200000000527C007BBA0073AD0074AF0075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00074AF0076B0007BBB007CBD007BBC007CBD007BBC +007CBC006FA5006DA3006EA4006EA4006EA4006DA3006FA70074AF0077B3006EA5005882 +00588200598300598200578200558100568100557F005784005B8800314800202E001A23 +000A0F000101000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000001000000001926 +0079B70073AD0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0074AF0075B00074AF0077B2007CBD007BBC007BBC007DBF0075B3006DA2006EA4006EA4 +006EA4006DA3006EA4006CA20075B1006FA5005882005882005983005882005982005680 +00558000547F005884004F7700344C001F2C001F2F000710000101000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000100000000527A007DBD0072AC0075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074B0 +007ABA007CBD007BBD007BBB006FA7006DA3006EA4006DA3006DA3006EA4006DA3006FA6 +006DA2005982005882005983005882005883005982005680005580005B88004C71002437 +001A28002435000C29000003000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000101000000001C2C0072AC0075B00074AF0075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00074AF0075B00074AF0077B2007CBC007CBD007AB9 +006DA3006DA4006DA3006EA4006EA4006EA4006DA3006AA0005A85005881005983005883 +00588200598300588200578200547F003F5E00283C001B2A002432000E17000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000203006CA30077B30074AF0074AF0075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00074AF0075B00074AE0077B5007DC00072AD006DA2006EA4006EA4006CA2 +006CA100679C00699F005C8B005580005A86005885005983005982005882005883005682 +00334E00253600203000202F00151D000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000101000000003A59007EBE0072AC +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075AF0074B1007BBC0071AB006DA2006BA100689D00679C00669B00669B00669C004E78 +005681005985005884005985005884005A8500588400334D002639002437001B29001A27 +000204000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000001000000000B10006CA30077B30074AE0074AF0075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00074AF0074AF0075B00071AA00689D +00689D00669B00669B00679B00669B00699F005C8C004970005783005985005885005883 +00598600598500324B002538002A3E001F30001621000102000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000102000000003E5E007DBC0073AD0075B00075AF0075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00074AF0075B00073AE00679D00669B00679C00679C00669B +00679C00669C004E77004F78005A86005884005884005986005A86003248002131002A3F +002637001520000102000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000D13006DA4 +0076B20074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00074AF0076B2006BA300659A00679C00679C00669B00689E005D8D00476E00517B +005A8600588400598500598400334B001F2F002639002A3D001521000103000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000203000000003E5E007CBB0073AD0074AF0075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00074AF0074AF0075B1006CA2 +00669A00679C00669B00669B00669B004F7900487000517A005A86005783005C8A00354E +00223000243500293D001B2A000101000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000060A006EA60076B10074AF0074AF0075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00074AF0075B00073AD00669B00679C00669B00699F +005D8D004970004A7200517A005984005C8A004C7200253500253500243600121C000202 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000102000000 +003A56007EBE0072AC0075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00074AF0075B00074AE00699E00669B00669B00689E005785004970004A72004F78 +005E8C004C73002638002536002538000C13000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000090F006DA40077B30074AF +0074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0076B1 +006EA600659900679D006397004B73004A72004A72005784004C72002536002636002638 +000C13000000000001000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000102000000003C59007DBD0072AC0075B00075AF0075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075AF0074AF0076B1006DA600659900699F005683 +00486F004A72004D76005C8A002B3F00273900283B000B12000000000001000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000001 +000000000D14006DA50077B30074AE0075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00074AF0075B00074AF00699F006396004A73004B73004C75004B71003750 +002536001E2E000B12000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000102000000003F5F007BB9 +0072AC0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B0 +0074AF006AA1005785004A7200476E003D5C00283900212F001722000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000080D0073AE0077B30074AE0075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00074AF0074AF0076B200699D004263003D5B +003B56002E44001E2C001925000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000001010000000021320076B30074AE0074AF0074AF0075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00073AE0079B6006294003147003A55003046002435001824000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000001000000 +005782007FBF0073AD0075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF0075B0 +0075B0004363003750003147001E2A00151F000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000006080059850077B40073AE +0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00074AF0077B3003D5B003954002131 +00131C000102000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000001000000000F16007BB90075B00074AF0075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00074AF0074AF0077B3006498003A56002638000E16000102000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00010200000000324C0079B60073AD0075B00074AF0075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00073AD007AB7 +005782002A3D00070A000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000006597 +007BBA0072AC0075B00074AF0075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00074AF0075B00073AD0079B500537B000E13000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000001000000000D14006A9F007AB80072AC0075B0 +0074AF0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00074AF +0075B00073AD0079B5006EA7001017000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000001000000000D13006A9F007AB80071AA0075B00075B00074AF0075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00074AF0075B00073AD0078B30073B2001734 +000000000102000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000102 +000000000E1500699E0080C10073AD0074AF0075B00074AF0075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B00075B0 +0075B00074AF0075B00073AD0078B40073AD001926000000000102000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000102000000000E14003D5C +007AB90074AE0072AC0074AF0075B00074AF0075B00075B00075B00075B00075B00075B0 +0075B00075B00075B00075B00075B00075B00075B00074AF0075B00074AE0072AB0078B4 +0073AD001826000000000202000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000100020300000000314B007DBD007CBB0075B0 +0073AD0074AF0074AF0075B00074AF0075B00075B00075B00075B00075B00075B00075B0 +0074AF0075B00074AF0073AE0072AB0077B3007EBE0072AD001724000000000203000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000010100020300000000324D0057830071AB007DBC0078B40073AE0073AE +0075B00074AF0074AF0074AF0074AF0074AF0074AF0074AF0074AF0072AB0075B00079B7 +0081C200669A005580001C2C000000000103000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00010200000100000000131E004B70006A9F0079B6007AB70074AF0075B10075B00075B0 +0075B00075B00075B00075B00077B30080C10077B3004F7800213200111A000000000101 +000101000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000102000203000000 +00000000000000273B0060910077B30072AC0073AE0073AE0073AE0073AE0073AD0077B3 +006497003955001E2C000000000001000001000203000001000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000010200000100000000000000060A +000B11000A0F000A10000A10000A10000A10000A0F000B1100080C000000000000000000 +000102000001000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000102000001000000000000000000000000 +000000000000000000000000000000000203000101000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 + +end +%%PageTrailer +%%Trailer +%%EOF diff --git a/doc/doxygen/figures/MED_small.png b/doc/doxygen/figures/MED_small.png new file mode 100644 index 000000000..dfa6c0c2f Binary files /dev/null and b/doc/doxygen/figures/MED_small.png differ diff --git a/doc/doxygen/figures/NonCoincident.png b/doc/doxygen/figures/NonCoincident.png new file mode 100755 index 000000000..72f011ab7 Binary files /dev/null and b/doc/doxygen/figures/NonCoincident.png differ diff --git a/doc/doxygen/figures/NonCoincident_small.eps b/doc/doxygen/figures/NonCoincident_small.eps new file mode 100644 index 000000000..25bc47382 --- /dev/null +++ b/doc/doxygen/figures/NonCoincident_small.eps @@ -0,0 +1,15904 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: (ImageMagick) +%%Title: (NonCoincident_small.eps) +%%CreationDate: (Thu Nov 29 18:36:36 2007) +%%BoundingBox: 0 0 375 281 +%%HiResBoundingBox: 0 0 375.052 281 +%%DocumentData: Clean7Bit +%%LanguageLevel: 1 +%%Pages: 1 +%%EndComments + +%%BeginDefaults +%%EndDefaults + +%%BeginProlog +% +% Display a color image. The image is displayed in color on +% Postscript viewers or printers that support color, otherwise +% it is displayed as grayscale. +% +/DirectClassPacket +{ + % + % Get a DirectClass packet. + % + % Parameters: + % red. + % green. + % blue. + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + compression 0 eq + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/DirectClassImage +{ + % + % Display a DirectClass image. + % + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { DirectClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayDirectClassPacket } image + } ifelse +} bind def + +/GrayDirectClassPacket +{ + % + % Get a DirectClass packet; convert to grayscale. + % + % Parameters: + % red + % green + % blue + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 eq + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/GrayPseudoClassPacket +{ + % + % Get a PseudoClass packet; convert to grayscale. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 eq + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassPacket +{ + % + % Get a PseudoClass packet. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + compression 0 eq + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassImage +{ + % + % Display a PseudoClass image. + % + % Parameters: + % class: 0-PseudoClass or 1-Grayscale. + % + currentfile buffer readline pop + token pop /class exch def pop + class 0 gt + { + currentfile buffer readline pop + token pop /depth exch def pop + /grays columns 8 add depth sub depth mul 8 idiv string def + columns rows depth + [ + columns 0 0 + rows neg 0 rows + ] + { currentfile grays readhexstring pop } image + } + { + % + % Parameters: + % colors: number of colors in the colormap. + % colormap: red, green, blue color packets. + % + currentfile buffer readline pop + token pop /colors exch def pop + /colors colors 3 mul def + /colormap colors string def + currentfile colormap readhexstring pop pop + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { PseudoClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayPseudoClassPacket } image + } ifelse + } ifelse +} bind def + +/DisplayImage +{ + % + % Display a DirectClass or PseudoClass image. + % + % Parameters: + % x & y translation. + % x & y scale. + % label pointsize. + % image label. + % image columns & rows. + % class: 0-DirectClass or 1-PseudoClass. + % compression: 0-none or 1-RunlengthEncoded. + % hex color packets. + % + gsave + /buffer 512 string def + /byte 1 string def + /color_packet 3 string def + /pixels 768 string def + + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + x y translate + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + currentfile buffer readline pop + token pop /pointsize exch def pop + /Times-Roman findfont pointsize scalefont setfont + x y scale + currentfile buffer readline pop + token pop /columns exch def + token pop /rows exch def pop + currentfile buffer readline pop + token pop /class exch def pop + currentfile buffer readline pop + token pop /compression exch def pop + class 0 gt { PseudoClassImage } { DirectClassImage } ifelse + grestore +} bind def +%%EndProlog +%%Page: 1 1 +%%PageBoundingBox: 0 0 375 281 +userdict begin +DisplayImage +0 0 +375.052 281.289 +12.000000 +500 375 +0 +0 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFEFCFCFCFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFBFBFBFCFCFCFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFA +FAFAFAFAFAFAFCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D48080808A8A8A898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +8989898989898989898989898A8A8A7B7B7B7676768A8A8A898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +898989898989898989898989898989898989898989898989898989898989898989898989 +8989898989898989898989898989898989898989898989898989898A8A8A7B7B7BD2D2D2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9AEAEAEF8F8F8F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F7F7F7BABABAA5A5A5F8F8F8F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3 +F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F8F8F8ABABABBCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBC8C8C86464644D4D4D747474 +D6D6D6FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4B4B49B9B9BFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFD7D7D73C3C3C8A8A8AA0A0A07979794C4C4CEEEEEEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFBFBFBD2D2D2404040636363FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFF9C9C9C +7C7C7CFFFFFFFFFFFFF8F8F8434343B2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFA6A6A6303030 +3C3C3C656565FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6F4F4F4FFFFFFFFFFFFF0F0F0 +434343B9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFBBBBBBB8B8B8888888626262FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3787878898989F9F9F9FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF898989626262FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF3F3F3787878868686F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +898989626262FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3797979868686F8F8F8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF898989626262FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFF4F4F4757575797979EEEEEEF3F3F3F2F2F2FBFBFBFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF898989626262FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFF9F9F9F +0C0C0C303030383838373737383838C4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +8B8B8B656565FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4C6C6C6C5C5C5C4C4C4C5C5C5 +C5C5C5EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E2D8D8D8FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF5F5F5 +F2F2F2EBEBEBE5E5E5E1E1E1D9D9D9D7D7D7CECECECCCCCCC6C6C6EFEFEFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FBFBFBF5F5F5F3F3F3EBEBEBE9E9E9E2E2E2DEDEDED9D9D9D2D2D2CFCFCFC3C3C3C1C1C1 +B5B5B5B0B0B0A8A8A8A0A0A09B9B9B8F8F8F8F8F8F9393939494949797979999999B9B9B +9F9F9FA0A0A0A4A4A4A1A1A16E6E6EDDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFBFBFBF7F7F7F3F3F3EDEDEDEBEBEBE4E4E4E2E2E2DBDBDBD8D8D8D0D0D0 +C7C7C7C3C3C3B6B6B6B3B3B3A7A7A7A3A3A39A9A9A919191939393959595959595979797 +9898989A9A9A9C9C9C9D9D9D9F9F9FA2A2A2AFAFAFB2B2B2BFBFBFC4C4C4CDCDCDD6D6D6 +DBDBDBE8E8E8E9E9E9EEEEEEEFEFEFF3F3F3F6F6F6F8F8F8FCFCFCFDFDFDFFFFFFE4E4E4 +9B9B9BF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEFEFEFEFEFEBEBEBEA3A3A3F5F5F5ECECECE7E7E7E5E5E5DFDFDF +DDDDDDD0D0D0CCCCCCC3C3C3BABABAB5B5B5A8A8A8A6A6A6999999959595969696979797 +9797979797979898989999999999999A9A9A9A9A9AA3A3A3ACACACB0B0B0BDBDBDC0C0C0 +CDCDCDD1D1D1DBDBDBE3E3E3E6E6E6EBEBEBECECECF2F2F2F3F3F3F8F8F8FBFBFBFDFDFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBCBCB7B7B7FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDFBFBFBF9F9F9F4F4F4F3F3F3EDEDEDEBEBEB +E8E8E8E4E4E4DFDFDFD2D2D2CFCFCFC2C2C2BEBEBEB5B5B5ACACACA6A6A69A9A9A9A9A9A +9B9B9B7575756767679A9A9A979797979797969696969696969696A4A4A4A8A8A8B0B0B0 +B9B9B9BEBEBECBCBCBCECECEDBDBDBDEDEDEE4E4E4E7E7E7EAEAEAF0F0F0F1F1F1F8F8F8 +F9F9F9FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFBFBFB999999E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDFCFCFCF9F9F9F6F6F6F4F4F4 +F0F0F0EFEFEFEAEAEAE8E8E8DFDFDFD6D6D6D1D1D1C4C4C4C1C1C1B5B5B5B1B1B1A6A6A6 +9F9F9F9E9E9E9C9C9C9B9B9B989898989898969696959595939393919191969696A3A3A3 +A5A5A5B2B2B2B5B5B5BEBEBEC6C6C6CCCCCCD8D8D8DADADAE5E5E5ADADADA0A0A0F1F1F1 +F1F1F1F7F7F7F9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E09A9A9A +FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFEFEFEFAFAFA +F8F8F8F5F5F5F3F3F3F1F1F1EDEDEDEBEBEBDEDEDEDADADAD0D0D0C8C8C8C2C2C2B7B7B7 +B4B4B4A7A7A7A4A4A4A0A0A09F9F9F9C9C9C9999999898989494949393939090908E8E8E +9797979F9F9FA4A4A4B0B0B0B2B2B2BEBEBEC1C1C1CCCCCCD2D2D2D7D7D7DDDDDDE0E0E0 +E8E8E8E9E9E9F1F1F1F5F5F5FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8BBBBBBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFEFBFBFBFAFAFAF8F8F8F6F6F6F3F3F3F2F2F2ECECECE0E0E0DDDDDDD0D0D0CDCDCD +C2C2C2BCBCBCB5B5B5AAAAAAA8A8A8A3A3A3A2A2A29C9C9C9A9A9A979797939393929292 +8C8C8C8D8D8D9999999C9C9CA5A5A5ABABABB2B2B2BCBCBCBEBEBECACACACCCCCCD5D5D5 +D9D9D9DFDFDFE5E5E5E8E8E8F1F1F1F3F3F3FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF9F9F9999999E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +FCFCFCF9F9F9F4F4F4E3E3E3D1D1D1C0C0C0A9A9A99F9F9FA4A4A49D9D9D929292818181 +9494948E8E8E8989898E8E8E9898989B9B9BA5A5A5A8A8A8B2B2B2B7B7B7BDBDBDC5C5C5 +C8C8C8D2D2D2D4D4D4DEDEDEE2E2E2E9E9E9EFEFEFF3F3F3FDFDFDFDFDFDFEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC9C9C9CFCFCFC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFEFCFCFCF9F9F9ECECECDBDBDBCACACABABABAACACACA0A0A09595958C8C8C969696 +A5A5A5B2B2B2767676ADADADD4D4D4DDDDDDD3D3D3999999CECECEF7F7F7FCFCFCFCFCFC +FDFDFDFDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4B4B4BFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEFCFCFCF4F4F4E4E4E4D4D4D4C4C4C4B5B5B5A8A8A89B9B9B8E8E8E919191 +9E9E9EAAAAAAB7B7B7C7C7C7D7D7D7E8E8E8F7F7F7FCFCFCFFFFFFE3E3E39D9D9DF8F8F8 +FFFFFFFFFFFFFFFFFFE4E4E4A7A7A7E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F7F7F7969696E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEFEFEFEFAFAFAECECECDDDDDDCECECEBFBFBFB0B0B0A1A1A19292928D8D8D +989898A3A3A3AEAEAEBCBCBCCDCDCDDFDFDFF0F0F0F9F9F9FCFCFCFEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +DCDCDCA7A7A7EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D99E9E9EFDFDFDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFDFDFDF3F3F3E5E5E5D8D8D8CACACAB9B9B9A9A9A99999998E8E8E +9494949D9D9DA6A6A6B1B1B1C3C3C3D6D6D6E8E8E8F4F4F4F9F9F9FDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EDEDED979797F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3ABABABF5F5F5 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFAFAFAFC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF9F9F9EDEDEDE1E1E1D4D4D4C4C4C4B3B3B3A2A2A2929292 +929292999999A0A0A0A7A7A7B9B9B9CBCBCBDEDEDEEEEEEEF5F5F5FAFAFAFEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDB6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFECACACAB1B1B1F8F8F8FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5 +979797E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF3F3F3E8E8E8DDDDDDCFCFCFBEBEBEABABAB999999 +9292929797979B9B9BA0A0A0ADADADC1C1C1D3D3D3E6E6E6F0F0F0F6F6F6FCFCFCFEFEFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF5F5F5989898E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFDFDFDC0C0C0BABABAFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D5A1A1A1FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8F8F8EFEFEFE5E5E5DADADAC8C8C8B5B5B5A3A3A3 +9595959696969898989B9B9BA3A3A3B5B5B5C9C9C9DDDDDDEAEAEAF1F1F1F8F8F8FEFEFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCB +AAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA +B7B7B7C4C4C4FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFACACACC8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF5F5F5ECECECE2E2E2D2D2D2C0C0C0ADADAD +9C9C9C9797979898989898989A9A9AABABABBEBEBED1D1D1E2E2E2EBEBEBF4F4F4FCFCFC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA9F9F9FDBDBDBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7AFAFAFCDCDCDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3969696 +ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9F2F2F2EAEAEADEDEDECACACAB7B7B7 +A4A4A49B9B9B999999969696959595A1A1A1B4B4B4C6C6C6D8D8D8E4E4E4EEEEEEF8F8F8 +FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD8D8D8A0A0A0FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2A9A9A9D7D7D7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D2A3A3A3FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCF7F7F7F1F1F1E8E8E8D5D5D5C1C1C1 +AFAFAFA1A1A19C9C9C979797929292989898AAAAAABCBCBCCECECEDCDCDCE7E7E7F2F2F2 +FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA7A7A7CFCFCF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFECECECA7A7A7E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFA8A8A8CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF5F5F5EFEFEFDFDFDFCDCDCD +BABABAA8A8A8A0A0A0999999929292919191A0A0A0B2B2B2C3C3C3D3D3D3DFDFDFECECEC +F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4999999F6F6F6FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4 +A6A6A6E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1969696EDEDED +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF9F9F9F5F5F5E9E9E9D7D7D7 +C5C5C5B2B2B2A6A6A69E9E9E9595958E8E8E989898A8A8A8B8B8B8C9C9C9D7D7D7E5E5E5 +F2F2F2FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFB1B1B1C2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDBA8A8A8EFEFEFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCECECEA6A6A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCF9F9F9F2F2F2E0E0E0 +CECECEBDBDBDAFAFAFA4A4A49999998E8E8E919191A0A0A0AFAFAFBEBEBECDCDCDDCDCDC +EBEBEBF9F9F9FEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED989898EFEFEFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D2ACACACF5F5F5FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFA5A5A5D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFEFEFEFCFCFCF8F8F8E9E9E9 +D8D8D8C8C8C8B8B8B8ABABAB9E9E9E9292928C8C8C9A9A9AA7A7A7B4B4B4C3C3C3D3D3D3 +E3E3E3F3F3F3FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB5B5B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEC9C9C9B2B2B2F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED979797F0F0F0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFCFCFCF5F5F5 +A6A6A6939393C6C6C6B4B4B4A6A6A69898988C8C8C949494A0A0A0ABABABB9B9B9C9C9C9 +DADADAEBEBEBF8F8F8FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5 +999999E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC0C0C0 +BABABAFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFCACACAAAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8F8F8 +E9E9E9DBDBDBCDCDCDBEBEBEAEAEAE9E9E9E8F8F8F9393936F6F6F777777B2B2B2BEBEBE +D0D0D0E2E2E2F2F2F2F9F9F9FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBAAAAAAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBB7B7B7C4C4C4FDFDFDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +A1A1A1D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC +F1F1F1E4E4E4D7D7D7C9C9C9B7B7B7A7A7A79696968F8F8F9696969E9E9EA6A6A6B3B3B3 +C6C6C6D9D9D9EBEBEBF9F9F9B5B5B5B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF9F9F99E9E9EDCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF7F7F7AFAFAFCDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA979797F2F2F2FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F7F7F7EBEBEBDFDFDFD2D2D2C2C2C2B1B1B19F9F9F9191919494949A9A9A9F9F9FA8A8A8 +BBBBBBCECECEE1E1E1EFEFEFF5F5F5FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8D8D8A1A1A1 +FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF2F2F2AAAAAAD6D6D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFC6C6C6ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFEF4F4F4E7E7E7DCDCDCCDCDCDBBBBBBA8A8A89696969494949898989B9B9BA0A0A0 +B0B0B0C3C3C3D7D7D7E8E8E8F0F0F0F7F7F7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA6A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDEDA7A7A7 +DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD9E9E9E +D9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F79696968C8C8C9B9B9B +A5A5A5B8B8B8CCCCCCDFDFDFEAEAEAF2F2F2FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE3E3E39B9B9BF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5A6A6A6E7E7E7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7989898F4F4F4FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1C1C1A8A8A8FBFBFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C3C3C3FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFDBDBDBA8A8A8EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC2C2C2B1B1B1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFAFAFAAAAAAAD0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFECECEC989898F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD2D2D2ACACACF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC9C9C9CDCDCDC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E89E9E9E +EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +BEBEBEB5B5B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C9B2B2B2 +F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4999999F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C9AEAEAEFBFBFBFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4989898E7E7E7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDBFBFBFBBBBBBFCFCFCFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFBEBEBEB4B4B4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFCFCFCABABABCDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFCBCBCBAAAAAAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFAFAFAB6B6B6C4C4C4FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB999999E1E1E1FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EAEAEA9E9E9EEBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA9D9D9D +DCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F7F7F7AFAFAFCECECEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE0E0E09A9A9AF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDABABABFBFBFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A1A1A1FBFBFBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2A9A9A9D7D7D7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9BABABAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCADADADCACACAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEA6A6A6CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECA6A6A6DFDFDFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA979797E4E4E4FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEDEDED9E9E9EE8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E39A9A9AF8F8F8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE4E4E4A6A6A6E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFDCDCDC9D9D9DFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF +A9A9A9FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +DCDCDCA8A8A8EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6B6B6 +BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB0B0B0C7C7C7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EDEDED979797F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D2ACACACF5F5F5 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FAFAFAEBEBEAEDECECFBFBFBFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8959595E8E8E8FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9E9E9EE6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEC9C9C9B2B2B2F9F9F9FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED5D6D6929899808D8E818D8E979C9D +E2E3E3C3C3C3ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFDADADA9E9E9EFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD2D2D2A8A8A8F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF5F5F5999999E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFDFDFDC0C0C0BABABAFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C97979797A7A7AC9C9C9FFFFFFFFFFFF +FFFFFFFFFFFFCECFCF849495A2C2C5B1D5D8B0D4D69FBEC08896979F9F9FAEAEAEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B2C2C2C2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB2B2B2C4C4C4 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCB +AAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA +B7B7B7C3C3C3FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC7C7C7585858707070565656313131D0D0D0FFFFFFFFFFFFEFEFEF879192ACCED1 +BCE2E5BBE0E3BBE0E3BDE2E5A8C9CC535B5BA8A8A8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6969696EAEAEAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0A0A0A0E3E3E3FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9E9E9EDCDCDCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6AFAFAFCECECEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD7C7C7CB2B2B2FFFFFF +F7F7F74747479D9D9DFFFFFFFFFFFFD2D2D27D9193BCE2E5BBE0E3BBE0E3BBE0E3BADFE2 +BCE1E4516162A5A5A5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD5D5D5A1A1A1FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD5D5D5A6A6A6F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD8D8D8A0A0A0FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2A9A9A9D7D7D7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1F1F1F1F6F6F6DFDFDF4E4E4EBFBFBFFFFFFF +FFFFFFC8C9C983989ABCE2E5BADFE2BBE0E3BBE0E3BADFE2BCE1E45C6E70A6A6A6FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEAEAEC5C5C5FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD +B6B6B6C1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA7A7A7CFCFCF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFECECECA6A6A6E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC1C1C13A3A3A242424969696FFFFFFFFFFFFFFFFFFDFDFDF7A8B8CB9DEE1 +BBE0E3BADFE2BADFE2BBE0E3B8DCDF485556A5A5A5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF5F5F5949494ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2A0A0A0E0E0E0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4999999F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4 +A5A5A5E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEBC1C1C1 +595959888888FFFFFFFFFFFFFFFFFFFBFAFAA2A7A894B0B2BAE0E3BDE3E6BDE3E6B9DEE1 +91ABAD737676ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +D2D2D2A3A3A3FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8D8D8A3A3A3F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFB1B1B1C2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDBA8A8A8EFEFEFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFAFAFAC5C5C5F0F0F0FFFFFFFFFFFFBCBCBC3B3B3BF6F6F6FFFFFF +FFFFFFFFFFFFEFEFEF9DA3A48196988EAAAC8DA9AB809496ABAFB0B8B8B8ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAACACACAFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEB9B9B9BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED979797EFEFEFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D2ACACACF4F4F4FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5 +4E4E4EAAAAAAFFFFFFEEEEEE565656525252F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFF9F8F8 +CCCDCDADAFAFAFB0B0D2D3D3FFFFFFC3C3C3ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF2F2F2959595EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4A1A1A1 +DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEC9C9C9B2B2B2F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAF3F3F3F535353393939 +424242DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCD +A7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDA2A2A2F4F4F4FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4 +9A9A9AE6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC0C0C0 +BABABAFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDD7D7D79C9C9C9E9E9EDFDFDFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7A7A7CECECEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEFEFEBBBBBBBBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF3F3F3DDDCDCD9D9D9EDEDEDFEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBAAAAAAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBB7B7B7C3C3C3FDFDFDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF0F0F0949494F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F6F6F6A3A3A3DADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEE6E6E6F3F3F3FFFFFFFFFFFFFFFFFFFFFFFF +FDFDFDD1D1D28B94957B8D8E7A8D8F838F90C1C2C3FAFAFAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF9F9F99E9E9EDCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF7F7F7B0B0B0CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBAAAAAA +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDFA1A1A1F3F3F3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC9C9C9393939BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFD2D3D3839395A8CACCB9DEE1 +BADFE2AED2D5879C9EBBBDBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8D8D8A0A0A0 +FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF2F2F2AAAAAAD7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA4A4A4D2D2D2FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBFB8B8B8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDE8E8E8949494303030393939F2F2F2 +FFFFFFFFFFFFFFFFFFF5F4F48C9596A7C8CBBCE2E5BBE0E3BBE0E3BCE1E4B3D7DA829091 +E5E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA6A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECA6A6A6 +DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFECECEC969696F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF7F7F7A3A3A3D8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF5F5F55A5A5A6262627474744C4C4CFBFBFBFFFFFFFFFFFFFFFFFFE2E1E1 +79898BB8DDE0BBE0E3BBE0E3BBE0E3BADFE2BCE1E4849C9EC1C2C2FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE3E3E39B9B9BF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5A6A6A6E8E8E8FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6C6C6ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E1 +A0A0A0F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCDDDDDD +F1F1F1535353A2A2A2FFFFFFFFFFFFFFFFFFFFFFFFE0E0E078898BBADFE2BBE0E3BBE0E3 +BBE0E3BADFE2BCE1E4869EA0BEBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B2C2C2C2FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFDCDCDCA8A8A8EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA1A1A1D6D6D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0B5B5B5FEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F73E3E3EB4B4B4FFFFFF +FFFFFFFFFFFFFFFFFFF1F1F1869091ACCED1BCE1E4BADFE2BBE0E3BBE0E3B7DBDE809091 +DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEDEDED989898F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD2D2D2ACACACF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E9E9E9969696F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF8F8F8A5A5A5D6D6D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFBABABA262626CECECEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +C4C6C685999BB1D5D8BCE1E4BCE2E5B6DBDE8DA6A8ADB0B1FDFDFDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +BEBEBEB5B5B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8B2B2B2 +F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3B0B0B0FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE4E4E49E9E9EF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A6A6A64A4A4AFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBBEC0C1828F9082999B +839B9D7F8F90AEB1B2F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4999999E7E7E7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDBFBFBFBABABAFCFCFCFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFCFCFC9D9D9DDBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3B2B2B2 +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF888888676767FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEE8E8E8C6C6C6C1C2C2DFDEDEFCFCFCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFCBCBCBAAAAAAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFAFAFAB6B6B6C3C3C3FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6 +989898F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9A8A8A8D2D2D2FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF8F8F8696969CACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA9D9D9D +DCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F7F7F7AFAFAFCDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB4B4B4FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE5E5E59F9F9FEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +F9F9F9FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A1A1A1FBFBFBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2AAAAAAD7D7D7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFAFAFA9C9C9CDEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +C9C9C9AFAFAFFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEA6A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEBA6A6A6E0E0E0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E2999999 +F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAAAAAAACFCFCFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E39A9A9AF7F7F7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE4E4E4A6A6A6E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBBB8B8B8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E99E9E9EECECECFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +DCDCDCA8A8A8EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF9F9F9999999E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFCBCBCBADADADFBFBFBFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +ECECEC979797F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D2ADADADF4F4F4 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE9C9C9CFAFAFA +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBACACAC +CCCCCCFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEC8C8C8B3B3B3F9F9F9FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7B7B7BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB9E9E9EEAEAEAFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF5F5F5989898E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFDFDFDBFBFBFBABABAFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F8F8F8989898E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFCECECEABABABFAFAFAFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCB +AAAAAAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB +B7B7B7C3C3C3FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDB9E9E9EFBFBFBFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FCFCFCAEAEAEC9C9C9FFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9E9E9EDBDBDBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7B0B0B0CDCDCDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB3B3B3C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED9F9F9FECECEC +BABABAB6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD8D8D8A0A0A0FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2A9A9A9D7D7D7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7 +959595E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D1ADADADB4B4B4B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA6A6A6CFCFCF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFECECECA6A6A6E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6A1A1A1FCFCFCFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEFEFEB5B5B5808080B7B7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4999999F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5 +A5A5A5E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFAFAFAFC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3 +6E6E6EB3B3B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFB1B1B1C3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDCA7A7A7EFEFEFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5949494 +EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAF7F7F7FFBFBFBFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE979797EFEFEFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3ACACACF4F4F4FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3A3A3A3FDFDFDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFBABABA6C6C6CC6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEC9C9C9B3B3B3F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFABABABC8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +BABABAA8A8A8A5A5A5E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4 +9A9A9AE6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDBFBFBF +BBBBBBFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3949494EFEFEF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B8B8B8DBDBDBA5A5A5 +F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCCAAAAAAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAB7B7B7C3C3C3FDFDFDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCECECEA7A7A7FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFB6B6B6C0C0C0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF9F9F99E9E9EDCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF7F7F7B0B0B0CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFA9A9A9CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFF3F3F3A1A1A1DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A1A1A1 +FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF1F1F1AAAAAAD7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0949494F2F2F2FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +D9D9D9A3A3A3F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA6A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEBA6A6A6 +E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFCCCCCCA9A9A9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFEFEFEBABABABCBCBCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE2E2E29B9B9BF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5A5A5A5E8E8E8FFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +A5A5A5D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFF5F5F5A1A1A1DEDEDEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C2C2C2FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFDCDCDCA7A7A7EFEFEFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF949494F3F3F3FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFDCDCDCA2A2A2F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFECECEC989898F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD3D3D3ACACACF4F4F4FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFC6C6C6ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBCBC +B9B9B9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +BDBDBDB7B7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8B2B2B2 +FCFCFCC3C3C3ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA3A3A3 +D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6A3A3A3D9D9D9FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3999999E8E8E8FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDBFBFBFBEBEBEC0C0C0ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB949494F6F6F6FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE0E0E0A0A0A0F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFCACACAABABABFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFBFBFBBABABA878787ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC4C4C4B0B0B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC0C0C0B6B6B6FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F99D9D9D +DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FAFAFA8B8B8B9C9C9CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA0A0A0D8D8D8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8A4A4A4D7D7D7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6A2A2A2FBFBFBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2686868DBDBDB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8979797F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4A3A3A3F1F1F1FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEA7A7A7D2D2D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C39C9C9CAFAFAFE2E2E2FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC0C0C0B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B96D6D6D9A9A9A989898989898989898989898989898 +9898989898989999996B6B6B737373989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +9898989898989898989898989898989898989898989898989898988B8B8B5B5B5B919191 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +9A9A9A7474746969698181816868688F8F8F999999989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +9898989898989898989898989898989898989898989898989797975F5F5F808080999999 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +989898989898989898989898989898989898989898989898989898989898989898989898 +9898989898989898989898989898989B9B9B6C6C6CBCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B99D9D9DDFDFDFDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +909090B2B2B2DDDDDDDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDCDCDC939393ADADADDEDEDEDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDFDFDFA7A7A7959595E1E1E1 +C7C7C7898989CCCCCCDCDCDCDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDCDCDCC2C2C2828282D9D9D9DBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDBDB +DBDBDBDFDFDF9A9A9ABCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6A1A1A1F0F0F0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +ECECEC999999F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFD4D4D4AFAFAFF5F5F5 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +BCBCBCB8B8B8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C4B2B2B2FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDB6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF6F6F6F7F7F7 +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFEFEFEC8C8C8B3B3B3F9F9F9FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F99B9B9BDFDFDFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF9F9F9A9A9A9D1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF4F4F4989898E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAF8F8F8F9F9F9FEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE2E2E29EA3A3838D8E858F8FA7AAABEAEAEAFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFDFDFDBFBFBFBBBBBBFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE1E1E19A9A9AFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E79F9F9F +EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACA +ABABABFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEBEBEB6363633A3A3A494949CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6 +85939499B7B9ABCDD0A9CBCE94B1B38B9697E3E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB +B6B6B6C3C3C3FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7B7B7 +BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8AEAEAEFCFCFCFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA9E9E9EDCDCDCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC535353424242 +B7B7B76868683D3D3DEDEDEDFFFFFFFFFFFFF2F2F28A9495A7C9CCBDE3E6BBE1E4BCE1E4 +BDE3E69EBDBF989E9FF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7AFAFAFCDCDCDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7999999E3E3E3FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFAFAFAAAAAAACECECEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD7D7D7A1A1A1FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCB5A5A5AE0E0E0FFFFFFD7D7D7313131E5E5E5 +FFFFFFFFFFFFCFD0D0819496BBE0E3BADFE2BBE0E3BBE0E3BBE0E3B8DDE0788889E5E5E5 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2AAAAAAD6D6D6FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFDDDDDD9C9C9CFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EAEAEA9E9E9EEBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA5A5A5D0D0D0 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFDFDFDFBFBFBFEFEFEFFFFFF8B8B8B383838ECECECFFFFFFFFFFFFC0C1C1869EA0 +BBE1E4BADFE2BBE0E3BBE0E3BADFE2BBE1E47A8C8DDBDADAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEEEEEEA9A9A9E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4B4B4BFBFBF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCCABABABFBFBFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E29A9A9AF8F8F8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6 +8888884B4B4BC6C6C6FFFFFFFFFFFFFFFFFFD8D8D87F9092B9DFE2BBE0E3BADFE2BADFE2 +BBE0E3B5D9DC7A8889EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED616161 +7A7A7AEBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6979797E7E7E7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBAEAEAECACACAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFB0B0B0C3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F77777772B2B2BC6C6C6FFFFFFFFFFFF +FFFFFFFFFFFFF9F9F9989F9F9BB9BBBCE2E5BCE2E5BCE2E5BAE0E391ACAEA9ADADFDFDFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA646464030303999999ABABABEFEFEFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD9D9D99F9F9FFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFECECEC9E9E9EE9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED989898EFEFEFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF7F7F78383836C6C6CCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8 +949C9D88A1A39AB9BC98B7BA869D9E9EA4A4F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFB1B1B1414141232323BBBBBBD7D7D7ABABABF4F4F4FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAFC3C3C3FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC +E5E5E5E3E3E3F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF +AAAAAAF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFBDBDBDB6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F77A7A7A616161DCDCDC +E5E5E5E1E1E1F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F2F2BCBDBD999C9C9C9F9F +C4C5C5F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E73A3A3A8F8F8F404040 +B8B8B8FFFFFFC9C9C9B3B3B3F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF4F4F4969696EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFF2F2F28888883A3A3A343434757575DBDBDB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCB0B0B0C8C8C8FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4 +999999E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFC2C2C21B1B1B2A2A2A3232323131312D2D2DA0A0A0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF919191636363F5F5F53E3E3EB8B8B8FFFFFFFCFCFCBFBFBF +BBBBBBFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +D5D5D5A2A2A2FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFBABABA515151CDCDCDD9D9D9565656606060FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEDEDED9F9F9FE6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBABABABFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F4F4F4DDDDDDDCDCDCDBDBDBDBDBDBDADADAEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2 +2B2B2BB5B5B5EAEAEA393939ABABABFDFDFDFFFFFFFAFAFAB6B6B6C4C4C4FDFDFDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADADADC7C7C7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFE7E7E7E8E8E8 +FFFFFFFFFFFF9A9A9A555555FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD3D3D3A7A7A7F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF9F9F99E9E9EDCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFF8D8D8D0808082E2E2E3333330C0C0C +262626C4C4C4FFFFFFFFFFFFF7F7F7AFAFAFCDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF2F2F2949494EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D4959595525252C5C5C5 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB1B1B1C5C5C5 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A1A1A1 +FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFE9E9E9CECECECDCDCDC7C7C7313131949494F3F3F3FFFFFFFFFFFF +FFFFFFF2F2F2AAAAAAD7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0D0D0 +A5A5A5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB2B2B24E4E4E4C4C4CAFAFAFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F09E9E9EE4E4E4FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA6A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF8F8F8414141B9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEBA7A7A7 +E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9A9A9CBCBCBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDFDFDFD +FFFFFFFFFFFFDFDFDF404040CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD5D5D5A6A6A6F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE3E3E39B9B9BF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDCFCFCF +EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4A6A6A6E8E8E8FFFFFFFFFFFF +FFFFFFFFFFFFF0F0F0959595F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFF9C9C9C7F7F7FF8F8F8FFFFFFF6F6F63B3B3B +BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +B4B4B4C1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C3C3C3FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFDCDCDCA7A7A7EFEFEFFFFFFFFFFFFFFFFFFFCDCDCDA8A8A8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFC6C6C6383838A5A5A5C4C4C4949494656565EBEBEBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F19F9F9FE2E2E2FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFECECEC989898F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD3D3D3ABABABF5F5F5FFFFFFFEFEFEA5A5A5CFCFCFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8 +464646363636626262E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9A4A4A4F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +BDBDBDB7B7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFECACACAB2B2B2 +F9F9F9EEEEEE949494F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF5F5F5F4F4F4F8F8F8FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB8B8B8BEBEBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3999999E8E8E8FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC0C0C0BFBFBFC6C6C6ACACACFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3A1A1A1 +DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFCACACAABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF7F7F7A2A2A2747474D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDBA2A2A2F6F6F6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F99D9D9D +DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF1F1F1E0E0E0C5C5C5A6A6A6989898 +7C7C7C7A7A7AF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFBBBBBBBBBBBBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A1A1A1FBFBFBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7F7F7E9E9E9 +D3D3D3B2B2B29C9C9C979797999999AEAEAECDCDCDE2E2E29D9D9DD1D1D1FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F4F4F4A1A1A1DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEA6A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFBFBFBF0F0F0DEDEDEC0C0C0A4A4A4999999969696A1A1A1C1C1C1DADADAECECEC +FBFBFBFFFFFFFFFFFFD4D4D4A6A6A6FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDA1A1A1F4F4F4 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E29B9B9BF7F7F7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFEFEFEF6F6F6E8E8E8CECECEAFAFAF9D9D9D969696989898 +B3B3B3D0D0D0E4E4E4F6F6F6FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F69D9D9D +E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB8B8B8FEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEBABABA909090C1C1C1 +A4A4A4989898939393A6A6A6C3C3C3DBDBDBEFEFEFFDFDFDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2B4B4B4FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF6F6F6A3A3A3D9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +ECECEC979797F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD +F6F6F6E5E5E5C9C9C9AEAEAE9F9F9F6E6E6E6E6E6EB9B9B9D0D0D0E7E7E7FAFAFAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFEBEBEB9B9B9BECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E0 +A0A0A0F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDB6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEFEFEFBFBFBEEEEEED5D5D5BABABAA4A4A4929292959595ABABABC4C4C4 +E2E2E2B9B9B9ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB2B2B2C2C2C2FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1C1C1B6B6B6FDFDFDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF4F4F4989898E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF7F7F7E0E0E0C5C5C5AEAEAE989898 +909090A2A2A2B8B8B8D2D2D2EDEDEDFCFCFCFEFEFEFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFDEDEDE9F9F9FF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF9F9F9A5A5A5D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACA +ABABABFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCEAEAEA +D1D1D1B8B8B8A1A1A18E8E8E9A9A9AAEAEAEC5C5C5E2E2E2F8F8F8FDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA +A5A5A5D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE3E3E39F9F9FF1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA9E9E9EDDDDDDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF3F3F3DBDBDBC3C3C3AAAAAA939393949494A5A5A5BABABAD6D6D6F1F1F1 +FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCECECEA9A9A9FCFCFCFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C4B2B2B2 +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD7D7D7A1A1A1FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAE5E5E5CFCFCFB5B5B59B9B9B9292929E9E9E +AFAFAFCACACAE8E8E8F7F7F7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF4F4F49E9E9EE2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA7A7A7D3D3D3FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA6A6A6D0D0D0 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDEFEFEFDADADAC1C1C1 +A5A5A5939393999999A5A5A5BEBEBEDBDBDBF1F1F1FAFAFAFEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBFB7B7B7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE7E7E79E9E9EEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E29A9A9AF8F8F8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +F6F6F6E4E4E4CDCDCDB1B1B19999999696969D9D9DB2B2B2D0D0D0E8E8E8F6F6F6FEFEFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E99B9B9BEFEFEFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +C6C6C6B0B0B0FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFB0B0B0C3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFBFBFBEDEDEDDADADABCBCBCA1A1A1979797989898A6A6A6C3C3C3 +DEDEDEF0F0F0FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFEAEAEAEC8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAAAAAAAD0D0D0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED989898F0F0F0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF3F3F3E5E5E5CACACAACACAC9A9A9A +9797979B9B9BB7B7B7D3D3D3E8E8E8F7F7F7FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDBA0A0A0F8F8F8FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E89F9F9FEDEDEDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9EDEDED +D8D8D8B8B8B8A0A0A0989898959595A9A9A9C7C7C7DFDFDFF1F1F1FDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF9F9F9A3A3A3D6D6D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC9C9C9AEAEAEFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5 +999999E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFCFCFCF3F3F3E4E4E4C6C6C6A8A8A89B9B9B9393939E9E9EBBBBBBD5D5D5E9E9E9 +FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCB +AAAAAAFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBABABAB +CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACAABABABFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8F8F8EDEDEDD3D3D3B4B4B4A0A0A0949494959595 +AEAEAECACACAE1E1E1F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F19B9B9BE6E6E6FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB9E9E9EEAEAEAFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF9F9F99E9E9EDCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCF4F4F4DEDEDEC1C1C1 +A9A9A9989898909090A3A3A3BEBEBED7D7D7EEEEEEFDFDFDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFBBBBBBB9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFCDCDCDAAAAAAFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A1A1A1 +FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +F9F9F9E8E8E8CDCDCDB3B3B39E9E9E9090909B9B9BB2B2B2CBCBCBE5E5E5F9F9F9FEFEFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E79A9A9AF2F2F2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FBFBFBAEAEAECACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA6A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFDFDFDF1F1F1D8D8D8BFBFBFA8A8A8929292949494A8A8A8BEBEBE +DADADAF2F2F2FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEABABABCBCBCBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED9E9E9EE8E8E8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE3E3E39A9A9AF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9E2E2E2CACACAB2B2B29A9A9A +909090A0A0A0B3B3B3CDCDCDEAEAEAF9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +D9D9D9A2A2A2FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0D0D0A9A9A9FAFAFAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B0B0C4C4C4FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDECECEC +D5D5D5BDBDBDA4A4A49090909A9A9AA9A9A9C1C1C1DEDEDEF4F4F4FCFCFCFEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8A1A1A1DADADAFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFCFCFCB1B1B1C6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFECECEC999999F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF5F5F5DFDFDFC9C9C9AFAFAF959595959595A1A1A1B5B5B5D1D1D1EDEDED +F9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFC8C8C8ADADADFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE +9F9F9FE5E5E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +BEBEBEB6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAE9E9E9D4D4D4BABABA9E9E9E9494949B9B9B +AAAAAAC5C5C5E3E3E3F4F4F4FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9C9C9C +E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D4A7A7A7F8F8F8FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3999999E7E7E7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF1F1F1E0E0E0C7C7C7 +A9A9A9969696989898A0A0A0B9B9B9D7D7D7EDEDEDF9F9F9FEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8BDBDBDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB2B2B2C5C5C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFCACACAABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +F7F7F7E9E9E9D3D3D3B5B5B59C9C9C979797999999ACACACCBCBCBE4E4E4F3F3F3FEFEFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE4E4E49D9D9DF2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF1F1F19F9F9FE3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F99D9D9D +DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFBFBFBF1F1F1E0E0E0C1C1C1A5A5A5999999959595A1A1A1BFBFBF +DADADAECECECFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCAAAAAACCCCCCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A5A5A5 +F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6A2A2A2FBFBFBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF6F6F6EAEAEACFCFCFAFAFAF9D9D9D +969696979797B2B2B2CFCFCFE4E4E4F6F6F6FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFD6D6D6A4A4A4FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB5B5B5C1C1C1FFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEA6A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFAFAFAF2F2F2 +DCDCDCBCBCBCA4A4A4989898929292A6A6A6C3C3C3DBDBDBEFEFEFFDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7 +9F9F9FDDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF2F2F2A0A0A0E1E1E1FFFFFFFFFFFFFFFFFFE2E2E29B9B9BF7F7F7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFDFDFDF7F7F7E7E7E7CACACAADADAD9D9D9D9191919B9B9BB7B7B7D0D0D0E7E7E7 +F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFC6C6C6B0B0B0FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +DADADAA3A3A3F6F6F6FFFFFFFFFFFFB0B0B0C4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF0F0F0D6D6D6B9B9B9A4A4A4949494949494 +ABABABC4C4C4DDDDDDF3F3F3FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFEEEEEE9B9B9BEAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8BDBDBDFFFFFF +EBEBEB989898F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF7F7F7E0E0E0C5C5C5 +AEAEAE999999909090A2A2A2B8B8B8D2D2D2EBEBEBFBFBFBFEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFB5B5B5C0C0C0 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4A2A2A2DFDFDFBFBFBFB8B8B8FFFFFFFEFEFE +FCFCFCEAEAEAD1D1D1B9B9B9A1A1A19090909A9A9AADADADC5C5C5E1E1E1F6F6F6FDFDFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFE1E1E19D9D9DF5F5F5FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFDDDDDD9999998A8A8AC6C6C6C6C6C6ACACAC939393959595A5A5A5B8B8B8 +D5D5D5F0F0F0FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FBFBFBA6A6A6D1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B2 +5555559A9A9AADADADC8C8C8E7E7E7F7F7F7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFD2D2D2A6A6A6FBFBFBFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9B0B0B0C1C1C1FEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2AEAEAEF9F9F99D9D9DE0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF7F7F7B2B2B2CCCCCCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2AFAFAFC6C6C6 +B3B3B3FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF2F2F2ADADADD4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C49A9A9AA0A0A0EDEDEDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEA9A9A9 +DBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC4C4C4626262C8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8A9A9A9E1E1E1FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF737373F9F9F9 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE4E4E4A7A7A7E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDFDFD828282A5A5A5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFDEDEDEA9A9A9ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +D3D3D36D6D6DABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7ABABAB +F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4A2A2A2A6A6A6AEAEAEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0D0D0AEAEAEF5F5F5FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFBEBEBEBABABAC3C3C3ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEFEFECACACAB2B2B2F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA9A9A9A +F3F3F3C3C3C3ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FDFDFDC2C2C2B9B9B9FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFEFEFDFCFCF1F1F1F7F7F7FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEAFAFAFC6C6C6FFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBBCBCBCBEBEBE +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFCCCCDCD888F8F7F898A7F8889 +A6AAAAEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFDCDCDC9F9F9FF7F7F7FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAB5B5B5C6C6C6FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBCBC868686FBFBFB +FFFFFFFFFFFFFEFEFEBBBDBE879A9CA7C8CBB2D6D9AFD3D694B0B3929A9BEDEDEDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA3A3A3D7D7D7FFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF6F6F6B1B1B1CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFBCBCBC1F1F1F7E7E7EFFFFFFFFFFFFFFFFFFDFDFDF829293 +B3D7DABCE1E4BBE0E3BBE0E3BCE2E594B0B2A6AAAAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFCCCCCCAAAAAAFDFDFDFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F3F3F3ADADADD4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB +585858232323B1B1B1FFFFFFFFFFFFFFFFFFB4B6B68CA6A8BCE2E5BADFE2BBE0E3BBE0E2 +BBE0E3B1D5D87C8687F6F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3 +9C9C9CE5E5E5FFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEAAAAAADADADA +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBCBC5C5C5CA9A9A9484848D6D6D6FFFFFF +FFFFFFFFFFFFA6AAAA93B0B2BCE1E5BADFE2BBE0E3BBE0E3BADFE2B6DADD798586EFEFEF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBBBABABAFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9A8A8A8E2E2E2FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFBDBDBD5A5A5AD8D8D8ADADAD464646FCFCFCFFFFFFFFFFFFFFFFFFC3C4C4869C9E +BCE2E5BBE0E3BADFE2BADFE2BCE1E4A9CCCF848D8EFAF9F9FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE7E7E79B9B9BF1F1F1FFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE3E3E3A8A8A8E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C34D4D4DC6C6C6F4F4F4 +767676414141F8F8F8FFFFFFFFFFFFFFFFFFF1F0F08D9798A2C3C6BDE3E6BDE2E5BDE3E6 +B7DBDE869C9EC4C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDACACACCACACA +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +DEDEDEA9A9A9ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF8B8B8B1818183838383434340B0B0B131313C3C3C3FFFFFF +FFFFFFFFFFFFFFFFFFDDDEDE8E9899869D9F94B1B38EA9AB819394B5B8B8FAFAFAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9A1A1A1F8F8F8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7ABABABF1F1F1 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E7E7E7C9C9C9C9C9C9C1C1C1313131949494F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EEEEEEC0C1C1A6A9A9B0B2B2D8D8D8FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F8F8F8A1A1A1D9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D1AEAEAEF5F5F5FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8 +4D4D4DEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C9ADADADFDFDFDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEFEFEC9C9C9B3B3B3F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5CFCFCFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF0F0F09B9B9BE8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD +C2C2C2B8B8B8FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8 +BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCBCBCBCBEBEBEFCFCFC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E49D9D9DF3F3F3FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9B5B5B5C6C6C6FEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFCFCFCAAAAAACDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF6F6F6B1B1B1CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D5A4A4A4FAFAFA +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3 +ADADADD3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF7F7F79F9F9FDEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEAAAAAADBDBDBFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +C5C5C5B0B0B0FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9A7A7A7E2E2E2FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE9B9B9BEAEAEAFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE3E3E3A8A8A8E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB6B6B6BFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD +A8A8A8EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E29D9D9D +F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7ABABABF0F0F0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA7A7A7D0D0D0FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFED0D0D0AEAEAEF4F4F4FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD3D3D3A5A5A5FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEC9C9C9B3B3B3F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F69D9D9DE0E0E0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC3C3C3 +B8B8B8FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFC3C3C3B2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCBBBBBBBFBFBFFCFCFCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC +9A9A9AEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF9F9F9B6B6B6C5C5C5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB2B2B2C3C3C3FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF7F7F7B0B0B0CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFDFDFDF9E9E9EF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3ADADAD +D3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA5A5A5D3D3D3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFA9A9A9DADADAFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCFA9A9A9FBFBFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE9E9E9A9A9A9E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F4F4F49E9E9EE2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE3E3E3A8A8A8E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0B5B5B5FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDA9A9A9 +ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE9E9E99C9C9CEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7ABABABF0F0F0FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB0B0B0 +C7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFD0D0D0AFAFAFF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDCA0A0A0F7F7F7FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFECACACAB3B3B3F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF9F9F9A3A3A3D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCC3C3C3B9B9B9 +FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCCAAAAAAFDFDFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCBBBBBBBFBFBFFCFCFCFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF2F2F29B9B9BE5E5E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF9F9F9B6B6B6C5C5C5FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +BABABAB9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F6F6F6B0B0B0CDCDCDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E89B9B9BF1F1F1FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3ADADADD3D3D3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEFEFEACACACCACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFAAAAAAD9D9D9FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADAA1A1A1 +F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEAEAEAA8A8A8E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9A1A1A1DADADAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E4E4E4A7A7A7E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC9C9C9ADADADFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDA9A9A9EDEDED +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F19C9C9CE7E7E7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7ABABABF2F2F2FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD0D0D0AFAFAFF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5 +9C9C9CF1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +C9C9C9B3B3B3F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCAAAAAACCCCCCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC2C2C2B9B9B9FBFBFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD7D7D7A3A3A3F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBBCBCBCBEBEBEFCFCFCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7A0A0A0DCDCDC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF9F9F9B6B6B6C6C6C6FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6C6C6B0B0B0FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6 +B1B1B1CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EEEEEE9C9C9CE9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3ADADADD3D3D3FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6B6B6BFBFBFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFAAAAAADADADAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE2E2E29E9E9EF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEAEAEAA8A8A8E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBA7A7A7 +D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4 +A8A8A8E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3A5A5A5FAFAFAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDA9A9A9EDEDEDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF5F5F59E9E9EDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6ABABABF1F1F1FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2B2B2B2FEFEFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD0D0D0AFAFAFF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFECECEC9A9A9AEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEC9C9C9 +B3B3B3F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B3B3B3C2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC2C2C2B8B8B8FBFBFBFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E09E9E9EF6F6F6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFBFBFBBCBCBCBFBFBFFCFCFCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFBFBFBA5A5A5D3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFAFAFAB5B5B5C6C6C6FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCFA8A8A8 +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B9B9B9B5B5B5FFFFFFFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFEFEF6F6F6B0B0B0 +CCCCCCFEFEFEFEFEFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFEFEFEF4F4F49C9C9CE2E2E2FFFFFFFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFFFFFFC2C2C2ACACACFFFFFF +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFFFFFFB2B2B2BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6C6C67272728D8D8D8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8D8D8D8080806262627777778C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C6D6D6D6161618B8B8B8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8D8D8D7676766E6E6E8D8D8D8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8D8D8D727272C8C8C8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFBFBFBEFEFEFEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEEEEEEE4E4E49C9C9CC9C9C9EFEFEFEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEEEEEED9D9D98F8F8FE2E2E2EEEEEE +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEEEEEEEFEFEFEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEFEFEFFBFBFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFEBEBEBA9A9A9E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEFEFEB1B1B1C5C5C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4A8A8A8 +E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD +A0A0A0F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDEA8A8A8EDEDEDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA5A5A5D5D5D5FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFD6D6D6ACACACF1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFCDCDCDAAAAAAFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD0D0D0AEAEAEF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F39D9D9DE4E4E4 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C9B3B3B3 +F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDB8B8B8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC2C2C2B9B9B9FAFAFAFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E8E8E89B9B9BF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFBFBFBBBBBBBBFBFBFFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDADADADC8C8C8FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F9F9F9B6B6B6C5C5C5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD9D9D9A1A1A1F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6B0B0B0CDCDCD +FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8A1A1A1 +D9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3ACACACD4D4D4FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C9ACACACFDFDFDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEFEFEFAAAAAADADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF0F0F09B9B9BE8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EAEAEAA8A8A8E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9BCBCBCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5A7A7A7E6E6E6 +FFFFFFFFFFFFFFFFFFFFFFFFE5E5E59C9C9CF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDEA9A9A9EBEBEBFFFFFFFFFFFFFDFDFD +AAAAAACDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD7D7D7ABABABF1F1F1FFFFFFD6D6D6A4A4A4FAFAFAFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +D0D0D0AFAFAFEEEEEEA0A0A0DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCB8C8C8CAEAEAE +FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBC8C8C8ECECECFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + +end +%%PageTrailer +%%Trailer +%%EOF diff --git a/doc/doxygen/figures/NonCoincident_small.png b/doc/doxygen/figures/NonCoincident_small.png new file mode 100644 index 000000000..aabe93bf2 Binary files /dev/null and b/doc/doxygen/figures/NonCoincident_small.png differ diff --git a/doc/doxygen/figures/SampGeo2D1.eps b/doc/doxygen/figures/SampGeo2D1.eps new file mode 100644 index 000000000..3d2234264 --- /dev/null +++ b/doc/doxygen/figures/SampGeo2D1.eps @@ -0,0 +1,131 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: SampGeo2D1.fig +%%Creator: fig2dev Version 3.2 Patchlevel 5-alpha7 +%%CreationDate: Mon Jul 28 11:05:25 2008 +%%For: geay@is205327 (Anthony GEAY - SFME/LGLS) +%%BoundingBox: 0 0 844 468 +%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 468 moveto 0 0 lineto 844 0 lineto 844 468 lineto closepath clip newpath +-13.4 552.9 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06299 0.06299 sc +% +% Fig objects follow +% +% +% here starts figure with depth 50 +% Polyline +0 slj +0 slc +7.500 slw +n 6982 8765 m + 6185 7386 l gs col0 s gr +% Polyline +n 225 8659 m + 225 8366 l gs col0 s gr +% Arc +n -2044.5 -6869.0 16460.0 60.0017 30.0004 arcn +gs col0 s gr + +% Arc +n -2044.5 -6869.0 18052.0 29.9999 59.9993 arc +gs col0 s gr + +% Arc +n 225.0 -5558.0 13924.0 90.0000 60.0010 arcn +gs col0 s gr + +% Arc +n 225.0 -5558.0 14216.5 60.0012 90.0000 arc +gs col0 s gr + +% Polyline +n 12210 1361 m + 13589 2157 l gs col0 s gr +% Polyline +n 7187 6501 m + 7333 6754 l gs col0 s gr +% here ends figure; +$F2psEnd +rs +showpage +%%Trailer +%EOF diff --git a/doc/doxygen/figures/SampGeo2D1.png b/doc/doxygen/figures/SampGeo2D1.png new file mode 100644 index 000000000..4f48e7928 Binary files /dev/null and b/doc/doxygen/figures/SampGeo2D1.png differ diff --git a/doc/doxygen/figures/SampGeo2D2.eps b/doc/doxygen/figures/SampGeo2D2.eps new file mode 100644 index 000000000..fbf9b8a6a --- /dev/null +++ b/doc/doxygen/figures/SampGeo2D2.eps @@ -0,0 +1,146 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: SampGeo2D2.fig +%%Creator: fig2dev Version 3.2 Patchlevel 5-alpha7 +%%CreationDate: Mon Jul 28 11:25:21 2008 +%%For: geay@is205327 (Anthony GEAY - SFME/LGLS) +%%BoundingBox: 0 0 844 468 +%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 468 moveto 0 0 lineto 844 0 lineto 844 468 lineto closepath clip newpath +0.8 467.8 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06299 0.06299 sc +% +% Fig objects follow +% +% +% here starts figure with depth 50 +% Arc +7.500 slw +0 slc +n -2269.5 -8219.0 16460.0 60.0017 58.7158 arcn +gs col0 s gr + +% Arc +n -2269.5 -8219.0 16460.3 58.7158 55.4365 arcn +gs col0 s gr + +% Arc +n -2269.5 -8219.0 16459.1 55.4365 30.0004 arcn +gs col0 s gr + +% Arc +n -2269.5 -8219.0 18052.0 29.9999 59.9993 arc +gs col0 s gr + +% Arc +n 0.0 -6908.0 13924.0 90.0000 60.0010 arcn +gs col1 s gr + +% Arc +n 0.0 -6908.0 14216.5 60.0012 63.7954 arc +gs col0 s gr + +% Arc +n 0.0 -6908.0 14217.2 63.7954 90.0000 arc +gs col0 s gr + +% Polyline +0 slj +n 11985 11 m + 13364 807 l gs col0 s gr +% Polyline +n 6757 7415 m + 5960 6036 l gs col0 s gr +% Polyline +n 6962 5151 m + 7068 5335 l gs col0 s gr +% Polyline +n 7068 5335 m + 7108 5404 l gs col0 s gr +% Polyline +n 0 7309 m + 0 7016 l gs col1 s gr +% here ends figure; +$F2psEnd +rs +showpage +%%Trailer +%EOF diff --git a/doc/doxygen/figures/SampGeo2D2.png b/doc/doxygen/figures/SampGeo2D2.png new file mode 100644 index 000000000..c9d22ff8a Binary files /dev/null and b/doc/doxygen/figures/SampGeo2D2.png differ diff --git a/doc/doxygen/figures/SampGeo2D3.eps b/doc/doxygen/figures/SampGeo2D3.eps new file mode 100644 index 000000000..71fd7b3d6 --- /dev/null +++ b/doc/doxygen/figures/SampGeo2D3.eps @@ -0,0 +1,146 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: SampGeo2D3.fig +%%Creator: fig2dev Version 3.2 Patchlevel 5-alpha7 +%%CreationDate: Mon Jul 28 11:18:27 2008 +%%For: geay@is205327 (Anthony GEAY - SFME/LGLS) +%%BoundingBox: 0 0 844 468 +%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 468 moveto 0 0 lineto 844 0 lineto 844 468 lineto closepath clip newpath +0.8 467.8 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06299 0.06299 sc +% +% Fig objects follow +% +% +% here starts figure with depth 50 +% Arc +7.500 slw +0 slc +n -2269.5 -8219.0 16460.0 60.0017 58.7158 arcn +gs col0 s gr + +% Arc +n -2269.5 -8219.0 16460.3 58.7158 55.4365 arcn +gs col0 s gr + +% Arc +n -2269.5 -8219.0 16459.1 55.4365 30.0004 arcn +gs col0 s gr + +% Arc +n -2269.5 -8219.0 18052.0 29.9999 59.9993 arc +gs col0 s gr + +% Arc +n 0.0 -6908.0 13924.0 90.0000 60.0010 arcn +gs col1 s gr + +% Arc +n 0.0 -6908.0 14216.5 60.0012 63.7954 arc +gs col2 s gr + +% Arc +n 0.0 -6908.0 14217.2 63.7954 90.0000 arc +gs col1 s gr + +% Polyline +0 slj +n 11985 11 m + 13364 807 l gs col0 s gr +% Polyline +n 6757 7415 m + 5960 6036 l gs col0 s gr +% Polyline +n 6962 5151 m + 7068 5335 l gs col1 s gr +% Polyline +n 7068 5335 m + 7108 5404 l gs col2 s gr +% Polyline +n 0 7309 m + 0 7016 l gs col1 s gr +% here ends figure; +$F2psEnd +rs +showpage +%%Trailer +%EOF diff --git a/doc/doxygen/figures/SampGeo2D3.png b/doc/doxygen/figures/SampGeo2D3.png new file mode 100644 index 000000000..ddb0cd7fb Binary files /dev/null and b/doc/doxygen/figures/SampGeo2D3.png differ diff --git a/doc/doxygen/figures/SampGeo2D4.eps b/doc/doxygen/figures/SampGeo2D4.eps new file mode 100644 index 000000000..036447b2b --- /dev/null +++ b/doc/doxygen/figures/SampGeo2D4.eps @@ -0,0 +1,114 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: SampGeo2D4.fig +%%Creator: fig2dev Version 3.2 Patchlevel 5-alpha7 +%%CreationDate: Mon Jul 28 11:32:45 2008 +%%For: geay@is205327 (Anthony GEAY - SFME/LGLS) +%%BoundingBox: 0 0 844 521 +%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 521 moveto 0 0 lineto 844 0 lineto 844 521 lineto closepath clip newpath +0.5 522.3 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06299 0.06299 sc +% +% Fig objects follow +% +% +% here starts figure with depth 50 +% Arc +7.500 slw +0 slc +n -101040.6 -197010.0 228811.3 60.0003 63.7947 arc +gs col2 s gr + +% Arc +n -137567.0 -218110.0 264913.0 58.7153 55.4354 arcn +gs col2 s gr + +% Polyline +0 slj +n 12727 42 m + 13364 1147 l gs col2 s gr +% here ends figure; +$F2psEnd +rs +showpage +%%Trailer +%EOF diff --git a/doc/doxygen/figures/SampGeo2D4.png b/doc/doxygen/figures/SampGeo2D4.png new file mode 100644 index 000000000..adc7b55e7 Binary files /dev/null and b/doc/doxygen/figures/SampGeo2D4.png differ diff --git a/doc/doxygen/figures/UML-0.png b/doc/doxygen/figures/UML-0.png new file mode 100644 index 000000000..ce143b48d Binary files /dev/null and b/doc/doxygen/figures/UML-0.png differ diff --git a/doc/doxygen/figures/UML-1.png b/doc/doxygen/figures/UML-1.png new file mode 100644 index 000000000..f5b8fcf07 Binary files /dev/null and b/doc/doxygen/figures/UML-1.png differ diff --git a/doc/doxygen/figures/UML-2.png b/doc/doxygen/figures/UML-2.png new file mode 100644 index 000000000..30940d893 Binary files /dev/null and b/doc/doxygen/figures/UML-2.png differ diff --git a/doc/doxygen/figures/UML-3.png b/doc/doxygen/figures/UML-3.png new file mode 100644 index 000000000..dbb152466 Binary files /dev/null and b/doc/doxygen/figures/UML-3.png differ diff --git a/doc/doxygen/figures/UML-4.png b/doc/doxygen/figures/UML-4.png new file mode 100644 index 000000000..0c78ad753 Binary files /dev/null and b/doc/doxygen/figures/UML-4.png differ diff --git a/doc/doxygen/figures/UML-5.png b/doc/doxygen/figures/UML-5.png new file mode 100644 index 000000000..f251b5a59 Binary files /dev/null and b/doc/doxygen/figures/UML-5.png differ diff --git a/doc/doxygen/figures/UML-6.png b/doc/doxygen/figures/UML-6.png new file mode 100644 index 000000000..9cdcfaa75 Binary files /dev/null and b/doc/doxygen/figures/UML-6.png differ diff --git a/doc/doxygen/figures/UML-7.png b/doc/doxygen/figures/UML-7.png new file mode 100644 index 000000000..d316de52c Binary files /dev/null and b/doc/doxygen/figures/UML-7.png differ diff --git a/doc/doxygen/figures/UML-8.png b/doc/doxygen/figures/UML-8.png new file mode 100644 index 000000000..a43d2c1b7 Binary files /dev/null and b/doc/doxygen/figures/UML-8.png differ diff --git a/doc/doxygen/figures/UML.png b/doc/doxygen/figures/UML.png new file mode 100644 index 000000000..28418d122 Binary files /dev/null and b/doc/doxygen/figures/UML.png differ diff --git a/doc/doxygen/figures/UML_light.png b/doc/doxygen/figures/UML_light.png new file mode 100644 index 000000000..8eff5fa9c Binary files /dev/null and b/doc/doxygen/figures/UML_light.png differ diff --git a/doc/doxygen/figures/UML_small.png b/doc/doxygen/figures/UML_small.png new file mode 100644 index 000000000..77109ab34 Binary files /dev/null and b/doc/doxygen/figures/UML_small.png differ diff --git a/doc/doxygen/figures/connectivity_arrays.eps b/doc/doxygen/figures/connectivity_arrays.eps new file mode 100644 index 000000000..fdbdfbe38 --- /dev/null +++ b/doc/doxygen/figures/connectivity_arrays.eps @@ -0,0 +1,19480 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: (ImageMagick) +%%Title: (connectivity_arrays.eps) +%%CreationDate: (Thu Nov 29 18:16:01 2007) +%%BoundingBox: 0 0 720 540 +%%HiResBoundingBox: 0 0 719.91 540 +%%DocumentData: Clean7Bit +%%LanguageLevel: 1 +%%Pages: 1 +%%EndComments + +%%BeginDefaults +%%EndDefaults + +%%BeginProlog +% +% Display a color image. The image is displayed in color on +% Postscript viewers or printers that support color, otherwise +% it is displayed as grayscale. +% +/DirectClassPacket +{ + % + % Get a DirectClass packet. + % + % Parameters: + % red. + % green. + % blue. + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + compression 0 eq + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/DirectClassImage +{ + % + % Display a DirectClass image. + % + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { DirectClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayDirectClassPacket } image + } ifelse +} bind def + +/GrayDirectClassPacket +{ + % + % Get a DirectClass packet; convert to grayscale. + % + % Parameters: + % red + % green + % blue + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 eq + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/GrayPseudoClassPacket +{ + % + % Get a PseudoClass packet; convert to grayscale. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 eq + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassPacket +{ + % + % Get a PseudoClass packet. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + compression 0 eq + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassImage +{ + % + % Display a PseudoClass image. + % + % Parameters: + % class: 0-PseudoClass or 1-Grayscale. + % + currentfile buffer readline pop + token pop /class exch def pop + class 0 gt + { + currentfile buffer readline pop + token pop /depth exch def pop + /grays columns 8 add depth sub depth mul 8 idiv string def + columns rows depth + [ + columns 0 0 + rows neg 0 rows + ] + { currentfile grays readhexstring pop } image + } + { + % + % Parameters: + % colors: number of colors in the colormap. + % colormap: red, green, blue color packets. + % + currentfile buffer readline pop + token pop /colors exch def pop + /colors colors 3 mul def + /colormap colors string def + currentfile colormap readhexstring pop pop + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { PseudoClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayPseudoClassPacket } image + } ifelse + } ifelse +} bind def + +/DisplayImage +{ + % + % Display a DirectClass or PseudoClass image. + % + % Parameters: + % x & y translation. + % x & y scale. + % label pointsize. + % image label. + % image columns & rows. + % class: 0-DirectClass or 1-PseudoClass. + % compression: 0-none or 1-RunlengthEncoded. + % hex color packets. + % + gsave + /buffer 512 string def + /byte 1 string def + /color_packet 3 string def + /pixels 768 string def + + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + x y translate + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + currentfile buffer readline pop + token pop /pointsize exch def pop + /Times-Roman findfont pointsize scalefont setfont + x y scale + currentfile buffer readline pop + token pop /columns exch def + token pop /rows exch def pop + currentfile buffer readline pop + token pop /class exch def pop + currentfile buffer readline pop + token pop /compression exch def pop + class 0 gt { PseudoClassImage } { DirectClassImage } ifelse + grestore +} bind def +%%EndProlog +%%Page: 1 1 +%%PageBoundingBox: 0 0 720 540 +userdict begin +DisplayImage +0 0 +719.91 539.933 +12.000000 +960 720 +1 +1 +1 +8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000 +000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF +FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000 +FFFFFFFFFFFF0000FFFFFF0000FFFF00000000FFFFFFFFFFFFFFFF0000000000FFFFFFFF +FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF00 +00FF000000000000FFFFFFFFFFFF00000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFF00000000FFFFFF000000FFFFFF +FF000000FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF00 +00FFFFFFFF0000FFFFFFFF000000FFFFFFFFFF000000FFFF0000FFFFFFFFFFFF000000FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFF00 +00FFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFF +0000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +0000FFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFF0000000000000000000000FF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFF00 +00FFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFF00 +000000FFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FF0000 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFF0000FF0000FFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF +FFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FF000000000000FFFFFFFFFFFF0000 +0000000000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FF00000000FFFFFFFFFFFF000000FFFFFFFFFF0000FFFFFF000000FFFFFFFFFFFF0000FF +FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFF +FF0000FFFFFFFF00000000FFFFFF000000FFFFFFFF000000FFFFFF000000FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFF00 +000000FFFFFF000000FFFFFFFF000000FFFFFF000000FFFFFFFFFFFFFFFFFFFFFF0000FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFF000000FFFF +FFFFFF000000FFFF0000FFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFF0000FF000000000000FFFFFFFF +FFFF00000000000000FFFFFFFFFFFFFFFFFFFFFF0000000000000000000000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF +FFFFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFFFF0000FFFF0000FFFF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFF0000FFFFFFFFFFFFFF0000FFFF00000000FFFFFFFFFFFFFFFF0000000000FFFFFFFF +FFFFFFFFFFFFFFFF0000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF0000FFFFFF +0000FFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFF0000000000000000000000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF00 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFF0000FFFFFF +FFFFFFFF0000FFFF0000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF +FFFFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFF0000FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF0000FF +0000FFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF00 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFF000000FFFF +FFFFFF0000FFFFFF000000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF +FFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFF00000000FFFFFF000000FFFFFFFF000000 +FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000 +00FFFFFFFFFFFF0000FF000000000000FFFFFFFFFFFF00000000000000FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFF00 +000000FFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97EF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20BFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFDF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF10AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC700E7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF009F +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB700DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE70087FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF8F00AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFDF007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF504070FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF0060 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10BF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F2840FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFBF40FF20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF609710F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF609FFF7F7FFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20DF40 +BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF710F7FFDF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF20FF708FFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF7F7FFFFFFF609FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF9F60FFAF50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE720F7FFFFFFE720F7FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF609FFFEF +18F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF6897FFFFFFFFFF7887FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF710F7FFFF50AFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFAF50FFFFFFFFFFFFF740C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF9768FFFFFFBF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE730E7FFFFFFFFFFFFFFD730 +F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFF +FF28D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFF748BFFFFFFFFFFFFFFFFFFFA758FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF30FFFFFFFFFF8F70FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF750 +B7FFFFFFFFFFFFFFFFFFFFFF9768FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF6897FFFFFFFFFFEF18F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7589FFFFFFFFFFFFFFFFFFFFFFFFF +FF7F70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF30FFFFFFFFFF +FFFF8F70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFDF38A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F40EFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF30CFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF9768FFFFFFFFFFFFFFFFFFC738FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9740EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFDF38AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE728EFFFFFFFFFFFFF +FFFFFFFF6897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFEF6868FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7507FF7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFF750B7FFFFFFFFFFFFFFFFFFFFFFEF40CFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F2897FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F28A7FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF609FFFFFFFFFFFFFFFFFFFFFFFFFFFDF40DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFAF2870E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFDF5838BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF708FFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFDF30EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7 +4050D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC740 +50D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF787FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF38E7FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB75038BFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF2868C7FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE738 +87FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF28B7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD7701848AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF9738207FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF28C7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEF4878F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE78F28288FE7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFDF7F203897EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFB75050EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +3097EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFD7A778381870D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC76810407F +AFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF8F2048AFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7682068D7FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFAF7F400828 +5887C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF7F502010487FB7E7FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFAF7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F5840101070DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF97280038407F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F9FBFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFBFBFBFAF7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7040404020000020507FBFF7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFEFB77F4818000028404040787F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7FB7BFBFCFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFA750080040507F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7FA7BFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC7BF7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F604018003887E7FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC797684018000000404040507F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F8F +BFBFBFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD7BFBFBF877F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F +7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F484040300000002040709FCFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE77F1858 +AFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7782060C7FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFCF9F703800386897BFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFDFBF8F6030084078A7D7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F207FE7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFF79F3858EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7701830608FC7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF7BF8758282887E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFEF5860F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFA738C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFE79730288FE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +7818489FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC730A7FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7408FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7501868CFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7601060BFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF38DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7707FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB73058AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79F4040CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFDF30EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF609FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFCF4048CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFBF3058DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE738DFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50AFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE76030BFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA72870 +EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEF40CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF750B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF7F209FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78F2097FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +6897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFE728EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF507F +F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEF6868F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC738FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F70FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD738AFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF9748EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFF738CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFB738D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF30CFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8778 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFCF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F48EFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF38AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE720F7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF609F +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7070FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF7509FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF30FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48B7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18E7FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF38C7FFFFFFFFFFFFFFFFFFFFFFFFFFFF9F60FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF748BFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +58FFFFFFFFFFFFFFFFFFFFFFFFFFC740F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFE730E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF50AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF720E7FFFFFFFFFFFFFFFFFFFF +FFEF30DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF40FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE718FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF7887FFFFFFFFFFFFFFFFFFFFFF609FFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6897FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +AF50FFFFFFFFFFFFFFFFFFFFCF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFEF28E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF6897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF10FFFFFFFFFFFFFFFFFFFF +40BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFBF40FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF720E7FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF10FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF6897FFFFFFFFFFFFFFFF58A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF708FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFAF50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F60FFFFFFFFFFFFFFEF18 +F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +D728FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7FFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFD728FFFFFFFFFFFFFF9F60FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF609FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFDF20FFFFFFFFFFFFFF6897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF708FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF58A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00000000000000000000000000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000 +0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF30CF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000FFFFFF00 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000FFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF9F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40BFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000 +000000000000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000FFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF08F7FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00000000000000000000000000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000 +0000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00000000000000000000000000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD728FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF20DFFFFFFFFFFFDF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF000000FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFE718FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000 +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFCF30FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78F7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000000000FFFFFFFFFFFF0000FFFF000000FF +FFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FF0000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FF0000000000FFFFFFFFFFFF0000FFFF000000FFFFFF00000000FFFFFFFFFFFFFFFFFFFF +FFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF87E7FFFFFFFFFFDF8FFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000000000 +FFFFFFFFFFFF0000FFFF000000FFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000000000FFFFFFFF +FFFF0000FFFF000000FFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF000000 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF +FFFFFFFF00000000000000FFFFFFFFFF0000000000000000FF000000000000FFFFFFFFFF +FFFFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF00000000000000FFFFFFFFFF +0000000000000000FF000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF00000000000000FFFFFFFFFF000000000000 +0000FF000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFF00000000000000FFFFFFFFFF0000000000000000FF00 +0000000000FFFFFFFFFFFFFFFFFFFFFFFF0000FF000000000000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF000000FFFFFF000000 +FFFFFFFF000000FFFFFF00000000FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFFFFFFFF0000FFFFFFFF000000FFFFFF000000FFFFFFFF000000FFFFFF00000000FFFF +FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFFFF000000FFFFFF000000FFFFFFFF000000FFFFFF00000000FFFFFF000000FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FF000000FFFFFF000000FFFFFFFF000000FFFFFF00000000FFFFFF000000FFFFFFFFFFFF +FFFFFFFFFF00000000FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000 +0000000000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFF000000FFFFFF0000FFFFFFFFFF00 +00FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000FFFFFFFF0000FFFFFF0000 +FFFFFFFFFFFF000000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF000000000000000000000000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFF +000000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF000000000000000000000000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFF000000FF +FFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000FFFFFFFF0000FF +FFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF000000000000000000000000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFF +0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000 +00000000000000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFF +FF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000 +000000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFF0000FF +FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF00000000000000000000 +00FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFFFFFFFF0000FFFFFF0000000000000000000000FFFFFF0000FFFFFFFFFF0000FFFFFF +FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFF0000000000000000000000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +0000000000000000000000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFF0000FFFFFF0000000000000000000000FFFFFF0000FFFFFFFFFF00 +00FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000 +000000000000000000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000000000000000 +000000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000000000000000000000FF +FFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF +FFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF +FF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FF +FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFF +FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFF +FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFF +FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFF0000FFFFFF000000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFF00 +00FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000 +00FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFF +FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF000000FFFFFFFFFF +FF0000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF000000FF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF000000FFFFFFFFFFFF0000FF +FFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FF +FFFFFF000000FFFFFF000000FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF000000FFFFFF000000FFFFFFFF +0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF000000FFFFFF000000FFFFFFFF0000FFFFFFFF +FF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFF000000FFFFFF000000FFFFFFFF0000FFFFFFFFFF0000FF +FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00000000000000000000000000FFFFFF0000FFFFFFFFFF00000000000000FF +FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000 +0000FFFFFF0000FFFFFFFFFF00000000000000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFF +FFFF0000FFFFFFFFFFFFFFFFFFFF0000000000000000000000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000FFFFFF00 +00FFFFFFFFFF00000000000000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFF +FFFFFFFFFFFFFFFFFFFF00000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000FFFFFF0000FFFFFF +FFFF00000000000000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF000000FFFFFFFF00FFFFFFFF000000FFFF +FFFF00FF000000FFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000 +000000000000FFFFFF0000FFFFFFFFFFFF0000000000FFFFFFFFFFFF0000FFFFFFFFFF00 +00FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000FFFFFF0000FFFFFFFFFF +FF0000000000FFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFF +FFFF0000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00000000000000000000000000FFFFFF0000FFFFFFFFFFFF0000000000 +FFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF00 +00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00000000000000000000000000FFFFFF0000FFFFFFFFFFFF0000000000FFFFFFFF +FFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FF0000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000FFFFFF0000FFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF00 +FFFF00FFFF00FFFFFFFFFF00FFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF00FFFF00FFFF00FFFFFFFFFF00 +FFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00000000000000FFFF00FFFF00000000000000FFFF00FFFFFFFF00FFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFF00FFFF00FFFFFFFFFFFFFFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF00FFFF00FFFF00FFFFFFFFFF00 +FFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFFFF00FFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFF +FFFF00FFFFFFFF000000FFFFFFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFC7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFCFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF409F +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7FFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFF700F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF409FFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF6868FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF00DFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF8F30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF308FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF6060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC700C7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF207F +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5858FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFB700B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0860FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF3030FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F107FFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF3808D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFCF1030FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF0808F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF407F40FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF710589FFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA75808 +F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD72830CFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFF710EF10F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFBF409F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF708F38C7FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF9F60708FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF40FF38C7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF7F7FD728FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF20DF7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF58A7B748FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50AFFFAF50FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF720E7FF50AFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD728FFCF +30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF710F7F710F7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE718FFFFFF18E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFA758FFFFB748FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7FFFFF20DFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFAF50FFFF50AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF708FFFFFFF8F +70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF30CFFFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFF720E7FFFF8F70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +40BFFFFFBF40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC738FFFFFFFFF738CFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9768FFFFFFFFC738FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F70FFFFFF +F720E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF30FFFFFFFF30CFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFF730D7FFFFFFFFFFCF38F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFE728EFFFFFFFFFFF6897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF720E7FFFFFFFF8778FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF48B7FFFFFFFFB748FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF609FFFFFFFFFFFFF +FF8778FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +AFFFFFFFFFFFFFE738DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF6897FFFFFFFFFFFF40BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F70 +FFFFFFFFFFFF708FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF609FFFFFFFFFFFFFFFFFFF7F7FFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF609FFFFFFFFFFFFFFFFFDF40DFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50FFFFFFFFFF +FFFFE728DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC740F7FFFFFFFFFFFFF740C7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFEF589FFFFFFFFFFFFFFFFFFFFFFF7F60EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFEF589FFFFFFFFFFFFFFFFFFFFFDF30C7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50F7FFFFFFFFFFFFFFFFD740DFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFC740EFFFFFFFFFFFFFFFFFEF40CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB728A7FFFFFFFFFFFFFFFFFF +FFFFFFFF9F28B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB728A7FFFF +FFFFFFFFFFFFFFFFFFFFD73878FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFDF5050F7FFFFFFFFFFFFFFFFFFFFDF287FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE76838EFFFFF +FFFFFFFFFFFFFFFFEF3068E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEF972848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7482897EFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79F3848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +871878DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B77F50404040404040404040404040404040404040 +404040404040404040404040404040404040404040404040402820AFFFFFFFFFFFFFFFFF +FFFFFFFFFFF77F0838404040404040404040404040404040404040404040404040404040 +404040404040404040404040404040406887CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFC77F584040404040404040404040404040404040404040404040404040 +4040404040404040404040404040404040301897FFFFFFFFFFFFFFFFFFFFFFFFFFFF9718 +304040404040404040404040404040404040404040404040404040404040404040404040 +4040404040404040607FC7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFDFB77F78404040404040404040404040404040404040404040404040404040404040 +4040404040404040404040404040404040404040404040404040404040404040181068D7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD768101840404040404040404040404040 +404040404040404040404040404040404040404040404040404040404040404040404040 +40404040404040404040404040787FB7DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFDFAF7F704040404040404040404040404040404040404040 +404040404040404040404040404040404040404040404040404040404040404040404040 +404040280860C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE787201040404040404040 +404040404040404040404040404040404040404040404040404040404040404040404040 +40404040404040404040404040404040587F97C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFAF28487FAFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF +BFBFBFBFBFBFBFBFBFBFBFBFBFD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7BFBFBF +BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF +BFBFBFBF97783048D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF38387FA7BFBF +BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF +BFBFBFBFBFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFBFBFBFBFBFBFBFBFBFBFBF +BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF9F7F3838 +C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA74820487F87BFBFBFBFBFBF +BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF +BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFE7BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF +BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF +BF877F482048A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB750 +20507F8FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF +BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFD7FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF +BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF +BFBFBFBFA77F68382097EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F50DFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB730B7FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F40C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7389FFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFD73858B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB75838D7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF4848AFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF6828C7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF707FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF750B7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF9F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF609FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F30C7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7309FFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFBF28B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE73887FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8770 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF730D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFBF40FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF40BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9760F7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFF7609FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB748E7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF787FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF38F7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC738 +FFFFFFFFFFFFFFFFFFFFFFFFFFEF28E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE728EFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF9F60FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF609F +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF40EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF708FFFFFFFFFFFFFFFFFFFFFFF +FF58A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA758FFFFFFFFFFFFFFFFFFFFFFFFFFA758FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50AFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE728EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6897FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFE720F7FFFFFFFFFFFFFFFFFFFFDF20FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF18E7FFFFFFFFFFFFFFFFFFFFFFE728EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFE730E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58A7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF28E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +708FFFFFFFFFFFFFFFFFFFFF708FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F70FFFFFFFFFFFF +FFFFFFFFFF48B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A758FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB748FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFA758FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFCF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD728FFFFFFFFFFFFFFFFFFF7 +10F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF710F7FFFFFFFFFFFFFFFFFFAF50FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50AFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7FFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF20DFFFFFFFFFFFFFFFFFAF50FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF58A7FFFFFFFFFFFFFFFFFF48B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFB748FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA758FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF7887FFFFFFFFFFFFFFFF609FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F60FFFFFFFFFF +FFFFFFCF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF50AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFF720E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEF10FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF40FFFFFFFFFFFFFFFF20 +DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF10FFFFFFFFFFFFFFFF7887FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8778FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFDF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6897FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB748FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFEF10FFFFFFFFFFFFFFEF10FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF20DFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFCF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F60FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF18E7FFFFFFFFFFFFB748FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50AFFFFFFFFF +FFFFEF10FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF10EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF6897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFE718FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF58A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48B7FFFFFFFFFFFF8778 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7887FFFFFFFFFFFFAF50FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50AFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20DFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40BFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF609FFFFFFFFFFFFF609FFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF9F60FFFFFFFFFFFF7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF28D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF7887FFFFFFFFFFFF609FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F60FFFFFFFF +FFFF708FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF8F70FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEF10FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF609FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7FFFFFFFFFFFFF50AF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50FFFFFFFFFFFF609FFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F60FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +DF20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7887FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20E7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF877FFFFFFFFFFFFF40C7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFBF48FFFFFFFFFFFF40C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF48FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF48FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF877FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFF7EFFFFFFFFFFFFFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7FFFFFFFF +FFFFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF300000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000090000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000900000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000900 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000003030000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000009000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000009000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +090000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000090000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000090000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000900000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000900000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000030FFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F00 +00007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000 +007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000000C000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000090000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000090000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000090000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000007FFFFF7F +7FFFFF7F0000007FFFFF7F7FFFFF7F0000007FFFFF7F7FFFFF7F0000007FFFFF7F7FFFFF +7F00000040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF100000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000010000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000100000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000100 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000001010000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000001000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000001000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +010000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000010000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000010000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000100000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000100000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000010FFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F00 +00007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000 +007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F00000004000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000010000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000010000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000010000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000007FFFFF +7F7FFFFF7F0000007BBFBF5F5FBFBF5F0000007FFFFF7F7FFFFF7F0000007FFFFF7F7FFF +FF7F000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7BF8F7F4028009FFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF300000 +0000000008C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFF72800000000000030FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF0000000000008FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +CF080000000000AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF280000000058FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F0000000038FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF302800 +000028F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE74808000000CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F2048BFFF200010D7FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +1887E7100050FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF78F1858CFFFFFFF8F00AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF6028CFFFFFA700CFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF7F1060DFFFFFFFFFFFF7 +87FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF9FCFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFCFBFBFAF7F7F7F60EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFB71878F7FFFFFFFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFE7701070E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF730F7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFE74040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFEF9F500008EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA700 +00000000000087FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818BFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF6010 +7FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF8F008FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF18 +0040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF9F5000000000 +48FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF38000000000030F7FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF58188FF7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7180018F7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8700000040FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7480000000000009FFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFCF0000000008CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF8710AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFBF48209FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F0000008FFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFEF480000000040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF7480000000008EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD748 +0800000078FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF3830AFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF71800000018F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF1800000000 +0040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF72800000048 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF78108FE7180028F7FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF9F1097FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF9F2840BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F0000000000 +8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF600000000040FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F204000009FFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF971868E7FFFF9700C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +4838D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78F +2050C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718000000000018F7FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF7F20000040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF7F20DFF74808EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC73838C7FFFFFF +FFFF97FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7107FFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF7F1860D7FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFD77F7F7F007F7F7FD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFDF +6040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFF78FFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE760189FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFEF6028C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE7701870DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFEFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF7871878EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC71870F7FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF68187FE7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB72848D7FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFCF60188FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFDF4820B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFD72858EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +BF50209FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7781887 +F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87189FFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF40309FFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA71858E7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFE73840E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF9F3040AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFCF3830C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +9F1887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7972050BFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF681897FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF5038D7FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF8F1860CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F1070EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB71878F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFE77F1868DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +BF2840D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76028C7FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF701878E7FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE75018AFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD760187FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFF77F107FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF7818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC750208FF7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF2050E7FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB740289FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD74028BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F189FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFA73038AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFEF70108FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E74838DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48BFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF971868EFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F1887FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFC73038CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEF6028CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE758 +18A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB71878F7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7871878EFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818BFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF0000FFFF +FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFB72848DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFC72860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718 +CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD74828B7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8718AFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFF +000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF781887F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFA71860E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF9F1097FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF0000FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000000000FFFFFFFFFFFF0000FFFF +00000000FFFFFFFFFFFF0000FFFF00000000FFFFFFFFFFFFFFFF0000000000FFFFFFFFFF +FFFFFF0000000000FFFFFF00000000000000FFFF0000FF0000FFFFFFFFFFFFFF0000FFFF +0000FF00000000000000FF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC73838C7FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE74838D7FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF00000000000000FFFFFFFFFF0000FF000000000000FFFFFFFFFF0000 +FF000000000000FFFFFFFFFFFF00000000000000FFFFFFFFFFFF00000000000000FFFF00 +000000000000FFFF0000FF0000FFFFFFFFFFFFFF0000FFFF0000FF00000000000000FF00 +00FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFE7681897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFB7107FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFF +FF000000FFFFFFFF00000000FFFFFF000000FFFFFFFF00000000FFFFFF000000FFFFFFFF +000000FFFFFF000000FFFFFFFF000000FFFFFF000000FFFFFF0000FFFFFFFFFF0000FFFF +0000FFFFFFFFFF0000FFFFFF0000FFFFFF0000FFFFFFFF0000FFFFFFFFFF0000FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F1070 +EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF6028C7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF000000FFFFFF000000FF +FFFFFFFF0000FFFFFFFF000000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF000000FFFF +000000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFF0000FFFF0000FFFFFFFFFF0000FFFFFF +0000FFFFFF0000FFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF2848D7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72070F7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000 +FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFF0000FFFF0000FFFFFFFFFF0000FFFFFF0000FFFFFF0000FFFFFFFFFF +0000FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFDF5020AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF77818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF +FFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF00 +00000000000000000000FFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFF +FF0000FFFFFF0000FFFFFFFF0000FFFFFF0000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77F107FF7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD72858EFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFF +FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000000000000000000000FFFF +0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFF0000FFFFFF0000FFFFFFFF +0000FFFFFF0000FFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFAF1858E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87189FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFF0000FFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000 +FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFF0000FFFFFFFF0000FF0000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFF +FF0000FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20 +DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +CF4030BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFE73840E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF0000FFFF0000FFFFFFFF +FFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF00 +00FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFF +FFFF0000FF0000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF70108FFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F1887FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF000000FFFFFFFFFFFFFFFF0000FFFFFF000000FFFFFFFFFF000000FFFFFF0000FFFF +FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF000000FFFFFFFFFFFF0000FFFF +000000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFF0000FFFFFFFF0000FF0000FFFFFFFFFF +0000FFFFFF0000FFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF971068EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFEF5030D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFF +000000FFFFFFFF000000FFFFFF000000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000 +FFFFFFFFFFFF0000FFFFFFFF000000FFFFFF000000FFFFFFFF0000FFFFFFFF000000FFFF +FF0000FFFFFFFFFF0000FFFFFFFFFF000000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFF +FFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF3040CFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB71878 +F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000FFFFFFFFFFFF00000000 +000000FFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF +FF00000000000000FFFFFFFFFFFF00000000000000FFFFFFFF0000000000FFFF0000FFFF +FFFFFF000000FFFFFFFFFFFF0000FFFFFF0000000000FFFFFFFFFF000000FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE75818A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76028C7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF000000000000FFFFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFF0000FFFF +FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFF0000000000FFFFFFFFFF +FFFFFF0000000000FFFFFFFFFFFF00000000FFFF0000FFFFFFFFFFFF00FFFFFFFFFFFFFF +0000FFFFFFFF00000000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF7871078F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC72860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB72050DFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7818B7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFD74828B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF78 +1087FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF8F189FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F1860E7FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE74838D7FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFC73838C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF9F1887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F +20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE760189FFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF6028 +CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF871078EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB71878F7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F +50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFB72848D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF77818BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF5020B7FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72860EFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFF7781087F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8718A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA71858 +E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFD73848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFAF3030AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF4030BFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F1097FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F2040BFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFEF681097FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFE74838D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF78F2050C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F1070EFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB710 +7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF7F +1860D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFBF3040CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF6028C7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7701870DFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E75818AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFC72068F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFDF60187FE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718CFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +7F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77F107FF7FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818B7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF58188FEFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F20DFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFAF2050DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73058EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFBF482097F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF20CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD74828BFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF87189FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +AF40309FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF70108FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE73840E7FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F3040AFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF971868E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF9F1887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFF7972050BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFAF50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC73838C7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF50 +30D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF871860CFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE76018A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB71878F7FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7781868DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF787 +1878EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFF76828C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFDF681870E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB72848D7FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72860EFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD760187FEFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF50FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFDF4828B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFC750208FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF781887F7FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD73848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB740289FFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFAF50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA71858E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F189FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA73038AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30CFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFCF3830C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE74838D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFF79F2048BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFAF50FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF681897FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +1887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF8F1850CFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +30CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20 +DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF8F1070EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF6028CFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFE77F1060DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF2840 +D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFB71878F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7701070 +E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE75020AFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818BFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF60107FEFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF77F107FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFCF50188FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF1850E7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF8718A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF40209FFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFD74028BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFAF3030AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EF70108FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF9F188FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20 +40B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF971868EFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +4838D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78F1850C7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFC73038CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7107FFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFEF7F1860D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE75818A7FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFEF6028C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7701870DFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7871878F7FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72068F7FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFDF60187FE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFB72048DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +58188FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD74828B7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFD73050EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF482097F7FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEF781887F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87189FFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFAF38309FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +1860E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFE73840E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F2840AFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC73838C7FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +9F1887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFF7972050BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF9F20DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFE7681897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF5030D7FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EF871860CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F20DFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F1078EFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB71878F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7781868DFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F18DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB72848D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76820C7FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFDF681870E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFDF5020AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF60187FEFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77F107FF7FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF7818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF50208FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFA71858E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFB740289FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF4030 +BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F189FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA73038AFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +AF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF70108FFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E74838D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF79F2048BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF971070EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA71887FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF8F1850CF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF3040CFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEF6028C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE77F1060DFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFE75818A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF1878F7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFDF701070E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F7871078F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818BFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF60107FEFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF2050DFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFC72860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFCF50188FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD74828B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8718A7FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF4020 +9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF781087FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF3030AFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F1868E7FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF9F188FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF9F2040B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFC73838C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE74838D7FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78F1850C7FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE760189FFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFB7187FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEF7F1060D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF871078EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF6028C7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE770 +1070DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7 +2848D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72068F7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF60187FE7FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10 +CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF4820B7FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF77818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFCF58188FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFF7781087F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73050EFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF482097F7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA71858E7FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87189FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFAF38309FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF4030C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFE74040E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +9F2840AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFEF681097FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F1887FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78F2050BFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F1070EFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFEF5030D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFEF871860CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFBF3040D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB71878 +F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7781868DFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE75018 +AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76820C7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF681870E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77F107FF7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC72860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFCF60187FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFAF2050DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F18B7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF50208FF7FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD74828BFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFAF40289FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF70108FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF8F189FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA73038AFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF971868E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE74838D7FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79F2048BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF +30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC73838CFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFA71887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFEF8F1850CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE75818A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF6028 +C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE77F1060DFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7871878EF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF1878F7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFDF701070E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB72848D7FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF77818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD760107F +EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFDF4828B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72860EFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC750188FF7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF781887F7FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8718A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFBF40209FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFA71858E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFD73848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF3030AFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF +3838C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F188FFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF9F2040B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7681897FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFE74838D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78F18 +50C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF8F1070EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB718 +78FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF7F1060D7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF2840D7FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF6028C7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFE7701070DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF5020AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFC72068F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF60107FE7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFF77F107FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818B7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFCF58188FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF1850E7FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73050EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +482097F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFD74030BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF87189FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF38309FFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF7010 +8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE74038E7FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF9F2840AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF971068EFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF9F1887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78F2050BFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC73038CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF58 +30D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF7F1860CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE75818A7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB71878F7FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E7701868DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFF7871078F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFF76820C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF681870E7FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFB72048DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72860EFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFCF60187FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD74828B7FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F10B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF50208FF7FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEF781887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD73848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF40289FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10 +CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F1860E7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97189FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF9F3038AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC73838C7FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE74838D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7972048BFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE7681897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7 +1887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEF8F1850CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF871078EFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF6028C7FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE77F1060DF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFB72848D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFBF1878F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF701070E7FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF +5020AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818B7FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD760107FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77F1087F7FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF2860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC750188FF7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFA71858E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF8718A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFB740209FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF4030BFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF3030 +AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF70108FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF9F188FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F2040B7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF8F1070EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +4838D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFF78F1850C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F +10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF3040CFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB71878FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF7F1060D7FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFE75818A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFEF6028C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE7701070DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF78710 +7FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72868F7FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF60 +107FE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF2050DFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF50188FEFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD74828B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFD73050EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFBF402097F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF78108FFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87189FFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF38309FFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF971868E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFE74038E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF9F2840AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFC73838C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +9F1887FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +8F2050BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE760189FFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF5828D7FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF7F1860CFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF871878EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB71878F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFE7701868DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB72848D7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF76820C7FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF601870E7FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF4820B7FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF60187FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +AF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFF7781887F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF7F10B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFBF50208FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA71858E7FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF40289FFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFCF3830C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF97109FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF9F3038AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +681097FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E74838D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7972048BFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F1070EFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA71887FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF871850CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFBF3040D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEF6028C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFE7781060DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE75018AFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF1878F7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF701070E7FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77F107FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77818B7FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFD760107FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFAF2050E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFCF2860EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC750188F +F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD74028BFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87189FFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB740209FFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF30FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF9F10CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFEF70108FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFD73848E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFA73030AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F10CFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9718 +68E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF9F188FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF79F2040B7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF300000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000090000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000900000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000900 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000003030000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000C0000007FFFFF7F0000007FFFFF7F0000007F +FFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFF +FF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF +300000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000090000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000090000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000007FFFFF7F7FFFFF +7F0000007FFFFF7F7FFFFF7F0000007FFFFF7F7FFFFF7F0000007FFFFF7F7FFFFF7F0000 +007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFF7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF +DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFC7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF100000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000010000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000100000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000100000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000001010000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000040000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000 +007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF7F000000 +7FFFFF7F0000007FFFFF7F0000007FFFFF7F0000007FFFFF100000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000010000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000010000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000007FFFFF7F7FFFFF7F0000007FFFFF7F7FFFFF7F +0000007FFFFF7F7FFFFF7F0000007FFFFF7F7FFFFF7F0000007FFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFF730F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC72808FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F008FFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFEF68000020FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7180018F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB71800000038 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF8F0000008FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE758000000000040FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF71800000018F7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFF77F080000000060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF8F87CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF8F00000000008FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD73800000070 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F00001860A7 +EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF718000000000018F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7188718007FFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF000000000000389FFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD77F7F7F007F7F7FD7FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF7858FFF7789FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFE7A700000000000048EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD710E7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA778401010401000000000 +7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF488FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF7BF8F68380028507FB7E7FFFF50000018BFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFAF30F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7B77F50280038688FBFF7 +FFFFFFFFFFFFFF870038E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF718C7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFCFA7784010104078A7CFFFFFFFFFFFFFFFFFFFFFFFFFFFAF78FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7060FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7BF8F68380028507FB7 +E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFCF18E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE7B77F50280040688FBFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF408FFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA778401010407F +A7CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFA730FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFF7BF8F68380028507FBFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F718C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7B77F50280040 +688FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7060FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFCFA778401010407FA7CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFCF18E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7BF8F683800 +28507FBFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFE7B77F50280040688FBFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA730FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA77840 +1010407FA7CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFF7BF8F68380028507FBFE7FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7068FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7B77F +50280040688FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF18E7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA778401010407FA7CFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF3897FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7BF +8F68380028507FBFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F30FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7B77F50280040688FBFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF18CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +CFA778401018407FA7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF +FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF7068FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7BF8F68380028587FBFE7FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF000000FFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF18E7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFE7B77F502800406897BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFF0000000000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA778401018407FA7D7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF00000000 +00FFFFFFFFFFFF0000FFFF00000000FFFFFFFFFFFF0000FFFF00000000FFFFFFFFFFFFFF +FF0000000000FFFFFFFFFFFFFFFF0000000000FFFFFF00000000000000FFFF0000FF0000 +FFFFFFFFFFFFFF0000FFFF0000FF00000000000000FF0000FFFFFFFFFFFF0000FFFFFF00 +00FFFFFFFF0000FFFF00000000FFFFFFFFFFFFFFFF00000000FFFF0000FFFFFFFFFFFF00 +00000000FFFFFFFF000000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF +FF000000000000FFFFFFFFFF0000FFFFFF000000000000000000FFFFFFFFFFFF00000000 +00FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFF00000000 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF000000FF0000FFFFFFFF +FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF9F38FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFF7BF8F68380028587FBFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000FFFFFFFFFF0000FF0000 +00000000FFFFFFFFFF0000FF000000000000FFFFFFFFFFFF00000000000000FFFFFFFFFF +FF00000000000000FFFF00000000000000FFFF0000FF0000FFFFFFFFFFFFFF0000FFFF00 +00FF00000000000000FF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFF0000FF00000000 +0000FFFFFFFFFFFF000000000000000000FFFFFFFFFF00000000000000FFFFFFFF0000FF +FFFFFFFF0000FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000000000000000FFFFFFFF +0000FFFFFF000000000000000000FFFFFFFFFF00000000000000FFFFFFFFFFFFFFFFFFFF +FFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FF000000000000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF18CFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7B77F502800406897BFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF000000FFFFFF000000FFFFFFFF00000000FFFFFF000000FFFFFFFF000000 +00FFFFFF000000FFFFFFFF000000FFFFFF000000FFFFFFFF000000FFFFFF000000FFFFFF +0000FFFFFFFFFF0000FFFF0000FFFFFFFFFF0000FFFFFF0000FFFFFF0000FFFFFFFF0000 +FFFFFFFFFF0000FFFFFFFF0000FFFFFFFF00000000FFFFFF000000FFFFFFFF000000FFFF +FF00000000FFFFFFFF000000FFFFFF000000FFFFFFFF0000FFFFFF000000FFFFFFFFFFFF +FFFFFFFF0000FFFFFFFFFF000000FFFFFFFF000000FFFFFF0000FFFFFFFFFFFFFFFFFF00 +00FFFFFFFFFF000000FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00000000FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFFFFFFFF0000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6870FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFCFA778401018407FA7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFF +FF000000FFFFFF000000FFFFFFFFFF0000FFFFFFFF000000FFFFFFFFFF0000FFFFFF0000 +FFFFFFFFFFFF000000FFFF000000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFF0000FFFF00 +00FFFFFFFFFF0000FFFFFF0000FFFFFF0000FFFFFFFFFF0000FFFFFFFF0000FFFFFFFF00 +00FFFFFFFF000000FFFFFFFFFF0000FFFFFF000000FFFFFFFFFF000000FFFFFF0000FFFF +FFFFFFFF000000FFFFFF000000FFFF0000FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF00 +00FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFF000000FFFFFFFF0000FFFFFFFFFF +FF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFCF18EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF8F68380028587FBFE7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFF +FFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFF00 +00FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFF0000FFFFFFFFFF0000FFFFFF00 +00FFFFFF0000FFFFFFFFFF0000FFFFFFFF0000FFFFFFFF0000FFFFFFFF0000FFFFFFFFFF +FF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFF00 +00FF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFF000000FFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +00000000000000000000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF309FFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFE7BF7F502800406897BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FF +FFFFFFFFFF0000FFFFFF0000000000000000000000FFFF0000FFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFF0000FFFFFF0000FFFFFF0000FFFFFFFF0000FFFFFF0000FFFFFFFFFF00 +00FFFFFF0000FFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFF +FFFFFF0000FFFFFF0000000000000000000000FFFFFFFFFF000000FFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFF000000000000FFFFFFFFFFFF0000FFFFFFFFFFFF000000FF +FFFFFFFFFF0000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000FFFF +FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF9738FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA77F401018407FA7D7FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000 +000000000000000000FFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFF +0000FFFFFF0000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFF0000FFFFFFFFFF00 +00FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFF00000000 +00000000000000FFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FF00000000000000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFF00000000000000 +00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFBF8F68400028587FBFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFF +FFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFF0000FF0000FFFFFFFFFF00 +00FFFFFF0000FFFFFFFFFFFF0000FFFF0000FFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFF +FF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +000000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000000000FFFFFF +0000FFFFFFFFFF0000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6870FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7BF7F502800406897BFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FF0000FFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FF +FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFF0000FFFFFFFF0000FF0000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF +FF0000FF0000FFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFF +FFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFF000000FFFFFF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFCF18EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFCFA77F401018407FAFD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFF0000FFFFFF000000FFFFFFFF +FF000000FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000 +00FFFFFFFFFFFF0000FFFF000000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFF0000FFFFFF +FF0000FF0000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF00000000FFFFFFFFFFFF00 +00FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFF000000FFFFFF000000FF +FFFFFFFFFF0000FFFFFF000000FF000000FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF00 +00FFFFFFFFFFFF0000FFFFFF0000FFFFFF000000FFFFFFFFFFFFFFFFFF000000FFFFFFFF +FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF8F68400030587FBF +EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF000000FFFFFFFFFFFF000000FFFFFFFF000000FFFFFF000000FFFFFFFF0000FFFFFF +FFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF000000FFFFFF000000FFFFFFFF +0000FFFFFFFF000000FFFFFF0000FFFFFFFFFF0000FFFFFFFFFF000000FFFFFFFFFFFF00 +00FFFFFF0000FFFFFFFFFFFFFF00000000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFF +FF0000FFFFFFFF000000FFFFFF00000000FFFFFFFF000000FFFFFF000000FFFFFFFF0000 +FFFFFF0000FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF000000FFFFFFFF000000FFFFFF +0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFF000000FFFFFF000000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9740FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE7BF7F502800407097BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000 +00FFFFFFFFFFFF00000000000000FFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FF +FFFFFFFFFF0000FFFFFFFFFF00000000000000FFFFFFFFFFFF00000000000000FFFFFFFF +0000000000FFFF0000FFFFFFFFFF000000FFFFFFFFFFFF0000FFFFFF0000000000FFFFFF +FFFF000000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFF00000000 +0000FF0000FFFFFFFFFF00000000000000FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFF +FFFFFFFF0000FFFFFFFFFFFF0000000000000000FFFFFFFF0000FFFF0000000000000000 +0000FFFFFFFFFF00000000000000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF +FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFF000000FFFFFFFF00FFFFFFFF000000FFFF +FFFF00FF000000FFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF0000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE720CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA77F401018407F +AFD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000FFFFFFFFFFFFFFFFFF00000000 +00FFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFF +FF0000000000FFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFF00000000FFFF0000FFFFFF +FFFFFF00FFFFFFFFFFFFFF0000FFFFFFFF00000000FFFFFFFFFF0000FFFFFFFFFFFFFF00 +00FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFF00000000FFFF0000FFFFFFFFFFFF00 +00000000FFFFFFFF000000FFFFFFFFFF000000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF +FF000000000000FFFFFFFFFF0000FFFF00000000000000000000FFFFFFFFFFFF00000000 +00FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF +0000FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0000FFFFFF0000FFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF +FFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6870FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFBF8F68400030587FBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF00 +FFFF00FFFF00FFFFFFFFFF00FFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC718F7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7BF7F50280040 +7097BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF00FFFF00FFFF00FFFFFFFFFF00 +FFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF30A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFCFA77F401018407FAFD7FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00000000000000FFFF00FFFF00000000000000FFFF00FFFFFFFF00FFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F40FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF8F684000 +30587FBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFF00FFFF00FFFFFFFFFFFFFFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE718CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFE7BF7F502800407097BFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF00FFFF00FFFF00FFFFFFFFFF00 +FFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF6078FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA77F40 +1018407FAFD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFFFF00FFFFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC718F7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF8F68400030587FBFEFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFF +FFFF00FFFFFFFF000000FFFFFFFF00FFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7BF7F +502800407097BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF8F48FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA77F401018487FAFD7FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE718D7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF +8F684000305887BFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6078FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7BF7F502808407097C7FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFBF18F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +CFA77F401018487FAFD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF730AFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF8F684000305887BFEFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF8F48FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFE7BF7F502808407097C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E710D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFA77F401018487FAFD7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF587FFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFBF8F684000305887BFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFBF20F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7BF7F502808407097C7FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF730 +AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFCFA77F401018487FAFD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F50FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF8F684000305887BFEFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE710DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFE7BF7F582808407097C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF587FFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7A77F401820487FAFD7FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF20F7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFBF97684000306087BFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFF728AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7BF7F58280840709FC7FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8750FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFD7A77F401820487FAFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE710E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF97684000306087BF +EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF5087FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE7BF7F58280840709FC7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB728F7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7A77F401820487F +AFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF728B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFBF97684000306087BFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF8750FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7BF7F58280840 +709FC7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE710E7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFD7A77F401820487FAFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5087FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF97684000 +306087BFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFB728F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFE7BF7F58280840709FC7FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF300000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000090000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000900000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000030FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF100000000000 +000000000000000000000000000000000000000000000000000000000000000000000000 +000000010000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000100000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000010FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF00000000000000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF0000 +FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000 +00FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF000000FFFFFFFFFFFFFFFF0000FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFF00000000FFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF0000FFFFFFFF00000000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +000000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF0000 +0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FF0000000000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFF0000FFFFFFFFFFFF0000000000FFFFFFFFFFFF0000FFFF00000000FFFF +FFFFFFFFFFFF0000000000FFFFFFFFFF0000FFFFFFFF0000FF0000FFFFFFFFFFFF0000FF +FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFF000000FFFFFF00000000FFFFFFFFFF +0000FFFF00000000FFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFF0000FF000000FFFF00 +00FFFFFF0000FFFF00000000FFFFFFFFFFFFFFFF00000000FFFF0000FFFFFFFF0000FFFF +FFFF0000FFFF00000000FFFFFFFFFFFFFF00000000FFFF0000FFFFFFFFFFFF0000000000 +FFFFFFFF000000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF000000 +000000FFFFFFFFFF0000FFFFFF000000000000000000FFFFFFFFFF0000000000FFFFFFFF +FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFF00000000FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF000000FF0000FFFFFFFFFFFF +FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF +FFFF00000000000000FFFFFFFFFF0000FF000000000000FFFFFFFFFF0000000000000000 +FFFFFFFF0000FFFFFFFF0000FFFF0000FFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF00 +00FFFFFFFF0000000000000000FF000000000000FFFFFFFF0000FF000000000000FFFFFF +FFFFFF00000000000000FFFFFFFFFF000000000000FFFF0000FFFFFF0000FF0000000000 +00FFFFFFFFFFFF000000000000FF0000FFFFFFFF0000FFFFFFFF0000FF000000000000FF +FFFFFFFF000000000000000000FFFFFFFFFF00000000000000FFFFFFFF0000FFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000000000000000FFFFFFFF0000FFFF +FF000000000000000000FFFFFFFF00000000000000FFFFFFFFFFFFFFFFFFFFFFFF0000FF +FFFFFFFFFFFFFFFFFFFFFF0000FF000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF000000FFFFFF000000FFFF +FFFF00000000FFFFFF000000FFFFFF000000FFFFFFFF000000FFFFFF0000FFFFFFFF0000 +FFFF0000FFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF000000FFFFFF00 +000000FFFFFF000000FFFFFF00000000FFFFFF000000FFFFFFFF000000FFFFFF000000FF +FFFFFF000000FFFFFFFFFF0000FFFFFF00000000FFFFFF000000FFFFFFFF000000FFFFFF +00000000FFFFFFFF0000FFFFFFFF00000000FFFFFF000000FFFFFF000000FFFFFF000000 +00FFFFFFFF000000FFFFFF000000FFFFFFFF0000FFFFFF000000FFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFF000000FFFFFFFF000000FFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFF +FF000000FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +000000FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFFFFFF0000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF0000FFFFFF000000FFFFFFFFFF000000FFFFFF000000FFFFFFFFFF0000 +00FFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFF0000FFFFFF0000FFFFFFFF0000FF +FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFF +000000FFFFFFFFFF000000FFFF0000FFFFFFFFFFFF000000FFFFFF0000FFFFFFFFFFFF00 +00FFFFFF000000FFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFF000000FFFFFFFF0000FFFF +FFFF000000FFFFFFFFFF0000FFFF000000FFFFFFFFFF000000FFFFFF0000FFFFFFFFFFFF +000000FFFFFF000000FFFF0000FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF +FFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFF000000FFFFFF0000FFFFFFFFFFFF000000FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF00000000000000FFFFFFFF0000FFFFFF +0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF00 +00FFFFFF0000FFFFFFFF0000FFFFFF000000FFFFFF0000FFFFFFFF0000FFFFFFFFFFFF00 +00FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FF +FF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF +0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000 +FFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFF0000FF0000 +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFF0000FFFF +FFFFFFFFFF000000FFFFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000 +0000000000000000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFFFFFFFFFF00000000000000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FF +FFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFF0000000000FFFFFF0000FFFFFFFF0000 +FFFFFFFF0000FFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFF +0000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFF0000000000000000000000 +FFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFF +FFFF0000FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFF00 +00FFFFFF0000000000000000000000FFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFFFFFFFFFF000000000000FFFFFFFFFFFF0000FFFFFFFFFFFF000000FFFFFFFFFF +0000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000FFFFFFFF +FFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF00 +00FFFFFFFF0000000000000000FFFFFF0000FFFFFFFF0000FFFFFFFFFF0000FFFF0000FF +FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFF +0000FFFFFFFFFFFFFF0000FFFF0000000000000000000000FFFFFF0000FFFFFFFFFFFF00 +00FFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFF0000FFFF +FFFF0000FFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFF0000FFFFFF0000000000000000 +000000FFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF000000 +00000000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFF0000000000000000000000FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF0000FFFFFF +0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFF00000000FFFFFF00 +00FFFFFF0000FFFFFFFF0000FFFFFFFFFF0000FFFF0000FFFFFFFF0000FFFFFFFFFFFF00 +00FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FF +FF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF +0000FFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000 +FFFF0000FFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFF0000000000FFFFFF0000FFFF +FFFFFF0000FFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FF +FFFF0000FFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFF0000 +FFFFFFFFFFFF0000FF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFF +0000FFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFF +FFFF0000FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFF0000FFFFFFFFFFFFFF00 +00FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FF0000FFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFF0000FFFFFFFF000000FFFFFFFFFFFFFF +0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFF +FF0000FFFFFFFF0000FFFFFF000000FFFFFFFFFF000000FFFFFF000000FFFFFFFFFF0000 +FFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFF0000FFFFFFFFFFFFFF00000000FF +FFFFFF0000FFFFFFFFFF000000FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFF +000000FFFFFFFFFF0000FFFFFF000000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF00 +00FFFFFF0000FFFFFFFFFFFF0000FFFFFFFF0000FFFFFFFFFF000000FFFFFFFF0000FFFF +FFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFF000000FFFFFF000000FFFFFFFFFF +FF0000FFFFFF000000FF000000FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF +FFFFFF0000FFFFFF0000FFFFFF000000FFFFFFFFFFFFFFFF000000FFFFFFFFFFFF0000FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFF00000000FFFFFFFF0000FFFFFF +FF000000FFFFFF000000FFFFFFFF00000000FFFFFF000000FFFFFF000000FFFFFF000000 +00FFFFFF0000FFFFFFFF0000FFFFFFFFFFFFFF00000000FFFFFFFF000000FFFFFF000000 +00FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFF00000000FFFFFF000000FFFF +FFFF000000FFFFFF000000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF +0000FFFFFFFF000000FFFFFF00000000FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000 +FFFFFF000000FFFFFF00000000FFFFFFFF000000FFFFFF000000FFFFFFFF0000FFFFFF00 +00FFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF000000FFFFFFFF000000FFFFFF0000FFFF +FF0000FFFFFFFFFFFFFFFFFFFF000000FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF00FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFF0000000000000000000000FFFFFFFFFFFF0000FFFFFFFFFF00000000000000FFFFFF +FFFF0000FF000000000000FFFFFFFFFF000000000000000000FFFFFF0000FFFFFFFF0000 +FFFFFFFFFFFFFFFF000000FFFFFFFFFF000000000000FF0000FFFFFFFF0000FFFFFFFFFF +0000FFFFFFFFFF0000FFFFFF0000FF000000000000FFFFFFFFFFFF00000000000000FFFF +FFFFFF0000FFFFFFFFFFFF0000FFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFF0000000000 +00FF0000FFFFFFFF0000FFFFFFFF0000FFFFFFFFFFFF0000FFFFFFFF000000000000FF00 +00FFFFFFFFFF00000000000000FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +0000FFFFFFFFFFFF0000000000000000FFFFFFFF0000FFFF00000000000000000000FFFF +FFFF00000000000000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF00 +00FFFFFFFFFFFF0000FFFF0000000000FFFFFFFFFF00FF00FF000000FFFFFFFFFFFF0000 +00FFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF0000FFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000FF +FFFFFFFFFFFFFF0000FFFFFFFFFFFF0000000000FFFFFFFFFFFF0000FFFF00000000FFFF +FFFFFFFFFF00000000FFFFFF0000FFFF0000FFFFFFFF0000FFFFFFFFFFFFFFFFFF0000FF +FFFFFFFFFF00000000FFFF0000FFFFFFFF0000FFFFFFFFFF0000FFFFFFFFFF0000FFFFFF +0000FFFF00000000FFFFFFFFFFFFFFFF0000000000FFFFFFFFFFFF0000FFFFFFFFFFFF00 +00FFFFFF0000FFFFFFFFFFFF0000FFFFFFFFFFFF00000000FFFF0000FFFFFFFF0000FFFF +FFFF0000FFFFFFFFFFFF0000FFFFFFFFFF00000000FFFF0000FFFFFFFFFFFF0000000000 +FFFFFFFF000000FFFFFFFFFF000000FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFF000000 +000000FFFFFFFFFF0000FFFF00000000000000000000FFFFFFFFFF0000000000FFFFFFFF +FFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF0000FFFFFF +00FFFF00FFFFFFFFFF00FF0000FFFFFF00FFFFFFFF00FFFFFF00FFFFFF00FFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFF +FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFF00FFFFFFFF00FFFF00 +FFFFFFFFFF00FFFF00FFFFFFFFFF00FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF +FFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFF00FFFFFF00FFFF00FFFFFFFFFF00FFFF00FFFFFF +FFFF00FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFF000000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFF00FFFFFF00FFFF00FFFFFFFFFF00FFFF00000000000000FFFFFF00000000FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF00FF00FFFFFF00 +FFFFFFFFFF00FFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000 +00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF00FF00FFFFFF00FFFFFFFFFF00FFFF00FFFFFF +FFFF00FFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +00FFFFFFFF00FF00FFFFFF0000FFFFFF00FFFFFFFF00FFFFFF00FFFFFF00FFFFFFFF00FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFF00FFFFFFFF00 +FF000000FFFFFFFFFFFF000000FFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF00FFFFFFFF00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFF00 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFend +%%PageTrailer +%%Trailer +%%EOF diff --git a/doc/doxygen/figures/connectivity_arrays.png b/doc/doxygen/figures/connectivity_arrays.png new file mode 100755 index 000000000..1e46a517d Binary files /dev/null and b/doc/doxygen/figures/connectivity_arrays.png differ diff --git a/doc/doxygen/figures/connectivity_arrays_small.eps b/doc/doxygen/figures/connectivity_arrays_small.eps new file mode 100644 index 000000000..16d766547 --- /dev/null +++ b/doc/doxygen/figures/connectivity_arrays_small.eps @@ -0,0 +1,5488 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: (ImageMagick) +%%Title: (connectivity_arrays_small.eps) +%%CreationDate: (Thu Nov 29 18:20:32 2007) +%%BoundingBox: 0 0 375 281 +%%HiResBoundingBox: 0 0 375.052 281 +%%DocumentData: Clean7Bit +%%LanguageLevel: 1 +%%Pages: 1 +%%EndComments + +%%BeginDefaults +%%EndDefaults + +%%BeginProlog +% +% Display a color image. The image is displayed in color on +% Postscript viewers or printers that support color, otherwise +% it is displayed as grayscale. +% +/DirectClassPacket +{ + % + % Get a DirectClass packet. + % + % Parameters: + % red. + % green. + % blue. + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + compression 0 eq + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/DirectClassImage +{ + % + % Display a DirectClass image. + % + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { DirectClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayDirectClassPacket } image + } ifelse +} bind def + +/GrayDirectClassPacket +{ + % + % Get a DirectClass packet; convert to grayscale. + % + % Parameters: + % red + % green + % blue + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 eq + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/GrayPseudoClassPacket +{ + % + % Get a PseudoClass packet; convert to grayscale. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 eq + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassPacket +{ + % + % Get a PseudoClass packet. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + compression 0 eq + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassImage +{ + % + % Display a PseudoClass image. + % + % Parameters: + % class: 0-PseudoClass or 1-Grayscale. + % + currentfile buffer readline pop + token pop /class exch def pop + class 0 gt + { + currentfile buffer readline pop + token pop /depth exch def pop + /grays columns 8 add depth sub depth mul 8 idiv string def + columns rows depth + [ + columns 0 0 + rows neg 0 rows + ] + { currentfile grays readhexstring pop } image + } + { + % + % Parameters: + % colors: number of colors in the colormap. + % colormap: red, green, blue color packets. + % + currentfile buffer readline pop + token pop /colors exch def pop + /colors colors 3 mul def + /colormap colors string def + currentfile colormap readhexstring pop pop + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { PseudoClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayPseudoClassPacket } image + } ifelse + } ifelse +} bind def + +/DisplayImage +{ + % + % Display a DirectClass or PseudoClass image. + % + % Parameters: + % x & y translation. + % x & y scale. + % label pointsize. + % image label. + % image columns & rows. + % class: 0-DirectClass or 1-PseudoClass. + % compression: 0-none or 1-RunlengthEncoded. + % hex color packets. + % + gsave + /buffer 512 string def + /byte 1 string def + /color_packet 3 string def + /pixels 768 string def + + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + x y translate + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + currentfile buffer readline pop + token pop /pointsize exch def pop + /Times-Roman findfont pointsize scalefont setfont + x y scale + currentfile buffer readline pop + token pop /columns exch def + token pop /rows exch def pop + currentfile buffer readline pop + token pop /class exch def pop + currentfile buffer readline pop + token pop /compression exch def pop + class 0 gt { PseudoClassImage } { DirectClassImage } ifelse + grestore +} bind def +%%EndProlog +%%Page: 1 1 +%%PageBoundingBox: 0 0 375 281 +userdict begin +DisplayImage +0 0 +375.052 281.289 +12.000000 +500 375 +1 +1 +1 +8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 +BCBCBDBFBCBCC7FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C2BBD9 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4393C2B12 +3A395AF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE45A3C3B4198FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF6FAAE3EF1F6F8E3 +E7FFFFEADFFEDBF1DDCCECFFFFFFE9CCCFF5FFFFFFFFFF8A66F1F9C244E0FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB440FAFFFF7185FFFF89 +73FC4B7B482855E9FFE1492C257AF7FFFFFFFFBDCFFFFFED34CCFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFF6DCDBDBDCDBDBDDF9FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF3E7FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB440FAFFFFAA53F1F03AC5FD3D37 +CFDD475CE65A85E7CA3085FFFFFFFFFFFFFFFEA75CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFCC35312C1B2F303FDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFA159FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB440FAFFFFDF38D9BB4CE8FB40A9FFFFC633 +CB256A77783F4EFEFFFFFFFFFFFEA961E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF7E2E4BC2CCDE3E4F1F1FFFFF8EDFEF1F5F3E7F3FFFFFFF8E8E8F7FFFFFF +FFFFFFF1922B49FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFB440FAFFFFFF77808A62FFFA40B4FFFFD035CB256876 +7577A6FEFFFFFFFFFEA961E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFD432E8FFFF9F6EFFFFBA5EFC7486662B5AE9FFF87E2B2B7DF7FFFFFFFFFFA8 +3B774BFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFB440FAFFFFFFD4334496FFFA3D79FAFE985DD82CACFFFCCEBAFF +FFFFFFFEAC66E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFD432E8FFFFB84BE9FF5898FF601D9ECD4756ED8858BFBF317FFCFFFFFFFFEDE9A74AFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB440FAFFFFFFF04412D8FFFA4037797D24B8FF9826856941C7FFFFFFFFAC +2176969398EBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD432E8 +FFFFF33AC2E445C8FF5E78FFFFD82CC63A78A2A16331F2FFFFFFFFFFFFA64AFDFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFCF86FBFFFFFFFF805AFAFFFA41A78255AAFEFFFC9F575DC7FFFFFFFFFF9C585B5959 +61E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD432E8FFFFFF89 +6EAF43FBFF5D8EFFFFEA33C6383D52515277F6FFFFFFFFFFFFA64AFDFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEF46590FFFFFA40B4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD432E8FFFFFFE0425D67FD +FF5E6BFBFFCB42D5399EFFFFEBC4FBFFFFFFFFFFFFA64AFDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6 +473AE8FFFFFA42B4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD432E8FFFFFFFA5500B7FFFF602085 +B03386FF9A249A9D459BFDFFFFFFFFFFFFA64AFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B9D9FFFF +FFFDCAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE61EDFFFFFFFFA833E8FFFF5E827B3774F4FF +FE9B3A3A96FDFFFFFFFFFFFFFFBA73FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFDF9FEFFFFFFFF9160FEFFFF5D8EFFF8FBFFFFFFFCF8F8 +FCFFFFFFFFFFFFFFFFFCFAFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFF77827C5FFFFFF5D8EFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFF9A1AFFBFFFFFFBBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDEFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDE6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF686EAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFB9A5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFF268DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFA08AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE856D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFF8878F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +D654C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E99594DAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB982B2FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDB8CCAB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA0BC9BFBFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE99EDF69DE0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA96F19AE1FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB1C6FFFFD6A6F7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBB8FFC1B2FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC9B1FAFFFFFEBDBBFCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFF49BE4FFED97EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFCC9AEF5FFFFFFFFFAB8BDF9FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFBFB6FFFFFFC0B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFF6B9B0F3FFFFFFFFFFFFF8BBAEF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFE59EF1FFFFFFF5A0DDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFEE5ABC0FAFFFFFFFFFFFFFFFFFDCDA5DCFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F0AAD8FFFFFFFFFFE0A7ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEB79CD1 +FDFFFFFFFFFFFFFFFFFFFFFEDDA0AEE7FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFAED1FEFF +FFFFFFFFFFD9A8EBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE8BC9BBEF2FFFFFFFFFF +FFFFFFFFFFFFFFFFFFF7C89BB5E3FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD8A1D0FEFFFFFFFFFFFF +FFFFD3A0D5FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEECAA197B8EBFEFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFF1BF989EC2EAF9FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFEFAF8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 +F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F5EFD1A2A4E3FFFFFFFFFFFFFFFFFFFFFFE7 +A6A1CDEEF5F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 +F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8FAFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFBF8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 +F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 +F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 +F8F8F8F8F8F8F8F7F3F1EDE0C4A89C95AAD6F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF9DBB1959BA6BFDCECF1F3F6F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 +F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 +F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8 +F8F8F8F8FAFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D8 +B1A49C9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A +9A9A9A9A9A9A9A9A9A9A9A9A9A9A978FA4D4F7FFFFFFFFFFFFFFFFFFFFFFFFFFF9D7A78F +969A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A +9A9A9A9A9A9A9A9A9A9A9A9A9CA3AFD4F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFCF6E6CCB6AAA6A29E9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A +9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A +9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A +9A9A9A9994918C97AFCADEF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFF6E1CDB49A8D9093989B9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A +9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A +9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A +9DA2A6AAB3C8E2F5FCFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD09AA0C0D0DEE2 +E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 +E1E1E1E1E1E1E1E1E1E1E9F8FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9EAE1E1E1 +E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 +E1E1E1E1E1E1E1E2DED1C1A39ACAFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FCE5B9A29394A9BCC5CCD4DAE2E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 +E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 +E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E5 +EEF3FCFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFEFDF5EFE6E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 +E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1 +E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E2DCD4CDC6 +BEAD9792A0B5E0FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B4AAE0FCFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFDE3AEB0F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0C5A097B9D5 +ECFCFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFDF0 +D8BE9A9CC0EBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4ADC2FAFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFBC9AAF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C199AED8F9FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDE +B398B8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF8B2C9FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFCFAFF4FFFFFFFFFFFFFFFFFFFFFFFFFBCE9CB4ECFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2BD9A +C3F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFBDB9FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +C1B5FEFFFFFFFFFFFFFFFFFFFFF4B4AAE4FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECB2ACEEFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE29FF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A1DAFF +FFFFFFFFFFFFFFFFE9A9C5FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD1A4E1FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +A5D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9A1F9FFFFFFFF +FFFFFFE4A5D7FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0A5DBFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE9CF9FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA0D8FFFFFFFFFFFFECA6 +DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8A7E2FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0C4FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCEA8FEFFFFFFFFF8A9D2FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEA2F2FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF495ECFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF097EDFFFFFFFFC4B2FEFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD9DFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9ED7FFFFFFF199EAFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF49AE6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFC3AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFB9BAFFFFFFC5AEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFBCB6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFABC9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF8F8F8F8F8F8FC +FEF9FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFAF8F8F8F8F8F9FEFCFAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF8F8FDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFD3A0FFFFFDA2D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFDF8F8F8F8F8F8FAFEFAFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFEFAF8FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFEFAF8F8F8F8F8F8FEFCFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE598F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFA0D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC383E3E3E3E3CBAE161EDFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9395FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD70393E3E3E3C50EBA982FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7C3C4094ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFDF95FFFFF690EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFDA443D3E3E3E3A84FC6CC5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBD57 +3C89E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFE77393E3E3E3D4CE7B17CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFF698E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFE97DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F42BAB8B8B8B7E8D532E8FFFEFEFDFE +FFFFFEFEFEFDFEFEFDFDFEFFFFFFFFFFFFF4AD2478FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFC467ABBB8B8B8BFFB8E5DFFFFFEFDFDFEFFFFFEFEFE +FDFEFEFDFEFEFFFFFFFFFB6D68BAB64C9AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4 +94FCFFEB8EFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD29AB +B9B8B8B7D2FA40B4FFFFFEFDFDFEFFFEFEFEFEFEFEFEFDFEFFFFFFFFFFDE419ABB5650F8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFE4E73BCB8B8B8BDF99955FFFFFEFDFDFEFFFFFEFEFEFDFEFEFDFEFEFFFFFFFFFFFE +FEFEFDFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99 +DBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC2F1 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E5DFFFFFFFFFFFFD432E8FFD9594670F0FFD467 +A54D91CF564DC3FFFFFFFFFFFF85374677FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFC46ABFFFFFFFFFFFF8E5DFFFFAD49479FFEFF9F808D4BC0A746 +67E9FFFFFFFFEB64E0FFFFAB46FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C4FBFFF0 +C4FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC34EDFFFFFFFF +FFFA40B4FFF3774655D3FFF46EA16468DB724599FDFFFFFFFFE3CBFEFFC039F4FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4D +A1FFFFFFFFFFFF9855FFFFB34A4799FDFFA67C914ABBAD4763E6FFFFFFFFFFAF8CA44669 +EBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7E9FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF8F47C7C5C5C4D1FFD432E9DC5564A83E61F4C41180982B48 +9C7130DDFFFFFFFFFFC9DA7675FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFC4683C8C5C5C3E2FF8E5DFFB0418992279DFF7821A0742563A64361FCFF +FFFFFEFAFEFFFF925FFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFFFFFEFEFEFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD2BB7C5C5C4C7F4FA40B5 +F8784BA56339D5F22B54A94434869226ADFFFFFFFFFFFFEDC56D94FEFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E7CC8C5C5 +C3DFFF9855FFB64285962895FF831D9D7A2460A64859F9FFFFFFFF911865A64164FDFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF92113837373462FBD432ED8552CDD3A91EBCC537F1FF6D77FFED34C9 +FFFFFFFFFFFFFF7575FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFC4621383737339BFF8E5EFB418DD1D1772EF37672FFEF35C1FFB43DF8FFFFFFFFFF +FFFFAC60E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF153337373741DAFC40B8C830BED2 +C23B75F435C5FFB03EF7FF5F89FFFFFFFFFFFFC43735AEFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E1F3837373393FF98 +55FD4786D1D17E29EE8068FFF339B8FFBD39F4FFFFFFFF903BE9FFB040FAFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF8E59F5F2F2F2F5FFD432ED841335343630C7C439F4FF707AFFF035C9FFFFFFFF +FFFFFF7575FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC46 +A2F6F2F2F2F8FF8E5EFB3B243534324CF57675FFF237C5FFB83EF8FFFFFFFFFFFEAC5EE0 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD32E1F3F2F2F3FCFA40B8C8113334352D8CF3 +35C9FFB440FAFF6289FFFFFFFFFFFFFBF3DC4DBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4D99F7F2F2F2F8FF9855FC4221 +35343347F1806BFFF63BBCFFC039F4FFFFFFFF8E5DFFFFB440FAFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +8E5DFFFFFFFFFFFFD432ED8157EEEFF0D4F3C139F4FF707AFFF035C9FFFFFFFFFFFFFF75 +75FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC46ABFFFFFF +FFFFFF8E5EFB3C9DF3F0EAD3FF7575FFF237C5FFB83EF8FFFFFFFFFEAD61E1FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFCC34EDFFFFFFFFFFFA40B8C62EDAF0F1DDE1F135C9FFB4 +40FAFF6289FFFFFFFFC791F7FFFF5598FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4DA1FFFFFFFFFFFF9855FC4295F3F0EBD2 +FF7F6BFFF63BBCFFC039F4FFFFFFFF8E5DFFFFB440FAFFFFFFFFC6E9FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E52E4E2 +E2E2E1F7D532EBBC2792E28C61E5C239F4FF707AFFF035C9FFFFFFFFFFFFFF7575FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4697E6E2E2E1E4FF8E +5EFF7E2FC4CF6C83FF7575FFF237C5FFB83EF8FFFFFFFEAB47C4E5E1EAFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFCD30D2E2E2E2E1ECFA40B6E83E62E0AA5ABCF235C9FFB440FAFF62 +89FFFFFFFFCD2EADE7C851CAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4D8FE6E2E2E1E4FF9855FF852CBFD26F7EFD7F6BFF +F63BBCFFC039F4FFFFFFFF8E5DFFFFB440FAF9DFF0FF9AD8FFE3E8FFF8EFDFF2ECE1FBFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C1D313131312FB6 +DC44EAFFB02C2D3ACFFFC64AF5FF7C85FFF147CDFFFFFFFFFFFFFF8181FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC56243231313045EB996BFFF678 +272865F0FF8181FFF348CAFFBE4EF8FFFFFFEB3A1F33312D6AFDFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFD3252F3131312D7CFC51BAFFD8422D29A4FEF147CDFFBA51FAFF6F93FFFFFF +FFFFC5422F40C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFE5E233231313041E5A364FFF87E27295FEDFF8A78FFF74CC2FF +C64AF5FFFFFFFF986BFFFFBA51F6B794A3F19BD8CF9699E0C575988F9691C3FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0DCDBDBDBDBDBF2FAE4FBFF +FCE1DAE8FFFFF6E4FDFFECEDFFFDE4F7FFFFFFFFFFFFFFECECFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE6DBDBDBDBDBDEFBF0E9FFFFF5DCDBF2FF +FFECECFFFDE4F7FFF5E5FEFFFFFFFBE0DCDBDBDAE5FEFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF8DEDBDBDBDBDAE8FEE5F5FFFFE9DAE0FBFFFDE4F7FFF5E5FEFFEAEFFFFFFFFFFFFEE4 +DAE3FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEE7DBDBDBDBDBDEFAF1E8FFFFF6DCDBF1FFFFEEEBFFFDE5F6FFF6E4FDFF +FFFFFFF0E9FFFFF5E9CC96EFBAA39EC689E4D78CB8A1FF86DFDC98FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFC7669286B59EC4668F8C9ABAB3FF8DEDDC98FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFDAA1F1C4CE9DCC9BE5D9BBBBB3FF8DEDDC98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF8A +B2FDBBE6E6939EF3D3CCFFB2F3E7B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF9FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6 +FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEF7FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFBFDFFFFFF +FEFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDB8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA1E7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF9A3E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFAFA3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF775D3FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF471D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFAB7AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF998AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA5EBCFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE51C7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFE9864FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF8574FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD473A5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD769ACFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFF59089DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFEE8F8BE4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFADB69AF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADB39AF3FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6A3 +B8BAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCEA9B1 +C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE899F5B0C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE99AF0ADC8FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA6D1E999F4FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA1D8E29BF8FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFAABCDFFEB9FE9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCAFC7FFE69DF0FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7A3F9FFB6BFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFAAFAFDB0C7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +C1BBFCFFFFD3AEF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFECBB1F9FFFFC9B3F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE3A6E4FFFFF4A8D0FCFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDCA7EBFFFFF0A8D7FDFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEAAFBBF9FFFF +FFFED1A3D8FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFEF0B7B2F4FFFFFFFDC5A5E4FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D6BEB9B9B9B9B9B9B9 +B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9AA9FE0FFFFFFFFF1AAA3B8B9B9B9B9B9B9B9B9B9B9 +B9B9B9B9B9B9B9B9B9B9B9BBCEEFFEFFFFFFFFFFFFFFFFFFFFF4D2BCB9B9B9B9B9B9B9B9 +B9B9B9B9B9B9B9B9B9B9B9B9B9B8A7A2E8FFFFFFFFEDA5A5B8B9B9B9B9B9B9B9B9B9B9B9 +B9B9B9B9B9B9B9B9B9B9BCD0F2FFFFFFFFFFFFFFFFFFFFFFFFFBE8D0BFB9B9B9B9B9B9B9 +B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B5A498C9FAFFFFFFFFFFFEDF +A19DB0B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9BBC9 +DFF6FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFF8E0C9BBB9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B8 +A898BEF6FFFFFFFFFFFDD49BA1B4B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9 +B9B9B9B9B9B9B9B9C4D7F2FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE09FA1B5B9B9B9B9B9B9B9B9B9B9B9 +B9B9B9B9B9B9B9B9B9B9B9C9F1FFFFFFFFFFFFF9D2BAB9B9B9B9B9B9B9B9B9B9B9B9B9B9 +B9B9B9B9B9B9B9B7A798CCFDFFFFFFFFFFFFFFFFDA9BA3B6B9B9B9B9B9B9B9B9B9B9B9B9 +B9B9B9B9B9B9B9B9B9BACCF5FFFFFFFFFFFFF7CFBAB9B9B9B9B9B9B9B9B9B9B9B9B9B9B9 +B9B9B9B9B9B9B6A599D4FFFFFFFFFFFFFFFFFFFEDFA495A5B4B9B9B9B9B9B9B9B9B9B9B9 +B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9BDD1F3FFFFFFFFFFFFFFFFFFFBDDC2B9 +B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B8AB9999C8FA +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD29C99 +ABB8B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9BACAECFEFF +FFFFFFFFFFFFFFF6D4BDB9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9B9 +B9B9B9B9B0A096BDF6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEA6E0FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFEEAFCAFFFFFFFFFFFFFFDAA8E6FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE9AAD3FFFFFFFFFFFFFFFECB9FD4F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE5AEB3F7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABCA9E0FCFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFEEEB8ABF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFF29FE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFF19FE2FFFFFFFFFFED9FE6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFEC9EE8FFFFFFFFFFFECEB0F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC8B4F7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBFB9F9FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +D2ADF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFBDB6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 +A7FDFFFFFFFFB6BDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6AD +FFFFFFFFFFE0A1F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB7BEFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7A4F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB5FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFF697E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF798E4FFFF +FFF394EDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF395EDFFFFFF +FAA3D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF29DE4FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF99EDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF59BE3FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA9E +FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4BFFFFFFFD1A4FE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADC6FFFFFFDC9EFAFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD4A3FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2B1FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB4FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD79DFFFFFFB4BDFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA7FFFFFFB1C1FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFE895F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFADC7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE697F6FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8CDFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE895F8FFFDA2D4FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF9CF9FFFB9BDEFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFC96E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FB96E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB93E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE98DEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF97EEFFF998E3FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA96F4FFF197ECFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFA7CEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58AF6FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9CE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF3A1ECFFF89EEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFF09EF3FFEDA0F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFB7C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE9BF9FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFB2CEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFEECFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFDEDFBFFFDECFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFDECFCFFFAEDFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBECFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFF1F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFD1AFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0AFAFB0B0B0B0B0B0B0B0B0 +B0B0B0B0B0B0B0B0B0B0B0B0B0AFAFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0 +B0AFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B4B6B0B0B0B0B0B0B0B0B0B0 +B0B0B0B0B0B0B0B0B0B0B0B0AFAFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0 +AFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0AFB0B0B0B0B0B0B0B0B0B0B0 +B0B0B0B0B0B0B0B0B0B0B0AFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0AFAF +B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0AFAFB0B0B0B0B0B0B0B0B0B0B0B0 +B0B0B0B0B0B0B0B0B0B0AFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B4EED9 +AFD2F7C2B3E8EAB4C0F7D4AFD6F6BFB5EBE7B2C4F8D0AFDAF5BCB6EFE3B1C7F8CCB0DEF2 +B9B9F2DFB0CBF8C9AFAFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0AFB0B0 +B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0AFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0 +B0B0B0B0B0B0B0AFAFB0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0AECCF7DFF7 +CBB0DFF2E3F4BCB6EEE8EDE8B3C2F7E0F5D7AEC7FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE85B2 +C0BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC39085C3BFBFBFBFBFBFBFBFBFBFBFBF +BFBFBFBFBFBFBFBFC38C89C3BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB768BCBF +BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC37747C0BFBFBFBFBFBFBFBFBFBFBFBFBF +BFBFBFBFBFBFBFC37A9CC2BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC1A96FC1BFBF +BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC1A573C2BFBFBFBFBFBFBFBFBFBFBFBFBFBF +BFBFBFBFBFBFC06DADC0BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC2977EC3BFBFBF +BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC29382C3BFBFBFBFBFBFBFBFBFBFBFBFBFBFBF +BFBFBFBFBFBA67B9BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC389C3E3BFDBF9CE +C2ECEEC3CCF8DDBEDEF8CCC3EFEBC1CFF9DABFE1F7C9C5F2E8C0D2FAD6BFE4F5C7C6F4E5 +BFD5FAD4AE6CC0BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC0AB6EC1BFBFBFBFBF +BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC271A7C1BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBF +BFBFC29E78C3BFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFC29994FCE5F9D5BFE5F4 +E9F6C9C5F2ECF0ECC2CEF8E6F7DFBC7BF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFC98F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEECFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFDD9FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE8 +FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2AD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD5FAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8CF1FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +A4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCADF5FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +94FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF4FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CED +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD0F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFEF3FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFDBCF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFB8AF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC6 +F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2AD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF0FDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD2FAFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC +A4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF2FDFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 +94FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CED +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD29FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8FF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E88EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 +9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFEDFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEE3FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE194FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88EFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE392FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF96DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD29FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFEDEFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE88DDEEEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDEDF1B2A4F2EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDF1ACAAF1EDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE380E9EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEDF28D4FEFEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDF196C1F0EDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDEDEFD189EFEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDEDEFCC8DF0EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEE86D6EEEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDEDF1BB9CF2EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDED +EDF1B5A1F2EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE77FE6EDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDEDEDF2A4BFFAEDF5FDF1EEFAFAEEF1FDF5EDF6FDF0EEFAF9EEF1 +FDF4EDF6FCF0EFFBF8EDF2FDF3EDF7FCEFEFFCF8EDF3FDF3D885EEEDEDEEEFF1F1EEEDED +EDEDEDEDEDEDEDEDEDEDEDEED488EFEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDF0 +8BCFEFEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDF0C494F1EDEDEDEDEDEDEDEDEDED +EDEDEDEDEDEDEDEDEDEDF0BE9AFFFAFAFAEEF0FCFAFDF9EFF4FDF8FDF3EDF8FCF9FCEFDD +FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFA4878C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C807D8D8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8D7F7E8D8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C8C8A768B8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +7C718C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8D7B838C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C8C86788C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C85 +798C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C77878C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C8C827C8D8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C817D +8D8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8A768A8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8C8C82D9C88ABDF4A790DEE192A3F3C18AC3F3A293E3DC8FA8F5BB8AC9 +F09D95E8D68DAEF5B58BCEED9A99ECD08CB4F6B086788C8C897A62493D7A8C8C8C8C8C8C +8C8C8C8C8C8C8C8C87788C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C78868C8C +8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C847A8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C +8C8C8C8C8C8C8C8283E3E1E1E2939E9B64795E64BAF4D1F4B28CD2EBD7EE9B98F9FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFEFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFEFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFEFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFEFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFEFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFDFEFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFEFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFEFFFEFDFEFEFEFDFEFEFDFEFEFEFDFEFEFEFDFEFEFDFEFEFEFDFEFEFEFDFE +FEFDFEFEFEFDFEFEFDFDFEFEFDFEFEFEFDFEFDFFDA4B1D0B4BEDFEFDFDFDFDFDFDFDFDFD +FDFDFDFDFDFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFEFDFDFDFDFDFD +FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFEFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD +FDFDFDFEFEFEFEFEFEFEFE8400002ED0FFFEFEFEFEFDFEFEFEFEFEFEFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF766000FB2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFEEBB841B15B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFECA0974B58F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE8 +B293B4E9888EFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFCE6FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE1D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFBDDB3E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC9A59687BAFEFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFDCE8DBDFAD8D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE2AB92B9EFFEFF +F2F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFD35FE5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBF +4096FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 +AC60263AE8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE89050021C9FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F1A996DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCA795C0F2FEFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7C0598 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6961D0294FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16C030076 +FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFED971C048EFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED692B2F5FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD6A099C9F6FEFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3220037E5FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB69090294FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA73615B7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFF6BD8EB99E5BEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B391D5FEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFF8D09C9BD0F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7502C58CBFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5705FA3FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB293D994EAFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFBD493A2E5FFF6E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF97A7F1FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFF5C9989FD7FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF8E884F1F9FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA1C6F8F3FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB391EFFFFBFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5A193D4 +FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFF9BE8DCDFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF1C4 +97A5DCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFDC91F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFCB391EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B78CBFF6FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE79CA0EAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEBB94ACE2FDFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFEA0C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFCB490EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACC8FA9EBFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFBC98CC3FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEAB493B1E6FDFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFDC91F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFDB490EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDF9C98DBFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEA5 +9AE3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE5AF94B9EBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +A0C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB490 +EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEFAC8DC7F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD38EB8F7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFCE0A894C0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD91F6FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB490EEFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF8C28DB1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4AE92DBFEFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFBD8A296C5F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA0C5FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB390EEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD794 +9FE3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDB92AFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A6 +99CCF8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD90F6FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB391EEFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9A492D0FCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF7B68FD3FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9DEF9FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA0C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFCB291EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4B98ABBF5FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFE296A7EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7C4C3D6FEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE5FCFFDBE4 +FFFFFFFFFFFFECD4FEF3ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFDC90F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFCB291EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCF91A7E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFABF8FC9FCFFFFFFFFFFFFFFFFFFFFFFFFFFFDA24937363F78EEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD5FF8FF86A4FFFFFFFF +FFFFC16EFE81A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFEA0C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFCB291EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFEE19E96D9FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE89F9FE9 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC23A7F4F4D53B9CFFFFE7D3D9FAFFFDDFF4E0D4F1 +FFFFE7EBEBD3E6FFFFFFF4D5D4EFFFFFFFECD3D6F7F69635CFF0DFE0DEFAFFFFEFE3EED8 +E2467EDFE5EAFFFFEEE3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFDC90F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB2 +91EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFEFB08FC5F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA8EBFFAFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFF154A3FFFFFFFFD8B0FED8402D2697FDF54786452667F1FF766A +602B3FD6FFF57226295CECFFE5502A2685BA240C2FB773754CD5FFFF9670B6506F0D1C55 +6883FFFF926FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +A1C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB391EFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9 +C68EAEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFA995E2FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE231DBFFFFFFFFFFFFE53F61E5AB26A3F7323CCFD12FA6FF6F1AAAE65A64 +FF7E65D1DC4562E9534DDDBD3ACBA73AE3FA638A747EFFF340BFB343ED4D8AF3A754F1F2 +3EBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD90F5FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB391EFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDA979DE0FEFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED590B6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFE231DBFFFFFFFFFFFFC930E6FFFF7867F838B3FFFF519DFF6C73FFFF9359FC3F5B84 +825C2CCB2FD3FFFDE9FCB440FAFF628CAE54F3C547E6B143FC5598FFE237D8C349E4FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA1C4FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB390EFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECA890CCFAFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFF4B191D9FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE436 +D4FFFFFFFFDFABC535F0FFFF8467F839C0FFFF519DFF6B7FFFFF9359FC3F4C6D6B6D8AD4 +32DEFFFFFFFFB440FAFF628AF654A56C8CFFAF43FC5598FFFE77808F5EFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD90F5FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB490EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6BD8BB7F3FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFEDD94ABF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7955EBFFFF +FD876BCA27C5FFF3586DF839C0FFFF519DFF6B7FFFFF9359FC4384FEFEE5B5DA2AB3FFF6 +ABE9B540FAFF6289FF85573ACFFFAF43FC5598FFFFD436498EFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA1C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFDB490EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFCD392A2E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +BB8ECFFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF44569F9F7D2ACBFA +7A2D975E37D4F639C0FFFF519DFF6B7FFFFF9359FFB82679873AA1FA8F53A16D2CDDBA2B +99DE6489FFD62A5FF8FFAF43FD5A5BAEF8F1440ED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFDD90F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFDB490EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFE5A192D5FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE69AA3ECFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9964F4F72D5FEFFF7864E5B +D3FFF87AD5FFFF8ABDFF9CA9FFFFB68FFFFFB8514FA2FEFFFC984E54C3FFEF754DC199AF +FFFCA1C8FFFFC981FEC4546AF1FF8553F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFDA1C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +B390EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF2B58CC0F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC58BC6FBFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF96B88FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFDD91F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB390EEFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC98EAAED +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDA09BE6FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE94F34E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD +A0C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB391EEFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDC9A99DDFEFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFDCE8DBCF8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F4B2D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC91F5FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB291EEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDAA8EC9FAFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFF2A896DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA0C5FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB291EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C18CB5F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFED692B2F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC91F5FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFCB291EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFCD693A0E5FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B491 +D5FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF7CFA5DDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA0C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFCB291EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFEE6A392D1FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF97A8F0FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C9989ED6 +F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFDC91F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FCB391EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B98B +BDF5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9BE8DCCFDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C295A5DDFBFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFEA0C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB391EFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACD91A8EAFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE89DA0EAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEBB94ABE2FDFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFDF92F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB990EFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE19D97D9FDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFCC88EC3FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDEAB491B0E7FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +ADC7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBE96EEFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0AF8DC6F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEEA598E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFDE5AE92B7EBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE49BF6FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBE96EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFF9C58EAFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FDD38EB8F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FCDFA794BFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADC7FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFDBE96EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFDD9969DE1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3AF93DBFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD9A194C5F4 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE39AF6FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFDBD96EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA +A890CEFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDC91AFF3FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D19D9ACBF7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADC7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFDBD97EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5BC8BB9F4FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B78FD2FDFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7CB989ED3FAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFE39AF6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBD97EE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD192A4E8FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE398A6EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF3C294A3DAFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFA7C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBD97EEFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE39F94D7FDFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFBBF8ECAFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEFBD91A8E1FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE38EF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBD97EEFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF0B28DC2F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE89F9FE8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +EAB793AEE6FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A7BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBD97EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFAC88DACEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA +8EBFF9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE5AE92B5ECFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF1FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDBD97EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FDDC999ADEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFA897E0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE0A992BBEEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8BBFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFDBD97EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEECAB8FCAFA +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED590B4F7FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBA396C4F2FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE48EF0FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFDBE96EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C08DB5F2FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B291D9FEFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFF9D59F98CBF5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8BBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBE96 +EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD594A0E4FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEDD95ABF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF7CD999BD1F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFE48EF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBE96EEFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFEE6A392D2FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFF8BB8DCFFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF5 +C7969FD6FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFA8BBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBE96EEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFF4B68CBDF6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFE59AA2EBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF1BF94A8DDFCFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE48EF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBB92EEFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFBCB8FA9EBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC58CC5 +FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEDB891ACE4FEFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A8BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDF9C96 +DBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDA09BE6FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE8B091B3E8FEFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF1FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFDBA8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFAD8DC7FAFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCE8DBCF8FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFDE2AB92BAEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7BCFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFDBA8DEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C48DB1F1FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2AA95DEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFCDBA494C1F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38FF2FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA +8DEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD8949EE2FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFED891B2F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD5 +9E96C8F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7BDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEBFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFE8A591CFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF5B392D5FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7D09C9BCFF7FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFE38FF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEBFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFF4BB8BBAF4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +DF97A8EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4C8979FD7F9FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFA8BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8CEBFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCF +92A6E8FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9BE8FCBFDFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1C194A3DCFBFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE38EF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8CEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE39D95D8FCFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE79EA0EBFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEEEBA92AAE2FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A8BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEBB8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0B18DC2F8FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC88DC2FAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEEAB492B1E6FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF2FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFEBB8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC88DACEEFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFEEA598E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE4AD +91B7ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7BCFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +BB8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFDDC989CDFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFDD28FB9F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDEA792BDEFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF2FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8CEAFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFECA98FCBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF3AE92DBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD8A296C5F4FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8CEAFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F6BE8BB7F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDC92 +AEF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D29B98CCF8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFE38DF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8CEAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD492A1E6FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7B98FD2FDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF6C9989DD3FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFA7BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4A193D5FCFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE397A6EEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF3C494A2DAFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE38EF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFDBA8DEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B68DC0F6FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC18EC9FCFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEBC92 +A9E1FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A7BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFDBA8DEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFACA8FA9EDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEA9E9FE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEAB591AEE7FDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF1FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FDBA8DEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFEDF9B99DCFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFCC98FBEF9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE5AE92B5EBFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7BBFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEBFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFEEAC8FC8F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFEFA897E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE0A893BCEFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF1FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8CEBFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C28DB4 +F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED591B4F7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFADBA394C3F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8BBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8CEAFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD7949FE2FEFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B290D8FEFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFF9D49D96CAF5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFE48EF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8A391D0FBFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDE94ABF2FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7CE9A9A +D0F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFA8BBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFEBB8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5BA8BBBF5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8BB8ECFFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5C596A0D7FBFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE48EF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEBB8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFCCE90A6EAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFE59BA1ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF1BF93A5DDFDFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A8BBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFDBB8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEE29D94D8FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFBC58EC5FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFEECB691ADE3FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF1FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8CEA +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0AF +8CC4F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC +A29AE6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFEE8B18FB2EAFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7BCFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8CEAFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C58EAEEFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCF8CBCF8FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFDE1AA92B9EEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF1FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEAFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDA969DE1FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2AB95DEFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDBA394C0 +F3FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7BDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9A88FCEFAFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED890B3F5FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD59E96C8F5FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFE38FF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFF6BC8BB9F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF6B392D4FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7CE999AD0F8FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFA8BDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFDBA8DEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFBD393A3E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFEE098A7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF4C8969FD6F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE38FF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFDBA8CEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +E4A193D6FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFF8BE8FCBFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEF1C193A4DDFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A8BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8C +EBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2B38EBFF7FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE79E9F +EAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEEEBB92A9E1FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF2FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8CEAFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACA8EABECFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC98EC1FAFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE9B391B0E6 +FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8BCFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8CEAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDD9A9ADCFDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEA59AE3FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE4AD91B7EBFEFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF2FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFEEAC8FC8FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED18FB8F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDEA591BEF0FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFEBB8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFF7C18BB4F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFF3AE91DBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFBD8A194C4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFE38EF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFDBA8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFDD5949FE4FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFEDB92ADF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF9D09B99CCF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFA7BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFDBA8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7A392D2 +FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F7B88ED2FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F6CA959CD3FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE38EF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA +8CEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3B88DBCF6FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE497A5EEFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2C295A3D9FB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A7BCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCC8FA8EBFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC28DC9FCFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEBB92A8E1FDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF1FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEAFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE09B97DAFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA9F9EE7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE9B390AFE6FDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF18AFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7BCFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEBFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEEAE8EC7F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCA8FBEF8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFEE5AE90B5EBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE38EF1FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBA8DEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF9C48DB1EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEFA897DFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFCDFA893BCEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF18AFBFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAABEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEBD91EDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDC9A +A2E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFED795B8F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB +DDA598C8F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC29D9F9F9F9F9F985E9D9F9F9F9F9F9F9F9F +9F9F9F9F9F9C9B9F9F9F9F9F9F995C92A09F9F9F9F9F9F9F9F9F9F9F9F9B9B9F9F9F9F9F +9F9F9F9FA0904F8AA19F9F9F9F9F9F9F9E999F9F9F9F9F9F9F9F9F9FA08D4C6D9DA19F9F +9F9F9F9F9FA09F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9A9CB1F4CF9ECAF6 +B4A3E5E5A3B4F6CA9ECFF4B0A5E9E0A1B8F7C59ED3F2ADA8EDDBA0BDF7C09FD8EFAAABF0 +D79FC2F1A99E9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F999E9F9F9F9F9F9F91 +4F78A0A09F9F9F9F9F9F9F9F9F9F9C9A9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F84486997A2 +A09F9AC3F5D9F6BBA0DDECDFEFABAAEEE0EBDEA1BAF6D9F4CA9ECFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFE85C3D3D2D2D2D2D2D4D2D2D2D2D2D2D2D2D2D2D2D2D2 +D69E91D6D2D2D2D2D2D0CED3D2D2D2D2D2D2D2D2D2D2D2D2D69996D6D2D2D2D2D2D2D2D2 +D2CBD0D3D2D2D2D2D2D2D2D2C971CFD2D2D2D2D2D2D2D2D2D1CAD4D4D2D2D2D2D2D2D2D6 +7F49D3D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D685AADDFAE8D2E6FADCD4F2F2 +D4DCFAE6D2E8FADAD5F4F0D3DEFBE4D2EAF9D8D6F6EED3E0FBE2D2EDF7D7D8F8ECD2E4DB +83D5D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D377BED3D2D2D2D2D1C7D3D4D2D2 +D2D2D2D2D2D2D2D2D2D5A68AD6D2D2D2D2D2D2D2D2D2D2D2D2D2CECBD4D4D3D2D2D5A0A2 +FEEDFBDFD3EFF6F0F7D8D7F7F0F6F0D3DFFAEDFAE6D0CDFDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF892F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF99CF8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEF0FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CED +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFCD5FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFDECFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCDFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF889F6FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAB3F9FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2AD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF4FEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCFFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFEF4FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFAB3F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CED +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF889F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFCCDFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDECFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD5FCFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF0FDFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +9855FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB +98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2AD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF99CF8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF892F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFC9A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFDE5FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFDDEFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CED +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9855FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFA2CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDB98FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF90E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9A7FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFDE2FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF868F9A9A9A9A +9A9A9A9A9A9A939A9A9A9A9A9A9A9A9A9C79719C9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A +9A9A9A9A9C76749C9A9A9A9A9A9A9A9C948B9A9A9A9A9A9A9A9A9A9A945D989A9A9A9A9A +9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9D67469B9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A +9A9A9A9C6A81AEF3CC99C7F5B09FE3E39FB0F5C799CCF3ACA1E8DE9DB5F6C299D1F1A8A3 +ECDA9BBAF7BD9AD6EEA5A6EFD49AC0DE719B9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A +9A9A9B618D9B9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9A9C7E6D9C9A9A9A9A9A9A9A +9A9A9A9A9A9A9A9A9A9A9A9A9A9C7A9BF7D7F5B89CDBEBDEEEA6A5EDDFEADD9CB6F5D7F4 +C799CDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9D8D8D8D8D8D8D8D8D8 +D9CA5DB9DAD8D8D8D8D8D8D8D8D9DAD8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 +D8D9DAD8D8D8D8D8D8D9D9B34348D7D8D8D8D8D8D8D8D8D8D8DAD8D8D8D8D8D8D8D8D8D8 +D8D8D8D8D8D8D8D8D8D8D8D8DBDDD8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8 +DAD9DFFAEBD8E9FBE1DAF4F4DAE1FBE9D8EBFADFDBF6F2D9E2FBE7D8EDF9DEDCF7F0D9E4 +FCE5D8EFF8DCDDF9EED8E6FADFD8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8DA +D9D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D9DAD8D8D8D8D8D8D8D8D8D8D8D8 +D8D8D8D8D8D8D8D8D8D8D9EAFBEFFBE4D9F1F7F2F8DDDCF8F2F7F2D9E3FBEFFAE9D8EBFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB41391 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFF9A7300064FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFEFBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF24F0031E0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFF78D140077FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFB9F8EC4EDFBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB39162DADFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE70 +5593FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFBF27200123DBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1DD7AD1EDFEFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9CC5F5ECFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFAEBD4BCA8 +978D63041383EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCC99F9FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFDF6E3CBB6A2908E9FB1C8DFF7C848 +B0FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF08EDDFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFEFDF0DAC5AF9B8C95A5B7D0E8F8FDFEFFFFFFF4E5FEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0ADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF9E7D5BEA8928F9CA9C1D9F0F9FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFE08EF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF3E1CEB79F8F +959EB0C9E4F3FBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFA9AC6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBECDDC7AE979199A1B8D3EAF5FCFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFC99AF9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFEF6E9D7BFA4939698A9C2DDEDF8FEFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF091DE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFCF2E4D0B59D96949BB0CDE2F0FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAEFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF9EFE0C6AC999593 +A0BCD3E7F3FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1 +EAEAF5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFCF7FFFEEFFAFFFFFFFFFFFFF3F4FFF7FBFFFFFFFFFFFFFFFCEFFCFFFFFFFFFF +FFFFFFFFFFFFFFF5F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F4FFFFFFFFFFFF +FEF0F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEFFDFFF2F3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE8EF0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF6ECD7BDA59A9395ABC3DBEAFAFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBAF51313163C4 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B697FFF460D0FFFFFFFFFFFF8D95FC80D6FFFFFFFFFFFFFFE04FE6FFFFFFFFFFFFFFFFFF +FFFFFF967DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE269C9FFFFFFFFFFFFFC69BFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCA52F2FFBC6FEAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9BC8FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFCF4E7CDB3A197909CB4CCDFF1FDFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9823A6D2D3862FDEFFFEF6 +F4F7FEFFFCF6FCF5F5FDFFFEF7FCF7F4FBFFFFFFF9F4F5FDFFFFFEF7F4F6FEFD7070F9FA +D3EEF8FEFFFFF8FBDFE1E331C8FAF7FCFFFFF8FCDB31E2FFF6FCF6F4FCFFFFFFF9F4FE84 +67FFFFFBF4F4FBFFF6F5FEFFFEF5FCFFFFFFFE6788FFFFF9F4F4F8FFFED5EDFDF4F4F4F4 +F9FFFFFBF4F4FCFFFFFFFFFFFDF6FDFFFFFFFFFFF7FBF8F4FAFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFF6B0EEFFFFFFFCB8482BF0FFFE7777FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC79BFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE +FAF2DDC5AC9F9291A6BCD2E5F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE244AEFFFFFFFA98B7FFD5493552E0FF +D65EAC403CBBFFF864AA5A338DFBFFF371353AB1FFFFE2543547D593161948D5678C70FC +FFFF7DAA938350092B7963C6FFFF79ADDF31E2F25EAE51349AFDFFEE6733715668FFFC91 +353590FEAB52EAFFCB6AE9FFFFFFCD3FE2FFF373353661EBFD6BC3D83F393A3097FFFA87 +35359AFDFFFFFFFFEB60E0FFFFFFFFFF759D6B3276F5FFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFE832D4FFFFFFCA2C7236F0FFFFD63DDAFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFEF8EE0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF9ECD5BBA9998D99AD +C3D7EDFCFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF43FBFFFFFFFFFEFFD73863C25445E7D01451BA +802EE0F83730A3A726B0F97857BA8F28B4E74751C16546D45858C9E839AB45C5FFD63EDC +7275BE269CD55E95FFD23EDDDD31E2EF2A39AB9E24C0F45E3EBC80026AFF974BA9AA2A91 +F55D76E73A84FFFFFFFF9D59F9FF8931B7C04272FD43B0F6C2C4831BC9FE8E4EAEA3279B +FFFFFFFFF8CDF5FFFFFFFFFF522394B43090FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFDFCE431D1FEFCFFEDD5C735F0FFFFF24FADFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFADB1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF7E4CCB7A3928FA0B4C9E0F4FDFEFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFAF43FBFFFFFFFFFFFF8F47F3FFEB37ABD228D3FFE832D4F9 +389CFFFF559ADD28A1B9B44C5AAE34E9FFF1C8FE7575FFF237C26395FFA951FA717BEF33 +D0FFAB46FFA553F9DB31E2EF2FADFFFC46AECE29D7FFFC6868F83787BAB96B31F4CA3F67 +7BF6FFFFFFFE4DA1FFFF8F2DAAC1D7D3FB43AFFFFFC42C83FBEE308FB9B8623AF8FFFFFF +FFFFFFFFFFFFFFFF517DFFFF7575FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +96403D0D384081FFFFFFC935F0FFFFFF8E5EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFDC8DF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFEFDF0DBC6B09D8D97A7BAD1E8F9FDFEFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFAF43FBFFFFFFFFDEDF8F5DFFFFFD4AAAD134EDFFE832D4F93BBCFFFF +559ADE1B3A41413F88AC46FCFFFFFFFF7575FFF237C8C546D950ADFF707BEF33D0FFE344 +C7559CFFDB31E2EF34CCFFFC46AECD35F0FFFF8467F8343041404065F5FF7811DCFFFFFF +FFFE4DA1FFFFF880380E42C2FD43AFFFF5577FFAFFED2B334140406DFAFFFFFFFFFFFFFF +FFFFFFFF519DFFFF7575FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2AFA022 +92B0C9FFFFFFC935F0FFFFFF8E5DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA99CAFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA +E9D4C0AA94909DACC1DAF0FAFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFE343ABFFFFFFFB6B8F934BF6FFEE3AABD134EDFFE832D4F93BBCFFFF559ADD29 +CBFFFEE3DAAC37EDFFF4D2FF7575FFF237C5FF4A6F3EF2FF707BEF33D0FFFF90574AB0FF +DB31E2EF34CCFFFC46AED93EDBFFFD6C67F836A4FFFEEECEFDD145487CF9FFFFFFFE4DA1 +FFFFDFE3F8BD6357FD43B0FA6E45F2FFFFED30B1FFFEEBCFFDFFFFFFFFFFFFFFFFFFFFFF +519DFFFF7575FFFFFFFFFFD2CCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE832D4FFFFFF +FFFFC935F0FFFFFF8E5DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC79DFBFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF5E1D0B8A29196A2B1CB +E4F4FBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FF9B23A2CFCF8233E5D3326FCE5E3DE2CE34EDFFE832D4F93BBCFFFF5599F9633CC29D4D +B2E34290D27144F7775DD4EA38C5FF932780FEFF707BEF30A6E0FFC50E36F3FFDB31E2EF +34CCFFFC46ABFF7245C8911A6AFF8A28B0B35291F8626DC035BFFFFFFFFF628EFFFF8B3B +C1CD4C6BFD43B2B51B9ECECBE5FC7E2DB6AD509AFEFFFFFFF9D6F7FFFFFFFFFF519DFFFF +7575FFFCD4DCFFBCB3FFDFD2FBF9E7D3E0EECCF1FFFFFFFFFFFFEC58DCFFFFFFFFFFC935 +F0FFFFFF7D73FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE8FE1FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEDDDC8B198939BA3BBD3ECF6FDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB353 +323266C8FFFFCD3F3048D9FFD454F0FFEB52DBFA5AC7FFFF70A8FFEF672F31A4FEFFDC52 +313DCAFFBD3741D459CEFFE263D6FFFF878FFD782B7AFFFB4677FEFFE151E7F154D4FFFD +63B8FFE95B2E718780FFFA882E2E83FBAC4BE7FF9958EBFFFFFFBB3EF5FFEF672F3156E6 +FD61BD772735343095FFF77E2E2F8DFBFFFFFFFFEA5CE0FFFFFFFFFF6CACFFFF8B8BFFC2 +A2A0D5BDB4DBA0A2BEE267A38E8DA1A0FCFFFFFFFFFFFDF5FCFFFFFFFFFFD155F2FFFFEC +37CBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADB4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEF6E8D7C1A695979CAAC2DFEEF8FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3EDEDF6FF +FFFFFEF1EDF2FEFFFBF1FDFFFDF1FCFEF2FAFFFFF3F8FFFFF6EDEEFCFFFFFEF2EDF1FEFF +FDEFEEFBF1FBFFFEF7FEFFFFF5F6FFF7EDF3FFF449B1FFFFFCF1FDFDF1FBFFFEF2F9FFFF +F5ECF6F7F4FFFFF9EDEDF9FFF2EFFDFFF7ECFAFFFFFFE448C0FFFFF6EDEDF4FFFEF2F9F3 +EDEDEDEDF5FFFFF8EDEDFAFFFFFFFFFFFDF1FCFFFFFFFFFFF3F8FFFFF5F6EB7FD8CC85B8 +B28BC7DB81C68DFFA6BFFA89F8FFFFFFFFFFFFFFFFFFFFFFFFFFFBF1FEFFFFB04FECFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFDC8FF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF1E5 +D1B79F96989DB2CEE3F1FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFD6564BF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9664EDFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEA689B98A3BBB27C919C +92D094FFA7C9FA89F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE55BA5FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFA99C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF9EFE0C8AD9B9896A3BDD6E8 +F4FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFD476CAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA4CEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5A1DACEBDBCB3B3C8DDAFD794FF +A7C9FA89F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5ACFCFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFC69EFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF6EBDABDA69B9697ABC6DCEBF9FEFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC9DA9F8DAD5FAAD9AE8EFC3FFCEE0FCBD +FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EE8FE2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFCF4E8CEB6A19B929EB7CDE1F0FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEACB4FFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFAF2DFC6 +ADA19493A7BED4E5F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA90F2FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF9EED5BDAA9C9199B0C5D9EDFC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF897CCFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFCF8E4CDB6A69590A3B6CBE0F5FEFEFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC39FFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFCF1DCC4B39E9098A9BCD1E9F9FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFEC90E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFAEAD4C1AA +97909FAEC2DBF0FBFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFEABB6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5E2CFBBA49398A4B2CBE4F6FBFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFD990F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFCEEDCCAB29B949EA7BBD5ECF6FDFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8 +97D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFEF8E8D9C1AA95999FACC4DFEFF8FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0A1FCFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF2E4D2B9A098 +9AA0B4CFE5F1FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFC8BEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC8EE4FFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFAEEE0CAAF9C9A9AA4BDD8E8F5FEFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8BEF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADBBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFEF8F0DEC4ABA19D9FB1CCE0ECF9FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5A0A2A2A2A2A2A2A2A2A2A05F99A2A2A2A2 +A2A2A2A2A29F9EA2A2A2A2A2A2A2A2A2A2985C97A2A2A2A2A2A2A2A2A29E9EA2A2A2A2A2 +A2A2A2A2A2A2966F48415B728494A1A4A2C1FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFE85C0CFCFCFCFCFCFCFCFCFCFD1CFCFCFCFCFCFCFCFCF +D29C8FD3CFCFCFCFCFCFCFCFCFCFD1D0CFCFCFCFCFCFCFCFD39794D3CFCFCFCFCFCFCFCF +CFCFCFD0D0D0D1D1D1D0CFCFC581FBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CED +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CED +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFBFB0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFF389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFD8CEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFB0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFB9B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F389FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE86D1 +E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E4A99BE5E1E1E1E1E1E1E1E1E1E1E1E1 +E1E1E1E1E1E1E1E1E5A3A1E5E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1D682FBFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB09094949494 +94949494949494949494949494949494948C8A9494949494949494949494949494949494 +94949494948B8B94949494949494949494949494949494949494949490AAFEFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBD4D3E2FFFFFFF7DFFC +FFFFFFFFFFFFFFF3E0FDFFFFFFFFFFFFFFFFFFFFFFE3EFFFE7EAFFFFFFFDE0F4FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1E0FEFF +FFFFFFFFFFFFFFFFFFFFFFFFFFF7DEFBFFFFFFFFFFFFFFFFFFFFFFF9DEFAFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF3DDFDFFFFFFFFFFFFEEE2FFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3EFFFF8DBFAFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE37129322F308CF4FFD041EEFFFFFFFF +FFFFFFBD4AF8FFFFFFFFFFFFFFFFFFFFFF5CA3FF7748E3FFFFF748C1FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFF7E7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC6CFDFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD340ECFFFFFFFFFFFFFFFFFFFFFFDD3FE4FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFF67E8FFDFFFFFFFFFFFFB175FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFF651A4FFF3739DFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15242AFE9E5972FA8FFCC34EDFFFCE6E1EDFFFFB8 +3EF2E3E6FCFFFFFDE7E1EBFFFF519DFF700179FFFFF63BBCFFEBF4FFFFEFF0FFF2EEF5E2 +F8F8E2E8FDFF7576F6E1EDFFFFFFF8E3E1F3FFFFF1ECE6ECEEDAFEECF4EEE1F1FFFFFFF4 +E1EBF7EAFFD033EBFDE8F9E7E2F8FFFFF9E3E8D931E2FFFDE8E1EBFFF7E1F4FFFFF0EDFF +FFFFFFAE4AF3FFFAE4E1E5FBFFEBDCFEEAE1E2E2E6FCFFF2E1E3F9FFFFFFFFFFFAE7FCFF +FFFFFFFEEAF6EBE1F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +BAB4FFFFFFFFCD660FA1FFFFDB3DD2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFAB28D6FFFFFFFFCCA8FFCC34EDFFB02E2D46DBFFB83A8E322F +B4FFED8B3D2D3FD4FF519DFF6D6660A9FFF63BBCFF60ACFFFF7F88FF9D417228848C2F33 +BEFF76636F2B46DBFFFA88292A65EFFF943D3C7BB55BFD65865A295CEAFFF36F284D9154 +FCD033ECE948983F288AFBFB8D283F6927E2FFBC322D3DD3E94F9CFFE860B4FFFFFFFC4F +A3FFFD9C2B312BA2FFA865FD6A2D332345F0EC5D2B2991FCFFFFFFFFDC5AECFFFFFFFFFA +56904F286CF2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A70FFFF +FFFC5C6F479DFFFFFF7677FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFF716CFFFFFEF1EDEFF4FFCC34F0B92790DA5D40E8BD0D6CDA8D27C09E3D +CAE06554FE519DFF6B82B150E7F73BBCFF4DA1FFFF707AFF9129C7B9246FDD7E3AF57915 +96DA5D40E49357BDD14066FB872FC9EDAB46FD5224ADD13D85FF9B34C6BC313AFBD033EC +E72047CBB326C49727B1CD3A1AE6C64E9AE16F38DDBF30CA7C48EFFFFFFFD845D1FFD423 +9FE6A035E39F51FFE5DDBF2B88F46A6ED3B32A97FFFFFFFFF9E2FBFFFFFFFFFA3D2FBAC8 +319DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCEEF27268F1EEFBFEE5F5 +529DFFFFFFAD52EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF707AFFFFF65C312D5CFECC34F27665FDFFE932C1BD33EAFFFC617BF0E5F1AB6246 +FD519DFF6B80F84F72F73BBCFF4DA1FFFF707AFF8E5DFFFB43AFFFCC34F27664FDFFE932 +BB4A6399976C25EA8567FFFFAB46FD518AFFFF7576F543BAFFFFA43CFBD033ECE62DC5FF +F83EB74E94FFFFCA2DE78D389896891EAEFE7F4960E0FFFFFFFFAB46FCFFE3396198C2DB +FD9D51FFFFE94854EBE0278397964A4DFEFFFFFFFFFFFFFFFFFFFFFA3FA0FFFF5D8EFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC40351917353CD6FFFFFF519DFFFF +FFE832D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75 +55F6FFFCD6CF8F40FDCC34F27675FFFFF63BC1BC3EF8FFFF707AFD8236543946FD519DFF +6B7FFFDB3DC93EBCFF4DA1FFFF707AFF8E5DFFFB43AFFFCC34F27675FFFFF63BBA4A3B5B +595A74F48567FFFFAB46FD519DFFFF7576F234CCFFFFB83EFBD033ECE631D8FFF83EB74E +A6FFFFDB31E78E215B595A60CEFFD10B87FFFFFFFFFFAB46FCFFFFD2622C186CF79E51FF +FF9554E9FFDF214F5A595A92FEFFFFFFFFFFFFFFFFFFFFFA40B4FFFF5D8EFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6CFD0625AD0CEF5FFFFFF519DFFFFFFE832D4 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC923B9FEFF +FFFFB340FDCC34F27954F4FFD82AC3BE29D9FFF35BA19C55CCF8AA46FD519DFF6B7FFFFD +9C5B2ABEFF4D9FFFF34E7BFF8E5DFFFB43AFFFCC34F27752F4FFD742D04A85FFFFEFBDFC +8467FFFFAB46FD519DFFFF7576F953A5FFFF8E3BFBD033ECE631D8FFF83EB97482FDFFB3 +28E78E46F0FFFCC2E6F15B573CC9FFFFFFFFAB46FCFFEDBBF9E6B42ADAA051FFA227C2FF +FFE029BBFFFFDEC7FFFFFFFFFFFFFFFFFFFFFFFA40B4FFFF5D8FF8DDFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7A70FFFFFFFFFFFF519DFFFFFFE832D4FFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA832270B1B18D4076 +FECC34EFD33564AD3B60F5BC1358AD6040F2A428A18C2845FB519DFF6B7FFFFFF74F02C0 +FF703CAD721A7EFF8E5DFFFB43AFFFCC34F2791B74AC3A74FFB225859D4390FF8467FFFF +AB46FD519DFFFF7575FFB1259892303BFBD033ECE631D8FFF83EBBD62882A14121E4DE3F +58AF5664EBA445D87962F5FFFFFFC245E6FFDD2E76B67333E89F52E63059B0AEBBF4832A +A18343B8FFFFFFFFF1BFF7FFFFFFFFFA40B4FFFF5D91C36BBDF4FFE7D7D5B7E4FFFFD3BC +F4FFE0B4CCFDFFFFFFFFFFFFA19AFFFFFFFFFFFF519DFFFFFFC943E2FFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C184414165C8FDFFD969F2 +FFD14F3F6EF0FFCA72B24550D4FFFB8F3D6AB375DA80B6FF92A0FFFFFFE05ECFFFEE6B3E +92919DFFAB87FFFC74C4FFD969F59A948F3E6EF0FFFFB143408DFBFFA48EFFFFC176FD7E +B6FFFF9999FFFD9A3E6AA43FFADC68F1EC67E2FFFA70CAFFB44355BB68E9FFDC553F62EA +E55CB4FFE759B5FFFFFFFB43B0FFFFC147424AC6FFB682C8434543415EF1FA884044B6FF +FFFFFFFFDF68EEFFFFFFFFFB72C7FFFF87AEC36F7AD7FFA98476BAA3E5D0AAB7AFE792BE +AEE1FFFFFFFFFFFFFEFEFFFFFFFFFFFF7EB6FFFFFF7F6BFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFBFBFCFEFFFFFEFCFEFFFEFBFB +FCFFFFFEFCFEFBFBFEFFFFFDFBFCFFFBFCFCFDFFFCFDFFFFFFFEFCFEFFFFFCFBFDFDFDFF +FDFCFFFEFCFDFFFEFCFEFDFDFDFBFCFFFFFFFEFBFBFDFFFFFDFCFFFFFDFCFEFCFDFFFFFD +FDF36DC2FFF18E57FBFEFCFEFEFCFEFFFEFCFEFFFEFBFCFEFCFEFFFEFCFBFCFFFDFAFDFF +FEFBFBFFFFFFFF9161FCFFFEFBFBFBFEFFFDFCFDFBFBFBFBFBFEFFFDFBFBFEFFFFFFFFFF +FEFCFEFFFFFFFFFEFCFDFFFFFCFFDB9AD2A5F18FB0B9FFC3AC8AB0C97BCA92C6D7FDFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFCFDFFFFEC48B8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7E26 +573E29BDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE55AABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFDB98FC9BA0B9B5BCFFC6AB869EB19CECDDB195D5FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFA8A71F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6AB979ADCFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +DFB6FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFDC7FEBB179D8B37BD1A5DAC3B6CDADEBBCD79FC9FFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFF3B0EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFF1A3CDE98AFFB499A6D7FFFDC3A8ECFFD09FBCFBFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F6A0B7FFBCC4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE7F9FF +F7F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFend +%%PageTrailer +%%Trailer +%%EOF diff --git a/doc/doxygen/figures/connectivity_arrays_small.png b/doc/doxygen/figures/connectivity_arrays_small.png new file mode 100644 index 000000000..5c28cadc3 Binary files /dev/null and b/doc/doxygen/figures/connectivity_arrays_small.png differ diff --git a/doc/doxygen/figures/connectivity_example.png b/doc/doxygen/figures/connectivity_example.png new file mode 100755 index 000000000..83eeea394 Binary files /dev/null and b/doc/doxygen/figures/connectivity_example.png differ diff --git a/doc/doxygen/figures/connectivity_example_small.png b/doc/doxygen/figures/connectivity_example_small.png new file mode 100644 index 000000000..6a64827c8 Binary files /dev/null and b/doc/doxygen/figures/connectivity_example_small.png differ diff --git a/doc/doxygen/figures/grid_example.png b/doc/doxygen/figures/grid_example.png new file mode 100755 index 000000000..00339ace3 Binary files /dev/null and b/doc/doxygen/figures/grid_example.png differ diff --git a/doc/doxygen/figures/mesh_splitted.png b/doc/doxygen/figures/mesh_splitted.png new file mode 100644 index 000000000..98a8518a4 Binary files /dev/null and b/doc/doxygen/figures/mesh_splitted.png differ diff --git a/doc/doxygen/figures/mesh_unsplitted.png b/doc/doxygen/figures/mesh_unsplitted.png new file mode 100644 index 000000000..338eeb62c Binary files /dev/null and b/doc/doxygen/figures/mesh_unsplitted.png differ diff --git a/doc/doxygen/figures/polygon_connectivity.png b/doc/doxygen/figures/polygon_connectivity.png new file mode 100755 index 000000000..a5b8f4252 Binary files /dev/null and b/doc/doxygen/figures/polygon_connectivity.png differ diff --git a/doc/doxygen/figures/polygon_connectivity_small.eps b/doc/doxygen/figures/polygon_connectivity_small.eps new file mode 100644 index 000000000..cb0726271 --- /dev/null +++ b/doc/doxygen/figures/polygon_connectivity_small.eps @@ -0,0 +1,15904 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: (ImageMagick) +%%Title: (polygon_connectivity_small.eps) +%%CreationDate: (Thu Feb 28 14:07:46 2008) +%%BoundingBox: 0 0 375 281 +%%HiResBoundingBox: 0 0 375.052 281 +%%DocumentData: Clean7Bit +%%LanguageLevel: 1 +%%Pages: 1 +%%EndComments + +%%BeginDefaults +%%EndDefaults + +%%BeginProlog +% +% Display a color image. The image is displayed in color on +% Postscript viewers or printers that support color, otherwise +% it is displayed as grayscale. +% +/DirectClassPacket +{ + % + % Get a DirectClass packet. + % + % Parameters: + % red. + % green. + % blue. + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + compression 0 eq + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/DirectClassImage +{ + % + % Display a DirectClass image. + % + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { DirectClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayDirectClassPacket } image + } ifelse +} bind def + +/GrayDirectClassPacket +{ + % + % Get a DirectClass packet; convert to grayscale. + % + % Parameters: + % red + % green + % blue + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 eq + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/GrayPseudoClassPacket +{ + % + % Get a PseudoClass packet; convert to grayscale. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 eq + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassPacket +{ + % + % Get a PseudoClass packet. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + compression 0 eq + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassImage +{ + % + % Display a PseudoClass image. + % + % Parameters: + % class: 0-PseudoClass or 1-Grayscale. + % + currentfile buffer readline pop + token pop /class exch def pop + class 0 gt + { + currentfile buffer readline pop + token pop /depth exch def pop + /grays columns 8 add depth sub depth mul 8 idiv string def + columns rows depth + [ + columns 0 0 + rows neg 0 rows + ] + { currentfile grays readhexstring pop } image + } + { + % + % Parameters: + % colors: number of colors in the colormap. + % colormap: red, green, blue color packets. + % + currentfile buffer readline pop + token pop /colors exch def pop + /colors colors 3 mul def + /colormap colors string def + currentfile colormap readhexstring pop pop + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { PseudoClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayPseudoClassPacket } image + } ifelse + } ifelse +} bind def + +/DisplayImage +{ + % + % Display a DirectClass or PseudoClass image. + % + % Parameters: + % x & y translation. + % x & y scale. + % label pointsize. + % image label. + % image columns & rows. + % class: 0-DirectClass or 1-PseudoClass. + % compression: 0-none or 1-RunlengthEncoded. + % hex color packets. + % + gsave + /buffer 512 string def + /byte 1 string def + /color_packet 3 string def + /pixels 768 string def + + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + x y translate + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + currentfile buffer readline pop + token pop /pointsize exch def pop + /Times-Roman findfont pointsize scalefont setfont + x y scale + currentfile buffer readline pop + token pop /columns exch def + token pop /rows exch def pop + currentfile buffer readline pop + token pop /class exch def pop + currentfile buffer readline pop + token pop /compression exch def pop + class 0 gt { PseudoClassImage } { DirectClassImage } ifelse + grestore +} bind def +%%EndProlog +%%Page: 1 1 +%%PageBoundingBox: 0 0 375 281 +userdict begin +DisplayImage +0 0 +375.052 281.289 +12.000000 +500 375 +0 +0 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9F6F6F6F6F6F6FBFBFBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD +C2C2C25858582F2F2F303030767676D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6A6A61212122F2F2F4949493B3B3B +020202343434EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC4C4C41111114A4A4AE5E5E5FFFFFFF5F5F5717171070707979797FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF939393101010 +C4C4C4FFFFFFFFFFFFFFFFFFF4F4F4B4B4B4D3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF8F8F8D6D6D6F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8393939414141D8D8D87B7B7B525252535353 +9F9F9FFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB +8D8D8D282828E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF8F8F83838381515151F1F1F1A1A1A2727271F1F1F101010999999FCFCFCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA8A8A8A080808181818E0E0E0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8393939050505 +707070D3D3D3F3F3F3E3E3E35555550F0F0FA8A8A8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD5D5D5373737252525353535161616E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCE4E4E4E0E0E0 +DFDFDFEBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F83636363D3D3DF7F7F7FFFFFFFFFFFFFFFFFF +D5D5D50E0E0E797979FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF717171505050C4C4C4 +747474131313E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE6E6E67E7E7E212121121212111111383838A0A0A0F8F8F8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF9F9F94141413C3C3CF5F5F5FFFFFFFFFFFFFFFFFFDDDDDD101010797979FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9F2F2F2FFFFFF737373131313E0E0E0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +7979790404043E3E3E7575757070701E1E1E0A0A0ABBBBBBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6A6A60D0D0D +AEAEAEFCFCFCFFFFFFFEFEFEA3A3A3131313AAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF737373131313E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E22A2A2A717171EFEFEFFFFFFF +FFFFFFB8B8B8141414555555FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F04343431717176F6F6F969696818181 +1414144C4C4CF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +737373131313E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF8F8F8D4D4D4E9E9E9FFFFFFFFFFFFFFFFFFF8F8F8353535424242 +FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEFEFEDFDFDF6B6B6B060606050505131313686868E0E0E0FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF737373131313E0E0E0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC2323236C6C6CFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F2F2F2CDCDCDCBCBCBD4D4D4FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF737373131313E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FDFDFD8080801A1A1AD1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +737373131313E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD919191252525B5B5B5FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF737373131313E0E0E0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE4E4E4858585242424B4B4B4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF919191464646E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D93E3E3E323232 +B5B5B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFC3C3C3 +AAACADB7B8B9DFDFDFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FAFAFAF7F7F7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFD9D9D93D3D3D646464F0F0F0FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDEDE8E9899839B9D92AEB089A3A5829293C0C2C2 +FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC +6868680404045454546666666464646464646161618F8F8FFDFDFDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F0EFEF8B9596A3C4C7BDE3E6BDE2E5BDE3E6B3D8DA859899CECFCFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E13838381F1F1F1D1D1D1C1C1C +1C1C1C1C1C1C1818185B5B5BFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C1C1869EA0BDE2E5BBE0E3 +BBDFE2BADFE2BCE1E4A5C6C98C9293FDFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFBFBFBEAEAEAE8E8E8E9E9E9E9E9E9E9E9E9E9E9E9E8E8E8EFEFEF +FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +FBFBFBF4F4F4ECECECE4E4E491949494B1B3BDE2E5BBE0E3BBE0E3BBE0E3BBE0E3B1D4D7 +818B8CF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFC +F7F7F7EFEFEFE9E9E9DEDEDECFCFCFBFBFBFAEAEAE9E9E9E999999989898979797979797 +6F71718DA8ABBDE3E6BADFE2BBE0E3BBE0E3BBE0E3AED1D4828A8BF6F5F5FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF9F9F9 +F3F3F3EDEDEDE4E4E4D4D4D4C4C4C4B3B3B3A3A3A39C9C9C9A9A9A979797949494979797 +A5A5A5B5B5B5C5C5C5D5D5D5E0E0E0E8E8E8F2F2F2FDFDFDD6D6D6829496B8DDE0BBE0E3 +BBE0E3BBE0E3BDE2E595B2B4A4A8A8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF6F6F6 +F1F1F1E9E9E9D9D9D9C9C9C9B9B9B9A9A9A9A1A1A19C9C9C979797929292929292A1A1A1 +B0B0B0BFBFBFCECECEDBDBDBE4E4E4EFEFEFF9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDFDFCACB0B089A0A2AED1D3B5D9DCB4D8DB99B7B98F999A +ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF8F8F8F5F5F5 +EEEEEEDEDEDECECECEBEBEBEAFAFAFA5A5A59E9E9E9898989191918F8F8F9D9D9DABABAB +BABABAC8C8C8D4D4D4E0E0E0EBEBEBF7F7F7FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF8F8F8BABCBC848D8E7B898B6470719A9F9FE9E9E9FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDFBFBFBF8F8F8F2F2F2 +E3E3E3D3D3D3C4C4C4B5B5B5AAAAAAA1A1A19999999191918D8D8D9A9A9AA7A7A7B5B5B5 +C1C1C1CECECEDBDBDBE7E7E7F4F4F4FDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEF4F4F4 +DCDBDB8C8C8CE7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCFAFAFAF5F5F5E7E7E7 +D9D9D9CACACABBBBBBAFAFAFA5A5A59B9B9B9191918C8C8C979797A3A3A3AFAFAFBBBBBB +C9C9C9D6D6D6E3E3E3F0F0F0FBFBFBFDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E9E9ED7D7D7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFDFD +FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDFEFEFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCF8F8F8EBEBEBDDDDDD +CFCFCFC1C1C1B5B5B5AAAAAA9E9E9E9292928C8C8C9595959F9F9FAAAAAAB5B5B5C3C3C3 +D1D1D1DFDFDFEDEDEDF9F9F9FCFCFCFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5B5B5BEBEBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEAB0B2B28F9596979C9DC5C6C6F8F8F8FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF9F9F9C7C7C7999E9E8E9595ACAFAFE6E5E5FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFBFBFBEFEFEFE1E1E1D5D5D5 +C8C8C8BBBBBBAEAEAEA1A1A19494948C8C8C9494949C9C9CA6A6A6AFAFAFBCBCBCCBCBCB +DADADAEAEAEAF6F6F6FAFAFAFCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFCFCFCFA4A4A4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +D8D9D98894958FA9ACA2C2C59DBCBE869C9E9EA4A4F4F3F3FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5A0A5A6 +869B9D9CBBBDA2C3C590ACAE869395D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF2F2F2E5E5E5DADADACECECE +C1C1C1B3B3B3A5A5A59797978C8C8C9393939A9A9AA2A2A2AAAAAAB5B5B5C5C5C5D5D5D5 +E6E6E6F3F3F3F7F7F7FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4969696FBFBFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F18C9697A5C7C9BDE2E5BCE1E4 +BCE1E5BBE0E38FA8ABB0B3B4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7BABA8CA4A6BAE0E3BCE2E5BCE1E4BDE3E6 +A8CACD8A9595EEEEEEFFFFFFFFFFFFFFFFFFFDFDFDF5F5F5EAEAEADFDFDFD4D4D4C7C7C7 +B8B8B8A9A9A99B9B9B8F8F8F9393939999999F9F9FA4A4A4B0B0B0C0C0C0D0D0D0E1E1E1 +EFEFEFF4F4F4F9F9F9FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1989898EBEBEBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFCACBCB819698BCE2E5BBE0E3BBE0E3BADFE2BBE0E3B1D5D87C8687 +ECECECF6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 +F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 +F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 +F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 +F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 +F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 +F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6 +F6F6F6EFEFEF7D8787AED1D4BBE0E3BADFE2BBE0E3BBE0E3BCE2E5869D9FA0A1A1BFBFBF +AEAEAE9F9F9F9292929494949898989C9C9CA0A0A0AAAAAABBBBBBCBCBCBDBDBDBEAEAEA +F1F1F1F6F6F6FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFDFDFD9C9C9CDBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B5B5 +8DA7A9BCE2E5BADFE2BBE0E3BBE0E3BADFE2B8DDE0687678878686979797969696969696 +969696969696969696969696969696969696969696969696969696969696969696969696 +969696969696969696969696969696969696969696969696969696969696969696969696 +969696969696969696969696969696969696969696969696969696969696969696969696 +969696969696969696969696969696969696969696969696969696969696969696969696 +969696969696969696969696969696969696969696969696969696969696969696969696 +969696969696969696969696969696969696969696969696969696969696969696969696 +9696969696969696969696969696969696969696969696969696968C8B8B616D6EB8DDE0 +BADFE2BBE0E3BBE0E3BADFE2BCE2E58FABAD747878B7B7B7C5C5C5D6D6D6E5E5E5EDEDED +F3F3F3FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACACACC6C6C6 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5C5C5839A9CBDE2E5BBE0E3BBE0E3 +BBDFE2BBE0E3B3D8DB788384DEDDDDEAEAEAE9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 +E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 +E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 +E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 +E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 +E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 +E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9 +E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E2E1E1778283B1D5D8BBE0E3BADFE2BBE0E3BADFE2 +BCE2E589A2A4BBBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7C7C7ACACACFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEBEAEA859192ADD0D3BCE2E5BBE0E3BBE0E3BCE2E595B2B4A3A7A8 +FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEA9ADAD92AEB0BCE2E5BBE0E3BBE0E3BCE2E5B0D3D6859293E6E6E6FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE1E1E1969696FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +CBCCCD8494959FBFC1AFD2D5ABCED190ACAE929A9BEDECECFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF939B9B +8FAAACABCDD0B0D3D69FBFC2859697C7C9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF959595 +F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDDBDCDC787D7D697272 +848C8CACAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0AFB2B3747B7C646C6D939999 +D5D5D5FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA9C9C9CDFDFDFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6A6A6C5C5C5FDFCFCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7C7C7A2A1A1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFA7A7A7CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFAFAFA9A9A9AE1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC3C3C3AEAEAEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF +B4B4B4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC969696F2F2F2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB4B4B4FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADA9C9C9CFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD999999FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8BABABAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEDEDED929292F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC3C3C3B0B0B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFB3B3B3C1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7 +9A9A9AE4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9A9A9CBCBCBFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADADADC7C7C7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4A4A4D0D0D0FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFCFCFC999999E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8A8A8CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB7B7B7BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EDEDED979797EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFA2A2A2D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +D1D1D1A4A4A4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE999999FDFDFDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE9D9D9DDADADAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA929292FAFAFAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFC8C8C8ABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFE979797E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF6F6F6959595EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +ACACACC7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FDFDFD929292E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FDFDFDA2A2A2D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE979797E0E0E0FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD8C8C8CEEEEEEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C0C0C0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF0F0F0979797EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF9F9F98C8C8CF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACAABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF +9A9A9AFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F4F4F4909090F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE3E3E3969696FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACAA8A8A8FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF939393F4F4F4FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5909090F1F1F1 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB1B1B1C2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE9E9E9969696F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9E9E9EDBDBDBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF989898 +DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E4E4E4999999F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFAEAEAEC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2949494EEEEEEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF9C9C9CF9F9F9FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2B0B0B0 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE0E0E09B9B9BF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFDADADA9F9F9FFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDB9D9D9DFCFCFCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCCA7A7A7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +D5D5D5A2A2A2FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF2F2F28E8E8EF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4B4B4BFBFBFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0D0D0A5A5A5FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA989898 +E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF9C9C9CDADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFCACACAA8A8A8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAACACACAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5929292EEEEEE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +C5C5C5ABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFBDBDBDB4B4B4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E29B9B9BF8F8F8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0B0B0B0FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D4 +A3A3A3FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFCECECEA6A6A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFBBBBBBB6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB939393F8F8F8FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7B7B7BBBBBBFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B6B6B6BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFAFAFA919191EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFE9F9F9FD7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C2C2C2FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +A5A5A5D1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F8F8F8909090EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFACACACC9C9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B9B9B9FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4989898F8F8F8FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A7A7A7CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFCECECEA7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFCFCFCFA6A6A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA2A2A2D5D5D5FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E3E3E3999999F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +BABABAB8B8B8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFDFDFD9D9D9DDBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F78F8F8FEFEFEFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA3A3A3D3D3D3FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC +979797E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFE9D9D9DDADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFAFAFA909090ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC929292E8E8E8FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFB3B3B3BFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9 +959595F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFBFBFB8D8D8DEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C9AAAAAAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D1A5A5A5FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA +8A8A8AF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD9D9D9DFAFAFAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFBBBBBBB7B7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F48E8E8EF5F5F5FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF1F1F1929292F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA7A7A7 +CECECEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEFEFEF919191F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE969696E2E2E2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA949494E8E8E8FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9 +959595F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADADADC7C7C7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFECECEC929292F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4989898F9F9F9FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC4C4C4AEAEAEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D4A2A2A2 +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFDDDDDD9C9C9CFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8D8D89F9F9F +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBBB6B6B6FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8D8D8 +A0A0A0FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB979797F3F3F3FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFA8A8A8CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3A4A4A4FDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFBFBFB949494E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA979797E3E3E3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFCDCDCDA7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5A5A5 +CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F08F8F8FF7F7F7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8 +ABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB4B4B4FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD9D9D99F9F9FFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3AEAEAEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD4D4D4A0A0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB4B4B4FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFBCBCBCB3B3B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6 +999999F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4A4A4717171 +7373737373737373737373737474747A7A7AE3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAACACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8 +B9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7949494EAEAEAFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6565650F0F0F131313131313131313141414 +0D0D0D101010D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FAFAFA9B9B9BDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BFBFBFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF9D9D9DD8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEBEBEBDFDFDFE0E0E0E0E0E0E2E2E2D4D4D44F4F4F898989FBFBFBFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1909090F5F5F5FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFAFAFAFC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B6B6B6BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF2F2F26969693D3D3DE6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFDCDCDC9B9B9BFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAA +CBCBCBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0D0D0A3A3A3FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8B8B8B131313 +C8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +C2C2C2B1B1B1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA6A6A6D0D0D0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE2E2E2989898F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4282828626262FBFBFBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAAC8C8C8FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFDFDFDA1A1A1D6D6D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F1F1F1979797ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF8B8B8B151515C8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFAFAFA9D9D9DDDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC9D9D9D +DCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE999999DDDDDDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4282828636363FAFAFA +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2 +929292F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB979797E3E3E3FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEAEAEC5C5C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF8A8A8A161616C7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E0979797FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFAFAFA939393E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC9C9C9AAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +696969191919E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFC5C5C5AFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F98F8F8F +EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF989898FDFDFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E42C2C2C606060F9F9F9FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACACAC +C6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F88A8A8AF4F4F4FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE979797EFEFEFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD3D3D30A0A0A888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9D9D9DDBDBDBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF4F4F48B8B8BF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFBFBFB999999E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB +929292CACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF1F1F1959595EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8F8F8F +F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7A7A7CCCCCC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E3959595 +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8949494F9F9F9FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0B3B3B3FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C9ABABABFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE2E2E2999999FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFDBDBDB9B9B9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFADADADC5C5C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC9D9D9D +FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCD6D6D6989898 +969696ABABABF1F1F1FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB929292 +EEEDEDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD9D9D9DDADADA +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A1A1A1FDFDFDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFAFAFA8B8B8B1D1D1D0404040404040909093F3F3FD4D4D4 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9BDBEBE656B6B8089899CA0A0D3D4D4FDFDFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1979797ECECECFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD1D1D1A5A5A5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC +868686070707626262C9C9C9C8C8C8797979171717717171FCFCFCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F8F8F8A4AAAA889EA0A0C0C3A7C9CC9BBABD839596BDBFC0FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE4E4E4959595FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBA9A9A9 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4656565727272F1F1F1FFFFFF +FFFFFFFFFFFF595959232323EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFC1C1889FA1BADFE2BCE2E5 +BCE1E4BDE2E5B3D7DA829294DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDA6A6A6FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5C5C5AEAEAEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFEFEFEFFFFFFFEFEFEFFFFFFB9B9B9191919444444 +F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFDFCFC8C9292A6C7CABCE1E4BADFE2BBE0E3BADFE2BDE3E690ABAE +ACAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC0C0C0B2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFCFCFC7A7A7A4848481616161E1E1ED7D7D7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9E4E4E4D1D1D1C7C7C7B4B4B4 +656F6FAFD1D4BBE0E3BBE0E3BBE0E3BBE0E3BCE2E59BB9BC9BA0A0FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF9C9C9CDADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBABABAB6B6B6 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC646464 +2B2B2B252525101010A2A2A2FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBE7E7E7D6D6D6CDCDCDC1C1C1 +9B9B9B8080807C7C7C8282827070706B6B6B7F7F7FA3A3A36C7273A6C8CABCE1E4BADFE2 +BBE0E3BADFE2BDE3E68FABADADAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3989898EAEAEAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4B4B4BBBBBBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7F7F7F5F5F5E3E3E34E4E4E111111 +B3B3B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAE9E9E9DBDBDBD3D3D3C6C6C6 +9F9F9F8686868181818787876F6F6F6A6A6A7D7D7DA1A1A1A7A7A7B2B2B2CACACAE9E9E9 +F3F3F3F7F7F7FCFCFCFFFFFFC2C3C3879D9FB9DFE2BCE2E5BCE1E4BDE2E5B3D7DA829193 +DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE5E5E5979797F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB0B0B0C1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACA0707078E8E8EFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBEBEBEBDFDFDFD8D8D8CACACA +A2A2A28B8B8B8787878686866E6E6E6868687C7C7C9B9B9BA0A0A0ACACACC7C7C7E7E7E7 +EFEFEFF4F4F4FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F9F9F9A9ADAD869C9EA0C0C3A8CACC9CBBBD839496C1C4C4FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +D0D0D0A3A3A3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACACACC7C7C7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6888888999999F8F8F8FFFFFF +FFFFFFFFFFFFC2C2C20B0B0B999999FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBEEEEEEE4E4E4DEDEDECECECE +A7A7A79191918E8E8E8B8B8B6C6C6C6767677D7D7D9999999A9A9AA6A6A6C2C2C2E3E3E3 +EAEAEAF0F0F0F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9C4C5C5959A9A +6971717C7F80D6D7D7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6B6B6BDBDBDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8A8A8CCCCCCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF9F9F96868680A0A0A868686E7E7E7E7E7E7D1D1D13939392D2D2D +E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF1F1F1E9E9E9E3E3E3D1D1D1 +ABABAB9797979393938989896C6C6C6666667C7C7C939393939393A1A1A1C0C0C0E1E1E1 +E6E6E6EDEDEDF8F8F8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBBB2B2B2FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF9D9D9DD8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEA5A5A5D2D2D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F0F0F0676767101010191919191919151515212121B5B5B5FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF4F4F4ECECECE8E8E8D3D3D3 +B1B1B19D9D9D9A9A9A8B8B8B6C6C6C6767677C7C7C8F8F8F8D8D8D9B9B9BBDBDBDDBDBDB +E1E1E1E9E9E9F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFD6D6D6A0A0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5 +969696E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA0A0A0D8D8D8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4B6B6B6696969 +676767818181DDDDDDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF7F7F7F0F0F0ECECECD6D6D6 +B6B6B6A3A3A39F9F9F8B8B8B6D6D6D6868687C7C7C8A8A8A878787979797BABABAD7D7D7 +DCDCDCE6E6E6F5F5F5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E8E8E8919191FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5989898F6F6F6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9D9D9DDDDDDDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9F4F4F4F1F1F1D9D9D9 +BBBBBBAAAAAAA6A6A68E8E8E6F6F6F6969697C7C7C858585818181919191B5B5B5D0D0D0 +D6D6D6E2E2E2F4F4F4FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2929292F2F2F2FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD3D3D3A1A1A1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFAFAFA989898E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF7F7F7F3F3F3DBDBDB +BFBFBFB0B0B0ABABAB8F8F8F7070706B6B6B7F7F7F8181817C7C7C8D8D8DB3B3B3CBCBCB +D1D1D1DFDFDFF2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF8F8F89A9A9AE3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9 +BABABAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9959595E9E9E9 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCFAFAFAF6F6F6DEDEDE +C5C5C5B7B7B7B2B2B29191917272726E6E6E7F7F7F7C7C7C777777898989B1B1B1C4C4C4 +CCCCCCDBDBDBF3F3F3FEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFEA2A2A2D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0A0A0D5D5D5FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDE7E6E6818181E6E5E5FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCF7F7F7DFDFDF +C9C9C9BDBDBDB6B6B6949494767676717171818181797979737373868686AEAEAEBFBFBF +C6C6C6D7D7D7F1F1F1FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADADADC4C4C4FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF7F7F7959595E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9 +9DA2A27B87886B7A7B7C8686B7B9B9F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDF9F9F9E2E2E2 +CECECEC3C3C3BABABA9595957A7A7A757575808080747474707070838383A9A9A9B8B8B8 +C0C0C0D3D3D3F0F0F0FAFAFAFCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB5B5B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6999999 +F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC8B969699B7B9B5D9DCB8DDE0B0D4D7 +8AA2A4ABAEAFFDFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9E5E5E5 +D3D3D3CACACABFBFBF9898987E7E7E7A7A7A8484847272726D6D6D818181A7A7A7B1B1B1 +BBBBBBD1D1D1EDEDEDF8F8F8FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD1D1D1A5A5A5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D5A0A0A0FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFA8ABAB94B0B2BDE2E5BBE0E3BBE0E2BBE0E3B8DDE0829697CECECEE9E9E9 +D8D8D8D0D0D0C3C3C39B9B9B8282827E7E7E8383836F6F6F6A6A6A7E7E7EA2A2A2AAAAAA +B5B5B5CDCDCDECECECF4F4F4F8F8F8FDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4949494FDFDFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFBDBDBDB6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4869090AACDD0 +BCE1E4BBE0E3BBE0E3BADFE2BDE2E594B1B35D60606F6F6F6969697F7F7F9F9F9FA4A4A4 +AFAFAFC8C8C8E8E8E8F1F1F1F5F5F5FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F28E8E8EF6F6F6FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3A3A3D1D1D1 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0828D8EAED1D4BBE1E4BBE0E3BBE0E3BADFE2 +BDE2E597B5B8939696EEEEEEF2F2F2FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF8F8F8979797E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA939393E8E8E8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFBFBFB949A9AA0C1C3BCE2E5BADFE2BADFE2BBE0E3BCE2E589A1A3BABCBCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA1A1A1D7D7D7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE8E8E8989898F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D3D3839697 +B2D6D9BDE3E6BDE2E5BDE2E5A2C2C58E9798F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACACACC6C6C6FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6A0A0A0FEFEFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC1C3C4839293869FA18EA9AB849A9C +8E9798DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFBABABAB8B8B8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0B2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEFEFEE5E5E58C8D8D858788C7C8C8F0F0F0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDA8A8A8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFA7A7A7CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFAEAEAEC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF9A9A9AFCFCFCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC939393E7E7E7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6A6A6CECECEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF0F0F08E8E8EF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFECECEC959595F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA1A1A1D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8929292 +EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +D6D6D6A0A0A0FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FAFAFA9B9B9BE0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC9E9E9EDBDBDBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2AFAFAFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7959595E9E9E9FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFABABABC8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFABABABC9C9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF4F4F48F8F8FF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9 +B8B8B8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC +959595E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EFEFEF8C8C8CFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C9ABABABFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0919191F4F4F4FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6939393FDFDFDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFDADADA9E9E9EFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD9D9D99F9F9FFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFDADADA9D9D9DFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC +919191F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3 +AFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +CFCFCFA6A6A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F88E8E8EF0F0F0FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEAEAEC5C5C5FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3B0B0B0FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFCFCFC9B9B9BDEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFCFCFC999999E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A8A8A8CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F38F8F8F +F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +AEAEAEC2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6B6B6BBBBBBFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD9C9C9CFBFBFBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7A7A7CBCBCBFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFC6C6C6ACACACFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC5C5C5AEAEAEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEFEFEA2A2A2D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +D7D7D7A1A1A1FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAFC3C3C3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA +9D9D9DDDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7969696F8F8F8FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC9D9D9DDBDBDBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7999999E5E5E5FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF6F6F68D8D8DF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF5F5F58F8F8FF2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF3F3F3949494EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FCFCFC969696E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E0999999FBFBFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0 +8F8F8FF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA6A6A6D0D0D0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7C7C7ACACACFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA8F8F8FFDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5B5B5BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFB1B1B1C1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFDFDFDF989898FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC4C4C4ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA0A0A0D8D8D8FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3 +A2A2A2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3A3A3A3FEFEFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF6F6F6919191EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C9ACACACFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E3999999F8F8F8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E5E5E5959595FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFBDBDBDB6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF3F3F3919191F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACAAAAAAAFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B2 +C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC929292E8E8E8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB2B2B2C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7A7A7CACACAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA1A1A1D5D5D5FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD +A1A1A1D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFA1A1A1D2D2D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB1B1B1C2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5949494ECECECFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC9E9E9E +DADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3AEAEAE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE9E9E9929292FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F79B9B9BE2E2E2FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D1A3A3A3FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCECECE +A7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF3F3F3979797EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE0E0E09C9C9CF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3BFBFBFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF949494 +F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE959595 +F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEFEFEA2A2A2D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB909090FAFAFAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB909090EBEBEBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5989898 +E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE4E4E4939393FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF9C9C9CD9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA919191FAFAFAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D99D9D9D +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEAEAE +C6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD3D3D3A2A2A2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDA8A8A8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0B2B2B2FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7B7B7BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC1C1C1B2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD0D0D0A2A2A2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA1A1A1D3D3D3FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7B7B7BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE +9C9C9CFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF6F6F6999999E5E5E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABABC7C7C7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB979797F2F2F2FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA949494F7F7F7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFA0A0A0D1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF8F8F8939393EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D79E9E9EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE9D9D9DD9D9D9 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +989898DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFBBBBBBB8B8B8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F99B9B9BE1E1E1FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9A9A9CBCBCBFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2A2A2D2D2D2FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF4F4F4999999E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFBCBCBCB7B7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF7F7F7999999E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0979797EEEEEE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +CFCFCFA4A4A4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EAEAEA969696F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB959595F6F6F6FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC9B9B9BFDFDFDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D99C9C9CFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE5E5E5939393FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE8E8E8999999F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFBFBFBFB4B4B4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD989898FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F5F5F5969696EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A4A4A4CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3A2A2A2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF969696E0E0E0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9989898E3E3E3FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC6C6C6AEAEAEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5A5A5CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEBEBEB979797F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBBB8B8B8FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFB8B8B8BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDB +9B9B9BFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAFC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBA8A8A8FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2B0B0B0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFA4A4A4CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC999999FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFA8A8A8CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B9B9BD8D8D8FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE7E7E7989898F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC969696 +E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFCFCFC999999DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1989898EBEBEB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC979797F1F1F1FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F6F6F6999999E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC979797E1E1E1FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFDCDCDC9C9C9CFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0989898ECECECFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFA0A0A0D3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6C6C6ACACAC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEBEBEB979797F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4B4B4C0C0C0 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABABC8C8C8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E5E5E5969696F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7C7C7ADADADFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFE969696E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF969696FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFDADADA9B9B9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF969696F0F0F0 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFD6D6D69D9D9DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6959595 +F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC9D9D9DFBFBFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +CACACAA9A9A9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0979797EDEDEDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC8C8C8A9A9A9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0B4B4B4FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF9F9F99A9A9AE1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B0B0C4C4C4FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB5B5B5BFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E9E9E +D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFE989898E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A9A9A9CACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEAEAEC4C4C4FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F2F2F2939393F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9D9DD6D6D6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFC2C2C2B1B1B1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE9C9C9CF9F9F9FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF969696DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6 +9E9E9EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFC9C9C9A9A9A9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA +969696E5E5E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7939393FCFCFCFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B3B3B3C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3979797EBEBEBFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEFEFEF959595F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE9B9B9BDBDBDBFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFECECEC989898F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7 +9A9A9AE3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF5F5F5919191F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6 +999999F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9FD6D6D6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E1 +9B9B9BF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF999999FCFCFCFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFABABABC7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBA8A8A8FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD9D9D99B9B9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +BEBEBEB5B5B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB5B5B5BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF +A3A3A3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D1A4A4A4FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA0A0A0 +D6D6D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDECECECE8E8E8E9E9E9E9E9E9E9E9E9 +E8E8E8EDEDEDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C4AFAFAFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE4E4E4939393FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8909090EFEFEFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF2F2F24747471A1A1A1C1C1C1C1C1C1C1C1C191919464646F4F4F4FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB8B8B8BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F0F0F0929292F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE5E5E5979797F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACA1C1C1C +4E4E4E656565646464646464626262808080F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEAEAE +C6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6999999E6E6E6FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDA7A7A7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF939393060606CCCCCCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3A3A3D1D1D1FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA0A0A0D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB7B7B7BABABAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF929292090909C8C8C8C0C0C0A8A8A8BEBEBEF9F9F9FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF989898DCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFA8A8A8C9C9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEA3A3A3D3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC707070252525 +4646460F0F0F0000000D0D0D545454DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD929292 +E5E5E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B9B9B9FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9929292EBEBEB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB242424161616696969B8B8B8BABABA9A9A9A +1313134E4E4EF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6959595EBEBEBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDA8A8A8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9949494F9F9F9FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF8F8F8B9B9B9CBCBCBFDFDFDFFFFFFFFFFFFFFFFFFA2A2A2101010B4B4B4FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEFEFEF979797EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE0E0E0979797FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD0D0D0A6A6A6FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFC8C8C8050505989898FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8999999 +F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8F8F8FF8F8F8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B8B8B8FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBD7D7D7E3E3E3FFFFFFFFFFFFFFFFFFFFFFFF +C8C8C8050505989898FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E19B9B9BF9F9F9FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6959595EAEAEAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA5A5A5D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF0F0F03E3E3E323232D1D1D1FFFFFFFFFFFFF7F7F77777771B1B1BCCCCCCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD9D9D99D9D9DFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFBFBFB9F9F9FDADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F9F9F9959595E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9797970D0D0D +2F2F2F7474747575755A5A5A0A0A0A767676FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D1A1A1A1 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8A8A8CBCBCB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED929292F9F9F9FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6BABABA2929291212121111112C2C2C +929292F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8AAAAAAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6B6B6BBBBBBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFDFDFDDDDDDDAEB0B1898C8C7F8181EEEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFDFDFDE6E6E6E0E0E0DFDFDFE7E7E7FEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFBDBDBDB5B5B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC8C8C8ACACACFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBB9BBBB8292938FAAAC +94B3B5859C9E8C9697DEDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3C1C1C1 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDB9D9D9D +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFC9CACB85999AB4D9DCBCE2E5BCE2E5BCE2E5A2C2C58D9798 +F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7A7A7CDCDCDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE8E8E8EFAFAFAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8 +8E9596A5C6C8BCE2E5BADFE2BBE0E3BBE0E3BCE2E5869EA0BFBFC0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF9D9D9DD8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF6F6F6919191EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC7F8C8DB1D4D7BBE0E3BBE0E3 +BBE0E3BBE0E3BDE3E694B1B4A5A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF939393E3E3E3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9C9C9C +DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF2F1F1858F8FADCFD2BBE1E4BBE0E3BBE0E3BADFE2BDE3E68CA8AB +A9ABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB909090EBEBEBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7A7A7CDCDCDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +A6AAAA94B1B3BDE3E6BBE0E3BBE0E3BCE1E4B6DBDE758688838484BBBBBBEBEBEBFEFEFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF2F2F2949494EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB4B4B4BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB8F979897B4B6B2D6D9 +B7DCDFABCDD0869C9EB2B5B5ECEBEBBABABA979797AFAFAFE0E0E0FDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA979797F3F3F3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5C5C5 +AEAEAEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECA2A7A77B8787748183848E8FC1C3C3FAFAFA +FFFFFFFEFEFEF3F3F3C5C5C59C9C9CA5A5A5D6D6D6F9F9F9FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E29A9A9AF7F7F7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A1A1A1FDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFBFBFBF2F2F2EFEEEEF6F5F5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F8F8F8D2D2D2A2A2A29C9C9CCBCBCBF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFDBDBDB9E9E9EFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE9E9E9939393FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBDFDFDF +AAAAAA999999BEBEBEEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3A1A1A1FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6 +8E8E8EF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDE8E8E8B6B6B6989898 +B3B3B3E5E5E5FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACAA7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB999999E2E2E2FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFC1C1C19A9A9AA8A8A8DBDBDB +FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC0C0C0B2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEFEFEA6A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5CECECE9E9E9EA0A0A0CFCFCFF6F6F6FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB6B6B6BDBDBDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B2B2B2BFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFAFAFAD9D9D9A7A7A79B9B9BC3C3C3F1F1F1FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADADADC7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1C1C1B0B0B0FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFDFDFDE3E3E3B1B1B1979797B6B6B6E9E9E9FDFDFDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFA3A3A3D3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFD3D3D3A3A3A3FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAC2C2C2A0A0A0A0A0A0CCCCCC +FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EDEDEDBDBDBD979797ACACACDFDFDFFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE989898DFDFDFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E4E4E4979797FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEAEAEA606060121212010101010101181818737373F4F4F4FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4C8C8C8 +9C9C9CA2A2A2D3D3D3F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDFDFD8F8F8FEAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F48D8D8DF5F5F5FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6A6A6A0A0A0A +8F8F8FC3C3C3C3C3C37C7C7C121212B9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAD6D6D6A4A4A49B9B9B +C7C7C7F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F7F7F78F8F8FF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFBFBFB949494E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE4B4B4B2E2E2EF4F4F4FFFFFFFFFFFFE6E6E6 +191919696969FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCE1E1E1AEAEAE979797BBBBBBEBEBEB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF949494F3F3F3FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFEA2A2A2D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF676767242424E0E0E0FFFFFFFFFFFFCECECE161616838383FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEEAEAEAB9B9B9979797B0B0B0E2E2E2FDFDFDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE6E6E6989898F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C1C1C1FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB555555 +3636365656565656562F2F2F6A6A6AF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEFEFEF2F2F2C4C4C49B9B9BA5A5A5D6D6D6FAFAFAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +DDDDDD9D9D9DFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0B1B1B1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C94B4B4B1A1A1A2727272626261A1A1A +595959D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF7F7F7D2D2D2A2A2A29D9D9DCCCCCCF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D4A2A2A2FDFDFDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD0D0D0A5A5A5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF5F5F5494949272727C8C8C8F2F2F2F2F2F2B7B7B71A1A1A626262FBFBFBFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB +DDDDDDA9A9A9999999C0C0C0EDEDEDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFCBCBCBA7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E09B9B9BFAFAFA +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1C1C10707079E9E9E +FFFFFFFFFFFFFFFFFFFFFFFF818181111111D6D6D6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDE7E7E7B4B4B4 +989898B3B3B3E5E5E5FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +C3C3C3ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF919191F5F5F5FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBCBC0101019B9B9BFFFFFFFFFFFFFFFFFFFFFFFF +7E7E7E0A0A0AD3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEEEEEEEC1C1C19A9A9AA9A9A9 +DDDDDDFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBABABAB8B8B8FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFBFBFB909090EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFDBDBDB2D2D2D262626C2C2C2EDEDEDEEEEEEB0B0B01A1A1A404040E9E9E9FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5CCCCCC9E9E9EA0A0A0D1D1D1F7F7F7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB0B0B0C4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE9E9E9ED9D9D9 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCC2E2E2E +1515152020202020201212123F3F3FDBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFAFAFAD9D9D9A6A6A69B9B9BC3C3C3F2F2F2FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +A6A6A6CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAEAEAEC6C6C6FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E38A8A8A5C5C5C5C5C5C989898 +E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFDFDFDE2E2E2B1B1B1989898B8B8B8EAEAEAFEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE9E9E9ED9D9D9FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFEBEBEBBCBCBC979797ADADADE0E0E0FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFDFDFD949494E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDA6A6A6 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4 +C8C8C89B9B9BA4A4A4D3D3D3F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB +8C8C8CEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD9D9D9DFAFAFAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9D3D3D3A4A4A4 +9C9C9CC8C8C8F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F38F8F8FF4F4F4FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F9F9F98888889B9B9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE9E9E98A8989DFDEDEFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCDFDFDFACACAC979797BCBCBC +ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE9E9E9959595F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9848484020202747474FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE8D9394606D6D +7A8889888F90CFD0D0FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDEAEAEAB7B7B7989898B1B1B1E2E2E2FDFDFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E1 +9B9B9BF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFC7C7C7121212000000757575FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFDBDBDB859394A2C2C5B5DADDB5DADCA8CACC869899C7C9C9 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEFEFEF1F1F1C3C3C39B9B9BA7A7A7D9D9D9F9F9F9FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8D8D8A1A1A1FCFCFCFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D4333333 +3E3E3E0C0C0C747474FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA +8F9697A3C3C6BCE2E5BBE0E3BBE0E3BCE1E4AFD2D5839091EBEBEBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF7F7F7D0D0D0A0A0A09E9E9ECDCDCDF5F5F5FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFCECECEA7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA5C5C5C1F1F1FA4A4A4161616737373FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E47D8B8DB7DCDFBADFE2BBE0E3 +BBE0E3BBE0E3BDE2E5809596CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FAFAFADCDCDCA9A9A99A9A9AC1C1C1EEEEEEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C4 +ADADADFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF9292921E1E1EBBBBBBE1E1E1131313737373FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF4F4F4EBEBEBE2E2E2 +D5D5D5C3C3C3B2B2B28888886B7C7DBADFE2BADFE2BBE0E3BBE0E3BADFE2BDE2E5859C9E +C3C3C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDE5E5E5 +B3B3B3999999B5B5B5E7E7E7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBBB5B5B5FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9313131676767FBFBFB +E0E0E0131313737373FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF6F6F6EEEEEEE6E6E6 +D8D8D8C5C5C5B4B4B4A2A2A29999999898989797979696969E9E9EB1B1B1C2C2C2CAC9C9 +788484B2D6D9BBE0E3BADFE2BADFE2BBE0E3BADFE27B8D8FDBDADAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEEDEDEDBFBFBF999999 +A9A9A9DEDEDEFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB4B4B4BFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE2E2E23B3B3B525252E0E0E0F1F1F1D1D1D11212126C6C6CF3F3F3 +FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF7F7F7F1F1F1E9E9E9 +DBDBDBC9C9C9B6B6B6A5A5A59C9C9C9999999696969393939C9C9CAEAEAEBFBFBFD0D0D0 +DEDEDEE8E8E8F3F3F3FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFB3B6B68CA5A7B9DEE1BDE2E5 +BDE2E5BCE1E498B6B89DA3A4F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4CCCCCC9D9D9DA2A2A2D2D2D2 +F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAA +CACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBCBC +0303031919192424242323231E1E1E0202020F0F0F303030D9D9D9FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9F3F3F3EDEDED +DDDDDDCBCBCBB9B9B9A8A8A8A0A0A09A9A9A9595959191919B9B9BABABABBDBDBDCDCDCD +DADADAE5E5E5F1F1F1FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF5F5F5A6AAAA8093958FAAAD92ADB0829799989FA0ECECEC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAD6D6D6A5A5A59B9B9BC6C6C6F3F3F3FEFEFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA2A2A2D5D5D5FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D45F5F5F5B5B5B5A5A5A5A5A5A +4F4F4F060606282828656565E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFAFAFAF6F6F6EFEFEF +DFDFDFCECECEBDBDBDACACACA3A3A39B9B9B9494948E8E8E9A9A9AAAAAAABABABAC9C9C9 +D6D6D6E3E3E3F0F0F0FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFAFAFAD4D4D4AEB0B1AAADADCACACBF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFDFDFDE1E1E1AFAFAF979797B9B9B9EAEAEAFEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFCFCFC999999E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E0131313737373FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF8F8F8F2F2F2 +E1E1E1D1D1D1BFBFBFB0B0B0A6A6A69C9C9C9393938D8D8D999999A7A7A7B6B6B6C5C5C5 +D3D3D3E1E1E1EEEEEEFBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEEBEBEBBABABA989898AEAEAEE1E1E1FCFCFCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA909090 +EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE0E0E0151515757575FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDFAFAFAF3F3F3 +E3E3E3D3D3D3C3C3C3B4B4B4A8A8A89D9D9D9292928C8C8C989898A5A5A5B3B3B3C1C1C1 +CFCFCFDEDEDEEDEDEDFAFAFAFDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F3F3F3C6C6C69B9B9BA4A4A4D6D6D6FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F88B8B8BF4F4F4FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F6F6F6BDBDBDD8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFCFCFCF4F4F4 +E5E5E5D6D6D6C7C7C7B8B8B8ABABAB9F9F9F9292928C8C8C989898A4A4A4AFAFAFBCBCBC +CCCCCCDCDCDCECECECF9F9F9FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8D3D3D3 +A2A2A29C9C9CC9C9C9F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEFEFEF909090F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDF5F5F5 +E7E7E7D9D9D9CACACABCBCBCAEAEAEA0A0A09292928D8D8D979797A2A2A2ACACACB9B9B9 +C9C9C9D9D9D9EAEAEAF7F7F7FAFAFAFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCDFDFDFACACAC989898 +BEBEBEEDEDEDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5979797 +F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF6F6F6 +E9E9E9DCDCDCCECECEC0C0C0B1B1B1A1A1A19292928F8F8F9797979F9F9FA8A8A8B4B4B4 +C6C6C6D7D7D7E8E8E8F5F5F5F9F9F9FDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDE8E8E8B6B6B6989898B2B2B2E4E4E4 +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADA9E9E9EFCFCFCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7 +EAEAEADFDFDFD3D3D3C4C4C4B3B3B3A3A3A39393939191919797979E9E9EA4A4A4B1B1B1 +C2C2C2D5D5D5E6E6E6F2F2F2F7F7F7FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF0F0F0C2C2C29B9B9BA7A7A7D9D9D9FAFAFAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD1D1D1A5A5A5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7F7F7 +EDEDEDE2E2E2D7D7D7C7C7C7B6B6B6A5A5A59494949393939797979C9C9CA1A1A1AEAEAE +C0C0C0D2D2D2E4E4E4EFEFEFF5F5F5FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF6F6F6CFCFCFA0A0A09F9F9FCFCFCFF5F5F5FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7C7C7ACACAC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8F8F8 +EFEFEFE5E5E5DBDBDBCBCBCBB9B9B9A7A7A79797979595959797979A9A9A9C9C9CABABAB +BDBDBDCFCFCFE1E1E1ECECECF3F3F3FAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFAFAFADADADAA7A7A79A9A9AC2C2C2F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDB3B3B3FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9 +F1F1F1E8E8E8DFDFDFCDCDCDBBBBBBAAAAAA9A9A9A989898989898989898999999A8A8A8 +BBBBBBCCCCCCDEDEDEE8E8E8F0F0F0F9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC +E5E5E5B2B2B2979797B6B6B6E8E8E8FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB6B6B6BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFAFAFA +F3F3F3ECECECE2E2E2D1D1D1BEBEBEACACAC9D9D9D9A9A9A979797959595969696A7A7A7 +B8B8B8C9C9C9DADADAE5E5E5EEEEEEF8F8F8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDEDBDBDBD +989898ABABABDFDFDFFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2CBCBCB7D7F7FA1A2A2 +F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFB +F5F5F5EFEFEFE5E5E5D3D3D3C2C2C2AFAFAFA1A1A19C9C9C989898939393949494A4A4A4 +B5B5B5C6C6C6D6D6D6E1E1E1ECECECF7F7F7FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4CACACA9C9C9CA2A2A2 +D3D3D3F9F9F9FFFFFFDBDBDB8D969783989A89A4A68297998B9596D7D8D8FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC +F7F7F7F2F2F2E8E8E8D6D6D6C4C4C4B2B2B2A5A5A59E9E9E989898919191939393A2A2A2 +B2B2B2C3C3C3D2D2D2DEDEDEEAEAEAF6F6F6FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9D6D6D6A4A4A49D9D9DB8B8B8879293 +A4C5C7BBE1E4BCE2E5BCE1E4A6C7CA869394E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFDFDFD +F9F9F9F5F5F5EAEAEAD8D8D8C7C7C7B6B6B6A9A9A9A0A0A09898988F8F8F919191A0A0A0 +B0B0B0BFBFBFCECECEDBDBDBE8E8E8F5F5F5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDE1E1E17F81818DA9ABBDE3E6BBE0E3BBE0E3BADFE2 +BDE3E693B0B29B9E9EDDDDDDCACACAB9B9B9ACACACA2A2A29898988E8E8E9191919F9F9F +ADADADBBBBBBCACACAD8D8D8E6E6E6F4F4F4FDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFCFBFB949999A2C2C5BCE1E5BBE0E3BBE0E3BBE0E3BCE1E4A5C6C96168699A9999 +ABABABB7B7B7C6C6C6D5D5D5E4E4E4F4F4F4FCFCFCFEFEFEFEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD969A9A9FBFC1 +BCE2E5BADFE2BBE0E3BBE0E3BCE2E5A2C2C5919697F9F9F9FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9BBBB8AA2A4BCE1E5BBE0E3BADFE2BBE0E3 +BDE2E58CA6A8B5B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF4F4F4969D9E94B1B3B6DBDEBBE0E4B7DCDF97B4B7929A9BF1F1F1FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE +A3A8A87987887B8C8D788788A0A5A6EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBEAEAEADCDCDCE9E9E8 +FBFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + +end +%%PageTrailer +%%Trailer +%%EOF diff --git a/doc/doxygen/figures/polygon_connectivity_small.png b/doc/doxygen/figures/polygon_connectivity_small.png new file mode 100644 index 000000000..c0d84ccab Binary files /dev/null and b/doc/doxygen/figures/polygon_connectivity_small.png differ diff --git a/doc/doxygen/figures/polyhedron_connectivity.png b/doc/doxygen/figures/polyhedron_connectivity.png new file mode 100755 index 000000000..f7d579691 Binary files /dev/null and b/doc/doxygen/figures/polyhedron_connectivity.png differ diff --git a/doc/doxygen/figures/polyhedron_connectivity_small.eps b/doc/doxygen/figures/polyhedron_connectivity_small.eps new file mode 100644 index 000000000..25b81ec07 --- /dev/null +++ b/doc/doxygen/figures/polyhedron_connectivity_small.eps @@ -0,0 +1,15904 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: (ImageMagick) +%%Title: (polyhedron_connectivity_small.eps) +%%CreationDate: (Thu Feb 28 14:07:37 2008) +%%BoundingBox: 0 0 375 281 +%%HiResBoundingBox: 0 0 375.052 281 +%%DocumentData: Clean7Bit +%%LanguageLevel: 1 +%%Pages: 1 +%%EndComments + +%%BeginDefaults +%%EndDefaults + +%%BeginProlog +% +% Display a color image. The image is displayed in color on +% Postscript viewers or printers that support color, otherwise +% it is displayed as grayscale. +% +/DirectClassPacket +{ + % + % Get a DirectClass packet. + % + % Parameters: + % red. + % green. + % blue. + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + compression 0 eq + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/DirectClassImage +{ + % + % Display a DirectClass image. + % + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { DirectClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayDirectClassPacket } image + } ifelse +} bind def + +/GrayDirectClassPacket +{ + % + % Get a DirectClass packet; convert to grayscale. + % + % Parameters: + % red + % green + % blue + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 eq + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/GrayPseudoClassPacket +{ + % + % Get a PseudoClass packet; convert to grayscale. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 eq + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassPacket +{ + % + % Get a PseudoClass packet. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + compression 0 eq + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassImage +{ + % + % Display a PseudoClass image. + % + % Parameters: + % class: 0-PseudoClass or 1-Grayscale. + % + currentfile buffer readline pop + token pop /class exch def pop + class 0 gt + { + currentfile buffer readline pop + token pop /depth exch def pop + /grays columns 8 add depth sub depth mul 8 idiv string def + columns rows depth + [ + columns 0 0 + rows neg 0 rows + ] + { currentfile grays readhexstring pop } image + } + { + % + % Parameters: + % colors: number of colors in the colormap. + % colormap: red, green, blue color packets. + % + currentfile buffer readline pop + token pop /colors exch def pop + /colors colors 3 mul def + /colormap colors string def + currentfile colormap readhexstring pop pop + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { PseudoClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayPseudoClassPacket } image + } ifelse + } ifelse +} bind def + +/DisplayImage +{ + % + % Display a DirectClass or PseudoClass image. + % + % Parameters: + % x & y translation. + % x & y scale. + % label pointsize. + % image label. + % image columns & rows. + % class: 0-DirectClass or 1-PseudoClass. + % compression: 0-none or 1-RunlengthEncoded. + % hex color packets. + % + gsave + /buffer 512 string def + /byte 1 string def + /color_packet 3 string def + /pixels 768 string def + + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + x y translate + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + currentfile buffer readline pop + token pop /pointsize exch def pop + /Times-Roman findfont pointsize scalefont setfont + x y scale + currentfile buffer readline pop + token pop /columns exch def + token pop /rows exch def pop + currentfile buffer readline pop + token pop /class exch def pop + currentfile buffer readline pop + token pop /compression exch def pop + class 0 gt { PseudoClassImage } { DirectClassImage } ifelse + grestore +} bind def +%%EndProlog +%%Page: 1 1 +%%PageBoundingBox: 0 0 375 281 +userdict begin +DisplayImage +0 0 +375.052 281.289 +12.000000 +500 375 +0 +0 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEE7E7E7DDDDDDE5E5E5FDFDFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF4F4F49696964343432E2E2E333333C9C9C9FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9A9A9282828 +BFBFBFE2E2E2525252636363FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C48D8D8D8C8C8C +B4B4B4FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3434343797979FFFFFFFFFFFFCFCFCF868686 +F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFBDBDBD3030305050505959592424249F9F9FFEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFAEAEAE292929B4B4B49A9A9AAFAFAFF5F5F5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4 +434343B7B7B7F9F9F9FFFFFFA6A6A6252525CBCBCBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD797979101010424242 +545454232323555555F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6CECECEF8F8F8FFFFFFFFFFFF +F6F6F63B3B3BBCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF2F2F22B2B2B3C3C3CD3D3D3FFFFFFBABABA252525AFAFAF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFB +F9F9F9FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD414141CFCFCFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F2F2F2343434A6A6A6FFFFFFFFFFFFFFFFFF555555989898FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D78989899595959B9B9BA5A5A5B2B2B2 +C3C3C3DEDEDEF8F8F8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF8383836D6D6DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2373737C5C5C5FFFFFF +FFFFFFF0F0F04E4E4EAEAEAEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFBDBDBDA2A2A2EBEBEBDEDEDED1D1D1BFBFBFAFAFAF9B9B9B909090A9A9A9 +CFCFCFF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD9C9C9C +686868EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFE7C7C7C646464F4F4F4F2F2F26161614B4B4BF6F6F6 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3 +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBEEEEEECCCCCCA6A6A6949494B8B8B8E9E9E9 +FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD9C9C9C676767EAEAEAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD9D9D93838384444444343433A3A3AD8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDECECECBCBCBC999999B4B4B4ECECECFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FDFDFD9E9E9E6A6A6AEBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7949494 +949494D9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF2F2F2C1C1C19C9C9CC8C8C8F8F8F8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD999999484848C7C7C7DDDDDD +DBDBDBDCDCDCF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFECECECAEAEAEABABABECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE4E4E4353535252525333333313131313131353535CCCCCCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDD0D0D0 +A2A2A2DBDBDBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB +E5E5E5E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4A8A8A8D3D3D3FEFEFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFADADADCCCCCCFEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF3F3F3AEAEAED0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0 +A9A9A9D8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9A1A1A1E9E9E9FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D4A8A8A8F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB8B8B8BEBEBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F19B9B9B +E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F4F4DBDBDBD6D6D6E6E5E5FDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBEB3B3B3FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDA9A9A9FCFCFCFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +D8D8D88E97977D8F907D90927F8D8EADB0B0F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFBDBDBD9A9A9AE3E3E3E8E8E8F1F1F1FBFBFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF9F9F99E9E9EDBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C9C9879798A5C6C9B8DDE0B9DEE1 +B4D8DB93AEB099A0A1F1F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF979797 +9C9C9C989898959595939393A9A9A9CBCBCBE4E4E4F8F8F8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +CCCCCCA9A9A9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE7E7E7859293ADD0D3BCE1E4BBE0E3BBE0E3BBE0E3BBE1E490ABADADB0B1 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF9F9F9F4F4F4EFEFEFE6E6E6 +CBCBCBA8A8A8999999969696B1B1B1E2E2E2FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6989898E7E7E7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8ABAB94AFB2 +BCE1E5BBE0E3BBE0E3BBE0E3BADFE2BBE0E3B5D9DC7F8E8FE5E5E5FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7F7F7E7E7E7 +C2C2C29B9B9BA2A2A2D3D3D3F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9B9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFBFB868D8DA9CBCEBBE0E3BBE0E3BBE0E3BBE0E3 +BBE0E3BADFE2BBE1E4839B9CC4C5C5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7D4D4D4A3A3A3 +A0A0A0DADADAFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE2E2E29B9B9BF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF5F5F5838C8CAED1D4BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3BDE2E5849DA0 +858686D6D6D6F0F0F0F9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCDCDCDCA3A3A3B5B5B5F1F1F1 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB979797E2E2E2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFCFC8A9091A9CBCE +BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3BADFE2BCE2E572898A1011111B1B1B3232325E5E5E +8D8D8DB3B3B3D4D4D4F1F1F1FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7C1C1C19D9D9DD6D6D6FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B0B0C3C3C3FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F3F373767687A2A4BDE2E5BBE0E3BBE0E3BBE0E3 +BBE0E3BBE0E3B3D7DA7785869797977575754949492929290D0D0D0D0D0D1D1D1D353535 +6060608F8F8FB7B7B7D5D5D5F2F2F2FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE5E5E5A9A9A9CACACAFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD1D1D1A3A3A3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +CECECE5A5A5A0D0D0D465152ACCED1BCE2E5BBE0E3BADFE2BBE0E3BCE1E48EA8AAB4B6B7 +FFFFFFFFFFFFF7F7F7E1E1E1C8C8C89F9F9F7373734747472727270D0D0D0B0B0B1E1E1E +373737636363919191BABABAD7D7D7F2F2F2FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F3F3F3B2B2B2C1C1C1FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4989898 +F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE8E8E8E202020161616808080B8B9B9 +8795969EBDBFB6DBDEB9DEE1AFD3D6738A8C4D5353E3E3E3FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF8F8F8DFDFDFC6C6C69D9D9D6F6F6F4545452525250D0D0D0A0A0A +202020393939646464939393BCBCBCD9D9D9F2F2F2FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8B9B9B9B8B8B8 +F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0979797EDEDEDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FAFAFAC0C0C04848480A0A0A4B4B4BC2C2C2FBFBFBFFFFFFE3E3E3989E9E7683846A787A +838D8E6769690C0C0C989898FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF8F8F8DDDDDDC2C2C29D9D9D6D6D6D4141412424240E0E0E +0909092222223C3C3C676767969696BFBFBFDBDBDBF2F2F2FEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBBBBBBBBBBBBBFDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFBFBFB969696E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E47C7C7C161616212121929292 +EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBE6E5E5D4D3D3F5F5F5E6E6E53C3C3C292929 +D8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7F7F7DDDDDDBEBEBE9C9C9C6B6B6B3F3F3F232323 +0F0F0F090909232323404040676767989898C1C1C1DCDCDCF2F2F2FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFAFAFAAFAFAFCACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF979797 +DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF6F6F6AFAFAF3838380C0C0C5B5B5BD0D0D0FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF3F3F3E4E4E4FFFFFFFFFFFFB0B0B00F0F0F6C6C6CF9F9F9FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFCF5F5F5DDDDDDBABABA9898986A6A6A3C3C3C +2020201111110909092323234545456B6B6B999999C5C5C5DEDEDEF3F3F3FEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F2F2F2A5A5A5DCDCDCFFFFFFFFFFFFFFFFFFFFFFFF9E9E9ED5D5D5FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED7D7D76969690F0F0F2F2F2F +A4A4A4F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A1A1A1 +FFFFFFFFFFFFF7F7F7666666111111B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF3F3F3DCDCDCB8B8B8939393696969 +3A3A3A1D1D1D1212120C0C0C2222224848486F6F6F9A9A9AC7C7C7E1E1E1F2F2F2FEFEFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6A0A0A0ECECEC +FFFFFFFFFFFFFFFFFFA6A6A6CECECEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFBABABA6969696B6B6B6B6B6B6E6E6EDADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF1F1F19E9E9E2A2A2A1212126F6F6FDBDBDBFEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E0B6B6B6FFFFFFFFFFFFFFFFFFD4D4D4 +242424434343E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF2F2F2DADADAB6B6B68F8F8F +6666663A3A3A1A1A1A1212120E0E0E2323234A4A4A7373739C9C9CC8C8C8E4E4E4F3F3F3 +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3B1B1B1FEFEFEFFFFFFFFFFFFA8A8A8 +CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F25858586B6B6B808080 +7F7F7F818181DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDCBCBCB5757570C0C0C +3E3E3EB3B3B3F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFBFBFBF8F8F8FFFFFFFFFFFFFFFFFFFFFFFF9191910B0B0B8D8D8DFEFEFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAF0F0F0D8D8D8B4B4B4 +8B8B8B6262623A3A3A1717171111111111112525254C4C4C777777A0A0A0C8C8C8E8E8E8 +F4F4F4FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF6F6F69F9F9FDEDEDEFFFFFFFFFFFFA8A8A8CCCCCCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFD8D8D8373737DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEBEBEB8B8B8B1F1F1F191919828282E6E6E6FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E2CCCCCC +FFFFFFFFFFFFFFFFFFFFFFFFECECEC464646242424D0D0D0FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9EEEEEED7D7D7 +B0B0B08989895E5E5E3737371515151010101313132727274F4F4F7B7B7BA4A4A4C9C9C9 +E9E9E9F6F6F6FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD4D4D4 +A5A5A5FBFBFBFFFFFFA8A8A8CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +8484845B5B5B959595878787B0B0B0FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFABDBDBD444444 +0B0B0B4D4D4DC4C4C4FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCCA7A7A7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFB8B8B8141414616161F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9ECECEC +D7D7D7ADADAD8585855B5B5B3535351313130F0F0F1515152828285252527D7D7DA8A8A8 +CCCCCCEBEBEBF7F7F7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA6A6A6D0D0D0FFFFFFA8A8A8 +CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F34E4E4E1A1A1A5D5D5D5D5D5D +2424249C9C9CFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE2E2E2797979151515242424949494EFEFEFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE7E7E7D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA7070700F0F0F +ABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8 +E9E9E9D5D5D5ACACAC8181815858583333331212120E0E0E181818292929555555818181 +AAAAAACECECEECECECF9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFD6D6D6A1A1A1FFFFFFA8A8A8CCCCCCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE9E9E9676767969696FAFAFAFFFFFFA9A9A9252525CACACAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7ADADAD +3636360D0D0D5E5E5ED2D2D2FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8F7F7F7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADA2D2D2D383838E3E3E3FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FAFAFAE7E7E7D2D2D2ACACAC7C7C7C5555553131311111110C0C0C1A1A1A2C2C2C555555 +858585ADADADD0D0D0EDEDEDFAFAFAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F8F8F8989898E7E7E7A9A9A9CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF6F6F63B3B3BBCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFED7D7D76767670D0D0D303030A6A6A6F5F5F5FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDBCBCBCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF9C9C9C0C0C0C818181FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFBFBFBE6E6E6CECECEAAAAAA7A7A7A5050503030301111110909091B1B1B2F2F2F +555555888888B1B1B1D1D1D1EEEEEEFCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDB9B9B9AAAAAA +CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3D9D9D9FFFFFFFFFFFFFFFFFF +DDDDDD2B2B2BBEBEBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1 +9A9A9A272727111111727272DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC8C8C8B5B5B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0 +5252521C1C1CC6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFAFAFAE6E6E6CBCBCBA8A8A87979794C4C4C2E2E2E1111110808081C1C1C +3333335757578A8A8AB5B5B5D2D2D2EFEFEFFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E79898989D9D9DCCCCCCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF6D6D6D646464FBFBFBFFFFFFFFFFFF8080803B3B3BEEEEEEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC9C9C95252520B0B0B3F3F3FB7B7B7FAFAFA +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3EFEFEF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C31A1A1A555555F2F2F2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFAFAFAE5E5E5C9C9C9A5A5A57979794949492B2B2B131313070707 +1B1B1B3737375A5A5A8A8A8AB9B9B9D4D4D4EEEEEEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF0F0F0767676868686CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3 +2B2B2B7A7A7AC6C6C68D8D8D252525B0B0B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E8E8E88787871C1C1C1A1A1A868686E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8E7E7E7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFCFCFC7E7E7E0C0C0CA0A0A0FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEFEFEFAFAFAE4E4E4C7C7C7A2A2A2777777484848272727131313 +0707071C1C1C3939395D5D5D8B8B8BBBBBBBD8D8D8EDEDEDFEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D2686868696969 +CECECEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1C1C13E3E3E363636626262 +C5C5C5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9BABABA4040400B0B0B515151C7C7C7 +FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFBBBBBBB9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE1E1E13737372D2D2DDCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9E4E4E4C4C4C4A0A0A0737373474747252525 +1414140808081D1D1D3B3B3B6161618D8D8DBBBBBBDBDBDBEEEEEEFDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA7A7A7A6A6A64F4F4FCFCFCFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCEFEFEFE7E7E7E5E5E5E9E9E9 +FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF5F5F5F4F4F4F8F8F8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFDEDEDE747474121212272727989898F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCECECECCCCCC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8A8A80E0E0E +737373FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF8F8F8E3E3E3C1C1C19E9E9E707070454545 +2222221414140A0A0A1D1D1D3E3E3E636363909090BDBDBDDDDDDDEFEFEFFCFCFCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E7E7E79A9A9ADFDFDF5E5E5ECBCBCBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDEFEFEF +D7D7D7BABABA9F9F9F929292969696989898969696818181F7F7F7FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6A8A8A83232320E0E0E636363 +D5D5D5FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAFAFAFAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F55E5E5E151515BCBCBCFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF6F6F6E3E3E3BEBEBE9A9A9A6F6F6F +4242422020201313130B0B0B1E1E1E424242666666939393BFBFBFDFDFDFF0F0F0FCFCFC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3C3C3C3F8F8F8777777 +C7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF4F4F4D3D3D3A4A4A49797979F9F9FB9B9B9D5D5D5E7E7E7 +F0F0F0F4F4F4F1F1F1878787F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFDFDFDD4D4D46262620E0E0E343434AAAAAAF5F5F5FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFCDCDCDD8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFCECECE2020204A4A4AEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF3F3F3E2E2E2BABABA959595 +6D6D6D4040401D1D1D1313130E0E0E1E1E1E4545456A6A6A969696C2C2C2E1E1E1F1F1F1 +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE8E8E89A9A9AF3F3F3FDFDFD838383C5C5C5FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF4F4F4DFDFDFDEDEDEDEDEDEDEDEDEE4E4E4FDFDFDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFBFBFBF +999999A3A3A3D1D1D1EFEFEFFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989 +F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF969696262626141414 +757575E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1C1C1C1 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +8B8B8B0B0B0B959595FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF0F0F0E0E0E0BABABA +9090906A6A6A3F3F3F1B1B1B1111111111111E1E1E474747707070989898C3C3C3E4E4E4 +F3F3F3FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B2 +C3C3C3FFFFFFFFFFFF8C8C8CC3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3A3A31C1C1C313131 +3131312E2E2E575757F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF6F6F6C0C0C0999999B5B5B5E7E7E7FDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989F3F3F3FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFBFBFBC7C7C75050500C0C0C424242B9B9B9FAFAFAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDEE4E4E4FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7404040262626D5D5D5 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBEFEFEFDDDDDD +B9B9B98C8C8C6565653E3E3E1818180F0F0F1414142121214848487474749C9C9CC4C4C4 +E6E6E6F4F4F4FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADAA2A2A2F7F7F7FFFFFFFFFFFF8D8D8D +BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF6F6F6414141777777E1E1E1DFDFDFDEDEDEE4E4E4FDFDFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEDADADA +A0A0A0B5B5B5EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFAFAFA898989F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E78484841B1B1B +1C1C1C888888E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF3F3F3F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3101010686868F7F7F7FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCEEEEEE +DBDBDBB7B7B78A8A8A6060603D3D3D1818180D0D0D151515242424484848777777A0A0A0 +C5C5C5E8E8E8F6F6F6FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF4F4F4A1A1A1DEDEDEFFFFFFFFFFFFFFFFFF969696C1C1C1FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F4F4F43F3F3FC1C1C1F5F5F5F2F2F2FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9C0C0C0A3A3A3DEDEDEFEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989 +F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF9F9F9B7B7B73F3F3F0B0B0B535353C9C9C9FCFCFCFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B2D0D0D0 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF8F8F8686868101010B2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB +EDEDEDD9D9D9B5B5B58989895C5C5C3A3A3A1818180A0A0A1616162727274B4B4B797979 +A4A4A4C7C7C7E8E8E8F9F9F9FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB8B8B8BFBFBFFFFFFF +FFFFFFFFFFFFFFFFFF9D9D9DD7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D14646466E6E6E363636 +353535787878D8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F1F1F1AEAEAEB7B7B7F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989F3F3F3FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD717171 +1111112828289A9A9AF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1CFCFCFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D5262626 +404040E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FBFBFBEBEBEBD7D7D7B3B3B38686865959593636361818180808081717172929294E4E4E +7A7A7AA9A9A9CACACAE8E8E8FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFDFDFDE5E5E5F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFC8C8C8B2B2B2F9F9F9FFFFFFFFFFFFFFFFFFFFFFFF969696 +E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF9D9D9D1D1D1D7A7A7AC8C8C8CACACA666666464646F3F3F3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECABABABCDCDCDFDFDFDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFAFAFA898989F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF5F5F5A6A6A63030300D0D0D666666D7D7D7FEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF1F1F1F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9595950B0B0B8A8A8AFEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFCFCFCEAEAEAD4D4D4B0B0B08282825757573333331818180808081818182B2B2B +5050507D7D7DAAAAAACDCDCDE9E9E9FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6 +747474E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D5 +AAAAAAF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFF9F9F9969696E5E5E5FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E7E7E7D8D8D8FFFFFFFFFFFFFFFFFFF3F3F3515151A9A9A9FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEAEAEAA9A9A9D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989 +F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED2D2D2 +5F5F5F0C0C0C363636AEAEAEF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADAEDEDED +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEEEEEE4A4A4A1F1F1FCDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFDFDFDE9E9E9D1D1D1B0B0B0808080545454313131171717070707181818 +2E2E2E515151808080ACACACCFCFCFEAEAEAFCFCFCACACAC676767E3E3E3FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8D8D8ACACACEEEEEEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF3F3F3979797EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF595959939393FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFA9A9A9D9D9D9 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989F3F3F3FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE9393932222221414147A7A7AE3E3E3FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9D9DD4D4D4FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +BEBEBE1515155D5D5DF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFDFDFDEAEAEACECECEAEAEAE7E7E7E5050502F2F2F171717070707 +1717173333334D4D4D4B4B4B616161BBBBBBECECECFCFCFCFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFED1D1D1AAAAAAEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7989898 +F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE4E4E4D4D4D4FFFFFFFFFFFFFFFFFFFFFFFF595959939393 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF6F6F6ADADADD1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFAFAFA898989F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB +C3C3C34C4C4C0B0B0B464646BEBEBEFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFBEBEBEE5E5E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB7474740D0D0DA9A9A9 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEFEFEFBFBFBEAEAEACBCBCBAAAAAA7E7E7E4C4C4C181818151515 +060606151515363636555555838383B1B1B1D4D4D4E5E5E5BDBDBDAFAFAFF2F2F2FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D1A3A3A3FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B0B0B0282828BDBDBDFFFFFFFFFFFFBDBDBD3E3E3ED3D3D3FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD +B7B7B7C1C1C1FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989 +F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E58080801717171E1E1E8C8C8CECECEC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9FDFDFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD2E2E2E363636E1E1E1FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6959595C3C3C36666666B6B6B4D4D4D282828 +1919190B0B0B1717172E2E2E2F2F2F7C7C7CB5B5B5D6D6D6EBEBEBFCFCFCFFFFFFFFFFFF +FFFFFFFFFFFFB4B4B4BFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA868686252525585858 +5959593D3D3D878787FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0D0D0AAAAAAF9F9F9FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989F3F3F3FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F8F8F8B3B3B33B3B3B0C0C0C575757CDCDCDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCBABABAE8E8E8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFA1A1A10C0C0C7C7C7CFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FCFCFCA4A4A4D3D3D3FCFCFC9B9B9BE0E0E0FAFAFAEBEBEBBDBDBD6363634747474B4B4B +2727271717170C0C0C1717173939395F5F5F868686B5B5B5DBDBDBEBEBEB969696E1E1E1 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8ABABAB919191939393D3D3D3FCFCFCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEDEDED9D9D9DE9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFAFAFA898989F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEDADADA6C6C6C1111112C2C2C9E9E9E +F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFBFBFB9C9C9CDEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2565656 +1A1A1AC3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9A0A0A0FAFAFAFBFBFB +9A9A9AE2E2E2F4F4F4C9C9C99F9F9FBCBCBCEFEFEFF6F6F6E7E7E7C7C7C79F9F9F757575 +4B4B4B2222221414140E0E0E191919393939373737828282B6B6B6DDDDDDEEEEEEFAFAFA +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3C3C3C3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989 +F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF2F2F2A1A1A12D2D2D1010106A6A6AD8D8D8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDDADADAF2F2F2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7C7C71C1C1C515151F0F0F0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF9F9F9A4A4A4D6D6D6FFFFFFFBFBFB9090909F9F9F9A9A9AACACAC +E4E4E4FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF4F4F4E5E5E5C4C4C49C9C9C +7272723535351818181313131010101A1A1A3D3D3D6565658F8F8FB7B7B7DEDEDEF0F0F0 +FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF9E9E9EF6F6F6FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA898989F3F3F3FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCCFCFCF5A5A5A0C0C0C393939 +AFAFAFF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDEDEDEDFAFAFAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFCFCFC8080800C0C0C9C9C9CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D2 +A4A4A4FCFCFCFFFFFFFDFDFDB7B7B7B6B6B6EAEAEAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7949494CACACAC3C3C3 +9999996E6E6E4545452020201010101212121B1B1B404040686868939393BABABADFDFDF +F2F2F2FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9BFC0C1B1B3B3CCCDCDF4F4F4 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFEA9A9A9CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF1F1F1E5E5E5 +D5D5D5C6C6C6BFBFBF7B7B7BF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFECECEC9191912020201616167D7D7DE3E3E3FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF8F8F8A3A3A3E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E3E3E33838382D2D2DDADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9A0A0A0DADADAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFDADADA9F9F9FFBFBFBFFFFFFFFFFFFFCFCFCF0F0F0E2E2E2 +C0C0C09696966B6B6B4343431E1E1E0E0E0E1313131D1D1D4242426C6C6C969696BDBDBD +E0E0E0F4F4F4FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFBFBFBC5C6C6828F90869EA08DA8AA819697909999DDDEDEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E3999999F8F8F8FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEF3F3F3DCDCDCBABABAA1A1A1959595929292A1A1A1AEAEAEAFAFAFC3C3C3 +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAC0C0C04A4A4A0B0B0B +484848C0C0C0FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8A7A7A7E7E7E7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACACAC0F0F0F727272 +F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFCDCDCDAAAAAAFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +AAAAAACBCBCBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDEFEFEF +DFDFDFC0C0C09292926767674141411D1D1D0B0B0B141414202020424242707070999999 +C0C0C0E3E3E3F6F6F6FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBEBE869A9CB1D4D7 +BCE2E5BCE1E4BBE1E4A5C5C8879596DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB3B3B3C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCE4E4E4B2B2B29595959B9B9B +B9B9B9D5D5D5EFEFEFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE4E4E47E7E7E1717172020208E8E8EECECECFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF1F1F1FBFBFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6616161141414B9B9B9FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F69C9C9CE0E0E0 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADAA1A1A1F9F9F9FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +EFEFEFDBDBDBBFBFBF8F8F8F6262623F3F3F1C1C1C090909141414242424434343737373 +9D9D9DC1C1C1E4E4E4F9F9F9E0E0E0839293B2D6D9BCE1E4BADFE2BADFE2BBE0E3BDE2E5 +A0C0C3959C9CF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5 +959595EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFAFAFAD3D3D3A4A4A4999999C2C2C2ECECECFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8AFAFAF393939 +0B0B0B595959CECECEFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF9F9F9D2D2D2F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFCFCFCF232323454545EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBAAAAAAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF8F8F8A1A1A1DBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FDFDFDEFEFEFD8D8D8BCBCBC8F8F8F5D5D5D3C3C3C1D1D1D070707131313272727474646 +53555592AEB0BDE2E5BADFE2BBE0E3BBE0E3BBE0E3BBE0E3BADFE27D8F91D8D8D8FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D2A3A3A3FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8A8A8A8A4A4A4D3D3D3 +F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFDADADA6969691010102C2C2CA1A1A1F4F4F4FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3969696E9E9E9 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD8E8E8E +0B0B0B909090FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F3F3F39C9C9CE4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6C6C6AEAEAE +FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFDFDFDEFEFEFD6D6D6B9B9B98E8E8E5C5C5C3535352D3333A2C3C6BCE2E5BBE0E3 +BBE0E3BBE0E3BBE0E3BADFE2BCE2E589A1A4BBBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFAFAFAFC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF8F8F8C3C3C39C9C9CD1D1D1FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F29E9E9E +2A2A2A1010106D6D6DDBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7BFBFBFF1F1F1FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA444444232323D2D2D2FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3B0B0B0FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8A0A0A0EBEBEBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEFEFEEAE9E9818989A5C6C8BCE1E4BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3 +BCE2E58CA6A7B5B7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9999999 +E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECA8A8A8B3B3B3 +F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDCCCCCC5555550B0B0B3C3C3CB3B3B3F8F8F8FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEF8F8F8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB7B7B7121212646464F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF2F2F29A9A9AE7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F3F3F3A6A6A6DADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +9EA2A29BBABCBDE2E5BADFE2BBE0E3BBE0E3BBE0E3BBE0E3BCE2E5829799C9CACAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB919191F9F9F9FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE4E4E4A6A6A6D3D3D3FDFDFDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA +8B8B8B1D1D1D191919818181E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3B2B2B2F3F3F3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FAFAFA6E6E6E0F0F0FAEAEAEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBD +B7B7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9B2B2B2C9C9C9FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEE2E2E2636363677C7EBCE1E4BBE0E3 +BADFE2BBE0E3BADFE2BCE1E4AED2D4848F90EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD6D6D6A0A0A0FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADA +A5A5A5E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9BDBDBD4545450A0A0A4B4B4BC3C3C3FBFBFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF989898EFEFEFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D92A2A2A3C3C3C +E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE9A9A9AEDEDEDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFBFBFBBFBFBFBABABAFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF6F6F6ACACAC3737370101011A1F2090ADB0BCE2E5BCE1E4BCE1E4BCE2E5B7DBDE +879D9FBFC1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3B1B1B1 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D5A8A8A8E9E9E9FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +E1E1E1797979151515232323949494EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFAFAFADDDDDDF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9999990B0B0B848484FDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD9D9D99E9E9EFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9BCBCBCBABABA +F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED7D7D76A6A6A111111040404 +0000002E2D2D8289898CA5A7A5C6C9ABCDD09EBEC1859799B3B5B6F9F9F9FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B0B0C1C1C1FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE0E0E0A4A4A4ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6ABABAB3636360D0D0D5E5E5ED0D0D0 +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAE8E8E8FDFDFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEEEEEE4D4D4D1D1D1DCACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C87171716F6F6FB9B9B9F5F5F5FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA8A8A8 +D3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF5F5F5B5B5B5BFBFBFFBFBFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF2F2F2A1A1A12C2C2C1111112626260A0A0A2E2E2EC3C3C3F7F7F7BABBBC +8E9494879091969B9BD2D3D3FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFA9A9A9C7C7C7FFFFFFFFFFFFFFFFFFFFFFFFEDEDEDA5A5A5E1E1E1FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFED6D6D66666660F0F0F303030A5A5A5F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC9B9B9BF5F5F5FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C0 +161616585858F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD3D3D32E2E2E5C5C5C7C7C7C353535999999FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E49E9E9EF1F1F1FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEE5E5E5 +A9A9A9C7C7C7FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDD0D0D05C5C5C0C0C0C +3737375F5F5F161616343434C8C8C8FFFFFFFFFFFFFFFFFFF9F9F9F4F3F3FCFCFCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA5A5A5CDCDCD +FFFFFFFFFFFFFFFFFFF7F7F7ACACACD1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F19B9B9B292929121212707070 +DCDCDCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFEFEFEFA7A7A7F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC7979790D0D0DA4A4A4FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE7E7E7E757575F7F7F7 +FFFFFF8A8A8A3B3B3BF2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFC0C0C0B5B5B5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8C5C5C59F9F9FD4D4D4FDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEFEFEF9494942222221515157878788B8B8B1D1D1D363636CBCBCB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD8F8F8FCCCCCCFFFFFFFFFFFFFFFFFFBCBCBC +BABABAFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFDFDFDC9C9C95454540C0C0C3E3E3EB6B6B6F8F8F8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF4F4F4FDFDFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFDFDFDF323232343434E0E0E0FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBED9D9D9FFFFFFFFFFFFC4C4C4353535F0F0F0 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F6F6F6A2A2A2DBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC +DEDEDEA5A5A5B2B2B2EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCC7C7C74F4F4F +0A0A0A454545BABABA9E9E9E1818183B3B3BD1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFDFDFD868686C7C7C7FFFFFFFFFFFFE4E4E49C9C9CF3F3F3FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E98888881D1D1D1A1A1A +828282E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3CACACAFDFDFDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFA4A4A40D0D0D7A7A7AFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEFEFEF8F8F8E1E1E1494949595959F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDCA1A1A1F6F6F6 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9D6D6D6A4A4A49D9D9DD6D6D6FDFDFDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE9E9E98686861C1C1C1A1A1A878787E6E6E69C9C9C161616 +3F3F3FD3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8D8D8DC1C1C1 +FFFFFFFCFCFCA8A8A8CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFBFBFBBBBBBB4242420A0A0A4E4E4EC5C5C5FBFBFBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE7E7E7919191FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2575757181818 +C2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD717171 +2626264E4E4EE9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB8B8B8BDBDBDFFFFFFFFFFFFFFFFFFFFFFFF +D7D7D79C9C9CA2A2A2D3D3D3F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFABCBCBC +4545450909094E4E4EC7C7C7F8F8F8989898121212444444D9D9D9FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8FB2B2B2FFFFFFD3D3D3A6A6A6FBFBFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E1767676131313 +242424969696EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1C1C1C1FCFCFC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C91C1C1C4E4E4EEFEFEFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED3D3D3A4A4A45C5C5CDCDCDCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF3F3F39F9F9FE1E1E1FFFFFFFFFFFFFBFBFB979797C7C7C7FEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E27A7A7A151515212121929292F1F1F1F9F9F9 +8E8E8E0F0F0F4C4C4CDCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF909090A1A1A1FDFDFD9C9C9CDEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF6F6F6AAAAAA3232320C0C0C616161D3D3D3FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFDFDFD8484840B0B0B999999FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF555555989898FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D5 +A4A4A4F9F9F9FFFFFFFAFAFA9A9A9AE2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8 +B1B1B13737370B0B0B5B5B5BD1D1D1FEFEFEF6F6F68A8A8A0F0F0F4F4F4FE1E1E1FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE929292828282 +DBDBDB9D9D9DFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDD3D3D3626262 +0D0D0D313131A9A9A9F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE9E9E9A9A9A9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6 +3C3C3C2A2A2AD7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB3B3B3737373F2F2F2FFFFFFFFFFFF +F0F0F04E4E4EAEAEAEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB1B1B1C5C5C5FFFFFFFAFAFA +9A9A9AE1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC6A6A6A1010102B2B2BA2A2A2F3F3F3 +FFFFFFF5F5F58181810B0B0B575757E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE979797686868A6A6A6C7C7C7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEEEEEE979797242424131313757575DFDFDFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4959595FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B0B01010106C6C6CF9F9F9 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD6D6D6353535646464C8C8C8A7A7A73D3D3D4D4D4DF6F6F6FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEEEEEE9D9D9DE8E8E8FCFCFC9A9A9AE1E1E1FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F5F5F5A2A2A22D2D2D0F0F0F6A6A6AD9D9D9FEFEFEFFFFFFF2F2F27D7D7D0D0D0D5A5A5A +E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFE9E9E9E6969697B7B7BF2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCC6C6C6 +5050500A0A0A424242B9B9B9F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF7F7F7656565141414B6B6B6FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +D5D5D54747473636363434347A7A7ADDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFCECECEAAAAAAF7F7F79A9A9AE1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED1D1D15D5D5D0C0C0C373737ADADAD +F7F7F7FFFFFFFFFFFFF2F2F27676760A0A0A626262EBEBEBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA5A5A57B7B7B +9C9C9CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E78383831A1A1A1D1D1D878787EAEAEAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF5F5F5E5E5E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD2D2D2252525444444EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF5F5F5F2F2F2F2F2F2 +FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCAAAAAAC9C9C9 +9B9B9BE1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFEFEFEF979797232323141414767676E2E2E2FFFFFFFFFFFFFFFFFFEEEEEE6F6F6F +0C0C0C686868EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA5A5A5A7A7A7A4A4A4FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9 +B6B6B63F3F3F0B0B0B535353C9C9C9FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDB9E9E9EFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE9191910A0A0A +8C8C8CFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8999999898989E2E2E2FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBC9C9C95151510A0A0A404040 +BABABAFAFAFAFFFFFFFFFFFFFFFFFFECECEC6B6B6B0A0A0A6D6D6DEEEEEEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEA2A2A2CBCBCB989898EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEDEDEDE7070701212122828289A9A9AF0F0F0 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E2AFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB464646222222CECECEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFC2C2C2606060E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEAEAEA8989891C1C1C191919848484E8E8E8FFFFFFFFFFFFFFFFFFFFFFFF +EAEAEA6262620B0B0B747474EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA2A2A2D5D5D5 +B5B5B5C1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F5F5F5A6A6A63030300E0E0E656565D5D5D5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFBFBFBF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFBABABA151515606060F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8 +B9B9B9EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFABEBEBE4646460A0A0A +4E4E4EC3C3C3FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFE6E6E66060600B0B0B787878F2F2F2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA2A2A2D5D5D5E1E1E19D9D9DF9F9F9FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDD1D1D15F5F5F0D0D0D343434AAAAAA +F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6CDCDCDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA +717171101010ABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE3E3E37C7C7C171717212121909090ECECECFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE5E5E55757570C0C0C828282F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEA2A2A2D4D4D4FFFFFFA8A8A8CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFEEEEEE949494242424141414777777E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCBA6A6A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D92E2E2E383838E5E5E5 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8B2B2B23B3B3B +0B0B0B585858CDCDCDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E05353530E0E0E +848484F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA2A2A2D4D4D4 +FFFFFFDDDDDD9E9E9EF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBC3C3C34D4D4D0A0A0A444444 +BBBBBBFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE2E2E2D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9D9D0B0B0B808080FDFDFDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFDDDDDD7070701010102929299E9E9EF2F2F2FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE0E0E04D4D4D0D0D0D8D8D8DF7F7F7FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEA2A2A2D4D4D4FFFFFFFEFEFEAFAFAFC7C7C7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE6E6E68181811818181D1D1D898989EAEAEAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9F8F8F8FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF0F0F05252521A1A1AC7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5A7A7A7 +2F2F2F0C0C0C666666D8D8D8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9 +484848111111929292F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEA2A2A2D4D4D4FFFFFFFFFFFFECECEC9D9D9DE8E8E8FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9B3B3B33C3C3C0A0A0A +555555CBCBCBFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACAC2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C4181818 +545454F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D56060600C0C0C333333ACACACF6F6F6FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7434343101010999999FAFAFAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4A4A4D1D1D1 +FFFFFFFFFFFFFFFFFFCECECEAAAAAAFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFDBDBDB6D6D6D1010102929299E9E9EF2F2F2FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFEFEFEFEFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC2C2C2B9B9B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC7C7C7C0B0B0BA0A0A0FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1 +999999262626111111757575DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD2D2D23B3B3B1515159F9F9FFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8A8A8C9C9C9FFFFFFFFFFFFFFFFFFFCFCFC +B7B7B7C2C2C2FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3A2A2A22C2C2C +0E0E0E696969D9D9D9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9BFBFBF5C5C5C4A4A4A797979 +F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0EEEEEEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE2E2E23535352F2F2FDEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC9C9C95555550A0A0A3E3E3EB7B7B7FAFAFA +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCECECE393939161616A4A4A4 +FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB0B0B0C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFF6F6F6ACACACD2D2D2FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDBD6D6D6FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFDFDFDCFCFCF5A5A5A0B0B0B383838AFAFAFF7F7F7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF9D9D9D2C2C2C9494949E9E9E3434346B6B6BF4F4F4FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +AAAAAA0D0D0D757575FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EBEBEB8C8C8C1D1D1D181818808080E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFC9C9C93232321A1A1AABABABFCFCFCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBBB7B7B7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDEDA8A8A8DCDCDCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADADAD707070F6F6F6FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED8F8F8F +2020201616167B7B7BE4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB3B3B3B +858585FFFFFFFFFFFFD2D2D2292929C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFB7B7B7BFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F45D5D5D141414BEBEBE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBC0C0C04747470A0A0A4A4A4AC4C4C4 +FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3303030 +1D1D1DADADADFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7C7C7ADADADFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEAEAEAA9A9A9DADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFB9B9B96D6D6DC7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFAFAFAC0C0C04949490B0B0B474747BFBFBFFBFBFBFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFA4A4A4ECECECFFFFFFFFFFFFECECEC +343434BDBDBDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8CECECEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCC1E1E1E4B4B4BECECECFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE6E6E67D7D7D1717171F1F1F909090EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C02A2A2A202020B5B5B5FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE0E0E0999999FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED +ACACACD1D1D1FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBABABAA7A7A79D9D9D +F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEE3E3E3 +7C7C7C1717172020208D8D8DECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9797973E3E3EE2E2E2FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFE8787870B0B0B949494FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9B4B4B43B3B3B0C0C0C585858 +CBCBCBFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +B9B9B9272727262626B8B8B8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5939393 +EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEABABABB8B8B8F5F5F5 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9BCBCBCB9B9B9BEBEBEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6B0B0B03A3A3A0C0C0C595959CCCCCCFDFDFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFEDEDED8787875C5C5CD7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFCDCDCDDDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E83E3E3E +292929D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFDDDDDD7171711212122929299B9B9BF2F2F2FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB7B7B7232323282828BEBEBEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA3A3A3D3D3D3FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7BFBFBFA5A5A5E0E0E0FDFDFDFFFFFFFFFFFF +FFFFFFB9B9B9BCBCBCEFEFEF9A9A9AEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +D9D9D96A6A6A0F0F0F2C2C2CA0A0A0F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF616161393939D7D7D7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABABC6C6C6FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B21111116A6A6AF8F8F8FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5A9A9A93232320D0D0D +636363D5D5D5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEAFAFAF1E1E1E2F2F2FC1C1C1FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFBBBBBBB7B7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEFEFED9D9D99E9E9EB3B3B3EDEDEDFFFFFFFFFFFFB9B9B9BBBBBBFFFFFF +BEBEBEB7B7B7FFFFFFFFFFFFFFFFFFFFFFFFF2F2F29F9F9F2B2B2B0F0F0F6B6B6BD9D9D9 +FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEFEFEC2C2C25B5B5B3E3E3ED8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF7F7F7686868121212B2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFDFDFDD7D7D76565650D0D0D313131A8A8A8F5F5F5FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCABABAB1C1C1C303030 +C7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E1 +9A9A9AFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F6F6F6C2C2C29A9A9AB7B7B7EBEBEBB8B8B8BBBBBBFFFFFFF0F0F09A9A9AEBEBEBFFFFFF +FDFDFDCCCCCC5858580B0B0B3A3A3AB2B2B2F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE2E2E2E +8C8C8CEBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF4F4F4F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +D4D4D4272727404040E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F29E9E9E282828 +101010717171DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFCFCFCA6A6A6171717373737CDCDCDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC9F9F9FD9D9D9FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDEDBCBCBC +9999997B7B7BBABABAFFFFFFFFFFFFC3C3C3B4B4B4ECECEC8D8D8D1F1F1F1616167E7E7E +E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2606060131313929292A4A4A4A1A1A1A5A5A5 +EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B0B0D6D6D6FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9393930B0B0B8A8A8A +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFDFDFDCECECE5757570A0A0A3B3B3BB4B4B4F8F8F8FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9E9E9E +1616163B3B3BD0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFC8C8C8ACACACFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4D0D0D0EAEAEAFFFFFF +FFFFFFF0F0F07979793F3F3F0A0A0A494949C2C2C2FBFBFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE3E3E35858584E4E4E4D4D4D4D4D4D4D4D4D535353D9D9D9FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAAD3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC494949212121CDCDCDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED8E8E8E +1F1F1F1616167E7E7EE4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9C9C9C111111404040D7D7D7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F2F2F2959595EDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E2797979141414181818 +919191EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFEFEFE +FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFEEEEEEF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFBDBDBD1616165D5D5DF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFCFCFCC2C2C24C4C4C090909474747BFBFBFFBFBFBFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F9F9F9939393101010454545D8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9BABABAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF6F6F6ADADAD3535350C0C0C5A5A5A868686E0E0E0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDBF1F1F1FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA747474 +0E0E0EA7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6 +8282821717171D1D1D8B8B8BEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F79090900D0D0D4A4A4ADEDEDE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F19B9B9BE7E7E7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED7D7D76565650E0E0E +2F2F2FA4A4A4F6F6F6CECECEA9A9A9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9A9A9AD8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC313131343434E1E1E1FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9B8B8B83D3D3D0A0A0A545454CCCCCCFDFDFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF6F6F68686860C0C0C525252E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFCCCCCCABABABFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF0F0F09A9A9A2727271212126F6F6FDCDCDCFFFFFFFFFFFFF8F8F8 +9E9E9EDEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFB8B8B8E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFA1A1A10B0B0B7C7C7CFCFCFCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E0E0E07373731212122525259B9B9BF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F38383830B0B0B +545454E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA5A5A5 +D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCC9C9C9535353 +0A0A0A3E3E3EB5B5B5F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFD3D3D3A5A5A5FCFCFCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9FCFCFCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F1F1F1555555191919C3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7AAAAAA3434340C0C0C626262D3D3D3 +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF2F2F27B7B7B0B0B0B5D5D5DE6E6E6FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5A2A2A2EBEBEBFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE9E9E98888881C1C1C191919838383E7E7E7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFBFBFBA0A0A0D9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEBCBCBCE9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C81C1C1C525252 +F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFED6D6D66666660E0E0E303030A6A6A6F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF +7474740C0C0C616161E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFD3D3D3AAAAAAF6F6F6FFFFFFFFFFFFFFFFFFF9F9F9BABABA +4343430A0A0A4E4E4EC4C4C4FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD5D5D5A4A4A4FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFE999999DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD8282820B0B0B9D9D9DFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F29F9F9F2A2A2A1111116D6D6D +DDDDDDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE6F6F6F090909686868ECECECFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFEC2C2C2B7B7B7FCFCFCFFFFFFDFDFDF767676141414242424959595EEEEEEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA6A6A6D2D2D2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED5D5D5F1F1F1FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE3E3E33939392C2C2CDADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFDFDFDCECECE5A5A5A0C0C0C383838B2B2B2F8F8F8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFEBEBEB6767670B0B0B6D6D6DEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAB7B7B7BEBEBE +A8A8A83434340C0C0C5F5F5FD2D2D2FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADA9F9F9FFBFBFBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF0F0F0FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAA +0E0E0E717171F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF919191212121161616 +7B7B7BE4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E96464640A0A0A747474 +F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCC4646460A0A0A2F2F2FA7A7A7F4F4F4 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD8D8D8A0A0A0FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FAFAFAA4A4A4E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F65E5E5E131313BABABAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFCFCFCC5C5C54D4D4D0A0A0A454545BDBDBDFAFAFAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE7E7E75B5B5B0B0B0B7B7B7BF1F1F1FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E0BBBBBBFEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F0F0F09797972727271414145858589B9B9BF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5A0A0A0DFDFDF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA4A4A4E6E6E6FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFD0D0D0212121484848ECECECFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E98484841A1A1A +1C1C1C878787EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E3585858 +0A0A0A7F7F7FF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFE838383454545FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC7C7C75151510A0A0A404040B7B7B7 +F7F7F7CBCBCBA3A3A3DDDDDDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDB7B7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEEFEFEFFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF8C8C8C0A0A0A929292FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFAFAFABABABA414141090909515151C8C8C8FDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E25050500B0B0B888888F5F5F5FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E3858585080808454545 +FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE9E9E98484841919191B1B1B858585E9E9E9FFFFFFFFFFFFFEFEFEDDDDDDA1A1A1 +B9B9B9F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E1E1E19E9E9EF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FAFAFAD6D6D6F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA424242252525 +D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E2787878 +121212242424969696F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +DCDCDC4D4D4D0E0E0E8C8C8CF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF5F5F54E4E4E3838385F5F5F484848FCFCFCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9B7B7B73E3E3E090909515151 +C7C7C7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5BCBCBC9E9E9ECCCCCCF6F6F6 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9A4A4A4D6D6D6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4979797E7E7E7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5B5B5121212666666F6F6F6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF6F6F6AFAFAF3535350B0B0B5E5E5ED3D3D3FEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDB4646460D0D0D959595F9F9F9 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA +BEBEBEF0F0F0ABABAB464646FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEDDDDDD7272721111112525259A9A9AF0F0F0FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEE2E2E2A9A9A9989898C1C1C1F0F0F0FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFC5C5C5B0B0B0FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF8F8F8BCBCBCF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF9F9F96B6B6B0F0F0FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEDADADA +6868680E0E0E2C2C2CA4A4A4F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD5D5D5404040121212989898FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABAB464646 +FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3A6A6A62F2F2F0D0D0D +646464D5D5D5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFDFDFDE7E7E7B2B2B2919191DADADAFFFFFFFFFFFFFFFFFFE8E8E89D9D9D +EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFEF9F9F9FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E0E0E0C7C7C7C9C9C9C9C9C9CACACADDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7 +2929293C3C3CE6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3A0A0A02C2C2C0F0F0F6D6D6DDADADAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D23D3D3D121212 +9F9F9FFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABAB464646FCFCFCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFDFDFDD0D0D05E5E5E0C0C0C343434AAAAAAF5F5F5FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFB3B3B3BABABAFFFFFFFFFFFFFBFBFBAAAAAACECECEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4B6B6B6F2F2F2FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE646464333333363636353535 +0D0D0D757575FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9898980C0C0C848484FCFCFC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD +CECECE5C5C5C0C0C0C383838AFAFAFF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFCDCDCD353535171717A5A5A5FBFBFBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFABABAB464646FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE939393242424 +141414757575E1E1E1FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9BBBBBBFFFFFF +FFFFFFCECECEAAAAAAFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEDEDED989898F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFBFBFBEFEFEFF0F0F0F0F0F09898985B5B5BE5E5E5FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEFEFEF4E4E4E1F1F1FCACACAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE959595222222151515787878E2E2E2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8 +343434191919A9A9A9FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABAB464646 +FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFCFCFCC3C3C34E4E4E0B0B0B434343BABABAF9F9F9FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9BBBBBBFFFFFFEEEEEE9E9E9EE8E8E8FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F8F8F8DADADAFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFDDDDDD3C3C3CD0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC0C0C01818185A5A5AF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FBFBFBC7C7C74F4F4F0A0A0A424242BCBCBCF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C32D2D2D1F1F1FB0B0B0FDFDFDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABAB464646FCFCFCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7808080 +1919191E1E1E898989E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFB9B9B9BBBBBBFFFFFFB0B0B0C6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAECECECFDFDFDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F26060609C9C9C +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA7878780E0E0E +A5A5A5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E98686861A1A1A1B1B1B878787 +E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFEBDBDBD2B2B2B212121B3B3B3FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB1B1B1545454FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF8F8F8B4B4B43C3C3C0C0C0C545454C9C9C9FCFCFCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9BCBCBCD9D9D9 +A5A5A5F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE9E9E99F9F9FF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B0B0505050EDEDEDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE323232333333E0E0E0FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFAFAFABCBCBC4343430A0A0A4F4F4FC6C6C6FBFBFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEBBBBBB252525252525BABABA +FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2E4E4E4 +FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEDCDCDC +6F6F6F1111112727279C9C9CF1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9B9B9AFAFAFA3A3A3E0E0E0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EAEAEAA5A5A5F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF7171717B7B7BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFA4A4A40D0D0D787878FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E37A7A7A151515222222 +939393EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEFEFEB3B3B32222222B2B2BBCBCBCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3A4A4A42F2F2F0D0D0D666666D7D7D7FEFEFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFB9B9B9757575C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF2F2F2FEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E23D3D3DCFCFCFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2 +585858181818C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C4 +CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF7F7F7B0B0B03939390B0B0B595959D0D0D0FDFDFDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDB0B0B01E1E1E +2D2D2DC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD +D0D0D05C5C5C0B0B0B363636ACACACF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B27E7E7EF7F7F7 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF2F2F2CFCFCFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB2B2B24B4B4BEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACA1E1E1E4E4E4EEFEFEF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB1717177E7E7EFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEDCDCDC6D6D6D101010 +2A2A2A9F9F9FF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDAAAAAA191919333333C7C7C7FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFDFDFEFEFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED919191212121151515787878E2E2E2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECE9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E2E2E2949494FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +989898A6A6A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFCFCFC8484840C0C0C999999FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF1F1F15B5B5B1414147E7E7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF4F4F4A5A5A52E2E2E0D0D0D686868D9D9D9FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC +A4A4A4171717353535CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFECEBEBB8BABA9A9F9FA2A5A5CACACAF9F9F8FFFFFFFFFFFF +FBFBFBC1C1C1494949090909454545BDBDBDFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEC0C0C0FDFDFDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE6E6E63C3C3C2A2A2AD9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F36262627C7C7C6F6F6F +7A7A7AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED3D3D35D5D5D +0D0D0D353535ADADADF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBA0A0A01212123D3D3DD2D2D2FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED2D3D3 +8A969789A3A59BBABC97B4B784999B9FA5A5EEEEEEE5E5E57D7D7D1616161E1E1E8D8D8D +EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B0B00F0F0F +6C6C6CF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFADADAD3E3E3EDDDDDD7272727A7A7AFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF1F1F1959595232323141414777777E0E0E0FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF9F9F9989898121212404040D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDB829192AACCCFBDE2E5BCE2E5BDE2E5 +BAE0E399B7B9747B7C3838380C0C0C585858CDCDCDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E6E6E6B0B0B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7646464121212B6B6B6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7 +2B2B2BACACACFFFFFF7070707A7A7AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCC8C8C8 +5151510A0A0A424242B9B9B9FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F89494940E0E0E464646 +DBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF8F8F8959C9CA1C0C3BCE2E5BADFE2BBE0E3BADFE2BBE0E3BDE2E5738A8C292A2B +9F9F9FF2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF989898FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD3D3D3242424424242EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F46969697D7D7DFCFCFCFFFFFF707070 +7A7A7AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E98A8A8A1B1B1B1A1A1A838383E9E9E9FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF7F7F78B8B8B0E0E0E4C4C4CDCDCDCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDBDB7B8D8EBADFE2 +BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3BCE1E4A5C7C9848C8CF7F6F6FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF5F5F5DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +9090900A0A0A8D8D8DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFBEBEBE0505054242426464646464642B2B2B2C2C2CACACACFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9 +BFBFBF4545450A0A0A4C4C4CC6C6C6FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5898989 +0D0D0D505050E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5C6C6859B9DBCE2E5BADFE2BBE0E3BBE0E3BBE0E3 +BBE0E3BBE0E3B5D9DC5F6C6D7C7C7C8C8C8C9D9D9DA7A7A7B9B9B9C2C2C2D3D3D3DDDDDD +E2E2E2E6E6E6EBEBEBF0F0F0F4F4F4F9F9F9FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F5F5F5E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB464646222222D1D1D1 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E18F8F8F +8B8B8B8989898B8B8B3C3C3C3F3F3FC2C2C2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEE4E4E47B7B7B161616202020929292EDEDED +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F47F7F7F0B0B0B575757E2E2E2FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFC5C5C6859B9DBCE2E5BADFE2BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3B6DADD475455 +1110101414141313131313131212121212121010101010101F1F1F2B2B2B383838444444 +5050505E5E5E6868687878788181819292929A9A9AABABABB4B4B4C6C6C6CDCDCDE0E0E0 +E4E4E4EAEAEAECECECF2F2F2F4F4F4F9F9F9FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7D7D7A3A3A3FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBABABA131313616161F6F6F6FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF707070 +7A7A7AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F7F7F7B2B2B23A3A3A0B0B0B5A5A5ACDCDCDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F1F1F17B7B7B0C0C0C5B5B5BE7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC7C8D8EB9DEE1 +BBE0E3BBE0E3BBE0E3BBE0E3BADFE2BCE1E4A7C8CB858D8DC8C7C7C6C6C6B3B3B3ACACAC +9A9A9A9292928181817878786868685E5E5E5050504545453737372B2B2B1E1E1E101010 +1010101111111212121313131313131414141515151515151919192D2D2D343434474747 +4E4E4E6161616969697B7B7B8484849393939D9D9DABABABB5B5B5C2C2C2CFCFCFDBDBDB +E8E8E8EBEBEBEFEFEFF2F2F2F6F6F6F8F8F8FDFDFDFDFDFDFEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFDCDCDCB0B0B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFAFAFA6F6F6F0F0F0FACACACFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C7C7C858585FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEDBDBDB6E6E6E1111112A2A2A9D9D9D +F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F07474740B0B0B646464E8E8E8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8969C9CA0C0C2BCE2E5BADFE2BBDFE2BADFE2 +BBE0E3BCE2E571888A7E7F7FF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FCFCFCFAFAFAF4F4F4F0F0F0EBEBEBE7E7E7E2E2E2DDDDDDD2D2D2C2C2C2B8B8B8A6A6A6 +9E9E9E8B8B8B8484847070706A6A6A5858585353534141413B3B3B292929232323111111 +0B0B0B0E0E0E1010101111111414141515151818181A1A1A1B1B1B272727383838424242 +5454545C5C5C7070707777778B8B8B919191A3A3A3A8A8A8BABABABFBFBFD1D1D1D7D7D7 +E9E9E9EEEEEEF2F2F2F3F3F3F7F7F7F9F9F9FCFCFCFEFEFEFEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FAFAFAF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADA2B2B2B +3B3B3BE4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFECECECEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF4F4F4A7A7A73131310E0E0E666666D6D6D6FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEDEDED6E6E6E0B0B0B666666EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFDBDBDB829192AACCCFBDE2E5BCE2E5BDE2E5BAE0E399B6B9414949101010 +787878EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFEF9F9F9F6F6F6EEEEEEECECECE4E4E4E1E1E1D9D9D9D6D6D6C1C1C1B9B9B9A6A6A6 +9D9D9D8C8C8C8080807272726464645A5A5A4D4D4D4444443636362F2F2F1F1F1F181818 +0808080808080D0D0D0F0F0F1414141515151A1A1A1C1C1C212121232323383838414141 +5454545D5D5D6F6F6F7A7A7A8A8A8A989898A2A2A2AEAEAEB7B7B7C5C5C5CBCBCBDBDBDB +E2E2E2F2F2F2F3F3F3F6F6F6F7F7F7FAFAFAFBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5D3D3D3FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B9B9B0B0B0B828282FCFCFCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED4D4D46262620D0D0D323232 +AAAAAAF5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED6868680A0A0A +6F6F6FEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED5D5D6 +8B969689A2A497B5B795B2B4829799A1A7A7D1D1D16464640A0A0A555555DADADAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFAFAFAF5F5F5F1F1F1E9E9E9E5E5E5DCDCDCD8D8D8D0D0D0C9C9C9B3B3B3ADADAD +9797979191917B7B7B7474745F5F5F5858584949494343433535352E2E2E222222191919 +0D0D0D0404040808080E0E0E111111171717191919202020232323292929313131464646 +4D4D4D6363636969698080808686869C9C9CA3A3A3B2B2B2B8B8B8C6C6C6CCCCCCD9D9D9 +E1E1E1EDEDEDF7F7F7F8F8F8F9F9F9FBFBFBFDFDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFCBCBCBA6A6A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEFEFEF5050501C1C1CC8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF2F2F29B9B9B252525111111737373DFDFDFFEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE9E9E96060600C0C0C737373EFEFEFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDEDB9BBBBA1A4A5A4A8A8 +CCCCCCF9F9F9FFFFFFF1F1F1848484111111383838C2C2C2FEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFEF6F6F6F2F2F2E8E8E8E4E4E4DBDBDBD6D6D6CDCDCDC7C7C7B7B7B7A9A9A9 +9B9B9B8C8C8C8080806E6E6E6464645050504A4A4A3D3D3D3838382A2A2A262626181818 +1212120505050202020B0B0B0E0E0E1616161A1A1A2121212626262C2C2C323232424242 +5050505E5E5E6E6E6E7A7A7A8C8C8C979797AAAAAAB0B0B0BEBEBEC3C3C3D1D1D1D6D6D6 +E4E4E4E8E8E8F7F7F7FAFAFAFCFCFCFCFCFCFEFEFEFEFEFEFEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E2E2E2CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +C2C2C2181818565656F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDCBCBCB5454540A0A0A +3D3D3DB8B8B8F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7 +5D5D5D0A0A0A7B7B7BF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FAFAFAA8A8A82222221D1D1DA1A1A1F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFAFAFAF0F0F0ECECECE1E1E1DDDDDDD2D2D2CDCDCDC2C2C2BCBCBCA7A7A7 +9F9F9F8A8A8A8181816D6D6D6363635151514646463C3C3C3535352C2C2C2424241C1C1C +1313130B0B0B0101010505050F0F0F1212121C1C1C1F1F1F2A2A2A2D2D2D3737373E3E3E +5353535B5B5B7070707979798D8D8D979797A9A9A9B4B4B4BFBFBFC6C6C6CFCFCFD8D8D8 +E0E0E0EAEAEAF1F1F1FCFCFCFDFDFDFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAF9F9F9FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB7C7C7C0C0C0CA1A1A1 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFECECEC8C8C8C1E1E1E171717808080E6E6E6FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E55454540C0C0C818181F3F3F3FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEC7C7C73B3B3B +101010808080EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFEFEFEFEFDFDFDF3F3F3ECECECE3E3E3DADADAD3D3D3C9C9C9C2C2C2B8B8B8ACACAC +9A9A9A8F8F8F7C7C7C7373735F5F5F5656564141413B3B3B3131312C2C2C2222221E1E1E +1414140F0F0F0505050101010B0B0B1212121A1A1A212121292929323232383838424242 +4E4E4E6060606B6B6B7D7D7D8787879B9B9BA4A4A4B9B9B9BFBFBFCACACACFCFCFDADADA +DFDFDFEAEAEAEFEFEFFAFAFAFFFFFFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFCFCFCFC1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E1353535313131DDDDDDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBC0C0C04A4A4A +0A0A0A494949C2C2C2FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE0E0E05252520C0C0C868686F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD5C5C5C0909095C5C5CDDDDDD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +FDFDFDFDFDFDFBFBFBF8F8F8EBEBEBE6E6E6D8D8D8D3D3D3C7C7C7C1C1C1B5B5B5AEAEAE +9A9A9A9090907D7D7D7272726161615454544444443636362F2F2F2929292323231C1C1C +1717170F0F0F0B0B0B0202020404041111111616162323232828283434343A3A3A464646 +4D4D4D6161616B6B6B7D7D7D888888999999A6A6A6B5B5B5C4C4C4CBCBCBD3D3D3D9D9D9 +E1E1E1E7E7E7F0F0F0F5F5F5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +C7C7C7B6B6B6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFA7A7A70E0E0E757575FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE5E5E58080801616161E1E1E8D8D8DEEEEEEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE4A4A4A0F0F0F8F8F8F +F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEEEEEE8080800E0E0E3C3C3CC9C9C9FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFE +FCFCFCFBFBFBF9F9F9F8F8F8EFEFEFE4E4E4DCDCDCD0D0D0C9C9C9BCBCBCB5B5B5A8A8A8 +9F9F9F8A8A8A8282826D6D6D6666665050504949493333332D2D2D2525252323231B1B1B +1818181111110E0E0E0808080303030C0C0C1717171F1F1F2B2B2B3232323F3F3F464646 +5353535B5B5B6F6F6F7878788D8D8D949494AAAAAAB1B1B1B6B6B6B8B8B8D7D7D7DADADA +E3E3E3E7E7E7EFEFEFF4F4F4FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F55C5C5C +171717BEBEBEFCFCFCE8E8E8EAEAEAFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8B5B5B5 +3B3B3B0B0B0B565656CDCDCDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD8D8D8454545111111929292F9F9F9FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF9F9F9A0A0A01E1E1E232323A9A9A9F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFC +FBFBFBF9F9F9F8F8F8F5F5F5F3F3F3E4E4E4DDDDDDCFCFCFC8C8C8BABABAB2B2B2A6A6A6 +9D9D9D8C8C8C7F7F7F7171716262625555554545453A3A3A2727272424241E1E1E1C1C1C +1616161515150F0F0F0D0D0D0909090909091717171D1D1D2C2C2C333333404040494949 +5555555E5E5E6D6D6D7B7B7B8A8A8A989898A5A5A5B5B5B5C0C0C0D2D2D2D6D6D6DEDEDE +E1E1E1EAEAEAECECECF5F5F5F8F8F8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCD222222404041888F90808D8E +808C8D929898D9D9D9FFFEFEFFFFFFDFDFDF6F6F6F1111112828289C9C9CF1F1F1FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6404040 +1313139B9B9BFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDC0C0C0 +363636111111868686F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC +FAFAFAF8F8F8F5F5F5F3F3F3F0F0F0EAEAEADADADAD3D3D3C3C3C3BDBDBDACACACA9A9A9 +6D6D6D6868687D7D7D7474745E5E5E5858584343433C3C3C2828281F1F1F1B1B1B1A1A1A +1717171414141212120F0F0F0D0D0D0909091010102020202727273838383D3D3D4F4F4F +5454546666666B6B6B8080808787879C9C9CA2A2A2B6B6B6BEBEBED1D1D1DADADAE0E0E0 +E4E4E4EAEAEAEEEEEEF3F3F3F9F9F9FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF8F8F77174745A6D6EA4C5C8B4D8DBB3D7DAA1C1C4859697BABCBC +A8A8A83131310E0E0E656565D5D5D5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0D0D03B3B3B1717179D9D9DFBFBFBFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D95252520A0A0A666666 +E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACACACACAFFFFFFFDFDFD +F8F8F8F7F7F7F3F3F3F1F1F1EDEDEDEBEBEBDCDCDCD2D2D2C5C5C5BABABAAEAEAEA1A1A1 +9898988989898080806D6D6D6464645151514A4A4A3636363030301B1B1B181818161616 +1616161414141313131111111010100E0E0E0E0E0E1E1E1E2828283535354141414C4C4C +5A5A5A6464647373737C7C7C8E8E8E979797A9A9A9B0B0B0C3C3C3CACACADEDEDEE1E1E1 +E8E8E8EAEAEAF0F0F0F2F2F2F9F9F9FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D1 +86999AB6DADDBCE1E4BBE0E3BBE0E3BCE1E4B4D8DB617173111111323232A7A7A7F6F6F6 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +CCCCCC383838181818A5A5A5FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA7676760D0D0D444444CCCCCCFEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF9F9F9F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFCFCFC +FAFAFAF5F5F5F3F3F3EEEEEEECECECE7E7E7E2E2E2CFCFCFC9C9C9B6B6B6B0B0B09E9E9E +9797978585857D7D7D6C6C6C6262625252524848483A3A3A2E2E2E212121131313121212 +1313131313131313131313131313131313131313131717172B2B2B3131314444444A4A4A +5D5D5D6464647777777F7F7F8F8F8F999999A7A7A7B2B2B2C0C0C0CCCCCCD9D9D9E6E6E6 +E9E9E9EDEDEDF0F0F0F4F4F4F7F7F7FDFDFDF4F4F48E9797A5C6C9BCE1E4BADFE2BBE0E3 +BBE0E3BADFE2BDE2E599B8BA535959D9D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C83131311D1D1DAAAAAAFCFCFC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF7F7F79797971818182A2A2AB2B2B2FBFBFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +D3D3D3DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC +FAFAFAF5F5F5F1F1F1EDEDEDE9E9E9E4E4E4E0E0E0D4D4D4C5C5C5BBBBBBAAAAAAA2A2A2 +9090908888887575756F6F6F5D5D5D5656564444443D3D3D2C2C2C2525251313130D0D0D +0F0F0F1111111212121313131515151616161717171919192525253535353F3F3F505050 +5959596C6C6C6464646C7D7EB9DEE1BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3B5DADD +7C898AEFEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC1C1C12F2F2F1D1D1DAFAFAFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC +B7B7B72E2E2E1616168F8F8FF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0B0B0C2C2C2FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +F9F9F9F7F7F7F0F0F0EDEDEDE6E6E6E3E3E3DCDCDCD8D8D8C5C5C5BCBCBCAAAAAAA0A0A0 +9090908585857676766969695D5D5D515151474747393939303030222222151414627576 +BEE4E7BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3BADFE2B9DFE27B8A8BE2E2E2FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF282828232323 +B5B5B5FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D34C4C4C0B0B0B +6C6C6CE8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFD8D8D8E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FCFCFCF7F7F7F1F1F1EBEBEBE6E6E6E1E1E1C0C0C0758789BADFE2BBE0E3BBE0E3BBE0E3 +BBE0E3BBE0E3BBE0E3B7DCDF788687EAE9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFB8B8B8262626262626B9B9B9FEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E76B6B6B0B0B0B4C4C4CD3D3D3FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F6F6F6FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF1F1F1869091ACCED1BBE1E4BADFE2BBE0E3BBE0E3BADFE2BCE1E4A4C5C8 +8D9495F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB6B6B6 +2121212A2A2AC1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF3F3F39191911616162E2E2EB8B8B8FDFDFDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5B5B5D5D5D5FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFC1C1 +8BA2A4BBE1E4BBE0E3BADFE2BADFE2BBE0E3B8DDE184989ACCCDCDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEADADAD1E1E1E2E2E2EC2C2C2FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FCFCFCB1B1B1282828181818999999F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFA6A6A6D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB585D5E799294B3D7DABADFE2 +BADFE2B0D4D789A0A2ABAEAFFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FDFDFDAAAAAA1B1B1B323232CACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCECECE454545 +0C0C0C747474EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EAEAEAF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF9F9F9F1110105A5D5D818E8F8093947F9293818C8DC0C2C2FAFAFA +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA3A3A3161616393939CDCDCD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5656565090909525252D9D9D9 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDF4F4F4FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D1272727 +3D3D3DE2E2E2EDECECD3D3D3D5D5D4EFEEEEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFAFAFA9D9D9D1616163B3B3BD2D2D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF1F1F1888888121212353535BEBEBEFDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF969696DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F25B5B5B161616B8B8B8FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA989898121212 +444444D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFBFBFBAAAAAA2424241C1C1C9F9F9FF8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B2B2B2E7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF9797970D0D0D7E7E7EFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF8F8F88F8F8F111111464646D9D9D9FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEC6C6C6 +3C3C3C0F0F0F7D7D7DEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8FDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCD222222424242E6E6E6 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7 +8D8D8D0F0F0F4E4E4EDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF5E5E5E0A0A0A595959 +DCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFDFDFDBEBEBEEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF0F0F0545454191919BEBEBEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F58484840F0F0F515151E0E0E0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE7D7D7D1010103C3C3CC5C5C5FEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC +959595E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE929292 +0C0C0C848484FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF3F3F38080800D0D0D575757E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF8F8F8A2A2A21F1F1F232323A6A6A6FAFAFAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFED0D0D0F2F2F2FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C81E1E1E484848EAEAEAFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F37878780B0B0B5E5E5E +E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +C0C0C0353535101010868686F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEFEFEF2F2F2FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFEDEDED4F4F4F1B1B1BC3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEFEFEF7575750B0B0B616161EAEAEAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D95555550B0B0B +636363E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8 +A4A4A4EAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE8B8B8B0B0B0B8B8B8B +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF6D6D6D +0A0A0A6B6B6BEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDED7777770B0B0B414141CDCDCDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8A0A0A0E9E9E9FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFC4C4C41B1B1B4D4D4DEDEDEDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC6666660B0B0B6D6D6DEFEFEFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF6F6F6999999191919282828B0B0B0FBFBFBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFDFDFDEDEDEDFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB +4949491F1F1FC9C9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EAEAEA6262620A0A0A767676F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FDFDFDBBBBBB3131311313138D8D8DF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA +D9D9D9F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC8484840C0C0C929292FEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E65959590D0D0D7A7A7AF3F3F3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D54B4B4B +0909096B6B6BE7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2979797EBEBEBFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFBEBEBE181818545454F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE3E3E35757570C0C0C828282F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E87070700D0D0D494949D0D0D0 +FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF6F6F6B8B8B8F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6424242232323 +CECECEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E04D4D4D0F0F0F +888888F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF5F5F59191911515152B2B2BB5B5B5FDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +F9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFBFBFB7E7E7E0D0D0D989898FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFDADADA4A4A4A1010108D8D8DF8F8F8FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFCFCFCB2B2B22B2B2B181818959595F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3B9B9B9F5F5F5FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +B8B8B81616165C5C5CF2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA0A0A0 +AFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9 +444444131313959595F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF +4545450C0C0C717171E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEDEDED979797F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E13B3B3B272727D1D1D1FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC9797970D0D0D848484FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D33F3F3F141414989898FAFAFAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E36666660B0B0B515151 +D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8 +D6D6D6F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF9F9F97777770E0E0E9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFA0A0A03F3F3F242424D8D8D8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD1D1D13B3B3B161616A1A1A1FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F28B8B8B131313323232BCBCBCFDFDFDFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBEFEFEFFDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB1B1B1141414 +626262F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF525252949494343434 +E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCB3535351A1A1AA4A4A4 +FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFAFAFAAAAAAA2323231C1C1C9E9E9EF8F8F8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEAEAEAA2A2A2F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF3636362C2C2CD6D6D6FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE7E7E7585858AEAEAEACACAC525252F0F0F0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFC6C6C63333331B1B1BACACACFDFDFDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +C8C8C83F3F3F0D0D0D7C7C7CECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF6F6F6CFCFCFFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA +A4A4A4F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F7F7F76E6E6E0E0E0EA5A5A5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE949494 +5F5F5FFDFDFD6C6C6C7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C32B2B2B +1F1F1FAFAFAFFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF5C5C5C090909 +595959DEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA8585855E5E5E +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF0F0F0FDFDFDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABAB111111696969F6F6F6 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA2A2A25F5F5FE3E3E3FDFDFD6969697B7B7B +FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBEBEBE2A2A2A202020B6B6B6FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F08181810F0F0F3A3A3AC4C4C4FEFEFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFDCDCDC7878780D0D0DACACACFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF3F3F3D4D4D4FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFDBDBDB303030323232DADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE9E9E93636362727274040403E3E3E181818262626BBBBBBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +BABABA242424262626BCBCBCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFAFAFAA5A5A51E1E1E202020A4A4A4FAFAFAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D2D2 +383838363636161616C7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E2 +979797F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6686868 +0F0F0FACACACFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECBDBDBDB9B9B9 +BABABA9B9B9B252525B0B0B0F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB1B1B1212121292929BFBFBFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFEC1C1C1383838111111848484EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFACACACA5A5A5CECECE404040D3D3D3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDEDBEBEBEFBFBFBFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4A4A40E0E0E707070F8F8F8FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8474747EEEEEE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFDFDFDAFAFAF1E1E1E2E2E2EC6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBDBDB575757 +0909095E5E5EE0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFDFDFDFFFFFF959595585858FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFDFDFDF9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD6D6D62B2B2B383838E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF868686A0A0A0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDA6A6A61B1B1B333333 +C8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC7878780E0E0E3F3F3FCACACA +FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFF939393595959FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7 +B6B6B6FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4606060111111B3B3B3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF9F9F9FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFBFBFBA2A2A2181818383838CFCFCFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF7F7F79C9C9C1C1C1C252525ACACACFAFAFAFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F65A5A5A9E9E9EFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE9B9B9BFEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFF9E9E9E0D0D0D767676FAFAFAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9B9B9B +1414143F3F3FD0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFDFDFDBBBBBB3131311212128A8A8AF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEDEDED343434CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF3F3F3DCDCDCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3 +2828283D3D3DE5E5E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9959595131313424242D6D6D6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5D5D5 +5050500B0B0B696969E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E2E2E2393939D2D2D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7 +EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1595959141414B7B7B7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F9F9F99191911010104A4A4AD9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E97070700B0B0B474747 +CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9E9E9E6A6A6AFCFCFCFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D9A3A3A3FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFE9999990B0B0B7D7D7DFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F78989891010104D4D4DDDDDDD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F59393931616162C2C2CB5B5B5FBFBFBFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEEEEEEEAEAEAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD8D8D8B0B0B0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCECECE232323424242 +E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF6F6F68686860D0D0D545454E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFBFBFBB5B5B52A2A2A181818939393F5F5F5FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9 +F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEEEEEE555555181818BDBDBDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F47D7D7D0C0C0C +575757E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +CFCFCF4646460A0A0A727272E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4D8D8D8FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD +9292920B0B0B838383FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF1F1F17B7B7B0B0B0B5D5D5DE8E8E8FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E46868680A0A0A +4F4F4FD5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFC5C5C5ABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8C8C8202020474747EAEAEAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1 +7272720A0A0A646464E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F38A8A8A131313303030BBBBBBFDFDFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDE +CECECEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFECECEC4E4E4E1C1C1CC3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC6D6D6D0A0A0A676767EEEEEEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFBFBFBACACAC2525251A1A1A9C9C9CF8F8F8FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAFAFAFAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC8989890A0A0A +8A8A8AFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFEBEBEB6666660A0A0A707070EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFECBCBCB3F3F3F0D0D0D767676ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFCDCDCDC7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C21B1B1B4F4F4FEDEDEDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E75E5E5E0C0C0C747474 +F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E0616161 +080808565656DADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF +B8B8B8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E9E9E9464646202020C9C9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE5E5E55B5B5B0C0C0C7D7D7DF3F3F3FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F18484840F0F0F363636C1C1C1 +FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECE9E9E9FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB8181810B0B0B929292FDFDFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E1525252 +0E0E0E808080F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF9F9F9A5A5A52121211E1E1EA4A4A4F8F8F8FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEDEDEDEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFBCBCBC171717555555EFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD4F4F4F0E0E0E898989F6F6F6FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFDFDFDC4C4C43A3A3A101010818181F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8 +C1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6404040 +242424CECECEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +DCDCDC4747471111118F8F8FF6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDCDCDC +5757570909095D5D5DDEDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3C3C3CBCBCBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA7A7A7A0C0C0C999999FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6444444111111949494F9F9F9 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB7A7A7A0E0E0E404040 +C8C8C8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF8F8F8F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFB6B6B61414145B5B5BF2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD5D5D53E3E3E1414149A9A9AF9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F89C9C9C1B1B1B242424AAAAAAFAFAFAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD3D3D3 +E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E43B3B3B292929D3D3D3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF393939161616 +9F9F9FFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFCFCFCBBBBBB3232321313138B8B8BF2F2F2FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABABC7C7C7FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF9F9F97474740C0C0C9E9E9EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFCCCCCC363636171717A8A8A8FBFBFBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +D7D7D75050500A0A0A666666E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD2D2D2E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B2 +111111626262F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC6C6C6 +2F2F2F1A1A1AAAAAAAFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E87171710A0A0A +434343CFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7 +FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E03636362C2C2CD7D7D7FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEC2C2C22E2E2E1D1D1DB2B2B2FEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F59696961818182A2A2AB2B2B2FCFCFC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB5B5B5DADADAFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF7F7F76F6F6F0E0E0EA6A6A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFEBDBDBD272727232323B5B5B5FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFCFCFCB6B6B62B2B2B131313909090F5F5F5FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFA8A8A8D3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAA0E0E0E686868 +F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEB5B5B5252525242424BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD2D2D24A4A4A0B0B0B6F6F6FE8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9 +F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFDADADA313131313131DCDCDCFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFDFDFDB2B2B22020202B2B2BC0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7696969 +0909094B4B4BD2D2D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E2F4F4F4FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6 +686868111111ABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDAAAAAA1D1D1D +2E2E2EC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F38D8D8D1414142F2F2FBABABA +FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF9D9D9DDBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4A4A40D0D0D6F6F6FF8F8F8FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFCFCFCA7A7A7191919343434CBCBCBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFBFBFBAFAFAF2727271A1A1A989898F5F5F5FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B2 +E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD6D6D62C2C2C373737DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB +9F9F9F151515393939CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFEFEFECACACA4141410C0C0C757575ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7FCFCFCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3606060141414 +B2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA9A9A9A1414143D3D3DD3D3D3FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E2 +6262620A0A0A545454D9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9D9D0D0D0D757575F9F9F9FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFAFAFA959595101010444444D4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF838383111111363636 +BEBEBEFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF929292 +E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +D0D0D02626263B3B3BE2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F88F8F8F0F0F0F474747 +DBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9A6A6A62222221E1E1EA2A2A2F9F9F9FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACAF1F1F1FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F25A5A5A161616B7B7B7FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF7F7F78B8B8B0C0C0C4E4E4EDDDDDDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEFEFEC5C5C53939390E0E0E7E7E7EEEEEEEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEFEFEF3F3F3FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFF9696960C0C0C7C7C7CFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5828282 +0B0B0B515151E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +DCDCDC5959590909095B5B5BE0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBA4A4A4 +EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCC212121 +424242E6E6E6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F38080800A0A0A595959E5E5E5FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7D7D7D0C0C0C +3C3C3CC6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB9B9B9BE9E9E9FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0525252181818BDBDBDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F1F1F17777770909095C5C5CE7E7E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F79E9E9E1C1C1C222222A9A9A9FAFAFA +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFEFEFEE9E9E9FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFEFE8E8E8E0B0B0B848484FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE727272090909646464ECECEC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFDFDFDBFBFBF343434111111878787F0F0F0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBDCDCDC +F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7C7C71C1C1C484848E9E9E9 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEDEDED6A6A6A0909096A6A6AEBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD7D7D7515151090909636363E2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3969696EDEDEDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFECECEC4B4B4B1B1B1BC4C4C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8636363090909 +6F6F6FF0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB747474 +0D0D0D434343CCCCCCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF4F4F4B4B4B4F3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFD898989 +0B0B0B8A8A8AFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFE7E7E75E5E5E0A0A0A777777F0F0F0FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6979797171717282828AEAEAE +FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF8F8F8 +FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C21818184E4E4EEDEDEDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3E3E3 +5757570C0C0C7B7B7BF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFCFCFCB6B6B62F2F2F1414148D8D8DF3F3F3FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5BDBDBDF5F5F5FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE8E8E84646461E1E1EC8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0E0E05353530C0C0C848484F4F4F4FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD2D2D24A4A4A0B0B0B6C6C6CE5E5E5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFEBEBEB979797F1F1F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC8383830B0B0B919191 +FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFDEDEDE4B4B4B0E0E0E878787F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5 +6B6B6B0B0B0B484848D2D2D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5D3D3D3 +FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFBCBCBC171717545454EFEFEFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDADADA4848480E0E0E8F8F8F +F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F39090901414142F2F2F +B7B7B7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF1F1F1FEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6 +414141212121CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD8D8D8414141111111939393F8F8F8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBAFAFAF272727181818979797F6F6F6FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE7E7E7A6A6A6F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA7B7B7B0C0C0C979797FEFEFEFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD1D1D13E3E3E +1111119B9B9BFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFCDCDCD4242420A0A0A747474EBEBEBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6A4A4A4 +F8F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFB6B6B6151515595959F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0D0D0383838151515A1A1A1FAFAFAFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E2E2E2616161090909535353D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAEEEEEEFDFDFDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1E1E1393939272727 +D2D2D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +CACACA323232171717A5A5A5FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2868686101010 +333333BEBEBEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF2F2F2D9D9D9FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF9F9F97474740D0D0D9D9D9DFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEC6C6C62F2F2F1A1A1AADADADFDFDFD +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA9A9A92121211D1D1D9F9F9FF8F8F8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD9B9B9B +FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +AFAFAF121212616161F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC0C0C02929291E1E1EB0B0B0FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEFEFEC5C5C53C3C3C0E0E0E7A7A7AEDEDEDFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9E9E9BCBCBCFCFCFCFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD3434342C2C2CD6D6D6FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEBABABA272727222222 +B8B8B8FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFDEDEDE5D5D5D0808085A5A5ADCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFCFCFCF9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF7F7F76B6B6B0E0E0EA5A5A5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEFEFEB6B6B6212121282828BBBBBBFEFEFEFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE7D7D7D +101010393939C3C3C3FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4BCBCBC +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA9A9A9101010 +696969F6F6F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDAEAEAE +202020292929C1C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F8F8A2A2A21E1E1E202020A5A5A5 +FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8D8D89E9E9EFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9D9D92F2F2F323232DBDBDBFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCABABAB1B1B1B303030C5C5C5FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDBFBFBF353535101010848484F0F0F0FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF0F0F0DADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F5F5F5646464101010ABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FCFCFCA3A3A3181818333333C9C9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD8D8D8545454090909606060E1E1E1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7EEEEEE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA4A4A40E0E0E6F6F6FF8F8F8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA0A0A0151515393939D0D0D0 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB +7676760B0B0B424242CBCBCBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD6D6D6A7A7A7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD6D6D62A2A2A373737E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFAFAFA9999991212123D3D3DD1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7979797181818262626 +ACACACFBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD8D8D8ABABABFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F35F5F5F +101010B1B1B1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9959595111111 +424242D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCB9B9B92E2E2E1414148E8E8EF3F3F3FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9F2F2F2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9D9D9D0C0C0C767676F9F9F9FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFF8F8F88F8F8F0D0D0D484848D9D9D9FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFD2D2D24A4A4A090909696969E5E5E5FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE8E8E8D9D9D9FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFD0D0D02626263B3B3BE2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6 +8787870C0C0C4C4C4CDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E7E7E76D6D6D0A0A0A484848D1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC9C9C9A7A7A7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1595959131313B8B8B8 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F58484840A0A0A535353E0E0E0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F58E8E8E161616 +2C2C2CB5B5B5FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDEDEDEC9C9C9 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFEFEFE9595950B0B0B7C7C7CFBFBFBFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF3F3F37A7A7A0A0A0A575757E4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCB2B2B2292929161616929292F6F6F6 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBFAFAFAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCB +222222404040E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F0F0777777090909606060 +E8E8E8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFCFCFCF4545450C0C0C717171E9E9E9FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFD1D1D1C6C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE515151181818BDBDBDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFEEEEEE6E6E6E080808636363EAEAEAFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE2E2E26666660909094E4E4ED5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2C2C2B3B3B3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFDFDFD8E8E8E0A0A0A838383FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFEAEAEA696969 +0909096C6C6CEDEDEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F2F2898989 +111111303030BCBCBCFCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEBE6E6E6FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5C5C51E1E1E484848 +E9E9E9FFFFFFFFFFFFFFFFFFFFFFFFEAEAEA636363090909717171EEEEEEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAA9A9A92323231B1B1B9B9B9B +F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF0F0F0F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFEAEAEA4C4C4C1C1C1CC2C2C2FFFFFFFFFFFFFFFFFFFFFFFF +E5E5E55D5D5D090909777777F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEC8C8C83E3E3E0D0D0D7A7A7AEDEDEDFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDBFBFBF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC +8787870A0A0A8A8A8AFCFCFCFFFFFFFFFFFFFFFFFFE4E4E45858580B0B0B7D7D7DF2F2F2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFDFDFDF5B5B5B090909585858DBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4C4C4C6C6C6FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0C0C01B1B1B4D4D4DECECECFFFFFF +FFFFFFFFFFFFE0E0E05050500B0B0B818181F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE +7F7F7F0F0F0F383838C1C1C1FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFF7F7F7F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE8E8E8444444202020C8C8C8FFFFFFFFFFFFFFFFFFDEDEDE4E4E4E0D0D0D +8A8A8AF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9A1A1A11D1D1D202020 +A5A5A5F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8D8D8E2E2E2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB8080800A0A0A +909090FDFDFDFFFFFFFFFFFFDADADA4646460F0F0F8D8D8DF8F8F8FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDBFBFBF363636111111818181EFEFEFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFABABABC7C7C7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBCBCBC161616545454EFEFEFFFFFFFFFFFFFD5D5D5 +434343101010959595F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFDADADA555555080808606060E1E1E1FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFCDCDCDE2E2E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +E5E5E53E3E3E242424CDCDCDFFFFFFFFFFFFD4D4D43B3B3B141414999999FAFAFAFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +EAEAEA7676760C0C0C3E3E3EC9C9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9FBFBFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFA7979790B0B0B989898FEFEFE +FFFFFFCCCCCC363636151515A1A1A1FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F79B9B9B1B1B1B +232323ABABABFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBABABAD8D8D8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFB4B4B41313135C5C5CF1F1F1FFFFFFCACACA3232321A1A1AA8A8A8 +FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDBABABA2F2F2F1111118A8A8AF3F3F3 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFA5A5A5D5D5D5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E2E23A3A3A +272727D3D3D3FFFFFFC3C3C32C2C2C1C1C1CACACACFDFDFDFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFD6D6D64E4E4E0A0A0A656565E3E3E3FFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5F4F4F4 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F97272720C0C0CA0A0A0FFFFFFBFBFBF2A2A2A +212121B3B3B3FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFE9E9E96E6E6E0A0A0A464646CFCFCFFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE4E4E4F7F7F7FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFAEAEAE101010606060F4F4F4BABABA242424242424B6B6B6FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4929292 +1616162A2A2AB2B2B2FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFF9A9A9AE0E0E0FFFFFFFFFFFFFFFFFFFFFFFFDEDEDE3434342C2C2CD8D8D8 +B6B6B6232323282828BEBEBEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCB3B3B32A2A2A151515929292 +F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFADADADE6E6E6 +FFFFFFFFFFFFFFFFFFF7F7F76B6B6B0E0E0EA5A5A5B2B2B21D1D1D2C2C2CC0C0C0FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFEFEFECDCDCD4545450C0C0C6F6F6FE8E8E8FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F6FCFCFCFFFFFFFFFFFFFFFFFFA8A8A8 +0E0E0E666666A1A1A11C1C1C2E2E2EC7C7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFE4E4E46868680909094D4D4DD3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFC1C1C1F3F3F3FFFFFFFFFFFFD8D8D83030302E2E2E8282821B1B1B353535 +CACACAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1 +888888131313313131BABABAFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E8E8EE8E8E8 +FFFFFFF5F5F56666660E0E0E4A4A4A181818363636CECECEFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAABABAB252525191919 +999999F7F7F7FFFFFFFFFFFFFCFBFBEAEAEAA5A5A5DEDDDDFCFBFBA2A2A20D0D0D191919 +1010103F3F3FD3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEC7C7C73D3D3D0C0C0C787878EDEDEDECECEC +A0A5A57B88897E8D8E7C898A8A90902B2B2B010101050505434343D5D5D5FFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFE0E0E05F5F5F0A0A0A4F4F4F85909199B7B9B6DBDEB9DEE1B7DCDF +95B3B63743440303034A4A4ADBDBDBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +F1F1F17F7E7E2A30319BBBBDBDE2E5BBE0E3BADFE2BBE0E3BDE3E6A0C0C34F5757D2D2D2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7C7C77D9294BBE0E3 +BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3879D9FC6C7C8FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6A8A895B2B4BDE2E5BBE0E3BBE0E3BBE0E3BBE0E3 +BADFE2BCE1E49AB9BB9A9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FEFDFD9CA0A09BBABCBCE2E5BBE0E3BBE0E3BBE0E3BBE0E3BBE0E3BBE1E4A2C3C68D9293 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA6A8A894B1B3BDE2E6 +BADFE2BBE0E3BBE0E3BBE0E3BADFE2BCE1E49BB9BC9A9E9EFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCBCBCB83989ABAE0E3BBE0E3BBE0E3BBE0E3BBDFE2 +BBE0E3BBE0E3869C9EC5C6C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFF9F8F8969C9D9EBDBFBCE2E5BBE0E3BBE0E3BBE0E3BCE2E5A1C1C492999AF5F5F5 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E3E38D9798 +98B5B7B4D8DBB8DDE0B4D9DB9AB8BA8A9596DDDEDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEBA2A6A77F8D8E7B8E8F7E8D8E +9FA4A4E9E9E9FFFFFFFFFFFFFFFFFFFAFAFAF0F0F0EFEFEFF3F3F3FEFEFEFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFCFCFCE6E6E6DBDBDBE5E5E5FBFBFBFFFFFFFFFFFFFFFFFF +FAFAFA898989303030343434444444D3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFC858585272727ACACACCACACA +777777525252D7D7D7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF6F6F6707070BBBBBBFFFFFFFFFFFFFFFFFF555555989898FFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE +FEFEFEFEFEFEFEFEFEFDFDFDCECECE4D4D4DB2B2B2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9C9C94A4A4A +151515666666FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5A8A8A88E8E8E282828A0A0A0FEFEFE +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C9C9C343434F0F0F0FFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCDEDEDEF5F5F5FFFFFFFFFFFF +FFFFFFC9C9C9353535F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFF5F5F54B4B4B7A7A7AF8F8F8FFFFFFF9F9F97C7C7C6D6D6DFBFBFB +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +C3C3C3363636636363777777646464363636CBCBCBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEE6E6E68F8F8F717171 +8D8D8DE5E5E5FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + +end +%%PageTrailer +%%Trailer +%%EOF diff --git a/doc/doxygen/figures/polyhedron_connectivity_small.png b/doc/doxygen/figures/polyhedron_connectivity_small.png new file mode 100644 index 000000000..fa59ed5c0 Binary files /dev/null and b/doc/doxygen/figures/polyhedron_connectivity_small.png differ diff --git a/doc/doxygen/grid.dox b/doc/doxygen/grid.dox new file mode 100644 index 000000000..36e09d3f8 --- /dev/null +++ b/doc/doxygen/grid.dox @@ -0,0 +1,21 @@ +/*! +\page grid GRID +\section GRIDgeneral General Information + +The GRID class represents structured meshes in the MEDMEM library. +As the GRID class inherits from MESH, all of the functionalities that were +described in the previous section apply for structured mesh GRID objects. +In particular, reading and writing from files, general information access +are similar. However, because of the particular nature of structured meshes, +there exist methods to access information related to the axes of the grid. + +The numbering of the cells and nodes in a grid starts at one and +the inner loop is that of the first axis, the outer loop being the one +of the last axis (c.f. figure \ref fig_grid_connectivity} ). + +\image html grid_example.png "Example for structured mesh connectivity. The numbering is automatically defined from the two input verctors X and Y." + +\section grid_outline Outline + +Constructors are defined in \ref GRID_constructors, methods related to axes are defined in \ref GRID_axes, while connectivity methods are given in \ref GRID_connectivity. +*/ diff --git a/doc/doxygen/interpkernel.dox b/doc/doxygen/interpkernel.dox new file mode 100644 index 000000000..deba6a461 --- /dev/null +++ b/doc/doxygen/interpkernel.dox @@ -0,0 +1,300 @@ +/*! +\page interpkernel Interpolation kernel toolkit + +\section InterpKerIntro Introduction + +The main purpose of this module is to propose a set of algorithms for +mesh interpolation \b fully \b independant \b of \b mesh \b datastructure to +support several type of format. This component is parameterized as +much as possible using C++ templates. +For the moment only interpolators for unstructured meshes are present in +%interpolation kernel. + +\section InterpKerTheory Theory of interpolation + +\subsection InterpKerPerfOverl Mesh overlapping + +When interpolation is performed between a source mesh S and a target +mesh T the aspect of overlapping is important. In fact if any cell of +of S is fully overlapped by cells of T and inversely any cell of T is +fully overlapped by cells of S the meshes S and T are said \b +coincidant and some general formulae in next sub section are simpler. +As far as possible in the next sub sections the formulae for +coincidant and non-coincidant meshes will be given. + +\subsection InterpKerRemapGlobal Global conservative remapping + +For fields with polynomial representation on each cell, the components of the discretized field \f$ \phi_s \f$ on the source side can be expressed as linear combinations of the components of the discretized field \f$ \phi_t \f$ on the target side, in terms of a matrix-vector product : + +\f[ + \phi_t=W.\phi_s. +\f] + +All the aim of interpolators is to compute W depending on a physical +quantities and the type of interpolation wanted (P0, P1, P1d etc...). + +For the \b intensive \b field \f$ \phi \f$ from the +source mesh \f$ S \f$ to the target mesh \f$ T \f$ the interpolation should preserve the +integral of \f$ \phi \f$ on any domain. At the discrete level, for any +target cell \f$ T_i \f$, the following \b general \b interpolation \b +equation \anchor InterpKerGenralEq has to +be always verified : + +\f[ +\int_{T_i} \phi = \sum_{S_j\cap T_i \neq \emptyset} \int_{T_i\cap S_j} \phi. +\f] + +To compute \f$ W_{ij} \f$ +this equation is used. The evaluation of integrals depends on the source and target meshes and on the nature of interpolation chosen : P0, P1, P1d etc... For the moment it is only possible to +remap fields with P0 representations. + +\subsection InterpKerRemapInt Conservative remapping of intensive physical quantities + +At the basis of many CFD numerical schemes is the fact that physical +quantities such as density, momentum per unit volume or energy per +unit volume obey some balance laws that should be preserved at the +discrete level on every cell. This property is critical for example to +accurately capture shockwaves. + +\subsection InterpKerP0P0Int cell-cell (P0->P0) conservative remapping of intensive physical quantities + +In the \ref InterpKerGenralEq "general interpolation equation" the +left hand side becomes : + +\f[ +\int_{T_i} \phi = (\sum_{S_j} Vol(T_i\cap S_j)).\phi_{T_i}. +\f] + +\note \f$ \sum_{S_j} Vol(T_i\cap S_j) = Vol(T_i) \f$ \ref InterpKerPerfOverl "in case of perfect overlapping". + +In the \ref InterpKerGenralEq "general interpolation equation" the +right hand side becomes : + +\f[ +\sum_{S_j\cap T_i \neq \emptyset} \int_{T_i\cap S_j} \phi = \sum_{S_j\cap T_i \neq \emptyset} {Vol(T_i\cap S_j)}.\phi_{S_j}. +\f] + +In the case where the \b intensive field values are constant on each +cell, the coefficients of the linear remapping matrix \f$ W \f$ are +given by the formula : + +\f[ + W_{ij}=\frac{Vol(T_i\cap S_j)}{ \sum_{S_j} Vol(T_i\cap S_j) }. +\f] + +and \ref InterpKerPerfOverl "in case of perfect overlapping" : + +\f[ + W_{ij}=\frac{Vol(T_i\cap S_j)}{ Vol(T_i) }. +\f] + +Where Vol represents the volume with mesh dimension of interpolation equals to 3, the +area when mesh dimension equals to 2, and length when mesh dimension equals to 1. + +\subsection InterpKerRemapExt Conservative remapping of extensive physical quantities + +In code coupling from neutronics to hydraulic code \b extensive field +of power is exchanged and the all power as to be kept the same. The +principle is to 'intensify' the field to move on from extensive field +\e P to an intensive one \f$ \phi \f$. + +\subsection InterpKerP0P0Ext cell-cell (P0->P0) conservative remapping of extensive physical quantities + +In the \ref InterpKerGenralEq "general interpolation equation" the +left hand side becomes : + +\f[ +\int_{T_i} \phi = P_{T_i}. +\f] + +In the \ref InterpKerGenralEq "general interpolation equation" the +right hand side becomes : + +\f[ +\sum_{S_j\cap T_i \neq \emptyset} \int_{T_i\cap S_j} \phi = +\sum_{S_j\cap T_i \neq \emptyset} \frac{Vol(T_i\cap S_j)}{\sum_{T_i} Vol(T_i \cap S_j)}.P_{S_j}. +\f] + +\note \f$ \sum_{T_i} Vol(T_i \cap S_j) = Vol(S_j) \f$ \ref InterpKerPerfOverl "in case of perfect overlapping". + +In the case where the \b extensive field values are constant on each +cell, the coefficients of the linear remapping matrix \f$ W \f$ are +given by the formula : + +\f[ + W_{ij}=\frac{Vol(T_i\cap S_j)}{ \sum_{T_i} Vol(T_i \cap S_j) }. +\f] + +and \ref InterpKerPerfOverl "in case of perfect overlapping" : + +\f[ + W_{ij}=\frac{Vol(T_i\cap S_j)}{ Vol(S_j) }. +\f] + +\section InterpKerMainArchitecture Main architecture of interpolation kernel. + +In %interpolation kernel, the algorithm that computes \f$ W_{ij} \f$ given cell i +in source mesh and cell j in target mesh is called intersector. + +As seen in \ref InterpKerTheory "the theory of interpolation", for all interpolation the aim is to +fill the W matrix (which is generally a sparse matrix). Fundamatally for each pair (i,j) \f$ W_{ij} \f$ is obtained +by calling each time the wanted intersector. The problem is that each call to algorithm +is CPU-expensive. +To reduce the computation time a first filtering is done to found a +maximim of (i,j) pairs where \f$ W_{ij} \f$ is obviously equal to 0. Typically it +is the case when a cell in source mesh is too far from an another cell +in target mesh each other. + +So for a given type of interpolation, the computation of W is +performed in two steps : + + -# A filtering process reduces the number of pairs of + elements for which the calculation must be carried out by + eliminating pairs that do not intersect through a comparison of + their bounding boxes. It reduces as much as possible call to intersector. + -# For all remaining pairs calling for each intersector (see \ref interpolation2D, \ref interpolation3Dsurf or \ref interpolation3D). + +Each interpolator inherits from INTERP_KERNEL::Interpolation ( whatever +its dimension and its type ) that is a +CRTP class in order to clearly see the main API without useless CPU cost. + +\subsection InterpKerMeshType class MeshType + +Each Interpolators and Intersectors are parameterized (templated in +C++ langage) with \c class \c MeshType . This type of generalization +has been chosen to reduce at maximum overhead. \n +Thanks to this principle \b intersectors \b and \b interpolators \b are \b usable +\b with \b several \b formats \b without \b preformance \b loss. For example MED, VTK...\n +\c MeshType is a concept that should strictly fulfilled the following +rules : + + - Const values / Types + - MyConnType : represents type of connectivity index. This is typically \c int or \c long \c int . + - MY_SPACEDIM : space dimension. Dimension relative to coordinates. + - MY_MESHDIM : the dimension of all cells in meshes. + - My_numPol : policy of numbering. C Format ( \f$ [0,n-1] \f$ ) or FORTRAN ( \f$ [1,n] \f$ ). + - Methods + -# \code void getBoundingBox(double *boundingBox) const \endcode + -# \code INTERP_KERNEL::NormalizedCellType getTypeOfElement(MyConnType eltId) const \endcode + -# \code unsigned char getNumberOfNodesOfElement(MyConnType eltId) const \endcode + -# \code unsigned long getNumberOfNodes() const \endcode + -# \code unsigned long getNumberOfElements() const \endcode + -# \code const MyConnType *getConnectivityPtr() const \endcode + -# \code const double *getCoordinatesPtr() const \endcode + -# \code const MyConnType *getConnectivityIndexPtr() const \endcode + -# \code void ReleaseTempArrays() \endcode + - Formats of arrays + - the array returned by \c getCoordinatesPtr must be a \b full \b interlace array. + - the arrays returned by \c getConnectivityPtr and \c + - getConnectivityIndexPtr must be with the same principle as it is in \ref medmemConnArrays "medmem". Of course the numbering format may change according to \a My_numPol policy. + +\note The arrays formats of connectivity is kept close to MED. It is +close to VTK too but slightly different. So it needs VTK side a copy +on wrap. To avoid this copy of a part of connectivity structure, iterator should be used. + +\subsection InterpKerMatrixType class MatrixType + +As already said, the matrix returned by interpolator is typically a sparse matrix. Instances of +\c class \c MatrixType are used to stores these results of +interpolation. To be able to be filled by the interpolator the \c MatrixType class has to match the following concept : + + - Methods + -# \code void resize(uint nbrows) \endcode + -# \code Row &operator [] (uint irow) \endcode + +\c class \c Row has to match at least following concept : + + - Methods + - \code void insert(const std::pair& myPair) \endcode + +\note \c std::vector\c < \c std::map > is a candidate for +\c MatrixType. + +\section InterpKerGenUsage Usage of interpolation kernel. + +\subsection InterpKerHighLevUsage high-level usage + +This the simplest mode of usage of interpolator. This way is strongly +linked with MED data-structure. All interpolators is completely hidden +to you. Even sparse interpolation matrix is hidden. An exemple of +usage : + +\code +... +std::string sourceFileName("source.med"); +MEDMEM::MESH med_source_mesh(MED_DRIVER,sourceFileName,"Source_Mesh"); +std::string targetFileName("target.med"); +MEDMEM::MESH med_target_mesh(MED_DRIVER,targetFileName,"Target_Mesh"); +FIELD sourceField(MED_DRIVER,sourceFileName,"Density",0,0); +FIELD targetField; +Remapper mapper; +mapper.prepare(med_source_mesh,med_target_mesh); +mapper.transfer(sourceField,targetField); +//use targetField +... +\endcode + +\subsection InterpKerMidLevUsage middle-level usage + +This mode is the mode that needs the minimum of prerequisites +(algorithms and the datastructure you intend to use). On the other +hand it is needed to specify precisely nature of interpolator. + +As consequence of genericity of interpolators, they are usable only by +instanciating an underneath mesh data structure. The two following +examples show how to use interpolator at this level. + +- The simplest way to use the interpolator with MED datastructure is : + +\code +... +std::string sourceFileName("source.med"); +MEDMEM::MESH med_source_mesh(MED_DRIVER,sourceFileName,"Source_Mesh"); +std::string targetFileName("target.med"); +MEDMEM::MESH med_target_mesh(MED_DRIVER,targetFileName,"Target_Mesh"); +// Ok at this point we have our mesh in MED-Memory format. +// Go to wrap med_source_mesh and med_target_mesh. +MEDNormalizedUnstructuredMesh<2,2> wrap_source_mesh(&med_source_mesh); +MEDNormalizedUnstructuredMesh<2,2> wrap_target_mesh(&med_target_mesh); +// Go for interpolation... +INTERP_KERNEL::Interpolation2D myInterpolator; +//optionnal call to parametrize your interpolation. First precision, tracelevel, intersector wanted. +myInterpolator.setOptions(1e-7,0,Geometric2D); +INTERP_KERNEL::Matrix resultMatrix; +myInterpolator.interpolateMeshes(wrap_source_mesh,wrap_target_mesh,resultMatrix,"P0P0"); +//Ok let's multiply resultMatrix by source field to interpolate to target field. +resultMatrix.multiply(...) +... +\endcode + +- Same with VTK datastructure : + +\code +... +vtkXMLUnstructuredGridReader *readerSource=vtkXMLUnstructuredGridReader::New(); +readerSource->SetFileName("source.vtu"); +vtkUnstructuredGrid *vtk_source_mesh=readerSource->GetOutput(); +readerSource->Update(); +vtkXMLUnstructuredGridReader *readerTarget=vtkXMLUnstructuredGridReader::New(); +readerTarget->SetFileName("target.vtu"); +vtkUnstructuredGrid *vtk_target_mesh=readerTarget->GetOutput(); +readerTarget->Update(); +// Ok at this point we have our mesh in VTK format. +// Go to wrap vtk_source_mesh and vtk_target_mesh. +VTKNormalizedUnstructuredMesh<2> wrap_source_mesh(vtk_source_mesh); +VTKNormalizedUnstructuredMesh<2> wrap_target_mesh(vtk_target_mesh); +// Go for interpolation... +INTERP_KERNEL::Interpolation2D myInterpolator; +//optionnal call to parametrize your interpolation. First precision, tracelevel, intersector wanted. +myInterpolator.setOptions(1e-7,0,Geometric2D); +INTERP_KERNEL::Matrix resultMatrix; +myInterpolator.interpolateMeshes(wrap_source_mesh,wrap_target_mesh,resultMatrix,"P0P0"); +//Ok let's multiply resultMatrix by source field to interpolate to target field. +resultMatrix.multiply(...) +//clean-up +readerSource->Delete(); +readerTarget->Delete(); +... +\endcode + +*/ diff --git a/doc/doxygen/main.dox b/doc/doxygen/main.dox new file mode 100644 index 000000000..a155d6a4d --- /dev/null +++ b/doc/doxygen/main.dox @@ -0,0 +1,23 @@ +/*!\mainpage MEDMEM user's guide + +\image html MED_small.png +\image latex MED_small.eps +\anchor fig_MED_small + +\section intro Introduction +This document constitutes the user guide of the %MEDMEM library and of its related tools. + +\section install Installation +The install procedure of the %MEDMEM library can handle a variety of configurations +to suit the needs of its user. Instructions for configuring and installing the library can be found in \ref medmem_install. + +\section outline Outline +This user guide contains three different chapters that covers the core %MEDMEM library, the %ParaMEDMEM library and the %MEDSPLITTER tool: +- Chapter \ref medmem covers the %MEDMEM core library, i.e. the implementation of meshes, supports and fields and the associated drivers (for MED-file, VTK, GIBI). +- Chapter \ref interpkernel describes the interpolation and +localization library. +- Chapter \ref paramedmem describes its MPI implementation, which is called %ParaMEDMEM. +- Chapter \ref tools describes various tools based on MEDMEM that can +be helpful for handling MED files (conversion tools and splitting tools). + +*/ diff --git a/doc/doxygen/medmem.dox b/doc/doxygen/medmem.dox new file mode 100644 index 000000000..429234d1b --- /dev/null +++ b/doc/doxygen/medmem.dox @@ -0,0 +1,268 @@ +/*! +\page medmem MEDMEM library + +\section medmem_introduction Introduction +\subsection medmem_rationale Rationale for Med Memory + +The Med data exchange model (DEM in English) is the format used in the Salome platform for communicating data between different components. It manipulates objects that describe the meshes underlying scientific computations and the value fields lying on these meshes. This data exchange can be achieved either through files using the Med-file formalism or directly through memory with the Med Memory (\c %MEDMEM) library. + +The Med libraries are oganized in multiple layers: +- The MED file layer : C and Fortran API to implement mesh and field persistency. +- The MED Memory level C++ API to create and manipulate mesh and field objects in memory. +- Python API generated using SWIG which wraps the complete C++ API of the MED Memory +- CORBA API to simplify distributed computation inside SALOME (Server Side). +- MED Client classes to simplify and optimize interaction of distant objects within the local solver. + +Thanks to Med Memory, any component can access a distant +mesh or field object. Two codes running on +different machines can thus exchange meshes and fields. +These meshes and fields can easily be read/written in a Med file +format, enabling access to the whole Salome suite of tools +(CAD, meshing, Visualization, other components). + +\subsection medmem_outline Outline + +In this document, we describe the API of the Med Memory library (available in C++ and in Python). This document is intended for developers who are in charge of integrating existing applications in the Salome platform. + +As will be seen in section \ref medmem_api, the API consists of very few classes: + +- a general MED container : \ref MED_class, +- meshes : \ref mesh , +- structured meshes : \ref grid , +- supports and derived classes : \ref support , +- mesh generation tool : \ref meshing , +- fields : \ref field , +- drivers for reading and writing in MED, GIBI and VTK files. + +All these are detailed in the following sections. The C++ +formalism will be used for the description in these sections. + Python syntax is very similar and is given in appendix \ref medmem_sec_python. + +\subsection medmem_naming Naming conventions + +The naming conventions are rather straightforward, but the user familiar with the Med-File semantics may find that there are a few noticeable differences (see the following section). + +- \b cell entity of dimension equal to the mesh dimension (1, 2 or 3). +- \b component in a field, represents a value that is available for each element of the support (for instance : \f$ T \f$, \f$ v_x \f$, \f$ \sigma_{xy} \f$)). +- \b connectivity \b (descending) connectivity table expressing connectivity of dimension \a d elements in terms of list of dimension \a d-1 elements. +- \b connectivity \b (nodal) connectivity table expressing connectivity of dimension \a d elements in terms of list of nodes. +- \b constituent \b entity entity having a dimension smaller than that of the mesh. +- \b coordinates in a mesh, coordinates can be described by strings giving the names of the coordinates, the units of the coordinates, and the type of coordinates ('MED_CART', 'MED_SPHER' or 'MED_CYL'). +- \b description string of characters used to describ an object without giving any access to a query method. +- \b dimension Med Memory discriminates the mesh dimension from the space dimension (a surface shape in 3D will have 2 as a mesh dimension). +- \b driver object attached to a mesh or a field to read (resp. write) data from (resp. to) a Med-file. +- \b edge entity of dimension 1 in a 2D mesh. +- \b element elementary component of a mesh (0D, 1D, 2D or 3D). +- \b entity category giving information on the dimension of elementary components of meshes : node, edge, face (only in 3D) or cell. +- \b face for 3D meshes, faces are the 2D entities. +- \b family support which is composed of a set of groups, which do not intersect each other, and which gives access to those groups. +- \b field array of integer, integer array, real or real array lying on a support (the dimension of the array of values for each element of the support is called the number of components). A field is uniquely defined by its name, its support, its iteration number and its order number. -1 is the default value of those two numbers. +- \b group support with additional access to parent families. +- \b iteration number] information attached to a field that expresses the number of the time step in the computation (-1 is its default value). +- \b name information attached to a mesh, support or field to name it and access to it. +- \b node entity of dimension 0. +- \b order \b number information attached to a field that expresses the number of an internal iteration inside a time step in the computation (-1 is its default value). +- \b support list of elements of the same entity. +- \b type category of an entity (triangle, segment, quadrangle, tetrahedron, hexahedron, etc...). + + +\subsection medmem_diff Differences with Med-File concepts +Though the %MEDMEM library can recompute a descending connectivity +from a nodal connectivity, %MEDMEM drivers can only read MED files containing the nodal +connectivities of the entities. +In %MEDMEM, constituent entities are stored as \c MED_FACE +or \c MED_EDGE, whereas in %MED File, they should be stored as \c + MED_MAILLE. + +The field notion in %MED File and %MEDMEM is quite different. In %MEDMEM +a field is of course defined by its name, but also by its iteration +number and its order number. +In %MED File a field is only flagged by its name. For instance, +a temperature at times \a t=0.0 s, \a t=1.0 s, \a t=2.0 s will be considered as a single field in Med File terminology, while it will be considered as three distinct fields in the Med Memory sense. + +\section medmem_api Med Memory API + +\subsection medmem_conventions Conventions + +- In this document, one refers to the main user documentation +\ref RefManualMedMemory where the variable \c $MED_ROOT_DIR (resp. +\c $MED_SRC_DIR) is the Med Memory directory installation (resp. sources +directory). +- All numberings start at one (take care of array index !). +- When one gets a C (resp. C++) type array (resp. STL container) using a \c {get...} method, one should not modify the array. Access is in read only. To modify a such array (resp. STL container) use a \c {set...} method. +- There are many couple of methods that have similar syntaxes (one singular and one +plural). The plural method returns an array and the singular one returns one +particular value in this array (see \c double \c getCoordinate(int i) and +\c double* \c getCoordinates() for example). Generally, only the plural version +of the methods are documented in this report. +- Difference between local and global number in mesh element connectivity list : when one talks about an +element number, one could see \f$ i^{th} \f$ quadrangle (\f$ i^{th} \f$ in quadrangles array : local numbering) or \f$ j^{th} \f$ element (\f$ j^{th} \f$ in all elements array : +global numbering). These two numberings are equivalent only if one has only one +geometric type. + + +\subsection namespaces Namespaces + +Med Memory uses two namespaces : \c MEDMEM which is the general +namespace where the main classes are defined and \c MED_EN +which defines enums that can be used by an English-speaking +programer. + +\subsection classes Classes +At a basic usage level, the API consists in few classes which are located in +the \c MEDMEM C++ namespace (consult figure \ref fig_UML_light which gives +an UML diagram view of the main Med Memory classes)~: + +- \b MED the global container; +- \b MESH the class containing 2D or 3D mesh objects; +- \b SUPPORT the class containing mainly a list of mesh elements; +- \b FIELD the class template containing list of values lying on a particular support. + +\anchor fig_UML_light +\image html UML_light.png " UML diagram of basic Med Memory API classes" +\image latex UML_light.eps " UML diagram of basic Med Memory API classes" + + +The API of those classes is quite sufficient for most of the component +integrations in the Salome platform. The use of the Med Memory libraries may +make easier the code coupling in the Salome framework. With these classes, it +is possible to~: + +- read/write meshes and fields from MED-files; +- create fields containing scalar or vectorial values on list of elements +of the mesh; +- communicate these fields between different components; +- read/write such fields. + +Note that on the figure \ref fig_UML_light as well as on figure +\ref fig_UML that the +MED container controls the life cycle of all the objects it contains~: its destructor will destroy all the objects it aggregates. On the other hand, the life cycle of mesh, support and field objects are independent. Destroying a support (resp. a field) will have no effect on the mesh (resp. support) which refers to it. But the user has to maintain the link~: a mesh aggregates a support which aggregates a field. If the user has to delete Med Memory objects, the field has to be deleted first, then the support and finally the mesh. + +A more advanced usage of the Med Memory is possible through other classes. +Figure \ref fig_UML gives a complete view of the Med Memory API. It includes : + +- \b GROUP a class inherited from the SUPPORT class used to create supports linked to mesh groups. It stores restricted list of elements used to set boundary conditions, initial values. +- \b FAMILY which is used to manipulate a certain kind of support which does not intersect each other; +\ b MESHING which builds meshes from scratch, it can be used to transform meshes from a specific format to the MED format or to integrate a mesher within Salome platform (note that class does not add element or node to a mesh); +- \b GRID which enables the user to manipulate specific functions for structured grid. + +\anchor fig_UML +\image html UML_small.png "UML diagram of Med Memory API classes" +\image latex UML_small.eps "UML diagram of Med Memory API classes" + + +\subsection medmem_enums Enums +A few enums are defined in the \c MED_EN namespace : + +- an enum which describes the way node coordinates or field values are stored, + - \c MED_FULL_INTERLACE for arrays such that \f$ x_1,y_1,z_1,x_2,y_2,z_2,\ldots,x_n,y_n,z_n \f$; + - \c MED_NO_INTERLACE for arrays such that \f$ x_1,x_2,\ldots,x_n,y_1,y_2,\ldots,y_n,z_1,z_2,\ldots,z_n \f$; + - \c MED_UNDEFINED_INTERLACE, the undefined interlacing mode. + . +- an enum which describes the type of connectivity + - \c MED_NODAL for nodal connectivity; + - \c MED_DESCENDING for descending connectivity. + . + +The user has to be aware of the fact that the Med Memory considers only meshes defined by their nodal connectivity. Nevertheless, the user may, after loading a file in memory, ask to the mesh object to calculate the descending connectivity. + +- an enum which contains the different mesh entities, \c medEntityMesh, the entries of which being : + - \c MED_CELL + - \c MED_FACE + - \c MED_EDGE + - \c MED_NODE + - \c MED_ALL_ENTITIES + . + +In 3D (resp. 2D), the user has to be aware of the fact that only mesh +entities \c MED_CELL and \c MED_FACE (resp. \c MED_EDGE) are +considered. In 1D, of course only mesh entities \c MED_CELL+ are considered. Using our naming convention (consult \ref medmem_naming), in $1$ D mesh +only \b node and \b cell are considered. In 2D mesh, only \b node, +\b cell and \b edge are considered. Finally in 3D mesh only +\b node}, \b cell and \b face are considered. + +- The \c medGeometryElement enum which defines geometric types. The +available types are linear and quadratic elements (consult +\ref RefManualMedMemory). The entries of this enum are quite +self-explanatory : + - \c MED_NONE + - \c MED_POINT1 + - \c MED_SEG2 + - \c MED_SEG3 + - \c MED_TRIA3 + - \c MED_QUAD4 + - \c MED_TRIA6 + - \c MED_QUAD8 + - \c MED_TETRA4 + - \c MED_PYRA5 + - \c MED_PENTA6 + - \c MED_HEXA8 + - \c MED_TETRA10 + - \c MED_PYRA13 + - \c MED_PENTA15 + - \c MED_HEXA20 + - \c MED_POLYGON + - \c MED_POLYHEDRA + - \c MED_ALL_ELEMENTS + . +The connectivity of all these elements is defined in MED project Web page +http://hammi.extra.cea.fr/static/MED/web_med/logiciels/med-2.3.1/doc/ . + + +*/ + +/*! +\page paramedmem ParaMEDMEM library + + +The ParaMEDMEM library is based on several classes that +describe the coupling between two parallel codes. + +The classes that make up the API of the library are : +- communication interface : \ref comm_interface, +- definition of processor groups : \ref processor_group, +- Data Exchange Channel(aka DEC, abstract class) : \ref dec, and its implementations : + - \ref intersectiondec for a \ref InterpKerRemapGlobal based on intersecting elems volume computation, + - NonCoincident DEC for a non-conservative interpolation based on element localization : \ref noncoincidentdec, + - Explicit Coincident DEC for remapping coincident meshes on a one-to-one basis. This class applies to unstructured topologies: \ref explicit_coincident_dec, + - Structured Coincident DEC for remapping coincident meshes on a one-to-one basis. This class applies to structured topologies : \ref structuredcoincidentdec. + +*/ + +/*! +\page medmem_install Configuring and Installing MEDMEM from sources + +The MEDMEM library can be configured in several manners so that it can run inside or outside the Salome platform. Also, partitioning and parallel functionalities are optional. + +The sources of the library are located in the \a MED_SRC directory. +The first step consists in preparing the configuration of the library : +\verbatim +cd ${MED_SRC} +./build_configure +\endverbatim + +This will create a MEDMEM library with link to the SALOME Kernel. If it is desirable to have a standalone version of the library to be used independently from SALOME, use : +\verbatim +cd ${MED_SRC} +./build_configure --without-kernel +\endverbatim + +The library can then be configured : +\verbatim +mkdir ../MED_BUILD +cd ../MED_BUILD +../MED_SRC/configure --prefix=`pwd`/../MED_INSTALL +\endverbatim + +This will configure the library without splitting functionalities. ParaMEDMEM will be compiled if an MPI version has been found. + +The following options can be useful to configure MEDMEM : +- \a --enable-splitter=yes will trigger the compilation of the MEDSPLITTER tool, +- \a --with-metis=${METISDIR} will specify a location for the METIS library, +- \a --with-scotch=${SCOTCHDIR} will specify a location for the SCOTCH library, +- \a --with-med2=${MED2DIR} specifies a location for MED-file library, +- \a --with-hdf5=${HDF5DIR} specifies a location for the HDF5 library (must be the same as that used for the MED-file library) +- \a --with-lam=${LAMDIR} specifies an install path for a LAM MPI library, +- \a --with-mpich=${MPICHDIR} specifies an install path for a MPICH-1 library. +*/ +>>>>>>> 1.1.4.1.2.1 diff --git a/doc/doxygen/medsplitter.dox b/doc/doxygen/medsplitter.dox new file mode 100644 index 000000000..636fa81f4 --- /dev/null +++ b/doc/doxygen/medsplitter.dox @@ -0,0 +1,16 @@ +/*! +\page medsplitter MEDSPLITTER tool + +The purpose of MEDSPLITTER is to split MED files into +a series of other MED files forming a partition of the original MED files. It can either work with serial meshes (1 to n) or distributed meshes (p to n). For serial meshes, it accepts MED files from the 2.1 version onwards. For distributed MED files, it accepts MED files from the 2.3 version onwards. + +It can be used either as an executable, \a medsplitter or as a library. The partitioning is made thanks to one of the following library : +- METIS (http://glaros.dtc.umn.edu/gkhome/views/metis/index.html) +- SCOTCH (http://www.labri.fr/perso/pelegrin/scotch/scotch_fr.html) + +The arguments to the medsplitter tool can be retrieved by calling : +\code +medsplitter --help +\endcode + +*/ \ No newline at end of file diff --git a/doc/doxygen/mesh.dox b/doc/doxygen/mesh.dox new file mode 100644 index 000000000..9a82793da --- /dev/null +++ b/doc/doxygen/mesh.dox @@ -0,0 +1,61 @@ +/*! +\page mesh MESH + +\section mesh_general General information + +The MESH class is dedicated to the handling of unstructured meshes. Two classes derive from it : MESHING supplies functions for creating meshes from scratch (c.f. \ref meshing), while GRID gives specific constructors for creating structured meshes. + +\section mesh_connectivity Content of the connectivity array +Underlying the unstructured meshes is the notion of connectivity. This section only covers meshes made out of standard elements, the \c MED_POLYGON and \c MED_POLYHEDRA case being detailed in section \ref polygon . + +\anchor medmemConnArrays +\image html connectivity_arrays_small.png "Nodal connectivity storage scheme" +\image latex connectivity_arrays_small.eps "Nodal connectivity storage scheme" + +In MEDMEM, an unstructured mesh nodal connectivity is defined with these arrays (if the mesh has no MED_POLYGON and MED_POLYHEDRA element) : +- the type array, which contains the number of cells for each present type +- the nodal connectivity array containing the connectivity of each cell, all cells being sorted by type, +- the connectivity index array, which indicates the beginning of each cell in the connectivity array, + +The cell types are ordered by their number of nodes. + +As an example, let us consider a mesh made out of a linear triangle, two linear quadrangles and a quadratic triangle (c.f. figure \ref fig_connectivity_example ). +\image html connectivity_example_small.png "Example for mesh connectivity" +\image latex connectivity_example_small.eps "Example for mesh connectivity" +The number of types is : 3 + +The type array writes : +\{ \a MED_TRIA3, \a MED_QUAD4, \a MED_TRIA6 \} + +The global numbering index is : \{ 1,2,4,5 \} }. Its dimension is \f$ n_{types}+1 \f$ +so that elements of type \f$ type[i] \f$ are stored between element \f$ index[i] \f$ and +\f$ index[i+1] \f$ ( \f$ index[i] \leq j < index[i+1] \f$). + +The connectivity array writes : +\{ 1, 2, 3, 2, 4, 5, 3, 5, 6, 7, 8, 4, 6, 5, 10, 11, 9\} + +The connectivity index array writes : +\{ 1, 4, 8, 12, 18\} + +Its dimension is \f$n_{cell}+1\f$, in order to be able to write +that nodes of element \f$i\f$ are located in the connectivity array between +\f$index[i]\f$ and \f$index[i+1]\f$ ( \f$index[i] \leq j < index[i+1]\f$).\\ + + +\warning +As MEDMEM respects MED numbering which starts Fortran-style at 1, reading these information to set C structures requires careful handling of index offsets. + + +\section mesh_outline Outline + +The description of MESH methods is given by the following sections : + +- Description of constructors is given in \ref MESH_constructors. +- Methods retrieveing general information is given in \ref MESH_general. +- Retrieval of information about mesh nodes can be found in \ref MESH_nodes. +- Connectivity information methods are described in \ref MESH_connectivity. +- The methods retrieving family information are given in \ref MESH_families. +- The IO methods are given in \ref MESH_io. +- The methods for an advanced usage (applying algorithms to meshes) are given in \ref MESH_advanced. + +*/ diff --git a/doc/doxygen/meshing.dox b/doc/doxygen/meshing.dox new file mode 100644 index 000000000..de2565a2c --- /dev/null +++ b/doc/doxygen/meshing.dox @@ -0,0 +1,40 @@ +/*! + +\page meshing MESHING + +\section meshing_overview Overview + +This class is a class derived from MESH class that is used +to build a MESH object from scratch. + +All verifications are under user responsability : if array values or array +dimensions are wrong, results are impredictable. +All the arrays passed as arguments in the set methods are duplicated in MESHING object. + +The creation of a mesh should respect the following sequence : +- setting general information (name, description, dimensions, coordinate system, ...), +- setting the nodes (number and coordinates), +- setting the connectivity (types, connectivity arrays,...), +- group creations. + +The following paragraphs describe the methods that must be called +when creating a mesh. An example illustrates the general procedure. +The specific case of \c MED_POLYGON and \c MED_POLYHEDRA +elements requires some methods that are described in \ref polygon. + +\section outline_meshing Outline + +The following sections point to various groups of MESHING methods : +- Constructors : \ref MESHING_constructors, +- General information : \ref MESHING_general, +- Setting nodes : \ref MESHING_nodes, +- Connectivity : \ref MESHING_connectivity, +- Groups : \ref MESHING_group. + +An example of mesh creation via MESHING is given in : +- C++ : +\include MESHINGexample.cxx +- Python: +\include MESHINGexample.py + +*/ \ No newline at end of file diff --git a/doc/doxygen/polygon.dox b/doc/doxygen/polygon.dox new file mode 100644 index 000000000..a9d29de0b --- /dev/null +++ b/doc/doxygen/polygon.dox @@ -0,0 +1,72 @@ +/*!\page polygon Polyhedra and polygons + +\section polygon_general General information + +The methods described in section \ref mesh do not take into account information about + \c polygonal and \c polyhedral cells contained in a MESH object. +Indeed, in the MEDMEM library, the connectivity data +for these elements are stored separately . Therefore, +the methods that give access to this data are slightly different from +those of section \ref mesh. + +Also, the polygon and the polyhedra case differ in nature, +because in 3D, the list of nodes is not sufficient +to described the shape of an element. A descending +cell>face>nodes connectivity has to be established +to fully describe the elements. + +\section polygon_connectivity Polygon connectivity + +Let us consider the case illustrated in figure \ref fig_polygon_connectivity . + +\anchor fig_polygon_connectivity +\image html polygon_connectivity_small.png "Example for polygon connectivity" +\image latex polygon_connectivity_small.eps "Example for polygon connectivity" + + +- The standard element connectivity table writes : {2, 6, 7, 3, 3, 7, 8, 4 } +- The standard element connectivity index table writes : {1, 5, 9 } +- The polygon element connectivity table writes : {1, 2, 3, 4, 5 } +- The polygon element connectivity index table writes : {1, 6 } + +\section polyhedron_conn Polyhedron connectivity + +For polyhedra, in the nodal connectivity case, +one more array is required, because a +list of nodes does not suffice to describe a general polyhedron. +A general polyhedron is therefore described by a list of faces, +each of those being described by a list of nodes. + +Let us consider an example with the two tetrahedra represented on +figure \ref fig_polyhedron_connectivity , the left one +being stored as a \c MED_TETRA4 element, the right one being stored +as a \c MED_POLYHEDRA element. + +\anchor fig_polyhedron_connectivity +\image html polyhedron_connectivity_small.png "Example for polyhedron connectivity. Node numbers are written with a normal font, while face numbers are written in italic font." +\image latex polyhedron_connectivity_small.eps "Example for polyhedron connectivity. Node numbers are written with a normal font, while face numbers are written in italic font." + +- The standard element index connectivity table writes : {1, 5 } +- The standard element connectivity table writes : {1, 2, 3, 4 } +- The polyhedra face connectivity index table writes :{1, 5} +- The polyhedra connectivity index table writes : {1, 4, 7, 10, 13} +- The polyhedra connectivity (face/node connectivity) table writes : {2, 3, 5, 2, 4, 5, 4, 5, 3, 2, 3, 4} + +Note that as they are not needed as such, the face numberings are not stored +in any array. Only the number of nodes per face is implicitly stored +in the polyhedra face connectivity index table. + +If there are two \c MED_POLYHEDRA elements that share a common face, +the list of nodes is repeated twice in the polyhedron connectivity +array. + +\section poly_outline Outline +The methods associated to polygons/polyhedra are located in the following classes : +- access methods are stored in MESH : \ref MESH_poly +- creation methods are in MESHING : \ref MESHING_poly + +\section poly_example Example +The following example illustrates the creation method for a mesh that +contains polygons and/or polyhedra : +\include test_MEDMEM_MeshingPoly.cxx +*/ \ No newline at end of file diff --git a/doc/doxygen/remapping.dox b/doc/doxygen/remapping.dox new file mode 100755 index 000000000..6611b9f07 --- /dev/null +++ b/doc/doxygen/remapping.dox @@ -0,0 +1,111 @@ +/*! +\defgroup InterpKerGrpIntPlan Plannar Intersector + +Here are listed all the methods to be called or to overload to all +concrete intersector. + +\page InterpKerIntersectors Intersectors + +\section interpolation2D Special features of 2D intersectors + +\subsection InterpKerPlanarIntGenP0P0 P0->P0 : PlanarIntersector. + +All the 2D intersectors inherits from INTERP_KERNEL::PlanarIntersector class. + +All the important methods are \ref InterpKerGrpIntPlan "described here".\n To sum up the main task offered by this class is to give the +evaluation of interpolation of one cell in source mesh with an another +cell in target mesh. + +\subsection InterpKerPlanarIntFeatureP0P0 P0->P0 intersectors features. + +When remapping two dimensional fields, areas of intersection between polygonal cells are to be computed. Three algorithms are available: +- Triangle: decompose each cells into triangles and computes triangle-triangle intersection by determining segment crossings and node inclusions. This algorithm is the fastest if both meshes are made of triangular cells. +- Convex: presume that both meshes are made of convex cells, and performs a direct computation of the intersection nodes between two cells through a sweep line algorithm (see F. Preparata and M. Shamos, 1985 in \ref references). +For the moment, it is only possible to remap two dimensional fields on +meshes with mixed triangular and quadrangular elements. +- Geometric2D: Any type of 2D cells (linear, quadratic, convex-polygons, +non-convex polygons) is supported by this algorithm. Due to its +flexibility this algo is slower than the other. + +The following options are available for the 2D intersection computations: + * + * + * + * + * + *
OptionDescription Admitted valuesDefault
Intersection_typeSpecifies the algorithm to be + * used in the computation of the cell-cell intersections + * Triangle, Convex, \ref interpkernelGeo2D "Geometric2D" Triangle
Precision Accuracy of the computations is precision times the characteristic size of the meshes positive real numbers 1.0E-12
PrintLevel Level of verboseness during the computations 0, 1, 2, 3 0
+ +\section interpolation3Dsurf Special features of 3D surface intersectors + +When remapping a three dimensional surfaces, one should give a meaning to the area of intersection between two three-dimensional non coplanar polygons. A projection phase is thus necessary to have both polygons on the same plane. Care must be taken when defining this projection to avoid non conservative remappings. After the projection step, the source and target cells lie in the same plane and the same algorithms as for 2D remapping can be employed. +For the moment, it is only possible to remap fields on three dimension surfacic meshes with mixed triangular and quadrangular elements. +Similar options as for the 2D remapping are available, plus some additional options specific to 3D surface remapping: + + * + * + * + * + * + * + *
OptionDescription Admitted valuesDefault
MedianPlane Position of the median plane where both cells will be projected real numbers between 0 and 1 0.5
Precision Accuracy of the computations is + * precision times the characteristic size of the meshes + * positive real numbers 1.E-12
DoRotate Performs a rotation of the coordinate + system such that the median plane is the Oxy plane + boolean true or false true
BoundingBoxAdjustmentWhen detecting an intersection between bounding boxes, the bounding are expanded by a factor (1+BoundingBoxAdjustment). It is particularly useful when detecting intersections for 3D surfaces for which the bounding boxes might not actually intersect. real numbers 0.1
+ +Note that choosing the Triangle Intersection_type necessarily set the DoRotate option to true. + +\section interpolation3D Special features of 3D volumes intersectors + +\subsection InterpKer3DIntGenP0P0 P0->P0 : TargetIntersector + +Unlike \ref InterpKerPlanarIntGenP0P0 "PlanarIntersector phylosophy" +this intersector is slightly different. Here for the moment +there is one instance per pair of meshes \b and target element. See INTERP_KERNEL::TargetIntersector for +more details. + +\subsection InterpKer3DIntFeatureP0P0 P0->P0 intersectors features. + +When remapping three dimensional fields, volumes of intersection between polyhedral cells are to be computed. We use the method of Jeffrey Grandy, 1999 (see \ref references) to intersect arbitrary polyhedra. The basic algorithm computes the intersection of a tetrahedron with an arbitrary (possibly non convex) polyhedron. Using splitting techniques, it is possible to transform the problem of computing the intersection between two general polyhedra into several tetrahedron-polyhedron intersection calculations. For the moment it is only possible to remap fields on meshes having mixed tetrahedral and hexahedral cells. When using a mesh with hexahedral cells, several splitting techniques may be employed depending mainly on wether the faces are planar or not. The following options are available for the splitting: + + * + * + * + * + *
OptionDescription Admitted valuesDefault
SplittingPolicy Way in which the hexahedra are split into tetrahedra PLANAR_FACE_5, PLANAR_FACE_6, GENERAL_24, GENERAL_48 GENERAL_48
PrintLevel Level of verboseness during the computations 1, 2, 3, 4, 5 0
+ +Note that a SplittingPolicy values starting with the word "PLANAR" presume that each face is to be considered planar, while the SplittingPolicy values starting with the word GENERAL does not. The integer at the end gives the number of tetrahedra that result from the split. + Consider an hexahedron with with planar faces and nodes numbered according to the following picture: +\verbatim + + 7 ------ 6 + /| /| + / | / | + 3 ------ 2 | + | | | | + | | | | + | 4-----|- 5 + | / | / + 0 ------ 1 +\endverbatim +The use of the SPLIT_NODES_5 splitting policy would lead to a 5 tetrahedra decomposition as follows : +\verbatim + 0, 1, 5, 2 + 0, 4, 5, 7 + 0, 3, 7, 2 + 5, 6, 7, 2 + 0, 2, 5, 7 +\endverbatim +The use of the SPLIT_NODES_6 splitting policy would lead to a 6 tetrahedra decomposition as follows : +\verbatim + 0, 1, 5, 6 + 0, 2, 1, 6 + 0, 5, 4, 6 + 0, 4, 7, 6 + 0, 3, 2, 6 + 0, 7, 3, 6 +\endverbatim + +*/ diff --git a/doc/doxygen/support.dox b/doc/doxygen/support.dox new file mode 100644 index 000000000..f0a495578 --- /dev/null +++ b/doc/doxygen/support.dox @@ -0,0 +1,44 @@ +/*! +\page support SUPPORT + +\section support_general General information + +The SUPPORT class is the class representing subregions + of the mesh in the MEDMEM library. A SUPPORT object groups together +a set of elements that have similar entity types. + +\section support_outline Outline + +The reference for the SUPPORT methods are given by the following links : +- constructors : \ref SUPPORT_constructors, +- creation methods : \ref SUPPORT_creation, +- query methods : \ref SUPPORT_query, +- advanced methods : \ref SUPPORT_advanced. + +\section family FAMILY objects + +The FAMILY concept is directly linked to the representation of +supports in the MED file. It is only useful for directly +manipulating the arrays that are written/read by the MED drivers. +More information can be found on this topic in +\ref RefManualMedFile "MED reference guide". + +A FAMILY is a SUPPORT with some additional methods that concern some optional attributes (we could have none) and groups (we could also have none) : + +- \a getIdentifier returns the family identifier (an integer), +- \a getNumberOfAttributes returns the number of attributes of this family, +- \a getAttributesIdentifiers and \a getAttributeIdentifier returns an integer array or an integer that represents attribute identifier, +- \a getAttributesValues and \a getAttributeValue returns an integer array or an integer that represents attribute value. +- \a getAttributesDescriptions and \a getAttributeDescription returns a string array or a string that represents attribute description, +- \a getNumberOfGroups returns the number of groups which it belongs to, +- \a getGroupsNames and \a getGroupName return a string array or a string that represents the group name which it belongs to. + + +\section group_section GROUP objects + +A GROUP is a SUPPORT with some additional methods to find FAMILY that makes it up : + +- \a getNumberOfFamilies returns the number of FAMILY that makes up the GROUP ; +- \a getFamilies and \a getFamily return a FAMILY array or a FAMILY that makes up the GROUP. + +*/ diff --git a/doc/doxygen/tools.dox b/doc/doxygen/tools.dox new file mode 100644 index 000000000..5da0c7060 --- /dev/null +++ b/doc/doxygen/tools.dox @@ -0,0 +1,66 @@ +/*! +\page tools MEDMEM tools + +\section Introduction +On top of the MEDMEM library, MEDMEM comes with a few executables that +are based on the MEDMEM library and that help the user to perform +common operations on MED files : +- conversion to other formats, +- splitting of a %MED file to a parallel %MED file distributed over a +number of subdomains. + +\section medsplitter MEDSPLITTERtool + +The purpose of MEDSPLITTER is to split MED files into +a series of other MED files forming a partition of the original MED files. It can either work with serial meshes (1 to n) or distributed meshes (p to n). For serial meshes, it accepts MED files from the 2.1 version onwards. For distributed MED files, it accepts MED files from the 2.3 version onwards. + +It can be used either as an executable, \a medsplitter or as a library. The partitioning is made thanks to one of the following library : +- METIS (http://glaros.dtc.umn.edu/gkhome/views/metis/index.html) +- SCOTCH (http://www.labri.fr/perso/pelegrin/scotch/scotch_fr.html) + +The arguments to the medsplitter tool can be retrieved by calling : +\code +medsplitter --help +\endcode + +For Salome V4.1.0, one gets the following arguments : + +\code +Available options: + --help : produces this help message + --mesh-only : do not create the fields contained in the original file(s) + --distributed : specifies that the input file is distributed + --input-file= : name of the input MED file + --output-file= : name of the resulting file + --meshname= : name of the input mesh (not used with --distributed option) + --ndomains= : number of subdomains in the output file, default is 1 + --plain-master : creates a plain masterfile instead of an XML file + --creates-boundary-faces: creates the necessary faces so that faces joints are created in the output files + --family-splitting : preserves the family names instead of focusing on the groups +\endcode + +\section sauv2med sauv2med tool + +The sauv2med tool enable conversion from a Cast3m \a sauv file into a +MED file. It is a python script that encapsulates the read/write +drivers provided by the MEDMEM library. + +Calling +\code +sauv2med myfile.med +\endcode +generates a \a sauv file named \a myfile.med.sauv + + +\section med2sauv med2sauv tool + +med2sauv operator is the operator that is inverse of sauv2med. Its +behaviour is symmetrical. + +Calling +\code +med2sauv myfile.sauv +\endcode +generates a \a med file named \a myfile.sauv.med + +*/ \ No newline at end of file diff --git a/doc/html/INPUT/HTML/MED.html b/doc/html/INPUT/HTML/MED.html deleted file mode 100644 index b8f484ade..000000000 --- a/doc/html/INPUT/HTML/MED.html +++ /dev/null @@ -1,422 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
interface MESH
IDL file
Python
string getName ( )
return_value = getName ( )
long getSpaceDimension ( )
return_value = getSpaceDimension ( )
long getMeshDimension ( )
return_value = getMeshDimension ( )
string getCoordinateSystem ( )
return_value = getCoordinateSystem ( )
long getNumberOfNodes ( )
return_value = getNumberOfNodes ( )
double_array getCoordinates ( in medModeSwitch typeSwitch )
return_value = getCoordinates ( typeSwitch )
string_array getCoordinatesNames ( )
return_value = getCoordinatesNames ( )
string_array getCoordinatesUnits ( )
return_value = getCoordinatesUnits ( )
long getNumberOfTypes ( in medEntityMesh entity )
return_value = getNumberOfTypes ( entity )
medGeometryElement_array getTypes ( in medEntityMesh entity )
return_value = getTypes ( entity )
long getNumberOfElements ( in medEntityMesh entity, in medGeometryElement geomElement )
return_value = getNumberOfElements ( entity, geomElement )
long_array getConnectivity ( in medModeSwitch typeSwitch, in medConnectivity mode, in medEntityMesh entity, in medGeometryElement geomElement )
return_value = getConnectivity ( typeSwitch, mode, entity, geomElement )
long_array getConnectivityIndex ( in medConnectivity mode, in medEntityMesh entity )
return_value = getConnectivityIndex ( mode, entity )
long getElementNumber ( in medConnectivity mode, in medEntityMesh entity, in medGeometryElement type, in long_array connectivity )
return_value = getElementNumber ( mode, entity, type, connectivity )
long_array getReverseConnectivity ( in medConnectivity mode )
return_value = getReverseConnectivity ( mode )
long_array getReverseConnectivityIndex ( in medConnectivity mode )
return_value = getReverseConnectivityIndex ( mode )
long getNumberOfFamilies ( in medEntityMesh entity )
return_value = getNumberOfFamilies ( entity )
long getNumberOfGroups ( in medEntityMesh entity )
return_value = getNumberOfGroups ( entity )
Family_array getFamilies ( in medEntityMesh entity )
return_value = getFamilies ( entity )
FAMILY getFamily ( in medEntityMesh entity, in long familyNumber )
return_value = getFamily ( entity, familyNumber )
Group_array getGroups ( in medEntityMesh entity )
return_value = getGroups ( entity )
GROUP getGroup ( in medEntityMesh entity, in long groupNumber )
return_value = getGroup ( entity, groupNumber )
FIELD getVolume ( in SUPPORT mySupport )
return_value = getVolume ( mySupport )
FIELD getArea ( in SUPPORT mySupport )
return_value = getArea ( mySupport )
FIELD getLength ( in SUPPORT mySupport )
return_value = getLength ( mySupport )
FIELD getNormal ( in SUPPORT mySupport )
return_value = getNormal ( mySupport )
FIELD getBarycenter ( in SUPPORT mySupport )
return_value = getBarycenter ( mySupport )
void addInStudy ( in Study myStudy, in MESH myIor )
addInStudy ( myStudy, myIor )
long addDriver ( in medDriverTypes driverType, in string fileName, in string meshName )
return_value = addDriver ( driverType, fileName, meshName )
void rmDriver ( in long i )
rmDriver ( i )
void read ( in long i )
read ( i )
void write ( in long i, in string driverMeshName )
write ( i, driverMeshName )
long getCorbaIndex ( )
return_value = getCorbaIndex ( )

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
interface SUPPORT
IDL file
Python
string getName ( )
return_value = getName ( )
string getDescription ( )
return_value = getDescription ( )
MESH getMesh ( )
return_value = getMesh ( )
medEntityMesh getEntity ( )
return_value = getEntity ( )
boolean isOnAllElements ( )
return_value = isOnAllElements ( )
long getNumberOfElements ( in medGeometryElement geomElement )
return_value = getNumberOfElements ( geomElement )
medGeometryElement_array getTypes ( )
return_value = getTypes ( )
long_array getNumber ( in medGeometryElement geomElement )
return_value = getNumber ( geomElement )
long_array getNumberIndex ( )
return_value = getNumberIndex ( )
long getNumberOfGaussPoints ( in medGeometryElement geomElement )
return_value = getNumberOfGaussPoints ( geomElement )
long getCorbaIndex ( )
return_value = getCorbaIndex ( )

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
interface FAMILY
IDL file
Python
long getIdentifier ( )
return_value = getIdentifier ( )
long getNumberOfAttributes ( )
return_value = getNumberOfAttributes ( )
long_array getAttributesIdentifiers ( )
return_value = getAttributesIdentifiers ( )
long getAttributeIdentifier ( in long i )
return_value = getAttributeIdentifier ( i )
long_array getAttributesValues ( )
return_value = getAttributesValues ( )
long getAttributeValue ( in long i )
return_value = getAttributeValue ( i )
string_array getAttributesDescriptions ( )
return_value = getAttributesDescriptions ( )
string getAttributeDescription ( in long i )
return_value = getAttributeDescription ( i )

- - - - - - - - - - - - - - - - - - - -
interface GROUP
IDL file
Python
long getNumberOfFamilies ( )
return_value = getNumberOfFamilies ( )
Family_array getFamilies ( )
return_value = getFamilies ( )
FAMILY getFamily ( in long i )
return_value = getFamily ( i )

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
interface FIELD
IDL file
Python
string getName ( )
return_value = getName ( )
string getDescription ( )
return_value = getDescription ( )
SUPPORT getSupport ( )
return_value = getSupport ( )
long getNumberOfComponents ( )
return_value = getNumberOfComponents ( )
string_array getComponentsNames ( )
return_value = getComponentsNames ( )
string getComponentName ( in long i )
return_value = getComponentName ( i )
string_array getComponentsUnits ( )
return_value = getComponentsUnits ( )
string getComponentUnit ( in long i )
return_value = getComponentUnit ( i )
long getIterationNumber ( )
return_value = getIterationNumber ( )
double getTime ( )
return_value = getTime ( )
long getOrderNumber ( )
return_value = getOrderNumber ( )
long addDriver ( in medDriverTypes driverType, in string fileName, in string fieldName )
return_value = addDriver ( driverType, fileName, fieldName )
void rmDriver ( in long i )
rmDriver ( i )
void read ( in long i )
read ( i )
void write ( in long i, in string driverFieldName )
write ( i, driverFieldName )
void addInStudy ( in Study myStudy, in FIELD myIor )
addInStudy ( myStudy, myIor )
long getCorbaIndex ( )
return_value = getCorbaIndex ( )

- - - - - - - - - - - -
interface FIELDDOUBLE
IDL file
Python
double_array getValue ( in medModeSwitch mode )
return_value = getValue ( mode )

- - - - - - - - - - - -
interface FIELDINT
IDL file
Python
long_array getValue ( in medModeSwitch mode )
return_value = getValue ( mode )

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
interface MED
IDL file
Python
long getNumberOfMeshes ( )
return_value = getNumberOfMeshes ( )
long getNumberOfFields ( )
return_value = getNumberOfFields ( )
string_array getMeshNames ( )
return_value = getMeshNames ( )
string_array getFieldNames ( )
return_value = getFieldNames ( )
MESH getMeshByName ( in string meshName )
return_value = getMeshByName ( meshName )
MESH getMesh ( in FIELD fieldPtr )
return_value = getMesh ( fieldPtr )
FIELD getField ( in string fieldName, in long pasTemps, in long numOrdre )
return_value = getField ( fieldName, pasTemps, numOrdre )
long addDriver ( in medDriverTypes driverType, in string fileName )
return_value = addDriver ( driverType, fileName )
void rmDriver ( in long i )
rmDriver ( i )
void readFileStruct ( in long i )
readFileStruct ( i )
void writeFrom ( in long i )
writeFrom ( i )
void write ( in long i )
write ( i )
void addMesh ( in MESH ptrMesh )
addMesh ( ptrMesh )
void addField ( in FIELD ptrField )
addField ( ptrField )
void addInStudy ( in Study myStudy, in MED medPtr )
addInStudy ( myStudy, medPtr )

-
diff --git a/doc/html/INPUT/HTML/MED_Gen.html b/doc/html/INPUT/HTML/MED_Gen.html deleted file mode 100644 index 44b43940b..000000000 --- a/doc/html/INPUT/HTML/MED_Gen.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
interface MED_Gen
IDL file
Python
MESH readMeshInFile ( in string fileName, in string studyName, in string meshName )
return_value = readMeshInFile ( fileName, studyName, meshName )
FIELD readFieldInFile ( in string fileName, in string studyName, in string fieldName, in long ordre, in long iter )
return_value = readFieldInFile ( fileName, studyName, fieldName, ordre, iter )
MED readStructFile ( in string fileName, in string studyName )
return_value = readStructFile ( fileName, studyName )
void readStructFileWithFieldType ( in string fileName, in string studyName )
readStructFileWithFieldType ( fileName, studyName )

-
diff --git a/doc/html/INPUT/doxyfile.in b/doc/html/INPUT/doxyfile.in deleted file mode 100755 index 023290eed..000000000 --- a/doc/html/INPUT/doxyfile.in +++ /dev/null @@ -1,201 +0,0 @@ -# Doxyfile 1.3-rc1 - -#--------------------------------------------------------------------------- -# General configuration options -#--------------------------------------------------------------------------- -PROJECT_NAME = "SALOME - MED - v.@VERSION@" -PROJECT_NUMBER = id#1.1 -OUTPUT_DIRECTORY = ../ -OUTPUT_LANGUAGE = English -EXTRACT_ALL = YES -EXTRACT_PRIVATE = YES -EXTRACT_STATIC = YES -EXTRACT_LOCAL_CLASSES = YES -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = NO -ALWAYS_DETAILED_SEC = YES -INLINE_INHERITED_MEMB = YES -FULL_PATH_NAMES = NO -STRIP_FROM_PATH = -INTERNAL_DOCS = YES -CASE_SENSE_NAMES = YES -SHORT_NAMES = NO -HIDE_SCOPE_NAMES = NO -VERBATIM_HEADERS = YES -SHOW_INCLUDE_FILES = YES -JAVADOC_AUTOBRIEF = YES -MULTILINE_CPP_IS_BRIEF = NO -DETAILS_AT_TOP = NO -INHERIT_DOCS = YES -INLINE_INFO = YES -SORT_MEMBER_DOCS = NO -DISTRIBUTE_GROUP_DOC = NO -TAB_SIZE = 5 -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -ALIASES = -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 25 -OPTIMIZE_OUTPUT_FOR_C = YES -OPTIMIZE_OUTPUT_JAVA = YES -SHOW_USED_FILES = NO -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = log.txt -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = ../../../share/salome/idl/MED.idl \ - ../../../share/salome/idl/MED_Gen.idl -FILE_PATTERNS = -RECURSIVE = NO -EXCLUDE = -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXAMPLE_PATH = -EXAMPLE_PATTERNS = -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = sources/ -INPUT_FILTER = -FILTER_SOURCE_FILES = YES -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = NO -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = NO -REFERENCES_RELATION = YES -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = NO -COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = html -HTML_FILE_EXTENSION = .html -HTML_HEADER = sources/myheader.html -HTML_FOOTER = -HTML_STYLESHEET = -HTML_ALIGN_MEMBERS = YES -GENERATE_HTMLHELP = NO -CHM_FILE = -HHC_LOCATION = -GENERATE_CHI = NO -BINARY_TOC = YES -TOC_EXPAND = YES -DISABLE_INDEX = YES -ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = YES -TREEVIEW_WIDTH = 250 -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- -GENERATE_LATEX = NO -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex -COMPACT_LATEX = NO -PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = NO -USE_PDFLATEX = NO -LATEX_BATCHMODE = NO -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = NO -XML_SCHEMA = -XML_DTD = -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- -GENERATE_PERLMOD = NO -PERLMOD_LATEX = NO -PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = YES -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = NO -#--------------------------------------------------------------------------- -# Configuration::addtions related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- -CLASS_DIAGRAMS = YES -HIDE_UNDOC_RELATIONS = NO -HAVE_DOT = YES -CLASS_GRAPH = YES -COLLABORATION_GRAPH = NO -TEMPLATE_RELATIONS = YES -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = NO -GRAPHICAL_HIERARCHY = YES -DOT_IMAGE_FORMAT = jpg -DOT_PATH = -DOTFILE_DIRS = -MAX_DOT_GRAPH_WIDTH = 1024 -MAX_DOT_GRAPH_HEIGHT = 1200 -GENERATE_LEGEND = NO -DOT_CLEANUP = YES -#--------------------------------------------------------------------------- -# Configuration::addtions related to the search engine -#--------------------------------------------------------------------------- -SEARCHENGINE = NO -CGI_NAME = search.cgi -CGI_URL = -DOC_URL = -DOC_ABSPATH = -BIN_ABSPATH = /usr/local/bin/ -EXT_DOC_PATHS = diff --git a/doc/html/INPUT/sources/Application-About.png b/doc/html/INPUT/sources/Application-About.png deleted file mode 100755 index 7b58330d5..000000000 Binary files a/doc/html/INPUT/sources/Application-About.png and /dev/null differ diff --git a/doc/html/INPUT/sources/Application-About1.jpg b/doc/html/INPUT/sources/Application-About1.jpg deleted file mode 100755 index cf7ab8ba0..000000000 Binary files a/doc/html/INPUT/sources/Application-About1.jpg and /dev/null differ diff --git a/doc/html/INPUT/sources/application.gif b/doc/html/INPUT/sources/application.gif deleted file mode 100644 index 0b05d5c18..000000000 Binary files a/doc/html/INPUT/sources/application.gif and /dev/null differ diff --git a/doc/html/INPUT/sources/application.jpg b/doc/html/INPUT/sources/application.jpg deleted file mode 100755 index a6979ab99..000000000 Binary files a/doc/html/INPUT/sources/application.jpg and /dev/null differ diff --git a/doc/html/INPUT/sources/bg_salome.gif b/doc/html/INPUT/sources/bg_salome.gif deleted file mode 100755 index 677b70468..000000000 Binary files a/doc/html/INPUT/sources/bg_salome.gif and /dev/null differ diff --git a/doc/html/INPUT/sources/bg_salomepro.gif b/doc/html/INPUT/sources/bg_salomepro.gif deleted file mode 100755 index 677b70468..000000000 Binary files a/doc/html/INPUT/sources/bg_salomepro.gif and /dev/null differ diff --git a/doc/html/INPUT/sources/doxygen.css b/doc/html/INPUT/sources/doxygen.css deleted file mode 100755 index acda4606c..000000000 --- a/doc/html/INPUT/sources/doxygen.css +++ /dev/null @@ -1,50 +0,0 @@ -H1 { text-align: center; } -CAPTION { font-weight: bold } -A.qindex {} -A.qindexRef {} -A.el { text-decoration: none; font-weight: bold } -A.elRef { font-weight: bold } -A.code { text-decoration: none; font-weight: normal; color: #4444ee } -A.codeRef { font-weight: normal; color: #4444ee } -A:hover { text-decoration: none; background-color: lightblue } -DL.el { margin-left: -1cm } -DIV.fragment { width: 100%; border: none; background-color: #CCCCCC } -DIV.ah { background-color: #CCCCCC; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } -TD.md { background-color: lightblue; font-weight: bold; } -TD.mdname1 { background-color: lightblue; font-weight: bold; color: #602020; } -TD.mdname { background-color: lightblue; font-weight: bold; color: #602020; width: 600px; } -DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold } -DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller } -BODY { background: #FFFFFF; } -/* BODY { background: url(sources/bg_salomepro.gif) } */ -TD.indexkey { - background-color: #CCCCCC; - font-weight: bold; - padding-right : 10px; - padding-top : 2px; - padding-left : 10px; - padding-bottom : 2px; - margin-left : 0px; - margin-right : 0px; - margin-top : 2px; - margin-bottom : 2px -} -TD.indexvalue { - background-color: #CCCCCC; - font-style: italic; - padding-right : 10px; - padding-top : 2px; - padding-left : 10px; - padding-bottom : 2px; - margin-left : 0px; - margin-right : 0px; - margin-top : 2px; - margin-bottom : 2px -} -span.keyword { color: #008000 } -span.keywordtype { color: #604020 } -span.keywordflow { color: #e08000 } -span.comment { color: #800000 } -span.preprocessor { color: #806020 } -span.stringliteral { color: #002080 } -span.charliteral { color: #008080 } diff --git a/doc/html/INPUT/sources/logocorp.gif b/doc/html/INPUT/sources/logocorp.gif deleted file mode 100755 index 7697e0837..000000000 Binary files a/doc/html/INPUT/sources/logocorp.gif and /dev/null differ diff --git a/doc/html/INPUT/sources/myheader.html b/doc/html/INPUT/sources/myheader.html deleted file mode 100755 index 83ca543cd..000000000 --- a/doc/html/INPUT/sources/myheader.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Main Page - - - -  -
- - - - - - -
-
-
- - - - diff --git a/doc/html/INPUT/sources/occ.gif b/doc/html/INPUT/sources/occ.gif deleted file mode 100755 index ce017c8ae..000000000 Binary files a/doc/html/INPUT/sources/occ.gif and /dev/null differ diff --git a/doc/html/INPUT/sources/static/doxygen.css b/doc/html/INPUT/sources/static/doxygen.css deleted file mode 100755 index 056702051..000000000 --- a/doc/html/INPUT/sources/static/doxygen.css +++ /dev/null @@ -1,50 +0,0 @@ -H1 { text-align: center; } -CAPTION { font-weight: bold } -A.qindex {} -A.qindexRef {} -A.el { text-decoration: none; font-weight: bold } -A.elRef { font-weight: bold } -A.code { text-decoration: none; font-weight: normal; color: #4444ee } -A.codeRef { font-weight: normal; color: #4444ee } -A:hover { text-decoration: none; background-color: lightblue } -DL.el { margin-left: -1cm } -DIV.fragment { width: 100%; border: none; background-color: #CCCCCC } -DIV.ah { background-color: #CCCCCC; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } -TD.md { background-color: lightblue; font-weight: bold; } -TD.mdname1 { background-color: lightblue; font-weight: bold; color: #602020; } -TD.mdname { background-color: lightblue; font-weight: bold; color: #602020; width: 600px; } -DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold } -DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller } -BODY { background: #FFFFFF; } -/* BODY { background: url(sources/bg_salome.gif) } */ -TD.indexkey { - background-color: #CCCCCC; - font-weight: bold; - padding-right : 10px; - padding-top : 2px; - padding-left : 10px; - padding-bottom : 2px; - margin-left : 0px; - margin-right : 0px; - margin-top : 2px; - margin-bottom : 2px -} -TD.indexvalue { - background-color: #CCCCCC; - font-style: italic; - padding-right : 10px; - padding-top : 2px; - padding-left : 10px; - padding-bottom : 2px; - margin-left : 0px; - margin-right : 0px; - margin-top : 2px; - margin-bottom : 2px -} -span.keyword { color: #008000 } -span.keywordtype { color: #604020 } -span.keywordflow { color: #e08000 } -span.comment { color: #800000 } -span.preprocessor { color: #806020 } -span.stringliteral { color: #002080 } -span.charliteral { color: #008080 } diff --git a/doc/html/INPUT/sources/static/page2.html b/doc/html/INPUT/sources/static/page2.html deleted file mode 100755 index 1891fe92c..000000000 --- a/doc/html/INPUT/sources/static/page2.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - Main Page - - - - -   -
- - - - - - - - -
- - -
-
- - -
- - diff --git a/doc/html/INPUT/sources/static/tree.js b/doc/html/INPUT/sources/static/tree.js deleted file mode 100755 index 7cdc19393..000000000 --- a/doc/html/INPUT/sources/static/tree.js +++ /dev/null @@ -1,23 +0,0 @@ -foldersTree = gFld("SALOME v.2.0.0 ", "", "") - insDoc(foldersTree, gLnk("Main Page", "", "main.html")) - -aux1 = insFld(foldersTree, gFld("TUI Reference Guide", "")) - aux2 = insFld(aux1, gFld("Modules", "")) - aux3 = insFld(aux2, gFld("SALOME MED module", "")) -/*! insDoc(aux3, gLnk("Overview", "", "overview_Med.html"))*/ - aux4 = insFld(aux3, gFld("Packages", "")) - insDoc(aux4, gLnk("SALOME_MED", "", "namespaceSALOME__MED.html")) -/*! insDoc(aux3, gLnk("Examples", "", "examples_MED.html")) -*/ - - insDoc(aux1, gLnk("Data Structures", "", "annotated.html")) - insDoc(aux1, gLnk("Class Hierarchy", "", "hierarchy.html")) - insDoc(aux1, gLnk("Class methods list", "", "functions.html")) - insDoc(aux1, gLnk("Namespace Members", "", "namespacemembers.html")) - insDoc(aux1, gLnk("File List", "", "files.html")) - -aux1 = insFld(foldersTree, gFld("IDL/Python mapping", "")) - insDoc(aux1, gLnk("Mapping of MED IDL definitions to Python language", "", "page2.html")) -aux1 = insFld(foldersTree, gFld("Med Memory Documentations", "")) - insDoc(aux1, gLnk("Users documentation", "", "../html_ref_user/index.html")) - insDoc(aux1, gLnk("Developpers documentation", "", "../html_ref_devel/index.html")) diff --git a/doc/html/INPUT/sources/static/treeview.js b/doc/html/INPUT/sources/static/treeview.js deleted file mode 100644 index 55eb43d07..000000000 --- a/doc/html/INPUT/sources/static/treeview.js +++ /dev/null @@ -1,505 +0,0 @@ -//**************************************************************** -// You are free to copy the "Folder-Tree" script as long as you -// keep this copyright notice: -// Script found in: http://www.geocities.com/Paris/LeftBank/2178/ -// Author: Marcelino Alves Martins (martins@hks.com) December '97. -//**************************************************************** - -//Log of changes: -// 17 Feb 98 - Fix initialization flashing problem with Netscape -// -// 27 Jan 98 - Root folder starts open; support for USETEXTLINKS; -// make the ftien4 a js file -// -// DvH: Dec 2000 - Made some minor changes to support external -// references - -// Definition of class Folder -// ***************************************************************** - -function Folder(folderDescription, tagName, hreference) //constructor -{ - //constant data - this.desc = folderDescription - this.tagName = tagName - this.hreference = hreference - this.id = -1 - this.navObj = 0 - this.iconImg = 0 - this.nodeImg = 0 - this.isLastNode = 0 - - //dynamic data - this.isOpen = true - this.iconSrc = "ftv2folderopen.png" - this.children = new Array - this.nChildren = 0 - - //methods - this.initialize = initializeFolder - this.setState = setStateFolder - this.addChild = addChild - this.createIndex = createEntryIndex - this.hide = hideFolder - this.display = display - this.renderOb = drawFolder - this.totalHeight = totalHeight - this.subEntries = folderSubEntries - this.outputLink = outputFolderLink -} - -function setStateFolder(isOpen) -{ - var subEntries - var totalHeight - var fIt = 0 - var i=0 - - if (isOpen == this.isOpen) - return - - if (browserVersion == 2) - { - totalHeight = 0 - for (i=0; i < this.nChildren; i++) - totalHeight = totalHeight + this.children[i].navObj.clip.height - subEntries = this.subEntries() - if (this.isOpen) - totalHeight = 0 - totalHeight - for (fIt = this.id + subEntries + 1; fIt < nEntries; fIt++) - indexOfEntries[fIt].navObj.moveBy(0, totalHeight) - } - this.isOpen = isOpen - propagateChangesInState(this) -} - -function propagateChangesInState(folder) -{ - var i=0 - - if (folder.isOpen) - { - if (folder.nodeImg) - if (folder.isLastNode) - folder.nodeImg.src = "ftv2mlastnode.png" - else - folder.nodeImg.src = "ftv2mnode.png" - folder.iconImg.src = "ftv2folderopen.png" - for (i=0; i 0) - auxEv = "" - else - auxEv = "" - - if (level>0) - if (lastNode) //the last 'brother' in the children array - { - this.renderOb(leftSide + auxEv + "") -// leftSide = leftSide + "" - this.isLastNode = 1 - } - else - { - this.renderOb(leftSide + auxEv + "") - leftSide = leftSide + "" - this.isLastNode = 0 - } - else - this.renderOb("") - - if (nc > 0) - { - level = level + 1 - for (i=0 ; i < this.nChildren; i++) - { - if (i == this.nChildren-1) - this.children[i].initialize(level, 1, leftSide) - else - this.children[i].initialize(level, 0, leftSide) - } - } -} - -function drawFolder(leftSide) -{ - if (browserVersion == 2) { - if (!doc.yPos) - doc.yPos=8 - doc.write("") - } - if (browserVersion == 3) - { - doc.write("
") - } - - doc.write("\n") - doc.write("\n\n") - doc.write("\n
") - doc.write(leftSide) - this.outputLink() - doc.write("") - doc.write("") - if (USETEXTLINKS) - { - this.outputLink() - doc.write(this.desc + "") - } - else - doc.write(this.desc) - -/*! - if (this.tagName!="") - { - doc.write(" [external]") - } -*/ - doc.write("
\n") - - if (browserVersion == 2) { - doc.write("") - } - if (browserVersion == 3) { - doc.write("
") - } - - if (browserVersion == 1) { - this.navObj = doc.all["folder"+this.id] - this.iconImg = doc.all["folderIcon"+this.id] - this.nodeImg = doc.all["nodeIcon"+this.id] - } else if (browserVersion == 2) { - this.navObj = doc.layers["folder"+this.id] - this.iconImg = this.navObj.document.images["folderIcon"+this.id] - this.nodeImg = this.navObj.document.images["nodeIcon"+this.id] - doc.yPos=doc.yPos+this.navObj.clip.height - } else if (browserVersion == 3) { - this.navObj = doc.getElementById("folder"+this.id) - this.iconImg = doc.images.namedItem("folderIcon"+this.id) - this.nodeImg = doc.images.namedItem("nodeIcon"+this.id) - } -} - -function outputFolderLink() -{ - if (this.hreference) - { - doc.write(" 0) - doc.write("onClick='javascript:clickOnFolder("+this.id+")'") - doc.write(">") - } - else - doc.write("") -} - -function addChild(childNode) -{ - this.children[this.nChildren] = childNode - this.nChildren++ - return childNode -} - -function folderSubEntries() -{ - var i = 0 - var se = this.nChildren - - for (i=0; i < this.nChildren; i++){ - if (this.children[i].children) //is a folder - se = se + this.children[i].subEntries() - } - - return se -} - - -// Definition of class Item (a document or link inside a Folder) -// ************************************************************* - -function Item(itemDescription, tagName, itemLink) // Constructor -{ - // constant data - this.desc = itemDescription - this.tagName = tagName - this.link = itemLink - this.id = -1 //initialized in initalize() - this.navObj = 0 //initialized in render() - this.iconImg = 0 //initialized in render() - this.iconSrc = "ftv2doc.png" - - // methods - this.initialize = initializeItem - this.createIndex = createEntryIndex - this.hide = hideItem - this.display = display - this.renderOb = drawItem - this.totalHeight = totalHeight -} - -function hideItem() -{ - if (browserVersion == 1 || browserVersion == 3) { - if (this.navObj.style.display == "none") - return - this.navObj.style.display = "none" - } else { - if (this.navObj.visibility == "hidden") - return - this.navObj.visibility = "hidden" - } -} - -function initializeItem(level, lastNode, leftSide) -{ - this.createIndex() - - if (level>0) - if (lastNode) //the last 'brother' in the children array - { - this.renderOb(leftSide + "") - leftSide = leftSide + "" - } - else - { - this.renderOb(leftSide + "") - leftSide = leftSide + "" - } - else - this.renderOb("") -} - -function drawItem(leftSide) -{ - if (browserVersion == 2) - doc.write("") - if (browserVersion == 3) - doc.write("
") - - doc.write("\n\n") - doc.write("\n
") - doc.write(leftSide) - if (this.link!="") - { - doc.write("") - } - doc.write("") - if (this.link!="") - { - doc.write("") - } - doc.write("") - if (USETEXTLINKS && this.link!="") - doc.write("" + this.desc + "") - else - doc.write(this.desc) -/*! - if (this.tagName!="") - { - doc.write(" [external]"); - } -*/ - doc.write("\n
\n") - - if (browserVersion == 2) - doc.write("") - if (browserVersion == 3) - doc.write("
") - - if (browserVersion == 1) { - this.navObj = doc.all["item"+this.id] - this.iconImg = doc.all["itemIcon"+this.id] - } else if (browserVersion == 2) { - this.navObj = doc.layers["item"+this.id] - this.iconImg = this.navObj.document.images["itemIcon"+this.id] - doc.yPos=doc.yPos+this.navObj.clip.height - } else if (browserVersion == 3) { - this.navObj = doc.getElementById("item"+this.id) - this.iconImg = doc.images.namedItem("itemIcon"+this.id) - } -} - - -// Methods common to both objects (pseudo-inheritance) -// ******************************************************** - -function display() -{ - if (browserVersion == 1 || browserVersion == 3) - this.navObj.style.display = "block" - else - this.navObj.visibility = "show" -} - -function createEntryIndex() -{ - this.id = nEntries - indexOfEntries[nEntries] = this - nEntries++ -} - -// total height of subEntries open -function totalHeight() //used with browserVersion == 2 -{ - var h = this.navObj.clip.height - var i = 0 - - if (this.isOpen) //is a folder and _is_ open - for (i=0 ; i < this.nChildren; i++) - h = h + this.children[i].totalHeight() - - return h -} - - -// Events -// ********************************************************* - -function clickOnFolder(folderId) -{ - var clicked = indexOfEntries[folderId] - - if (!clicked.isOpen) - clickOnNode(folderId) - - return - - if (clicked.isSelected) - return -} - -function clickOnNode(folderId) -{ - var clickedFolder = 0 - var state = 0 - - clickedFolder = indexOfEntries[folderId] - state = clickedFolder.isOpen - - clickedFolder.setState(!state) //open<->close -} - -function initializeDocument() -{ - doc = document; - if (doc.all) - browserVersion = 1 //IE4 - else - if (doc.layers) - browserVersion = 2 //NS4 - else if(navigator.userAgent.toLowerCase().indexOf('gecko') != -1) - browserVersion = 3 //mozilla - else - browserVersion = 0 //other - - foldersTree.initialize(0, 1, "") - foldersTree.display() - - if (browserVersion > 0) - { - if(browserVersion != 3) - doc.write(" ") - - // close the whole tree - clickOnNode(0) - // open the root folder - clickOnNode(0) - } -} - -// Auxiliary Functions for Folder-Treee backward compatibility -// ********************************************************* - -function gFld(description, tagName, hreference) -{ - folder = new Folder(description, tagName, hreference) - return folder -} - -function gLnk(description, tagName, linkData) -{ - fullLink = "" - - if (linkData!="") - { - fullLink = "'"+linkData+"' target=\"basefrm\"" - } - - linkItem = new Item(description, tagName, fullLink) - return linkItem -} - -function insFld(parentFolder, childFolder) -{ - return parentFolder.addChild(childFolder) -} - -function insDoc(parentFolder, document) -{ - parentFolder.addChild(document) -} - -// Global variables -// **************** - -USETEXTLINKS = 1 -indexOfEntries = new Array -nEntries = 0 -doc = document -browserVersion = 0 -selectedFolder=0 diff --git a/doc/salome/Makefile.am b/doc/salome/Makefile.am index 1bfebe55b..b48efacd3 100644 --- a/doc/salome/Makefile.am +++ b/doc/salome/Makefile.am @@ -1,4 +1,7 @@ -# Copyright (C) 2005 CEA/DEN, EDF R&D, OPEN CASCADE, PRINCIPIA R&D +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -14,19 +17,17 @@ # 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # - # -* Makefile *- -# # Author : Patrick GOLDBRONN (CEA) # Date : 30/11/2001 # $Header$ # - -SUBDIRSTUI= tui +SUBDIRS = tui +SUBDIRSTUI = tui dev_docs: @@SETX@; for d in $(SUBDIRSTUI); do \ (cd $$d && $(MAKE) $@) || exit 1; \ - done; + done; \ No newline at end of file diff --git a/doc/salome/tui/MED/HTML/MED.html b/doc/salome/tui/MED/HTML/MED.html deleted file mode 100644 index 8b1abaeb1..000000000 --- a/doc/salome/tui/MED/HTML/MED.html +++ /dev/null @@ -1,502 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
interface MESH
IDL file
Python
string getName ( )
return_value = getName ( )
long getSpaceDimension ( )
return_value = getSpaceDimension ( )
long getMeshDimension ( )
return_value = getMeshDimension ( )
boolean getIsAGrid ( )
return_value = getIsAGrid ( )
boolean existConnectivity ( in medConnectivity mode, in medEntityMesh entity )
return_value = existConnectivity ( mode, entity )
string getCoordinatesSystem ( )
return_value = getCoordinatesSystem ( )
long getNumberOfNodes ( )
return_value = getNumberOfNodes ( )
double_array getCoordinates ( in medModeSwitch typeSwitch )
return_value = getCoordinates ( typeSwitch )
double getCoordinate ( in long Number, in long Axis )
return_value = getCoordinate ( Number, Axis )
string_array getCoordinatesNames ( )
return_value = getCoordinatesNames ( )
string_array getCoordinatesUnits ( )
return_value = getCoordinatesUnits ( )
SUPPORT getBoundaryElements ( in medEntityMesh Entity )
return_value = getBoundaryElements ( Entity )
SUPPORT getSkin ( in SUPPORT mySupport3D )
return_value = getSkin ( mySupport3D )
long_array getGlobalNumberingIndex ( in medEntityMesh entity )
return_value = getGlobalNumberingIndex ( entity )
coordinateInfos getCoordGlobal ( )
return_value = getCoordGlobal ( )
long getNumberOfTypes ( in medEntityMesh entity )
return_value = getNumberOfTypes ( entity )
medGeometryElement_array getTypes ( in medEntityMesh entity )
return_value = getTypes ( entity )
long getNumberOfElements ( in medEntityMesh entity, in medGeometryElement geomElement )
return_value = getNumberOfElements ( entity, geomElement )
long_array getConnectivity ( in medModeSwitch typeSwitch, in medConnectivity mode, in medEntityMesh entity, in medGeometryElement geomElement )
return_value = getConnectivity ( typeSwitch, mode, entity, geomElement )
long_array getConnectivityIndex ( in medConnectivity mode, in medEntityMesh entity )
return_value = getConnectivityIndex ( mode, entity )
long getElementNumber ( in medConnectivity mode, in medEntityMesh entity, in medGeometryElement type, in long_array connectivity )
return_value = getElementNumber ( mode, entity, type, connectivity )
medGeometryElement getElementType ( in medEntityMesh entity, in long number )
return_value = getElementType ( entity, number )
long_array getReverseConnectivity ( in medConnectivity mode )
return_value = getReverseConnectivity ( mode )
long_array getReverseConnectivityIndex ( in medConnectivity mode )
return_value = getReverseConnectivityIndex ( mode )
connectivityInfos getConnectGlobal ( in medEntityMesh entity )
return_value = getConnectGlobal ( entity )
long getNumberOfFamilies ( in medEntityMesh entity )
return_value = getNumberOfFamilies ( entity )
long getNumberOfGroups ( in medEntityMesh entity )
return_value = getNumberOfGroups ( entity )
Family_array getFamilies ( in medEntityMesh entity )
return_value = getFamilies ( entity )
FAMILY getFamily ( in medEntityMesh entity, in long familyNumber )
return_value = getFamily ( entity, familyNumber )
Group_array getGroups ( in medEntityMesh entity )
return_value = getGroups ( entity )
GROUP getGroup ( in medEntityMesh entity, in long groupNumber )
return_value = getGroup ( entity, groupNumber )
FIELD getVolume ( in SUPPORT mySupport )
return_value = getVolume ( mySupport )
FIELD getArea ( in SUPPORT mySupport )
return_value = getArea ( mySupport )
FIELD getLength ( in SUPPORT mySupport )
return_value = getLength ( mySupport )
FIELD getNormal ( in SUPPORT mySupport )
return_value = getNormal ( mySupport )
FIELD getBarycenter ( in SUPPORT mySupport )
return_value = getBarycenter ( mySupport )
void addInStudy ( in Study myStudy, in MESH myIor )
addInStudy ( myStudy, myIor )
long addDriver ( in medDriverTypes driverType, in string fileName, in string meshName )
return_value = addDriver ( driverType, fileName, meshName )
void rmDriver ( in long i )
rmDriver ( i )
void read ( in long i )
read ( i )
void write ( in long i, in string driverMeshName )
write ( i, driverMeshName )
long getCorbaIndex ( )
return_value = getCorbaIndex ( )
meshInfos getMeshGlobal ( )
return_value = getMeshGlobal ( )

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
interface SUPPORT
IDL file
Python
string getName ( )
return_value = getName ( )
string getDescription ( )
return_value = getDescription ( )
MESH getMesh ( )
return_value = getMesh ( )
medEntityMesh getEntity ( )
return_value = getEntity ( )
boolean isOnAllElements ( )
return_value = isOnAllElements ( )
long getNumberOfElements ( in medGeometryElement geomElement )
return_value = getNumberOfElements ( geomElement )
long getNumberOfTypes ( )
return_value = getNumberOfTypes ( )
medGeometryElement_array getTypes ( )
return_value = getTypes ( )
long_array getNumber ( in medGeometryElement geomElement )
return_value = getNumber ( geomElement )
long_array getNumberIndex ( )
return_value = getNumberIndex ( )
long getNumberOfGaussPoint ( in medGeometryElement geomElement )
return_value = getNumberOfGaussPoint ( geomElement )
long_array getNumbersOfGaussPoint ( )
return_value = getNumbersOfGaussPoint ( )
void getBoundaryElements ( )
getBoundaryElements ( )
long getCorbaIndex ( )
return_value = getCorbaIndex ( )
supportInfos getSupportGlobal ( )
return_value = getSupportGlobal ( )

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
interface FAMILY
IDL file
Python
long getIdentifier ( )
return_value = getIdentifier ( )
long getNumberOfAttributes ( )
return_value = getNumberOfAttributes ( )
long_array getAttributesIdentifiers ( )
return_value = getAttributesIdentifiers ( )
long getAttributeIdentifier ( in long i )
return_value = getAttributeIdentifier ( i )
long_array getAttributesValues ( )
return_value = getAttributesValues ( )
long getAttributeValue ( in long i )
return_value = getAttributeValue ( i )
string_array getAttributesDescriptions ( )
return_value = getAttributesDescriptions ( )
string getAttributeDescription ( in long i )
return_value = getAttributeDescription ( i )
long getNumberOfGroups ( )
return_value = getNumberOfGroups ( )
string_array getGroupsNames ( )
return_value = getGroupsNames ( )
string getGroupName ( in long i )
return_value = getGroupName ( i )

- - - - - - - - - - - - - - - - - - - -
interface GROUP
IDL file
Python
long getNumberOfFamilies ( )
return_value = getNumberOfFamilies ( )
Family_array getFamilies ( )
return_value = getFamilies ( )
FAMILY getFamily ( in long i )
return_value = getFamily ( i )

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
interface FIELD
IDL file
Python
string getName ( )
return_value = getName ( )
string getDescription ( )
return_value = getDescription ( )
SUPPORT getSupport ( )
return_value = getSupport ( )
long getNumberOfComponents ( )
return_value = getNumberOfComponents ( )
string_array getComponentsNames ( )
return_value = getComponentsNames ( )
string getComponentName ( in long i )
return_value = getComponentName ( i )
string_array getComponentsUnits ( )
return_value = getComponentsUnits ( )
string getComponentUnit ( in long i )
return_value = getComponentUnit ( i )
long getIterationNumber ( )
return_value = getIterationNumber ( )
double getTime ( )
return_value = getTime ( )
long getOrderNumber ( )
return_value = getOrderNumber ( )
long addDriver ( in medDriverTypes driverType, in string fileName, in string fieldName )
return_value = addDriver ( driverType, fileName, fieldName )
void rmDriver ( in long i )
rmDriver ( i )
void read ( in long i )
read ( i )
void write ( in long i, in string driverFieldName )
write ( i, driverFieldName )
void addInStudy ( in Study myStudy, in FIELD myIor )
addInStudy ( myStudy, myIor )
long getCorbaIndex ( )
return_value = getCorbaIndex ( )

- - - - - - - - - - - -
interface FIELDDOUBLE
IDL file
Python
double_array getValue ( in medModeSwitch mode )
return_value = getValue ( mode )

- - - - - - - - - - - -
interface FIELDINT
IDL file
Python
long_array getValue ( in medModeSwitch mode )
return_value = getValue ( mode )

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
interface MED
IDL file
Python
long getNumberOfMeshes ( )
return_value = getNumberOfMeshes ( )
long getNumberOfFields ( )
return_value = getNumberOfFields ( )
string_array getMeshNames ( )
return_value = getMeshNames ( )
string_array getFieldNames ( )
return_value = getFieldNames ( )
MESH getMeshByName ( in string meshName )
return_value = getMeshByName ( meshName )
MESH getMesh ( in FIELD fieldPtr )
return_value = getMesh ( fieldPtr )
long getFieldNumberOfIteration ( in string fieldName )
return_value = getFieldNumberOfIteration ( fieldName )
long_array getFieldIteration ( in string fieldName, in long i )
return_value = getFieldIteration ( fieldName, i )
long_array getFieldIterations ( in string fieldName )
return_value = getFieldIterations ( fieldName )
FIELD getField ( in string fieldName, in long pasTemps, in long numOrdre )
return_value = getField ( fieldName, pasTemps, numOrdre )
long addDriver ( in medDriverTypes driverType, in string fileName )
return_value = addDriver ( driverType, fileName )
void rmDriver ( in long i )
rmDriver ( i )
void readFileStruct ( in long i )
readFileStruct ( i )
void writeFrom ( in long i )
writeFrom ( i )
void write ( in long i )
write ( i )
void addMesh ( in MESH ptrMesh )
addMesh ( ptrMesh )
void addField ( in FIELD ptrField )
addField ( ptrField )
void addInStudy ( in Study myStudy, in MED medPtr )
addInStudy ( myStudy, medPtr )

-
diff --git a/doc/salome/tui/MED/HTML/MED_Gen.html b/doc/salome/tui/MED/HTML/MED_Gen.html deleted file mode 100644 index 44b43940b..000000000 --- a/doc/salome/tui/MED/HTML/MED_Gen.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
interface MED_Gen
IDL file
Python
MESH readMeshInFile ( in string fileName, in string studyName, in string meshName )
return_value = readMeshInFile ( fileName, studyName, meshName )
FIELD readFieldInFile ( in string fileName, in string studyName, in string fieldName, in long ordre, in long iter )
return_value = readFieldInFile ( fileName, studyName, fieldName, ordre, iter )
MED readStructFile ( in string fileName, in string studyName )
return_value = readStructFile ( fileName, studyName )
void readStructFileWithFieldType ( in string fileName, in string studyName )
readStructFileWithFieldType ( fileName, studyName )

-
diff --git a/doc/salome/tui/MED/Makefile.am b/doc/salome/tui/MED/Makefile.am deleted file mode 100644 index e0b08cffa..000000000 --- a/doc/salome/tui/MED/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (C) 2003 CEA/DEN, EDF R&D -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -include $(top_srcdir)/adm_local/unix/make_common_starter.am - -SUBDIRS = sources -EXTRA_DIST += HTML - -#doctuidir= $(docdir)/tui/MED -#nodist_doctui_DATA= doxyfile - -#doctuistaticdir= $(docdir)/tui/MED/sources/static -#nodist_doctuistatic_DATA= MED/sources/static/tree.js diff --git a/doc/salome/tui/MED/doxyfile.in b/doc/salome/tui/MED/doxyfile.in deleted file mode 100755 index 06d537f1f..000000000 --- a/doc/salome/tui/MED/doxyfile.in +++ /dev/null @@ -1,231 +0,0 @@ -# Doxyfile 1.3.7 - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- -PROJECT_NAME = "SALOME - MED - v.@VERSION@" -PROJECT_NUMBER = -OUTPUT_DIRECTORY = ../ -CREATE_SUBDIRS = NO -OUTPUT_LANGUAGE = English -USE_WINDOWS_ENCODING = NO -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = YES -STRIP_FROM_PATH = ../../../share/salome \ - ../../../build/salome -STRIP_FROM_INC_PATH = -SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = YES -MULTILINE_CPP_IS_BRIEF = NO -DETAILS_AT_TOP = NO -INHERIT_DOCS = NO -DISTRIBUTE_GROUP_DOC = NO -TAB_SIZE = 5 -ALIASES = -OPTIMIZE_OUTPUT_FOR_C = YES -OPTIMIZE_OUTPUT_JAVA = YES -SUBGROUPING = YES - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- -EXTRACT_ALL = YES -EXTRACT_PRIVATE = YES -EXTRACT_STATIC = YES -EXTRACT_LOCAL_CLASSES = YES -EXTRACT_LOCAL_METHODS = NO -HIDE_UNDOC_MEMBERS = YES -HIDE_UNDOC_CLASSES = YES -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = YES -CASE_SENSE_NAMES = YES -HIDE_SCOPE_NAMES = NO -SHOW_INCLUDE_FILES = YES -INLINE_INFO = YES -SORT_MEMBER_DOCS = NO -SORT_BRIEF_DOCS = NO -SORT_BY_SCOPE_NAME = NO -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 25 -SHOW_USED_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES -WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = log.txt - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = ../../../share/salome/src \ - ../../../share/salome/idl \ - ../../../build/salome/bin -FILE_PATTERNS = *.idl *.h *.hh *.hxx *.c *.cc *.cxx *.ixx *.jxx python_extension_must_be_here -RECURSIVE = YES -EXCLUDE = -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXAMPLE_PATH = -EXAMPLE_PATTERNS = -EXAMPLE_RECURSIVE = YES -IMAGE_PATH = sources/ -INPUT_FILTER = -FILTER_SOURCE_FILES = YES - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = NO -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = NO -REFERENCES_RELATION = YES -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = YES -COLS_IN_ALPHA_INDEX = 3 -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = MED -HTML_FILE_EXTENSION = .html -HTML_HEADER = sources/myheader.html -HTML_FOOTER = sources/footer.html -HTML_STYLESHEET = sources/static/doxygen.css -HTML_ALIGN_MEMBERS = YES -GENERATE_HTMLHELP = NO -CHM_FILE = -HHC_LOCATION = -GENERATE_CHI = NO -BINARY_TOC = YES -TOC_EXPAND = YES -DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = NO -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- -GENERATE_LATEX = NO -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex -COMPACT_LATEX = NO -PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = NO -USE_PDFLATEX = NO -LATEX_BATCHMODE = NO -LATEX_HIDE_INDICES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = NO -XML_OUTPUT = xml -XML_SCHEMA = -XML_DTD = -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- -GENERATE_PERLMOD = NO -PERLMOD_LATEX = NO -PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = YES -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = NO - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- -CLASS_DIAGRAMS = YES -HIDE_UNDOC_RELATIONS = NO -HAVE_DOT = YES -CLASS_GRAPH = YES -COLLABORATION_GRAPH = NO -UML_LOOK = NO -TEMPLATE_RELATIONS = YES -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = NO -CALL_GRAPH = NO -GRAPHICAL_HIERARCHY = YES -DOT_IMAGE_FORMAT = jpg -DOT_PATH = -DOTFILE_DIRS = -MAX_DOT_GRAPH_WIDTH = 1024 -MAX_DOT_GRAPH_HEIGHT = 1200 -MAX_DOT_GRAPH_DEPTH = 0 -GENERATE_LEGEND = NO -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- -SEARCHENGINE = NO diff --git a/doc/salome/tui/MED/sources/Application-About.png b/doc/salome/tui/MED/sources/Application-About.png deleted file mode 100755 index df0d5a187..000000000 Binary files a/doc/salome/tui/MED/sources/Application-About.png and /dev/null differ diff --git a/doc/salome/tui/MED/sources/Application-About1.jpg b/doc/salome/tui/MED/sources/Application-About1.jpg deleted file mode 100755 index cf7ab8ba0..000000000 Binary files a/doc/salome/tui/MED/sources/Application-About1.jpg and /dev/null differ diff --git a/doc/salome/tui/MED/sources/Makefile.am b/doc/salome/tui/MED/sources/Makefile.am deleted file mode 100644 index db3b477a8..000000000 --- a/doc/salome/tui/MED/sources/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (C) 2003 CEA/DEN, EDF R&D -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -include $(top_srcdir)/adm_local/unix/make_common_starter.am - -SUBDIRS = static -EXTRA_DIST += \ - Application-About1.jpg \ - Application-About.png \ - application.gif \ - application.jpg \ - bg_salome.gif \ - footer.html \ - logocorp.gif \ - myheader.html \ - occ.gif - -#doctuidir= $(docdir)/tui/MED -#nodist_doctui_DATA= doxyfile - -#doctuistaticdir= $(docdir)/tui/MED/sources/static -#nodist_doctuistatic_DATA= MED/sources/static/tree.js diff --git a/doc/salome/tui/MED/sources/application.gif b/doc/salome/tui/MED/sources/application.gif deleted file mode 100644 index 0b05d5c18..000000000 Binary files a/doc/salome/tui/MED/sources/application.gif and /dev/null differ diff --git a/doc/salome/tui/MED/sources/application.jpg b/doc/salome/tui/MED/sources/application.jpg deleted file mode 100755 index a6979ab99..000000000 Binary files a/doc/salome/tui/MED/sources/application.jpg and /dev/null differ diff --git a/doc/salome/tui/MED/sources/bg_salome.gif b/doc/salome/tui/MED/sources/bg_salome.gif deleted file mode 100755 index 677b70468..000000000 Binary files a/doc/salome/tui/MED/sources/bg_salome.gif and /dev/null differ diff --git a/doc/salome/tui/MED/sources/footer.html b/doc/salome/tui/MED/sources/footer.html deleted file mode 100755 index cb55f397a..000000000 --- a/doc/salome/tui/MED/sources/footer.html +++ /dev/null @@ -1,5 +0,0 @@ - -
- - diff --git a/doc/salome/tui/MED/sources/logocorp.gif b/doc/salome/tui/MED/sources/logocorp.gif deleted file mode 100755 index 7697e0837..000000000 Binary files a/doc/salome/tui/MED/sources/logocorp.gif and /dev/null differ diff --git a/doc/salome/tui/MED/sources/myheader.html b/doc/salome/tui/MED/sources/myheader.html deleted file mode 100755 index d2efb75fa..000000000 --- a/doc/salome/tui/MED/sources/myheader.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Main Page - - - - -  - - diff --git a/doc/salome/tui/MED/sources/occ.gif b/doc/salome/tui/MED/sources/occ.gif deleted file mode 100755 index ce017c8ae..000000000 Binary files a/doc/salome/tui/MED/sources/occ.gif and /dev/null differ diff --git a/doc/salome/tui/MED/sources/static/Makefile.am b/doc/salome/tui/MED/sources/static/Makefile.am deleted file mode 100644 index 42b89594a..000000000 --- a/doc/salome/tui/MED/sources/static/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (C) 2003 CEA/DEN, EDF R&D -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -include $(top_srcdir)/adm_local/unix/make_common_starter.am - -EXTRA_DIST += \ - doxygen.css \ - page2.html \ - treeview.js - -#doctuidir= $(docdir)/tui/MED -#nodist_doctui_DATA= doxyfile - -#doctuistaticdir= $(docdir)/tui/MED/sources/static -#nodist_doctuistatic_DATA= MED/sources/static/tree.js diff --git a/doc/salome/tui/MED/sources/static/doxygen.css b/doc/salome/tui/MED/sources/static/doxygen.css deleted file mode 100755 index 88e613d23..000000000 --- a/doc/salome/tui/MED/sources/static/doxygen.css +++ /dev/null @@ -1,170 +0,0 @@ -H1 { - text-align: center; -} - -CAPTION { - font-weight: bold -} - -/* Link in the top navbar */ -A.qindex {} - -A.qindexRef {} - -/* Link to any cross-referenced Doxygen element */ -A.el { - text-decoration: none; - font-weight: bold -} - -A.elRef { - font-weight: bold -} - -/* Link to any cross-referenced Doxygen element inside a code section - (ex: header) -*/ -A.code { - text-decoration: none; - font-weight: normal; - color: #4444ee -} - -A.codeRef { - font-weight: normal; - color: #4444ee -} - -A:hover { - text-decoration: none; - background-color: lightblue -} - -DL.el { - margin-left: -1cm -} - -/* A code fragment (ex: header) */ -DIV.fragment { - width: 100%; - border: none; - background-color: #CCCCCC -} - -/* In the alpha list (coumpound index), style of an alphabetical index letter */ -DIV.ah { - background-color: #CCCCCC; - font-weight: bold; - color: #ffffff; - margin-bottom: 3px; - margin-top: 3px -} - -/* Method name (+ type) */ -TD.md { - background-color: lightblue; - font-weight: bold; -} - -/* Method parameter (some of them) */ -TD.mdname1 { - background-color: lightblue; - font-weight: bold; color: #602020; -} - -/* Method parameter (some of them) */ -TD.mdname { - background-color: lightblue; - font-weight: bold; - color: #602020; - width: 600px; -} - -/* Separator between methods group (usually empty, seems not supported by IE) */ -DIV.groupHeader { - margin-left: 16px; - margin-top: 12px; - margin-bottom: 6px; - font-weight: bold -} - -DIV.groupText { - margin-left: 16px; - font-style: italic; - font-size: smaller -} - -BODY { - background: #FFFFFF; -} - -/*div.div-page { - background-color: #FFFFFF; - margin-left: 1em; - margin-right: 1em; - margin-top: 1em; - margin-bottom: 0.1em; - - padding-left: 1em; - padding-right: 1em; - padding-top: 0.5em; - padding-bottom: 0.5em; - - border: 2px solid #0D299A; - border-width: 2px; - border-color: #0D299A; -}*/ - -div.tabs { - text-align: justify; - margin-left : 2px; - margin-right : 2px; - margin-top : 2px; - margin-bottom : 2px - font-weight: bold; - color: #FFFFFF; -} - -DIV.div-footer { - margin-left: 1em; - margin-right: 1em; - margin-bottom: 0.2em; - text-align: right; - font-size: 9pt; -} - -/* In File List, Coumpound List, etc, 1st column of the index */ -TD.indexkey { - background-color: #CCCCCC; - font-weight: bold; - padding-right : 10px; - padding-top : 2px; - padding-left : 10px; - padding-bottom : 2px; - margin-left : 0px; - margin-right : 0px; - margin-top : 2px; - margin-bottom : 2px -} - -/* In File List, Coumpound List, etc, 2nd column of the index */ -TD.indexvalue { - background-color: #CCCCCC; - font-style: italic; - padding-right : 10px; - padding-top : 2px; - padding-left : 10px; - padding-bottom : 2px; - margin-left : 0px; - margin-right : 0px; - margin-top : 2px; - margin-bottom : 2px -} - -span.keyword { color: #008000 } -span.keywordtype { color: #604020 } -span.keywordflow { color: #e08000 } -span.comment { color: #800000 } -span.preprocessor { color: #806020 } -span.stringliteral { color: #002080 } -span.charliteral { color: #008080 } diff --git a/doc/salome/tui/MED/sources/static/page2.html b/doc/salome/tui/MED/sources/static/page2.html deleted file mode 100755 index 1891fe92c..000000000 --- a/doc/salome/tui/MED/sources/static/page2.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - Main Page - - - - -   -
- - - - - - - - -
- - -
-
- - -
- - diff --git a/doc/salome/tui/MED/sources/static/tree.js.in b/doc/salome/tui/MED/sources/static/tree.js.in deleted file mode 100755 index b4ff3414f..000000000 --- a/doc/salome/tui/MED/sources/static/tree.js.in +++ /dev/null @@ -1,20 +0,0 @@ -foldersTree = gFld("SALOME v.@VERSION@ ", "", "") - insDoc(foldersTree, gLnk("Main Page", "", "main.html")) - -aux1 = insFld(foldersTree, gFld("TUI Reference Guide", "")) - aux2 = insFld(aux1, gFld("Modules", "")) - aux3 = insFld(aux2, gFld("SALOME MED module", "")) -/*! insDoc(aux3, gLnk("Overview", "", "overview_Med.html"))*/ - aux4 = insFld(aux3, gFld("Packages", "")) - insDoc(aux4, gLnk("SALOME_MED", "", "namespaceSALOME__MED.html")) -/*! insDoc(aux3, gLnk("Examples", "", "examples_MED.html")) -*/ - - insDoc(aux1, gLnk("Data Structures", "", "annotated.html")) - insDoc(aux1, gLnk("Class Hierarchy", "", "hierarchy.html")) - insDoc(aux1, gLnk("Class methods list", "", "functions.html")) - insDoc(aux1, gLnk("Namespace Members", "", "namespacemembers.html")) - insDoc(aux1, gLnk("File List", "", "files.html")) - -aux1 = insFld(foldersTree, gFld("IDL/Python mapping", "")) - insDoc(aux1, gLnk("Mapping of MED IDL definitions to Python language", "", "page2.html")) diff --git a/doc/salome/tui/MED/sources/static/treeview.js b/doc/salome/tui/MED/sources/static/treeview.js deleted file mode 100644 index 55eb43d07..000000000 --- a/doc/salome/tui/MED/sources/static/treeview.js +++ /dev/null @@ -1,505 +0,0 @@ -//**************************************************************** -// You are free to copy the "Folder-Tree" script as long as you -// keep this copyright notice: -// Script found in: http://www.geocities.com/Paris/LeftBank/2178/ -// Author: Marcelino Alves Martins (martins@hks.com) December '97. -//**************************************************************** - -//Log of changes: -// 17 Feb 98 - Fix initialization flashing problem with Netscape -// -// 27 Jan 98 - Root folder starts open; support for USETEXTLINKS; -// make the ftien4 a js file -// -// DvH: Dec 2000 - Made some minor changes to support external -// references - -// Definition of class Folder -// ***************************************************************** - -function Folder(folderDescription, tagName, hreference) //constructor -{ - //constant data - this.desc = folderDescription - this.tagName = tagName - this.hreference = hreference - this.id = -1 - this.navObj = 0 - this.iconImg = 0 - this.nodeImg = 0 - this.isLastNode = 0 - - //dynamic data - this.isOpen = true - this.iconSrc = "ftv2folderopen.png" - this.children = new Array - this.nChildren = 0 - - //methods - this.initialize = initializeFolder - this.setState = setStateFolder - this.addChild = addChild - this.createIndex = createEntryIndex - this.hide = hideFolder - this.display = display - this.renderOb = drawFolder - this.totalHeight = totalHeight - this.subEntries = folderSubEntries - this.outputLink = outputFolderLink -} - -function setStateFolder(isOpen) -{ - var subEntries - var totalHeight - var fIt = 0 - var i=0 - - if (isOpen == this.isOpen) - return - - if (browserVersion == 2) - { - totalHeight = 0 - for (i=0; i < this.nChildren; i++) - totalHeight = totalHeight + this.children[i].navObj.clip.height - subEntries = this.subEntries() - if (this.isOpen) - totalHeight = 0 - totalHeight - for (fIt = this.id + subEntries + 1; fIt < nEntries; fIt++) - indexOfEntries[fIt].navObj.moveBy(0, totalHeight) - } - this.isOpen = isOpen - propagateChangesInState(this) -} - -function propagateChangesInState(folder) -{ - var i=0 - - if (folder.isOpen) - { - if (folder.nodeImg) - if (folder.isLastNode) - folder.nodeImg.src = "ftv2mlastnode.png" - else - folder.nodeImg.src = "ftv2mnode.png" - folder.iconImg.src = "ftv2folderopen.png" - for (i=0; i 0) - auxEv = "" - else - auxEv = "" - - if (level>0) - if (lastNode) //the last 'brother' in the children array - { - this.renderOb(leftSide + auxEv + "") -// leftSide = leftSide + "" - this.isLastNode = 1 - } - else - { - this.renderOb(leftSide + auxEv + "") - leftSide = leftSide + "" - this.isLastNode = 0 - } - else - this.renderOb("") - - if (nc > 0) - { - level = level + 1 - for (i=0 ; i < this.nChildren; i++) - { - if (i == this.nChildren-1) - this.children[i].initialize(level, 1, leftSide) - else - this.children[i].initialize(level, 0, leftSide) - } - } -} - -function drawFolder(leftSide) -{ - if (browserVersion == 2) { - if (!doc.yPos) - doc.yPos=8 - doc.write("") - } - if (browserVersion == 3) - { - doc.write("
") - } - - doc.write("\n") - doc.write("\n\n") - doc.write("\n
") - doc.write(leftSide) - this.outputLink() - doc.write("") - doc.write("") - if (USETEXTLINKS) - { - this.outputLink() - doc.write(this.desc + "") - } - else - doc.write(this.desc) - -/*! - if (this.tagName!="") - { - doc.write(" [external]") - } -*/ - doc.write("
\n") - - if (browserVersion == 2) { - doc.write("") - } - if (browserVersion == 3) { - doc.write("
") - } - - if (browserVersion == 1) { - this.navObj = doc.all["folder"+this.id] - this.iconImg = doc.all["folderIcon"+this.id] - this.nodeImg = doc.all["nodeIcon"+this.id] - } else if (browserVersion == 2) { - this.navObj = doc.layers["folder"+this.id] - this.iconImg = this.navObj.document.images["folderIcon"+this.id] - this.nodeImg = this.navObj.document.images["nodeIcon"+this.id] - doc.yPos=doc.yPos+this.navObj.clip.height - } else if (browserVersion == 3) { - this.navObj = doc.getElementById("folder"+this.id) - this.iconImg = doc.images.namedItem("folderIcon"+this.id) - this.nodeImg = doc.images.namedItem("nodeIcon"+this.id) - } -} - -function outputFolderLink() -{ - if (this.hreference) - { - doc.write(" 0) - doc.write("onClick='javascript:clickOnFolder("+this.id+")'") - doc.write(">") - } - else - doc.write("") -} - -function addChild(childNode) -{ - this.children[this.nChildren] = childNode - this.nChildren++ - return childNode -} - -function folderSubEntries() -{ - var i = 0 - var se = this.nChildren - - for (i=0; i < this.nChildren; i++){ - if (this.children[i].children) //is a folder - se = se + this.children[i].subEntries() - } - - return se -} - - -// Definition of class Item (a document or link inside a Folder) -// ************************************************************* - -function Item(itemDescription, tagName, itemLink) // Constructor -{ - // constant data - this.desc = itemDescription - this.tagName = tagName - this.link = itemLink - this.id = -1 //initialized in initalize() - this.navObj = 0 //initialized in render() - this.iconImg = 0 //initialized in render() - this.iconSrc = "ftv2doc.png" - - // methods - this.initialize = initializeItem - this.createIndex = createEntryIndex - this.hide = hideItem - this.display = display - this.renderOb = drawItem - this.totalHeight = totalHeight -} - -function hideItem() -{ - if (browserVersion == 1 || browserVersion == 3) { - if (this.navObj.style.display == "none") - return - this.navObj.style.display = "none" - } else { - if (this.navObj.visibility == "hidden") - return - this.navObj.visibility = "hidden" - } -} - -function initializeItem(level, lastNode, leftSide) -{ - this.createIndex() - - if (level>0) - if (lastNode) //the last 'brother' in the children array - { - this.renderOb(leftSide + "") - leftSide = leftSide + "" - } - else - { - this.renderOb(leftSide + "") - leftSide = leftSide + "" - } - else - this.renderOb("") -} - -function drawItem(leftSide) -{ - if (browserVersion == 2) - doc.write("") - if (browserVersion == 3) - doc.write("
") - - doc.write("\n\n") - doc.write("\n
") - doc.write(leftSide) - if (this.link!="") - { - doc.write("") - } - doc.write("") - if (this.link!="") - { - doc.write("") - } - doc.write("") - if (USETEXTLINKS && this.link!="") - doc.write("" + this.desc + "") - else - doc.write(this.desc) -/*! - if (this.tagName!="") - { - doc.write(" [external]"); - } -*/ - doc.write("\n
\n") - - if (browserVersion == 2) - doc.write("") - if (browserVersion == 3) - doc.write("
") - - if (browserVersion == 1) { - this.navObj = doc.all["item"+this.id] - this.iconImg = doc.all["itemIcon"+this.id] - } else if (browserVersion == 2) { - this.navObj = doc.layers["item"+this.id] - this.iconImg = this.navObj.document.images["itemIcon"+this.id] - doc.yPos=doc.yPos+this.navObj.clip.height - } else if (browserVersion == 3) { - this.navObj = doc.getElementById("item"+this.id) - this.iconImg = doc.images.namedItem("itemIcon"+this.id) - } -} - - -// Methods common to both objects (pseudo-inheritance) -// ******************************************************** - -function display() -{ - if (browserVersion == 1 || browserVersion == 3) - this.navObj.style.display = "block" - else - this.navObj.visibility = "show" -} - -function createEntryIndex() -{ - this.id = nEntries - indexOfEntries[nEntries] = this - nEntries++ -} - -// total height of subEntries open -function totalHeight() //used with browserVersion == 2 -{ - var h = this.navObj.clip.height - var i = 0 - - if (this.isOpen) //is a folder and _is_ open - for (i=0 ; i < this.nChildren; i++) - h = h + this.children[i].totalHeight() - - return h -} - - -// Events -// ********************************************************* - -function clickOnFolder(folderId) -{ - var clicked = indexOfEntries[folderId] - - if (!clicked.isOpen) - clickOnNode(folderId) - - return - - if (clicked.isSelected) - return -} - -function clickOnNode(folderId) -{ - var clickedFolder = 0 - var state = 0 - - clickedFolder = indexOfEntries[folderId] - state = clickedFolder.isOpen - - clickedFolder.setState(!state) //open<->close -} - -function initializeDocument() -{ - doc = document; - if (doc.all) - browserVersion = 1 //IE4 - else - if (doc.layers) - browserVersion = 2 //NS4 - else if(navigator.userAgent.toLowerCase().indexOf('gecko') != -1) - browserVersion = 3 //mozilla - else - browserVersion = 0 //other - - foldersTree.initialize(0, 1, "") - foldersTree.display() - - if (browserVersion > 0) - { - if(browserVersion != 3) - doc.write(" ") - - // close the whole tree - clickOnNode(0) - // open the root folder - clickOnNode(0) - } -} - -// Auxiliary Functions for Folder-Treee backward compatibility -// ********************************************************* - -function gFld(description, tagName, hreference) -{ - folder = new Folder(description, tagName, hreference) - return folder -} - -function gLnk(description, tagName, linkData) -{ - fullLink = "" - - if (linkData!="") - { - fullLink = "'"+linkData+"' target=\"basefrm\"" - } - - linkItem = new Item(description, tagName, fullLink) - return linkItem -} - -function insFld(parentFolder, childFolder) -{ - return parentFolder.addChild(childFolder) -} - -function insDoc(parentFolder, document) -{ - parentFolder.addChild(document) -} - -// Global variables -// **************** - -USETEXTLINKS = 1 -indexOfEntries = new Array -nEntries = 0 -doc = document -browserVersion = 0 -selectedFolder=0 diff --git a/doc/salome/tui/Makefile.am b/doc/salome/tui/Makefile.am index e1cf0f083..92fc6ebeb 100644 --- a/doc/salome/tui/Makefile.am +++ b/doc/salome/tui/Makefile.am @@ -1,40 +1,40 @@ -# Copyright (C) 2003 CEA/DEN, EDF R&D +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 # - include $(top_srcdir)/adm_local/unix/make_common_starter.am -SUBDIRS = MED -#EXTRA_DIST+= MED +EXTRA_DIST += images static + +dev_docs: doxyfile + echo "Running doxygen in directory: "`pwd`; \ + $(DOXYGEN) $<; -dev_docs: - cp -fr $(srcdir)/MED ./INPUT; \ - cp -fr ./MED/doxyfile ./INPUT; \ - cp -fr ./MED/sources/static/tree.js ./INPUT/sources/static; \ - cd INPUT; \ - sed 's|../../../share/salome|$(top_srcdir)|' ./doxyfile > ./doxyfile1; \ - sed 's|../../build/salome|$(top_builddir)|' ./doxyfile1 > ./doxyfile2; \ - mv -f doxyfile2 doxyfile1; \ - echo "DOXYGEN SUPPORT PYTHON - @DOXYGEN_WITH_PYTHON@"; \ - if( test "x@DOXYGEN_WITH_PYTHON@" = "xyes"); then \ - sed 's|python_extension_must_be_here|*.py|' ./doxyfile1 > ./doxyfile2; \ - mv -f doxyfile2 doxyfile1; \ - $(DOXYGEN) -u ./doxyfile1; \ - else \ - sed 's|python_extension_must_be_here||' ./doxyfile1 > ./doxyfile2; \ - mv -f doxyfile2 doxyfile1; \ - fi; \ - mv -f doxyfile1 doxyfile; \ - $(DOXYGEN) ./doxyfile; \ - cd ..; \ - cp -fr $(srcdir)/MED/sources/static/*.* ./MED/ - cp -fr $(srcdir)/MED/sources/ MED/ - cp -fr $(srcdir)/MED/HTML/ MED/ - rm -fr INPUT +clean-local: + -rm -fr MED doxygen.bak -#doctuidir= $(docdir)/tui/MED -#nodist_doctui_DATA= MED/doxyfile +install-data-local: + if test -d MED; then \ + $(INSTALL) -d $(DESTDIR)$(docdir)/tui ; \ + cp -rp MED $(DESTDIR)$(docdir)/tui ; \ + fi; -#doctuistaticdir= $(docdir)/tui/MED/sources/static -#nodist_doctuistatic_DATA= MED/sources/static/tree.js +uninstall-local: + rm -rf $(DESTDIR)$(docdir)/tui/MED diff --git a/doc/salome/tui/doxyfile.in b/doc/salome/tui/doxyfile.in new file mode 100755 index 000000000..a32a31648 --- /dev/null +++ b/doc/salome/tui/doxyfile.in @@ -0,0 +1,263 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +# Doxyfile 1.4.6 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = "Med Module Programming Guide v.@VERSION@" +PROJECT_NUMBER = +OUTPUT_DIRECTORY = MED +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = @top_srcdir@ @top_builddir@ +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = YES +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = NO +DISTRIBUTE_GROUP_DOC = NO +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 5 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = YES +BUILTIN_STL_SUPPORT = @DOXYGEN_SUPPORT_STL@ +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = YES +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = NO +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 25 +SHOW_USED_FILES = NO +SHOW_DIRECTORIES = NO +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = @top_srcdir@/src \ + @top_srcdir@/bin \ + @top_srcdir@/idl \ + @top_builddir@/bin +FILE_PATTERNS = *.idl *.h *.hh *.hxx *.c *.cc *.cxx *.ixx *.jxx @DOXYGEN_PYTHON_EXTENSION@ +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = YES +IMAGE_PATH = @srcdir@/images +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 3 +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = . +HTML_FILE_EXTENSION = .html +HTML_HEADER = @srcdir@/static/myheader.html +HTML_FOOTER = @srcdir@/static/footer.html +HTML_STYLESHEET = @srcdir@/static/doxygen.css +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = YES +TOC_EXPAND = YES +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = NO + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = NO +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = NO +GROUP_GRAPHS = NO +UML_LOOK = NO +TEMPLATE_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = NO +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = jpg +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1200 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = NO +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/doc/salome/tui/images/application.gif b/doc/salome/tui/images/application.gif new file mode 100644 index 000000000..0b05d5c18 Binary files /dev/null and b/doc/salome/tui/images/application.gif differ diff --git a/doc/salome/tui/images/application.jpg b/doc/salome/tui/images/application.jpg new file mode 100755 index 000000000..a6979ab99 Binary files /dev/null and b/doc/salome/tui/images/application.jpg differ diff --git a/doc/salome/tui/images/logocorp.gif b/doc/salome/tui/images/logocorp.gif new file mode 100755 index 000000000..7697e0837 Binary files /dev/null and b/doc/salome/tui/images/logocorp.gif differ diff --git a/doc/salome/tui/images/occ.gif b/doc/salome/tui/images/occ.gif new file mode 100755 index 000000000..ce017c8ae Binary files /dev/null and b/doc/salome/tui/images/occ.gif differ diff --git a/doc/salome/tui/static/doxygen.css b/doc/salome/tui/static/doxygen.css new file mode 100755 index 000000000..88e613d23 --- /dev/null +++ b/doc/salome/tui/static/doxygen.css @@ -0,0 +1,170 @@ +H1 { + text-align: center; +} + +CAPTION { + font-weight: bold +} + +/* Link in the top navbar */ +A.qindex {} + +A.qindexRef {} + +/* Link to any cross-referenced Doxygen element */ +A.el { + text-decoration: none; + font-weight: bold +} + +A.elRef { + font-weight: bold +} + +/* Link to any cross-referenced Doxygen element inside a code section + (ex: header) +*/ +A.code { + text-decoration: none; + font-weight: normal; + color: #4444ee +} + +A.codeRef { + font-weight: normal; + color: #4444ee +} + +A:hover { + text-decoration: none; + background-color: lightblue +} + +DL.el { + margin-left: -1cm +} + +/* A code fragment (ex: header) */ +DIV.fragment { + width: 100%; + border: none; + background-color: #CCCCCC +} + +/* In the alpha list (coumpound index), style of an alphabetical index letter */ +DIV.ah { + background-color: #CCCCCC; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px +} + +/* Method name (+ type) */ +TD.md { + background-color: lightblue; + font-weight: bold; +} + +/* Method parameter (some of them) */ +TD.mdname1 { + background-color: lightblue; + font-weight: bold; color: #602020; +} + +/* Method parameter (some of them) */ +TD.mdname { + background-color: lightblue; + font-weight: bold; + color: #602020; + width: 600px; +} + +/* Separator between methods group (usually empty, seems not supported by IE) */ +DIV.groupHeader { + margin-left: 16px; + margin-top: 12px; + margin-bottom: 6px; + font-weight: bold +} + +DIV.groupText { + margin-left: 16px; + font-style: italic; + font-size: smaller +} + +BODY { + background: #FFFFFF; +} + +/*div.div-page { + background-color: #FFFFFF; + margin-left: 1em; + margin-right: 1em; + margin-top: 1em; + margin-bottom: 0.1em; + + padding-left: 1em; + padding-right: 1em; + padding-top: 0.5em; + padding-bottom: 0.5em; + + border: 2px solid #0D299A; + border-width: 2px; + border-color: #0D299A; +}*/ + +div.tabs { + text-align: justify; + margin-left : 2px; + margin-right : 2px; + margin-top : 2px; + margin-bottom : 2px + font-weight: bold; + color: #FFFFFF; +} + +DIV.div-footer { + margin-left: 1em; + margin-right: 1em; + margin-bottom: 0.2em; + text-align: right; + font-size: 9pt; +} + +/* In File List, Coumpound List, etc, 1st column of the index */ +TD.indexkey { + background-color: #CCCCCC; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px +} + +/* In File List, Coumpound List, etc, 2nd column of the index */ +TD.indexvalue { + background-color: #CCCCCC; + font-style: italic; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px +} + +span.keyword { color: #008000 } +span.keywordtype { color: #604020 } +span.keywordflow { color: #e08000 } +span.comment { color: #800000 } +span.preprocessor { color: #806020 } +span.stringliteral { color: #002080 } +span.charliteral { color: #008080 } diff --git a/doc/salome/tui/static/footer.html b/doc/salome/tui/static/footer.html new file mode 100755 index 000000000..cb55f397a --- /dev/null +++ b/doc/salome/tui/static/footer.html @@ -0,0 +1,5 @@ + +
+ + diff --git a/doc/salome/tui/static/myheader.html b/doc/salome/tui/static/myheader.html new file mode 100755 index 000000000..d2efb75fa --- /dev/null +++ b/doc/salome/tui/static/myheader.html @@ -0,0 +1,13 @@ + + + + + + Main Page + + + + +  + + diff --git a/idl/Compo1Py.idl b/idl/Compo1Py.idl index 776ea172b..bf1e6cc27 100644 --- a/idl/Compo1Py.idl +++ b/idl/Compo1Py.idl @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "SALOME_Component.idl" #include "MED.idl" diff --git a/idl/MED.idl b/idl/MED.idl index 60b8dac41..41f9bec66 100644 --- a/idl/MED.idl +++ b/idl/MED.idl @@ -1,26 +1,28 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // // File: MED.idl // Project: SALOME // $Header$ - +// /*! This file contains the main IDL definitions of the %MED component in %SALOME application. */ @@ -258,6 +260,12 @@ This enumeration contains a set of elements defining the type of connectivity. SUPPORT getBoundaryElements(in medEntityMesh Entity) raises (SALOME::SALOME_Exception); + /*! + Returns the %SUPPORT defined on all the element of an Entity. + */ + SUPPORT getSupportOnAll(in medEntityMesh Entity) + raises (SALOME::SALOME_Exception); + /*! Returns the %SUPPORT containing the boundary elements of the support mySupport3D. @@ -1097,6 +1105,15 @@ Internal Corba method. void addInStudy (in SALOMEDS::Study myStudy, in MED medPtr) raises (SALOME::SALOME_Exception, SALOMEDS::StudyBuilder::LockProtection); }; + + /*! \brief A structure containing information about MED file + */ + struct MedFileInfo + { + string fileName; //!< name of file + long fileSize; //!< size of file + long major, minor, release; //!< MED file version + }; }; #endif /* MED_IDL */ diff --git a/idl/MED_Gen.idl b/idl/MED_Gen.idl index 8b5b13a87..2f31c25a7 100644 --- a/idl/MED_Gen.idl +++ b/idl/MED_Gen.idl @@ -1,27 +1,29 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // //============================================================================= // File : Med_Gen.idl // Project : SALOME //============================================================================= - +// #ifndef _Med_GEN_IDL_ #define _Med_GEN_IDL_ diff --git a/idl/Makefile.am b/idl/Makefile.am index 44eea992d..c931358ec 100644 --- a/idl/Makefile.am +++ b/idl/Makefile.am @@ -1,55 +1,51 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# - +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 # # This Makefile is responsible of generating the client and server # implementation of IDL interfaces for both C++ and python usage. # The building process of the C++ files is in charge of each source # package and then is not manage here. # - include $(top_srcdir)/adm_local/unix/make_common_starter.am BASEIDL_FILES= MED.idl MED_Gen.idl Compo1Py.idl -EXTRA_DIST+= $(BASEIDL_FILES) - # This variable defines the files to be installed -salomeidl_DATA = $(BASEIDL_FILES) +dist_salomeidl_DATA = $(BASEIDL_FILES) # GUI idl common library lib_LTLIBRARIES = libSalomeIDLMED.la # Sources built from idl files -nodist_libSalomeIDLMED_la_SOURCES= MEDSK.cc MED_GenSK.cc Compo1PySK.cc +nodist_libSalomeIDLMED_la_SOURCES = MEDSK.cc MED_GenSK.cc Compo1PySK.cc # header files must be exported: other modules have to use this library -nodist_salomeinclude_HEADERS= $(BASEIDL_FILES:%.idl=%.hh) +nodist_salomeinclude_HEADERS = $(BASEIDL_FILES:%.idl=%.hh) -libSalomeIDLMED_la_CPPFLAGS =\ - -I$(top_builddir)/salome_adm/unix \ - -I$(top_builddir)/idl \ +libSalomeIDLMED_la_CPPFLAGS = \ + -I$(top_builddir)/salome_adm/unix \ + -I$(top_builddir)/idl \ @CORBA_CXXFLAGS@ @CORBA_INCLUDES@ @KERNEL_CXXFLAGS@ libSalomeIDLMED_la_LDFLAGS = -no-undefined -version-info=0:0:0 -libSalomeIDLMED_la_LIBADD = \ - @CORBA_LIBS@ \ - $(KERNEL_LDFLAGS) -lSalomeIDLKernel +libSalomeIDLMED_la_LIBADD = @CORBA_LIBS@ $(KERNEL_LDFLAGS) -lSalomeIDLKernel # These variables defines the building process of CORBA files OMNIORB_IDL = @OMNIORB_IDL@ @@ -66,14 +62,14 @@ SUFFIXES = .idl .hh SK.cc $(OMNIORB_IDL) $(IDLCXXFLAGS) $(OMNIORB_IDLCXXFLAGS) $< install-exec-local: $(BASEIDL_FILES:%=$(top_srcdir)/idl/%) - $(INSTALL) -d $(pkgpythondir) + $(INSTALL) -d $(DESTDIR)$(salomepythondir) ls $^ | while read file; do \ - $(OMNIORB_IDL) $(IDLPYFLAGS) -C$(pkgpythondir) $$file ; \ + $(OMNIORB_IDL) $(IDLPYFLAGS) -C$(DESTDIR)$(salomepythondir) $$file ; \ done # uninstall-local removes too much, but it works in distcheck uninstall-local: - rm -rf $(pkgpythondir)/* + rm -rf $(DESTDIR)$(salomepythondir)/* mostlyclean-local: clean-idls diff --git a/resources/Box1.med b/resources/Box1.med new file mode 100644 index 000000000..329a2860e Binary files /dev/null and b/resources/Box1.med differ diff --git a/resources/Box1Moderate.med b/resources/Box1Moderate.med new file mode 100644 index 000000000..3fef76cd2 Binary files /dev/null and b/resources/Box1Moderate.med differ diff --git a/resources/Box2.med b/resources/Box2.med new file mode 100644 index 000000000..adc472503 Binary files /dev/null and b/resources/Box2.med differ diff --git a/resources/Box2Moderate.med b/resources/Box2Moderate.med new file mode 100644 index 000000000..9aaa9ffb3 Binary files /dev/null and b/resources/Box2Moderate.med differ diff --git a/resources/Box3.med b/resources/Box3.med new file mode 100644 index 000000000..9686dfb48 Binary files /dev/null and b/resources/Box3.med differ diff --git a/resources/BoxEvenSmaller1.med b/resources/BoxEvenSmaller1.med new file mode 100644 index 000000000..e789adaec Binary files /dev/null and b/resources/BoxEvenSmaller1.med differ diff --git a/resources/BoxHexa1.med b/resources/BoxHexa1.med new file mode 100644 index 000000000..016f1186d Binary files /dev/null and b/resources/BoxHexa1.med differ diff --git a/resources/BoxHexa2.med b/resources/BoxHexa2.med new file mode 100644 index 000000000..9653f1ff2 Binary files /dev/null and b/resources/BoxHexa2.med differ diff --git a/resources/BoxModSmall1.med b/resources/BoxModSmall1.med new file mode 100644 index 000000000..a2d1575da Binary files /dev/null and b/resources/BoxModSmall1.med differ diff --git a/resources/BoxModSmall2.med b/resources/BoxModSmall2.med new file mode 100644 index 000000000..bfad92a81 Binary files /dev/null and b/resources/BoxModSmall2.med differ diff --git a/resources/BoxTetra2.med b/resources/BoxTetra2.med new file mode 100644 index 000000000..44807eb2a Binary files /dev/null and b/resources/BoxTetra2.med differ diff --git a/resources/ComplexIncludedTetra.med b/resources/ComplexIncludedTetra.med new file mode 100644 index 000000000..93b4e74cf Binary files /dev/null and b/resources/ComplexIncludedTetra.med differ diff --git a/resources/ComplexIncludingTetra.med b/resources/ComplexIncludingTetra.med new file mode 100644 index 000000000..c900d2ad7 Binary files /dev/null and b/resources/ComplexIncludingTetra.med differ diff --git a/resources/CornerTetra.med b/resources/CornerTetra.med new file mode 100644 index 000000000..d1a6a675a Binary files /dev/null and b/resources/CornerTetra.med differ diff --git a/resources/DegenEdgeXY.med b/resources/DegenEdgeXY.med new file mode 100644 index 000000000..425238535 Binary files /dev/null and b/resources/DegenEdgeXY.med differ diff --git a/resources/DegenFaceXYZ.med b/resources/DegenFaceXYZ.med new file mode 100644 index 000000000..e48d9b76f Binary files /dev/null and b/resources/DegenFaceXYZ.med differ diff --git a/resources/DegenTranslatedInPlane.med b/resources/DegenTranslatedInPlane.med new file mode 100644 index 000000000..8fa088b3f Binary files /dev/null and b/resources/DegenTranslatedInPlane.med differ diff --git a/resources/DividedGenTetra1.med b/resources/DividedGenTetra1.med new file mode 100644 index 000000000..564cad0c9 Binary files /dev/null and b/resources/DividedGenTetra1.med differ diff --git a/resources/DividedGenTetra2.med b/resources/DividedGenTetra2.med new file mode 100644 index 000000000..fcfee02c8 Binary files /dev/null and b/resources/DividedGenTetra2.med differ diff --git a/resources/DividedUnitTetra.med b/resources/DividedUnitTetra.med new file mode 100644 index 000000000..f2feced90 Binary files /dev/null and b/resources/DividedUnitTetra.med differ diff --git a/resources/DividedUnitTetraSimpler.med b/resources/DividedUnitTetraSimpler.med new file mode 100644 index 000000000..5dfbeb1f5 Binary files /dev/null and b/resources/DividedUnitTetraSimpler.med differ diff --git a/resources/GenTetra1.med b/resources/GenTetra1.med new file mode 100644 index 000000000..4683d902d Binary files /dev/null and b/resources/GenTetra1.med differ diff --git a/resources/GenTetra2.med b/resources/GenTetra2.med new file mode 100644 index 000000000..6b88cd2a2 Binary files /dev/null and b/resources/GenTetra2.med differ diff --git a/resources/GeneralTetra.med b/resources/GeneralTetra.med new file mode 100644 index 000000000..38d0747a3 Binary files /dev/null and b/resources/GeneralTetra.med differ diff --git a/resources/HalfstripOnly.med b/resources/HalfstripOnly.med new file mode 100644 index 000000000..87dfa507d Binary files /dev/null and b/resources/HalfstripOnly.med differ diff --git a/resources/HalfstripOnly2.med b/resources/HalfstripOnly2.med new file mode 100644 index 000000000..36f51836a Binary files /dev/null and b/resources/HalfstripOnly2.med differ diff --git a/resources/LargeInconsistentTetra.med b/resources/LargeInconsistentTetra.med new file mode 100644 index 000000000..50897d2ae Binary files /dev/null and b/resources/LargeInconsistentTetra.med differ diff --git a/resources/LargeUnitTetra.med b/resources/LargeUnitTetra.med new file mode 100644 index 000000000..e910d3faa Binary files /dev/null and b/resources/LargeUnitTetra.med differ diff --git a/resources/MEDCatalog.xml.in b/resources/MEDCatalog.xml.in index 14cc93a22..a7d7e6926 100644 --- a/resources/MEDCatalog.xml.in +++ b/resources/MEDCatalog.xml.in @@ -1,4 +1,27 @@ + @@ -8,15 +31,6 @@ - - - - - - FIELD - - - diff --git a/resources/MED_en.xml b/resources/MED_en.xml index f407f6453..2e0c802ec 100644 --- a/resources/MED_en.xml +++ b/resources/MED_en.xml @@ -1,5 +1,28 @@ + diff --git a/resources/Makefile.am b/resources/Makefile.am index 1ae9cd770..22c0acf10 100644 --- a/resources/Makefile.am +++ b/resources/Makefile.am @@ -1,22 +1,24 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# - +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# include $(top_srcdir)/adm_local/unix/make_common_starter.am # @@ -25,26 +27,42 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am # =============================================================== # -dist_salomeres_DATA=\ +dist_salomeres_DATA = \ + MED.config \ + MED_en.xml \ + SalomeApp.xml \ + ModuleMed.png \ + Data.png \ + Infos.png \ + Structure.png \ + explore_med_file.png \ + field_selection.png \ + mesh_selection.png \ boitenew.cnc \ boitenew.inp \ boitenew.xyz \ + Case1.cnc \ + Case1.inp \ + Case1.xyz \ + cube.cnc \ + cube.inp \ + cube.xyz \ + test3.cnc \ + test3.inp \ + test3.xyz \ + titi.cnc \ + titi.inp \ + titi.xyz \ carre_en_quad4_import22.med \ carre_en_quad4.med \ carre_en_quad4_seg2_import22.med \ carre_en_quad4_seg2.med \ cas_defaut_domaine_fluide.med \ - Case1.cnc \ - Case1.inp \ - Case1.xyz \ ChampsDarcy.med \ - cube.cnc \ cube_hexa8_import22.med \ cube_hexa8.med \ cube_hexa8_quad4_import22.med \ cube_hexa8_quad4.med \ - cube.inp \ - cube.xyz \ darcy_1.1_res.med \ darcy_1.3_resCASTEM.med \ darcy_1.3_resPORFLOW.med \ @@ -54,7 +72,6 @@ dist_salomeres_DATA=\ darcy2_Castem_qua_VF.med \ Darcy3_3D_H_10x10x10_2.med \ Darcy3_3D_H_10x10x10.sauve \ - Data.png \ Deff_fdt_5.8_castem_efmh_diff_conc_dom.med \ Deff_fdt_5.8_castem_vf_diff_conc_dom.med \ dx200_dy1_avec_2couches.sauve \ @@ -83,7 +100,6 @@ dist_salomeres_DATA=\ H_Traces_Se79_COUPLEX1.med \ inclusion_2d_raf.sauve \ inclusion_2d.sauve \ - Infos.png \ mail_ktest1-3-hexa.sauve \ mail_ktest1-3-tetra.sauve \ mail_ktest3-1.sauve \ @@ -110,13 +126,10 @@ dist_salomeres_DATA=\ mail_test1-2-tri.sauve \ mail-test1-4-1.sauve \ mail-test1-4-2.sauve \ - MED.config \ - MED_en.xml \ mesh_import22.med \ mesh.med \ Mistrat_import22.med \ Mistrat.med \ - ModuleMed.png \ Old_ChampsDarcy.med \ Old_darcy_1.1_res.med \ Old_darcy_1.3_resCASTEM.med \ @@ -145,20 +158,71 @@ dist_salomeres_DATA=\ polyedres.med \ polygones.med \ recoll_bord.med \ - SalomeApp.xml \ - Structure.png \ test19.med \ test_2D.med \ - test3.cnc \ - test3.inp \ - test3.xyz \ + trio_2D.med \ TimeStamps_import22.med \ TimeStamps.med \ - titi.cnc \ - titi.inp \ - titi.xyz \ zzzz121b.med \ - zzzz121b_without_tr6.med + zzzz121b_without_tr6.med \ + UnitTetra.med \ + GeneralTetra.med \ + NudgedSimpler.med \ + NudgedTetra.med \ + CornerTetra.med \ + SimpleIncludedTetra.med \ + SimpleIncludingTetra.med \ + trio_2D.med \ + UnitTetraDegenT.med \ + DegenEdgeXY.med \ + DegenFaceXYZ.med \ + DegenTranslatedInPlane.med \ + ComplexIncludedTetra.med \ + ComplexIncludingTetra.med \ + HalfstripOnly.med \ + HalfstripOnly2.med \ + SimpleHalfstripOnly.med \ + GenTetra1.med \ + GenTetra2.med \ + TrickyTetra1.med \ + LargeUnitTetra.med \ + LargeInconsistentTetra.med \ + DividedUnitTetraSimpler.med \ + DividedUnitTetra.med \ + NudgedDividedUnitTetra.med \ + NudgedDividedUnitTetraSimpler.med \ + DividedGenTetra1.med DividedGenTetra2.med \ + Box1.med \ + Box2.med \ + Box3.med \ + Box1Moderate.med \ + Box2Moderate.med \ + BoxModSmall1.med \ + BoxModSmall2.med \ + BoxEvenSmaller1.med \ + TinyBox.med \ + BoxHexa1.med \ + BoxHexa2.med \ + MovedHexaBox1.med \ + MovedHexaBox2.med \ + BoxTetra2.med \ + square1.med \ + square1_split \ + square1_split1.med \ + square1_split2.med \ + square1_split3.med \ + square2.med \ + square2_split \ + square2_split1.med \ + square2_split2.med \ + Pol1.fig Pol2.fig Pol3.fig Pol4.fig \ + blow5_ascii.case \ + blow5_ascii.geo \ + blow5_ascii_cd_displacement \ + blow5_ascii_cd_thickness \ + blow5_ascii_pd_displacement \ + blow5_ascii_pd_thickness + -nodist_salomeres_DATA=MEDCatalog.xml -EXTRA_DIST+= config +# VSR: little trick to avoid putting if MEDCatalog.xml to the distribution archive +nodist_salomeres_SCRIPTS = MEDCatalog.xml diff --git a/resources/ModuleMed.png b/resources/ModuleMed.png index 521a5c78c..21c34275a 100644 Binary files a/resources/ModuleMed.png and b/resources/ModuleMed.png differ diff --git a/resources/MovedHexaBox1.med b/resources/MovedHexaBox1.med new file mode 100644 index 000000000..82e5dcf06 Binary files /dev/null and b/resources/MovedHexaBox1.med differ diff --git a/resources/MovedHexaBox2.med b/resources/MovedHexaBox2.med new file mode 100644 index 000000000..8e4244f4c Binary files /dev/null and b/resources/MovedHexaBox2.med differ diff --git a/resources/NudgedDividedUnitTetra.med b/resources/NudgedDividedUnitTetra.med new file mode 100644 index 000000000..c19006836 Binary files /dev/null and b/resources/NudgedDividedUnitTetra.med differ diff --git a/resources/NudgedDividedUnitTetraSimpler.med b/resources/NudgedDividedUnitTetraSimpler.med new file mode 100644 index 000000000..d71c6e680 Binary files /dev/null and b/resources/NudgedDividedUnitTetraSimpler.med differ diff --git a/resources/NudgedSimpler.med b/resources/NudgedSimpler.med new file mode 100644 index 000000000..8c04f9711 Binary files /dev/null and b/resources/NudgedSimpler.med differ diff --git a/resources/NudgedTetra.med b/resources/NudgedTetra.med new file mode 100644 index 000000000..4ad4cb66e Binary files /dev/null and b/resources/NudgedTetra.med differ diff --git a/resources/Pol1.fig b/resources/Pol1.fig new file mode 100644 index 000000000..cee7eb792 --- /dev/null +++ b/resources/Pol1.fig @@ -0,0 +1,15 @@ +#FIG 3.2 Produced by xfig version 3.2.5-alpha5 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 2700.000 4800.000 3600 6000 4200 4800 3600 3600 +5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 5400.000 1200.000 3600 3600 5400 4200 7200 3600 +5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 5100.000 6300.000 7200 3600 7800 4200 8400 5400 +5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 8400.000 6000.000 8400 5400 7800 6000 8400 6600 +5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 9128.571 9642.857 8400 6600 6600 7800 6000 9600 +5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 2820.000 9120.000 6000 9600 5400 7200 3600 6000 diff --git a/resources/Pol2.fig b/resources/Pol2.fig new file mode 100644 index 000000000..4778e6735 --- /dev/null +++ b/resources/Pol2.fig @@ -0,0 +1,13 @@ +#FIG 3.2 Produced by xfig version 3.2.5-alpha5 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 13000.000 7200.000 6600 9000 6600 5400 8400 2400 +5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 10500.000 -900.000 8400 2400 10800 3000 12600 2400 +5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 16242.857 6471.429 12600 2400 10800 6000 11400 9000 +5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 9000.000 13500.000 6600 9000 9000 8400 11400 9000 diff --git a/resources/Pol3.fig b/resources/Pol3.fig new file mode 100644 index 000000000..4bad14493 --- /dev/null +++ b/resources/Pol3.fig @@ -0,0 +1,11 @@ +#FIG 3.2 Produced by xfig version 3.2.5-alpha5 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 +3000 7200 6600 3600 diff --git a/resources/Pol4.fig b/resources/Pol4.fig new file mode 100644 index 000000000..1c6cd7924 --- /dev/null +++ b/resources/Pol4.fig @@ -0,0 +1,10 @@ +#FIG 3.2 Produced by xfig version 3.2.5-alpha5 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 4800.000 4837.500 4200 7200 4800 2400 5400 7200 diff --git a/resources/SalomeApp.xml b/resources/SalomeApp.xml index bfb313ecc..c6fb634f1 100644 --- a/resources/SalomeApp.xml +++ b/resources/SalomeApp.xml @@ -1,3 +1,26 @@ +
diff --git a/resources/SimpleHalfstripOnly.med b/resources/SimpleHalfstripOnly.med new file mode 100644 index 000000000..b7a6dd719 Binary files /dev/null and b/resources/SimpleHalfstripOnly.med differ diff --git a/resources/SimpleIncludedTetra.med b/resources/SimpleIncludedTetra.med new file mode 100644 index 000000000..127d890d4 Binary files /dev/null and b/resources/SimpleIncludedTetra.med differ diff --git a/resources/SimpleIncludingTetra.med b/resources/SimpleIncludingTetra.med new file mode 100644 index 000000000..e72ef0879 Binary files /dev/null and b/resources/SimpleIncludingTetra.med differ diff --git a/resources/TinyBox.med b/resources/TinyBox.med new file mode 100644 index 000000000..3f76ecd80 Binary files /dev/null and b/resources/TinyBox.med differ diff --git a/resources/TrickyTetra1.med b/resources/TrickyTetra1.med new file mode 100644 index 000000000..32b45916a Binary files /dev/null and b/resources/TrickyTetra1.med differ diff --git a/resources/UnitTetra.med b/resources/UnitTetra.med new file mode 100644 index 000000000..a5f4a1ce4 Binary files /dev/null and b/resources/UnitTetra.med differ diff --git a/resources/UnitTetraDegenT.med b/resources/UnitTetraDegenT.med new file mode 100644 index 000000000..42c660c60 Binary files /dev/null and b/resources/UnitTetraDegenT.med differ diff --git a/resources/blow5_ascii.case b/resources/blow5_ascii.case new file mode 100644 index 000000000..7c73e9f79 --- /dev/null +++ b/resources/blow5_ascii.case @@ -0,0 +1,14 @@ +#EnSight 6 file written by VTK + +FORMAT +type: ensight + +GEOMETRY +model: blow5_ascii.geo + +VARIABLE +vector per node: displacement blow5_ascii_pd_displacement +scalar per node: thickness blow5_ascii_pd_thickness +vector per element: displacement_c blow5_ascii_cd_displacement +scalar per element: thickness_c blow5_ascii_cd_thickness + diff --git a/resources/blow5_ascii.geo b/resources/blow5_ascii.geo new file mode 100644 index 000000000..7c399f7d1 --- /dev/null +++ b/resources/blow5_ascii.geo @@ -0,0 +1,1756 @@ +Unstructured data file written by VTK. +ASCII +node id off +element id off +coordinates + 687 + 5.00000e+00 7.00000e+00 1.00000e+01 + 5.00000e+00 7.00000e+00 1.00000e+01 + 5.00000e+00 8.00000e+00 1.12500e+01 + 5.00000e+00 8.25000e+00 1.10000e+01 + 5.00000e+00 8.00000e+00 1.00000e+01 + 5.00000e+00 7.00000e+00 1.12500e+01 + 5.00000e+00 7.50000e+00 1.30000e+01 + 5.00000e+00 8.00000e+00 1.25000e+01 + 5.00000e+00 7.00000e+00 1.03125e+01 + 5.00000e+00 7.00000e+00 1.06250e+01 + 5.00000e+00 7.00000e+00 1.09375e+01 + 5.00000e+00 7.38766e+00 1.12500e+01 + 5.00000e+00 7.64592e+00 1.12500e+01 + 5.00000e+00 7.80052e+00 1.12500e+01 + 5.00000e+00 7.90878e+00 1.12500e+01 + 5.00000e+00 8.01755e+00 1.11580e+01 + 5.00000e+00 8.07322e+00 1.10732e+01 + 5.00000e+00 8.15798e+00 1.10176e+01 + 5.00000e+00 8.25000e+00 1.01644e+01 + 5.00000e+00 8.25000e+00 1.03763e+01 + 5.00000e+00 8.25000e+00 1.05485e+01 + 5.00000e+00 8.25000e+00 1.06871e+01 + 5.00000e+00 8.25000e+00 1.08026e+01 + 5.00000e+00 8.25000e+00 1.09045e+01 + 5.00000e+00 7.74324e+00 1.00000e+01 + 5.00000e+00 7.41786e+00 1.00000e+01 + 5.00000e+00 7.00000e+00 1.16875e+01 + 5.00000e+00 7.00000e+00 1.21250e+01 + 5.00000e+00 7.00000e+00 1.25625e+01 + 5.00000e+00 7.30926e+00 1.30000e+01 + 5.00000e+00 7.68405e+00 1.29649e+01 + 5.00000e+00 7.85355e+00 1.28536e+01 + 5.00000e+00 7.96489e+00 1.26840e+01 + 5.00000e+00 8.00000e+00 1.23065e+01 + 5.00000e+00 8.00000e+00 1.21233e+01 + 5.00000e+00 8.00000e+00 1.19567e+01 + 5.00000e+00 8.00000e+00 1.18086e+01 + 5.00000e+00 8.00000e+00 1.16771e+01 + 5.00000e+00 8.00000e+00 1.15591e+01 + 5.00000e+00 8.00000e+00 1.14509e+01 + 5.00000e+00 8.00000e+00 1.13489e+01 + 5.00000e+00 7.93205e+00 1.10425e+01 + 5.00000e+00 7.80734e+00 1.10245e+01 + 5.00000e+00 7.67859e+00 1.09900e+01 + 5.00000e+00 7.51824e+00 1.09746e+01 + 5.00000e+00 7.32515e+00 1.09611e+01 + 5.00000e+00 8.01086e+00 1.02002e+01 + 5.00000e+00 8.03769e+00 1.03933e+01 + 5.00000e+00 8.06323e+00 1.05667e+01 + 5.00000e+00 8.09469e+00 1.07162e+01 + 5.00000e+00 8.13242e+00 1.08231e+01 + 5.00000e+00 8.14712e+00 1.09220e+01 + 5.00000e+00 7.39469e+00 1.06822e+01 + 5.00000e+00 7.65901e+00 1.06508e+01 + 5.00000e+00 7.87050e+00 1.06089e+01 + 5.00000e+00 7.93308e+00 1.07880e+01 + 5.00000e+00 7.93412e+00 1.09257e+01 + 5.00000e+00 7.72820e+00 1.08379e+01 + 5.00000e+00 7.82322e+00 1.09294e+01 + 5.00000e+00 7.54704e+00 1.08316e+01 + 5.00000e+00 8.04809e+00 1.09431e+01 + 5.00000e+00 8.03786e+00 1.08514e+01 + 5.00000e+00 7.44218e+00 1.03424e+01 + 5.00000e+00 7.75573e+00 1.02431e+01 + 5.00000e+00 7.82664e+00 1.04299e+01 + 5.00000e+00 7.64261e+00 1.04744e+01 + 5.00000e+00 7.91347e+00 1.11466e+01 + 5.00000e+00 7.79547e+00 1.11360e+01 + 5.00000e+00 7.66053e+00 1.11230e+01 + 5.00000e+00 7.52214e+00 1.11159e+01 + 5.00000e+00 7.44943e+00 1.17066e+01 + 5.00000e+00 7.68075e+00 1.16735e+01 + 5.00000e+00 7.84745e+00 1.16670e+01 + 5.00000e+00 7.40022e+00 1.21904e+01 + 5.00000e+00 7.64784e+00 1.21371e+01 + 5.00000e+00 7.83294e+00 1.21302e+01 + 5.00000e+00 7.85639e+00 1.24875e+01 + 5.00000e+00 7.71852e+00 1.25169e+01 + 5.00000e+00 7.56210e+00 1.25627e+01 + 5.00000e+00 7.35291e+00 1.26213e+01 + 5.00000e+00 7.84497e+00 1.23142e+01 + 5.00000e+00 7.69057e+00 1.23325e+01 + 5.00000e+00 7.55096e+00 1.23619e+01 + 5.00000e+00 7.62604e+00 1.27508e+01 + 5.00000e+00 7.76505e+00 1.26851e+01 + 5.00000e+00 7.86211e+00 1.26189e+01 + 5.00000e+00 7.49298e+00 1.27907e+01 + 5.00000e+00 7.85524e+00 1.18031e+01 + 5.00000e+00 7.83896e+00 1.19463e+01 + 5.00000e+00 7.66770e+00 1.18951e+01 + 5.00000e+00 7.73456e+00 1.17906e+01 + 5.00000e+00 7.80890e+00 1.13764e+01 + 5.00000e+00 7.85382e+00 1.15144e+01 + 5.00000e+00 7.69160e+00 1.15296e+01 + 5.00000e+00 7.67156e+00 1.13874e+01 + 5.00000e+00 7.56029e+00 1.15433e+01 + 5.00000e+00 7.53983e+00 1.13935e+01 + 5.00000e+00 7.90972e+00 1.13537e+01 + 5.00000e+00 7.92118e+00 1.14397e+01 + 5.00000e+00 2.40000e+01 8.00000e+00 + 5.00000e+00 2.40000e+01 9.00000e+00 + 5.00000e+00 1.97500e+01 8.00000e+00 + 5.00000e+00 1.60000e+01 9.00000e+00 + 5.00000e+00 1.60000e+01 1.10000e+01 + 5.00000e+00 1.12500e+01 9.00000e+00 + 5.00000e+00 1.12500e+01 1.10000e+01 + 5.00000e+00 8.25000e+00 9.92300e+00 + 5.00000e+00 0.00000e+00 1.30000e+01 + 5.00000e+00 0.00000e+00 1.00000e+01 + 5.00000e+00 7.00000e+00 1.30000e+01 + 0.00000e+00 8.15430e+00 1.10190e+01 + 0.00000e+00 8.07322e+00 1.10732e+01 + 0.00000e+00 8.01904e+00 1.11543e+01 + 0.00000e+00 8.00000e+00 1.12500e+01 + 2.50000e+00 8.25000e+00 1.10000e+01 + 2.50000e+00 8.15432e+00 1.10190e+01 + 2.50000e+00 8.07324e+00 1.10732e+01 + 2.50000e+00 8.01903e+00 1.11543e+01 + 2.50000e+00 8.00000e+00 1.12500e+01 + 5.00000e+00 8.15434e+00 1.10190e+01 + 5.00000e+00 8.01902e+00 1.11543e+01 + 0.00000e+00 7.96192e+00 1.26914e+01 + 0.00000e+00 7.85355e+00 1.28536e+01 + 0.00000e+00 7.69140e+00 1.29619e+01 + 2.50000e+00 8.00000e+00 1.25000e+01 + 2.50000e+00 7.96192e+00 1.26914e+01 + 2.50000e+00 7.85355e+00 1.28536e+01 + 2.50000e+00 7.69140e+00 1.29619e+01 + 2.50000e+00 7.50000e+00 1.30000e+01 + 5.00000e+00 7.96192e+00 1.26914e+01 + 5.00000e+00 7.69140e+00 1.29619e+01 + 0.00000e+00 2.40000e+01 9.00000e+00 + 0.00000e+00 2.40000e+01 8.00000e+00 + 0.00000e+00 1.60000e+01 9.00000e+00 + 0.00000e+00 1.60000e+01 1.10000e+01 + 0.00000e+00 0.00000e+00 1.00000e+01 + 0.00000e+00 0.00000e+00 1.30000e+01 + 0.00000e+00 8.25000e+00 1.10000e+01 + 0.00000e+00 8.00000e+00 1.25000e+01 + 0.00000e+00 7.50000e+00 1.30000e+01 + 0.00000e+00 2.60000e+01 8.00000e+00 + 7.00000e+00 2.60000e+01 8.00000e+00 + 7.00000e+00 2.40000e+01 8.00000e+00 + 7.00000e+00 1.97500e+01 8.00000e+00 + 7.00000e+00 1.60000e+01 9.00000e+00 + 7.00000e+00 1.12500e+01 9.00000e+00 + 7.00000e+00 8.00000e+00 1.00000e+01 + 7.00000e+00 0.00000e+00 1.00000e+01 + 7.00000e+00-2.00000e+00 1.00000e+01 + 0.00000e+00-2.00000e+00 1.00000e+01 + 0.00000e+00 0.00000e+00-1.10000e+01 + 0.00000e+00 0.00000e+00-8.00000e+00 + 0.00000e+00-2.00000e+00-8.00000e+00 + 5.00000e+00-2.00000e+00-8.00000e+00 + 7.00000e+00-2.00000e+00-8.00000e+00 + 5.00000e+00 0.00000e+00-8.00000e+00 + 5.00000e+00 0.00000e+00-1.10000e+01 + 5.00000e+00 8.00000e+00-1.10000e+01 + 5.00000e+00 8.00000e+00-8.00000e+00 + 7.00000e+00 8.00000e+00-8.00000e+00 + 5.00000e+00 1.12500e+01-1.10000e+01 + 5.00000e+00 1.12500e+01-9.00000e+00 + 7.00000e+00 1.12500e+01-9.00000e+00 + 5.00000e+00 1.60000e+01-1.10000e+01 + 5.00000e+00 1.60000e+01-9.00000e+00 + 7.00000e+00 1.60000e+01-9.00000e+00 + 5.00000e+00 1.97500e+01-1.10000e+01 + 5.00000e+00 1.97500e+01-1.00000e+01 + 7.00000e+00 1.97500e+01-1.00000e+01 + 0.00000e+00 2.40000e+01-1.10000e+01 + 0.00000e+00 2.40000e+01-1.00000e+01 + 5.00000e+00 2.40000e+01-1.00000e+01 + 5.00000e+00 2.40000e+01-1.10000e+01 + 0.00000e+00 2.60000e+01-1.00000e+01 + 5.00000e+00 2.60000e+01-1.00000e+01 + 7.00000e+00 2.60000e+01-1.00000e+01 + 0.00000e+00-1.20000e+01-4.00000e+00 + 0.00000e+00-1.20000e+01 4.00000e+00 + 5.96910e-01-1.20000e+01-3.95521e+00 + 1.23343e+00-1.20000e+01-3.80508e+00 + 1.86684e+00-1.20000e+01-3.53764e+00 + 2.40310e+00-1.20000e+01-3.19767e+00 + 2.82877e+00-1.20000e+01-2.82808e+00 + 3.32044e+00-1.20000e+01-2.23040e+00 + 3.73551e+00-1.20000e+01-1.43038e+00 + 3.93533e+00-1.20000e+01-7.16380e-01 + 3.99986e+00-1.20000e+01 3.33600e-02 + 3.92368e+00-1.20000e+01 7.77650e-01 + 3.70276e+00-1.20000e+01 1.51312e+00 + 3.35693e+00-1.20000e+01 2.17509e+00 + 2.89656e+00-1.20000e+01 2.75861e+00 + 2.35395e+00-1.20000e+01 3.23403e+00 + 1.75721e+00-1.20000e+01 3.59335e+00 + 1.15512e+00-1.20000e+01 3.82958e+00 + 5.60930e-01-1.20000e+01 3.96047e+00 + 0.00000e+00 3.60000e+01 4.00000e+00 + 0.00000e+00-1.07505e+01 4.54992e+00 + 0.00000e+00-8.88054e+00 4.94366e+00 + 0.00000e+00-6.61954e+00 5.20103e+00 + 0.00000e+00-4.42374e+00 5.30706e+00 + 0.00000e+00-8.72624e-01 5.37094e+00 + 0.00000e+00 4.20557e+00 5.34435e+00 + 0.00000e+00 6.63516e+00 5.33259e+00 + 0.00000e+00 9.69823e+00 5.40153e+00 + 0.00000e+00 1.20544e+01 5.20571e+00 + 0.00000e+00 1.44622e+01 5.40358e+00 + 0.00000e+00 1.75762e+01 5.33859e+00 + 0.00000e+00 2.02567e+01 5.35976e+00 + 0.00000e+00 2.49134e+01 5.37083e+00 + 0.00000e+00 2.94209e+01 5.28421e+00 + 0.00000e+00 3.16852e+01 5.10334e+00 + 0.00000e+00 3.36169e+01 4.81160e+00 + 0.00000e+00 3.50774e+01 4.41126e+00 + 0.00000e+00 3.60000e+01-4.00000e+00 + 5.99930e-01 3.60000e+01 3.95476e+00 + 1.23847e+00 3.60000e+01 3.80344e+00 + 1.87132e+00 3.60000e+01 3.53528e+00 + 2.40580e+00 3.60000e+01 3.19564e+00 + 2.82825e+00 3.60000e+01 2.82860e+00 + 3.31559e+00 3.60000e+01 2.23760e+00 + 3.73171e+00 3.60000e+01 1.44025e+00 + 3.93289e+00 3.60000e+01 7.29640e-01 + 3.99999e+00 3.60000e+01 7.29000e-03 + 3.93339e+00 3.60000e+01-7.26930e-01 + 3.73030e+00 3.60000e+01-1.44391e+00 + 3.33354e+00 3.60000e+01-2.21076e+00 + 2.85148e+00 3.60000e+01-2.80519e+00 + 2.28639e+00 3.60000e+01-3.28214e+00 + 1.63682e+00 3.60000e+01-3.64977e+00 + 1.11455e+00 3.60000e+01-3.84158e+00 + 5.64610e-01 3.60000e+01-3.95995e+00 + 0.00000e+00 3.46707e+01-4.56857e+00 + 0.00000e+00 3.25408e+01-5.02108e+00 + 0.00000e+00 2.99486e+01-5.24789e+00 + 0.00000e+00 2.79246e+01-5.31896e+00 + 0.00000e+00 2.48894e+01-5.37712e+00 + 0.00000e+00 2.02404e+01-5.36176e+00 + 0.00000e+00 1.75060e+01-5.33682e+00 + 0.00000e+00 1.43161e+01-5.40468e+00 + 0.00000e+00 1.19693e+01-5.20696e+00 + 0.00000e+00 9.56507e+00-5.40372e+00 + 0.00000e+00 6.45820e+00-5.33925e+00 + 0.00000e+00 3.77241e+00-5.36048e+00 + 0.00000e+00-4.01789e-01-5.37654e+00 + 0.00000e+00-4.91587e+00-5.30795e+00 + 0.00000e+00-7.47861e+00-5.12219e+00 + 0.00000e+00-9.50304e+00-4.83480e+00 + 0.00000e+00-1.10332e+01-4.42749e+00 + 0.00000e+00 2.12943e+00-5.36694e+00 + 0.00000e+00 1.30675e+00-5.37314e+00 + 0.00000e+00 5.53541e-01-5.38462e+00 + 0.00000e+00 2.29078e+00 5.37206e+00 + 0.00000e+00 8.73155e-01 5.38203e+00 + 0.00000e+00-2.14545e-01 5.38049e+00 + 0.00000e+00 2.19376e+01-5.36897e+00 + 0.00000e+00 2.31842e+01-5.38316e+00 + 0.00000e+00 2.42865e+01-5.38335e+00 + 0.00000e+00 2.18916e+01 5.36586e+00 + 0.00000e+00 2.31058e+01 5.38160e+00 + 0.00000e+00 2.41699e+01 5.38169e+00 + 0.00000e+00-2.82274e+00-5.35964e+00 + 0.00000e+00-1.40569e+00-5.37215e+00 + 0.00000e+00-2.67704e+00 5.37577e+00 + 0.00000e+00-1.49138e+00 5.37038e+00 + 0.00000e+00 2.64886e+01-5.36083e+00 + 0.00000e+00 2.54629e+01-5.37544e+00 + 0.00000e+00 2.72589e+01 5.34494e+00 + 0.00000e+00 2.57282e+01 5.37106e+00 + 3.12814e+00 1.19303e+01-4.38305e+00 + 2.56612e+00 7.72124e+00-4.67156e+00 + 1.88259e+00 4.86234e+00-5.01258e+00 + 4.21057e+00 4.80164e+00-3.39406e+00 + 5.43019e+00 4.86815e+00 1.14613e-01 + 5.33366e+00 1.19791e+01 8.91230e-02 + 4.09500e+00 4.83564e+00 3.53052e+00 + 1.78793e+00 4.99655e+00 5.03798e+00 + 2.49007e+00 7.80193e+00 4.70697e+00 + 3.09814e+00 1.20443e+01 4.39886e+00 + 5.43204e+00 1.91176e+01 6.47300e-03 + 4.14819e+00 1.91660e+01-3.47150e+00 + 1.84666e+00 1.91140e+01-5.02728e+00 + 2.56989e+00 1.62207e+01-4.66775e+00 + 2.52331e+00 1.63019e+01 4.69445e+00 + 1.85796e+00 1.91732e+01 5.02124e+00 + 4.16574e+00 1.92457e+01 3.44854e+00 + 1.06930e+00-9.04624e+00-4.80996e+00 + 1.80809e+00-6.42918e+00-4.91267e+00 + 2.51080e+00-9.18698e+00-4.24079e+00 + 3.64418e+00-9.70145e+00-3.11365e+00 + 4.12228e+00-6.55740e+00-3.29319e+00 + 4.60957e+00-9.33609e+00-1.67187e+00 + 4.78160e+00-9.73733e+00 4.12950e-02 + 5.29116e+00-6.57581e+00 4.44060e-02 + 1.38556e+00-4.20010e+00-5.12173e+00 + 4.01755e+00-3.50459e+00-3.48967e+00 + 2.75691e+00-4.00026e+00-4.58152e+00 + 5.31720e+00-3.46431e+00 3.06410e-02 + 5.01721e+00-3.83235e+00-1.86869e+00 + 1.34743e+00 3.04515e+00-5.18385e+00 + 2.69939e+00 2.69600e+00-4.66492e+00 + 4.01257e+00 2.23246e+00-3.55514e+00 + 5.05000e+00 2.51040e+00-1.88642e+00 + 5.35439e+00 2.21304e+00 6.49580e-02 + 4.56510e+00-9.36585e+00 1.77651e+00 + 3.53782e+00-9.72487e+00 3.22108e+00 + 4.02207e+00-6.60331e+00 3.40632e+00 + 2.26167e+00-9.27124e+00 4.37244e+00 + 1.04909e+00-8.36876e+00 4.91169e+00 + 1.89069e+00-6.63802e+00 4.82586e+00 + 3.77466e+00-3.38299e+00 3.77008e+00 + 4.97780e+00-3.81682e+00 1.98509e+00 + 1.07509e+00-4.96956e+00 5.18328e+00 + 2.38742e+00-4.32193e+00 4.78538e+00 + 5.00236e+00 2.50760e+00 2.01175e+00 + 3.93748e+00 2.22141e+00 3.63842e+00 + 2.59701e+00 2.66261e+00 4.72738e+00 + 1.09189e+00 2.93502e+00 5.25909e+00 + 1.32536e+00 2.09435e+01-5.19104e+00 + 3.97669e+00 2.17575e+01-3.59622e+00 + 2.66872e+00 2.13010e+01-4.68347e+00 + 5.35478e+00 2.17726e+01-2.59400e-03 + 5.02852e+00 2.14865e+01-1.94520e+00 + 1.13581e+00 2.83900e+01-5.19389e+00 + 1.77209e+00 3.09741e+01-4.88387e+00 + 2.62066e+00 2.85057e+01-4.64447e+00 + 3.83679e+00 2.75012e+01-3.70167e+00 + 4.06590e+00 3.07767e+01-3.33329e+00 + 4.99760e+00 2.79013e+01-1.92917e+00 + 5.31609e+00 2.75336e+01 2.31430e-02 + 5.28415e+00 3.06831e+01 2.47110e-02 + 1.27045e+00 3.31889e+01-4.71843e+00 + 3.64397e+00 3.37882e+01-3.08036e+00 + 2.55155e+00 3.33617e+01-4.17580e+00 + 4.76855e+00 3.37955e+01 1.28420e-02 + 4.58407e+00 3.34132e+01-1.69074e+00 + 3.98724e+00 2.17904e+01 3.58393e+00 + 5.03103e+00 2.15061e+01 1.93737e+00 + 1.33402e+00 2.09656e+01 5.18710e+00 + 2.67816e+00 2.13314e+01 4.67594e+00 + 4.97477e+00 2.78635e+01 1.99116e+00 + 3.77899e+00 2.74084e+01 3.76384e+00 + 4.02732e+00 3.06741e+01 3.38982e+00 + 2.59818e+00 2.83410e+01 4.66480e+00 + 1.16456e+00 2.81154e+01 5.20110e+00 + 1.72798e+00 3.06777e+01 4.91929e+00 + 3.60995e+00 3.37657e+01 3.13105e+00 + 4.57762e+00 3.33914e+01 1.72317e+00 + 1.05640e+00 3.31571e+01 4.79186e+00 + 2.48702e+00 3.32760e+01 4.23356e+00 + 6.05852e-01-1.05579e+01-4.54306e+00 + 1.40123e+00-1.07979e+01-4.30287e+00 + 2.09171e+00-1.07574e+01-3.99466e+00 + 2.72115e+00-1.09768e+01-3.53000e+00 + 3.36268e+00-1.11238e+01-2.81612e+00 + 3.91614e+00-1.08389e+01-2.20836e+00 + 4.20133e+00-1.08151e+01-1.57490e+00 + 4.38180e+00-1.09831e+01-8.04068e-01 + 4.43606e+00-1.09538e+01 2.47910e-02 + 7.29206e-01-3.46296e+00-5.28707e+00 + 2.48946e+00-2.58008e+00-4.72558e+00 + 1.51050e+00-2.61076e+00-5.15418e+00 + 3.94286e+00-2.31321e+00-3.59030e+00 + 3.27772e+00-2.32612e+00-4.23230e+00 + 4.96756e+00-2.37607e+00-1.93446e+00 + 4.54327e+00-2.23584e+00-2.82697e+00 + 5.32543e+00-2.27666e+00 1.96380e-02 + 5.25665e+00-2.21993e+00-9.78861e-01 + 6.56006e-01 2.31168e+00-5.32870e+00 + 1.39594e+00 1.67028e+00-5.20286e+00 + 2.20758e+00 1.06708e+00-4.90121e+00 + 3.19514e+00 1.18677e+00-4.32105e+00 + 3.90942e+00 9.72268e-01-3.66757e+00 + 4.53827e+00 1.15270e+00-2.86288e+00 + 4.98069e+00 1.02504e+00-1.96597e+00 + 5.27114e+00 1.15611e+00-9.79603e-01 + 5.35194e+00 9.72659e-01 3.40080e-02 + 4.36825e+00-1.09937e+01 8.56820e-01 + 4.14608e+00-1.08630e+01 1.66853e+00 + 3.74147e+00-1.09891e+01 2.41483e+00 + 3.22255e+00-1.09445e+01 3.05384e+00 + 2.62020e+00-1.09651e+01 3.61090e+00 + 1.93963e+00-1.08556e+01 4.03423e+00 + 1.19714e+00-1.10255e+01 4.28504e+00 + 9.19667e-01-9.85039e+00 4.67269e+00 + 4.94205e+00-2.36427e+00 1.99899e+00 + 5.24680e+00-2.21489e+00 1.03097e+00 + 3.86933e+00-2.19924e+00 3.67502e+00 + 4.48264e+00-2.19039e+00 2.92171e+00 + 2.71014e+00-2.71735e+00 4.60775e+00 + 3.32358e+00-2.01028e+00 4.19825e+00 + 1.01082e+00-3.57583e+00 5.25053e+00 + 1.53237e+00-2.43499e+00 5.14802e+00 + 5.25660e+00 1.15441e+00 1.05440e+00 + 4.95384e+00 1.02283e+00 2.03260e+00 + 4.49557e+00 1.14881e+00 2.92906e+00 + 3.86091e+00 9.65425e-01 3.71821e+00 + 3.13857e+00 1.16971e+00 4.36244e+00 + 2.14668e+00 1.00690e+00 4.92672e+00 + 1.34184e+00 1.57166e+00 5.21564e+00 + 7.52024e-01 1.97730e+00 5.32007e+00 + 6.65474e-01 2.16961e+01-5.32991e+00 + 2.18836e+00 2.29431e+01-4.91170e+00 + 1.40084e+00 2.23097e+01-5.20217e+00 + 3.91035e+00 2.30313e+01-3.66832e+00 + 3.17927e+00 2.28147e+01-4.33450e+00 + 4.96809e+00 2.29683e+01-2.00082e+00 + 4.53080e+00 2.28347e+01-2.87614e+00 + 5.35284e+00 2.30255e+01-3.80580e-02 + 5.26134e+00 2.28309e+01-1.03568e+00 + 6.96637e-01 2.69045e+01-5.30281e+00 + 1.72335e+00 2.67025e+01-5.07862e+00 + 2.82516e+00 2.68634e+01-4.53125e+00 + 3.37346e+00 2.60896e+01-4.15840e+00 + 3.91578e+00 2.62737e+01-3.62539e+00 + 4.50763e+00 2.62439e+01-2.88589e+00 + 4.95644e+00 2.64199e+01-1.96442e+00 + 5.25350e+00 2.62565e+01-1.00138e+00 + 5.32549e+00 2.63264e+01 1.56680e-02 + 6.50241e-01 3.39369e+01-4.68958e+00 + 2.17139e+00 3.50393e+01-3.84810e+00 + 1.27928e+00 3.48182e+01-4.33859e+00 + 3.37330e+00 3.51349e+01-2.79526e+00 + 2.89392e+00 3.48925e+01-3.41610e+00 + 4.17745e+00 3.48586e+01-1.59409e+00 + 3.90578e+00 3.48687e+01-2.20255e+00 + 4.42420e+00 3.49859e+01 7.15900e-03 + 4.36911e+00 3.50077e+01-8.17196e-01 + 4.98258e+00 2.29837e+01 1.96248e+00 + 5.27060e+00 2.28383e+01 9.85986e-01 + 3.91310e+00 2.30425e+01 3.66415e+00 + 4.53686e+00 2.28495e+01 2.86491e+00 + 2.21133e+00 2.29494e+01 4.89924e+00 + 3.19427e+00 2.28178e+01 4.32128e+00 + 6.68045e-01 2.16738e+01 5.32650e+00 + 1.40673e+00 2.23003e+01 5.19830e+00 + 5.24892e+00 2.62500e+01 1.02520e+00 + 4.93962e+00 2.64053e+01 2.00481e+00 + 4.47133e+00 2.62200e+01 2.93951e+00 + 3.84432e+00 2.62113e+01 3.70193e+00 + 3.30784e+00 2.60108e+01 4.21111e+00 + 2.78318e+00 2.67658e+01 4.55893e+00 + 1.73285e+00 2.66461e+01 5.07076e+00 + 9.14048e-01 2.68958e+01 5.26216e+00 + 4.17661e+00 3.48488e+01 1.60636e+00 + 4.36837e+00 3.50036e+01 8.29370e-01 + 3.34571e+00 3.51493e+01 2.82176e+00 + 3.89861e+00 3.48616e+01 2.22238e+00 + 2.08870e+00 3.48043e+01 3.97896e+00 + 2.71896e+00 3.50024e+01 3.51989e+00 + 6.06282e-01 3.45988e+01 4.52996e+00 + 1.40499e+00 3.48348e+01 4.28821e+00 + 7.09742e-01-1.62553e+00-5.32844e+00 + 6.07295e-01-7.98883e-01-5.34354e+00 + 1.44117e+00-1.06074e+00-5.17996e+00 + 2.39785e+00-1.57624e+00-4.81726e+00 + 1.42682e+00-2.76890e-01-5.18069e+00 + 1.01892e+00-4.32962e-01-5.27848e+00 + 2.10271e+00-7.70977e-01-4.94082e+00 + 1.81172e+00-4.44315e-01-5.05767e+00 + 3.13601e+00-1.13034e+00-4.35902e+00 + 3.90901e+00-1.33983e+00-3.68763e+00 + 3.02783e+00-4.82615e-01-4.42997e+00 + 2.61739e+00-7.11181e-01-4.68785e+00 + 3.84943e+00-6.21744e-01-3.73095e+00 + 3.50387e+00-5.20317e-01-4.06536e+00 + 4.49184e+00-1.06118e+00-2.92787e+00 + 4.98222e+00-1.32153e+00-2.00215e+00 + 4.43579e+00-4.48849e-01-3.00574e+00 + 4.14104e+00-6.12336e-01-3.40560e+00 + 4.95274e+00-6.09156e-01-2.03576e+00 + 4.74864e+00-4.97686e-01-2.48528e+00 + 5.25433e+00-1.04786e+00-1.04736e+00 + 5.36686e+00-1.30120e+00-3.19200e-03 + 5.23439e+00-4.37531e-01-1.12390e+00 + 5.10525e+00-5.98745e-01-1.62031e+00 + 5.35229e+00-5.99153e-01-2.50620e-02 + 5.33062e+00-4.86771e-01-5.22809e-01 + 4.75351e-01 1.27338e+00-5.35852e+00 + 8.18540e-01 6.45481e-01-5.31724e+00 + 1.46946e+00 6.78295e-01-5.16965e+00 + 1.82670e+00 4.64494e-01-5.04977e+00 + 2.15784e+00 3.69981e-01-4.91532e+00 + 2.69940e+00 4.05772e-01-4.64187e+00 + 3.14102e+00 5.08815e-01-4.34676e+00 + 3.52898e+00 4.32844e-01-4.03951e+00 + 3.87823e+00 4.38032e-01-3.69635e+00 + 4.22195e+00 4.10775e-01-3.30290e+00 + 4.51563e+00 5.04609e-01-2.87889e+00 + 4.76627e+00 4.42281e-01-2.44616e+00 + 4.96797e+00 4.62684e-01-1.98946e+00 + 5.14415e+00 4.29723e-01-1.48952e+00 + 5.26008e+00 5.13311e-01-9.81245e-01 + 5.33178e+00 4.37961e-01-4.80354e-01 + 5.34885e+00 4.47093e-01 2.29030e-02 + 5.26316e+00-1.04475e+00 9.99917e-01 + 4.97823e+00-1.31013e+00 2.01056e+00 + 5.27102e+00-4.35966e-01 9.33591e-01 + 5.33821e+00-5.92400e-01 4.17812e-01 + 4.96796e+00-6.03173e-01 1.99623e+00 + 5.13494e+00-4.87780e-01 1.52577e+00 + 4.50651e+00-1.03884e+00 2.90233e+00 + 3.90126e+00-1.26028e+00 3.69188e+00 + 4.53358e+00-4.37995e-01 2.85302e+00 + 4.78962e+00-5.94228e-01 2.39917e+00 + 3.86905e+00-5.90537e-01 3.70916e+00 + 4.19435e+00-4.82330e-01 3.33970e+00 + 3.16098e+00-1.05125e+00 4.33895e+00 + 2.42499e+00-1.52626e+00 4.79834e+00 + 3.07974e+00-3.87291e-01 4.39327e+00 + 3.55287e+00-5.78355e-01 4.01893e+00 + 2.07628e+00-7.75302e-01 4.94954e+00 + 2.62186e+00-6.68827e-01 4.68348e+00 + 1.38652e+00-1.05558e+00 5.19443e+00 + 6.87181e-01-1.59065e+00 5.32949e+00 + 1.34739e+00-2.93907e-01 5.20086e+00 + 1.75932e+00-4.69529e-01 5.07454e+00 + 4.76201e-01-8.73133e-01 5.35504e+00 + 7.94924e-01-3.66029e-01 5.31901e+00 + 5.32497e+00 4.19956e-01 5.54219e-01 + 5.24268e+00 5.12106e-01 1.06958e+00 + 5.12168e+00 4.46723e-01 1.56256e+00 + 4.94870e+00 4.62816e-01 2.03589e+00 + 4.72924e+00 4.25804e-01 2.51698e+00 + 4.46242e+00 5.04815e-01 2.95982e+00 + 4.16895e+00 4.28147e-01 3.36790e+00 + 3.83804e+00 4.36605e-01 3.73699e+00 + 3.46769e+00 4.29870e-01 4.09115e+00 + 3.07466e+00 5.38206e-01 4.39369e+00 + 2.64283e+00 4.18523e-01 4.67229e+00 + 2.09953e+00 3.15467e-01 4.93979e+00 + 1.76149e+00 3.93494e-01 5.07281e+00 + 1.41363e+00 6.35727e-01 5.18590e+00 + 8.12771e-01 7.26337e-01 5.31955e+00 + 5.84536e-01 1.38745e+00 5.34994e+00 + 5.75681e-01 2.26287e+01-5.34971e+00 + 1.44368e+00 2.33099e+01-5.17877e+00 + 8.22272e-01 2.32571e+01-5.31873e+00 + 2.13446e+00 2.36412e+01-4.92722e+00 + 1.80483e+00 2.35416e+01-5.05941e+00 + 3.12117e+00 2.34913e+01-4.36299e+00 + 2.68749e+00 2.35981e+01-4.65035e+00 + 3.93709e+00 2.36737e+01-3.63835e+00 + 3.52404e+00 2.35974e+01-4.04619e+00 + 4.51564e+00 2.34688e+01-2.88080e+00 + 4.27851e+00 2.35044e+01-3.22795e+00 + 4.95807e+00 2.35367e+01-2.01759e+00 + 4.75953e+00 2.35461e+01-2.46167e+00 + 5.24916e+00 2.34623e+01-1.04428e+00 + 5.13665e+00 2.35613e+01-1.51948e+00 + 5.35089e+00 2.36323e+01-1.10214e-01 + 5.31823e+00 2.34714e+01-6.11602e-01 + 2.87160e-01 2.48606e+01-5.37174e+00 + 7.16728e-01 2.56571e+01-5.33293e+00 + 7.66755e-01 2.45683e+01-5.32574e+00 + 1.39632e+00 2.43026e+01-5.19033e+00 + 1.57901e+00 2.51292e+01-5.13981e+00 + 1.82654e+00 2.44486e+01-5.05282e+00 + 2.15035e+00 2.47855e+01-4.92080e+00 + 2.51345e+00 2.56163e+01-4.75184e+00 + 2.63367e+00 2.47119e+01-4.67881e+00 + 3.02613e+00 2.44941e+01-4.43185e+00 + 3.17559e+00 2.51182e+01-4.33088e+00 + 3.49546e+00 2.45231e+01-4.07331e+00 + 3.83728e+00 2.46364e+01-3.74465e+00 + 3.90839e+00 2.53159e+01-3.68710e+00 + 4.11655e+00 2.46111e+01-3.43692e+00 + 4.41802e+00 2.44359e+01-3.03455e+00 + 4.47840e+00 2.50696e+01-2.94987e+00 + 4.74307e+00 2.44878e+01-2.49893e+00 + 4.95168e+00 2.46085e+01-2.04203e+00 + 4.97315e+00 2.53402e+01-2.02802e+00 + 5.10225e+00 2.46026e+01-1.63469e+00 + 5.23239e+00 2.44452e+01-1.13889e+00 + 5.25239e+00 2.50717e+01-1.06362e+00 + 5.33293e+00 2.44832e+01-5.13041e-01 + 5.35382e+00 2.46190e+01-3.75600e-03 + 5.36802e+00 2.53291e+01-1.22140e-02 + 5.25738e+00 2.34690e+01 1.00144e+00 + 5.33089e+00 2.35982e+01 5.11322e-01 + 4.99877e+00 2.36208e+01 1.91655e+00 + 5.15977e+00 2.34654e+01 1.42952e+00 + 4.51885e+00 2.34781e+01 2.87433e+00 + 4.76426e+00 2.35791e+01 2.45125e+00 + 3.93608e+00 2.36713e+01 3.63781e+00 + 4.28122e+00 2.35041e+01 3.22266e+00 + 3.12587e+00 2.34463e+01 4.35868e+00 + 3.50223e+00 2.35925e+01 4.06335e+00 + 2.21544e+00 2.37220e+01 4.89110e+00 + 2.75279e+00 2.34664e+01 4.60798e+00 + 1.44767e+00 2.32899e+01 5.17654e+00 + 1.81405e+00 2.35695e+01 5.05567e+00 + 5.77726e-01 2.25744e+01 5.34721e+00 + 8.33189e-01 2.31935e+01 5.31588e+00 + 5.33868e+00 2.46157e+01 4.27399e-01 + 5.27315e+00 2.44513e+01 9.27590e-01 + 5.26521e+00 2.50741e+01 9.94584e-01 + 5.13153e+00 2.44858e+01 1.54211e+00 + 4.95070e+00 2.46020e+01 2.04264e+00 + 4.97190e+00 2.53219e+01 2.03039e+00 + 4.73171e+00 2.45003e+01 2.51714e+00 + 4.41281e+00 2.44171e+01 3.04008e+00 + 4.45803e+00 2.50495e+01 2.97844e+00 + 4.09643e+00 2.45874e+01 3.45911e+00 + 3.81433e+00 2.46498e+01 3.76730e+00 + 3.86902e+00 2.52895e+01 3.72679e+00 + 3.51575e+00 2.46037e+01 4.05332e+00 + 3.05753e+00 2.43631e+01 4.41084e+00 + 3.14398e+00 2.50570e+01 4.35309e+00 + 2.58009e+00 2.46492e+01 4.70793e+00 + 2.05548e+00 2.47904e+01 4.96075e+00 + 2.45655e+00 2.55690e+01 4.78090e+00 + 1.73608e+00 2.44963e+01 5.08423e+00 + 1.34892e+00 2.42663e+01 5.20138e+00 + 1.42462e+00 2.51103e+01 5.18755e+00 + 8.03648e-01 2.43309e+01 5.31906e+00 + 4.98434e-01 2.49122e+01 5.35358e+00 + 7.69399e-01 2.59653e+01 5.31944e+00 + 5.87260e-01-9.66460e-02-5.34688e+00 + 1.13753e+00 1.13629e-01-5.25502e+00 + 1.53515e+00 2.01736e-01-5.14849e+00 + 1.84020e+00 2.87670e-02-5.04764e+00 + 2.28732e+00-1.83687e-01-4.86080e+00 + 2.76183e+00-1.88945e-01-4.60188e+00 + 3.17707e+00 1.78390e-02-4.32695e+00 + 3.52042e+00-3.30790e-02-4.04506e+00 + 3.87475e+00-8.06620e-02-3.71218e+00 + 4.24978e+00-1.40150e-01-3.26594e+00 + 4.54286e+00 3.54380e-02-2.84565e+00 + 4.76105e+00-1.74210e-02-2.45245e+00 + 4.97041e+00-6.43620e-02-2.00632e+00 + 5.15685e+00-1.25810e-01-1.44196e+00 + 5.27378e+00 4.50150e-02-9.36476e-01 + 5.32998e+00-1.27890e-02-4.85242e-01 + 5.35749e+00-6.39980e-02 9.10100e-03 + 5.31889e+00-1.26200e-01 6.06494e-01 + 5.23774e+00 4.48330e-02 1.12005e+00 + 5.12027e+00-1.06980e-02 1.56092e+00 + 4.96076e+00-6.11310e-02 2.02840e+00 + 4.70111e+00-1.26612e-01 2.56724e+00 + 4.43663e+00 4.08710e-02 3.00797e+00 + 4.16560e+00-1.75760e-02 3.36953e+00 + 3.84754e+00-6.21610e-02 3.73896e+00 + 3.40700e+00-9.36350e-02 4.14217e+00 + 3.07115e+00 1.34381e-01 4.40028e+00 + 2.73425e+00-1.35288e-01 4.61690e+00 + 2.24711e+00-1.94962e-01 4.87789e+00 + 1.77582e+00-2.29760e-02 5.06960e+00 + 1.46682e+00 1.63590e-01 5.16784e+00 + 1.06034e+00 1.67286e-01 5.27102e+00 + 5.35296e-01 1.78737e-01 5.35325e+00 + 5.22020e-01 2.38819e+01-5.35633e+00 + 1.07089e+00 2.38596e+01-5.27051e+00 + 1.50189e+00 2.37978e+01-5.15948e+00 + 1.82333e+00 2.39787e+01-5.05511e+00 + 2.28910e+00 2.41913e+01-4.86083e+00 + 2.75933e+00 2.41955e+01-4.60436e+00 + 3.16816e+00 2.39910e+01-4.33485e+00 + 3.50093e+00 2.40655e+01-4.06371e+00 + 3.81027e+00 2.41680e+01-3.77805e+00 + 4.19288e+00 2.40572e+01-3.34289e+00 + 4.53730e+00 2.39308e+01-2.85659e+00 + 4.75559e+00 2.40033e+01-2.46591e+00 + 4.96515e+00 2.40598e+01-2.02298e+00 + 5.15254e+00 2.41239e+01-1.46340e+00 + 5.27024e+00 2.39249e+01-9.66448e-01 + 5.33704e+00 2.39263e+01-4.30411e-01 + 5.35738e+00 2.41461e+01 6.77110e-02 + 5.32061e+00 2.41532e+01 6.04186e-01 + 5.24531e+00 2.39355e+01 1.09226e+00 + 5.10497e+00 2.39235e+01 1.61707e+00 + 4.93377e+00 2.41102e+01 2.09236e+00 + 4.74308e+00 2.40353e+01 2.48822e+00 + 4.53443e+00 2.39352e+01 2.85925e+00 + 4.18906e+00 2.40454e+01 3.34629e+00 + 3.79087e+00 2.41857e+01 3.79702e+00 + 3.39472e+00 2.41213e+01 4.15412e+00 + 3.08771e+00 2.38320e+01 4.39048e+00 + 2.64906e+00 2.40457e+01 4.66981e+00 + 2.17026e+00 2.42918e+01 4.91322e+00 + 1.79012e+00 2.40309e+01 5.06611e+00 + 1.48884e+00 2.37954e+01 5.16266e+00 + 1.07554e+00 2.37768e+01 5.26869e+00 + 5.44199e-01 2.37664e+01 5.35275e+00 + 4.99103e+00 8.28431e+00-1.96086e+00 + 4.93386e+00 8.30510e+00 2.09914e+00 + 4.97754e+00 1.56707e+01-1.99783e+00 + 4.95406e+00 1.57236e+01 2.05648e+00 +part 1 +another part +quad4 + 129 + 59 43 42 57 + 58 59 57 56 + 58 44 43 59 + 54 58 56 55 + 60 45 44 58 + 53 60 58 54 + 53 46 45 60 + 10 11 46 53 + 62 61 52 51 + 56 62 51 50 + 56 57 61 62 + 55 56 50 49 + 57 42 17 61 + 61 17 18 52 + 63 53 54 66 + 66 54 55 65 + 63 66 65 64 + 65 55 49 48 + 64 65 48 47 + 9 10 53 63 + 25 64 47 5 + 26 63 64 25 + 2 9 63 26 + 49 50 22 21 + 50 51 23 22 + 51 52 24 23 + 48 49 21 20 + 52 18 4 24 + 5 47 19 107 + 47 48 20 19 + 42 67 16 17 + 67 15 3 16 + 44 69 68 43 + 69 13 14 68 + 46 12 70 45 + 70 12 13 69 + 45 70 69 44 + 68 14 15 67 + 43 68 67 42 + 11 6 12 46 + 83 79 78 82 + 74 83 82 75 + 74 80 79 83 + 28 29 80 74 + 82 78 77 81 + 75 82 81 76 + 81 77 8 34 + 76 81 34 35 + 84 31 32 85 + 79 84 85 78 + 77 86 33 8 + 78 85 86 77 + 85 32 33 86 + 87 7 31 84 + 80 87 84 79 + 80 30 7 87 + 29 110 30 80 + 90 75 76 89 + 91 90 89 88 + 72 91 88 73 + 71 90 91 72 + 71 74 75 90 + 27 28 74 71 + 89 76 35 36 + 88 89 36 37 + 73 88 37 38 + 13 95 92 14 + 95 94 93 92 + 94 72 73 93 + 97 96 94 95 + 12 97 95 13 + 12 71 96 97 + 96 71 72 94 + 6 27 71 12 + 98 99 40 41 + 92 93 99 98 + 99 93 39 40 + 93 73 38 39 + 15 98 41 3 + 14 92 98 15 + 103 101 100 102 + 105 106 104 103 + 109 108 110 2 + 107 4 106 105 + 138 111 116 115 + 111 112 117 116 + 112 113 118 117 + 113 114 119 118 + 115 116 120 4 + 116 117 17 120 + 117 118 121 17 + 118 119 3 121 + 139 122 126 125 + 122 123 127 126 + 123 124 128 127 + 124 140 129 128 + 125 126 130 8 + 126 127 32 130 + 127 128 131 32 + 128 129 7 131 + 132 101 100 133 + 134 103 101 132 + 135 104 103 134 + 138 4 104 135 + 139 8 3 114 + 137 108 7 140 + 137 108 109 136 + 133 143 142 141 + 102 144 143 100 + 103 145 144 102 + 105 146 145 103 + 5 147 146 105 + 109 148 147 5 + 150 149 148 136 + 151 152 156 157 + 152 153 154 156 + 154 155 160 159 + 157 156 159 158 + 158 159 162 161 + 159 160 163 162 + 161 162 165 164 + 162 163 166 165 + 164 165 168 167 + 165 166 169 168 + 167 168 172 173 + 168 169 176 175 + 174 171 172 175 + 170 171 172 173 + 151 157 173 170 +tria3 + 928 + 270 271 272 + 684 270 272 + 684 272 273 + 685 684 273 + 684 274 269 + 684 269 270 + 275 276 277 + 685 275 277 + 685 277 278 + 685 278 274 + 684 685 274 + 685 273 275 + 280 281 282 + 686 280 282 + 686 282 269 + 686 269 274 + 687 686 274 + 686 279 280 + 283 284 285 + 687 283 285 + 687 285 279 + 686 687 279 + 687 274 278 + 687 278 283 + 246 247 286 + 286 287 246 + 288 289 290 + 287 286 288 + 288 290 287 + 291 292 293 + 290 289 291 + 291 293 290 + 245 246 287 + 287 294 245 + 296 294 287 + 290 295 296 + 296 287 290 + 298 295 290 + 293 297 298 + 298 290 293 + 243 299 271 + 271 242 243 + 300 301 272 + 271 299 300 + 300 272 271 + 302 303 273 + 272 301 302 + 302 273 272 + 242 271 270 + 270 241 242 + 269 241 270 + 241 269 240 + 304 305 306 + 293 292 304 + 304 306 293 + 307 308 309 + 306 305 307 + 307 309 306 + 199 309 308 + 308 198 199 + 311 297 293 + 306 310 311 + 311 293 306 + 313 310 306 + 309 312 313 + 313 306 309 + 199 200 312 + 312 309 199 + 314 315 275 + 273 303 314 + 314 275 273 + 316 317 276 + 275 315 316 + 316 276 275 + 202 203 276 + 276 317 202 + 203 204 277 + 277 276 203 + 204 278 277 + 278 204 205 + 239 269 282 + 269 239 240 + 238 239 282 + 282 281 238 + 237 238 281 + 281 318 237 + 320 318 281 + 280 319 320 + 320 281 280 + 322 319 280 + 279 321 322 + 322 280 279 + 234 235 323 + 323 324 234 + 325 326 327 + 324 323 325 + 325 327 324 + 328 329 330 + 327 326 328 + 328 330 327 + 233 234 324 + 324 331 233 + 333 331 324 + 327 332 333 + 333 324 327 + 335 332 327 + 330 334 335 + 335 327 330 + 278 206 283 + 206 278 205 + 207 284 283 + 283 206 207 + 337 321 279 + 285 336 337 + 337 279 285 + 339 336 285 + 284 338 339 + 339 285 284 + 208 338 284 + 284 207 208 + 340 341 342 + 330 329 340 + 340 342 330 + 343 344 345 + 342 341 343 + 343 345 342 + 210 211 345 + 345 344 210 + 347 334 330 + 342 346 347 + 347 330 342 + 349 346 342 + 345 348 349 + 349 342 345 + 211 212 348 + 348 345 211 + 247 248 350 + 350 286 247 + 351 352 288 + 286 350 351 + 351 288 286 + 353 354 289 + 288 352 353 + 353 289 288 + 355 356 291 + 289 354 355 + 355 291 289 + 357 358 292 + 291 356 357 + 357 292 291 + 245 294 359 + 359 261 245 + 361 359 294 + 296 360 361 + 361 294 296 + 363 360 296 + 295 362 363 + 363 296 295 + 365 362 295 + 298 364 365 + 365 295 298 + 367 364 298 + 297 366 367 + 367 298 297 + 243 249 368 + 368 299 243 + 369 370 300 + 299 368 369 + 369 300 299 + 371 372 301 + 300 370 371 + 371 301 300 + 373 374 302 + 301 372 373 + 373 302 301 + 375 376 303 + 302 374 375 + 375 303 302 + 377 378 304 + 292 358 377 + 377 304 292 + 379 380 305 + 304 378 379 + 379 305 304 + 381 382 307 + 305 380 381 + 381 307 305 + 307 384 308 + 307 382 383 + 384 307 383 + 198 308 384 + 384 197 198 + 386 366 297 + 311 385 386 + 386 297 311 + 388 385 311 + 310 387 388 + 388 311 310 + 390 387 310 + 310 389 390 + 389 310 313 + 392 389 313 + 313 391 392 + 391 313 312 + 200 263 391 + 391 312 200 + 393 394 314 + 303 376 393 + 393 314 303 + 395 396 315 + 314 394 395 + 395 315 314 + 397 398 316 + 315 396 397 + 397 316 315 + 399 400 317 + 316 398 399 + 399 317 316 + 252 202 317 + 317 400 252 + 237 318 401 + 401 255 237 + 403 401 318 + 320 402 403 + 403 318 320 + 405 402 320 + 319 404 405 + 405 320 319 + 407 404 319 + 322 406 407 + 407 319 322 + 409 406 322 + 321 408 409 + 409 322 321 + 235 265 410 + 410 323 235 + 411 412 325 + 323 410 411 + 411 325 323 + 413 414 326 + 326 412 413 + 412 326 325 + 415 416 328 + 326 414 415 + 415 328 326 + 417 418 329 + 328 416 417 + 417 329 328 + 233 331 419 + 419 232 233 + 421 419 331 + 333 420 421 + 421 331 333 + 423 420 333 + 332 422 423 + 423 333 332 + 425 422 332 + 335 424 425 + 425 332 335 + 427 424 335 + 334 426 427 + 427 335 334 + 429 408 321 + 337 428 429 + 429 321 337 + 431 428 337 + 336 430 431 + 431 337 336 + 433 430 336 + 339 432 433 + 433 336 339 + 435 432 339 + 338 434 435 + 435 339 338 + 208 258 434 + 434 338 208 + 436 437 340 + 329 418 436 + 436 340 329 + 438 439 341 + 340 437 438 + 438 341 340 + 341 441 343 + 341 439 440 + 441 341 440 + 442 443 344 + 343 441 442 + 442 344 343 + 267 210 344 + 344 443 267 + 445 426 334 + 347 444 445 + 445 334 347 + 447 444 347 + 346 446 447 + 447 347 346 + 449 446 346 + 349 448 449 + 449 346 349 + 451 448 349 + 348 450 451 + 451 349 348 + 212 213 450 + 450 348 212 + 179 350 248 + 248 177 179 + 179 180 351 + 351 350 179 + 181 352 351 + 351 180 181 + 181 182 353 + 353 352 181 + 183 354 353 + 353 182 183 + 354 184 355 + 184 354 183 + 185 356 355 + 355 184 185 + 185 186 357 + 357 356 185 + 187 358 357 + 357 186 187 + 361 261 359 + 452 262 261 + 262 452 453 + 453 244 262 + 361 454 452 + 261 361 452 + 361 360 455 + 455 454 361 + 454 453 452 + 454 456 457 + 453 454 457 + 459 456 454 + 454 458 459 + 458 454 455 + 363 460 455 + 455 360 363 + 363 362 461 + 461 460 363 + 463 458 455 + 460 462 463 + 463 455 460 + 465 462 460 + 461 464 465 + 465 460 461 + 365 466 461 + 461 362 365 + 365 364 467 + 467 466 365 + 469 464 461 + 466 468 469 + 469 461 466 + 471 468 466 + 467 470 471 + 471 466 467 + 367 472 467 + 467 364 367 + 367 366 473 + 473 472 367 + 475 470 467 + 472 474 475 + 475 467 472 + 477 474 472 + 473 476 477 + 477 472 473 + 249 250 478 + 478 368 249 + 479 480 369 + 369 478 479 + 478 369 368 + 481 482 370 + 370 480 481 + 480 370 369 + 483 484 371 + 370 482 483 + 483 371 370 + 485 486 372 + 371 484 485 + 485 372 371 + 487 488 373 + 372 486 487 + 487 373 372 + 489 490 374 + 373 488 489 + 489 374 373 + 491 492 375 + 374 490 491 + 491 375 374 + 493 494 376 + 375 492 493 + 493 376 375 + 187 188 377 + 377 358 187 + 189 378 377 + 377 188 189 + 189 190 379 + 379 378 189 + 191 380 379 + 379 190 191 + 191 192 381 + 381 380 191 + 193 382 381 + 381 192 193 + 193 194 383 + 383 382 193 + 197 383 195 + 383 194 195 + 195 178 197 + 383 197 384 + 386 495 473 + 473 366 386 + 386 385 496 + 496 495 386 + 498 476 473 + 495 497 498 + 498 473 495 + 500 497 495 + 496 499 500 + 500 495 496 + 388 501 496 + 496 385 388 + 388 387 502 + 502 501 388 + 504 499 496 + 501 503 504 + 504 496 501 + 506 503 501 + 502 505 506 + 506 501 502 + 390 507 502 + 502 387 390 + 390 389 508 + 508 507 390 + 510 505 502 + 507 509 510 + 510 502 507 + 512 509 507 + 508 511 512 + 512 507 508 + 392 513 508 + 508 389 392 + 263 392 391 + 514 513 392 + 513 511 508 + 513 515 516 + 511 513 516 + 518 515 513 + 513 517 518 + 517 513 514 + 263 264 514 + 392 263 514 + 264 201 517 + 517 514 264 + 519 520 393 + 376 494 519 + 519 393 376 + 521 522 394 + 393 520 521 + 521 394 393 + 523 524 395 + 394 522 523 + 523 395 394 + 525 526 396 + 395 524 525 + 525 396 395 + 527 528 397 + 396 526 527 + 527 397 396 + 529 530 398 + 397 528 529 + 529 398 397 + 398 532 399 + 398 530 531 + 532 398 531 + 399 534 400 + 399 532 533 + 534 399 533 + 252 400 534 + 534 253 252 + 255 401 535 + 535 256 255 + 403 535 401 + 403 536 537 + 535 403 537 + 402 536 403 + 402 538 539 + 536 402 539 + 541 538 402 + 405 540 541 + 541 402 405 + 543 540 405 + 404 542 543 + 543 405 404 + 545 542 404 + 407 544 545 + 545 404 407 + 547 544 407 + 406 546 547 + 547 407 406 + 549 546 406 + 409 548 549 + 549 406 409 + 551 548 409 + 408 550 551 + 551 409 408 + 266 236 552 + 552 553 266 + 265 266 553 + 553 410 265 + 554 555 556 + 553 552 554 + 554 556 553 + 556 558 559 + 556 555 557 + 558 556 557 + 411 410 553 + 553 556 411 + 411 556 559 + 559 412 411 + 560 561 562 + 559 558 560 + 560 562 559 + 563 564 565 + 562 561 563 + 563 565 562 + 413 412 559 + 559 562 413 + 413 562 565 + 565 414 413 + 566 567 568 + 565 564 566 + 566 568 565 + 569 570 571 + 568 567 569 + 569 571 568 + 415 414 565 + 565 568 415 + 415 568 571 + 571 416 415 + 572 573 574 + 571 570 572 + 572 574 571 + 575 576 577 + 574 573 575 + 575 577 574 + 417 416 571 + 571 574 417 + 417 574 577 + 577 418 417 + 231 214 232 + 421 232 419 + 232 421 231 + 421 230 231 + 229 230 421 + 421 420 229 + 228 420 423 + 420 228 229 + 227 228 423 + 423 422 227 + 226 422 425 + 422 226 227 + 225 226 425 + 425 424 225 + 225 424 427 + 427 224 225 + 223 224 427 + 427 426 223 + 579 550 408 + 429 578 579 + 579 408 429 + 581 578 429 + 428 580 581 + 581 429 428 + 583 580 428 + 431 582 583 + 583 428 431 + 585 582 431 + 430 584 585 + 585 431 430 + 587 584 430 + 433 586 587 + 587 430 433 + 589 586 433 + 432 588 589 + 589 433 432 + 591 588 432 + 432 590 591 + 590 432 435 + 593 590 435 + 435 592 593 + 592 435 434 + 258 259 592 + 592 434 258 + 594 595 596 + 577 576 594 + 594 596 577 + 597 598 599 + 596 595 597 + 597 599 596 + 436 418 577 + 577 596 436 + 436 596 599 + 599 437 436 + 600 601 602 + 599 598 600 + 600 602 599 + 603 604 605 + 602 601 603 + 603 605 602 + 438 437 599 + 599 602 438 + 438 602 605 + 605 439 438 + 606 607 608 + 605 604 606 + 606 608 605 + 609 610 611 + 608 607 609 + 609 611 608 + 440 439 605 + 605 608 440 + 440 608 611 + 611 441 440 + 612 613 614 + 614 610 612 + 610 614 611 + 614 616 617 + 614 613 615 + 616 614 615 + 442 441 611 + 611 614 442 + 442 614 617 + 617 443 442 + 268 617 616 + 616 209 268 + 267 443 617 + 617 268 267 + 223 426 445 + 445 222 223 + 221 222 445 + 445 444 221 + 221 444 447 + 447 220 221 + 446 220 447 + 220 446 219 + 219 446 449 + 449 218 219 + 217 218 449 + 449 448 217 + 217 448 451 + 451 216 217 + 215 216 451 + 451 450 215 + 213 196 215 + 215 450 213 + 244 453 618 + 618 251 244 + 479 251 618 + 478 250 251 + 457 619 618 + 618 453 457 + 619 456 620 + 456 619 457 + 251 479 478 + 618 619 479 + 480 619 620 + 619 480 479 + 456 621 620 + 621 456 459 + 459 458 622 + 622 621 459 + 481 480 620 + 620 621 481 + 482 621 622 + 621 482 481 + 463 623 622 + 622 458 463 + 623 462 624 + 462 623 463 + 483 482 622 + 622 623 483 + 483 623 624 + 624 484 483 + 465 625 624 + 624 462 465 + 465 464 626 + 626 625 465 + 485 484 624 + 624 625 485 + 485 625 626 + 626 486 485 + 469 627 626 + 626 464 469 + 627 468 628 + 468 627 469 + 487 486 626 + 626 627 487 + 487 627 628 + 628 488 487 + 471 629 628 + 628 468 471 + 471 470 630 + 630 629 471 + 489 488 628 + 628 629 489 + 489 629 630 + 630 490 489 + 475 631 630 + 630 470 475 + 631 474 632 + 474 631 475 + 491 490 630 + 630 631 491 + 491 631 632 + 632 492 491 + 477 633 632 + 632 474 477 + 477 476 634 + 634 633 477 + 493 492 632 + 632 633 493 + 493 633 634 + 634 494 493 + 498 635 634 + 634 476 498 + 635 497 636 + 497 635 498 + 519 494 634 + 634 635 519 + 519 635 636 + 636 520 519 + 500 637 636 + 636 497 500 + 500 499 638 + 638 637 500 + 521 520 636 + 636 637 521 + 521 637 638 + 638 522 521 + 504 639 638 + 638 499 504 + 639 503 640 + 503 639 504 + 523 522 638 + 638 639 523 + 523 639 640 + 640 524 523 + 506 641 640 + 640 503 506 + 506 505 642 + 642 641 506 + 525 524 640 + 640 641 525 + 525 641 642 + 642 526 525 + 510 643 642 + 642 505 510 + 643 509 644 + 509 643 510 + 527 526 642 + 642 643 527 + 527 643 644 + 644 528 527 + 509 645 644 + 645 509 512 + 512 511 646 + 646 645 512 + 529 528 644 + 644 645 529 + 529 645 646 + 646 530 529 + 516 647 646 + 646 511 516 + 647 515 648 + 515 647 516 + 647 530 646 + 530 647 531 + 531 647 648 + 648 532 531 + 515 649 648 + 649 515 518 + 254 518 517 + 650 649 518 + 649 532 648 + 532 649 533 + 533 649 650 + 253 533 650 + 518 254 650 + 517 201 254 + 533 253 534 + 650 254 253 + 537 256 535 + 651 257 256 + 554 257 651 + 552 236 257 + 537 652 651 + 256 537 651 + 652 536 653 + 536 652 537 + 257 554 552 + 651 652 554 + 555 652 653 + 652 555 554 + 539 654 653 + 653 536 539 + 654 538 655 + 538 654 539 + 654 555 653 + 555 654 557 + 557 654 655 + 655 558 557 + 541 656 655 + 655 538 541 + 541 540 657 + 657 656 541 + 560 558 655 + 655 656 560 + 561 656 657 + 656 561 560 + 543 658 657 + 657 540 543 + 543 542 659 + 659 658 543 + 563 561 657 + 657 658 563 + 563 658 659 + 659 564 563 + 542 660 659 + 660 542 545 + 545 544 661 + 661 660 545 + 566 564 659 + 659 660 566 + 567 660 661 + 660 567 566 + 547 662 661 + 661 544 547 + 547 546 663 + 663 662 547 + 569 567 661 + 661 662 569 + 569 662 663 + 663 570 569 + 549 664 663 + 663 546 549 + 549 548 665 + 665 664 549 + 572 570 663 + 663 664 572 + 573 664 665 + 664 573 572 + 551 666 665 + 665 548 551 + 666 550 667 + 550 666 551 + 575 573 665 + 665 666 575 + 575 666 667 + 667 576 575 + 579 668 667 + 667 550 579 + 579 578 669 + 669 668 579 + 594 576 667 + 667 668 594 + 595 668 669 + 668 595 594 + 581 670 669 + 669 578 581 + 670 580 671 + 580 670 581 + 597 595 669 + 669 670 597 + 597 670 671 + 671 598 597 + 583 672 671 + 671 580 583 + 583 582 673 + 673 672 583 + 600 598 671 + 671 672 600 + 600 672 673 + 673 601 600 + 585 674 673 + 673 582 585 + 674 584 675 + 584 674 585 + 674 601 673 + 601 674 603 + 603 674 675 + 675 604 603 + 587 676 675 + 675 584 587 + 587 586 677 + 677 676 587 + 606 604 675 + 675 676 606 + 607 676 677 + 676 607 606 + 589 678 677 + 677 586 589 + 678 588 679 + 588 678 589 + 678 607 677 + 607 678 609 + 609 678 679 + 679 610 609 + 588 680 679 + 680 588 591 + 591 590 681 + 681 680 591 + 612 610 679 + 679 680 612 + 613 680 681 + 680 613 612 + 590 682 681 + 682 590 593 + 259 593 592 + 683 682 593 + 682 613 681 + 613 682 615 + 615 682 683 + 260 615 683 + 259 260 683 + 593 259 683 + 260 209 616 + 615 260 616 diff --git a/resources/blow5_ascii_cd_displacement b/resources/blow5_ascii_cd_displacement new file mode 100644 index 000000000..a2e399e8a --- /dev/null +++ b/resources/blow5_ascii_cd_displacement @@ -0,0 +1,533 @@ +displacement +part 1 +quad4 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 +tria3 + 7.49973e-01 5.16383e-02-1.09664e+00 1.01029e+00 4.36397e-02-8.38765e-01 + 1.27113e+00 4.62967e-02-4.43042e-01 1.32101e+00 3.87537e-02 1.79620e-02 + 1.15128e+00 1.13253e-02-5.23928e-01 9.22706e-01 2.55373e-02-9.15584e-01 + 7.27295e-01 5.11807e-02 1.10840e+00 9.91572e-01 4.35223e-02 8.59891e-01 + 9.09691e-01 2.45447e-02 9.26870e-01 1.14421e+00 1.06527e-02 5.43048e-01 + 1.28875e+00 2.18847e-02 1.38953e-02 1.25836e+00 4.64993e-02 4.80135e-01 + 7.42599e-01-5.08397e-02-1.10393e+00 1.00490e+00-4.28500e-02-8.47374e-01 + 9.21906e-01-2.40267e-02-9.17864e-01 1.15060e+00-1.00800e-02-5.26727e-01 + 1.28990e+00-2.16967e-02 8.37968e-03 1.26615e+00-4.60100e-02-4.60577e-01 + 7.41561e-01-5.27400e-02 1.10304e+00 1.00179e+00-4.47637e-02 8.51149e-01 + 1.26596e+00-4.72133e-02 4.62834e-01 1.32246e+00-3.88033e-02 4.03968e-03 + 1.14605e+00-1.15233e-02 5.40331e-01 9.14439e-01-2.61803e-02 9.24306e-01 + 6.67223e-02 1.04800e-02-9.54170e-01 2.15243e-01 1.98453e-02-1.05986e+00 + 6.95377e-01 1.09970e-02-6.98273e-01 3.73157e-01 1.46500e-02-9.51916e-01 + 6.43436e-01 2.16557e-02-9.09821e-01 9.74373e-01 8.73300e-03-9.61033e-02 + 8.20820e-01 9.91567e-03-5.34091e-01 1.05079e+00 2.12823e-02-3.58001e-01 + 1.48521e-01 2.61690e-02-1.19400e+00 2.64048e-01 2.77903e-02-1.23961e+00 + 4.98166e-01 3.02363e-02-1.18680e+00 9.05070e-01 3.31257e-02-9.30186e-01 + 7.19641e-01 2.96753e-02-1.02687e+00 1.09450e+00 3.41610e-02-7.02848e-01 + 1.29307e+00 3.46693e-02-1.49068e-01 1.19099e+00 3.14187e-02-4.11894e-01 + 2.79318e-01 5.99727e-02-1.31132e+00 1.63586e-01 5.60610e-02-1.32076e+00 + 9.45936e-01 5.80730e-02-9.87347e-01 5.14179e-01 5.99327e-02-1.25710e+00 + 7.68622e-01 5.79683e-02-1.10888e+00 1.36337e+00 5.38947e-02-1.47006e-01 + 1.14583e+00 5.65640e-02-7.49096e-01 1.28198e+00 5.45810e-02-4.41093e-01 + 3.79798e-01 4.96910e-02-1.25430e+00 2.16212e-01 4.31330e-02-1.30136e+00 + 4.98805e-01 2.69780e-02-1.22052e+00 2.82592e-01 1.27860e-02-1.23580e+00 + 8.01540e-01 8.98633e-03 5.51272e-01 9.70359e-01 8.42867e-03 1.13927e-01 + 1.03900e+00 2.09363e-02 3.78471e-01 3.63989e-01 1.63293e-02 9.70850e-01 + 6.63215e-01 1.01040e-02 7.16524e-01 6.21408e-01 2.01380e-02 9.04369e-01 + 2.22972e-01 2.26437e-02 1.09785e+00 7.18057e-02 1.73793e-02 1.04808e+00 + 1.29068e+00 3.49390e-02 1.73609e-01 1.06678e+00 3.43673e-02 7.46448e-01 + 1.18082e+00 3.16467e-02 4.37225e-01 8.50437e-01 3.20140e-02 9.79523e-01 + 4.46912e-01 2.70867e-02 1.18577e+00 6.85210e-01 2.73773e-02 1.03094e+00 + 9.09263e-02 2.79357e-02 1.25755e+00 2.42093e-01 2.61617e-02 1.18619e+00 + 1.12690e+00 5.68660e-02 7.77134e-01 1.35967e+00 5.39600e-02 1.85527e-01 + 1.26935e+00 5.47217e-02 4.79392e-01 4.77035e-01 5.99957e-02 1.27357e+00 + 9.22334e-01 5.84350e-02 1.01129e+00 7.43502e-01 5.79560e-02 1.12561e+00 + 1.55778e-01 5.46453e-02 1.31307e+00 2.50557e-01 5.93730e-02 1.31603e+00 + 2.10272e-01 4.12267e-02 1.29981e+00 3.66050e-01 4.84927e-02 1.25340e+00 + 4.89636e-01 2.49370e-02 1.22180e+00 2.79365e-01 1.05517e-02 1.23526e+00 + 4.98689e-01-2.51433e-02-1.22032e+00 2.82592e-01-1.11767e-02-1.23612e+00 + 2.16096e-01-4.15993e-02-1.30035e+00 3.77016e-01-4.84723e-02-1.25445e+00 + 1.60920e-01-5.51457e-02-1.32186e+00 2.74903e-01-5.94227e-02-1.31419e+00 + 5.07268e-01-5.94163e-02-1.26132e+00 9.35997e-01-5.78603e-02-9.98996e-01 + 7.58868e-01-5.75067e-02-1.11846e+00 1.13678e+00-5.64870e-02-7.63981e-01 + 1.36209e+00-5.40807e-02-1.66051e-01 1.27608e+00-5.45937e-02-4.60837e-01 + 9.61127e-02-2.78033e-02-1.28385e+00 2.38812e-01-2.64803e-02-1.21634e+00 + 8.72963e-01-3.14973e-02-9.50206e-01 4.60901e-01-2.91003e-02-1.18519e+00 + 6.94273e-01-2.81073e-02-1.01630e+00 1.28932e+00-3.38760e-02-1.57344e-01 + 1.07342e+00-3.31203e-02-7.26850e-01 1.18010e+00-3.01900e-02-4.18653e-01 + 1.42699e-01-2.39607e-02-1.12846e+00 2.18956e-01-1.75540e-02-9.97982e-01 + 3.73213e-01-1.30667e-02-9.12457e-01 6.79493e-01-9.10667e-03-6.80962e-01 + 6.26441e-01-2.03470e-02-8.86323e-01 8.02498e-01-7.95733e-03-5.27792e-01 + 9.61511e-01-7.48367e-03-9.88030e-02 1.03481e+00-1.96573e-02-3.58862e-01 + 4.92543e-01-2.72137e-02 1.22263e+00 2.79365e-01-1.30500e-02 1.23594e+00 + 3.74841e-01-5.05700e-02 1.25621e+00 2.13179e-01-4.36270e-02 1.30265e+00 + 1.36223e+00-5.42943e-02 1.65215e-01 1.13894e+00-5.75943e-02 7.59925e-01 + 1.27736e+00-5.53673e-02 4.58534e-01 9.38698e-01-5.91767e-02 9.94629e-01 + 5.09386e-01-6.09223e-02 1.25854e+00 7.61425e-01-5.91193e-02 1.11438e+00 + 2.76343e-01-6.09593e-02 1.31185e+00 1.61662e-01-5.69863e-02 1.32087e+00 + 1.06565e+00-3.38903e-02 7.43536e-01 1.28773e+00-3.40300e-02 1.70965e-01 + 1.17676e+00-3.07503e-02 4.33986e-01 4.60274e-01-2.98067e-02 1.19979e+00 + 8.65431e-01-3.23803e-02 9.64853e-01 6.89230e-01-2.88170e-02 1.03262e+00 + 1.40760e-01-2.58463e-02 1.17532e+00 2.39537e-01-2.77297e-02 1.23969e+00 + 9.62564e-01-7.68333e-03 1.06745e-01 8.01470e-01-9.00700e-03 5.39663e-01 + 1.03411e+00-2.02633e-02 3.71016e-01 6.76610e-01-1.01093e-02 6.97438e-01 + 3.58734e-01-1.39853e-02 9.36466e-01 6.21947e-01-2.09423e-02 9.06106e-01 + 6.45187e-02-9.80167e-03 9.33656e-01 2.05279e-01-1.93593e-02 1.04259e+00 + 2.51773e-02-7.15467e-03-6.13553e-01 9.18997e-02-2.01500e-03-7.72896e-01 + 2.88492e-01-3.81367e-03-5.84009e-01 1.45147e-01-2.46700e-03-6.61433e-01 + 2.77884e-01 4.83267e-03-7.34759e-01 3.92111e-01-9.92133e-03-3.75645e-01 + 3.27954e-01-5.42700e-03-5.38112e-01 4.51085e-01-1.09833e-03-5.59433e-01 + 5.78814e-01-7.07500e-03-2.41215e-01 4.43250e-01-1.01280e-02-3.36164e-01 + 6.27668e-01-2.38633e-03-3.55770e-01 5.55108e-01-1.32707e-02-2.49073e-02 + 5.84113e-01-6.58833e-03-1.87252e-01 6.93086e-01-3.12567e-03-1.27245e-01 + 1.76872e-01 2.99623e-02-1.29712e+00 6.13453e-02 3.20983e-02-1.33066e+00 + 3.05383e-01 3.36230e-02-1.29968e+00 5.71087e-01 3.68773e-02-1.21720e+00 + 4.78156e-01 3.38797e-02-1.24138e+00 7.18752e-01 3.81690e-02-1.13526e+00 + 9.38713e-01 3.99003e-02-9.42770e-01 8.44244e-01 3.73960e-02-1.02704e+00 + 1.04502e+00 4.02713e-02-8.23883e-01 1.21958e+00 4.06407e-02-5.54154e-01 + 1.13998e+00 3.88023e-02-6.80812e-01 1.27857e+00 4.08643e-02-3.98348e-01 + 1.32237e+00 4.13397e-02-7.68873e-02 1.30411e+00 3.94910e-02-2.34650e-01 + 5.66653e-02 6.12220e-02-1.36192e+00 1.72398e-01 6.14773e-02-1.34325e+00 + 5.44568e-01 5.95697e-02-1.26331e+00 2.93496e-01 6.08137e-02-1.33591e+00 + 4.71692e-01 6.11037e-02-1.28241e+00 9.44427e-01 5.56877e-02-9.77465e-01 + 6.96134e-01 5.82443e-02-1.18518e+00 8.48425e-01 5.82470e-02-1.06661e+00 + 1.24009e+00 5.49220e-02-5.69250e-01 1.05703e+00 5.51390e-02-8.52031e-01 + 1.16091e+00 5.61893e-02-7.02922e-01 1.34840e+00 5.28717e-02-7.46123e-02 + 1.30099e+00 5.44937e-02-4.09531e-01 1.33248e+00 5.46417e-02-2.38554e-01 + 5.72273e-01-7.41933e-03 1.94756e-01 5.53767e-01-1.33240e-02 3.08853e-02 + 6.87731e-01-3.48333e-03 1.38578e-01 4.25345e-01-1.20913e-02 3.60401e-01 + 5.50855e-01-7.12600e-03 2.49114e-01 5.98704e-01-2.54733e-03 3.67263e-01 + 2.98939e-01-6.04833e-03 5.41532e-01 3.89108e-01-1.22480e-02 4.02319e-01 + 4.24142e-01-1.58633e-03 5.74433e-01 2.64205e-01 9.16167e-03 8.55404e-01 + 2.45407e-01-6.85167e-03 5.62145e-01 2.29019e-01 4.76667e-04 6.67444e-01 + 1.23188e-01 8.54833e-03 8.96609e-01 5.13823e-02 3.76667e-04 7.46740e-01 + 1.32147e+00 4.14403e-02 9.18590e-02 1.27297e+00 4.14087e-02 4.20207e-01 + 1.30081e+00 3.98613e-02 2.56773e-01 1.20945e+00 4.12067e-02 5.79455e-01 + 1.01625e+00 4.05630e-02 8.65984e-01 1.11460e+00 3.91727e-02 7.25842e-01 + 9.18835e-01 4.03320e-02 9.74409e-01 8.23645e-01 3.91417e-02 1.05393e+00 + 7.48831e-01 3.53247e-02 1.09934e+00 5.62331e-01 3.55747e-02 1.22468e+00 + 4.21027e-01 3.32917e-02 1.27877e+00 3.82060e-01 2.99453e-02 1.26206e+00 + 8.63150e-02 3.17530e-02 1.33489e+00 1.77241e-01 2.91310e-02 1.29782e+00 + 1.29371e+00 5.46573e-02 4.32148e-01 1.34714e+00 5.28960e-02 9.75060e-02 + 1.32752e+00 5.47313e-02 2.66096e-01 1.04272e+00 5.55170e-02 8.69208e-01 + 1.23033e+00 5.51890e-02 5.91170e-01 1.14718e+00 5.65437e-02 7.26215e-01 + 6.77290e-01 5.84147e-02 1.19717e+00 9.28926e-01 5.60077e-02 9.92591e-01 + 8.28815e-01 5.86033e-02 1.08375e+00 2.75818e-01 6.09823e-02 1.34716e+00 + 5.25741e-01 5.97323e-02 1.27248e+00 4.37435e-01 6.14417e-02 1.29979e+00 + 9.47790e-02 6.13767e-02 1.35262e+00 1.59640e-01 6.15400e-02 1.35754e+00 + 1.71535e-01-6.10900e-02-1.34532e+00 5.75513e-02-6.08603e-02-1.36370e+00 + 2.93102e-01-6.04763e-02-1.33763e+00 5.41027e-01-5.92733e-02-1.26647e+00 + 4.67915e-01-6.07763e-02-1.28522e+00 6.90936e-01-5.79573e-02-1.18972e+00 + 9.40623e-01-5.55567e-02-9.82806e-01 8.41890e-01-5.80440e-02-1.07339e+00 + 1.05392e+00-5.50963e-02-8.57171e-01 1.23719e+00-5.50067e-02-5.78614e-01 + 1.15597e+00-5.62103e-02-7.12738e-01 1.29798e+00-5.46273e-02-4.22464e-01 + 1.34813e+00-5.31043e-02-9.12047e-02 1.33030e+00-5.48247e-02-2.54022e-01 + 5.89490e-02-3.44000e-02-1.33884e+00 1.55062e-01-3.16733e-02-1.31346e+00 + 6.05702e-01-3.57507e-02-1.19336e+00 3.01544e-01-3.41137e-02-1.30390e+00 + 4.64685e-01-3.28637e-02-1.24314e+00 9.32756e-01-3.99600e-02-9.59294e-01 + 8.42835e-01-3.88073e-02-1.03531e+00 7.80608e-01-3.53773e-02-1.06932e+00 + 1.21499e+00-4.04497e-02-5.67649e-01 1.02817e+00-4.01267e-02-8.51371e-01 + 1.12367e+00-3.84633e-02-7.10387e-01 1.32197e+00-4.08300e-02-8.08317e-02 + 1.27669e+00-4.05863e-02-4.08833e-01 1.30269e+00-3.89960e-02-2.43563e-01 + 1.09464e-01-9.68067e-03-8.68395e-01 3.32070e-02-4.89700e-03-7.72436e-01 + 1.55328e-01 2.66667e-05-6.96363e-01 2.66347e-01 4.71767e-03-5.45953e-01 + 2.76378e-01-1.93267e-03-7.08643e-01 3.22403e-01 5.66100e-03-4.99721e-01 + 3.94951e-01 1.09303e-02-3.70488e-01 4.51929e-01 3.07067e-03-5.43709e-01 + 4.33161e-01 1.05970e-02-3.28357e-01 5.63722e-01 7.89767e-03-2.38774e-01 + 6.13143e-01 3.88667e-03-3.48409e-01 5.69332e-01 7.21367e-03-1.86195e-01 + 5.43330e-01 1.35830e-02-2.65150e-02 6.79189e-01 4.03600e-03-1.28339e-01 + 1.34886e+00-5.31937e-02 7.99047e-02 1.29991e+00-5.50843e-02 4.14034e-01 + 1.33116e+00-5.51277e-02 2.48353e-01 1.23879e+00-5.55880e-02 5.73304e-01 + 1.05534e+00-5.59177e-02 8.54250e-01 1.15737e+00-5.69713e-02 7.09593e-01 + 9.42769e-01-5.64940e-02 9.79499e-01 6.94516e-01-5.90667e-02 1.18554e+00 + 8.44561e-01-5.91300e-02 1.06955e+00 5.43941e-01-6.04607e-02 1.26295e+00 + 2.94415e-01-6.17670e-02 1.33494e+00 4.69733e-01-6.20600e-02 1.28247e+00 + 5.77250e-02-6.21733e-02 1.36095e+00 1.72406e-01-6.24263e-02 1.34284e+00 + 1.27322e+00-4.09343e-02 4.19433e-01 1.32160e+00-4.08907e-02 8.92617e-02 + 1.30073e+00-3.92107e-02 2.54839e-01 1.01464e+00-4.07457e-02 8.67767e-01 + 1.20862e+00-4.08933e-02 5.80579e-01 1.11437e+00-3.89833e-02 7.25725e-01 + 7.71598e-01-3.61433e-02 1.08093e+00 9.17064e-01-4.07357e-02 9.75860e-01 + 8.29733e-01-3.96193e-02 1.04802e+00 3.22856e-01-3.49770e-02 1.30081e+00 + 6.01688e-01-3.65403e-02 1.19758e+00 4.66565e-01-3.37670e-02 1.24868e+00 + 9.87763e-02-3.02170e-02 1.30854e+00 1.75806e-01-3.35040e-02 1.32077e+00 + 5.43807e-01 1.36693e-02 2.84870e-02 5.71940e-01 7.09500e-03 1.89176e-01 + 6.80719e-01 3.92267e-03 1.32211e-01 5.66770e-01 7.50567e-03 2.42293e-01 + 4.32673e-01 1.03973e-02 3.32265e-01 6.14785e-01 3.05633e-03 3.55415e-01 + 3.82440e-01 1.01370e-02 3.69973e-01 3.19237e-01 5.79067e-03 5.26671e-01 + 4.39692e-01 1.69367e-03 5.50897e-01 2.80508e-01 4.31667e-03 5.70935e-01 + 1.41247e-01 3.00600e-03 6.46560e-01 2.70058e-01-4.12633e-03 7.19706e-01 + 2.46440e-02 7.62833e-03 5.96131e-01 8.91627e-02 2.70467e-03 7.54387e-01 + 2.51773e-02-6.65000e-03-3.35287e-01 0.00000e+00-2.62000e-03-1.42498e-01 + 5.32473e-02-9.56667e-04-1.66803e-01 7.84247e-02-4.98667e-03-3.59592e-01 + 1.30578e-01-7.08333e-03-3.17893e-01 5.32473e-02-9.56667e-04-1.66803e-01 + 9.27093e-02-2.57000e-03-1.20906e-01 1.70040e-01-8.69667e-03-2.71997e-01 + 1.91649e-01-8.12333e-03-2.03234e-01 9.27093e-02-2.57000e-03-1.20906e-01 + 2.42788e-01-8.33000e-03-1.63752e-01 9.89393e-02-5.55333e-03-8.23273e-02 + 2.95458e-01-9.26333e-03-1.39281e-01 1.43849e-01-2.77667e-03-8.14250e-02 + 1.49148e-01-2.29000e-03-2.74627e-02 3.00757e-01-8.77667e-03-8.53187e-02 + 2.94526e-01-1.02467e-02-2.70590e-02 1.49148e-01-2.29000e-03-2.74627e-02 + 1.89856e-01 3.57590e-02-1.33322e+00 6.05440e-02 4.11257e-02-1.36508e+00 + 1.12296e-01 4.47390e-02-1.36825e+00 5.17517e-02 4.71247e-02-1.37261e+00 + 3.11805e-01 4.21163e-02-1.33521e+00 1.89055e-01 3.89610e-02-1.34624e+00 + 5.41689e-01 4.01867e-02-1.24636e+00 4.55982e-01 4.24803e-02-1.29305e+00 + 2.35046e-01 4.54480e-02-1.35305e+00 3.30556e-01 4.88103e-02-1.33410e+00 + 2.61121e-01 4.77827e-02-1.34895e+00 3.97789e-01 4.87860e-02-1.31452e+00 + 4.54931e-01 4.78803e-02-1.29327e+00 5.05801e-01 4.59340e-02-1.27478e+00 + 7.47184e-01 4.36563e-02-1.13986e+00 6.89354e-01 4.14783e-02-1.16442e+00 + 9.37682e-01 4.26943e-02-9.69985e-01 8.75383e-01 4.41627e-02-1.04203e+00 + 6.05078e-01 4.65560e-02-1.23130e+00 7.44771e-01 4.75833e-02-1.14582e+00 + 6.93036e-01 4.58603e-02-1.18196e+00 8.19775e-01 4.77680e-02-1.09266e+00 + 9.55313e-01 4.73580e-02-9.76077e-01 8.96238e-01 4.65513e-02-1.03097e+00 + 1.09554e+00 4.46590e-02-8.00299e-01 1.04399e+00 4.30653e-02-8.51098e-01 + 1.21957e+00 4.35990e-02-5.68590e-01 1.18617e+00 4.48370e-02-6.56071e-01 + 1.00855e+00 4.71950e-02-9.19153e-01 1.10498e+00 4.76090e-02-7.91010e-01 + 1.06332e+00 4.65137e-02-8.51200e-01 1.15611e+00 4.76890e-02-7.12882e-01 + 1.24254e+00 4.73990e-02-5.52640e-01 1.20507e+00 4.67717e-02-6.28844e-01 + 1.30887e+00 4.50817e-02-3.40576e-01 1.27856e+00 4.38227e-02-4.12783e-01 + 1.33891e+00 4.38453e-02-7.99917e-02 1.34094e+00 4.50803e-02-1.70338e-01 + 1.27201e+00 4.72593e-02-4.79011e-01 1.31587e+00 4.74663e-02-3.20040e-01 + 1.29825e+00 4.66530e-02-3.95528e-01 1.33492e+00 4.75377e-02-2.27281e-01 + 1.35631e+00 4.72803e-02-4.60543e-02 1.34938e+00 4.67230e-02-1.32531e-01 + 4.10670e-02 5.93007e-02-1.37138e+00 9.77323e-02 6.01133e-02-1.36645e+00 + 3.16198e-01 5.70870e-02-1.34147e+00 2.32029e-01 5.81653e-02-1.35879e+00 + 2.18831e-01 5.99037e-02-1.35695e+00 5.26843e-01 5.48710e-02-1.26507e+00 + 4.68999e-01 5.54990e-02-1.28809e+00 4.34943e-01 5.74227e-02-1.30473e+00 + 7.67827e-01 5.42753e-02-1.13119e+00 6.00947e-01 5.46170e-02-1.23039e+00 + 6.90532e-01 5.54430e-02-1.18073e+00 9.57185e-01 5.30680e-02-9.65069e-01 + 8.37478e-01 5.39993e-02-1.07891e+00 9.02437e-01 5.43003e-02-1.02070e+00 + 1.12314e+00 5.28290e-02-7.65135e-01 1.01530e+00 5.28683e-02-9.02106e-01 + 1.07315e+00 5.35520e-02-8.32305e-01 1.24070e+00 5.19730e-02-5.39941e-01 + 1.16858e+00 5.26577e-02-6.92268e-01 1.20779e+00 5.29827e-02-6.14947e-01 + 1.32277e+00 5.17807e-02-2.91201e-01 1.27222e+00 5.18170e-02-4.58956e-01 + 1.30021e+00 5.23983e-02-3.74243e-01 1.34961e+00 5.12377e-02-3.55277e-02 + 1.33811e+00 5.17100e-02-2.05927e-01 1.34615e+00 5.20060e-02-1.20410e-01 + 1.47807e-01-2.34333e-03 2.83300e-02 2.93186e-01-1.03000e-02 2.87337e-02 + 2.92931e-01-9.30333e-03 8.66600e-02 1.47807e-01-2.34333e-03 2.83300e-02 + 1.26389e-01-2.05000e-03 8.26877e-02 2.71512e-01-9.01000e-03 1.41018e-01 + 2.32372e-01-9.71000e-03 1.83922e-01 1.26389e-01-2.05000e-03 8.26877e-02 + 9.01517e-02-2.20667e-03 1.24605e-01 1.96135e-01-9.86667e-03 2.25840e-01 + 1.57922e-01-9.05000e-03 2.68183e-01 9.01517e-02-2.20667e-03 1.24605e-01 + 3.66193e-02-3.01000e-03 1.45218e-01 1.04389e-01-9.85333e-03 2.88796e-01 + 3.66193e-02-5.50667e-03 3.28526e-01 3.66193e-02-3.01000e-03 1.45218e-01 + 0.00000e+00-2.49667e-03 1.83308e-01 8.80017e-02-5.02167e-03 5.77403e-01 + 1.34059e+00 4.52463e-02 1.71691e-01 1.33800e+00 4.39460e-02 8.87547e-02 + 1.27471e+00 4.42183e-02 4.24723e-01 1.30787e+00 4.53687e-02 3.43081e-01 + 1.35651e+00 4.71973e-02 3.35793e-02 1.33856e+00 4.75617e-02 1.99437e-01 + 1.35013e+00 4.67053e-02 1.20386e-01 1.32186e+00 4.77583e-02 2.93154e-01 + 1.27489e+00 4.76530e-02 4.69440e-01 1.30071e+00 4.70243e-02 3.85493e-01 + 1.18075e+00 4.51887e-02 6.63568e-01 1.21119e+00 4.40163e-02 5.83971e-01 + 1.03132e+00 4.34813e-02 8.67784e-01 1.08932e+00 4.49923e-02 8.06904e-01 + 1.24557e+00 4.75937e-02 5.43384e-01 1.16722e+00 4.78613e-02 6.90787e-01 + 1.20779e+00 4.69870e-02 6.20676e-01 1.11768e+00 4.80140e-02 7.70909e-01 + 1.01262e+00 4.75587e-02 9.12321e-01 1.06683e+00 4.69433e-02 8.44134e-01 + 8.78921e-01 4.45457e-02 1.03839e+00 9.33910e-01 4.32503e-02 9.76209e-01 + 7.13265e-01 4.12977e-02 1.15094e+00 7.53465e-01 4.37833e-02 1.13361e+00 + 9.58548e-01 4.73970e-02 9.70314e-01 8.28828e-01 4.77780e-02 1.08361e+00 + 8.99767e-01 4.65660e-02 1.02519e+00 7.50282e-01 4.76707e-02 1.14042e+00 + 6.03544e-01 4.62590e-02 1.22866e+00 6.95765e-01 4.56963e-02 1.17722e+00 + 4.53755e-01 4.22353e-02 1.29152e+00 5.63525e-01 3.97790e-02 1.23466e+00 + 2.16208e-01 3.48657e-02 1.33744e+00 3.06136e-01 4.18493e-02 1.33574e+00 + 4.99460e-01 4.55387e-02 1.27390e+00 3.81059e-01 4.84753e-02 1.31839e+00 + 4.42487e-01 4.75303e-02 1.29596e+00 2.99520e-01 4.86920e-02 1.34079e+00 + 2.25904e-01 4.74767e-02 1.35467e+00 2.16796e-01 4.48823e-02 1.35443e+00 + 5.83937e-02 4.01880e-02 1.36951e+00 1.88287e-01 3.84137e-02 1.35096e+00 + 4.05537e-02 4.54647e-02 1.37070e+00 9.89473e-02 4.39453e-02 1.36785e+00 + 1.33481e+00 5.17810e-02 2.26350e-01 1.34911e+00 5.12427e-02 5.18267e-02 + 1.34438e+00 5.20353e-02 1.39063e-01 1.26598e+00 5.20517e-02 4.75068e-01 + 1.31784e+00 5.19300e-02 3.11499e-01 1.29450e+00 5.25800e-02 3.92680e-01 + 1.15689e+00 5.29750e-02 7.11083e-01 1.23335e+00 5.22053e-02 5.55937e-01 + 1.19849e+00 5.32653e-02 6.32570e-01 1.00252e+00 5.31323e-02 9.15430e-01 + 1.10988e+00 5.31760e-02 7.83265e-01 1.06032e+00 5.38793e-02 8.47868e-01 + 8.21248e-01 5.42113e-02 1.09094e+00 9.43725e-01 5.32767e-02 9.77250e-01 + 8.87726e-01 5.45143e-02 1.03307e+00 5.84984e-01 5.45647e-02 1.23668e+00 + 7.51892e-01 5.44757e-02 1.14117e+00 6.74866e-01 5.55317e-02 1.18864e+00 + 4.19604e-01 5.74840e-02 1.30911e+00 5.10312e-01 5.47050e-02 1.27106e+00 + 4.52808e-01 5.54283e-02 1.29366e+00 2.31508e-01 6.01363e-02 1.35783e+00 + 3.05932e-01 5.73850e-02 1.34443e+00 2.36060e-01 5.86540e-02 1.35996e+00 + 1.15330e-01 6.06940e-02 1.36821e+00 5.04687e-02 5.95410e-02 1.37585e+00 + 1.07272e-01-5.98737e-02-1.36729e+00 4.97203e-02-5.85333e-02-1.37488e+00 + 2.28839e-01-5.96933e-02-1.35720e+00 3.14972e-01-5.70160e-02-1.34339e+00 + 2.41581e-01-5.81367e-02-1.35898e+00 4.31773e-01-5.71723e-02-1.30734e+00 + 5.21667e-01-5.45673e-02-1.26899e+00 4.63585e-01-5.52430e-02-1.29185e+00 + 5.96659e-01-5.43137e-02-1.23413e+00 7.64267e-01-5.40437e-02-1.13541e+00 + 6.86943e-01-5.51670e-02-1.18454e+00 8.34634e-01-5.37670e-02-1.08302e+00 + 9.62732e-01-5.27630e-02-9.62076e-01 9.01313e-01-5.41033e-02-1.02343e+00 + 1.02563e+00-5.27400e-02-8.91735e-01 1.12745e+00-5.29700e-02-7.60298e-01 + 1.07750e+00-5.36200e-02-8.27458e-01 1.16793e+00-5.27463e-02-6.95363e-01 + 1.23900e+00-5.20763e-02-5.47091e-01 1.20615e+00-5.30663e-02-6.20796e-01 + 1.27050e+00-5.19333e-02-4.67308e-01 1.32115e+00-5.19610e-02-3.04172e-01 + 1.29843e+00-5.25440e-02-3.84863e-01 1.33568e+00-5.19947e-02-2.27346e-01 + 1.34970e+00-5.14543e-02-6.41380e-02 1.34467e+00-5.23013e-02-1.42514e-01 + 2.44933e-02-4.55400e-02-1.37667e+00 8.58760e-02-4.40800e-02-1.37381e+00 + 6.13827e-02-4.10197e-02-1.36827e+00 1.20332e-01-3.84397e-02-1.35537e+00 + 3.18229e-01-4.81563e-02-1.33711e+00 1.51194e-01-4.59233e-02-1.37089e+00 + 2.61026e-01-4.55133e-02-1.35061e+00 5.30618e-01-4.55307e-02-1.26317e+00 + 4.07967e-01-4.83627e-02-1.31209e+00 4.71712e-01-4.74663e-02-1.28814e+00 + 2.66814e-01-3.83833e-02-1.33185e+00 3.42190e-01-4.17570e-02-1.32514e+00 + 4.94770e-01-4.21847e-02-1.27452e+00 5.97575e-01-3.96947e-02-1.21411e+00 + 7.49476e-01-4.74173e-02-1.14311e+00 6.19667e-01-4.62673e-02-1.22227e+00 + 7.07072e-01-4.56843e-02-1.17218e+00 9.53589e-01-4.72810e-02-9.77981e-01 + 8.22488e-01-4.76303e-02-1.09146e+00 8.98851e-01-4.65007e-02-1.02926e+00 + 7.35409e-01-4.12077e-02-1.13483e+00 7.68015e-01-4.37540e-02-1.12502e+00 + 8.86782e-01-4.43573e-02-1.03375e+00 9.44097e-01-4.29637e-02-9.67540e-01 + 1.10093e+00-4.76537e-02-7.98537e-01 1.00559e+00-4.71647e-02-9.23119e-01 + 1.06028e+00-4.65413e-02-8.55841e-01 1.24204e+00-4.74663e-02-5.57171e-01 + 1.15373e+00-4.77733e-02-7.18937e-01 1.20339e+00-4.68267e-02-6.34620e-01 + 1.03951e+00-4.31303e-02-8.59616e-01 1.09162e+00-4.46810e-02-8.07265e-01 + 1.18193e+00-4.48467e-02-6.65644e-01 1.21548e+00-4.35397e-02-5.78865e-01 + 1.31616e+00-4.74823e-02-3.24525e-01 1.27177e+00-4.73057e-02-4.83601e-01 + 1.29793e+00-4.66487e-02-4.00966e-01 1.35771e+00-4.72567e-02-4.48503e-02 + 1.33566e+00-4.75597e-02-2.29709e-01 1.35041e+00-4.66797e-02-1.34513e-01 + 1.27717e+00-4.36763e-02-4.20049e-01 1.30843e+00-4.49660e-02-3.46745e-01 + 1.34141e+00-4.49197e-02-1.75108e-01 1.33928e+00-4.35570e-02-8.38273e-02 + 0.00000e+00 3.24367e-03-1.89523e-01 7.90717e-02 4.81033e-03-6.00404e-01 + 4.58647e-02 5.65733e-03-3.57850e-01 4.58647e-02 2.41367e-03-1.68327e-01 + 4.58647e-02 2.41367e-03-1.68327e-01 1.12090e-01 7.52400e-03-2.91119e-01 + 1.68146e-01 8.46733e-03-2.44887e-01 6.62253e-02 5.11033e-03-1.22792e-01 + 1.01920e-01 3.35700e-03-1.22095e-01 1.99199e-01 8.41033e-03-2.03707e-01 + 2.37409e-01 8.07700e-03-1.61577e-01 9.72787e-02 5.05333e-03-8.16127e-02 + 1.40130e-01 3.02367e-03-7.99643e-02 2.86460e-01 9.55467e-03-1.37110e-01 + 2.92071e-01 8.87067e-03-8.45310e-02 1.45741e-01 2.33967e-03-2.73853e-02 + 1.45741e-01 2.33967e-03-2.73853e-02 2.87143e-01 1.02297e-02-2.72257e-02 + 1.35128e+00-5.13670e-02 3.06100e-02 1.33867e+00-5.20767e-02 2.10903e-01 + 1.34698e+00-5.23033e-02 1.23343e-01 1.32393e+00-5.23430e-02 2.88333e-01 + 1.27657e+00-5.23433e-02 4.47597e-01 1.30160e+00-5.30000e-02 3.69372e-01 + 1.24401e+00-5.24203e-02 5.34221e-01 1.16878e+00-5.33103e-02 6.92460e-01 + 1.20791e+00-5.35807e-02 6.15267e-01 1.12808e+00-5.36200e-02 7.57738e-01 + 1.02564e+00-5.35100e-02 8.90188e-01 1.07812e+00-5.43403e-02 8.25052e-01 + 9.60655e-01-5.36037e-02 9.62359e-01 8.34122e-01-5.47833e-02 1.08206e+00 + 9.00575e-01-5.50103e-02 1.02247e+00 7.71000e-01-5.52507e-02 1.12887e+00 + 6.10565e-01-5.53313e-02 1.22508e+00 6.95092e-01-5.63477e-02 1.17707e+00 + 5.31117e-01-5.53770e-02 1.26392e+00 4.66500e-01-5.62603e-02 1.28943e+00 + 4.34339e-01-5.83113e-02 1.30447e+00 3.16712e-01-5.82403e-02 1.34151e+00 + 2.43157e-01-5.94203e-02 1.35679e+00 2.29619e-01-6.09643e-02 1.35449e+00 + 4.98853e-02-5.98570e-02 1.37255e+00 1.07610e-01-6.11670e-02 1.36442e+00 + 1.33987e+00-4.75530e-02 1.98671e-01 1.35776e+00-4.71433e-02 3.47697e-02 + 1.35136e+00-4.66230e-02 1.19306e-01 1.27401e+00-4.78300e-02 4.75876e-01 + 1.32294e+00-4.78193e-02 2.92988e-01 1.30129e+00-4.70797e-02 3.87498e-01 + 1.33890e+00-4.36177e-02 8.62660e-02 1.34194e+00-4.50370e-02 1.69185e-01 + 1.30881e+00-4.52273e-02 3.43059e-01 1.27513e+00-4.40143e-02 4.25419e-01 + 1.14988e+00-4.83360e-02 7.22709e-01 1.24040e+00-4.79133e-02 5.58580e-01 + 1.20003e+00-4.73163e-02 6.38303e-01 9.98189e-01-4.78527e-02 9.29706e-01 + 1.09644e+00-4.83063e-02 8.02662e-01 1.05294e+00-4.72227e-02 8.62843e-01 + 1.21053e+00-4.39733e-02 5.86565e-01 1.17655e+00-4.53397e-02 6.72307e-01 + 1.08290e+00-4.52757e-02 8.16894e-01 1.02691e+00-4.37853e-02 8.73494e-01 + 8.23948e-01-4.85403e-02 1.08942e+00 9.49537e-01-4.78557e-02 9.80831e-01 + 8.94030e-01-4.71897e-02 1.03207e+00 6.02167e-01-4.71867e-02 1.23020e+00 + 7.44914e-01-4.85673e-02 1.14546e+00 6.94842e-01-4.66637e-02 1.17859e+00 + 9.29329e-01-4.37753e-02 9.81587e-01 8.75060e-01-4.52297e-02 1.04309e+00 + 7.54907e-01-4.46767e-02 1.13357e+00 7.21845e-01-4.21060e-02 1.14423e+00 + 3.83347e-01-4.91427e-02 1.31990e+00 4.43129e-01-4.81433e-02 1.29865e+00 + 5.04820e-01-4.63137e-02 1.27345e+00 2.29644e-01-4.49403e-02 1.35401e+00 + 3.04351e-01-4.94760e-02 1.34150e+00 2.32357e-01-4.81767e-02 1.35518e+00 + 5.90023e-01-4.05133e-02 1.21732e+00 4.77583e-01-4.29473e-02 1.27980e+00 + 3.34183e-01-4.18740e-02 1.32542e+00 2.89753e-01-3.84940e-02 1.32218e+00 + 1.08184e-01-4.36397e-02 1.36749e+00 4.25113e-02-4.56833e-02 1.37090e+00 + 1.42702e-01-3.70210e-02 1.34214e+00 6.56730e-02-3.91003e-02 1.35886e+00 + 2.87619e-01 1.03160e-02 2.77763e-02 1.46217e-01 2.42600e-03 2.76167e-02 + 1.46217e-01 2.42600e-03 2.76167e-02 2.93626e-01 8.95167e-03 8.52923e-02 + 2.88456e-01 9.36233e-03 1.38409e-01 1.41047e-01 2.83667e-03 8.07337e-02 + 2.37250e-01 8.32100e-03 1.61468e-01 9.62030e-02 5.48433e-03 8.07343e-02 + 1.87016e-01 8.06067e-03 1.99175e-01 9.08133e-02 2.57633e-03 1.18441e-01 + 9.08133e-02 2.57633e-03 1.18441e-01 1.65782e-01 8.74967e-03 2.65012e-01 + 1.27053e-01 7.27567e-03 3.09276e-01 5.20840e-02 1.10233e-03 1.62705e-01 + 5.20840e-02 1.10233e-03 1.62705e-01 7.67280e-02 5.27567e-03 3.51217e-01 + 0.00000e+00 2.65400e-03 1.37087e-01 2.46440e-02 6.82733e-03 3.25599e-01 + 1.01712e-01 4.97173e-02-1.37219e+00 4.99600e-02 5.24120e-02-1.37734e+00 + 1.19823e-01 5.43920e-02-1.37312e+00 4.10670e-02 5.76163e-02-1.37727e+00 + 2.33345e-01 5.14403e-02-1.35593e+00 1.88330e-01 4.96663e-02-1.36373e+00 + 3.48375e-01 5.21483e-02-1.32863e+00 3.04572e-01 5.10423e-02-1.34051e+00 + 1.10930e-01 5.66907e-02-1.37418e+00 2.16590e-01 5.34713e-02-1.36016e+00 + 3.52424e-01 5.37667e-02-1.32780e+00 2.91866e-01 5.46917e-02-1.34391e+00 + 4.07968e-01 5.18877e-02-1.31004e+00 4.31398e-01 5.07573e-02-1.30233e+00 + 5.26487e-01 4.94337e-02-1.26513e+00 5.04518e-01 5.08250e-02-1.27484e+00 + 4.10812e-01 5.42383e-02-1.30872e+00 4.41936e-01 5.31057e-02-1.29801e+00 + 5.33747e-01 5.21337e-02-1.26170e+00 4.94595e-01 5.32840e-02-1.27717e+00 + 6.50377e-01 4.97790e-02-1.20371e+00 5.94664e-01 4.88883e-02-1.23301e+00 + 7.60001e-01 5.02363e-02-1.13503e+00 7.12526e-01 4.91697e-02-1.16586e+00 + 6.06646e-01 5.26120e-02-1.22654e+00 6.57609e-01 5.16067e-02-1.19985e+00 + 7.32804e-01 5.17420e-02-1.15368e+00 7.64665e-01 5.26620e-02-1.13104e+00 + 8.64324e-01 5.01577e-02-1.05629e+00 8.22990e-01 4.95723e-02-1.08959e+00 + 9.50875e-01 4.90223e-02-9.76913e-01 9.23303e-01 4.98607e-02-1.00375e+00 + 8.34316e-01 5.23860e-02-1.07876e+00 8.66203e-01 5.15247e-02-1.05331e+00 + 9.25181e-01 5.12277e-02-1.00077e+00 9.54804e-01 5.17680e-02-9.70261e-01 + 1.03787e+00 4.94307e-02-8.80470e-01 1.00411e+00 4.88593e-02-9.19990e-01 + 1.11785e+00 4.96197e-02-7.71875e-01 1.08397e+00 4.88617e-02-8.19443e-01 + 1.01292e+00 5.15683e-02-9.07298e-01 1.04463e+00 5.07610e-02-8.71449e-01 + 1.10030e+00 5.07710e-02-7.97165e-01 1.12203e+00 5.14773e-02-7.63598e-01 + 1.18711e+00 4.95470e-02-6.58695e-01 1.16012e+00 4.90810e-02-7.05827e-01 + 1.23931e+00 4.86753e-02-5.52274e-01 1.22327e+00 4.93270e-02-5.87548e-01 + 1.16746e+00 5.13060e-02-6.90731e-01 1.18818e+00 5.06260e-02-6.54935e-01 + 1.22434e+00 5.04060e-02-5.83788e-01 1.24095e+00 5.08610e-02-5.44193e-01 + 1.28600e+00 4.89777e-02-4.28492e-01 1.26878e+00 4.85357e-02-4.78645e-01 + 1.32111e+00 4.91380e-02-2.95623e-01 1.30685e+00 4.85147e-02-3.53370e-01 + 1.27246e+00 5.07050e-02-4.63208e-01 1.28911e+00 5.00403e-02-4.17375e-01 + 1.31391e+00 5.00660e-02-3.26588e-01 1.32172e+00 5.06630e-02-2.87449e-01 + 1.34384e+00 4.91350e-02-1.64029e-01 1.33619e+00 4.87143e-02-2.17979e-01 + 1.35319e+00 4.84593e-02-4.51200e-02 1.35123e+00 4.90107e-02-8.40100e-02 + 1.33706e+00 5.05923e-02-2.02175e-01 1.34324e+00 5.00557e-02-1.60397e-01 + 1.35063e+00 4.99313e-02-8.03783e-02 1.35144e+00 5.03487e-02-3.75333e-02 + 1.35080e+00 4.88507e-02 8.77957e-02 1.35339e+00 4.83763e-02 3.45137e-02 + 1.33422e+00 4.92223e-02 2.25202e-01 1.34234e+00 4.85280e-02 1.65912e-01 + 1.35093e+00 5.03537e-02 4.98210e-02 1.34949e+00 4.98593e-02 9.91480e-02 + 1.33898e+00 5.00430e-02 1.93065e-01 1.33189e+00 5.06983e-02 2.31920e-01 + 1.30666e+00 4.94350e-02 3.55982e-01 1.31945e+00 4.89290e-02 3.03109e-01 + 1.27123e+00 4.88953e-02 4.70054e-01 1.28390e+00 4.94370e-02 4.33135e-01 + 1.31493e+00 5.08473e-02 3.17069e-01 1.30509e+00 5.03960e-02 3.58766e-01 + 1.28233e+00 5.03980e-02 4.35919e-01 1.26747e+00 5.09527e-02 4.75664e-01 + 1.21986e+00 4.93763e-02 5.92405e-01 1.24191e+00 4.88360e-02 5.43998e-01 + 1.15380e+00 4.98147e-02 7.13626e-01 1.18295e+00 4.90083e-02 6.61902e-01 + 1.23484e+00 5.11063e-02 5.56533e-01 1.21499e+00 5.05503e-02 6.02114e-01 + 1.17069e+00 5.07977e-02 6.85056e-01 1.15031e+00 5.16100e-02 7.17727e-01 + 1.08095e+00 4.99983e-02 8.23413e-01 1.11182e+00 4.94120e-02 7.79720e-01 + 1.00694e+00 4.91840e-02 9.15257e-01 1.03180e+00 4.99377e-02 8.86128e-01 + 1.10330e+00 5.18110e-02 7.89909e-01 1.07860e+00 5.12207e-02 8.25182e-01 + 1.02945e+00 5.11600e-02 8.87897e-01 1.00172e+00 5.18070e-02 9.18567e-01 + 9.14369e-01 4.97630e-02 1.01040e+00 9.52870e-01 4.90223e-02 9.73249e-01 + 8.08696e-01 5.05350e-02 1.09834e+00 8.49109e-01 4.93497e-02 1.06588e+00 + 9.42926e-01 5.19513e-02 9.80387e-01 9.07300e-01 5.12913e-02 1.01599e+00 + 8.41576e-01 5.17220e-02 1.07213e+00 8.13587e-01 5.27257e-02 1.09305e+00 + 7.51929e-01 5.05807e-02 1.13901e+00 7.13796e-01 4.92880e-02 1.16336e+00 + 5.88035e-01 4.86863e-02 1.23400e+00 6.43771e-01 4.97410e-02 1.20550e+00 + 7.44231e-01 5.29900e-02 1.14328e+00 7.15454e-01 5.20320e-02 1.16303e+00 + 6.45892e-01 5.16410e-02 1.20451e+00 5.92403e-01 5.25260e-02 1.23208e+00 + 4.90130e-01 5.05610e-02 1.27892e+00 5.15142e-01 4.91523e-02 1.26784e+00 + 3.89142e-01 5.16723e-02 1.31483e+00 4.13795e-01 5.04760e-02 1.30672e+00 + 5.18934e-01 5.19063e-02 1.26665e+00 4.77812e-01 5.30450e-02 1.28292e+00 + 4.24355e-01 5.28960e-02 1.30331e+00 3.94111e-01 5.41503e-02 1.31390e+00 + 3.28638e-01 5.21430e-02 1.33308e+00 2.71752e-01 5.11633e-02 1.34736e+00 + 1.08055e-01 4.91777e-02 1.37147e+00 2.03118e-01 5.21647e-02 1.36204e+00 + 3.34810e-01 5.38610e-02 1.33232e+00 2.79836e-01 5.50400e-02 1.34740e+00 + 2.05030e-01 5.43233e-02 1.36283e+00 1.14949e-01 5.57430e-02 1.37356e+00 + 1.13037e-01 5.13943e-02 1.37226e+00 4.05537e-02 4.81027e-02 1.37407e+00 + 1.19882e-01 5.77287e-02 1.37366e+00 4.55353e-02 5.38823e-02 1.37857e+00 + 1.20014e-01-5.71037e-02-1.37380e+00 4.44633e-02-5.32157e-02-1.38059e+00 + 1.09782e-01-5.05690e-02-1.37509e+00 2.44933e-02-4.78963e-02-1.37930e+00 + 2.05880e-01-5.38293e-02-1.36393e+00 1.14757e-01-5.51330e-02-1.37471e+00 + 3.41848e-01-5.36057e-02-1.33192e+00 2.84528e-01-5.46793e-02-1.34743e+00 + 8.98117e-02-4.85933e-02-1.37582e+00 2.00905e-01-5.13990e-02-1.36425e+00 + 3.37323e-01-5.19057e-02-1.33269e+00 2.75027e-01-5.05490e-02-1.34851e+00 + 4.35959e-01-5.28337e-02-1.30142e+00 4.04105e-01-5.40130e-02-1.31239e+00 + 5.30634e-01-5.18237e-02-1.26426e+00 4.89537e-01-5.29873e-02-1.28075e+00 + 4.01165e-01-5.15693e-02-1.31336e+00 4.28607e-01-5.04190e-02-1.30417e+00 + 5.04498e-01-5.05197e-02-1.27573e+00 5.31863e-01-4.91027e-02-1.26352e+00 + 6.56739e-01-5.13233e-02-1.20152e+00 6.04041e-01-5.23137e-02-1.22918e+00 + 7.61660e-01-5.24340e-02-1.13472e+00 7.31132e-01-5.14907e-02-1.15606e+00 + 6.00181e-01-4.85833e-02-1.23095e+00 6.51741e-01-4.95137e-02-1.20361e+00 + 7.59127e-01-4.99977e-02-1.13667e+00 7.13632e-01-4.89307e-02-1.16586e+00 + 8.63926e-01-5.12743e-02-1.05703e+00 8.32027e-01-5.21573e-02-1.08233e+00 + 9.54563e-01-5.13537e-02-9.72524e-01 9.17986e-01-5.09107e-02-1.00916e+00 + 8.21622e-01-4.93777e-02-1.09160e+00 8.61573e-01-4.99543e-02-1.05986e+00 + 9.15633e-01-4.95907e-02-1.01199e+00 9.43789e-01-4.87973e-02-9.84604e-01 + 1.01063e+00-5.06370e-02-9.12490e-01 1.04933e+00-5.14437e-02-8.64725e-01 + 1.12657e+00-5.16603e-02-7.58618e-01 1.10032e+00-5.10140e-02-7.98768e-01 + 9.95793e-01-4.86810e-02-9.29742e-01 1.02612e+00-4.93973e-02-8.95833e-01 + 1.11206e+00-4.98033e-02-7.82606e-01 1.07657e+00-4.89933e-02-8.31906e-01 + 1.18736e+00-5.07543e-02-6.58889e-01 1.16704e+00-5.14367e-02-6.93684e-01 + 1.23989e+00-5.09637e-02-5.49861e-01 1.22363e+00-5.05177e-02-5.88237e-01 + 1.15846e+00-4.92033e-02-7.11010e-01 1.18645e+00-4.96843e-02-6.62534e-01 + 1.22272e+00-4.94477e-02-5.91882e-01 1.23916e+00-4.87837e-02-5.56010e-01 + 1.28860e+00-5.01570e-02-4.23702e-01 1.27139e+00-5.08207e-02-4.70078e-01 + 1.32085e+00-5.08507e-02-2.98311e-01 1.31369e+00-5.02137e-02-3.34022e-01 + 1.26890e+00-4.86230e-02-4.82439e-01 1.28593e+00-4.90693e-02-4.33559e-01 + 1.32135e+00-4.92567e-02-3.01819e-01 1.30703e+00-4.85857e-02-3.58280e-01 + 1.34337e+00-5.03910e-02-1.69837e-01 1.33537e+00-5.08843e-02-2.21485e-01 + 1.35314e+00-4.99773e-02-4.00313e-02 1.34870e+00-5.06543e-02-9.73223e-02 + 1.33694e+00-4.88270e-02-2.21533e-01 1.34566e+00-4.93470e-02-1.61703e-01 + 1.35298e+00-4.91203e-02-7.41903e-02 1.35427e+00-4.84503e-02-3.81320e-02 + 1.35100e+00-4.99073e-02 9.98197e-02 1.35287e+00-5.03607e-02 3.95097e-02 + 1.33548e+00-5.09597e-02 2.19831e-01 1.34152e+00-5.02167e-02 1.86483e-01 + 1.35432e+00-4.83370e-02 4.14880e-02 1.35175e+00-4.88373e-02 9.28253e-02 + 1.33632e+00-4.93633e-02 2.21672e-01 1.34371e+00-4.85737e-02 1.65472e-01 + 1.30859e+00-5.08427e-02 3.49437e-01 1.32074e+00-5.12260e-02 2.97261e-01 + 1.26876e+00-5.07203e-02 4.75252e-01 1.28675e+00-5.13030e-02 4.18733e-01 + 1.32115e+00-4.91127e-02 3.01140e-01 1.30715e+00-4.97727e-02 3.59329e-01 + 1.28106e+00-4.97367e-02 4.44072e-01 1.26812e+00-4.91067e-02 4.80125e-01 + 1.21958e+00-5.09097e-02 5.94534e-01 1.24065e+00-5.12570e-02 5.45928e-01 + 1.16709e+00-5.19803e-02 6.91961e-01 1.18605e+00-5.12363e-02 6.59634e-01 + 1.23451e+00-4.91900e-02 5.62830e-01 1.21709e+00-4.98460e-02 6.00506e-01 + 1.18357e+00-5.01727e-02 6.65606e-01 1.15612e+00-4.97667e-02 7.12603e-01 + 1.09954e+00-5.16773e-02 7.98222e-01 1.12640e+00-5.22900e-02 7.57239e-01 + 1.00827e+00-5.13637e-02 9.13803e-01 1.04873e+00-5.21770e-02 8.63858e-01 + 1.11054e+00-5.04510e-02 7.82995e-01 1.07357e+00-4.96907e-02 8.33925e-01 + 1.02210e+00-5.01037e-02 8.99098e-01 9.90222e-01-4.93493e-02 9.34699e-01 + 9.05513e-01-5.16467e-02 1.01962e+00 9.50663e-01-5.21463e-02 9.74889e-01 + 8.23457e-01-5.33837e-02 1.08720e+00 8.46171e-01-5.23240e-02 1.07028e+00 + 9.41571e-01-4.93523e-02 9.85823e-01 9.06614e-01-5.01530e-02 1.01922e+00 + 8.08575e-01-5.12710e-02 1.10041e+00 8.44499e-01-5.00070e-02 1.07157e+00 + 7.20278e-01-5.30707e-02 1.16165e+00 7.60334e-01-5.38510e-02 1.13402e+00 + 5.97041e-01-5.21733e-02 1.23134e+00 6.46417e-01-5.34540e-02 1.20451e+00 + 7.45804e-01-5.15503e-02 1.14496e+00 7.02693e-01-5.03133e-02 1.17217e+00 + 6.27791e-01-5.05530e-02 1.21568e+00 5.77337e-01-4.93300e-02 1.24058e+00 + 5.24406e-01-5.23303e-02 1.26591e+00 4.94333e-01-5.36567e-02 1.27793e+00 + 4.04122e-01-5.49970e-02 1.31161e+00 4.32787e-01-5.36600e-02 1.30184e+00 + 5.05912e-01-4.96697e-02 1.27339e+00 4.83731e-01-5.10497e-02 1.28307e+00 + 3.93123e-01-5.24663e-02 1.31480e+00 4.13993e-01-5.11823e-02 1.30804e+00 + 3.41500e-01-5.47540e-02 1.33120e+00 2.86251e-01-5.59463e-02 1.34606e+00 + 1.21148e-01-5.84397e-02 1.37197e+00 2.09177e-01-5.52493e-02 1.36238e+00 + 3.32564e-01-5.30363e-02 1.33301e+00 2.74439e-01-5.20857e-02 1.34786e+00 + 2.06300e-01-5.31063e-02 1.36237e+00 1.14752e-01-5.23530e-02 1.37303e+00 + 4.63663e-02-5.47300e-02 1.37887e+00 1.17629e-01-5.65627e-02 1.37302e+00 + 4.25113e-02-4.88403e-02 1.37444e+00 1.10897e-01-5.00330e-02 1.37220e+00 diff --git a/resources/blow5_ascii_cd_thickness b/resources/blow5_ascii_cd_thickness new file mode 100644 index 000000000..31f2283ad --- /dev/null +++ b/resources/blow5_ascii_cd_thickness @@ -0,0 +1,181 @@ +thickness +part 1 +quad4 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 +tria3 + 6.75982e-01 6.79165e-01 6.79126e-01 6.81478e-01 6.84119e-01 6.80832e-01 + 6.75583e-01 6.78697e-01 6.80298e-01 6.83705e-01 6.84803e-01 6.78779e-01 + 6.75748e-01 6.78935e-01 6.80706e-01 6.84031e-01 6.84673e-01 6.78893e-01 + 6.75582e-01 6.78617e-01 6.78697e-01 6.81307e-01 6.83663e-01 6.80217e-01 + 7.19629e-01 7.03539e-01 7.22064e-01 7.13957e-01 7.04044e-01 7.25095e-01 + 7.23473e-01 7.07851e-01 6.88092e-01 6.80420e-01 6.80324e-01 6.82754e-01 + 6.86534e-01 6.83406e-01 6.84373e-01 6.89585e-01 6.72929e-01 6.74277e-01 + 6.74525e-01 6.73054e-01 6.74308e-01 6.76506e-01 6.75427e-01 6.76397e-01 + 6.76077e-01 6.76665e-01 6.78238e-01 6.78282e-01 7.24692e-01 7.25523e-01 + 7.08641e-01 7.09402e-01 7.22966e-01 7.04515e-01 6.95661e-01 7.05978e-01 + 6.84481e-01 6.83729e-01 6.90055e-01 6.82828e-01 6.80561e-01 6.86754e-01 + 6.79771e-01 6.84582e-01 6.75101e-01 6.76434e-01 6.76184e-01 6.72476e-01 + 6.74124e-01 6.73884e-01 6.74039e-01 6.72450e-01 6.76452e-01 6.75765e-01 + 6.77872e-01 6.78085e-01 6.78275e-01 6.78358e-01 6.76737e-01 6.75980e-01 + 6.74126e-01 6.72673e-01 6.72819e-01 6.74310e-01 6.74040e-01 6.75253e-01 + 6.76421e-01 6.76221e-01 6.76860e-01 6.83420e-01 6.83654e-01 6.82544e-01 + 6.89172e-01 6.84794e-01 6.84037e-01 6.90583e-01 6.96028e-01 7.10989e-01 + 7.16853e-01 7.23481e-01 7.06827e-01 7.24872e-01 7.26244e-01 7.09247e-01 + 6.77825e-01 6.78078e-01 6.75687e-01 6.76330e-01 6.76399e-01 6.75189e-01 + 6.76162e-01 6.74277e-01 6.72836e-01 6.74005e-01 6.72710e-01 6.73984e-01 + 6.83724e-01 6.84785e-01 6.90350e-01 6.80520e-01 6.83050e-01 6.87301e-01 + 6.89361e-01 6.80964e-01 7.26161e-01 7.24662e-01 7.08938e-01 7.23340e-01 + 7.15507e-01 7.05241e-01 7.21487e-01 7.05067e-01 7.61512e-01 7.38943e-01 + 7.55875e-01 7.51751e-01 7.42854e-01 7.69560e-01 7.57973e-01 7.51246e-01 + 7.57245e-01 7.66413e-01 7.49508e-01 7.67944e-01 7.61018e-01 7.54318e-01 + 6.75564e-01 6.74690e-01 6.74087e-01 6.74644e-01 6.75125e-01 6.75120e-01 + 6.75688e-01 6.76218e-01 6.76064e-01 6.77010e-01 6.77247e-01 6.77279e-01 + 6.77230e-01 6.77897e-01 6.71515e-01 6.71963e-01 6.72015e-01 6.71520e-01 + 6.72038e-01 6.74109e-01 6.72754e-01 6.73623e-01 6.75105e-01 6.74556e-01 + 6.74973e-01 6.75942e-01 6.75408e-01 6.75792e-01 7.62353e-01 7.68128e-01 + 7.54930e-01 7.66892e-01 7.62034e-01 7.54003e-01 7.58528e-01 7.66557e-01 + 7.51943e-01 7.24646e-01 7.57317e-01 7.47525e-01 7.21159e-01 7.42956e-01 + 6.77279e-01 6.77508e-01 6.78054e-01 6.77249e-01 6.75859e-01 6.77265e-01 + 6.75236e-01 6.74901e-01 6.75855e-01 6.74390e-01 6.73905e-01 6.75280e-01 + 6.72888e-01 6.74426e-01 6.75327e-01 6.75942e-01 6.75720e-01 6.74383e-01 + 6.74982e-01 6.74745e-01 6.72572e-01 6.73943e-01 6.73328e-01 6.70819e-01 + 6.71724e-01 6.71453e-01 6.71433e-01 6.70825e-01 6.71730e-01 6.71283e-01 + 6.71308e-01 6.71812e-01 6.71822e-01 6.72577e-01 6.73994e-01 6.73465e-01 + 6.74453e-01 6.75003e-01 6.74867e-01 6.75315e-01 6.75878e-01 6.75722e-01 + 6.72871e-01 6.74204e-01 6.75470e-01 6.74044e-01 6.75825e-01 6.75348e-01 + 6.75206e-01 6.76672e-01 6.77207e-01 6.75927e-01 6.77341e-01 6.77215e-01 + 6.77440e-01 6.78026e-01 7.27805e-01 7.44143e-01 7.47461e-01 7.60099e-01 + 7.43214e-01 7.59773e-01 7.66415e-01 7.48790e-01 7.66854e-01 7.58288e-01 + 7.50620e-01 7.61958e-01 7.68528e-01 7.55357e-01 6.75882e-01 6.75323e-01 + 6.75704e-01 6.75022e-01 6.74470e-01 6.74853e-01 6.73994e-01 6.72596e-01 + 6.73465e-01 6.71845e-01 6.71369e-01 6.71858e-01 6.71377e-01 6.71810e-01 + 6.77479e-01 6.77228e-01 6.78031e-01 6.75866e-01 6.77255e-01 6.77274e-01 + 6.76241e-01 6.75240e-01 6.75050e-01 6.73695e-01 6.75048e-01 6.75075e-01 + 6.75452e-01 6.73627e-01 7.68549e-01 7.61911e-01 7.55295e-01 7.58220e-01 + 7.67317e-01 7.50634e-01 7.70402e-01 7.59161e-01 7.52397e-01 7.57213e-01 + 7.53507e-01 7.44463e-01 7.63181e-01 7.40971e-01 7.82153e-01 8.08945e-01 + 8.02520e-01 7.76756e-01 7.78510e-01 8.02115e-01 8.04669e-01 7.80608e-01 + 7.92960e-01 8.09763e-01 7.90207e-01 8.03779e-01 7.79041e-01 7.95098e-01 + 8.05595e-01 7.82814e-01 7.87105e-01 8.06915e-01 6.73213e-01 6.71940e-01 + 6.71493e-01 6.71413e-01 6.72109e-01 6.72438e-01 6.73099e-01 6.72377e-01 + 6.71589e-01 6.71648e-01 6.71528e-01 6.71851e-01 6.72006e-01 6.72133e-01 + 6.73086e-01 6.73575e-01 6.74479e-01 6.73460e-01 6.72350e-01 6.72560e-01 + 6.72426e-01 6.72754e-01 6.73298e-01 6.72993e-01 6.74247e-01 6.74855e-01 + 6.75556e-01 6.74617e-01 6.73506e-01 6.73769e-01 6.73613e-01 6.73971e-01 + 6.74456e-01 6.74184e-01 6.75154e-01 6.75825e-01 6.76149e-01 6.75294e-01 + 6.74589e-01 6.74654e-01 6.74587e-01 6.74721e-01 6.74927e-01 6.74793e-01 + 6.70447e-01 6.70845e-01 6.71284e-01 6.70835e-01 6.70907e-01 6.72262e-01 + 6.72022e-01 6.71670e-01 6.73140e-01 6.72475e-01 6.72752e-01 6.73986e-01 + 6.73400e-01 6.73702e-01 6.74474e-01 6.74191e-01 6.74355e-01 6.75074e-01 + 6.74675e-01 6.74867e-01 6.75425e-01 6.75233e-01 6.75330e-01 6.75695e-01 + 6.75471e-01 6.75631e-01 8.07037e-01 7.87289e-01 7.84131e-01 8.06127e-01 + 8.05599e-01 7.83812e-01 7.86467e-01 8.06317e-01 8.06293e-01 7.86132e-01 + 7.81249e-01 8.04792e-01 8.02897e-01 7.80038e-01 7.87429e-01 8.06463e-01 + 8.06471e-01 7.62581e-01 6.75379e-01 6.76198e-01 6.76008e-01 6.75300e-01 + 6.74937e-01 6.74802e-01 6.74840e-01 6.74768e-01 6.74746e-01 6.74727e-01 + 6.74822e-01 6.75748e-01 6.74795e-01 6.74389e-01 6.74635e-01 6.74202e-01 + 6.74398e-01 6.73986e-01 6.73592e-01 6.73749e-01 6.73309e-01 6.74172e-01 + 6.73509e-01 6.72980e-01 6.73370e-01 6.72874e-01 6.73071e-01 6.72677e-01 + 6.72493e-01 6.72545e-01 6.72334e-01 6.73028e-01 6.72308e-01 6.72079e-01 + 6.72349e-01 6.72039e-01 6.72220e-01 6.71842e-01 6.71750e-01 6.71820e-01 + 6.71761e-01 6.72016e-01 6.71517e-01 6.71665e-01 6.75499e-01 6.75715e-01 + 6.75651e-01 6.75226e-01 6.75426e-01 6.75313e-01 6.74636e-01 6.75088e-01 + 6.74829e-01 6.74161e-01 6.74403e-01 6.74276e-01 6.73371e-01 6.73986e-01 + 6.73662e-01 6.72474e-01 6.73096e-01 6.72713e-01 6.71486e-01 6.72244e-01 + 6.71962e-01 6.70426e-01 6.71015e-01 6.70531e-01 6.70432e-01 6.70568e-01 + 6.70683e-01 6.70625e-01 6.70741e-01 6.71073e-01 6.70665e-01 6.71474e-01 + 6.72062e-01 6.71826e-01 6.72287e-01 6.72965e-01 6.72586e-01 6.73230e-01 + 6.73831e-01 6.73570e-01 6.74091e-01 6.74401e-01 6.74287e-01 6.74572e-01 + 6.74972e-01 6.74764e-01 6.75126e-01 6.75320e-01 6.75229e-01 6.75393e-01 + 6.75568e-01 6.75566e-01 6.70859e-01 6.71028e-01 6.71337e-01 6.72079e-01 + 6.71644e-01 6.71243e-01 6.71575e-01 6.72190e-01 6.71835e-01 6.71945e-01 + 6.72596e-01 6.72249e-01 6.72642e-01 6.73597e-01 6.72481e-01 6.72321e-01 + 6.72456e-01 6.73197e-01 6.72679e-01 6.72913e-01 6.73766e-01 6.72987e-01 + 6.73245e-01 6.74166e-01 6.73744e-01 6.73413e-01 6.73551e-01 6.74419e-01 + 6.73956e-01 6.74180e-01 6.74745e-01 6.74248e-01 6.74665e-01 6.75626e-01 + 6.74577e-01 6.74539e-01 6.74540e-01 6.74831e-01 6.74650e-01 6.74720e-01 + 6.75859e-01 6.75137e-01 6.75244e-01 6.76103e-01 8.08423e-01 7.63799e-01 + 7.85836e-01 8.05835e-01 8.05942e-01 7.86490e-01 7.86396e-01 7.99322e-01 + 7.98710e-01 7.89711e-01 7.90179e-01 8.03656e-01 7.95438e-01 7.79781e-01 + 7.83450e-01 8.05985e-01 8.07255e-01 7.87529e-01 6.75544e-01 6.75375e-01 + 6.75548e-01 6.75369e-01 6.75191e-01 6.75303e-01 6.75005e-01 6.74598e-01 + 6.74816e-01 6.74426e-01 6.74119e-01 6.74320e-01 6.73855e-01 6.73217e-01 + 6.73579e-01 6.72965e-01 6.72330e-01 6.72613e-01 6.72065e-01 6.71797e-01 + 6.71478e-01 6.71030e-01 6.70647e-01 6.70791e-01 6.70636e-01 6.70753e-01 + 6.74667e-01 6.74810e-01 6.74715e-01 6.74678e-01 6.74665e-01 6.74648e-01 + 6.76116e-01 6.75274e-01 6.75209e-01 6.75948e-01 6.74039e-01 6.74538e-01 + 6.74289e-01 6.73418e-01 6.73808e-01 6.73603e-01 6.75724e-01 6.74766e-01 + 6.74311e-01 6.74768e-01 6.72706e-01 6.73193e-01 6.72929e-01 6.72290e-01 + 6.72507e-01 6.72459e-01 6.74142e-01 6.73236e-01 6.72965e-01 6.73681e-01 + 6.71675e-01 6.71809e-01 6.72086e-01 6.71605e-01 6.71505e-01 6.71414e-01 + 6.73465e-01 6.72489e-01 6.72234e-01 6.72755e-01 6.71433e-01 6.71188e-01 + 6.72687e-01 6.71994e-01 7.87550e-01 8.07372e-01 8.06011e-01 7.83395e-01 + 7.79704e-01 7.95593e-01 7.90791e-01 8.04070e-01 7.93400e-01 8.09827e-01 + 8.04905e-01 7.81434e-01 7.79486e-01 8.02490e-01 8.03040e-01 7.78121e-01 + 8.09373e-01 7.83486e-01 6.71375e-01 6.71202e-01 6.71072e-01 6.70435e-01 + 6.71427e-01 6.71393e-01 6.71713e-01 6.71563e-01 6.70762e-01 6.71279e-01 + 6.71716e-01 6.71418e-01 6.71919e-01 6.71972e-01 6.72215e-01 6.72179e-01 + 6.71935e-01 6.72051e-01 6.72312e-01 6.72237e-01 6.72481e-01 6.72321e-01 + 6.72858e-01 6.72643e-01 6.72539e-01 6.72611e-01 6.72834e-01 6.73051e-01 + 6.73041e-01 6.72953e-01 6.73289e-01 6.73211e-01 6.73312e-01 6.73238e-01 + 6.73408e-01 6.73753e-01 6.73676e-01 6.73498e-01 6.74074e-01 6.73840e-01 + 6.73959e-01 6.73869e-01 6.74120e-01 6.74360e-01 6.74274e-01 6.74181e-01 + 6.74454e-01 6.74400e-01 6.74561e-01 6.74466e-01 6.74592e-01 6.74906e-01 + 6.74714e-01 6.74588e-01 6.74951e-01 6.74783e-01 6.75066e-01 6.74933e-01 + 6.75077e-01 6.75278e-01 6.74946e-01 6.74932e-01 6.74926e-01 6.74944e-01 + 6.75324e-01 6.75144e-01 6.75141e-01 6.75413e-01 6.74994e-01 6.74936e-01 + 6.75054e-01 6.74956e-01 6.75433e-01 6.75201e-01 6.75211e-01 6.75359e-01 + 6.74886e-01 6.74950e-01 6.74714e-01 6.74766e-01 6.75286e-01 6.75054e-01 + 6.74934e-01 6.75098e-01 6.74542e-01 6.74603e-01 6.74333e-01 6.74378e-01 + 6.74960e-01 6.74683e-01 6.74515e-01 6.74553e-01 6.73929e-01 6.74098e-01 + 6.73609e-01 6.73712e-01 6.74320e-01 6.74052e-01 6.73835e-01 6.73968e-01 + 6.73307e-01 6.73387e-01 6.73081e-01 6.73095e-01 6.73793e-01 6.73477e-01 + 6.73289e-01 6.73323e-01 6.72912e-01 6.72728e-01 6.72445e-01 6.72547e-01 + 6.73048e-01 6.72844e-01 6.72639e-01 6.72561e-01 6.72250e-01 6.72343e-01 + 6.71975e-01 6.72061e-01 6.72346e-01 6.72229e-01 6.72048e-01 6.71883e-01 + 6.71783e-01 6.71671e-01 6.71541e-01 6.71471e-01 6.71706e-01 6.71315e-01 + 6.71191e-01 6.70959e-01 6.71433e-01 6.71463e-01 6.70598e-01 6.71184e-01 + 6.70662e-01 6.71009e-01 6.71175e-01 6.70983e-01 6.71100e-01 6.70917e-01 + 6.71573e-01 6.71253e-01 6.71109e-01 6.71284e-01 6.71616e-01 6.71481e-01 + 6.71869e-01 6.71744e-01 6.72125e-01 6.72037e-01 6.71791e-01 6.71846e-01 + 6.72011e-01 6.72041e-01 6.72438e-01 6.72347e-01 6.72870e-01 6.72670e-01 + 6.72162e-01 6.72336e-01 6.72715e-01 6.72518e-01 6.73075e-01 6.73135e-01 + 6.73560e-01 6.73232e-01 6.72830e-01 6.72906e-01 6.73062e-01 6.73168e-01 + 6.73705e-01 6.73979e-01 6.74297e-01 6.74072e-01 6.73383e-01 6.73565e-01 + 6.74019e-01 6.73787e-01 6.74383e-01 6.74468e-01 6.74809e-01 6.74503e-01 + 6.74133e-01 6.74210e-01 6.74330e-01 6.74387e-01 6.74823e-01 6.74962e-01 + 6.75167e-01 6.74964e-01 6.74506e-01 6.74615e-01 6.74848e-01 6.74685e-01 + 6.75124e-01 6.75239e-01 6.75132e-01 6.75278e-01 6.74849e-01 6.74918e-01 + 6.74888e-01 6.74804e-01 6.75028e-01 6.75229e-01 6.75221e-01 6.75061e-01 + 6.74783e-01 6.74823e-01 6.74917e-01 6.74803e-01 6.75051e-01 6.75215e-01 + 6.74873e-01 6.75093e-01 6.74851e-01 6.74852e-01 6.74715e-01 6.74612e-01 + 6.74538e-01 6.74824e-01 6.74488e-01 6.74417e-01 6.74472e-01 6.74383e-01 + 6.74262e-01 6.74186e-01 6.74099e-01 6.74316e-01 6.73729e-01 6.74008e-01 + 6.74053e-01 6.73822e-01 6.73590e-01 6.73390e-01 6.73250e-01 6.73581e-01 + 6.73122e-01 6.73084e-01 6.73166e-01 6.73077e-01 6.72874e-01 6.72882e-01 + 6.72672e-01 6.72869e-01 6.72295e-01 6.72484e-01 6.72716e-01 6.72523e-01 + 6.72291e-01 6.72106e-01 6.72070e-01 6.71995e-01 6.71671e-01 6.71784e-01 + 6.71944e-01 6.71904e-01 6.71682e-01 6.71727e-01 6.71487e-01 6.71165e-01 + 6.70609e-01 6.71009e-01 6.71506e-01 6.71381e-01 6.71206e-01 6.71167e-01 + 6.70996e-01 6.70834e-01 6.71197e-01 6.71250e-01 diff --git a/resources/blow5_ascii_pd_displacement b/resources/blow5_ascii_pd_displacement new file mode 100644 index 000000000..69bcaa421 --- /dev/null +++ b/resources/blow5_ascii_pd_displacement @@ -0,0 +1,345 @@ +displacement + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00-7.49000e-03 5.49924e-01 0.00000e+00 7.16500e-03 9.43663e-01 + 0.00000e+00 2.79480e-02 1.20103e+00 0.00000e+00 2.82800e-02 1.30706e+00 + 0.00000e+00 4.67360e-02 1.37094e+00 0.00000e+00 6.03940e-02 1.34435e+00 + 0.00000e+00 4.76790e-02 1.33259e+00 0.00000e+00 3.40650e-02 1.40153e+00 + 0.00000e+00-1.22000e-03 1.20571e+00 0.00000e+00-3.67400e-02 1.40358e+00 + 0.00000e+00-5.04300e-02 1.33859e+00 0.00000e+00-6.29600e-02 1.35976e+00 + 0.00000e+00-4.73310e-02 1.37083e+00 0.00000e+00-2.62700e-02 1.28421e+00 + 0.00000e+00-2.49990e-02 1.10334e+00 0.00000e+00 2.40300e-03 8.11597e-01 + 0.00000e+00 7.96200e-03 4.11260e-01 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 + 0.00000e+00 0.00000e+00 0.00000e+00 0.00000e+00 9.73100e-03-5.68569e-01 + 0.00000e+00-2.18810e-02-1.02108e+00 0.00000e+00-2.38400e-02-1.24789e+00 + 0.00000e+00-3.01300e-02-1.31896e+00 0.00000e+00-4.66290e-02-1.37712e+00 + 0.00000e+00-6.16000e-02-1.36176e+00 0.00000e+00-4.81580e-02-1.33683e+00 + 0.00000e+00-3.50600e-02-1.40468e+00 0.00000e+00 3.20000e-04-1.20696e+00 + 0.00000e+00 3.68280e-02-1.40372e+00 0.00000e+00 4.96750e-02-1.33925e+00 + 0.00000e+00 6.20060e-02-1.36048e+00 0.00000e+00 4.98610e-02-1.37654e+00 + 0.00000e+00 2.65300e-02-1.30795e+00 0.00000e+00 2.53950e-02-1.12219e+00 + 0.00000e+00-1.51400e-03-8.34800e-01 0.00000e+00-7.86000e-03-4.27493e-01 + 0.00000e+00 6.06440e-02-1.36694e+00 0.00000e+00 5.85780e-02-1.37314e+00 + 0.00000e+00 5.55910e-02-1.38462e+00 0.00000e+00 6.18740e-02 1.37206e+00 + 0.00000e+00 5.74250e-02 1.38203e+00 0.00000e+00 5.08550e-02 1.38049e+00 + 0.00000e+00-6.03000e-02-1.36897e+00 0.00000e+00-5.66600e-02-1.38316e+00 + 0.00000e+00-5.02590e-02-1.38335e+00 0.00000e+00-6.15900e-02 1.36586e+00 + 0.00000e+00-5.80400e-02 1.38160e+00 0.00000e+00-5.18400e-02 1.38169e+00 + 0.00000e+00 3.66670e-02-1.35964e+00 0.00000e+00 4.40060e-02-1.37215e+00 + 0.00000e+00 3.54450e-02 1.37577e+00 0.00000e+00 4.29410e-02 1.37038e+00 + 0.00000e+00-3.76200e-02-1.36083e+00 0.00000e+00-4.31900e-02-1.37544e+00 + 0.00000e+00-3.37320e-02 1.34494e+00 0.00000e+00-4.23690e-02 1.37106e+00 + 8.47777e-01 1.21000e-03-1.09672e+00 6.48637e-01 4.28960e-02-1.16111e+00 + 4.90757e-01 5.65020e-02-1.26254e+00 1.11053e+00 5.55170e-02-8.66263e-01 + 1.43117e+00 5.08670e-02 2.60630e-02 1.33437e+00 2.60000e-04 1.38630e-02 + 1.08374e+00 5.57430e-02 8.97594e-01 4.67334e-01 5.58630e-02 1.26227e+00 + 6.30815e-01 4.19360e-02 1.16533e+00 8.38094e-01-1.19000e-03 1.09853e+00 + 1.43204e+00-5.10600e-02 8.43000e-04 1.09675e+00-5.52600e-02-8.85252e-01 + 4.82759e-01-5.56790e-02-1.26699e+00 6.48289e-01-4.15800e-02-1.15955e+00 + 6.39536e-01-4.37110e-02 1.16579e+00 4.84986e-01-5.75690e-02 1.26426e+00 + 1.10016e+00-5.69400e-02 8.79061e-01 2.00167e-01 7.55900e-03-9.05522e-01 + 4.45563e-01 2.65820e-02-1.15188e+00 4.73742e-01 9.80900e-03-7.98347e-01 + 6.01386e-01-5.39400e-03-5.17234e-01 1.01100e+00 2.85760e-02-7.79238e-01 + 8.50070e-01 6.56500e-03-3.05801e-01 7.81745e-01-9.07200e-03 6.45500e-03 + 1.29130e+00 2.87060e-02 1.10360e-02 3.46580e-01 3.02590e-02-1.25902e+00 + 1.00185e+00 3.69330e-02-8.61826e-01 7.02356e-01 3.38680e-02-1.14949e+00 + 1.31726e+00 3.83280e-02 9.24100e-03 1.27066e+00 3.69740e-02-4.67480e-01 + 3.47197e-01 6.14100e-02-1.31093e+00 7.04583e-01 6.18860e-02-1.19783e+00 + 1.02270e+00 5.68160e-02-8.97948e-01 1.30425e+00 5.73590e-02-4.83078e-01 + 1.35469e+00 5.34580e-02 1.59980e-02 8.38027e-01 5.65200e-03 3.24289e-01 + 5.78919e-01-7.14400e-03 5.29437e-01 9.87674e-01 2.84510e-02 8.00089e-01 + 4.23052e-01 9.00500e-03 8.20046e-01 2.15417e-01 1.70250e-02 9.99533e-01 + 4.53499e-01 2.29580e-02 1.09297e+00 9.49180e-01 3.68680e-02 9.38707e-01 + 1.26349e+00 3.77830e-02 5.00549e-01 2.72779e-01 2.75790e-02 1.26457e+00 + 6.14457e-01 3.07230e-02 1.19977e+00 1.29314e+00 5.75550e-02 5.14519e-01 + 1.00383e+00 5.73000e-02 9.19288e-01 6.79435e-01 6.22620e-02 1.21698e+00 + 2.84337e-01 6.18620e-02 1.34146e+00 3.41950e-01-6.09890e-02-1.31381e+00 + 1.01415e+00-5.67400e-02-9.08590e-01 6.97094e-01-6.15810e-02-1.20315e+00 + 1.35478e+00-5.37210e-02-8.94000e-04 1.29946e+00-5.74610e-02-4.98101e-01 + 2.88338e-01-2.94400e-02-1.28471e+00 4.28097e-01-2.61610e-02-1.11642e+00 + 6.66269e-01-3.17000e-02-1.15444e+00 9.64165e-01-3.63310e-02-9.18140e-01 + 9.88454e-01-2.64610e-02-7.78044e-01 1.26765e+00-3.65690e-02-4.84365e-01 + 1.31613e+00-3.75190e-02 5.88300e-03 1.28419e+00-2.75400e-02 6.45100e-03 + 2.28770e-01-4.62000e-03-8.56446e-01 5.87255e-01 7.56000e-03-5.00341e-01 + 4.62771e-01-8.41900e-03-7.64502e-01 7.68562e-01 1.00600e-02 2.13200e-03 + 8.31784e-01-4.97100e-03-3.04992e-01 1.01681e+00-5.77410e-02 9.05016e-01 + 1.29986e+00-5.81020e-02 4.95697e-01 3.44044e-01-6.23490e-02 1.31154e+00 + 6.99128e-01-6.28490e-02 1.19981e+00 1.26288e+00-3.70310e-02 5.00561e-01 + 9.50884e-01-3.69600e-02 9.35101e-01 9.83196e-01-2.76800e-02 7.94947e-01 + 6.62213e-01-3.25010e-02 1.16451e+00 2.96329e-01-3.06490e-02 1.29647e+00 + 4.22281e-01-2.62700e-02 1.13840e+00 5.86270e-01 6.22900e-03 5.12392e-01 + 8.34943e-01-5.57000e-03 3.11651e-01 1.93556e-01-6.80900e-03 8.86027e-01 + 4.60365e-01-8.87700e-03 7.84976e-01 7.55320e-02-1.20900e-02-5.78367e-01 + 1.59742e-01-2.87000e-03-5.00409e-01 2.31992e-01-1.83800e-02-4.53271e-01 + 2.78128e-01-7.71000e-03-3.62719e-01 2.96818e-01-1.66600e-02-2.46982e-01 + 4.31547e-01-8.33000e-03-2.44275e-01 4.54826e-01-1.94600e-02-1.73568e-01 + 4.47444e-01-6.87000e-03-8.23880e-02 4.36135e-01-2.38700e-02 1.21100e-03 + 1.84036e-01 3.30980e-02-1.32439e+00 6.25372e-01 3.92520e-02-1.18649e+00 + 3.85532e-01 3.75120e-02-1.31563e+00 9.85762e-01 4.13810e-02-8.96694e-01 + 8.28527e-01 4.13870e-02-1.06979e+00 1.24064e+00 4.24480e-02-4.81853e-01 + 1.14744e+00 4.25000e-02-7.13130e-01 1.32545e+00 4.25200e-02 5.80800e-03 + 1.32441e+00 4.31710e-02-2.45711e-01 1.69996e-01 6.10160e-02-1.35834e+00 + 3.63296e-01 6.00150e-02-1.33845e+00 5.65824e-01 5.68080e-02-1.25366e+00 + 8.17994e-01 5.60390e-02-1.10404e+00 9.92587e-01 5.42080e-02-9.30405e-01 + 1.15579e+00 5.43930e-02-7.27740e-01 1.26022e+00 5.30140e-02-4.96932e-01 + 1.33850e+00 5.31080e-02-2.48583e-01 1.35202e+00 5.20490e-02 8.74800e-03 + 4.43422e-01-7.03000e-03 8.49900e-02 4.35370e-01-2.08800e-02 1.74990e-01 + 3.79167e-01-6.15000e-03 2.48063e-01 3.17950e-01-2.29800e-02 3.03704e-01 + 2.70455e-01-6.62000e-03 3.73816e-01 2.03310e-01-2.05300e-02 4.30734e-01 + 1.09858e-01-9.03000e-03 4.35654e-01 1.54147e-01 1.45500e-03 7.46632e-01 + 1.23373e+00 4.29700e-02 4.99544e-01 1.32170e+00 4.34730e-02 2.60528e-01 + 9.68427e-01 4.19540e-02 9.20974e-01 1.13113e+00 4.28670e-02 7.38271e-01 + 6.82856e-01 3.83830e-02 1.15954e+00 8.38898e-01 4.21740e-02 1.06355e+00 + 2.58945e-01 3.15340e-02 1.32183e+00 3.89679e-01 3.76180e-02 1.31471e+00 + 1.33471e+00 5.31810e-02 2.67772e-01 1.25326e+00 5.32360e-02 5.14153e-01 + 1.14457e+00 5.47760e-02 7.44837e-01 9.79767e-01 5.44750e-02 9.43500e-01 + 8.03181e-01 5.62480e-02 1.11498e+00 5.49255e-01 5.67340e-02 1.25953e+00 + 3.48534e-01 6.02010e-02 1.34093e+00 1.94584e-01 6.08840e-02 1.35910e+00 + 1.72654e-01-6.06810e-02-1.36038e+00 5.61285e-01-5.64800e-02-1.25758e+00 + 3.64701e-01-5.97590e-02-1.33870e+00 9.93294e-01-5.41190e-02-9.31401e-01 + 8.14429e-01-5.58110e-02-1.10843e+00 1.25781e+00-5.31290e-02-5.06218e-01 + 1.15432e+00-5.44300e-02-7.31523e-01 1.35294e+00-5.23000e-02-9.64800e-03 + 1.33667e+00-5.32920e-02-2.63072e-01 1.76847e-01-3.54500e-02-1.33673e+00 + 4.39448e-01-3.74510e-02-1.29027e+00 7.11389e-01-3.81010e-02-1.13538e+00 + 8.52951e-01-4.19900e-02-1.05243e+00 9.81151e-01-4.15590e-02-9.07317e-01 + 1.13920e+00-4.24900e-02-7.28655e-01 1.23812e+00-4.22900e-02-4.89928e-01 + 1.32429e+00-4.29000e-02-2.52206e-01 1.32551e+00-4.20710e-02 3.82800e-03 + 9.96210e-02-2.54100e-03-7.27661e-01 1.98676e-01 1.53310e-02-3.68376e-01 + 1.37594e-01 7.24100e-03-5.04981e-01 2.91836e-01 1.51600e-02-2.44838e-01 + 3.05761e-01 1.00710e-02-3.66284e-01 4.38990e-01 1.95930e-02-1.71437e-01 + 4.20391e-01 9.07100e-03-2.39893e-01 4.24206e-01 2.36700e-02 4.79000e-04 + 4.37222e-01 7.01900e-03-8.21560e-02 1.26104e+00-5.35910e-02 4.96149e-01 + 1.33884e+00-5.35600e-02 2.50256e-01 9.93753e-01-5.49410e-02 9.29668e-01 + 1.15545e+00-5.50710e-02 7.28066e-01 5.66670e-01-5.75510e-02 1.25300e+00 + 8.17750e-01-5.68000e-02 1.10381e+00 1.73175e-01-6.19700e-02 1.35723e+00 + 3.66026e-01-6.09820e-02 1.33605e+00 1.32317e+00-4.30820e-02 2.58074e-01 + 1.23361e+00-4.26900e-02 4.99663e-01 1.12936e+00-4.29590e-02 7.41513e-01 + 9.63692e-01-4.23180e-02 9.26688e-01 8.36617e-01-4.29290e-02 1.06579e+00 + 7.01698e-01-3.89690e-02 1.14317e+00 4.41152e-01-3.81510e-02 1.28506e+00 + 2.31088e-01-3.61310e-02 1.32090e+00 4.42226e-01 1.95770e-02 1.73027e-01 + 4.38652e-01 7.27800e-03 8.28500e-02 2.88609e-01 1.64530e-02 2.42203e-01 + 4.23141e-01 8.51000e-03 2.42201e-01 2.24907e-01 1.85200e-02 4.39714e-01 + 2.72440e-01 7.72900e-03 3.55323e-01 7.39320e-02 1.25200e-02 5.65537e-01 + 1.56252e-01 3.30700e-03 4.88115e-01 1.81632e-01 4.27040e-02-1.36346e+00 + 1.55255e-01 4.75070e-02-1.36916e+00 3.68252e-01 4.61330e-02-1.32654e+00 + 6.14163e-01 4.37960e-02-1.23697e+00 3.63561e-01 5.05900e-02-1.32459e+00 + 2.59855e-01 4.97080e-02-1.35116e+00 5.34988e-01 4.78730e-02-1.26084e+00 + 4.61553e-01 4.96350e-02-1.29244e+00 7.98863e-01 4.57860e-02-1.11283e+00 + 9.98758e-01 4.53150e-02-9.43471e-01 7.69367e-01 4.89650e-02-1.12855e+00 + 6.66082e-01 4.79990e-02-1.19608e+00 9.76086e-01 4.82060e-02-9.48156e-01 + 8.91094e-01 4.85530e-02-1.03660e+00 1.14042e+00 4.61620e-02-7.44296e-01 + 1.27064e+00 4.58490e-02-5.10786e-01 1.12374e+00 4.86010e-02-7.62900e-01 + 1.05080e+00 4.80640e-02-8.65833e-01 1.25283e+00 4.80440e-02-5.15682e-01 + 1.20416e+00 4.83040e-02-6.31451e-01 1.33154e+00 4.62250e-02-2.65232e-01 + 1.36686e+00 4.58450e-02-7.20000e-05 1.32349e+00 4.82890e-02-2.84321e-01 + 1.29257e+00 4.78850e-02-4.10566e-01 1.35234e+00 4.78970e-02-5.80200e-03 + 1.34973e+00 4.80990e-02-1.32289e-01 1.23201e-01 5.86800e-02-1.37406e+00 + 2.09590e-01 5.58010e-02-1.36386e+00 3.75709e-01 5.54450e-02-1.32209e+00 + 4.65464e-01 5.42440e-02-1.28852e+00 5.49240e-01 5.35610e-02-1.25302e+00 + 6.87777e-01 5.34820e-02-1.18450e+00 7.97711e-01 5.33050e-02-1.10502e+00 + 8.96730e-01 5.26540e-02-1.02766e+00 9.82238e-01 5.23420e-02-9.37141e-01 + 1.07107e+00 5.20550e-02-8.38771e-01 1.14257e+00 5.20390e-02-7.28893e-01 + 1.20737e+00 5.15410e-02-6.20170e-01 1.25453e+00 5.13640e-02-5.02720e-01 + 1.30191e+00 5.10730e-02-3.77215e-01 1.32790e+00 5.11610e-02-2.47805e-01 + 1.34792e+00 5.08610e-02-1.21394e-01 1.34889e+00 5.08030e-02 6.06300e-03 + 1.33321e+00 4.64210e-02 2.54617e-01 1.26870e+00 4.62120e-02 5.14098e-01 + 1.33213e+00 4.84140e-02 2.37081e-01 1.35033e+00 4.78500e-02 1.06612e-01 + 1.25574e+00 4.83070e-02 5.06459e-01 1.30024e+00 4.84400e-02 3.87763e-01 + 1.14242e+00 4.64870e-02 7.38335e-01 9.94406e-01 4.56230e-02 9.44106e-01 + 1.14697e+00 4.88350e-02 7.24431e-01 1.21227e+00 4.82620e-02 6.09595e-01 + 9.79802e-01 4.83330e-02 9.42896e-01 1.06366e+00 4.87200e-02 8.49962e-01 + 8.03458e-01 4.58400e-02 1.10753e+00 6.18040e-01 4.33360e-02 1.22974e+00 + 7.81589e-01 4.92590e-02 1.11936e+00 9.01437e-01 4.82350e-02 1.02394e+00 + 5.26793e-01 4.75280e-02 1.26186e+00 6.65798e-01 4.79130e-02 1.19438e+00 + 3.53547e-01 4.57520e-02 1.33011e+00 1.75181e-01 4.21780e-02 1.36239e+00 + 3.42508e-01 5.03630e-02 1.32914e+00 4.47121e-01 4.93110e-02 1.29590e+00 + 1.21661e-01 4.67170e-02 1.37078e+00 2.02504e-01 4.99610e-02 1.36312e+00 + 1.34641e+00 5.08760e-02 1.40669e-01 1.32329e+00 5.12860e-02 2.70609e-01 + 1.29553e+00 5.13230e-02 3.96115e-01 1.24916e+00 5.15960e-02 5.14937e-01 + 1.19765e+00 5.17840e-02 6.38721e-01 1.12845e+00 5.23650e-02 7.49691e-01 + 1.05661e+00 5.23870e-02 8.55268e-01 9.71177e-01 5.25350e-02 9.47522e-01 + 8.80231e-01 5.28200e-02 1.04073e+00 7.80331e-01 5.35660e-02 1.11710e+00 + 6.72163e-01 5.36130e-02 1.19141e+00 5.33534e-01 5.33470e-02 1.25908e+00 + 4.48147e-01 5.40340e-02 1.29456e+00 3.61022e-01 5.55170e-02 1.32688e+00 + 2.08241e-01 5.64370e-02 1.36549e+00 1.51406e-01 5.93240e-02 1.37346e+00 + 1.49161e-01-5.86400e-02-1.37251e+00 3.69332e-01-5.52780e-02-1.32575e+00 + 2.10882e-01-5.60110e-02-1.36573e+00 5.43578e-01-5.32510e-02-1.25719e+00 + 4.60138e-01-5.39710e-02-1.29221e+00 7.93257e-01-5.31100e-02-1.11017e+00 + 6.85115e-01-5.32100e-02-1.18763e+00 9.98684e-01-5.17900e-02-9.24355e-01 + 8.96217e-01-5.23800e-02-1.03047e+00 1.14314e+00-5.21690e-02-7.29921e-01 + 1.08490e+00-5.23110e-02-8.19450e-01 1.25289e+00-5.14600e-02-5.10408e-01 + 1.20631e+00-5.16400e-02-6.24646e-01 1.32597e+00-5.13800e-02-2.64145e-01 + 1.30082e+00-5.12110e-02-3.85299e-01 1.35174e+00-5.07510e-02-2.79440e-02 + 1.34440e+00-5.13120e-02-1.54822e-01 7.34800e-02-4.68010e-02-1.37744e+00 + 1.84148e-01-4.22490e-02-1.36854e+00 1.95955e-01-4.87200e-02-1.36668e+00 + 3.55756e-01-5.01780e-02-1.32805e+00 4.02975e-01-4.55710e-02-1.31660e+00 + 4.65170e-01-4.93390e-02-1.29161e+00 5.46991e-01-4.74890e-02-1.25621e+00 + 6.41887e-01-4.35320e-02-1.21669e+00 6.70122e-01-4.77810e-02-1.19392e+00 + 7.69100e-01-4.87310e-02-1.12946e+00 8.09206e-01-4.57400e-02-1.10594e+00 + 8.89158e-01-4.84200e-02-1.03897e+00 9.73421e-01-4.80810e-02-9.52097e-01 + 9.98188e-01-4.53420e-02-9.42876e-01 1.04517e+00-4.80710e-02-8.74383e-01 + 1.12012e+00-4.86790e-02-7.70964e-01 1.13749e+00-4.62110e-02-7.50265e-01 + 1.20359e+00-4.84300e-02-6.35583e-01 1.25342e+00-4.81300e-02-5.17918e-01 + 1.26911e+00-4.58390e-02-5.18013e-01 1.29278e+00-4.79480e-02-4.14871e-01 + 1.32379e+00-4.83400e-02-2.88690e-01 1.33191e+00-4.61590e-02-2.70015e-01 + 1.35127e+00-4.81800e-02-1.30421e-01 1.35382e+00-4.78900e-02-1.02600e-03 + 1.36803e+00-4.57000e-02-3.10400e-03 1.32802e+00-5.16200e-02 2.53031e-01 + 1.34916e+00-5.10500e-02 1.29422e-01 1.26374e+00-5.15900e-02 4.84929e-01 + 1.30493e+00-5.18490e-02 3.61712e-01 1.14363e+00-5.27800e-02 7.27727e-01 + 1.20725e+00-5.20800e-02 6.21586e-01 9.97989e-01-5.25800e-02 9.23475e-01 + 1.08516e+00-5.30090e-02 8.17421e-01 7.94394e-01-5.42600e-02 1.10842e+00 + 8.90222e-01-5.32900e-02 1.03393e+00 5.64171e-01-5.37510e-02 1.24784e+00 + 7.00855e-01-5.46920e-02 1.17439e+00 3.70322e-01-5.64010e-02 1.32436e+00 + 4.62509e-01-5.48290e-02 1.29092e+00 1.49656e-01-5.99410e-02 1.37018e+00 + 2.13789e-01-5.73380e-02 1.36413e+00 1.35142e+00-4.78400e-02 1.08439e-01 + 1.33357e+00-4.84900e-02 2.34990e-01 1.33463e+00-4.63290e-02 2.52584e-01 + 1.30062e+00-4.86390e-02 3.91389e-01 1.25277e+00-4.85800e-02 5.17718e-01 + 1.26862e+00-4.62710e-02 5.18520e-01 1.19979e+00-4.88890e-02 6.39502e-01 + 1.11817e+00-4.93300e-02 7.71738e-01 1.13167e+00-4.67890e-02 7.56888e-01 + 1.03948e+00-4.88000e-02 8.79360e-01 9.67407e-01-4.86790e-02 9.57479e-01 + 9.87678e-01-4.60790e-02 9.52280e-01 8.93526e-01-4.88090e-02 1.03273e+00 + 7.77433e-01-5.01310e-02 1.12433e+00 8.00886e-01-4.66810e-02 1.11119e+00 + 6.56422e-01-4.88900e-02 1.20087e+00 5.22861e-01-4.82500e-02 1.26601e+00 + 6.27219e-01-4.44200e-02 1.22372e+00 4.42146e-01-4.99090e-02 1.29930e+00 + 3.43516e-01-5.12480e-02 1.32979e+00 3.64379e-01-4.62710e-02 1.33062e+00 + 2.05158e-01-5.09090e-02 1.36409e+00 1.27534e-01-4.73500e-02 1.37081e+00 + 1.97019e-01-4.12000e-02 1.36059e+00 1.49880e-01 5.17840e-02-1.37086e+00 + 2.90300e-01 5.28290e-02-1.34577e+00 3.91263e-01 5.30260e-02-1.31554e+00 + 4.69080e-01 5.20470e-02-1.28998e+00 5.82921e-01 5.07930e-02-1.24210e+00 + 7.02128e-01 5.05450e-02-1.17294e+00 8.08508e-01 5.11990e-02-1.10361e+00 + 8.93370e-01 5.07210e-02-1.02867e+00 9.85444e-01 5.03080e-02-9.45981e-01 + 1.07736e+00 4.99200e-02-8.29595e-01 1.15245e+00 5.03380e-02-7.23129e-01 + 1.20470e+00 4.99990e-02-6.21505e-01 1.26095e+00 4.96780e-02-5.09688e-01 + 1.30449e+00 4.93700e-02-3.65223e-01 1.33535e+00 4.97550e-02-2.37326e-01 + 1.34646e+00 4.95510e-02-1.22472e-01 1.35750e+00 4.93820e-02 2.73100e-03 + 1.34456e+00 4.93200e-02 1.54044e-01 1.32598e+00 4.99330e-02 2.84482e-01 + 1.29375e+00 4.99320e-02 3.95700e-01 1.25772e+00 4.99390e-02 5.15941e-01 + 1.18961e+00 4.99280e-02 6.51679e-01 1.12482e+00 5.06810e-02 7.64768e-01 + 1.05438e+00 5.05940e-02 8.55510e-01 9.77370e-01 5.04990e-02 9.52912e-01 + 8.64300e-01 5.05550e-02 1.05434e+00 7.80198e-01 5.17910e-02 1.12132e+00 + 6.94001e-01 5.06920e-02 1.17635e+00 5.71513e-01 5.06180e-02 1.24576e+00 + 4.51755e-01 5.17540e-02 1.29510e+00 3.73163e-01 5.29000e-02 1.32026e+00 + 2.70244e-01 5.31660e-02 1.34983e+00 1.36606e-01 5.33670e-02 1.37317e+00 + 1.33390e-01-5.27280e-02-1.37524e+00 2.73369e-01-5.27490e-02-1.35082e+00 + 3.82844e-01-5.27900e-02-1.31920e+00 4.64896e-01-5.17400e-02-1.29284e+00 + 5.83429e-01-5.04800e-02-1.24273e+00 7.01673e-01-5.02800e-02-1.17419e+00 + 8.06607e-01-5.09820e-02-1.10636e+00 8.88953e-01-5.04610e-02-1.03426e+00 + 9.68789e-01-4.98910e-02-9.62745e-01 1.06441e+00-5.02300e-02-8.50370e-01 + 1.15165e+00-5.05010e-02-7.26484e-01 1.20410e+00-5.01220e-02-6.25536e-01 + 1.26048e+00-4.97910e-02-5.14528e-01 1.30452e+00-4.94690e-02-3.71279e-01 + 1.33575e+00-4.99610e-02-2.45488e-01 1.34996e+00-4.99000e-02-1.09201e-01 + 1.35770e+00-4.92810e-02 1.70510e-02 1.34614e+00-4.93910e-02 1.52986e-01 + 1.32925e+00-5.02090e-02 2.77041e-01 1.29158e+00-5.04700e-02 4.09558e-01 + 1.25097e+00-5.01010e-02 5.31269e-01 1.20051e+00-5.05480e-02 6.30747e-01 + 1.15040e+00-5.10810e-02 7.26569e-01 1.06305e+00-5.09420e-02 8.50677e-01 + 9.63779e-01-5.05690e-02 9.67257e-01 8.62537e-01-5.10810e-02 1.05766e+00 + 7.85754e-01-5.26010e-02 1.11925e+00 6.74224e-01-5.19190e-02 1.19131e+00 + 5.52728e-01-5.08500e-02 1.25486e+00 4.56318e-01-5.23900e-02 1.29504e+00 + 3.79534e-01-5.37610e-02 1.31956e+00 2.74643e-01-5.41000e-02 1.34969e+00 + 1.39099e-01-5.43100e-02 1.37332e+00 1.27171e+00 3.25060e-02-4.88925e-01 + 1.26016e+00 3.28880e-02 5.16748e-01 1.26965e+00-3.17100e-02-4.97322e-01 + 1.26569e+00-3.36400e-02 5.08598e-01 diff --git a/resources/blow5_ascii_pd_thickness b/resources/blow5_ascii_pd_thickness new file mode 100644 index 000000000..cf025511a --- /dev/null +++ b/resources/blow5_ascii_pd_thickness @@ -0,0 +1,116 @@ +thickness + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 9.07029e-01 + 9.07029e-01 9.07029e-01 8.36678e-01 8.35487e-01 7.98732e-01 8.33593e-01 + 7.97518e-01 8.34963e-01 8.12800e-01 8.13982e-01 7.99230e-01 8.34150e-01 + 8.03192e-01 8.33964e-01 8.00460e-01 8.33338e-01 8.02613e-01 8.34271e-01 + 7.98110e-01 8.32221e-01 8.08808e-01 8.35991e-01 7.75118e-01 7.19486e-01 + 6.88724e-01 6.74102e-01 6.71367e-01 6.72270e-01 6.76127e-01 6.75784e-01 + 6.78086e-01 6.75761e-01 6.75901e-01 6.72219e-01 6.71133e-01 6.78711e-01 + 6.99880e-01 7.38752e-01 7.92457e-01 8.40376e-01 7.99670e-01 8.33090e-01 + 7.98020e-01 8.34493e-01 8.12785e-01 8.14213e-01 7.99618e-01 8.34393e-01 + 8.03703e-01 8.34106e-01 7.99893e-01 8.13470e-01 8.13382e-01 8.11113e-01 + 8.10412e-01 8.34799e-01 8.10092e-01 7.74800e-01 7.13648e-01 6.80904e-01 + 6.73854e-01 6.70974e-01 6.72131e-01 6.76392e-01 6.76125e-01 6.77941e-01 + 6.75898e-01 6.76289e-01 6.72411e-01 6.71408e-01 6.77375e-01 6.98361e-01 + 7.36809e-01 7.91425e-01 6.70900e-01 6.70040e-01 6.70863e-01 6.70669e-01 + 6.70853e-01 6.71435e-01 6.70690e-01 6.70854e-01 6.71076e-01 6.70782e-01 + 6.70780e-01 6.71185e-01 6.72725e-01 6.71449e-01 6.71873e-01 6.71597e-01 + 6.71826e-01 6.70705e-01 6.72956e-01 6.71158e-01 6.81008e-01 6.77810e-01 + 6.74133e-01 6.76004e-01 6.77692e-01 6.87668e-01 6.75582e-01 6.73722e-01 + 6.77446e-01 6.80386e-01 6.77568e-01 6.75695e-01 6.73856e-01 6.77693e-01 + 6.77328e-01 6.73831e-01 6.75587e-01 7.23716e-01 6.88541e-01 7.29614e-01 + 7.42599e-01 6.93977e-01 7.33842e-01 7.45708e-01 6.95735e-01 6.75346e-01 + 6.77198e-01 6.77086e-01 6.78343e-01 6.79042e-01 6.72244e-01 6.72787e-01 + 6.74784e-01 6.75493e-01 6.76332e-01 7.35125e-01 7.43886e-01 6.95064e-01 + 7.29949e-01 7.09724e-01 6.88533e-01 6.76756e-01 6.79366e-01 6.76487e-01 + 6.76664e-01 6.75279e-01 6.74441e-01 6.72348e-01 6.71359e-01 6.72032e-01 + 6.74665e-01 6.72570e-01 6.76296e-01 6.75400e-01 6.75824e-01 6.93533e-01 + 6.78277e-01 6.76978e-01 6.95706e-01 6.79426e-01 6.78337e-01 6.96618e-01 + 7.25787e-01 7.43494e-01 7.31241e-01 7.46699e-01 7.35416e-01 6.74649e-01 + 6.75332e-01 6.72081e-01 6.72597e-01 6.79401e-01 6.76739e-01 6.95032e-01 + 6.77379e-01 6.74687e-01 6.89493e-01 7.43789e-01 7.35165e-01 7.25829e-01 + 7.31200e-01 7.56303e-01 7.75233e-01 7.62779e-01 7.81526e-01 7.84555e-01 + 7.72084e-01 7.65808e-01 7.83403e-01 7.74719e-01 6.73972e-01 6.73903e-01 + 6.72943e-01 6.75495e-01 6.74370e-01 6.76487e-01 6.75499e-01 6.77040e-01 + 6.76307e-01 6.71233e-01 6.71084e-01 6.72175e-01 6.73300e-01 6.74245e-01 + 6.74641e-01 6.75180e-01 6.75550e-01 6.75945e-01 7.83956e-01 7.67977e-01 + 7.82999e-01 7.73790e-01 7.81994e-01 7.63642e-01 7.78360e-01 7.34265e-01 + 6.76707e-01 6.76453e-01 6.75148e-01 6.75674e-01 6.74144e-01 6.73804e-01 + 6.72688e-01 6.72362e-01 6.75550e-01 6.75152e-01 6.74514e-01 6.74193e-01 + 6.73194e-01 6.72172e-01 6.70653e-01 6.70446e-01 6.71027e-01 6.72001e-01 + 6.70865e-01 6.74158e-01 6.73160e-01 6.75074e-01 6.74536e-01 6.75869e-01 + 6.75470e-01 6.72934e-01 6.73374e-01 6.74760e-01 6.73880e-01 6.75186e-01 + 6.75619e-01 6.76578e-01 6.76315e-01 6.76992e-01 7.43981e-01 7.76442e-01 + 7.72615e-01 7.84117e-01 7.71635e-01 7.66500e-01 7.72950e-01 7.74926e-01 + 7.83957e-01 6.75155e-01 6.75483e-01 6.74184e-01 6.74578e-01 6.72043e-01 + 6.73149e-01 6.71129e-01 6.70896e-01 6.76355e-01 6.76681e-01 6.75682e-01 + 6.75177e-01 6.73806e-01 6.74604e-01 6.73160e-01 6.73236e-01 7.66547e-01 + 7.84021e-01 7.85213e-01 7.72948e-01 7.64080e-01 7.82203e-01 7.58332e-01 + 7.76360e-01 6.71646e-01 6.71383e-01 6.71739e-01 6.72451e-01 6.71743e-01 + 6.71462e-01 6.72208e-01 6.72072e-01 6.72437e-01 6.73572e-01 6.72852e-01 + 6.72390e-01 6.73349e-01 6.72971e-01 6.73669e-01 6.74681e-01 6.74041e-01 + 6.73597e-01 6.74483e-01 6.74203e-01 6.74475e-01 6.75101e-01 6.74882e-01 + 6.74604e-01 6.74874e-01 6.74805e-01 6.70403e-01 6.71019e-01 6.71750e-01 + 6.72140e-01 6.72470e-01 6.72780e-01 6.73339e-01 6.73563e-01 6.74151e-01 + 6.74178e-01 6.74603e-01 6.74780e-01 6.75260e-01 6.75259e-01 6.75466e-01 + 6.75397e-01 6.75741e-01 6.74584e-01 6.74864e-01 6.74987e-01 6.74835e-01 + 6.74641e-01 6.74733e-01 6.73929e-01 6.73564e-01 6.74276e-01 6.74400e-01 + 6.73458e-01 6.73753e-01 6.72559e-01 6.72579e-01 6.72976e-01 6.73089e-01 + 6.72405e-01 6.72496e-01 6.72062e-01 6.71813e-01 6.71863e-01 6.72191e-01 + 6.71586e-01 6.71601e-01 6.75458e-01 6.75491e-01 6.75236e-01 6.75289e-01 + 6.74821e-01 6.74573e-01 6.74121e-01 6.74168e-01 6.73598e-01 6.73322e-01 + 6.72772e-01 6.72477e-01 6.72081e-01 6.71633e-01 6.70761e-01 6.70181e-01 + 6.70332e-01 6.71556e-01 6.70799e-01 6.72264e-01 6.71919e-01 6.73138e-01 + 6.72596e-01 6.73946e-01 6.73391e-01 6.74497e-01 6.74169e-01 6.75159e-01 + 6.74683e-01 6.75347e-01 6.75144e-01 6.75474e-01 6.75361e-01 6.70899e-01 + 6.71479e-01 6.71351e-01 6.71687e-01 6.71894e-01 6.71923e-01 6.72018e-01 + 6.72657e-01 6.72287e-01 6.72731e-01 6.72424e-01 6.72882e-01 6.73278e-01 + 6.73432e-01 6.73528e-01 6.74010e-01 6.73694e-01 6.74164e-01 6.74411e-01 + 6.74683e-01 6.74522e-01 6.74795e-01 6.74414e-01 6.74742e-01 6.74748e-01 + 6.75002e-01 6.75352e-01 6.75291e-01 6.75145e-01 6.75272e-01 6.74501e-01 + 6.74715e-01 6.73976e-01 6.74197e-01 6.73098e-01 6.73405e-01 6.72299e-01 + 6.72647e-01 6.71494e-01 6.71854e-01 6.70346e-01 6.70700e-01 6.74678e-01 + 6.74859e-01 6.74464e-01 6.74672e-01 6.74554e-01 6.74807e-01 6.74252e-01 + 6.74058e-01 6.73807e-01 6.73558e-01 6.73251e-01 6.73444e-01 6.72885e-01 + 6.72776e-01 6.72458e-01 6.72287e-01 6.71952e-01 6.72632e-01 6.71800e-01 + 6.71548e-01 6.71675e-01 6.71292e-01 6.71274e-01 6.71868e-01 6.71335e-01 + 6.71484e-01 6.71913e-01 6.72100e-01 6.72366e-01 6.72686e-01 6.73035e-01 + 6.73115e-01 6.73547e-01 6.73883e-01 6.74299e-01 6.74319e-01 6.74677e-01 + 6.74862e-01 6.75109e-01 6.74926e-01 6.75100e-01 6.75046e-01 6.75130e-01 + 6.74795e-01 6.74770e-01 6.74457e-01 6.74266e-01 6.73768e-01 6.73614e-01 + 6.73219e-01 6.73049e-01 6.72712e-01 6.72432e-01 6.72128e-01 6.71935e-01 + 6.71551e-01 6.71262e-01 6.71098e-01 6.71404e-01 6.71758e-01 6.71929e-01 + 6.72182e-01 6.72537e-01 6.72875e-01 6.72960e-01 6.73344e-01 6.73824e-01 + 6.74224e-01 6.74241e-01 6.74584e-01 6.74740e-01 6.75009e-01 6.75001e-01 + 6.74921e-01 6.74871e-01 6.75021e-01 6.74862e-01 6.74611e-01 6.74286e-01 + 6.74249e-01 6.73851e-01 6.73361e-01 6.72983e-01 6.72863e-01 6.72507e-01 + 6.72079e-01 6.71831e-01 6.71666e-01 6.71302e-01 6.71024e-01 6.83680e-01 + 6.83062e-01 6.83416e-01 6.82936e-01 diff --git a/resources/config b/resources/config deleted file mode 100644 index e3471120d..000000000 --- a/resources/config +++ /dev/null @@ -1 +0,0 @@ -language=en diff --git a/resources/explore_med_file.png b/resources/explore_med_file.png new file mode 100644 index 000000000..b9060d6e3 Binary files /dev/null and b/resources/explore_med_file.png differ diff --git a/resources/field_selection.png b/resources/field_selection.png new file mode 100644 index 000000000..11b6e6821 Binary files /dev/null and b/resources/field_selection.png differ diff --git a/resources/mesh_selection.png b/resources/mesh_selection.png new file mode 100644 index 000000000..b1b7dcf08 Binary files /dev/null and b/resources/mesh_selection.png differ diff --git a/resources/square1.med b/resources/square1.med new file mode 100644 index 000000000..3fd7c4111 Binary files /dev/null and b/resources/square1.med differ diff --git a/resources/square1_split b/resources/square1_split new file mode 100644 index 000000000..c6a1bce25 --- /dev/null +++ b/resources/square1_split @@ -0,0 +1,6 @@ +#MED Fichier V 2.3 +# +3 +Mesh_2 1 Mesh_2_1 localhost /home/vb144235/resources/square1_split1.med +Mesh_2 2 Mesh_2_2 localhost /home/vb144235/resources/square1_split2.med +Mesh_2 3 Mesh_2_3 localhost /home/vb144235/resources/square1_split3.med diff --git a/resources/square1_split1.med b/resources/square1_split1.med new file mode 100644 index 000000000..763b1d2ab Binary files /dev/null and b/resources/square1_split1.med differ diff --git a/resources/square1_split2.med b/resources/square1_split2.med new file mode 100644 index 000000000..2e1cd9ff9 Binary files /dev/null and b/resources/square1_split2.med differ diff --git a/resources/square1_split3.med b/resources/square1_split3.med new file mode 100644 index 000000000..9b51ae1d3 Binary files /dev/null and b/resources/square1_split3.med differ diff --git a/resources/square2.med b/resources/square2.med new file mode 100644 index 000000000..9b9d0a40e Binary files /dev/null and b/resources/square2.med differ diff --git a/resources/square2_split b/resources/square2_split new file mode 100644 index 000000000..bad1d1a8f --- /dev/null +++ b/resources/square2_split @@ -0,0 +1,5 @@ +#MED Fichier V 2.3 +# +2 +Mesh_3 1 Mesh_3_1 localhost /home/vb144235/resources/square2_split1.med +Mesh_3 2 Mesh_3_2 localhost /home/vb144235/resources/square2_split2.med diff --git a/resources/square2_split1.med b/resources/square2_split1.med new file mode 100644 index 000000000..497957256 Binary files /dev/null and b/resources/square2_split1.med differ diff --git a/resources/square2_split2.med b/resources/square2_split2.med new file mode 100644 index 000000000..109f2500f Binary files /dev/null and b/resources/square2_split2.med differ diff --git a/resources/trio_2D.med b/resources/trio_2D.med new file mode 100644 index 000000000..06b9dc46a Binary files /dev/null and b/resources/trio_2D.med differ diff --git a/src/INTERPOLATION/MEDMEM_Interpolation.hxx b/src/INTERPOLATION/MEDMEM_Interpolation.hxx index 85a62820c..860c74216 100644 --- a/src/INTERPOLATION/MEDMEM_Interpolation.hxx +++ b/src/INTERPOLATION/MEDMEM_Interpolation.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // # ifndef INTERPOLATION_HXX # define INTERPOLATION_HXX @@ -92,11 +94,11 @@ public : }; -template void INTERPOLATION::init() { - - const char * LOC = "INTERPOLATION::init(): "; +template void INTERPOLATION::init() +{ - BEGIN_OF(LOC); + const char* LOC = "INTERPOLATION::init(): "; + BEGIN_OF_MED(LOC); _fromField = ( FIELD * ) NULL; _toField = ( FIELD * ) NULL; _fromMesh = ( MESH * ) NULL; @@ -104,16 +106,16 @@ template void INTERPOLATION::init() { _fromWrapper = ( Meta_Wrapper * ) NULL; _toWrapper = ( Meta_Wrapper * ) NULL; _mapping = ( Meta_Mapping * ) NULL; - _iType = UNDEFINED ; - _isConvexFromMesh = UNDEFINED ; - END_OF(LOC); + _iType = MED_UNDEFINED ; + _isConvexFromMesh = MED_UNDEFINED ; + END_OF_MED(LOC); } template INTERPOLATION::INTERPOLATION(const MESH & fromMesh ) { const char * LOC = "INTERPOLATION::INTERPOLATION(MESH * fromMesh ) : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); init(); @@ -131,13 +133,13 @@ template INTERPOLATION::INTERPOLATION(const MESH & fr _mapping = new Meta_Mapping (_fromWrapper); - END_OF(LOC); + END_OF_MED(LOC); }; template INTERPOLATION::INTERPOLATION(const MESH & fromMesh,const MESH & toMesh ) { const char * LOC = "INTERPOLATION::INTERPOLATION(MESH * fromMesh,,const MESH & toMesh) : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); init(); @@ -164,13 +166,13 @@ template INTERPOLATION::INTERPOLATION(const MESH & fr _mapping = new Meta_Mapping (_fromWrapper); - END_OF(LOC); + END_OF_MED(LOC); }; template INTERPOLATION::INTERPOLATION(const FIELD & fromField,const MESH & toMesh) { const char * LOC = "INTERPOLATION(const FIELD & field,const MESH & toMesh) : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); init(); @@ -199,7 +201,7 @@ template INTERPOLATION::INTERPOLATION(const FIELD (_fromWrapper); - END_OF(LOC); + END_OF_MED(LOC); }; template INTERPOLATION::~INTERPOLATION() @@ -213,13 +215,13 @@ template int INTERPOLATION::getNearestNode( double * const char * LOC = "INTERPOLATION::getNearestNode( double * node ) "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if ( ! _mapping ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"mapping is a NULL pointer !")) ; return _mapping->Donne_dTree()->trouve_plus_proche_point(Wrapper_Noeud (node) ); - END_OF(LOC); + END_OF_MED(LOC); }; @@ -227,7 +229,7 @@ template int INTERPOLATION::getContainingCell ( doubl const char * LOC = "INTERPOLATION::getContainingCell( double * node ) "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if ( ! _mapping ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"mapping is a NULL pointer !")) ; @@ -237,7 +239,7 @@ template int INTERPOLATION::getContainingCell ( doubl return _mapping->Trouve_Maille_Contenant_Noeud(node,beginingCell,flagIsConvexMesh); - END_OF(LOC); + END_OF_MED(LOC); }; @@ -245,7 +247,7 @@ template vector INTERPOLATION::getMapping ( int const char * LOC = "INTERPOLATION::getMapping( ) "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if ( ! _mapping ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"mapping is a NULL pointer !")) ; if ( ! _toWrapper ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"toWrapper is a NULL pointer !")) ; @@ -256,7 +258,7 @@ template vector INTERPOLATION::getMapping ( int return _mapping->Get_Mapping(); - END_OF(LOC); + END_OF_MED(LOC); }; @@ -264,7 +266,7 @@ template FIELD * INTERPOLATION::interpolate(i const char * LOC = "INTERPOLATION::interpolate(int itype,int flagIsConvexFromMesh) "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if ( ! _mapping ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"mapping is a NULL pointer !")) ; if ( ! _toWrapper ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"toWrapper is a NULL pointer !")) ; @@ -332,7 +334,7 @@ template FIELD * INTERPOLATION::interpolate(i return _toField; - END_OF(LOC); + END_OF_MED(LOC); }; @@ -340,7 +342,7 @@ template FIELD * INTERPOLATION::interpolateNe const char * LOC = "INTERPOLATION::interpolateNextStep(int itype,int flagIsConvexFromMesh) "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if ( ! _mapping ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"mapping is a NULL pointer !" )); if ( ! _toWrapper ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"toWrapper is a NULL pointer !" )) ; @@ -349,8 +351,8 @@ template FIELD * INTERPOLATION::interpolateNe if ( ! _toField ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"toField is a NULL pointer, wrong use of interpolateNextStep" )) ; - if ( _iType==UNDEFINED ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"_iType is not defined, wrong use of interpolateNextStep" )) ; - if ( _isConvexFromMesh==UNDEFINED ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"_isConvexFromMesh is not defined, wrong use of interpolateNextStep" )) ; + if ( _iType==MED_UNDEFINED ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"_iType is not defined, wrong use of interpolateNextStep" )) ; + if ( _isConvexFromMesh==MED_UNDEFINED ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"_isConvexFromMesh is not defined, wrong use of interpolateNextStep" )) ; // delete _toField; ???????????????????????????? diff --git a/src/INTERPOLATION/MEDMEM_InterpolationHighLevelObjects.hxx b/src/INTERPOLATION/MEDMEM_InterpolationHighLevelObjects.hxx index 50d0392c5..d2f4e647e 100644 --- a/src/INTERPOLATION/MEDMEM_InterpolationHighLevelObjects.hxx +++ b/src/INTERPOLATION/MEDMEM_InterpolationHighLevelObjects.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef MEDMEM_INTERPOLATION_HIGHLEVEL_OBJECTS_HXX #define MEDMEM_INTERPOLATION_HIGHLEVEL_OBJECTS_HXX @@ -60,7 +62,8 @@ public : inline int trouve_plus_proche_point_bourrin(double *node); // FIN PATCH inline int trouve_plus_proche_point(double * node); -}; + int get_all_close(double * node, double tolerance, list & closeNumbers); + }; /*********************************************************/ /* */ @@ -270,7 +273,7 @@ public : nlpp = mapping->Get_Noeud_Le_Plus_Proche(i); //cout<<" | et dont le point le plus proche a pour numéro : "< -#ifndef UNDEFINED -#define UNDEFINED -1 +#ifndef MED_UNDEFINED +#define MED_UNDEFINED -1 #endif #ifndef FAUX @@ -176,7 +178,7 @@ template Wrapper_Maillage::Wrapper_Maillage(NUA voisins_de_maille.resize(nbr_mailles); faces_contenues.resize(nbr_mailles); - maille_au_bord.resize(nbr_mailles,UNDEFINED); + maille_au_bord.resize(nbr_mailles,MED_UNDEFINED); type_retour sommets_face; @@ -189,8 +191,8 @@ template Wrapper_Maillage::Wrapper_Maillage(NUA for (num_maille=0;num_maille(tmp,UNDEFINED); - faces_contenues[num_maille]=vector(tmp,UNDEFINED); + voisins_de_maille[num_maille]=vector(tmp,MED_UNDEFINED); + faces_contenues[num_maille]=vector(tmp,MED_UNDEFINED); approx_nbr_formants+=tmp; } @@ -234,13 +236,13 @@ template Wrapper_Maillage::Wrapper_Maillage(NUA // (borné, par 8*4=32) num_loc=(*mailles)[num_maille_sec].DONNE_NUM_LOC_FACE_EGALE_A_FORMANT(sommets_face); - if (num_loc>UNDEFINED) + if (num_loc>MED_UNDEFINED) { // et dans ce cas, la maille secondaire est voisine de la maille primaire, on met à jour les tableaux // si on voulait construire le tableau des faces, c'est ici qu'il faudrait le faire -1- - // MESSAGE("La maille "< Wrapper_Maillage::Wrapper_Maillage(NUA // On regarde si tous les numéros globaux des faces sont définis - if (faces_contenues[num_maille][ind_num_cont]==UNDEFINED) + if (faces_contenues[num_maille][ind_num_cont]==MED_UNDEFINED) { // si un seul numéro n'est pas défini, la maille est au bord // si on voulait construire le tableau des faces, c'est ici qu'il faudrait le faire -2- - // MESSAGE("La maille "< Wrapper_Maillage::Wrapper_Maillage(NUA nf=0; for (j=0;j<(int)faces_contenues[i].size();j++) { - if (faces_contenues[i][j]==UNDEFINED) verif++; - if (voisins_de_maille[i][j]==UNDEFINED) nf++; + if (faces_contenues[i][j]==MED_UNDEFINED) verif++; + if (voisins_de_maille[i][j]==MED_UNDEFINED) nf++; } - if (maille_au_bord[i]==UNDEFINED) cerr<<"Maille "< #define DTREE_FANTOME -1 #define DTREE_RACINE 0 @@ -34,8 +37,9 @@ #define DTREE_NBR_MIN_NOEUDS 2 #define DTREE_NBR_MAX_DESC 8 // pour meilleu re lecture -#define _TEMPLATE_ template -#define _DTREE_ dTree +#define _TEMPLATE_ \ +template +#define _DTREE_ dTree ////////////////////////////////////////////////////////////////// /// /// @@ -79,7 +83,8 @@ template <> struct DeuxPuissance<0> // - NBR_NOEUDS_PAR_CASE ne doit pas être modifié sauf peut-être dans le cas où l'utilisateur veut utiliser des d-Tree parallèles // ou utilise des nuages de noeud trop grands -template class dTree +template +class dTree { protected : // types @@ -139,6 +144,9 @@ public : int Get_Nbr_Descendants_Non_Vides() const; int Get_Nbr_Descendants_Vides() const; int Get_Profondeur_Max() const; + + // return numbers of nodes close to P within tolerance d + int get_all_close(NOEUD P, double d, list & closeNumbers) const; }; @@ -575,7 +583,8 @@ _TEMPLATE_ void _DTREE_::cree_filiation() niveau=0; } - if (noeud_contenu->size()<=NBR_NOEUDS_PAR_CASE) + if (noeud_contenu->size()<=NBR_NOEUDS_PAR_CASE || + niveau > MAX_DEPTH) // badly needed for the case with coincident nodes { etat=DTREE_TERMINAL; } @@ -669,6 +678,36 @@ _TEMPLATE_ int _DTREE_::Get_Profondeur_Max() const } } +// return numbers of nodes close to P within tolerance d +_TEMPLATE_ int _DTREE_::get_all_close(NOEUD P, double d, list & closeNumbers) const +{ + int i, nbAdded = 0; + if (Localise_Point(P,d)) + { + if (etat==DTREE_TERMINAL) + { + int nb = noeud_contenu->size(); + for (i=0;iget_all_close(P,d,closeNumbers); + } + } + } + return nbAdded; +} + #undef _TEMPLATE_ #undef _DTREE_ diff --git a/src/INTERPOLATION/MEDMEM_dTreeSommet.hxx b/src/INTERPOLATION/MEDMEM_dTreeSommet.hxx index a23ddc63d..d431076be 100644 --- a/src/INTERPOLATION/MEDMEM_dTreeSommet.hxx +++ b/src/INTERPOLATION/MEDMEM_dTreeSommet.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef SOMMET_HPP #define SOMMET_HPP diff --git a/src/INTERPOLATION/Makefile.am b/src/INTERPOLATION/Makefile.am index bf12b5291..6d548d194 100644 --- a/src/INTERPOLATION/Makefile.am +++ b/src/INTERPOLATION/Makefile.am @@ -1,29 +1,28 @@ -# MED MEDMEM : MED files in memory +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# 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. # +# 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 +# +# MED MEDMEM : MED files in memory # File : Makefile.in # Module : MED - +# include $(top_srcdir)/adm_local/unix/make_common_starter.am bin_PROGRAMS = \ @@ -64,10 +63,15 @@ dist_UseCaseInterpolationwots_SOURCES= UseCaseInterpolationwots.cxx dist_UseCaseMapping_SOURCES= UseCaseMapping.cxx dist_UseCaseWrapper_Maillage_SOURCES= UseCaseWrapper_Maillage.cxx -AM_CPPFLAGS=-U_DEBUG_ $(MED2_INCLUDES) $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ -I$(srcdir)/../MEDMEM -I$(srcdir)/../MEDWrapper/V2_1/Core +AM_CPPFLAGS=-U_DEBUG_ $(MED2_INCLUDES) $(HDF5_INCLUDES) -I$(srcdir)/../MEDMEM -I$(srcdir)/../MEDWrapper/V2_1/Core LDADD=-lm $(MED2_LIBS) $(HDF5_LIBS) ../MEDMEM/libmedmem.la ../MEDWrapper/V2_1/Core/libmed_V2_1.la +AM_CXXFLAGS= @CXXTMPDPTHFLAGS@ + if MED_ENABLE_KERNEL AM_CPPFLAGS+= ${KERNEL_CXXFLAGS} LDADD+= -lSALOMELocalTrace -lSALOMEBasics ${KERNEL_LDFLAGS} endif + +OBSOLETE_FILES = test_MEDMEM_Interpolation.cxx +EXTRA_DIST += $(OBSOLETE_FILES) diff --git a/src/INTERPOLATION/UseCaseInterpolationts.cxx b/src/INTERPOLATION/UseCaseInterpolationts.cxx index 753ddaf2c..30f79b0d4 100644 --- a/src/INTERPOLATION/UseCaseInterpolationts.cxx +++ b/src/INTERPOLATION/UseCaseInterpolationts.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_Exception.hxx" #include "MEDMEM_define.hxx" @@ -32,7 +34,7 @@ using namespace MEDMEM; using namespace MED_EN; -main () { +int main () { const char * fromFileName = "ResultatSyrthes.med"; const char * toFileName = "MaillageAster.med"; const char * resultFileName = "ResultatInterpolation.med"; @@ -94,6 +96,6 @@ main () { } } catch (MEDEXCEPTION& ex){ - MESSAGE(ex.what()) ; + MESSAGE_MED(ex.what()) ; } } diff --git a/src/INTERPOLATION/UseCaseInterpolationwots.cxx b/src/INTERPOLATION/UseCaseInterpolationwots.cxx index 99e14362f..e59a7524b 100644 --- a/src/INTERPOLATION/UseCaseInterpolationwots.cxx +++ b/src/INTERPOLATION/UseCaseInterpolationwots.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_Exception.hxx" #include "MEDMEM_define.hxx" @@ -29,7 +31,7 @@ using namespace MEDMEM; using namespace MED_EN; -main () { +int main () { const char * fromFileName = "fromMesh.med"; const char * toFileName = "toMesh.med"; const char * fieldName = "fieldnodedouble"; @@ -57,6 +59,6 @@ main () { } catch (MEDEXCEPTION& ex){ - MESSAGE(ex.what()) ; + MESSAGE_MED(ex.what()) ; } } diff --git a/src/INTERPOLATION/UseCaseMapping.cxx b/src/INTERPOLATION/UseCaseMapping.cxx index 8a67dafbc..e064416e6 100644 --- a/src/INTERPOLATION/UseCaseMapping.cxx +++ b/src/INTERPOLATION/UseCaseMapping.cxx @@ -1,26 +1,28 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "stdio.h" #include "stdlib.h" -#include +#include #include "MEDMEM_InterpolationHighLevelObjects.hxx" diff --git a/src/INTERPOLATION/UseCaseWrapper_Maillage.cxx b/src/INTERPOLATION/UseCaseWrapper_Maillage.cxx index cf866f6ab..9ebbd6c32 100644 --- a/src/INTERPOLATION/UseCaseWrapper_Maillage.cxx +++ b/src/INTERPOLATION/UseCaseWrapper_Maillage.cxx @@ -1,26 +1,28 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "stdio.h" #include "stdlib.h" -#include +#include #include "MEDMEM_InterpolationHighLevelObjects.hxx" diff --git a/src/INTERPOLATION/UseCasedTree.cxx b/src/INTERPOLATION/UseCasedTree.cxx index 8e2902d32..c2f3b0956 100644 --- a/src/INTERPOLATION/UseCasedTree.cxx +++ b/src/INTERPOLATION/UseCasedTree.cxx @@ -1,29 +1,33 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "stdio.h" #include "stdlib.h" -#include - +#include +#include #include "MEDMEM_InterpolationHighLevelObjects.hxx" +using namespace std; + #define affiche(NOEUD) cout< close; + int nb = Octree.get_all_close( tmp1, toler, close ); + cout << "With tolerance " << toler << " - " << nb << endl; + list::iterator n = close.begin(); + while ( n != close.end() ) { + int node = *n++; + tmp2=&noeuds[DIMENSION*node]; + cout<<"\t"<< node << " : "; + affiche(tmp2); + double dist = 0; + for ( int dim = 0; dim < DIMENSION; ++dim ) + dist += ( tmp1[dim] - tmp2[dim] ) * ( tmp1[dim] - tmp2[dim] ); + cout << "\t distance: " << sqrt( dist ) << endl; + } + if ( nb == NBR_NOEUDS ) + break; // no sens in increase toler as all nodes found + } + } } diff --git a/src/INTERPOLATION/create_mesh_interpolation.c b/src/INTERPOLATION/create_mesh_interpolation.c index 46f284260..9a009a359 100644 --- a/src/INTERPOLATION/create_mesh_interpolation.c +++ b/src/INTERPOLATION/create_mesh_interpolation.c @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #include #include diff --git a/src/INTERPOLATION/test_MEDMEM_Interpolation.cxx b/src/INTERPOLATION/test_MEDMEM_Interpolation.cxx index 74860bdf8..a71115c86 100644 --- a/src/INTERPOLATION/test_MEDMEM_Interpolation.cxx +++ b/src/INTERPOLATION/test_MEDMEM_Interpolation.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_Exception.hxx" #include "MEDMEM_define.hxx" @@ -26,7 +28,7 @@ #include "stdio.h" -main () { +int main () { const char * fromFileName = "fromMesh.med"; const char * toFileName = "toMesh.med"; //const char * fieldName = "fieldcelldoublevector"; @@ -69,6 +71,6 @@ main () { cout<<"Fin"< * firstField, FIELD * secondField) #include "MEDMEM_WrapperCells.hxx" -main () { +int main () { const char * fromFileName = "ResultatSyrthes.med"; const char * toFileName = "MaillageAster.med"; const char * resultFileName = "ResultatFlipback.med"; @@ -165,7 +167,7 @@ main () { try { - string flag="================[MAIN MESSAGES]================> "; + string flag="================[MAIN MESSAGE_MEDS]================> "; cout< +#include + +#include +#include + +template +class BBTree +{ + +private: + BBTree* _left; + BBTree* _right; + int _level; + double _max_left; + double _min_right; + double* _bb; + typename std::vector _elems; + bool _terminal; + ConnType _nbelems; + double _epsilon; + + static const int MIN_NB_ELEMS=15; + static const int MAX_LEVEL=20; +public: + + /*! + Constructor of the bounding box tree + \param bbs pointer to the [xmin1 xmax1 ymin1 ymax1 xmin2 xmax2 ...] array containing the bounding boxes that are to be indexed. + \param elems array to the indices of the elements contained in the BBTree + \param level level in the BBTree recursive structure + \param nbelems nb of elements in the BBTree + \param epsilon precision to which points are decided to be coincident + + Parameters \a elems and \a level are used only by BBTree itself for creating trees recursively. A typical use is therefore : + \code + int nbelems=... + double* bbs= new double[2*2*nbelems]; + // filling bbs ... + ... + BBTree<2> tree = new BBTree<2>(elems,0,0,nbelems,1e-12); + \endcode + */ + + BBTree(double* bbs, ConnType* elems, int level, ConnType nbelems, double epsilon=1E-12): + _left(0), _right(0), _level(level), _bb(bbs), _terminal(false),_nbelems(nbelems),_epsilon(epsilon) + { + if (nbelems < MIN_NB_ELEMS || level> MAX_LEVEL) + { + _terminal=true; + + } + double* nodes=new double [nbelems]; + _elems.resize(nbelems); + for (ConnType i=0; i(nodes, nodes+nbelems/2, nodes+nbelems); + double median = *(nodes+nbelems/2); + delete[] nodes; + // std:: cout << *median < new_elems_left; + std::vector new_elems_right; + + new_elems_left.reserve(nbelems/2+1); + new_elems_right.reserve(nbelems/2+1); + double max_left = -std::numeric_limits::max(); + double min_right= std::numeric_limits::max(); + for (int i=0; imedian) + { + new_elems_right.push_back(elem); + if (minmax_left) max_left = max; + } + + + } + _max_left=max_left+_epsilon; + _min_right=min_right-_epsilon; + _left=new BBTree(bbs, &(new_elems_left[0]), level+1, new_elems_left.size(),_epsilon); + _right=new BBTree(bbs, &(new_elems_right[0]), level+1, new_elems_right.size(),_epsilon); + + } + + + + ~BBTree() + { + if (_left!=0) delete _left; + if (_right!=0) delete _right; + + } + + + /*! returns in \a elems the list of elements potentially intersecting the bounding box pointed to by \a bb + + \param bb pointer to query bounding box + \param elems list of elements (given in 0-indexing that is to say in \b C \b mode) intersecting the bounding box + */ + + void getIntersectingElems(const double* bb, std::vector& elems) const + { + // terminal node : return list of elements intersecting bb + if (_terminal) + { + for (int i=0; i<_nbelems; i++) + { + const double* const bb_ptr=_bb+_elems[i]*2*dim; + bool intersects = true; + for (int idim=0; idim-_epsilon|| bb_ptr[idim*2+1]-bb[idim*2]<_epsilon) + intersects=false; + } + if (intersects) + { + elems.push_back(_elems[i]); + } + } + return; + } + + //non terminal node + double min = bb[(_level%dim)*2]; + double max = bb[(_level%dim)*2+1]; + if (max < _min_right) + { + _left->getIntersectingElems(bb, elems); + return; + } + if (min> _max_left) + { + _right->getIntersectingElems(bb,elems); + return; + } + _left->getIntersectingElems(bb,elems); + _right->getIntersectingElems(bb,elems); + } + + + /*! returns in \a elems the list of elements potentially containing the point pointed to by \a xx + \param xx pointer to query point coords + \param elems list of elements (given in 0-indexing) intersecting the bounding box + */ + + void getElementsAroundPoint(const double* xx, std::vector& elems) const + { + // terminal node : return list of elements intersecting bb + if (_terminal) + { + for (ConnType i=0; i<_nbelems; i++) + { + const double* const bb_ptr=_bb+_elems[i]*2*dim; + bool intersects = true; + for (int idim=0; idim_epsilon|| bb_ptr[idim*2+1]-xx[idim]<-_epsilon) + intersects=false; + } + if (intersects) + { + elems.push_back(_elems[i]); + } + } + return; + } + + //non terminal node + if (xx[_level%dim] < _min_right) + { + _left->getElementsAroundPoint(xx, elems); + return; + } + if (xx[_level%dim]> _max_left) + { + _right->getElementsAroundPoint(xx,elems); + return; + } + _left->getElementsAroundPoint(xx,elems); + _right->getElementsAroundPoint(xx,elems); + } + + + + int size() + { + if (_terminal) return _nbelems; + return _left->size()+_right->size(); + } +}; +#endif diff --git a/src/INTERP_KERNEL/Bases/INTERPKERNELBASESDefines.hxx b/src/INTERP_KERNEL/Bases/INTERPKERNELBASESDefines.hxx new file mode 100644 index 000000000..f07ce5f69 --- /dev/null +++ b/src/INTERP_KERNEL/Bases/INTERPKERNELBASESDefines.hxx @@ -0,0 +1,33 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERPKERNELBASESDEFINES_HXX__ +#define __INTERPKERNELBASESDEFINES_HXX__ + +//export symbols +#ifdef WIN32 +# ifdef INTERPKERNELBASES_EXPORTS +# define INTERPKERNELBASES_EXPORT __declspec(dllexport) +# else +# define INTERPKERNELBASES_EXPORT __declspec(dllimport) +# endif +#else +# define INTERPKERNELBASES_EXPORT +#endif + +#endif diff --git a/src/INTERP_KERNEL/Bases/InterpKernelException.cxx b/src/INTERP_KERNEL/Bases/InterpKernelException.cxx new file mode 100644 index 000000000..137b71c35 --- /dev/null +++ b/src/INTERP_KERNEL/Bases/InterpKernelException.cxx @@ -0,0 +1,36 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "InterpKernelException.hxx" + +INTERP_KERNEL::Exception::Exception(const char *what):_reason(what) +{ +} + +INTERP_KERNEL::Exception::Exception(const char *what, const char *file, int line):_reason(what) +{ +} + +INTERP_KERNEL::Exception::~Exception() throw () +{ +} + +const char *INTERP_KERNEL::Exception::what() const throw() +{ + return _reason.c_str(); +} diff --git a/src/INTERP_KERNEL/Bases/InterpKernelException.hxx b/src/INTERP_KERNEL/Bases/InterpKernelException.hxx new file mode 100644 index 000000000..8f3199297 --- /dev/null +++ b/src/INTERP_KERNEL/Bases/InterpKernelException.hxx @@ -0,0 +1,41 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERPKERNELEXCEPTION_HXX__ +#define __INTERPKERNELEXCEPTION_HXX__ + +#include "INTERPKERNELBASESDefines.hxx" + +#include +#include + +namespace INTERP_KERNEL +{ + class INTERPKERNELBASES_EXPORT Exception : std::exception + { + public: + Exception(const char *what); + Exception(const char *what, const char *file, int line); + ~Exception() throw (); + const char *what() const throw(); + protected: + std::string _reason; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Bases/Makefile.am b/src/INTERP_KERNEL/Bases/Makefile.am new file mode 100755 index 000000000..9c7c593e6 --- /dev/null +++ b/src/INTERP_KERNEL/Bases/Makefile.am @@ -0,0 +1,35 @@ +# Copyright (C) 2007-2008 CEA/DEN, 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. +# +# 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 +# +# File : Makefile.am +# Author : Vincent BERGEAUD (CEA/DEN/DANS/DM2S/SFME/LGLS) +# Module : MED +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +lib_LTLIBRARIES = libinterpkernelbases.la + +salomeinclude_HEADERS = \ +INTERPKERNELBASESDefines.hxx \ +InterpKernelException.hxx \ +NormalizedUnstructuredMesh.hxx + +# Libraries targets + +dist_libinterpkernelbases_la_SOURCES = \ +InterpKernelException.cxx diff --git a/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx b/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx new file mode 100644 index 000000000..949e2e655 --- /dev/null +++ b/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx @@ -0,0 +1,57 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __NORMALIZEDUNSTRUCTUREDMESH_HXX__ +#define __NORMALIZEDUNSTRUCTUREDMESH_HXX__ + +namespace INTERP_KERNEL +{ + typedef enum + { + ALL_C_MODE , + ALL_FORTRAN_MODE + } NumberingPolicy; + + + typedef enum + { + NORM_SEG2 = 1, + NORM_SEG3 = 2, + NORM_TRI3 = 3, + NORM_QUAD4 = 4, + NORM_POLYGON = 5, + NORM_TRI6 = 6, + NORM_QUAD8 = 8, + // + NORM_TETRA4 = 14, + NORM_PYRA5 = 15, + NORM_PENTA6 = 16, + NORM_HEXA8 = 18, + NORM_TETRA10 = 20, + NORM_PYRA13 = 23, + NORM_PENTA15 = 25, + NORM_HEXA20 = 30, + NORM_POLYHED = 31, + NORM_ERROR = 40 + } NormalizedCellType; + + class GenericMesh + {}; +} + +#endif diff --git a/src/INTERP_KERNEL/BoundingBox.cxx b/src/INTERP_KERNEL/BoundingBox.cxx new file mode 100644 index 000000000..06e18cd98 --- /dev/null +++ b/src/INTERP_KERNEL/BoundingBox.cxx @@ -0,0 +1,168 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "BoundingBox.hxx" + +#include +#include +#include + +namespace INTERP_KERNEL +{ + + /** + * Constructor creating box from an array of the points corresponding + * to the vertices of the element. + * Each point is represented by an array of three doubles. + * + * @param pts array of points + * @param numPts number of vertices + * + */ + BoundingBox::BoundingBox(const double** pts, const unsigned numPts) + :_coords(new double[6]) + { + using namespace std; + assert(numPts > 1); + + // initialize with first two points + const double* pt1 = pts[0]; + const double* pt2 = pts[1]; + + for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1)) + { + _coords[c] = min(pt1[c], pt2[c]); + _coords[c + 3] = max(pt1[c], pt2[c]); + } + + for(unsigned i = 2 ; i < numPts ; ++i) + { + updateWithPoint(pts[i]); + } + + assert(isValid()); + } + + /** + * Constructor creating box from union of two boxes, resulting in a box that encloses both of them + * + * @param box1 the first box + * @param box2 the second box + */ + BoundingBox::BoundingBox(const BoundingBox& box1, const BoundingBox& box2) + : _coords(new double[6]) + { + using namespace std; + assert(_coords != 0); + + for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1)) + { + _coords[c] = min(box1._coords[c], box2._coords[c]); + _coords[c + 3] = max(box1._coords[c + 3], box2._coords[c + 3]); + } + + assert(isValid()); + } + + /** + * Destructor + * + */ + BoundingBox::~BoundingBox() + { + delete[] _coords; + } + + /** + * Determines if the intersection with a given box is empty + * + * @param box BoundingBox with which intersection is tested + * @return true if intersection between boxes is empty, false if not + */ + bool BoundingBox::isDisjointWith(const BoundingBox& box) const + { + for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1)) + { + const double otherMinCoord = box.getCoordinate(c); + const double otherMaxCoord = box.getCoordinate(BoxCoord(c + 3)); + + // boxes are disjoint if there exists a direction in which the + // minimum coordinate of one is greater than the maximum coordinate of the other + + // more stable version ? + // const double tol = 1.0e-2*_coords[c]; + // if(_coords[c] > otherMaxCoord + tol + // || _coords[c + 3] < otherMinCoord - tol) + + + if(_coords[c] > otherMaxCoord + || _coords[c + 3] < otherMinCoord) + + { + return true; + } + + } + return false; + } + + + + /** + * Updates the bounding box to include a given point + * + * @param pt point to be included + * + */ + void BoundingBox::updateWithPoint(const double* pt) + { + using namespace std; + + for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1)) + { + const double ptVal = pt[c]; + + // update min and max coordinates + _coords[c] = min(_coords[c], ptVal); + _coords[c + 3] = max(_coords[c + 3], ptVal); + + } + } + + /** + * Checks if the box is valid, which it is if its minimum coordinates are + * smaller than its maximum coordinates in all directions. + * + * @return true if the box is valid, false if not + */ + bool BoundingBox::isValid() const + { + bool valid = true; + for(BoxCoord c = XMIN ; c < ZMIN ; c = BoxCoord(c + 1)) + { + if(_coords[c] > _coords[c + 3]) + { + std::cout << "+++ Error in BoundingBox |: coordinate " << c << " is invalid : " + <<_coords[c] << " > " << _coords[c+3] << std::endl; + valid = false; + } + } + return valid; + } + +} diff --git a/src/INTERP_KERNEL/BoundingBox.hxx b/src/INTERP_KERNEL/BoundingBox.hxx new file mode 100644 index 000000000..dbb18646c --- /dev/null +++ b/src/INTERP_KERNEL/BoundingBox.hxx @@ -0,0 +1,109 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __BOUNDINGBOX_HXX__ +#define __BOUNDINGBOX_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include + +namespace INTERP_KERNEL +{ + + /** + * \brief Class representing the bounding box of a number of points. + * + */ + class INTERPKERNEL_EXPORT BoundingBox + { + public: + + /// Enumeration representing the six coordinates that define the bounding box + enum BoxCoord { XMIN = 0, YMIN = 1, ZMIN = 2, XMAX = 3, YMAX = 4, ZMAX = 5 }; + + BoundingBox(const double** pts, const unsigned numPts); + + BoundingBox(const BoundingBox& box1, const BoundingBox& box2); + + ~BoundingBox(); + + bool isDisjointWith(const BoundingBox& box) const; + + inline void setCoordinate(const BoxCoord coord, double value); + + inline double getCoordinate(const BoxCoord coord) const; + + void updateWithPoint(const double* pt); + + inline void dumpCoords() const; + + private: + + bool isValid() const; + + /// disallow copying + BoundingBox(const BoundingBox& box); + + /// disallow assignment + BoundingBox& operator=(const BoundingBox& box); + + /// Vector containing the coordinates of the box + /// interlaced in the order XMIN, YMIN, ZMIN, XMAX, YMAX, ZMAX + double* _coords; + + }; + + /** + * Sets a coordinate of the box to a given value. + * + * @param coord coordinate to set + * @param value new value for coordinate + * + */ + inline void BoundingBox::setCoordinate(const BoxCoord coord, double value) + { + _coords[coord] = value; + } + + /** + * Gets a coordinate of the box + * + * @param coord coordinate to get + * @return value of coordinate + * + */ + inline double BoundingBox::getCoordinate(const BoxCoord coord) const + { + return _coords[coord]; + } + + /** + * Prints the coordinates of the box to std::cout + * + */ + inline void BoundingBox::dumpCoords() const + { + std::cout << "[xmin, xmax] = [" << _coords[XMIN] << ", " << _coords[XMAX] << "]" << " | "; + std::cout << "[ymin, ymax] = [" << _coords[YMIN] << ", " << _coords[YMAX] << "]" << " | "; + std::cout << "[zmin, zmax] = [" << _coords[ZMIN] << ", " << _coords[ZMAX] << "]"; + std::cout << std::endl; + } + +} + +#endif diff --git a/src/INTERP_KERNEL/CellModel.cxx b/src/INTERP_KERNEL/CellModel.cxx new file mode 100644 index 000000000..81c2a77ea --- /dev/null +++ b/src/INTERP_KERNEL/CellModel.cxx @@ -0,0 +1,230 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "CellModel.hxx" + +#include "InterpKernelException.hxx" + +#include +#include + +using namespace std; + +namespace INTERP_KERNEL +{ + std::map CellModel::_map_of_unique_instance; + + const CellModel& CellModel::getCellModel(NormalizedCellType type) + { + if(_map_of_unique_instance.empty()) + buildUniqueInstance(); + const map::iterator iter=_map_of_unique_instance.find(type); + if(iter==_map_of_unique_instance.end()) + { + ostringstream stream; stream << "no cellmodel for normalized type " << type; + throw Exception(stream.str().c_str()); + } + return (*iter).second; + } + + void CellModel::buildUniqueInstance() + { + _map_of_unique_instance.insert(make_pair(NORM_SEG2,CellModel(NORM_SEG2))); + _map_of_unique_instance.insert(make_pair(NORM_SEG3,CellModel(NORM_SEG3))); + _map_of_unique_instance.insert(make_pair(NORM_TRI3,CellModel(NORM_TRI3))); + _map_of_unique_instance.insert(make_pair(NORM_QUAD4,CellModel(NORM_QUAD4))); + _map_of_unique_instance.insert(make_pair(NORM_TRI6,CellModel(NORM_TRI6))); + _map_of_unique_instance.insert(make_pair(NORM_QUAD8,CellModel(NORM_QUAD8))); + _map_of_unique_instance.insert(make_pair(NORM_TETRA4,CellModel(NORM_TETRA4))); + _map_of_unique_instance.insert(make_pair(NORM_HEXA8,CellModel(NORM_HEXA8))); + _map_of_unique_instance.insert(make_pair(NORM_PYRA5,CellModel(NORM_PYRA5))); + _map_of_unique_instance.insert(make_pair(NORM_PENTA6,CellModel(NORM_PENTA6))); + _map_of_unique_instance.insert(make_pair(NORM_TETRA10,CellModel(NORM_TETRA10))); + _map_of_unique_instance.insert(make_pair(NORM_PYRA13,CellModel(NORM_PYRA13))); + _map_of_unique_instance.insert(make_pair(NORM_PENTA15,CellModel(NORM_PENTA15))); + _map_of_unique_instance.insert(make_pair(NORM_HEXA20,CellModel(NORM_HEXA20))); + } + + CellModel::CellModel(NormalizedCellType type) + { + _quadratic=false; + _dyn=false; + switch(type) + { + case NORM_SEG2: + { + _nb_of_pts=2; _nb_of_sons=0; _dim=1; + } + break; + case NORM_SEG3: + { + _nb_of_pts=3; _nb_of_sons=0; _dim=1; + } + break; + case NORM_TETRA4: + { + _nb_of_pts=4; _nb_of_sons=4; _dim=3; + _sons_type[0]=NORM_TRI3; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_TRI3; _sons_type[3]=NORM_TRI3; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _nb_of_sons_con[0]=3; + _sons_con[1][0]=0; _sons_con[1][1]=3; _sons_con[1][2]=1; _nb_of_sons_con[1]=3; + _sons_con[2][0]=1; _sons_con[2][1]=3; _sons_con[2][2]=2; _nb_of_sons_con[2]=3; + _sons_con[3][0]=2; _sons_con[3][1]=3; _sons_con[3][2]=0; _nb_of_sons_con[3]=3; + } + break; + case NORM_HEXA8: + { + _nb_of_pts=8; _nb_of_sons=6; _dim=3; + _sons_type[0]=NORM_QUAD4; _sons_type[1]=NORM_QUAD4; _sons_type[2]=NORM_QUAD4; _sons_type[3]=NORM_QUAD4; _sons_type[4]=NORM_QUAD4; _sons_type[5]=NORM_QUAD4; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _nb_of_sons_con[0]=4; + _sons_con[1][0]=4; _sons_con[1][1]=7; _sons_con[1][2]=6; _sons_con[1][3]=5; _nb_of_sons_con[1]=4; + _sons_con[2][0]=0; _sons_con[2][1]=4; _sons_con[2][2]=5; _sons_con[2][3]=1; _nb_of_sons_con[2]=4; + _sons_con[3][0]=1; _sons_con[3][1]=5; _sons_con[3][2]=6; _sons_con[3][3]=2; _nb_of_sons_con[3]=4; + _sons_con[4][0]=2; _sons_con[4][1]=6; _sons_con[4][2]=7; _sons_con[4][3]=3; _nb_of_sons_con[4]=4; + _sons_con[5][0]=3; _sons_con[5][1]=7; _sons_con[5][2]=4; _sons_con[5][3]=0; _nb_of_sons_con[5]=4; + } + break; + case NORM_QUAD4: + { + _nb_of_pts=4; _nb_of_sons=4; _dim=2; + _sons_type[0]=NORM_SEG2; _sons_type[1]=NORM_SEG2; _sons_type[2]=NORM_SEG2; _sons_type[3]=NORM_SEG2; + _sons_con[0][0]=0; _sons_con[0][1]=1; _nb_of_sons_con[0]=2; + _sons_con[1][0]=1; _sons_con[1][1]=2; _nb_of_sons_con[1]=2; + _sons_con[2][0]=2; _sons_con[2][1]=3; _nb_of_sons_con[2]=2; + _sons_con[3][0]=3; _sons_con[3][1]=0; _nb_of_sons_con[3]=2; + } + break; + case NORM_TRI3: + { + _nb_of_pts=3; _nb_of_sons=3; _dim=2; + _sons_type[0]=NORM_SEG2; _sons_type[1]=NORM_SEG2; _sons_type[2]=NORM_SEG2; + _sons_con[0][0]=0; _sons_con[0][1]=1; _nb_of_sons_con[0]=2; + _sons_con[1][0]=1; _sons_con[1][1]=2; _nb_of_sons_con[1]=2; + _sons_con[2][0]=2; _sons_con[2][1]=0; _nb_of_sons_con[2]=2; + } + break; + case NORM_TRI6: + { + _nb_of_pts=6; _nb_of_sons=3; _dim=2; + _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=3; _nb_of_sons_con[0]=3; + _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=4; _nb_of_sons_con[1]=3; + _sons_con[2][0]=2; _sons_con[2][1]=0; _sons_con[2][2]=5; _nb_of_sons_con[2]=3; _quadratic=true; + } + break; + case NORM_QUAD8: + { + _nb_of_pts=8; _nb_of_sons=4; _dim=2; + _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; _sons_type[3]=NORM_SEG3; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=4; _nb_of_sons_con[0]=3; + _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=5; _nb_of_sons_con[1]=3; + _sons_con[2][0]=2; _sons_con[2][1]=3; _sons_con[2][2]=6; _nb_of_sons_con[2]=3; + _sons_con[3][0]=3; _sons_con[3][1]=0; _sons_con[3][2]=7; _nb_of_sons_con[3]=3; _quadratic=true; + } + break; + case NORM_PYRA5: + { + _nb_of_pts=5; _nb_of_sons=5; _dim=3; + _sons_type[0]=NORM_QUAD4; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_TRI3; _sons_type[3]=NORM_TRI3; _sons_type[4]=NORM_TRI3; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _nb_of_sons_con[0]=4; + _sons_con[1][0]=0; _sons_con[1][1]=4; _sons_con[1][2]=1; _nb_of_sons_con[1]=3; + _sons_con[2][0]=1; _sons_con[2][1]=4; _sons_con[2][2]=2; _nb_of_sons_con[2]=3; + _sons_con[3][0]=2; _sons_con[3][1]=4; _sons_con[3][2]=3; _nb_of_sons_con[3]=3; + _sons_con[4][0]=3; _sons_con[4][1]=4; _sons_con[4][2]=0; _nb_of_sons_con[4]=3; + } + break; + case NORM_PENTA6: + { + _nb_of_pts=6; _nb_of_sons=5; _dim=3; + _sons_type[0]=NORM_TRI3; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_QUAD4; _sons_type[3]=NORM_QUAD4; _sons_type[4]=NORM_QUAD4; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _nb_of_sons_con[0]=3; + _sons_con[1][0]=3; _sons_con[1][1]=5; _sons_con[1][2]=4; _nb_of_sons_con[1]=3; + _sons_con[2][0]=0; _sons_con[2][1]=3; _sons_con[2][2]=4; _sons_con[2][3]=1; _nb_of_sons_con[2]=4; + _sons_con[3][0]=1; _sons_con[3][1]=4; _sons_con[3][2]=5; _sons_con[3][3]=2; _nb_of_sons_con[3]=4; + _sons_con[4][0]=2; _sons_con[4][1]=4; _sons_con[4][2]=5; _sons_con[4][3]=0; _nb_of_sons_con[4]=4; + } + break; + case NORM_TETRA10: + { + _nb_of_pts=10; _nb_of_sons=4; _dim=3; + _sons_type[0]=NORM_TRI6; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_TRI6; _sons_type[3]=NORM_TRI6; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=4; _sons_con[0][4]=5; _sons_con[0][5]=6; _nb_of_sons_con[0]=6; + _sons_con[1][0]=0; _sons_con[1][1]=3; _sons_con[1][2]=1; _sons_con[1][3]=7; _sons_con[1][4]=8; _sons_con[1][5]=4; _nb_of_sons_con[1]=6; + _sons_con[2][0]=1; _sons_con[2][1]=3; _sons_con[2][2]=2; _sons_con[2][3]=8; _sons_con[2][4]=9; _sons_con[2][5]=5; _nb_of_sons_con[2]=6; + _sons_con[3][0]=2; _sons_con[3][1]=3; _sons_con[3][2]=0; _sons_con[3][3]=9; _sons_con[3][4]=7; _sons_con[3][5]=6; _nb_of_sons_con[3]=6; _quadratic=true; + } + break; + case NORM_PYRA13: + { + _nb_of_pts=13; _nb_of_sons=5; _dim=3; + _sons_type[0]=NORM_QUAD8; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_TRI6; _sons_type[3]=NORM_TRI6; _sons_type[4]=NORM_TRI6; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=5; _sons_con[0][5]=6; _sons_con[0][6]=7; _sons_con[0][7]=8; _nb_of_sons_con[0]=8; + _sons_con[1][0]=0; _sons_con[1][1]=4; _sons_con[1][2]=1; _sons_con[1][3]=9; _sons_con[1][4]=10; _sons_con[1][5]=5; _nb_of_sons_con[1]=6; + _sons_con[2][0]=1; _sons_con[2][1]=4; _sons_con[2][2]=2; _sons_con[2][3]=10; _sons_con[2][4]=11; _sons_con[2][5]=6; _nb_of_sons_con[2]=6; + _sons_con[3][0]=2; _sons_con[3][1]=4; _sons_con[3][2]=3; _sons_con[3][3]=11; _sons_con[3][4]=12; _sons_con[3][5]=7; _nb_of_sons_con[3]=6; + _sons_con[4][0]=3; _sons_con[4][1]=4; _sons_con[4][2]=0; _sons_con[4][3]=12; _sons_con[4][4]=9; _sons_con[4][5]=8; _nb_of_sons_con[4]=6; _quadratic=true; + } + break; + case NORM_PENTA15: + { + _nb_of_pts=15; _nb_of_sons=5; _dim=3; + _sons_type[0]=NORM_TRI6; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_QUAD8; _sons_type[3]=NORM_QUAD8; _sons_type[4]=NORM_QUAD8; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=6; _sons_con[0][4]=7; _sons_con[0][5]=8; _nb_of_sons_con[0]=6; + _sons_con[1][0]=3; _sons_con[1][1]=5; _sons_con[1][2]=4; _sons_con[1][3]=11; _sons_con[1][4]=10; _sons_con[1][5]=9; _nb_of_sons_con[1]=6; + _sons_con[2][0]=0; _sons_con[2][1]=3; _sons_con[2][2]=4; _sons_con[2][3]=1; _sons_con[2][4]=12; _sons_con[2][5]=9; _sons_con[2][6]=13; _sons_con[2][7]=6; _nb_of_sons_con[2]=8; + _sons_con[3][0]=1; _sons_con[3][1]=4; _sons_con[3][2]=5; _sons_con[3][3]=2; _sons_con[3][4]=13; _sons_con[3][5]=10; _sons_con[3][6]=14; _sons_con[3][7]=7; _nb_of_sons_con[3]=8; + _sons_con[4][0]=2; _sons_con[4][1]=4; _sons_con[4][2]=5; _sons_con[4][3]=0; _sons_con[4][4]=14; _sons_con[4][5]=11; _sons_con[4][6]=12; _sons_con[4][7]=8; _nb_of_sons_con[4]=8; _quadratic=true; + } + break; + case NORM_HEXA20: + { + _nb_of_pts=20; _nb_of_sons=6; _dim=3; + _sons_type[0]=NORM_QUAD8; _sons_type[1]=NORM_QUAD8; _sons_type[2]=NORM_QUAD8; _sons_type[3]=NORM_QUAD8; _sons_type[4]=NORM_QUAD8; _sons_type[5]=NORM_QUAD8; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=8; _sons_con[0][5]=9; _sons_con[0][6]=10; _sons_con[0][7]=11; _nb_of_sons_con[0]=8; + _sons_con[1][0]=4; _sons_con[1][1]=7; _sons_con[1][2]=6; _sons_con[1][3]=5; _sons_con[1][4]=15; _sons_con[1][5]=14; _sons_con[1][6]=13; _sons_con[1][7]=12; _nb_of_sons_con[1]=8; + _sons_con[2][0]=0; _sons_con[2][1]=4; _sons_con[2][2]=5; _sons_con[2][3]=1; _sons_con[2][4]=16; _sons_con[2][5]=12; _sons_con[2][6]=17; _sons_con[2][7]=8; _nb_of_sons_con[2]=8; + _sons_con[3][0]=1; _sons_con[3][1]=5; _sons_con[3][3]=6; _sons_con[3][3]=2; _sons_con[3][4]=17; _sons_con[3][5]=13; _sons_con[3][6]=18; _sons_con[3][7]=9;_nb_of_sons_con[3]=8; + _sons_con[4][0]=2; _sons_con[4][1]=6; _sons_con[4][3]=7; _sons_con[4][3]=3; _sons_con[4][4]=18; _sons_con[4][5]=14; _sons_con[4][6]=19; _sons_con[4][7]=10; _nb_of_sons_con[4]=8; + _sons_con[5][0]=3; _sons_con[5][1]=7; _sons_con[5][3]=4; _sons_con[5][3]=0; _sons_con[5][4]=19; _sons_con[5][5]=15; _sons_con[5][6]=16; _sons_con[5][7]=11; _nb_of_sons_con[5]=8; _quadratic=true; + } + break; + case NORM_POLYGON: + { + _nb_of_pts=0; _nb_of_sons=0; _dim=2; _dyn=true; + } + break; + case NORM_POLYHED: + { + _nb_of_pts=0; _nb_of_sons=0; _dim=3; _dyn=true; + } + break; + case NORM_ERROR: + { + _nb_of_pts=std::numeric_limits::max(); _nb_of_sons=std::numeric_limits::max(); _dim=std::numeric_limits::max(); + } + break; + } + } + + void CellModel::fillSonCellNodalConnectivity(int sonId, const int *nodalConn, int *sonNodalConn) const + { + unsigned nbOfTurnLoop=_nb_of_sons_con[sonId]; + const unsigned *sonConn=_sons_con[sonId]; + for(unsigned i=0;i + +namespace INTERP_KERNEL +{ + /*! + * This class descibes all static elements (different from polygons and polyhedron) 3D, 2D and 1D. + */ + class INTERPKERNEL_EXPORT CellModel + { + public: + static const unsigned MAX_NB_OF_SONS=6; + static const unsigned MAX_NB_OF_NODES_PER_ELEM=30; + private: + CellModel(NormalizedCellType type); + static void buildUniqueInstance(); + public: + static const CellModel& getCellModel(NormalizedCellType type); + bool isDynamic() const { return _dyn; } + bool isQuadratic() const { return _quadratic; } + unsigned getDimension() const { return _dim; } + //! sonId is in C format. + const unsigned *getNodesConstituentTheSon(unsigned sonId) const { return _sons_con[sonId]; } + unsigned getNumberOfNodes() const { return _nb_of_pts; } + unsigned getNumberOfSons() const { return _nb_of_sons; } + unsigned getNumberOfNodesConstituentTheSon(unsigned sonId) const { return _nb_of_sons_con[sonId]; } + NormalizedCellType getSonType(unsigned sonId) const { return _sons_type[sonId]; } + void fillSonCellNodalConnectivity(int sonId, const int *nodalConn, int *sonNodalConn) const; + private: + bool _dyn; + bool _quadratic; + unsigned _dim; + unsigned _nb_of_pts; + unsigned _nb_of_sons; + unsigned _sons_con[MAX_NB_OF_SONS][MAX_NB_OF_NODES_PER_ELEM]; + unsigned _nb_of_sons_con[MAX_NB_OF_SONS]; + NormalizedCellType _sons_type[MAX_NB_OF_SONS]; + static std::map _map_of_unique_instance; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/ConvexIntersector.hxx b/src/INTERP_KERNEL/ConvexIntersector.hxx new file mode 100644 index 000000000..cdbae3d0a --- /dev/null +++ b/src/INTERP_KERNEL/ConvexIntersector.hxx @@ -0,0 +1,48 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __CONVEXINTERSECTOR_HXX__ +#define __CONVEXINTERSECTOR_HXX__ + +#include "PlanarIntersectorP0P0.hxx" +#include "PlanarIntersectorP0P1.hxx" +#include "PlanarIntersectorP1P0.hxx" +#include "InterpolationUtils.hxx" + +namespace INTERP_KERNEL +{ + template class InterpType > + class ConvexIntersector : public InterpType > + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + ConvexIntersector(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double precision, double medianPlane, + bool doRotate, int orientation, int printLevel); + double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); + double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad); + private : + double _epsilon; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/ConvexIntersector.txx b/src/INTERP_KERNEL/ConvexIntersector.txx new file mode 100644 index 000000000..c15bc3f0e --- /dev/null +++ b/src/INTERP_KERNEL/ConvexIntersector.txx @@ -0,0 +1,115 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __CONVEXINTERSECTOR_TXX__ +#define __CONVEXINTERSECTOR_TXX__ + +#include "ConvexIntersector.hxx" +#include "PlanarIntersectorP0P0.txx" +#include "PlanarIntersectorP0P1.txx" +#include "PlanarIntersectorP1P0.txx" + +#include "PolygonAlgorithms.txx" + +#include + +namespace INTERP_KERNEL +{ + template class InterpType> + ConvexIntersector::ConvexIntersector(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double precision, + double medianPlane, bool doRotate , int oriantation, int printLevel) + :InterpType >(meshT,meshS,dimCaracteristic, precision, medianPlane, doRotate, oriantation, printLevel), + _epsilon(precision*dimCaracteristic) + { + if(PlanarIntersector::_print_level >= 1) + { + std::cout << " - intersection type = convex " << std::endl; + if(SPACEDIM==3){ + if(PlanarIntersector::_do_rotate) std::cout << " _do_rotate = true" << std::endl; + else std::cout << " _do_rotate = false" << std::endl; + } + } + } + + template class InterpType> + double ConvexIntersector::intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS) + { + double result = 0; + int orientation = 1; + + /*** Obtain the coordinates of T and S ***/ + std::vector CoordsT; + std::vector CoordsS; + PlanarIntersector::getRealCoordinates(icellT,icellS,nbNodesT,nbNodesS,CoordsT,CoordsS,orientation); + /*** Compute the intersection area ***/ + INTERP_KERNEL::PolygonAlgorithms P(_epsilon, PlanarIntersector::_precision); + std::deque inter = P.intersectConvexPolygons(&CoordsT[0], &CoordsS[0], + CoordsT.size()/SPACEDIM, CoordsS.size()/SPACEDIM); + double area[SPACEDIM]; + int nb_inter =((int)inter.size())/SPACEDIM; + for(int i = 1; i(&inter[0],&inter[SPACEDIM*i],&inter[SPACEDIM*(i+1)],area); + result +=0.5*norm(area); + } + + //DEBUG prints + if(PlanarIntersector::_print_level >= 3) + { + std::cout << std::endl << "Number of nodes of the intersection = "<< nb_inter << std::endl; + for(int i=0; i< nb_inter; i++) + {for (int idim=0; idimgetListBehind()) +{ + first(); +} + +void IteratorOnComposedEdge::operator=(const IteratorOnComposedEdge& other) +{ + _deep_it=other._deep_it; + _list_handle=other._list_handle; +} + +void IteratorOnComposedEdge::last() +{ + _deep_it=_list_handle->end(); + _deep_it--; +} + +void IteratorOnComposedEdge::nextLoop() +{ + _deep_it++; + if(_deep_it==_list_handle->end()) + first(); +} + +void IteratorOnComposedEdge::previousLoop() +{ + if(_deep_it!=_list_handle->begin()) + _deep_it--; + else + last(); +} + +bool IteratorOnComposedEdge::goToNextInOn(bool direction, int& i, int nbMax) +{ + TypeOfEdgeLocInPolygon loc=current()->getLoc(); + if(direction) + { + while(loc==FULL_OUT_1 && igetLoc(); + } + if(i==nbMax) + return false; + return true; + } + else + { + while(loc==FULL_OUT_1 && igetLoc(); + } + if(i==nbMax) + return false; + while(loc!=FULL_OUT_1 && igetLoc(); + } + nextLoop(); i--; + return true; + } +} + +void IteratorOnComposedEdge::assignMySelfToAllElems(ComposedEdge *elems) +{ + std::list *myList=elems->getListBehind(); + for(std::list::iterator iter=myList->begin();iter!=myList->end();iter++) + (*iter)->getIterator()=(*this); +} + +void IteratorOnComposedEdge::insertElemEdges(ComposedEdge *elems, bool changeMySelf) +{ + std::list *myListToInsert=elems->getListBehind(); + std::list::iterator iter=myListToInsert->begin(); + *_deep_it=*iter; + _deep_it++; + iter++; + int sizeOfMyList=myListToInsert->size(); + _list_handle->insert(_deep_it,iter,myListToInsert->end()); + if(!changeMySelf) + { + for(int i=0;i +#include +#include + +namespace INTERP_KERNEL +{ + class Edge; + class Node; + class Bounds; + + class ComposedEdge; + class ElementaryEdge; + + /*! + * Asumption is done with this iterator that we iterate on a container containing more than one edge. + */ + class IteratorOnComposedEdge + { + friend class ComposedEdge; + friend class ElementaryEdge; + friend class QuadraticPolygon; + public: + IteratorOnComposedEdge(); + IteratorOnComposedEdge(ComposedEdge *compEdges); + bool isValid() const { return _list_handle!=0; } + void operator=(const IteratorOnComposedEdge& other); + void first() { _deep_it=_list_handle->begin(); } + void next() { _deep_it++; } + void last(); + void nextLoop(); + void previousLoop(); + bool finished() const { return _deep_it==_list_handle->end(); } + bool goToNextInOn(bool direction, int& i, int nbMax); + ElementaryEdge *current() { return *_deep_it; } + void assignMySelfToAllElems(ComposedEdge *elems); + void insertElemEdges(ComposedEdge *elems, bool changeMySelf); + private: + std::list::iterator _deep_it; + std::list* _list_handle; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Geometric2D/Bounds.cxx b/src/INTERP_KERNEL/Geometric2D/Bounds.cxx new file mode 100644 index 000000000..8e168ea5a --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/Bounds.cxx @@ -0,0 +1,197 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "Bounds.hxx" +#include "InterpKernelException.hxx" +#include "EdgeArcCircle.hxx" +#include "Node.hxx" + +using namespace INTERP_KERNEL; + +const double& Bounds::operator[](int i) const +{ + switch(i) + { + case 0: + return _x_min; + case 1: + return _x_max; + case 2: + return _y_min; + case 3: + return _y_max; + } + throw Exception("internal error occurs !"); +} + +double &Bounds::operator[](int i) +{ + switch(i) + { + case 0: + return _x_min; + case 1: + return _x_max; + case 2: + return _y_min; + case 3: + return _y_max; + } + throw Exception("internal error occurs !"); +} + +double Bounds::getDiagonal() const +{ + double a=_x_max-_x_min; + double b=_y_max-_y_min; + return sqrt(a*a+b*b); +} + +/*! + * See Node::applySimilarity to see signification of params. + */ +void Bounds::applySimilarity(double xBary, double yBary, double dimChar) +{ + _x_min=(_x_min-xBary)/dimChar; + _x_max=(_x_max-xBary)/dimChar; + _y_min=(_y_min-yBary)/dimChar; + _y_max=(_y_max-yBary)/dimChar; +} + +void Bounds::getBarycenter(double& xBary, double& yBary) const +{ + xBary=(_x_min+_x_max)/2.; + yBary=(_y_max+_y_min)/2.; +} + +void Bounds::prepareForAggregation() +{ + _x_min=1e200; _x_max=-1e200; _y_min=1e200; _y_max=-1e200; +} + +/*! + * Given an arc defined by 'center', 'radius' and 'intrcptArcDelta' in radian, returns (by outputs intrcptArcAngle0 and intrcptArcDelta) + * the intercepted angle of 'this' from 'center' point of view. + * If diagonal of 'this' is the same order of 2*radius, intrcptArcAngle0 and intrcptArcDelta remains unchanged. + * @param center IN parameter. + * @param radius IN parameter. + * @param intrcptArcAngle0 OUT parameter. + * @param intrcptArcDelta IN/OUT parameter. + */ +void Bounds::getInterceptedArc(const double *center, double radius, double& intrcptArcAngle0, double& intrcptArcDelta) const +{ + double diag=getDiagonal(); + if(diag<2.*radius) + { + double v1[2],v2[2],w1[2],w2[2]; + v1[0]=_x_min-center[0]; v1[1]=_y_max-center[1]; v2[0]=_x_max-center[0]; v2[1]=_y_min-center[1]; + w1[0]=v1[0]; w1[1]=_y_min-center[1]; w2[0]=v2[0]; w2[1]=_y_max-center[1]; + double delta1=EdgeArcCircle::safeAsin(v1[0]*v2[1]-v1[1]*v2[0]); + double delta2=EdgeArcCircle::safeAsin(w1[0]*w2[1]-w1[1]*w2[0]); + double tmp; + if(fabs(delta1)>fabs(delta2)) + { + intrcptArcDelta=delta1; + intrcptArcAngle0=EdgeArcCircle::getAbsoluteAngle(v1,tmp); + } + else + { + intrcptArcDelta=delta2; + intrcptArcAngle0=EdgeArcCircle::getAbsoluteAngle(w1,tmp); + } + } +} + +double Bounds::fitXForXFigD(double val, int res) const +{ + double delta=std::max(_x_max-_x_min,_y_max-_y_min)/2.; + double ret=val-(_x_max+_x_min)/2.+delta; + delta=11.1375*res/(2.*delta); + return ret*delta; +} + +double Bounds::fitYForXFigD(double val, int res) const +{ + double delta=std::max(_x_max-_x_min,_y_max-_y_min)/2.; + double ret=val-(_y_max+_y_min)/2.+delta; + delta=11.1375*res/(2.*delta); + return ret*delta; +} + +Bounds *Bounds::nearlyAmIIntersectingWith(const Bounds& other) const +{ + if( (other._x_min > _x_max+QUADRATIC_PLANAR::_precision) || (other._x_max < _x_min-QUADRATIC_PLANAR::_precision) || (other._y_min > _y_max+QUADRATIC_PLANAR::_precision) + || (other._y_max < _y_min-QUADRATIC_PLANAR::_precision) ) + return 0; + if( (other._x_min >= _x_max ) || (other._x_max <= _x_min) || (other._y_min >= _y_max) || (other._y_max <= _y_min) ) + return new Bounds(std::max(_x_min-QUADRATIC_PLANAR::_precision,other._x_min), + std::min(_x_max+QUADRATIC_PLANAR::_precision,other._x_max), + std::max(_y_min-QUADRATIC_PLANAR::_precision,other._y_min), + std::min(_y_max+QUADRATIC_PLANAR::_precision,other._y_max));//In approx cases. + else + return new Bounds(std::max(_x_min,other._x_min),std::min(_x_max,other._x_max),std::max(_y_min,other._y_min),std::min(_y_max,other._y_max)); +} + +Bounds *Bounds::amIIntersectingWith(const Bounds& other) const +{ + if( (other._x_min > _x_max) || (other._x_max < _x_min) || (other._y_min > _y_max) || (other._y_max < _y_min) ) + return 0; + return new Bounds(std::max(_x_min,other._x_min),std::min(_x_max,other._x_max),std::max(_y_min,other._y_min),std::min(_y_max,other._y_max)); +} + +Position Bounds::where(double x, double y) const +{ + if((x>=_x_min && x<=_x_max) && (y>=_y_min && y<=_y_max)) + return IN; + else + return OUT; +} + +Position Bounds::nearlyWhere(double x, double y) const +{ + bool thinX=Node::areDoubleEquals(_x_min,_x_max); + bool thinY=Node::areDoubleEquals(_y_min,_y_max); + if(!thinX) + { + if(Node::areDoubleEquals(x,_x_min) || Node::areDoubleEquals(x,_x_max) && (y<_y_max+QUADRATIC_PLANAR::_precision) && (y>_y_min-QUADRATIC_PLANAR::_precision)) + return ON_BOUNDARY_POS; + } + else + if(!Node::areDoubleEquals(_x_min,x) && !Node::areDoubleEquals(_x_max,x)) + return OUT; + if(!thinY) + { + if(Node::areDoubleEquals(y,_y_min) || Node::areDoubleEquals(y,_y_max) && (x<_x_max+QUADRATIC_PLANAR::_precision) && (x>_x_min-QUADRATIC_PLANAR::_precision)) + return ON_BOUNDARY_POS; + } + else + if(!Node::areDoubleEquals(_y_min,y) && !Node::areDoubleEquals(_y_max,y)) + return OUT; + if(thinX && thinY) + return ON_BOUNDARY_POS; + if((x>=_x_min && x<=_x_max) && (y>=_y_min && y<=_y_max)) + return IN; + else + return OUT; +} + +void Bounds::aggregate(const Bounds& other) +{ + _x_min=std::min(_x_min,other._x_min); _x_max=std::max(_x_max,other._x_max); + _y_min=std::min(_y_min,other._y_min); _y_max=std::max(_y_max,other._y_max); +} diff --git a/src/INTERP_KERNEL/Geometric2D/Bounds.hxx b/src/INTERP_KERNEL/Geometric2D/Bounds.hxx new file mode 100644 index 000000000..49d72dc67 --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/Bounds.hxx @@ -0,0 +1,73 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __BOUNDS_HXX__ +#define __BOUNDS_HXX__ + +#include "INTERPKERNELGEOMETRIC2DDefines.hxx" + +#include + +namespace INTERP_KERNEL +{ + /*! + * Relative LOC + */ + typedef enum + { + IN = 0, + OUT = 1, + ON_BOUNDARY_POS = 2, + ON_BOUNDARY_NEG = 3 + } Position; + + class INTERPKERNELGEOMETRIC2D_EXPORT Bounds + { + public: + Bounds():_x_min(0.),_x_max(0.),_y_min(0.),_y_max(0.) { } + double &operator[](int i); + const double& operator[](int i) const; + double getDiagonal() const; + void getBarycenter(double& xBary, double& yBary) const; + void applySimilarity(double xBary, double yBary, double dimChar); + Bounds& operator=(const Bounds& other) { _x_min=other._x_min; _x_max=other._x_max; _y_min=other._y_min; _y_max=other._y_max; return *this; } + Bounds(double xMin, double xMax, double yMin, double yMax):_x_min(xMin),_x_max(xMax),_y_min(yMin),_y_max(yMax) { } + void setValues(double xMin, double xMax, double yMin, double yMax) { _x_min=xMin; _x_max=xMax; _y_min=yMin; _y_max=yMax; } + void prepareForAggregation(); + void getInterceptedArc(const double *center, double radius, double& intrcptArcAngle0, double& intrcptArcDelta) const; + int fitXForXFig(double val, int res) const { return (int)fitXForXFigD(val,res); } + int fitYForXFig(double val, int res) const { return (int)fitYForXFigD(val,res); } + double fitXForXFigD(double val, int res) const; + double fitYForXFigD(double val, int res) const; + Bounds *nearlyAmIIntersectingWith(const Bounds& other) const; + Bounds *amIIntersectingWith(const Bounds& other) const; + //! No approximations. + Position where(double x, double y) const; + //! Idem where method but with approximations. + Position nearlyWhere(double x, double y) const; + void aggregate(const Bounds& other); + double getCaracteristicDim() const { return std::max(_x_max-_x_min,_y_max-_y_min); } + protected: + double _x_min; + double _x_max; + double _y_min; + double _y_max; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Geometric2D/ComposedEdge.cxx b/src/INTERP_KERNEL/Geometric2D/ComposedEdge.cxx new file mode 100644 index 000000000..9909ada8d --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/ComposedEdge.cxx @@ -0,0 +1,446 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "ComposedEdge.hxx" +#include "ElementaryEdge.hxx" +#include "EdgeInfLin.hxx" +#include "InterpKernelException.hxx" + +#include +#include +#include + +using namespace std; +using namespace INTERP_KERNEL; + +ComposedEdge::ComposedEdge(const ComposedEdge& other) +{ + for(list::const_iterator iter=other._sub_edges.begin();iter!=other._sub_edges.end();iter++) + _sub_edges.push_back((*iter)->clone()); +} + +ComposedEdge::~ComposedEdge() +{ + clearAll(_sub_edges.begin()); +} + +void ComposedEdge::setValueAt(int i, Edge *e, bool direction) +{ + list::iterator it=_sub_edges.begin(); + for(int j=0;jgetPtr()==_b1->getPtr();} + + ElementaryEdge *_b1; +}; + +double ComposedEdge::getCommonLengthWith(const ComposedEdge& other) const +{ + double ret=0.; + for(list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + if(find_if(other._sub_edges.begin(),other._sub_edges.end(),AbsEdgeCmp(*iter))!=other._sub_edges.end()) + { + const ElementaryEdge *tmp=static_cast(*iter); + ret+=tmp->getCurveLength(); + } + } + return ret; +} + +void ComposedEdge::clear() +{ + clearAll(_sub_edges.begin()); + _sub_edges.clear(); +} + +void ComposedEdge::pushBack(Edge *edge, bool direction) +{ + _sub_edges.push_back(new ElementaryEdge(edge,direction)); +} + +void ComposedEdge::pushBack(ElementaryEdge *elem) +{ + _sub_edges.push_back(elem); +} + +void ComposedEdge::pushBack(ComposedEdge *elem) +{ + list *elemsOfElem=elem->getListBehind(); + _sub_edges.insert(_sub_edges.end(),elemsOfElem->begin(),elemsOfElem->end()); +} + +ElementaryEdge *ComposedEdge::operator[](int i) const +{ + list::const_iterator iter=_sub_edges.begin(); + for(int ii=0;ii::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->reverse(); +} + +void ComposedEdge::initLocations() const +{ + for(list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->initLocations(); +} + +ComposedEdge *ComposedEdge::clone() const +{ + return new ComposedEdge(*this); +} + +bool ComposedEdge::isNodeIn(Node *n) const +{ + bool ret=false; + for(list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end() && !ret;iter++) + ret=(*iter)->isNodeIn(n); + return ret; +} + +/*! + * This method computes the area of 'this'. + * By definition : + * \f[ + * Area=\int_{Polygon} dS + * \f] + * Thanks to Green's theorem we have. + * \f[ + * \int_{Polygon} x \cdot dS=\sum_{0 \leq i < nb of edges} -\int_{Edge_{i}}ydx=\sum_{0 \leq i < nb of edges} AreaOfZone_{Edge_{i}} + * \f] + * Where \f$ AreaOfZone_{i} \f$ is computed virtually by INTERP_KERNEL::Edge::getAreaOfZone with following formula : + * \f[ + * AreaOfZone_{i}=\int_{Edge_{i}} -ydx + * \f] + */ +double ComposedEdge::getArea() const +{ + double ret=0.; + for(list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + ret+=(*iter)->getAreaOfZone(); + return ret; +} + +double ComposedEdge::getPerimeter() const +{ + double ret=0.; + for(list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + ret+=(*iter)->getCurveLength(); + return ret; +} + +double ComposedEdge::getHydraulicDiameter() const +{ + return 4*fabs(getArea())/getPerimeter(); +} + +/*! + * This method computes barycenter of 'this' by returning xG in bary[0] and yG in bary[1]. + * By definition : + * \f[ + * Area \cdot x_{G}=\int_{Polygon} x \cdot dS + * \f] + * \f[ + * Area \cdot y_{G}=\int_{Polygon} y \cdot dS + * \f] + * Thanks to Green's theorem we have. + * \f[ + * \int_{Polygon} x \cdot dS=\sum_{0 \leq i < nb of edges} -\int_{Edge_{i}}yxdx + * \f] + * \f[ + * \int_{Polygon} y \cdot dS=\sum_{0 \leq i < nb of edges} -\int_{Edge_{i}}\frac{y^{2}}{2}dx + * \f] + * Area is computed using the same principle than described in INTERP_KERNEL::ComposedEdge::getArea method. + * \f$ -\int_{Edge_{i}}yxdx \f$ and \f$ -\int_{Edge_{i}}\frac{y^{2}}{2}dx \f$ are computed virtually with INTERP_KERNEL::Edge::getBarycenterOfZone. + */ +void ComposedEdge::getBarycenter(double *bary) const +{ + bary[0]=0.; + bary[1]=0.; + double area=0.; + for(list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + (*iter)->getBarycenterOfZone(bary); + area+=(*iter)->getAreaOfZone(); + } + bary[0]/=area; + bary[1]/=area; +} + +double ComposedEdge::normalize(ComposedEdge *other) +{ + Bounds b; + b.prepareForAggregation(); + fillBounds(b); + other->fillBounds(b); + double dimChar=b.getCaracteristicDim(); + double xBary,yBary; + b.getBarycenter(xBary,yBary); + applyGlobalSimilarity(xBary,yBary,dimChar); + other->applyGlobalSimilarity(xBary,yBary,dimChar); + return dimChar; +} + +void ComposedEdge::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const +{ + stream.precision(10); + for(list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->dumpInXfigFile(stream,resolution,box); +} + +Node *ComposedEdge::getEndNode() const +{ + return _sub_edges.back()->getEndNode(); +} + +Node *ComposedEdge::getStartNode() const +{ + return _sub_edges.front()->getStartNode(); +} + +bool ComposedEdge::changeEndNodeWith(Node *node) const +{ + return _sub_edges.back()->changeEndNodeWith(node); +} + +bool ComposedEdge::changeStartNodeWith(Node *node) const +{ + return _sub_edges.front()->changeStartNodeWith(node); +} + +void ComposedEdge::fillBounds(Bounds& output) const +{ + for(list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->fillBounds(output); +} + +/*! + * \b WARNING : applies similarity \b ONLY on edges without any change on Nodes. To perform a global similarity call applyGlobalSimilarity. + */ +void ComposedEdge::applySimilarity(double xBary, double yBary, double dimChar) +{ + for(list::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->applySimilarity(xBary,yBary,dimChar); +} + +/*! + * Perform Similarity transformation on all elements of this Nodes and Edges. + */ +void ComposedEdge::applyGlobalSimilarity(double xBary, double yBary, double dimChar) +{ + set allNodes; + getAllNodes(allNodes); + for(set::iterator iter=allNodes.begin();iter!=allNodes.end();iter++) + (*iter)->applySimilarity(xBary,yBary,dimChar); + for(list::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->applySimilarity(xBary,yBary,dimChar); +} + +/*! + * This method append to param 'partConsidered' the part of length of subedges IN or ON. + * @param partConsidered INOUT param. + */ +void ComposedEdge::dispatchPerimeter(double& partConsidered) const +{ + for(list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + TypeOfEdgeLocInPolygon loc=(*iter)->getLoc(); + if(loc==FULL_IN_1 || loc==FULL_ON_1) + partConsidered+=(*iter)->getCurveLength(); + } +} + +/*! + * Idem dispatchPerimeterExcl except that when a subedge is declared as ON this subedge is counted in commonPart. + */ +void ComposedEdge::dispatchPerimeterExcl(double& partConsidered, double& commonPart) const +{ + for(list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + TypeOfEdgeLocInPolygon loc=(*iter)->getLoc(); + if(loc==FULL_IN_1) + partConsidered+=(*iter)->getCurveLength(); + if(loc==FULL_ON_1) + commonPart+=(*iter)->getCurveLength(); + } +} + +void ComposedEdge::getAllNodes(std::set& output) const +{ + list::const_iterator iter=_sub_edges.begin(); + for(;iter!=_sub_edges.end();iter++) + (*iter)->getAllNodes(output); +} + +void ComposedEdge::getBarycenter(double *bary, double& weigh) const +{ + weigh=0.; bary[0]=0.; bary[1]=0.; + double tmp1,tmp2[2]; + for(list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + (*iter)->getBarycenter(tmp2,tmp1); + weigh+=tmp1; + bary[0]+=tmp1*tmp2[0]; + bary[1]+=tmp1*tmp2[1]; + } + bary[0]/=weigh; + bary[1]/=weigh; +} + +bool ComposedEdge::isInOrOut(Node *nodeToTest) const +{ + Bounds b; b.prepareForAggregation(); + fillBounds(b); + if(b.nearlyWhere((*nodeToTest)[0],(*nodeToTest)[1])==OUT) + return false; + // searching for e1 + set nodes; + getAllNodes(nodes); + set radialDistributionOfNodes; + set::const_iterator iter; + for(iter=nodes.begin();iter!=nodes.end();iter++) + radialDistributionOfNodes.insert(nodeToTest->getSlope(*(*iter))); + vector radialDistrib(radialDistributionOfNodes.begin(),radialDistributionOfNodes.end()); + radialDistributionOfNodes.clear(); + vector radialDistrib2(radialDistrib.size()); + copy(radialDistrib.begin()+1,radialDistrib.end(),radialDistrib2.begin()); + radialDistrib2.back()=M_PI+radialDistrib.front(); + vector radialDistrib3(radialDistrib.size()); + transform(radialDistrib2.begin(),radialDistrib2.end(),radialDistrib.begin(),radialDistrib3.begin(),minus()); + vector::iterator iter3=max_element(radialDistrib3.begin(),radialDistrib3.end()); + int i=iter3-radialDistrib3.begin(); + // ok for e1 - Let's go. + EdgeInfLin *e1=new EdgeInfLin(nodeToTest,radialDistrib[i]+radialDistrib3[i]/2.); + double ref=e1->getCharactValue(*nodeToTest); + set< IntersectElement > inOutSwitch; + for(list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + ElementaryEdge *val=(*iter); + if(val) + { + Edge *e=val->getPtr(); + auto_ptr intersc(Edge::buildIntersectorWith(e1,e)); + bool obviousNoIntersection,areOverlapped; + intersc->areOverlappedOrOnlyColinears(0,obviousNoIntersection,areOverlapped); + if(obviousNoIntersection) + { + continue; + } + if(!areOverlapped) + { + list< IntersectElement > listOfIntesc=intersc->getIntersectionsCharacteristicVal(); + for(list< IntersectElement >::iterator iter2=listOfIntesc.begin();iter2!=listOfIntesc.end();iter2++) + if((*iter2).isIncludedByBoth()) + inOutSwitch.insert(*iter2); + } + //if overlapped we can forget + } + else + throw Exception("Invalid use of ComposedEdge::isInOrOut : only one level supported !"); + } + e1->decrRef(); + bool ret=false; + for(set< IntersectElement >::iterator iter=inOutSwitch.begin();iter!=inOutSwitch.end();iter++) + { + if((*iter).getVal1()getLoc()==ON_1) + ret=!ret; + } + else + break; + } + return ret; +} + +/*bool ComposedEdge::isInOrOut(Node *aNodeOn, Node *nodeToTest) const +{ + + EdgeInfLin *e1=new EdgeInfLin(aNodeOn,nodeToTest); + double ref=e1->getCharactValue(*nodeToTest); + set< IntersectElement > inOutSwitch; + for(vector::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + ElementaryEdge *val=dynamic_cast(*iter); + if(val) + { + Edge *e=val->getPtr(); + auto_ptr intersc(Edge::buildIntersectorWith(e1,e)); + bool obviousNoIntersection,areOverlapped; + intersc->areOverlappedOrOnlyColinears(0,obviousNoIntersection,areOverlapped); + if(obviousNoIntersection) + { + continue; + } + if(!areOverlapped) + { + list< IntersectElement > listOfIntesc=intersc->getIntersectionsCharacteristicVal(); + for(list< IntersectElement >::iterator iter2=listOfIntesc.begin();iter2!=listOfIntesc.end();iter2++) + if((*iter2).isIncludedByBoth()) + inOutSwitch.insert(*iter2); + } + //if overlapped we can forget + } + else + throw Exception("Invalid use of ComposedEdge::isInOrOut : only one level supported !"); + } + e1->decrRef(); + bool ret=false; + for(set< IntersectElement >::iterator iter=inOutSwitch.begin();iter!=inOutSwitch.end();iter++) + { + if((*iter).getVal1()getLoc()==ON_1) + ret=!ret; + } + else + break; + } + return ret; +}*/ + +bool ComposedEdge::getDirection() const +{ + throw Exception("ComposedEdge::getDirection : no sense"); +} + +bool ComposedEdge::intresincEqCoarse(const Edge *other) const +{ + if(_sub_edges.size()!=1) + return false; + return _sub_edges.front()->intresincEqCoarse(other); +} + +void ComposedEdge::clearAll(list::iterator startToDel) +{ + for(list::iterator iter=startToDel;iter!=_sub_edges.end();iter++) + delete (*iter); +} diff --git a/src/INTERP_KERNEL/Geometric2D/ComposedEdge.hxx b/src/INTERP_KERNEL/Geometric2D/ComposedEdge.hxx new file mode 100644 index 000000000..583e4af08 --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/ComposedEdge.hxx @@ -0,0 +1,95 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __COMPOSEDNODE_HXX__ +#define __COMPOSEDNODE_HXX__ + +#include "INTERPKERNELGEOMETRIC2DDefines.hxx" + +#include +#include +#include + +namespace INTERP_KERNEL +{ + class Node; + class Edge; + class Bounds; + class ElementaryEdge; + class IteratorOnComposedEdge; + + class INTERPKERNELGEOMETRIC2D_EXPORT ComposedEdge + { + friend class IteratorOnComposedEdge; + public: + ComposedEdge() { } + ComposedEdge(const ComposedEdge& other); + ComposedEdge(int size):_sub_edges(size) { } + static void Delete(ComposedEdge *pt) { delete pt; } + static void SoftDelete(ComposedEdge *pt) { pt->_sub_edges.clear(); delete pt; } + void reverse(); + int recursiveSize() const { return _sub_edges.size(); } + void initLocations() const; + ComposedEdge *clone() const; + bool isNodeIn(Node *n) const; + double getArea() const; + double getPerimeter() const; + double getHydraulicDiameter() const; + void getBarycenter(double *bary) const; + double normalize(ComposedEdge *other); + void fillBounds(Bounds& output) const; + void applySimilarity(double xBary, double yBary, double dimChar); + void applyGlobalSimilarity(double xBary, double yBary, double dimChar); + void dispatchPerimeter(double& partConsidered) const; + void dispatchPerimeterExcl(double& partConsidered, double& commonPart) const; + double dispatchPerimeterAdv(const ComposedEdge& father, std::vector& result) const; + void getAllNodes(std::set& output) const; + void getBarycenter(double *bary, double& weigh) const; + bool completed() const { return getEndNode()==getStartNode(); } + void setValueAt(int i, Edge *e, bool direction=true); + double getCommonLengthWith(const ComposedEdge& other) const; + void clear(); + bool empty() const { return _sub_edges.empty(); } + ElementaryEdge *front() const { return _sub_edges.front(); } + ElementaryEdge *back() const { return _sub_edges.back(); } + void resize(int i) { _sub_edges.resize(i); } + void pushBack(Edge *edge, bool direction=true); + void pushBack(ElementaryEdge *elem); + void pushBack(ComposedEdge *elem); + int size() const { return _sub_edges.size(); } + ElementaryEdge *operator[](int i) const; + Node *getEndNode() const; + Node *getStartNode() const; + bool changeEndNodeWith(Node *node) const; + bool changeStartNodeWith(Node *node) const; + void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const; + bool isInOrOut(Node *nodeToTest) const; + bool getDirection() const; + bool intresincEqCoarse(const Edge *other) const; + private: + std::list* getListBehind() { return &_sub_edges; } + protected: + ~ComposedEdge(); + private: + void clearAll(std::list::iterator startToDel); + protected: + std::list _sub_edges; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Geometric2D/Edge.cxx b/src/INTERP_KERNEL/Geometric2D/Edge.cxx new file mode 100644 index 000000000..334b4d886 --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/Edge.cxx @@ -0,0 +1,846 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "Edge.hxx" +#include "EdgeLin.hxx" +#include "EdgeInfLin.hxx" +//#include "EdgeParabol.hxx" +#include "EdgeArcCircle.hxx" +#include "InterpKernelException.hxx" + +#include + +using namespace std; +using namespace INTERP_KERNEL; + +MergePoints::MergePoints():_ass1Start1(0),_ass1End1(0),_ass1Start2(0),_ass1End2(0), + _ass2Start1(0),_ass2End1(0),_ass2Start2(0),_ass2End2(0) +{ +} + +void MergePoints::start1Replaced() +{ + unsigned nbOfAsso=getNumberOfAssociations(); + if(nbOfAsso==0) + _ass1Start1=1; + else + _ass2Start1=1; +} + +void MergePoints::end1Replaced() +{ + unsigned nbOfAsso=getNumberOfAssociations(); + if(nbOfAsso==0) + _ass1End1=1; + else + _ass2End1=1; +} + +void MergePoints::start1OnStart2() +{ + unsigned nbOfAsso=getNumberOfAssociations(); + if(nbOfAsso==0) + { + _ass1Start1=1; + _ass1Start2=1; + } + else + { + _ass2Start1=1; + _ass2Start2=1; + } +} + +void MergePoints::start1OnEnd2() +{ + unsigned nbOfAsso=getNumberOfAssociations(); + if(nbOfAsso==0) + { + _ass1Start1=1; + _ass1End2=1; + } + else + { + _ass2Start1=1; + _ass2End2=1; + } +} + +void MergePoints::end1OnStart2() +{ + unsigned nbOfAsso=getNumberOfAssociations(); + if(nbOfAsso==0) + { + _ass1End1=1; + _ass1Start2=1; + } + else + { + _ass2End1=1; + _ass2Start2=1; + } +} + +void MergePoints::end1OnEnd2() +{ + unsigned nbOfAsso=getNumberOfAssociations(); + if(nbOfAsso==0) + { + _ass1End1=1; + _ass1End2=1; + } + else + { + _ass2End1=1; + _ass2End2=1; + } +} + +bool MergePoints::isStart1(unsigned rk) const +{ + if(rk==0) + return _ass1Start1; + else + return _ass2Start1; +} + +bool MergePoints::isEnd1(unsigned rk) const +{ + if(rk==0) + return _ass1End1; + else + return _ass2End1; +} + +bool MergePoints::isStart2(unsigned rk) const +{ + if(rk==0) + return _ass1Start2; + else + return _ass2Start2; +} + +bool MergePoints::isEnd2(unsigned rk) const +{ + if(rk==0) + return _ass1End2; + else + return _ass2End2; +} + +void MergePoints::clear() +{ + _ass1Start1=0;_ass1End1=0;_ass1Start2=0;_ass1End2=0; + _ass2Start1=0;_ass2End1=0;_ass2Start2=0;_ass2End2=0; +} + +unsigned MergePoints::getNumberOfAssociations() const +{ + unsigned ret=0; + unsigned subTot=_ass1Start1+_ass1End1+_ass1Start2+_ass1End2; + if(subTot!=0) + ret++; + subTot=_ass2Start1+_ass2End1+_ass2Start2+_ass2End2; + if(subTot!=0) + ret++; + return ret; +} + +IntersectElement::IntersectElement(double val1, double val2, bool start1, bool end1, bool start2, bool end2, Node *node + , const Edge& e1, const Edge& e2, bool keepOrder):_1S(keepOrder?start1:start2), + _1E(keepOrder?end1:end2), + _2S(keepOrder?start2:start1), + _2E(keepOrder?end2:end1), + _chararct_val_for_e1(keepOrder?val1:val2), + _chararct_val_for_e2(keepOrder?val2:val1), + _node(node),_loc_of_node(node->getLoc()),_e1(keepOrder?e1:e2), + _e2(keepOrder?e2:e1) +{ +} + +IntersectElement::IntersectElement(const IntersectElement& other):_1S(other._1S),_1E(other._1E),_2S(other._2S),_2E(other._2E), + _chararct_val_for_e1(other._chararct_val_for_e1), + _chararct_val_for_e2(other._chararct_val_for_e2),_node(other._node), + _loc_of_node(other._loc_of_node),_e1(other._e1), _e2(other._e2) +{ + if(_node) + _node->incrRef(); +} + +IntersectElement& IntersectElement::operator=(const IntersectElement& other) +{ + _1S=other._1S;_1E=other._1E; _2S=other._2S; _2E=other._2E; + _chararct_val_for_e1=other._chararct_val_for_e1; + _chararct_val_for_e2=other._chararct_val_for_e2; + setNode(other._node); + return *this; +} + +bool IntersectElement::operator<(const IntersectElement& other) const +{ + return _e1.isLower(_chararct_val_for_e1,other._chararct_val_for_e1); +} + +IntersectElement::~IntersectElement() +{ + if(_node) + _node->decrRef(); +} + +/*! + * Returns 0 or 1. + */ +bool IntersectElement::isOnMergedExtremity() const +{ + if( (_1S && _2S) || (_1S && _2E) || (_1E && _2S) || (_1E && _2E) ) + return true; + return false; +} + +/*! + * To call if isOnMergedExtremity returned true. + */ +void IntersectElement::performMerging(MergePoints& commonNode) const +{ + if(_1S && _2S) + { + if(_e1.changeStartNodeWith(_e2.getStartNode())) + { + _e2.getStartNode()->declareOnLim(); + commonNode.start1OnStart2(); + } + } + else if(_1S && _2E) + { + if(_e1.changeStartNodeWith(_e2.getEndNode())) + { + _e2.getEndNode()->declareOnLim(); + commonNode.start1OnEnd2(); + } + } + else if(_1E && _2S) + { + if(_e1.changeEndNodeWith(_e2.getStartNode())) + { + _e2.getStartNode()->declareOnLim(); + commonNode.end1OnStart2(); + } + } + else if(_1E && _2E) + { + if(_e1.changeEndNodeWith(_e2.getEndNode())) + { + _e2.getEndNode()->declareOnLim(); + commonNode.end1OnEnd2(); + } + } +} + +/*! + * This methode is const because 'node' is supposed to be equal geomitrically to _node. + */ +void IntersectElement::setNode(Node *node) const +{ + if(node!=_node) + { + if(_node) + ((Node *)_node)->decrRef(); + ((IntersectElement *)(this))->_node=node; + if(_node) + _node->incrRef(); + } +} + +bool IntersectElement::isLowerOnOther(const IntersectElement& other) const +{ + return _e2.isLower(_chararct_val_for_e2,other._chararct_val_for_e2); +} + +unsigned IntersectElement::isOnExtrForAnEdgeAndInForOtherEdge() const +{ + if(( _1S && !(_2S || _2E) ) || ( _1E && !(_2S || _2E) )) + { + if(_1S && !(_2S || _2E)) + setNode(_e1.getStartNode()); + else + setNode(_e1.getEndNode()); + if(_e2.isIn(_chararct_val_for_e2)) + return LIMIT_ON; + return LIMIT_ALONE; + } + if(( _2S && !(_1S || _1E) ) || ( _2E && !(_1S || _1E))) + { + if(_2S && !(_1S || _1E)) + setNode(_e2.getStartNode()); + else + setNode(_e2.getEndNode()); + if(_e1.isIn(_chararct_val_for_e1)) + return LIMIT_ON; + return LIMIT_ALONE; + } + return NO_LIMIT; +} + +bool IntersectElement::isIncludedByBoth() const +{ + return _e1.isIn(_chararct_val_for_e1) && _e2.isIn(_chararct_val_for_e2); +} + +bool EdgeIntersector::intersect(const Bounds *whereToFind, std::vector& newNodes, bool& order, MergePoints& commonNode) +{ + list< IntersectElement > listOfIntesc=getIntersectionsCharacteristicVal(); + list< IntersectElement >::iterator iter; + for(iter=listOfIntesc.begin();iter!=listOfIntesc.end();) + { + if((*iter).isOnMergedExtremity()) + { + (*iter).performMerging(commonNode); + iter=listOfIntesc.erase(iter); + continue; + } + unsigned tmp=(*iter).isOnExtrForAnEdgeAndInForOtherEdge(); + if(tmp==IntersectElement::LIMIT_ALONE) + { + iter=listOfIntesc.erase(iter); + continue; + } + else if(tmp==IntersectElement::LIMIT_ON) + { + (*iter).attachLoc(); + iter++; + continue; + } + if(!(*iter).isIncludedByBoth()) + { + iter=listOfIntesc.erase(iter); + continue; + } + (*iter).attachLoc(); + iter++; + } + if(listOfIntesc.size()==0) + return false; + if(listOfIntesc.size()==1) + { + order=true;//useless + newNodes.push_back(listOfIntesc.front().getNodeAndReleaseIt()); + } + else + { + vector vecOfIntesc(listOfIntesc.begin(),listOfIntesc.end()); + listOfIntesc.clear(); + sort(vecOfIntesc.begin(),vecOfIntesc.end()); + for(vector::iterator iterV=vecOfIntesc.begin();iterV!=vecOfIntesc.end();iterV++) + newNodes.push_back((*iterV).getNodeAndReleaseIt()); + order=vecOfIntesc.front().isLowerOnOther(vecOfIntesc.back()); + } + return true; +} + +/*! + * Locates 'node' regarding edge this->_e1. If node is located close to (with distant lt epsilon) start or end point of _e1, + * 'node' takes its place. In this case 'obvious' is set to true and 'commonNode' stores information of merge point and finally 'where' is set. + * Furthermore 'node' is declared as ON LIMIT to indicate in locating process that an absolute location computation will have to be done. + * If 'node' is not close to start or end point of _e1, 'obvious' is set to false and 'commonNode' and 'where' are let unchanged. + */ +void EdgeIntersector::obviousCaseForCurvAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode, bool& obvious) const +{ + obvious=true; + if(node->isEqual(*_e1.getStartNode())) + { + where=START; + if(_e1.changeStartNodeWith(node)) + { + commonNode.start1Replaced(); + node->declareOnLim(); + } + return ; + } + if(node->isEqual(*_e1.getEndNode())) + { + where=END; + if(_e1.changeEndNodeWith(node)) + { + commonNode.end1Replaced(); + node->declareOnLim(); + } + return ; + } + obvious=false; +} + +Edge::Edge(double sX, double sY, double eX, double eY):_cnt(1),_loc(FULL_UNKNOWN),_start(new Node(sX,sY)),_end(new Node(eX,eY)) +{ +} + +Edge::~Edge() +{ + _start->decrRef(); + if(_end) + _end->decrRef(); +} + +bool Edge::decrRef() +{ + bool ret=(--_cnt==0); + if(ret) + delete this; + return ret; +} + +void Edge::declareOn() const +{ + if(_loc==FULL_UNKNOWN) + { + _loc=FULL_ON_1; + _start->declareOn(); + _end->declareOn(); + } +} + +void Edge::declareIn() const +{ + if(_loc==FULL_UNKNOWN) + { + _loc=FULL_IN_1; + _start->declareIn(); + _end->declareIn(); + } +} + +void Edge::declareOut() const +{ + if(_loc==FULL_UNKNOWN) + { + _loc=FULL_OUT_1; + _start->declareOut(); + _end->declareOut(); + } +} + +void Edge::fillXfigStreamForLoc(std::ostream& stream) const +{ + switch(_loc) + { + case FULL_IN_1: + stream << '2';//Green + break; + case FULL_OUT_1: + stream << '1';//Bleue + break; + case FULL_ON_1: + stream << '4';//Red + break; + default: + stream << '0'; + } +} + +bool Edge::changeStartNodeWith(Node *otherStartNode) const +{ + if(_start==otherStartNode) + return true; + if(_start->isEqual(*otherStartNode)) + { + (((Edge *)this)->_start)->decrRef();//un-const cast Ok thanks to 2 lines above. + (((Edge *)this)->_start)=otherStartNode; + _start->incrRef(); + return true; + } + return false; +} + +bool Edge::changeStartNodeWithAndKeepTrack(Node *otherStartNode, std::vector& track) const +{ + if(_start==otherStartNode) + return true; + if(_start->isEqualAndKeepTrack(*otherStartNode,track)) + { + (((Edge *)this)->_start)->decrRef();//un-const cast Ok thanks to 2 lines above. + (((Edge *)this)->_start)=otherStartNode; + otherStartNode->incrRef(); + return true; + } + return false; +} + +bool Edge::changeEndNodeWith(Node *otherEndNode) const +{ + if(_end==otherEndNode) + return true; + if(_end->isEqual(*otherEndNode)) + { + (((Edge *)this)->_end)->decrRef(); + (((Edge *)this)->_end)=otherEndNode; + _end->incrRef(); + return true; + } + return false; +} + +bool Edge::changeEndNodeWithAndKeepTrack(Node *otherEndNode, std::vector& track) const +{ + if(_end==otherEndNode) + return true; + if(_end->isEqualAndKeepTrack(*otherEndNode,track)) + { + (((Edge *)this)->_end)->decrRef(); + (((Edge *)this)->_end)=otherEndNode; + otherEndNode->incrRef(); + return true; + } + return false; +} + +/*! + * Precondition : 'start' and 'end' are lying on the same curve than 'this'. + * Add in vec the sub edge lying on this. + * If 'start' is equal (by pointer) to '_end' and 'end' is equal to '_end' too nothing is added. + * If 'start' is equal (by pointer) to '_start' and 'end' is equal to '_start' too nothing is added. + * If 'start' is equal (by pointer) to '_start' and 'end' is equal to '_end' this is added in vec. + */ +void Edge::addSubEdgeInVector(Node *start, Node *end, ComposedEdge& vec) const +{ + if((start==_start && end==_start) || (start==_end && end==_end)) + return ; + if(start==_start && end==_end) + { + incrRef(); + vec.pushBack((Edge *)this); + return ; + } + vec.pushBack(buildEdgeLyingOnMe(start,end,true)); +} + +/*! + * Retrieves a vector 'vectOutput' that is normal to 'this'. 'vectOutput' is normalized. + */ +void Edge::getNormalVector(double *vectOutput) const +{ + copy((const double *)(*_end),(const double *)(*_end)+2,vectOutput); + transform(vectOutput,vectOutput+2,(const double *)(*_start),vectOutput,minus()); + double norm=1./Node::norm(vectOutput); + transform(vectOutput,vectOutput+2,vectOutput,bind2nd(multiplies(),norm)); + double tmp=vectOutput[0]; + vectOutput[0]=vectOutput[1]; + vectOutput[1]=-tmp; +} + +Edge *Edge::buildEdgeFrom(Node *start, Node *end) +{ + return new EdgeLin(start,end); +} + +Edge *Edge::buildFromXfigLine(std::istream& str) +{ + unsigned char type; + str >> type; + if(type=='2') + return new EdgeLin(str); + else if(type=='5') + return new EdgeArcCircle(str); + else + { + std::cerr << "Unknown line found..."; + return 0; + } +} + +/*! + * \param other The Edge with which we are going to intersect. + * \param commonNode Output. The common nodes found during operation of intersecting. + * \param outVal1 Output filled in case true is returned. It specifies the new or not new edges by which 'this' is replaced after intersecting op. + * \param outVal2 Output filled in case true is returned. It specifies the new or not new edges by which 'other' is replaced after intersecting op. + * return true if the intersection between this. + */ +bool Edge::intersectWith(const Edge *other, MergePoints& commonNode, + ComposedEdge& outVal1, ComposedEdge& outVal2) const +{ + bool ret=true; + Bounds *merge=_bounds.nearlyAmIIntersectingWith(other->getBounds()); + if(!merge) + return false; + delete merge; + merge=0; + EdgeIntersector *intersector=buildIntersectorWith(this,other); + ret=intersect(this,other,intersector,merge,commonNode,outVal1,outVal2); + delete intersector; + return ret; +} + +bool Edge::intersectOverlapped(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, MergePoints& commonNode, + ComposedEdge& outValForF1, ComposedEdge& outValForF2) +{ + bool rev=intersector->haveTheySameDirection(); + Node *f2Start=f2->getNode(rev?START:END); + Node *f2End=f2->getNode(rev?END:START); + TypeOfLocInEdge place1, place2; + intersector->getPlacements(f2Start,f2End,place1,place2,commonNode); + int codeForIntersectionCase=combineCodes(place1,place2); + return splitOverlappedEdges(f1,f2,f2Start,f2End,rev,codeForIntersectionCase,outValForF1,outValForF2); +} + +/*! + * Perform 1D linear interpolation. Warning distrib1 and distrib2 are expected to be in ascending mode. + */ +void Edge::interpolate1DLin(const std::vector& distrib1, const std::vector& distrib2, std::map >& result) +{ + int nbOfV1=distrib1.size()-1; + int nbOfV2=distrib2.size()-1; + Node *n1=new Node(0.,0.); Node *n3=new Node(0.,0.); + Node *n2=new Node(0.,0.); Node *n4=new Node(0.,0.); + MergePoints commonNode; + for(int i=0;i::const_iterator iter=find_if(distrib2.begin()+1,distrib2.end(),bind2nd(greater_equal(),distrib1[i])); + if(iter!=distrib2.end()) + { + for(int j=(iter-1)-distrib2.begin();jsetNewCoords(distrib1[i],0.); n2->setNewCoords(distrib1[i+1],0.); + n3->setNewCoords(distrib2[j],0.); n4->setNewCoords(distrib2[j+1],0.); + ComposedEdge *f1=new ComposedEdge; + ComposedEdge *f2=new ComposedEdge; + SegSegIntersector inters(*e1,*e2); + bool b1,b2; + inters.areOverlappedOrOnlyColinears(0,b1,b2); + if(intersectOverlapped(e1,e2,&inters,commonNode,*f1,*f2)) + { + result[i][j]=f1->getCommonLengthWith(*f2)/e1->getCurveLength(); + } + ComposedEdge::Delete(f1); ComposedEdge::Delete(f2); + e1->decrRef(); e2->decrRef(); + } + } + } + } + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); +} + +EdgeIntersector *Edge::buildIntersectorWith(const Edge *e1, const Edge *e2) +{ + EdgeIntersector *ret=0; + const EdgeLin *tmp1=0; + const EdgeArcCircle *tmp2=0; + unsigned char type1=e1->getTypeOfFunc(); + e1->dynCastFunction(tmp1,tmp2); + unsigned char type2=e2->getTypeOfFunc(); + e2->dynCastFunction(tmp1,tmp2); + type1|=type2; + switch(type1) + { + case 1:// Intersection seg/seg + ret=new SegSegIntersector((const EdgeLin &)(*e1),(const EdgeLin &)(*e2)); + break; + case 5:// Intersection seg/arc of circle + ret=new ArcCSegIntersector(*tmp2,*tmp1,tmp2==e1); + break; + case 4:// Intersection arc/arc of circle + ret=new ArcCArcCIntersector((const EdgeArcCircle &)(*e1),(const EdgeArcCircle &)(*e2)); + break; + default: + //Should never happen + throw Exception("A non managed association of edge has been detected. Go work for intersection computation implementation."); + } + return ret; +} + +/*! + * See Node::applySimilarity to see signification of params. + */ +void Edge::applySimilarity(double xBary, double yBary, double dimChar) +{ + _bounds.applySimilarity(xBary,yBary,dimChar); +} + +bool Edge::intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, const Bounds *whereToFind, MergePoints& commonNode, + ComposedEdge& outValForF1, ComposedEdge& outValForF2) +{ + bool obviousNoIntersection; + bool areOverlapped; + intersector->areOverlappedOrOnlyColinears(whereToFind,obviousNoIntersection,areOverlapped); + if(areOverlapped) + return intersectOverlapped(f1,f2,intersector,commonNode,outValForF1,outValForF2); + if(obviousNoIntersection) + return false; + vector newNodes; + bool order; + if(intersector->intersect(whereToFind,newNodes,order,commonNode)) + { + if(newNodes.empty()) + throw Exception("Internal error occured - error in intersector implementation!");// This case should never happen + vector::iterator iter=newNodes.begin(); + vector::reverse_iterator iterR=newNodes.rbegin(); + f1->addSubEdgeInVector(f1->getStartNode(),*iter,outValForF1); + f2->addSubEdgeInVector(f2->getStartNode(),order?*iter:*iterR,outValForF2); + for(vector::iterator iter=newNodes.begin();iter!=newNodes.end();iter++,iterR++) + { + if((iter+1)==newNodes.end()) + { + f1->addSubEdgeInVector(*iter,f1->getEndNode(),outValForF1); + (*iter)->decrRef(); + f2->addSubEdgeInVector(order?*iter:*iterR,f2->getEndNode(),outValForF2); + } + else + { + f1->addSubEdgeInVector(*iter,*(iter+1),outValForF1); + (*iter)->decrRef(); + f2->addSubEdgeInVector(order?*iter:*iterR,order?*(iter+1):*(iterR+1),outValForF2); + } + } + return true; + } + else//no intersection inside whereToFind + return false; +} + +int Edge::combineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2) +{ + int ret=(int)code1; + ret*=OFFSET_FOR_TYPEOFLOCINEDGE; + ret+=(int)code2; + return ret; +} + +/*! + * This method splits e1 and e2 into pieces as much sharable as possible. The precondition to the call of this method + * is that e1 and e2 have been declared as overlapped by corresponding intersector built from e1 and e2 type. + * + * @param nS start node of e2 with the SAME DIRECTION as e1. The pointer nS should be equal to start node of e2 or to its end node. + * @param nE end node of e2 with the SAME DIRECTION as e1. The pointer nE should be equal to start node of e2 or to its end node. + * @param direction is param that specifies if e2 and e1 have same directions (true) or opposed (false). + * @param code is the code returned by method Edge::combineCodes. + */ +bool Edge::splitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *nE, bool direction, int code, + ComposedEdge& outVal1, ComposedEdge& outVal2) +{ + Edge *tmp; + switch(code) + { + case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+START: // OUT_BEFORE - START + case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_BEFORE: // OUT_BEFORE - OUT_BEFORE + case OUT_AFTER*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // OUT_AFTER - OUT_AFTER + case END*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // END - OUT_AFTER + case END*OFFSET_FOR_TYPEOFLOCINEDGE+START: // END - START + return false; + case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // INSIDE - OUT_AFTER + outVal1.pushBack(e1->buildEdgeLyingOnMe(e1->getStartNode(),nS,true)); + tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef(); + outVal1.pushBack(tmp); + outVal2.resize(2); + outVal2.setValueAt(direction?0:1,tmp,direction); tmp->declareOn(); + outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); + return true; + case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // INSIDE - INSIDE + { + if(!e2->isIn(e2->getCharactValue(*(e1->getStartNode())))) + { + e2->incrRef(); e2->incrRef(); + outVal1.resize(3); + outVal1.setValueAt(0,e1->buildEdgeLyingOnMe(e1->getStartNode(),nS)); + outVal1.setValueAt(1,(Edge*)e2,direction); + outVal1.setValueAt(2,e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); + outVal2.pushBack((Edge*)e2); e2->declareOn(); + return true; + } + else + { + outVal1.resize(3); + outVal2.resize(3); + tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef(); tmp->declareOn(); + outVal1.setValueAt(0,tmp,true); outVal2.setValueAt(direction?2:0,tmp,direction); + outVal1.setValueAt(1,e1->buildEdgeLyingOnMe(nE,nS)); + tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef(); tmp->declareOn(); + outVal1.setValueAt(2,tmp,true); outVal2.setValueAt(direction?0:2,tmp,direction); + tmp=e1->buildEdgeLyingOnMe(e1->getEndNode(),e1->getStartNode()); + outVal2.setValueAt(1,tmp,direction); + return true; + } + } + case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // OUT_BEFORE - INSIDE + tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef(); + outVal1.pushBack(tmp); + outVal1.pushBack(e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); + outVal2.resize(2); + outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction)); + outVal2.setValueAt(direction?1:0,tmp,direction); tmp->declareOn(); + return true; + case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // OUT_BEFORE - OUT_AFTER + e1->incrRef(); e1->incrRef(); + outVal1.pushBack((Edge*)e1); + outVal2.resize(3); + outVal2.setValueAt(direction?0:2,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction)); + outVal2.setValueAt(1,(Edge*)e1,direction); e1->declareOn(); + outVal2.setValueAt(direction?2:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); + return true; + case START*OFFSET_FOR_TYPEOFLOCINEDGE+END: // START - END + e1->incrRef(); e1->incrRef(); + outVal1.pushBack((Edge*)e1); + outVal2.pushBack((Edge*)e1,direction); e1->declareOn(); + return true; + case START*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // START - OUT_AFTER + e1->incrRef(); e1->incrRef(); + outVal1.pushBack((Edge*)e1); + outVal2.resize(2); + outVal2.setValueAt(direction?0:1,(Edge*)e1,direction); e1->declareOn(); + outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); + return true; + case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+END: // INSIDE - END + e2->incrRef(); e2->incrRef(); + outVal1.pushBack(e1->buildEdgeLyingOnMe(e1->getStartNode(),nS,true)); + outVal1.pushBack((Edge*)e2,direction); + outVal2.pushBack((Edge*)e2); e2->declareOn(); + return true; + case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+END: // OUT_BEFORE - END + e1->incrRef(); e1->incrRef(); + outVal1.pushBack((Edge*)e1); + outVal2.resize(2); + outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction)); + outVal2.setValueAt(direction?1:0,(Edge*)e1,direction); e1->declareOn(); + return true; + case START*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // START - INSIDE + e2->incrRef(); e2->incrRef(); + outVal1.pushBack((Edge*)e2,direction); + outVal1.pushBack(e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); + outVal2.pushBack((Edge*)e2); e2->declareOn(); + return true; + case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+START: // INSIDE - START + outVal1.resize(2); + outVal2.resize(2); + tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef(); tmp->declareOn(); + outVal1.setValueAt(0,e1->buildEdgeLyingOnMe(e1->getStartNode(),nS)); + outVal1.setValueAt(1,tmp); + outVal2.setValueAt(direction?0:1,tmp,direction); + outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); + return true; + case END*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // END - INSIDE + outVal1.resize(2); + outVal2.resize(2); + tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef(); tmp->declareOn(); + outVal1.setValueAt(0,tmp); + outVal1.setValueAt(1,e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); + outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(e1->getEndNode(),e1->getStartNode(),direction)); + outVal2.setValueAt(direction?1:0,tmp,direction); + return true; + default: + throw Exception("Unexpected situation of overlapping edges : internal error occurs ! "); + } +} diff --git a/src/INTERP_KERNEL/Geometric2D/Edge.hxx b/src/INTERP_KERNEL/Geometric2D/Edge.hxx new file mode 100644 index 000000000..3aff6efce --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/Edge.hxx @@ -0,0 +1,279 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __EDGE_HXX__ +#define __EDGE_HXX__ + +#include "INTERPKERNELGEOMETRIC2DDefines.hxx" +#include "ComposedEdge.hxx" +#include "InterpKernelException.hxx" +#include "Bounds.hxx" +#include "Node.hxx" + +#include +#include +#include +#include + +namespace INTERP_KERNEL +{ + typedef enum + { + SEG = 1, + ARC_CIRCLE = 4, + ARC_PARABOL = 8 + } TypeOfFunction; + + typedef enum + { + CIRCLE = 0 , + PARABOL = 1 + } TypeOfMod4QuadEdge; + + typedef enum + { + START = 5, + END = 1, + INSIDE = 2, + OUT_BEFORE = 3, + OUT_AFTER = 4 + } TypeOfLocInEdge; //see Edge::OFFSET_FOR_TYPEOFLOCINEDGE + + typedef enum + { + FULL_IN_1 = 1, + FULL_ON_1 = 4, + FULL_OUT_1 = 2, + FULL_UNKNOWN = 3 + } TypeOfEdgeLocInPolygon; + + class INTERPKERNELGEOMETRIC2D_EXPORT MergePoints + { + public: + MergePoints(); + + //methods called during intersection edge-edge + void start1Replaced(); + void end1Replaced(); + void start1OnStart2(); + void start1OnEnd2(); + void end1OnStart2(); + void end1OnEnd2(); + //methods to be called during aggregation + bool isStart1(unsigned rk) const; + bool isEnd1(unsigned rk) const; + bool isStart2(unsigned rk) const; + bool isEnd2(unsigned rk) const; + void clear(); + unsigned getNumberOfAssociations() const; + private: + unsigned _ass1Start1 : 1; + unsigned _ass1End1 : 1; + unsigned _ass1Start2 : 1; + unsigned _ass1End2 : 1; + unsigned _ass2Start1 : 1; + unsigned _ass2End1 : 1; + unsigned _ass2Start2 : 1; + unsigned _ass2End2 : 1; + }; + + /*! + * This class is in charge to store an intersection point as result of \b non oververlapping edge intersection. + * This class manages the cases when intersect element is one of the extrimities of edge1 and/or edge2. + */ + class INTERPKERNELGEOMETRIC2D_EXPORT IntersectElement + { + public: + IntersectElement(double val1, double val2, bool start1, bool end1, bool start2, bool end2, Node *node, const Edge& e1, const Edge& e2, bool keepOrder); + IntersectElement(const IntersectElement& other); + //! The sort operator is done on the edge 1 \b not edge 2. + bool operator<(const IntersectElement& other) const; + IntersectElement& operator=(const IntersectElement& other); + double getVal1() const { return _chararct_val_for_e1; } + double getVal2() const { return _chararct_val_for_e2; } + //! idem operator< method except that the orientation is done on edge 2 \b not edge 1. + bool isLowerOnOther(const IntersectElement& other) const; + unsigned isOnExtrForAnEdgeAndInForOtherEdge() const; + void attachLoc() { _node->setLoc(_loc_of_node); } + bool isOnMergedExtremity() const; + bool isIncludedByBoth() const; + void setNode(Node *node) const; + void performMerging(MergePoints& commonNode) const; + Node *getNodeOnly() const { return _node; } + Node *getNodeAndReleaseIt() { Node *tmp=_node; _node=0; return tmp; } + ~IntersectElement(); + private: + bool _1S; + bool _1E; + bool _2S; + bool _2E; + double _chararct_val_for_e1; + double _chararct_val_for_e2; + Node *_node; + TypeOfLocInPolygon _loc_of_node; + const Edge& _e1; + const Edge& _e2; + public: + static const unsigned LIMIT_ALONE = 22; + static const unsigned LIMIT_ON = 73; + static const unsigned NO_LIMIT = 19; + }; + + /*! + * This abstract interface specifies all the methods to be overloaded of all possibilities edge-intersection. + */ + class INTERPKERNELGEOMETRIC2D_EXPORT EdgeIntersector + { + protected: + //! All non symetric methods are relative to 'e1'. + EdgeIntersector(const Edge& e1, const Edge& e2):_e1(e1),_e2(e2) { } + public: + virtual ~EdgeIntersector() { } + virtual bool keepOrder() const = 0; + //!to call only if 'areOverlapped' have been set to true when areOverlappedOrOnlyColinears was called + virtual bool haveTheySameDirection() const = 0; + //!to call only if 'areOverlapped' have been set to true when areOverlappedOrOnlyColinears was called + virtual void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const = 0; + //! When true is returned, newNodes should contains at least 1 element. All merging nodes betw _e1 and _e2 extremities must be done. + bool intersect(const Bounds *whereToFind, std::vector& newNodes, bool& order, MergePoints& commonNode); + //! Should be called only once per association. + virtual void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped) = 0; + //! The size of returned vector is equal to number of potential intersections point. The values are so that their are interpretable by virtual Edge::isIn method. + virtual std::list< IntersectElement > getIntersectionsCharacteristicVal() const = 0; + protected: + void obviousCaseForCurvAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode, bool& obvious) const; + protected: + const Edge& _e1; + const Edge& _e2; + }; + + class INTERPKERNELGEOMETRIC2D_EXPORT SameTypeEdgeIntersector : public EdgeIntersector + { + protected: + SameTypeEdgeIntersector(const Edge& e1, const Edge& e2):EdgeIntersector(e1,e2) { } + bool keepOrder() const { return true; } + }; + + class INTERPKERNELGEOMETRIC2D_EXPORT CrossTypeEdgeIntersector : public EdgeIntersector + { + protected: + CrossTypeEdgeIntersector(const Edge& e1, const Edge& e2, bool reverse):EdgeIntersector(e1,e2),_reverse(reverse) { } + bool keepOrder() const { return _reverse; } + bool haveTheySameDirection() const { throw Exception("Cross type intersector is not supposed to deal with overlapped in cross type."); } + const Edge *myE1() { if(_reverse) return &_e1; else return &_e2; } + const Edge *myE2() { if(_reverse) return &_e2; else return &_e1; } + protected: + //! boolean to inform intersector that unsymetrics treatments reverse of e1 and e2 should be done. + bool _reverse; + }; + + class EdgeLin; + class EdgeInfLin; + class EdgeArcCircle; + + /*! + * Deal with an oriented edge of a polygon. + * An Edge is definied with a start node a end node and an equation of 1D curve. + * All other attributes are mutable because they don't impact these 3 invariant attributes. + * To be exact start and end node can change (adress) but their location remain + * the same (at precision). + */ + class INTERPKERNELGEOMETRIC2D_EXPORT Edge + { + public: + Edge(Node *start, Node *end, bool direction=true):_cnt(1),_loc(FULL_UNKNOWN) { if(direction) { _start=start; _end=end; } else { _start=end; _end=start; } _start->incrRef(); _end->incrRef(); } + Edge(double sX, double sY, double eX, double eY); + TypeOfEdgeLocInPolygon getLoc() const { return _loc; } + void incrRef() const { _cnt++; } + bool decrRef(); + void initLocs() const { _loc=FULL_UNKNOWN; _start->initLocs(); _end->initLocs(); } + void declareOn() const; + void declareIn() const; + void declareOut() const; + const Bounds& getBounds() const { return _bounds; } + void fillXfigStreamForLoc(std::ostream& stream) const; + Node *getNode(TypeOfLocInEdge where) const { if(where==START) return _start; else if(where==END) return _end; else return 0; } + Node *getStartNode() const { return _start; } + Node *getEndNode() const { return _end; } + void setEndNodeWithoutChange(Node *newEnd); + void setStartNodeWithoutChange(Node *newStart); + bool changeStartNodeWith(Node *otherStartNode) const; + bool changeStartNodeWithAndKeepTrack(Node *otherStartNode, std::vector& track) const; + bool changeEndNodeWith(Node *otherEndNode) const; + bool changeEndNodeWithAndKeepTrack(Node *otherEndNode, std::vector& track) const; + void addSubEdgeInVector(Node *start, Node *end, ComposedEdge& vec) const; + void getNormalVector(double *vectOutput) const; + static EdgeIntersector *buildIntersectorWith(const Edge *e1, const Edge *e2); + static Edge *buildFromXfigLine(std::istream& str); + static Edge *buildEdgeFrom(Node *start, Node *end); + template + static Edge *buildEdgeFrom(Node *start, Node *middle, Node *end); + virtual void update(Node *m) = 0; + //! returns area between this and axe Ox delimited along Ox by _start and _end. + virtual double getAreaOfZone() const = 0; + //! apply a similiraty transformation on 'this' + virtual void applySimilarity(double xBary, double yBary, double dimChar); + //! return the length of arc. Value is always > 0. ! + virtual double getCurveLength() const = 0; + virtual void getBarycenter(double *bary) const = 0; + virtual void getBarycenterOfZone(double *bary) const = 0; + //! Retrieves a point that is owning to this, well placed for IN/OUT detection of this. Typically midlle of this is returned. + virtual Node *buildRepresentantOfMySelf() const = 0; + //! Given a magnitude specified by sub-type returns if in or not. See getCharactValue method. + virtual bool isIn(double characterVal) const = 0; + //! With the same magnitude as defined in 'isIn' method perform a compararison. Precondition : val1 and val2 are different and exactly INSIDE this. + virtual bool isLower(double val1, double val2) const = 0; + //! node is expected to lay on 'this'. It returns a characteristic magnitude usable by isIn method. + virtual double getCharactValue(const Node& node) const = 0; + //! retrieves the distance to this : The min distance from pt and any point of this. + virtual double getDistanceToPoint(const double *pt) const = 0; + //! return if node with coords 'coordOfNode' is on this (with precision). + virtual bool isNodeLyingOn(const double *coordOfNode) const = 0; + virtual TypeOfFunction getTypeOfFunc() const = 0; + virtual void dynCastFunction(const EdgeLin * &seg, + const EdgeArcCircle * &arcSeg) const = 0; + bool intersectWith(const Edge *other, MergePoints& commonNode, + ComposedEdge& outVal1, ComposedEdge& outVal2) const; + static bool intersectOverlapped(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, MergePoints& commonNode, + ComposedEdge& outValForF1, ComposedEdge& outValForF2); + static void interpolate1DLin(const std::vector& distrib1, const std::vector& distrib2, + std::map >& result); + virtual void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const = 0; + protected: + Edge():_cnt(1),_loc(FULL_UNKNOWN),_start(0),_end(0) { } + virtual ~Edge(); + static int combineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2); + static bool intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, const Bounds *whereToFind, MergePoints& commonNode, + ComposedEdge& outValForF1, ComposedEdge& outValForF2); + //! The code 'code' is built by method combineCodes + static bool splitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *nE, bool direction, int code, + ComposedEdge& outVal1, ComposedEdge& outVal2); + virtual Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction=true) const = 0; + protected: + mutable unsigned char _cnt; + mutable TypeOfEdgeLocInPolygon _loc; + Bounds _bounds; + Node *_start; + Node *_end; + protected: + //In relation with max possible value of TypeOfLocInEdge. + static const int OFFSET_FOR_TYPEOFLOCINEDGE = 8; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Geometric2D/Edge.txx b/src/INTERP_KERNEL/Geometric2D/Edge.txx new file mode 100644 index 000000000..6a3f80f5b --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/Edge.txx @@ -0,0 +1,30 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __EDGE_TXX__ +#define __EDGE_TXX__ + +#include "EdgeArcCircle.hxx" + +template +INTERP_KERNEL::Edge *INTERP_KERNEL::Edge::buildEdgeFrom(Node *start, Node *middle, Node *end) +{ + return new INTERP_KERNEL::EdgeArcCircle(start,middle,end); +} + +#endif diff --git a/src/INTERP_KERNEL/Geometric2D/EdgeArcCircle.cxx b/src/INTERP_KERNEL/Geometric2D/EdgeArcCircle.cxx new file mode 100644 index 000000000..f65ab1510 --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/EdgeArcCircle.cxx @@ -0,0 +1,695 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "EdgeArcCircle.hxx" +#include "EdgeLin.hxx" +#include "InterpKernelException.hxx" +#include "Node.hxx" + +#include +#include + +using namespace std; +using namespace INTERP_KERNEL; + +ArcCArcCIntersector::ArcCArcCIntersector(const EdgeArcCircle& e1, const EdgeArcCircle& e2):SameTypeEdgeIntersector(e1,e2),_dist(0.) +{ +} + +bool ArcCArcCIntersector::haveTheySameDirection() const +{ + return (getE1().getAngle()>0. && getE2().getAngle()>0.) || (getE1().getAngle()<0. && getE2().getAngle()<0.); +} + +/*! + * Precondition 'start' and 'end' are on the same curve than this. + */ +void ArcCArcCIntersector::getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const +{ + bool obvious1,obvious2; + obviousCaseForCurvAbscisse(start,whereStart,commonNode,obvious1); + obviousCaseForCurvAbscisse(end,whereEnd,commonNode,obvious2); + if(obvious1 && obvious2) + return ; + double angleInRadStart=getAngle(start); + double angleInRadEnd=getAngle(end); + if(obvious1 || obvious2) + { + if(obvious1) + { + if(EdgeArcCircle::isIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadEnd)) + whereEnd=INSIDE; + else + whereEnd=OUT_AFTER; + return ; + } + else + { + if(EdgeArcCircle::isIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadStart)) + whereStart=INSIDE; + else + whereStart=OUT_BEFORE; + return ; + } + } + if(EdgeArcCircle::isIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadStart)) + { + whereStart=INSIDE; + if(EdgeArcCircle::isIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadEnd)) + whereEnd=INSIDE; + else + whereEnd=OUT_AFTER; + } + else + {//we are out in start. + if(EdgeArcCircle::isIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadEnd)) + { + whereStart=OUT_BEFORE; + whereEnd=INSIDE; + } + else + { + if(EdgeArcCircle::isIn2Pi(getE2().getAngle0(),getE2().getAngle(),getE1().getAngle0())) + {//_e2 contains stictly _e1 + whereStart=OUT_BEFORE; + whereEnd=OUT_AFTER; + } + else + {//_e2 is outside from _e1 + whereStart=OUT_BEFORE; + whereEnd=OUT_BEFORE; + } + } + } +} + +/*! + * Return angle between ]-Pi;Pi[ + */ +double ArcCArcCIntersector::getAngle(Node *node) const +{ + return EdgeArcCircle::getAbsoluteAngleOfNormalizedVect(((*node)[0]-getE1().getCenter()[0])/getE1().getRadius(),((*node)[1]-getE1().getCenter()[1])/getE1().getRadius()); +} + +bool ArcCArcCIntersector::areArcsOverlapped(const EdgeArcCircle& a1, const EdgeArcCircle& a2) +{ + double centerL[2],radiusL,angle0L,angleL; + double centerB[2],radiusB; + double lgth1=fabs(a1.getAngle()*a1.getRadius()); + double lgth2=fabs(a2.getAngle()*a2.getRadius()); + if(lgth1getInterceptedArc(centerL,radiusL,angle0L,angleL); + delete merge; + // + tmp=sqrt(tmp); + if(Node::areDoubleEqualsWP(tmp,0.,1/(10*std::max(radiusL,radiusB)))) + { + if(Node::areDoubleEquals(radiusL,radiusB)) + return true; + else + return false; + } + double phi=EdgeArcCircle::getAbsoluteAngleOfNormalizedVect((centerL[0]-centerB[0])/tmp,(centerL[1]-centerB[1])/tmp); + double cst2=2*radiusL*tmp/(radiusB*radiusB); + double cmpContainer[4]; + int sizeOfCmpContainer=2; + cmpContainer[0]=cst+cst2*cos(phi-angle0L); + cmpContainer[1]=cst+cst2*cos(phi-angle0L+angleL); + double a=EdgeArcCircle::normalizeAngle(phi-angle0L); + if(EdgeArcCircle::isIn2Pi(angle0L,angleL,a)) + cmpContainer[sizeOfCmpContainer++]=cst+cst2; + a=EdgeArcCircle::normalizeAngle(phi-angle0L+M_PI); + if(EdgeArcCircle::isIn2Pi(angle0L,angleL,a)) + cmpContainer[sizeOfCmpContainer++]=cst-cst2; + a=*max_element(cmpContainer,cmpContainer+sizeOfCmpContainer); + return Node::areDoubleEqualsWP(a,1.,2.); +} + +void ArcCArcCIntersector::areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped) +{ + _dist=Node::distanceBtw2Pt(getE1().getCenter(),getE2().getCenter()); + double radius1=getE1().getRadius(); double radius2=getE2().getRadius(); + if(_dist>radius1+radius2+QUADRATIC_PLANAR::_precision || _dist+std::min(radius1,radius2)+QUADRATIC_PLANAR::_precision ArcCArcCIntersector::getIntersectionsCharacteristicVal() const +{ + std::list< IntersectElement > ret; + const double *center1=getE1().getCenter(); + const double *center2=getE2().getCenter(); + double radius1=getE1().getRadius(); double radius2=getE2().getRadius(); + double d1_1=(_dist*_dist-radius2*radius2+radius1*radius1)/(2.*_dist); + double u[2];//u is normalized vector from center1 to center2. + u[0]=(center2[0]-center1[0])/_dist; u[1]=(center2[1]-center1[1])/_dist; + double d1_1y=EdgeArcCircle::safeSqrt(radius1*radius1-d1_1*d1_1); + double angleE1=EdgeArcCircle::normalizeAngle(getE1().getAngle0()+getE1().getAngle()); + double angleE2=EdgeArcCircle::normalizeAngle(getE2().getAngle0()+getE2().getAngle()); + if(!Node::areDoubleEquals(d1_1y,0)) + { + //2 intersections + double v1[2],v2[2]; + v1[0]=u[0]*d1_1-u[1]*d1_1y; v1[1]=u[1]*d1_1+u[0]*d1_1y; + v2[0]=u[0]*d1_1+u[1]*d1_1y; v2[1]=u[1]*d1_1-u[0]*d1_1y; + Node *node1=new Node(center1[0]+v1[0],center1[1]+v1[1]); node1->declareOn(); + Node *node2=new Node(center1[0]+v2[0],center1[1]+v2[1]); node2->declareOn(); + double angle1_1=EdgeArcCircle::getAbsoluteAngleOfNormalizedVect(v1[0]/radius1,v1[1]/radius1); + double angle2_1=EdgeArcCircle::getAbsoluteAngleOfNormalizedVect(v2[0]/radius1,v2[1]/radius1); + double v3[2],v4[2]; + v3[0]=center1[0]-center2[0]+v1[0]; v3[1]=center1[1]-center2[1]+v1[1]; + v4[0]=center1[0]-center2[0]+v2[0]; v4[1]=center1[1]-center2[1]+v2[1]; + double angle1_2=EdgeArcCircle::getAbsoluteAngleOfNormalizedVect(v3[0]/radius2,v3[1]/radius2); + double angle2_2=EdgeArcCircle::getAbsoluteAngleOfNormalizedVect(v4[0]/radius2,v4[1]/radius2); + // + bool e1_1S=Node::areDoubleEqualsWP(angle1_1,getE1().getAngle0(),radius1); + bool e1_1E=Node::areDoubleEqualsWP(angle1_1,angleE1,radius1); + bool e1_2S=Node::areDoubleEqualsWP(angle1_2,getE2().getAngle0(),radius1); + bool e1_2E=Node::areDoubleEqualsWP(angle1_2,angleE2,radius1); + // + bool e2_1S=Node::areDoubleEqualsWP(angle2_1,getE1().getAngle0(),radius2); + bool e2_1E=Node::areDoubleEqualsWP(angle2_1,angleE1,radius2); + bool e2_2S=Node::areDoubleEqualsWP(angle2_2,getE2().getAngle0(),radius2); + bool e2_2E=Node::areDoubleEqualsWP(angle2_2,angleE2,radius2); + ret.push_back(IntersectElement(angle1_1,angle1_2,e1_1S,e1_1E,e1_2S,e1_2E,node1,_e1,_e2,keepOrder())); + ret.push_back(IntersectElement(angle2_1,angle2_2,e2_1S,e2_1E,e2_2S,e2_2E,node2,_e1,_e2,keepOrder())); + } + else + { + //tangent intersection + double v1[2],v2[2]; + v1[0]=d1_1*u[0]; v1[1]=d1_1*u[1]; + v2[0]=center1[0]-center2[0]+v1[0]; v2[1]=center1[1]-center2[1]+v1[1]; + double angle0_1=EdgeArcCircle::getAbsoluteAngleOfNormalizedVect(v1[0]/radius1,v1[1]/radius1); + double angle0_2=EdgeArcCircle::getAbsoluteAngleOfNormalizedVect(v2[0]/radius2,v2[1]/radius2); + bool e0_1S=Node::areDoubleEqualsWP(angle0_1,getE1().getAngle0(),radius1); + bool e0_1E=Node::areDoubleEqualsWP(angle0_1,angleE1,radius1); + bool e0_2S=Node::areDoubleEqualsWP(angle0_2,getE2().getAngle0(),radius2); + bool e0_2E=Node::areDoubleEqualsWP(angle0_2,angleE2,radius2); + Node *node=new Node(center1[0]+d1_1*u[0],center1[1]+d1_1*u[1]); node->declareOnTangent(); + ret.push_back(IntersectElement(angle0_1,angle0_2,e0_1S,e0_1E,e0_2S,e0_2E,node,_e1,_e2,keepOrder())); + } + return ret; +} +/*double angle0_2; + double signDeltaAngle2; + double d1_2; + if(u[1]<0.) + angle0_1=-angle0_1; + if(d1_1>=0.) + { + if(_dist>radius1) + { + angle0_2=angle0_1+M_PI; + signDeltaAngle2=-1.; + } + else + { + angle0_2=angle0_1; + signDeltaAngle2=1.; + } + } + else + { + angle0_1+=M_PI; + angle0_2=angle0_1; + signDeltaAngle2=1.; + } + angle0_1=normalizeAngle(angle0_1); + angle0_2=normalizeAngle(angle0_2); + double angleE1=normalizeAngle(getE1().getAngle0()+getE1().getAngle()); + double angleE2=normalizeAngle(getE2().getAngle0()+getE2().getAngle()); + if(!(Node::areDoubleEquals(d1_1,radius1) || Node::areDoubleEquals(d1_1,-radius1)) ) + { + //2 intersections + double deltaAngle1=EdgeArcCircle::safeAcos(fabs(d1_1)/radius1); //owns to 0;Pi/2 by construction + double deltaAngle2=EdgeArcCircle::safeAcos(fabs(d1_2)/radius2); //owns to 0;Pi/2 by construction + double angle1_1=normalizeAngle(angle0_1+deltaAngle1);// Intersection 1 seen for _e1 + double angle2_1=normalizeAngle(angle0_1-deltaAngle1);// Intersection 2 seen for _e1 + double angle1_2=normalizeAngle(angle0_2+signDeltaAngle2*deltaAngle2);// Intersection 1 seen for _e2 + double angle2_2=normalizeAngle(angle0_2-signDeltaAngle2*deltaAngle2);// Intersection 2 seen for _e2 + // + bool e1_1S=Node::areDoubleEqualsWP(angle1_1,getE1().getAngle0(),radius1); + bool e1_1E=Node::areDoubleEqualsWP(angle1_1,angleE1,radius1); + bool e1_2S=Node::areDoubleEqualsWP(angle1_2,getE2().getAngle0(),radius1); + bool e1_2E=Node::areDoubleEqualsWP(angle1_2,angleE2,radius1); + // + bool e2_1S=Node::areDoubleEqualsWP(angle2_1,getE1().getAngle0(),radius2); + bool e2_1E=Node::areDoubleEqualsWP(angle2_1,angleE1,radius2); + bool e2_2S=Node::areDoubleEqualsWP(angle2_2,getE2().getAngle0(),radius2); + bool e2_2E=Node::areDoubleEqualsWP(angle2_2,angleE2,radius2); + Node *node1=new Node(center1[0]+radius1*cos(angle1_1),center1[0]+radius1*sin(angle1_1)); node1->declareOn(); + Node *node2=new Node(center1[0]+radius1*cos(angle2_1),center1[0]+radius1*sin(angle2_1)); node2->declareOn(); + ret.push_back(IntersectElement(angle1_1,angle1_2,e1_1S,e1_1E,e1_2S,e1_2E,node1,_e1,_e2,keepOrder())); + ret.push_back(IntersectElement(angle2_1,angle2_2,e2_1S,e2_1E,e2_2S,e2_2E,node2,_e1,_e2,keepOrder())); + } + else + //tangent intersection + { + bool e0_1S=Node::areDoubleEqualsWP(angle0_1,getE1().getAngle0(),radius1); + bool e0_1E=Node::areDoubleEqualsWP(angle0_1,angleE1,radius1); + bool e0_2S=Node::areDoubleEqualsWP(angle0_2,getE2().getAngle0(),radius2); + bool e0_2E=Node::areDoubleEqualsWP(angle0_2,angleE2,radius2); + Node *node=new Node(center1[0]+radius1*cos(angle0_1),center1[0]+radius1*sin(angle0_1)); node->declareOnTangent(); + ret.push_back(IntersectElement(angle0_1,angle0_2,e0_1S,e0_1E,e0_2S,e0_2E,node,_e1,_e2,keepOrder())); + } + return ret;*/ + +ArcCSegIntersector::ArcCSegIntersector(const EdgeArcCircle& e1, const EdgeLin& e2, bool reverse):CrossTypeEdgeIntersector(e1,e2,reverse) +{ +} + +void ArcCSegIntersector::areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped) +{ + areOverlapped=false;//No overlapping by contruction + const double *center=getE1().getCenter(); + _dx=(*(_e2.getEndNode()))[0]-(*(_e2.getStartNode()))[0]; + _dy=(*(_e2.getEndNode()))[1]-(*(_e2.getStartNode()))[1]; + _drSq=_dx*_dx+_dy*_dy; + _cross= + ((*(_e2.getStartNode()))[0]-center[0])*((*(_e2.getEndNode()))[1]-center[1])- + ((*(_e2.getStartNode()))[1]-center[1])*((*(_e2.getEndNode()))[0]-center[0]); + _determinant=getE1().getRadius()*getE1().getRadius()/_drSq-_cross*_cross/(_drSq*_drSq); + if(_determinant>-2*QUADRATIC_PLANAR::_precision)//QUADRATIC_PLANAR::_precision*QUADRATIC_PLANAR::_precision*_drSq*_drSq/(2.*_dx*_dx)) + obviousNoIntersection=false; + else + obviousNoIntersection=true; +} + +void ArcCSegIntersector::getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const +{ + throw Exception("Internal error. Should never been called : no overlapping possible between arc of circle and a segment."); +} + +std::list< IntersectElement > ArcCSegIntersector::getIntersectionsCharacteristicVal() const +{ + std::list< IntersectElement > ret; + const double *center=getE1().getCenter(); + if(!(fabs(_determinant)<(2.*QUADRATIC_PLANAR::_precision)))//QUADRATIC_PLANAR::_precision*QUADRATIC_PLANAR::_precision*_drSq*_drSq/(2.*_dx*_dx)) + { + double determinant=EdgeArcCircle::safeSqrt(_determinant); + double x1=(_cross*_dy/_drSq+Node::sign(_dy)*_dx*determinant)+center[0]; + double y1=(-_cross*_dx/_drSq+fabs(_dy)*determinant)+center[1]; + Node *intersect1=new Node(x1,y1); intersect1->declareOn(); + bool i1_1S=_e1.getStartNode()->isEqual(*intersect1); + bool i1_1E=_e1.getEndNode()->isEqual(*intersect1); + bool i1_2S=_e2.getStartNode()->isEqual(*intersect1); + bool i1_2E=_e2.getEndNode()->isEqual(*intersect1); + ret.push_back(IntersectElement(getE1().getCharactValue(*intersect1),getE2().getCharactValue(*intersect1),i1_1S,i1_1E,i1_2S,i1_2E,intersect1,_e1,_e2,keepOrder())); + // + double x2=(_cross*_dy/_drSq-Node::sign(_dy)*_dx*determinant)+center[0]; + double y2=(-_cross*_dx/_drSq-fabs(_dy)*determinant)+center[1]; + Node *intersect2=new Node(x2,y2); intersect2->declareOn(); + bool i2_1S=_e1.getStartNode()->isEqual(*intersect2); + bool i2_1E=_e1.getEndNode()->isEqual(*intersect2); + bool i2_2S=_e2.getStartNode()->isEqual(*intersect2); + bool i2_2E=_e2.getEndNode()->isEqual(*intersect2); + ret.push_back(IntersectElement(getE1().getCharactValue(*intersect2),getE2().getCharactValue(*intersect2),i2_1S,i2_1E,i2_2S,i2_2E,intersect2,_e1,_e2,keepOrder())); + } + else//tangent intersection + { + double x=(_cross*_dy)/_drSq+center[0]; + double y=(-_cross*_dx)/_drSq+center[1]; + Node *intersect=new Node(x,y); intersect->declareOnTangent(); + bool i_1S=_e1.getStartNode()->isEqual(*intersect); + bool i_1E=_e1.getEndNode()->isEqual(*intersect); + bool i_2S=_e2.getStartNode()->isEqual(*intersect); + bool i_2E=_e2.getEndNode()->isEqual(*intersect); + ret.push_back(IntersectElement(_e1.getCharactValue(*intersect),_e2.getCharactValue(*intersect),i_1S,i_1E,i_2S,i_2E,intersect,_e1,_e2,keepOrder())); + } + return ret; +} + +EdgeArcCircle::EdgeArcCircle(std::istream& lineInXfig) +{ + const unsigned NB_OF_SKIP_FIELDS=15; + std::string tmpS; + for(unsigned i=0;i> tmpS; + _start=new Node(lineInXfig); + Node *middle=new Node(lineInXfig); + _end=new Node(lineInXfig); + getArcOfCirclePassingThru(*_start,*middle,*_end,_center,_radius,_angle,_angle0); + middle->decrRef(); + updateBounds(); +} + +EdgeArcCircle::EdgeArcCircle(Node *start, Node *middle, Node *end, bool direction):Edge(start,end, direction) +{ + getArcOfCirclePassingThru(*_start,*middle,*_end,_center,_radius,_angle,_angle0); + updateBounds(); +} + +EdgeArcCircle::EdgeArcCircle(double sX, double sY, double mX, double mY, double eX, double eY):Edge(sX,sY,eX,eY) +{ + double middle[2]; middle[0]=mX; middle[1]=mY; + getArcOfCirclePassingThru(*_start,middle,*_end,_center,_radius,_angle,_angle0); + updateBounds(); +} + +/*! + * @param angle0 in ]-Pi;Pi[ + * @param deltaAngle in ]-2.*Pi;2.*Pi[ + */ +EdgeArcCircle::EdgeArcCircle(Node *start, Node *end, const double *center, double radius, double angle0, double deltaAngle, bool direction):Edge(start,end,direction),_angle(deltaAngle), + _angle0(angle0),_radius(radius) +{ + _center[0]=center[0]; + _center[1]=center[1]; + updateBounds(); +} + +void EdgeArcCircle::changeMiddle(Node *newMiddle) +{ + getArcOfCirclePassingThru(*_start,*newMiddle,*_end,_center,_radius,_angle,_angle0); + updateBounds(); +} + +Edge *EdgeArcCircle::buildEdgeLyingOnMe(Node *start, Node *end, bool direction) const +{ + double sx=((*start)[0]-_center[0])/_radius; + double sy=((*start)[1]-_center[1])/_radius; + double ex=((*end)[0]-_center[0])/_radius; + double ey=((*end)[1]-_center[1])/_radius; + double angle0=getAbsoluteAngleOfNormalizedVect(direction?sx:ex,direction?sy:ey); + double deltaAngle=getAbsoluteAngleOfNormalizedVect(sx*ex+sy*ey,sx*ey-sy*ex); + if(deltaAngle>0. && _angle<0.) + deltaAngle-=2.*M_PI; + else if(deltaAngle<0. && _angle>0.) + deltaAngle+=2.*M_PI; + deltaAngle=direction?deltaAngle:-deltaAngle; + return new EdgeArcCircle(start,end,_center,_radius,angle0,deltaAngle,direction); +} + +void EdgeArcCircle::applySimilarity(double xBary, double yBary, double dimChar) +{ + Edge::applySimilarity(xBary,yBary,dimChar); + _radius/=dimChar; + _center[0]=(_center[0]-xBary)/dimChar; + _center[1]=(_center[1]-yBary)/dimChar; +} + +/*! + * Given an \b NON normalized vector 'vect', returns its norm 'normVect' and its + * angle in ]-Pi,Pi] relative to Ox axe. + */ +double EdgeArcCircle::getAbsoluteAngle(const double *vect, double& normVect) +{ + normVect=Node::norm(vect); + return getAbsoluteAngleOfNormalizedVect(vect[0]/normVect,vect[1]/normVect); +} + +/*! + * Given a \b normalized vector defined by (ux,uy) returns its angle in ]-Pi;Pi]. + * So before using this method ux*ux+uy*uy should as much as possible close to 1. + * This methods is quite time consuming in order to keep as much as possible precision. + * It is NOT ALWAYS possible to do that only in one call of acos. Sometimes call to asin is necessary + * due to imperfection of acos near 0. and Pi (cos x ~ 1-x*x/2.) + */ +double EdgeArcCircle::getAbsoluteAngleOfNormalizedVect(double ux, double uy) +{ + //When arc is lower than 0.707 Using Asin + if(fabs(ux)<0.707) + { + double ret=safeAcos(ux); + if(uy>0.) + return ret; + ret=-ret; + return ret; + } + else + { + double ret=safeAsin(uy); + if(ux>0.) + return ret; + if(ret>0.) + return M_PI-ret; + else + return -M_PI-ret; + } +} + +void EdgeArcCircle::getArcOfCirclePassingThru(const double *start, const double *middle, const double *end, + double *center, double& radius, double& angleInRad, double& angleInRad0) +{ + double delta=(middle[0]-start[0])*(end[1]-middle[1])-(end[0]-middle[0])*(middle[1]-start[1]); + double b1=(middle[1]*middle[1]+middle[0]*middle[0]-start[0]*start[0]-start[1]*start[1])/2; + double b2=(end[1]*end[1]+end[0]*end[0]-middle[0]*middle[0]-middle[1]*middle[1])/2; + center[0]=((end[1]-middle[1])*b1+(start[1]-middle[1])*b2)/delta; + center[1]=((middle[0]-end[0])*b1+(middle[0]-start[0])*b2)/delta; + radius=safeSqrt((start[0]-center[0])*(start[0]-center[0])+(start[1]-center[1])*(start[1]-center[1])); + angleInRad0=getAbsoluteAngleOfNormalizedVect((start[0]-center[0])/radius,(start[1]-center[1])/radius); + double angleInRadM=getAbsoluteAngleOfNormalizedVect((middle[0]-center[0])/radius,(middle[1]-center[1])/radius); + angleInRad=getAbsoluteAngleOfNormalizedVect(((start[0]-center[0])*(end[0]-center[0])+(start[1]-center[1])*(end[1]-center[1]))/(radius*radius), + ((start[0]-center[0])*(end[1]-center[1])-(start[1]-center[1])*(end[0]-center[0]))/(radius*radius)); + if(isAngleNotIn(angleInRad0,angleInRad,angleInRadM)) + angleInRad=angleInRad<0?2*M_PI+angleInRad:angleInRad-2*M_PI; +} + +void EdgeArcCircle::dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const +{ + stream << "5 1 0 1 "; + fillXfigStreamForLoc(stream); + stream << " 7 50 -1 -1 0.000 0 "; + if( (direction && _angle>=0) || (!direction && _angle<0)) + stream << '0';//'0' + else + stream << '1';//'1' + stream << " 0 0 "; + stream << box.fitXForXFigD(_center[0],resolution) << " " << box.fitYForXFigD(_center[1],resolution) << " "; + direction?_start->dumpInXfigFile(stream,resolution,box):_end->dumpInXfigFile(stream,resolution,box); + Node *middle=buildRepresentantOfMySelf(); + middle->dumpInXfigFile(stream,resolution,box); + middle->decrRef(); + direction?_end->dumpInXfigFile(stream,resolution,box):_start->dumpInXfigFile(stream,resolution,box); + stream << endl; +} + +void EdgeArcCircle::update(Node *m) +{ + getArcOfCirclePassingThru(*_start,*m,*_end,_center,_radius,_angle,_angle0); + updateBounds(); +} + +/*! + * This methods computes : + * \f[ + * \int_{Current Edge} -ydx + * \f] + */ +double EdgeArcCircle::getAreaOfZone() const +{ + return -_radius*_radius*(sin(_angle)-_angle)/2.+((*_start)[0]-(*_end)[0])*((*_start)[1]+(*_end)[1])/2.; +} + +double EdgeArcCircle::getCurveLength() const +{ + return fabs(_angle*_radius); +} + +void EdgeArcCircle::getBarycenter(double *bary) const +{ + bary[0]=_center[0]+_radius*cos(_angle0+_angle/2.); + bary[1]=_center[1]+_radius*sin(_angle0+_angle/2.); +} + +/*! + * \f[ + * bary[0]=\int_{Current Edge} -yxdx + * \f] + * \f[ + * bary[1]=\int_{Current Edge} -\frac{y^{2}}{2}dx + * \f] + * To compute these 2 expressions in this class we have : + * \f[ + * x=x_{0}+Radius \cdot cos(\theta) + * \f] + * \f[ + * y=y_{0}+Radius \cdot sin(\theta) + * \f] + * \f[ + * dx=-Radius \cdot sin(\theta) \cdot d\theta + * \f] + */ +void EdgeArcCircle::getBarycenterOfZone(double *bary) const +{ + double x0=_center[0]; + double y0=_center[1]; + double angle1=_angle0+_angle; + double tmp1=sin(angle1); + double tmp0=sin(_angle0); + double tmp2=_radius*_radius*_radius; + double tmp3=cos(angle1); + double tmp4=cos(_angle0); + bary[0]=_radius*x0*y0*(tmp4-tmp3)+_radius*_radius*(y0*(cos(2*_angle0)-cos(2*angle1))/4.+ + x0*(_angle/2.+(sin(2.*_angle0)-sin(2.*angle1))/4.)) + +tmp2*(tmp1*tmp1*tmp1-tmp0*tmp0*tmp0)/3.; + bary[1]=y0*y0*_radius*(tmp4-tmp3)/2.+_radius*_radius*y0*(_angle/2.+(sin(2.*_angle0)-sin(2.*angle1))/4.) + +tmp2*(tmp4-tmp3+(tmp3*tmp3*tmp3-tmp4*tmp4*tmp4)/3.)/2.; +} + +/*! + * Characteristic value used is angle in ]_Pi;Pi[ from axe 0x. + */ +bool EdgeArcCircle::isIn(double characterVal) const +{ + return isIn2Pi(_angle0,_angle,characterVal); +} + +Node *EdgeArcCircle::buildRepresentantOfMySelf() const +{ + return new Node(_center[0]+_radius*cos(_angle0+_angle/2.),_center[1]+_radius*sin(_angle0+_angle/2.)); +} + +/*! + * Characteristic value used is angle in ]_Pi;Pi[ from axe 0x. + * 'val1' and 'val2' have been detected previously as owning to this. + */ +bool EdgeArcCircle::isLower(double val1, double val2) const +{ + double myDelta1=val1-_angle0; + double myDelta2=val2-_angle0; + if(_angle>0.) + { + myDelta1=myDelta1>-(_radius*QUADRATIC_PLANAR::_precision)?myDelta1:myDelta1+2.*M_PI;//in some cases val1 or val2 are so close to angle0 that myDelta is close to 0. but negative. + myDelta2=myDelta2>-(_radius*QUADRATIC_PLANAR::_precision)?myDelta2:myDelta2+2.*M_PI; + return myDelta10.) + { + myDelta=myDelta>=0.?myDelta:myDelta+2.*M_PI; + return myDelta>0. && myDeltadelta; + } +} + +/*! + * Given the arc 'a' defined by 'start' angle and a 'delta' [-Pi;Pi] states for the angle 'angleIn' [-Pi;Pi] if it owns or not 'a'. + */ +bool EdgeArcCircle::isAngleNotIn(double start, double delta, double angleIn) +{ + double tmp=start; + if(tmp<0.) + tmp+=2*M_PI; + double tmp2=angleIn; + if(tmp2<0.) + tmp2+=2*M_PI; + if(tmp+delta>=2.*M_PI) + return (tmp2tmp+delta-2*M_PI); + else if(tmp+delta>=0.) + return (tmp2std::max(tmp,tmp+delta)); + else + return (tmp2>tmp) && (tmp2<(tmp+delta+2.*M_PI)); +} + +void EdgeArcCircle::updateBounds() +{ + _bounds.setValues(std::min((*_start)[0],(*_end)[0]),std::max((*_start)[0],(*_end)[0]),std::min((*_start)[1],(*_end)[1]),std::max((*_start)[1],(*_end)[1])); + if(isIn2Pi(_angle0,_angle,M_PI/2)) + _bounds[3]=_center[1]+_radius; + if(isIn2Pi(_angle0,_angle,-M_PI/2)) + _bounds[2]=_center[1]-_radius; + if(isIn2Pi(_angle0,_angle,0.)) + _bounds[1]=_center[0]+_radius; + if(isIn2Pi(_angle0,_angle,M_PI)) + _bounds[0]=_center[0]-_radius; +} diff --git a/src/INTERP_KERNEL/Geometric2D/EdgeArcCircle.hxx b/src/INTERP_KERNEL/Geometric2D/EdgeArcCircle.hxx new file mode 100644 index 000000000..b3a4a3e20 --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/EdgeArcCircle.hxx @@ -0,0 +1,122 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __EDGEARCCIRCLE_HXX__ +#define __EDGEARCCIRCLE_HXX__ + +#include "Edge.hxx" + +namespace INTERP_KERNEL +{ + class ArcCArcCIntersector : public SameTypeEdgeIntersector + { + public: + ArcCArcCIntersector(const EdgeArcCircle& e1, const EdgeArcCircle& e2); + bool haveTheySameDirection() const; + void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const; + void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped); + std::list< IntersectElement > getIntersectionsCharacteristicVal() const; + private: + //! return angle in ]-Pi;Pi[ - 'node' must be on curve of '_e1' + double getAngle(Node *node) const; + static bool areArcsOverlapped(const EdgeArcCircle& a1, const EdgeArcCircle& a2); + private: + const EdgeArcCircle& getE1() const { return (const EdgeArcCircle&)_e1; } + const EdgeArcCircle& getE2() const { return (const EdgeArcCircle&)_e2; } + private: + double _dist; + }; + + class ArcCSegIntersector : public CrossTypeEdgeIntersector + { + public: + ArcCSegIntersector(const EdgeArcCircle& e1, const EdgeLin& e2, bool reverse=true); + //virtual overloading + void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const; + void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped); + std::list< IntersectElement > getIntersectionsCharacteristicVal() const; + private: + const EdgeArcCircle& getE1() const { return (const EdgeArcCircle&)_e1; } + const EdgeLin& getE2() const { return (const EdgeLin&)_e2; } + private: + double _dx; + double _dy; + double _drSq; + double _cross; + double _determinant; + }; + + class EdgeArcCircle : public Edge + { + public: + EdgeArcCircle(std::istream& lineInXfig); + EdgeArcCircle(Node *start, Node *middle, Node *end, bool direction = true); + EdgeArcCircle(double sX, double sY, double mX, double mY, double eX, double eY); + EdgeArcCircle(Node *start, Node *end, const double *center, double radius, double angle0, double deltaAngle, bool direction=true); + //! for tests + void changeMiddle(Node *newMiddle); + void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const; + void update(Node *m); + double getAreaOfZone() const; + double getCurveLength() const; + void getBarycenter(double *bary) const; + void getBarycenterOfZone(double *bary) const; + bool isIn(double characterVal) const; + Node *buildRepresentantOfMySelf() const; + bool isLower(double val1, double val2) const; + double getCharactValue(const Node& node) const; + double getDistanceToPoint(const double *pt) const; + bool isNodeLyingOn(const double *coordOfNode) const; + TypeOfFunction getTypeOfFunc() const { return ARC_CIRCLE; } + void dynCastFunction(const EdgeLin * &seg, + const EdgeArcCircle * &arcSeg) const { arcSeg=this; } + const double *getCenter() const { return _center; } + void getCenter(double *center) const { center[0]=_center[0]; center[1]=_center[1]; } + bool doIHaveSameDirectionAs(const Edge& other) const { return false; } + void applySimilarity(double xBary, double yBary, double dimChar); + double getAngle0() const { return _angle0; } + double getRadius() const { return _radius; } + double getAngle() const { return _angle; } + static double getAbsoluteAngle(const double *vect, double& normVect); + static double getAbsoluteAngleOfNormalizedVect(double ux, double uy); + static void getArcOfCirclePassingThru(const double *start, const double *middle, const double *end, + double *center, double& radius, double& angleInRad, double& angleInRad0); + //! To avoid in aggressive optimizations nan. + static double safeSqrt(double val) { double ret=std::max(val,0.); return sqrt(ret); } + static double safeAcos(double cosAngle) { double ret=std::min(cosAngle,1.); ret=std::max(ret,-1.); return acos(ret); } + static double safeAsin(double sinAngle) { double ret=std::min(sinAngle,1.); ret=std::max(ret,-1.); return asin(ret); } + //! @param start and @param angleIn in ]-Pi;Pi] and @param delta in ]-2*Pi,2*Pi[ + static bool isIn2Pi(double start, double delta, double angleIn); + //! 'delta' 'start' in ]-Pi;Pi[ + static bool isAngleNotIn(double start, double delta, double angleIn); + //! for an angle 'angle' in ]-3*Pi;3*Pi[ returns angle in ]-Pi;Pi[ + static double normalizeAngle(double angle) { if(angle>M_PI) return angle-2.*M_PI; if(angle<-M_PI) return angle+2.*M_PI; return angle; } + protected: + void updateBounds(); + Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction=true) const; + protected: + //!Value between -2Pi and 2Pi + double _angle; + //!Value between -Pi and Pi + double _angle0; + double _radius; + double _center[2]; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Geometric2D/EdgeInfLin.cxx b/src/INTERP_KERNEL/Geometric2D/EdgeInfLin.cxx new file mode 100644 index 000000000..2f3fd9da5 --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/EdgeInfLin.cxx @@ -0,0 +1,28 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "EdgeInfLin.hxx" + +using namespace INTERP_KERNEL; + +EdgeInfLin::EdgeInfLin(Node *pointPassingThrough, double slope) +{ + _start=pointPassingThrough; + _start->incrRef(); + _end=new Node((*_start)[0]+cos(slope),(*_start)[1]+sin(slope)); +} diff --git a/src/INTERP_KERNEL/Geometric2D/EdgeInfLin.hxx b/src/INTERP_KERNEL/Geometric2D/EdgeInfLin.hxx new file mode 100644 index 000000000..d600b7701 --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/EdgeInfLin.hxx @@ -0,0 +1,40 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __EDGEINFLIN_HXX__ +#define __EDGEINFLIN_HXX__ + +#include "EdgeLin.hxx" + +namespace INTERP_KERNEL +{ + class EdgeInfLin : public EdgeLin + { + public: + EdgeInfLin(Node *start, Node *end):EdgeLin(start,end,true) { } + EdgeInfLin(Node *pointPassingThrough, double slope); + bool isIn(double characterVal) const { return true; } + void dynCastFunction(const EdgeLin * &seg, + const EdgeArcCircle * &arcSeg) const { seg=this; } + void dumpInXfigFile(std::ostream& stream) const { } + private: + ~EdgeInfLin() { } + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Geometric2D/EdgeLin.cxx b/src/INTERP_KERNEL/Geometric2D/EdgeLin.cxx new file mode 100644 index 000000000..92f051610 --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/EdgeLin.cxx @@ -0,0 +1,294 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "EdgeLin.hxx" +#include "Node.hxx" +#include "InterpKernelException.hxx" + +using namespace std; +using namespace INTERP_KERNEL; + +namespace INTERP_KERNEL +{ + extern const unsigned MAX_SIZE_OF_LINE_XFIG_FILE=1024; +} + +SegSegIntersector::SegSegIntersector(const EdgeLin& e1, const EdgeLin& e2):SameTypeEdgeIntersector(e1,e2) +{ + _matrix[0]=(*(e2.getStartNode()))[0]-(*(e2.getEndNode()))[0]; + _matrix[1]=(*(e1.getEndNode()))[0]-(*(e1.getStartNode()))[0]; + _matrix[2]=(*(e2.getStartNode()))[1]-(*(e2.getEndNode()))[1]; + _matrix[3]=(*(e1.getEndNode()))[1]-(*(e1.getStartNode()))[1]; + _col[0]=_matrix[3]*(*(e1.getStartNode()))[0]-_matrix[1]*(*(e1.getStartNode()))[1]; + _col[1]=-_matrix[2]*(*(e2.getStartNode()))[0]+_matrix[0]*(*(e2.getStartNode()))[1]; + //Little trick to avoid problems if 'e1' and 'e2' are colinears and along Ox or Oy axes. + if(fabs(_matrix[3])>fabs(_matrix[1])) + _ind=0; + else + _ind=1; +} + +/*! + * Must be called when 'this' and 'other' have been detected to be at least colinear. Typically they are overlapped. + * Must be called after call of areOverlappedOrOnlyColinears. + */ +bool SegSegIntersector::haveTheySameDirection() const +{ + return (_matrix[3]*_matrix[1]+_matrix[2]*_matrix[0])>0.; + //return (_matrix[_ind?1:0]>0. && _matrix[_ind?3:2]>0.) || (_matrix[_ind?1:0]<0. && _matrix[_ind?3:2]<0.); +} + +/*! + * Precondition start and end must be so that there predecessor was in the same direction than 'e1' + */ +void SegSegIntersector::getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const +{ + getCurveAbscisse(start,whereStart,commonNode); + getCurveAbscisse(end,whereEnd,commonNode); +} + +void SegSegIntersector::getCurveAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode) const +{ + bool obvious; + obviousCaseForCurvAbscisse(node,where,commonNode,obvious); + if(obvious) + return ; + double ret=((*node)[!_ind]-(*_e1.getStartNode())[!_ind])/((*_e1.getEndNode())[!_ind]-(*_e1.getStartNode())[!_ind]); + if(ret>0. && ret <1.) + where=INSIDE; + else if(ret<0.) + where=OUT_BEFORE; + else + where=OUT_AFTER; +} + +/*! + * areColinears method should be called before with a returned colinearity equal to false to avoid bad news. + */ +std::list< IntersectElement > SegSegIntersector::getIntersectionsCharacteristicVal() const +{ + std::list< IntersectElement > ret; + double x=_matrix[0]*_col[0]+_matrix[1]*_col[1]; + double y=_matrix[2]*_col[0]+_matrix[3]*_col[1]; + //Only one intersect point possible + Node *node=new Node(x,y); + node->declareOn(); + bool i_1S=_e1.getStartNode()->isEqual(*node); + bool i_1E=_e1.getEndNode()->isEqual(*node); + bool i_2S=_e2.getStartNode()->isEqual(*node); + bool i_2E=_e2.getEndNode()->isEqual(*node); + ret.push_back(IntersectElement(_e1.getCharactValue(*node), + _e2.getCharactValue(*node), + i_1S,i_1E,i_2S,i_2E,node,_e1,_e2,keepOrder())); + return ret; +} + +/*! + * retrieves if segs are colinears. + * WARNING !!! Contrary to areOverlappedOrOnlyColinears method, this method use an + * another precision to detect colinearity ! + */ +bool SegSegIntersector::areColinears() const +{ + double determinant=_matrix[0]*_matrix[3]-_matrix[1]*_matrix[2]; + return fabs(determinant)2.*QUADRATIC_PLANAR::_precision)//2*_precision due to max of offset on _start and _end + { + colinearity=false; areOverlapped=false; + _matrix[0]/=determinant; _matrix[1]/=determinant; _matrix[2]/=determinant; _matrix[3]/=determinant; + } + else + { + colinearity=true; + //retrieving initial matrix + double tmp=_matrix[0]; _matrix[0]=_matrix[3]; _matrix[3]=tmp; + _matrix[1]=-_matrix[1]; _matrix[2]=-_matrix[2]; + // + double deno=sqrt(_matrix[0]*_matrix[0]+_matrix[1]*_matrix[1]); + double x=(*(_e1.getStartNode()))[0]-(*(_e2.getStartNode()))[0]; + double y=(*(_e1.getStartNode()))[1]-(*(_e2.getStartNode()))[1]; + areOverlapped=fabs((_matrix[1]*y+_matrix[0]*x)/deno)0. && characterVal<1.; +} + +Node *EdgeLin::buildRepresentantOfMySelf() const +{ + return new Node(((*(_start))[0]+(*(_end))[0])/2.,((*(_start))[1]+(*(_end))[1])/2.); +} + +double EdgeLin::getCharactValue(const Node& node) const +{ + return getCharactValueEng(node); +} + +double EdgeLin::getDistanceToPoint(const double *pt) const +{ + double loc=getCharactValueEng(pt); + if(loc>0. && loc<1.) + { + double tmp[2]; + tmp[0]=(*_start)[0]*(1-loc)+loc*(*_end)[0]; + tmp[1]=(*_start)[1]*(1-loc)+loc*(*_end)[1]; + return Node::distanceBtw2Pt(pt,tmp); + } + else + { + double dist1=Node::distanceBtw2Pt(*_start,pt); + double dist2=Node::distanceBtw2Pt(*_end,pt); + return std::min(dist1,dist2); + } +} + +bool EdgeLin::isNodeLyingOn(const double *coordOfNode) const +{ + double dBase=sqrt(_start->distanceWithSq(*_end)); + double d1=Node::distanceBtw2Pt(*_start,coordOfNode); + d1+=Node::distanceBtw2Pt(*_end,coordOfNode); + return Node::areDoubleEquals(dBase,d1); +} + +void EdgeLin::dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const +{ + stream << "2 1 0 1 "; + fillXfigStreamForLoc(stream); + stream << " 7 50 -1 -1 0.000 0 0 -1 0 0 2" << endl; + direction?_start->dumpInXfigFile(stream,resolution,box):_end->dumpInXfigFile(stream,resolution,box); + direction?_end->dumpInXfigFile(stream,resolution,box):_start->dumpInXfigFile(stream,resolution,box); + stream << endl; +} + +void EdgeLin::update(Node *m) +{ + updateBounds(); +} + +double EdgeLin::getNormSq() const +{ + return _start->distanceWithSq(*_end); +} + +/*! + * This methods computes : + * \f[ + * \int_{Current Edge} -ydx + * \f] + */ +double EdgeLin::getAreaOfZone() const +{ + return ((*_start)[0]-(*_end)[0])*((*_start)[1]+(*_end)[1])/2.; +} + +void EdgeLin::getBarycenter(double *bary) const +{ + bary[0]=((*_start)[0]+(*_end)[0])/2.; + bary[1]=((*_start)[1]+(*_end)[1])/2.; +} + +/*! + * \f[ + * bary[0]=\int_{Current Edge} -yxdx + * \f] + * \f[ + * bary[1]=\int_{Current Edge} -\frac{y^{2}}{2}dx + * \f] + * To compute these 2 expressions in this class we have : + * \f[ + * y=y_{1}+\frac{y_{2}-y_{1}}{x_{2}-x_{1}}(x-x_{1}) + * \f] + */ +void EdgeLin::getBarycenterOfZone(double *bary) const +{ + double x1=(*_start)[0]; + double y1=(*_start)[1]; + double x2=(*_end)[0]; + double y2=(*_end)[1]; + bary[0]=(x1-x2)*(y1*(2.*x1+x2)+y2*(2.*x2+x1))/6.; + //bary[0]+=(y1-y2)*(x2*x2/3.-(x1*x2+x1*x1)/6.)+y1*(x1*x1-x2*x2)/2.; + //bary[0]+=(y1-y2)*((x2*x2+x1*x2+x1*x1)/3.-(x2+x1)*x1/2.)+y1*(x1*x1-x2*x2)/2.; + bary[1]=(x1-x2)*(y1*(y1+y2)+y2*y2)/6.; +} + +double EdgeLin::getCurveLength() const +{ + double x=(*_start)[0]-(*_end)[0]; + double y=(*_start)[1]-(*_end)[1]; + return sqrt(x*x+y*y); +} + +Edge *EdgeLin::buildEdgeLyingOnMe(Node *start, Node *end, bool direction) const +{ + return new EdgeLin(start,end,direction); +} + +/*! + * No precision should be introduced here. Just think as if precision was perfect. + */ +void EdgeLin::updateBounds() +{ + _bounds.setValues(std::min((*_start)[0],(*_end)[0]),std::max((*_start)[0],(*_end)[0]),std::min((*_start)[1],(*_end)[1]),std::max((*_start)[1],(*_end)[1])); +} + +double EdgeLin::getCharactValueEng(const double *node) const +{ + double car1_1x=node[0]-(*(_start))[0]; double car1_2x=(*(_end))[0]-(*(_start))[0]; + double car1_1y=node[1]-(*(_start))[1]; double car1_2y=(*(_end))[1]-(*(_start))[1]; + return (car1_1x*car1_2x+car1_1y*car1_2y)/(car1_2x*car1_2x+car1_2y*car1_2y); +} diff --git a/src/INTERP_KERNEL/Geometric2D/EdgeLin.hxx b/src/INTERP_KERNEL/Geometric2D/EdgeLin.hxx new file mode 100644 index 000000000..0c11ae39b --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/EdgeLin.hxx @@ -0,0 +1,78 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __EDGELIN_HXX__ +#define __EDGELIN_HXX__ + +#include "Edge.hxx" + +namespace INTERP_KERNEL +{ + class SegSegIntersector : SameTypeEdgeIntersector + { + friend class Edge; + public: + SegSegIntersector(const EdgeLin& e1, const EdgeLin& e2); + bool areColinears() const; + bool haveTheySameDirection() const; + void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const; + void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped); + std::list< IntersectElement > getIntersectionsCharacteristicVal() const; + private: + void getCurveAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode) const; + private: + //! index on which all single index op will be performed. Filled in case colinearity is equal to true. + int _ind; + double _col[2]; + double _matrix[4];//SPACEDIM*SPACEDIM + }; + + class EdgeLin : public Edge + { + friend class SegSegIntersector; + public: + EdgeLin(std::istream& lineInXfig); + EdgeLin(Node *start, Node *end, bool direction=true); + EdgeLin(double sX, double sY, double eX, double eY); + ~EdgeLin(); + TypeOfFunction getTypeOfFunc() const { return SEG; } + void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const; + void update(Node *m); + double getNormSq() const; + double getAreaOfZone() const; + double getCurveLength() const; + void getBarycenter(double *bary) const; + void getBarycenterOfZone(double *bary) const; + bool isIn(double characterVal) const; + Node *buildRepresentantOfMySelf() const; + double getCharactValue(const Node& node) const; + double getDistanceToPoint(const double *pt) const; + bool isNodeLyingOn(const double *coordOfNode) const; + bool isLower(double val1, double val2) const { return val1incrRef(); +} + +ElementaryEdge::~ElementaryEdge() +{ + if(_ptr) + _ptr->decrRef(); +} + +bool ElementaryEdge::isNodeIn(Node *n) const +{ + return _ptr->getStartNode()==n || _ptr->getEndNode()==n; +} + +/*! + * \b WARNING contrary to INTERP_KERNEL::Edge::getBarycenterOfZone method called, + * this one is cumulative. + */ +void ElementaryEdge::getBarycenterOfZone(double *bary) const +{ + double tmp[2]; + _ptr->getBarycenterOfZone(tmp); + if(_direction) + { + bary[0]+=tmp[0]; + bary[1]+=tmp[1]; + } + else + { + bary[0]-=tmp[0]; + bary[1]-=tmp[1]; + } +} + +void ElementaryEdge::fillBounds(Bounds& output) const +{ + output.aggregate(_ptr->getBounds()); +} + +void ElementaryEdge::getAllNodes(std::set& output) const +{ + output.insert(_ptr->getStartNode()); + output.insert(_ptr->getEndNode()); +} + +void ElementaryEdge::getBarycenter(double *bary, double& weigh) const +{ + _ptr->getBarycenter(bary); + weigh=_ptr->getCurveLength(); +} + +ElementaryEdge *ElementaryEdge::clone() const +{ + return new ElementaryEdge(*this); +} + +void ElementaryEdge::initLocations() const +{ + _ptr->initLocs(); +} + +/*! + * WARNING use this method if and only if this is so that it is completely in/out/on of @param pol. + */ +TypeOfEdgeLocInPolygon ElementaryEdge::locateFullyMySelf(const ComposedEdge& pol, TypeOfEdgeLocInPolygon precEdgeLoc) const +{ + if(getLoc()!=FULL_UNKNOWN) + return getLoc(); + //obvious cases + if(precEdgeLoc==FULL_IN_1) + { + if(getStartNode()->getLoc()==ON_1) + { + declareOut(); + return getLoc(); + } + else if(getStartNode()->getLoc()==IN_1 || getStartNode()->getLoc()==ON_TANG_1) + { + declareIn(); + return getLoc(); + } + } + if(precEdgeLoc==FULL_OUT_1) + { + if(getStartNode()->getLoc()==ON_1) + { + declareIn(); + return getLoc(); + } + else if(getStartNode()->getLoc()==IN_1 || getStartNode()->getLoc()==ON_TANG_1) + { + declareOut(); + return getLoc(); + } + } + if(getStartNode()->getLoc()==IN_1 || getEndNode()->getLoc()==IN_1) + { + declareIn(); + return getLoc(); + } + if(getStartNode()->getLoc()==OUT_1 || getEndNode()->getLoc()==OUT_1) + { + declareOut(); + return getLoc(); + } + //a seek is requested + return locateFullyMySelfAbsolute(pol); +} + +TypeOfEdgeLocInPolygon ElementaryEdge::locateFullyMySelfAbsolute(const ComposedEdge& pol) const +{ + Node *node=_ptr->buildRepresentantOfMySelf(); + if(pol.isInOrOut(node)) + declareIn(); + else + declareOut(); + node->decrRef(); + return getLoc(); +} + +Node *ElementaryEdge::getEndNode() const +{ + if(_direction) + return _ptr->getEndNode(); + else return _ptr->getStartNode(); +} + +Node *ElementaryEdge::getStartNode() const +{ + if(_direction) + return _ptr->getStartNode(); + else + return _ptr->getEndNode(); +} + +bool ElementaryEdge::changeEndNodeWith(Node *node) const +{ + if(_direction) + return _ptr->changeEndNodeWith(node); + else + return _ptr->changeStartNodeWith(node); +} + +bool ElementaryEdge::changeStartNodeWith(Node *node) const +{ + if(_direction) + return _ptr->changeStartNodeWith(node); + else + return _ptr->changeEndNodeWith(node); +} + +void ElementaryEdge::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const +{ + _ptr->dumpInXfigFile(stream,_direction,resolution,box); +} + +bool ElementaryEdge::intresicEqual(const ElementaryEdge *other) const +{ + return _ptr==other->_ptr; +} + +bool ElementaryEdge::intresicEqualDirSensitive(const ElementaryEdge *other) const +{ + return ( _direction==other->_direction ) && (_ptr==other->_ptr); +} + +bool ElementaryEdge::intresincEqCoarse(const Edge *other) const +{ + return _ptr==other; +} diff --git a/src/INTERP_KERNEL/Geometric2D/ElementaryEdge.hxx b/src/INTERP_KERNEL/Geometric2D/ElementaryEdge.hxx new file mode 100644 index 000000000..19f4e1968 --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/ElementaryEdge.hxx @@ -0,0 +1,73 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __ELEMENTARYEDGE_HXX__ +#define __ELEMENTARYEDGE_HXX__ + +#include "INTERPKERNELGEOMETRIC2DDefines.hxx" +#include "InterpKernelException.hxx" +#include "AbstractEdge.hxx" +#include "Edge.hxx" + +namespace INTERP_KERNEL +{ + class INTERPKERNELGEOMETRIC2D_EXPORT ElementaryEdge + { + public: + ElementaryEdge(Edge *ptr, bool direction):_direction(direction),_ptr(ptr) { } + ElementaryEdge(const ElementaryEdge& other); + ~ElementaryEdge(); + bool isThereStartPoint() const { return _iterator.isValid(); } + IteratorOnComposedEdge& getIterator() { return _iterator; } + bool completed() const { return false; } + void declareOn() const { _ptr->declareOn(); } + void declareIn() const { _ptr->declareIn(); } + void declareOut() const { _ptr->declareOut(); } + TypeOfEdgeLocInPolygon getLoc() const { return _ptr->getLoc(); } + Edge *getPtr() const { return _ptr; } + void reverse() { _direction=(!_direction); } + bool isNodeIn(Node *n) const; + double getAreaOfZone() const { double ret=_ptr->getAreaOfZone(); return _direction?ret:-ret; } + void getBarycenterOfZone(double *bary) const; + void fillBounds(Bounds& output) const; + void applySimilarity(double xBary, double yBary, double dimChar) { _ptr->applySimilarity(xBary,yBary,dimChar); } + void getAllNodes(std::set& output) const; + void getBarycenter(double *bary, double& weigh) const; + ElementaryEdge *clone() const; + void initLocations() const; + int size() const; + TypeOfEdgeLocInPolygon locateFullyMySelfAbsolute(const ComposedEdge& pol) const; + TypeOfEdgeLocInPolygon locateFullyMySelf(const ComposedEdge& pol, TypeOfEdgeLocInPolygon precEdgeLoc) const; + Node *getEndNode() const; + Node *getStartNode() const; + double getCurveLength() const { return _ptr->getCurveLength(); } + bool changeEndNodeWith(Node *node) const; + bool changeStartNodeWith(Node *node) const; + bool intresicEqual(const ElementaryEdge *other) const; + bool intresicEqualDirSensitive(const ElementaryEdge *other) const; + void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const; + bool getDirection() const { return _direction; } + bool intresincEqCoarse(const Edge *other) const; + private: + bool _direction; + Edge *_ptr; + IteratorOnComposedEdge _iterator; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Geometric2D/INTERPKERNELGEOMETRIC2DDefines.hxx b/src/INTERP_KERNEL/Geometric2D/INTERPKERNELGEOMETRIC2DDefines.hxx new file mode 100644 index 000000000..6817031db --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/INTERPKERNELGEOMETRIC2DDefines.hxx @@ -0,0 +1,33 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERPKERNELGEOMETRIC2DDEFINES_HXX__ +#define __INTERPKERNELGEOMETRIC2DDEFINES_HXX__ + +//export symbols +#ifdef WIN32 +# ifdef INTERPKERNELGEOMETRIC2D_EXPORTS +# define INTERPKERNELGEOMETRIC2D_EXPORT __declspec(dllexport) +# else +# define INTERPKERNELGEOMETRIC2D_EXPORT __declspec(dllimport) +# endif +#else +# define INTERPKERNELGEOMETRIC2D_EXPORT +#endif + +#endif diff --git a/src/INTERP_KERNEL/Geometric2D/Makefile.am b/src/INTERP_KERNEL/Geometric2D/Makefile.am new file mode 100644 index 000000000..0c31caed1 --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/Makefile.am @@ -0,0 +1,57 @@ +# Copyright (C) 2007-2008 CEA/DEN, 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. +# +# 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 +# +# File : Makefile.am +# Author : Anthony GEAY (CEA/DEN/DANS/DM2S/SFME/LGLS) +# Module : MED +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +noinst_LTLIBRARIES = libInterpGeometric2DAlg.la + +dist_libInterpGeometric2DAlg_la_SOURCES = \ +AbstractEdge.cxx \ +Bounds.cxx \ +Precision.cxx \ +ComposedEdge.cxx \ +EdgeArcCircle.cxx \ +Edge.cxx \ +EdgeInfLin.cxx \ +EdgeLin.cxx \ +ElementaryEdge.cxx \ +Node.cxx \ +QuadraticPolygon.cxx + +salomeinclude_HEADERS = \ +INTERPKERNELGEOMETRIC2DDefines.hxx \ +AbstractEdge.hxx \ +Bounds.hxx \ +Precision.hxx \ +ComposedEdge.hxx \ +EdgeArcCircle.hxx \ +Edge.hxx \ +EdgeInfLin.hxx \ +EdgeLin.hxx \ +ElementaryEdge.hxx \ +Node.hxx \ +QuadraticPolygon.hxx \ +Edge.txx + +libInterpGeometric2DAlg_la_CPPFLAGS = -I$(srcdir)/../Bases + +libInterpGeometric2DAlg_la_LIBADD = ../Bases/libinterpkernelbases.la diff --git a/src/INTERP_KERNEL/Geometric2D/Node.cxx b/src/INTERP_KERNEL/Geometric2D/Node.cxx new file mode 100644 index 000000000..fb64ded3c --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/Node.cxx @@ -0,0 +1,132 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "Node.hxx" +#include "EdgeArcCircle.hxx" + +using namespace std; +using namespace INTERP_KERNEL; + +Node::Node(double x, double y):_cnt(1),_loc(UNKNOWN) +{ + _coords[0]=x; _coords[1]=y; +} + +Node::Node(const double *coords):_cnt(1),_loc(UNKNOWN) +{ + _coords[0]=coords[0]; + _coords[1]=coords[1]; +} + +Node::Node(std::istream& stream):_cnt(1),_loc(UNKNOWN) +{ + int tmp; + stream >> tmp; + _coords[0]=((double) tmp)/1e4; + stream >> tmp; + _coords[1]=((double) tmp)/1e4; +} + +Node::~Node() +{ +} + +bool Node::decrRef() +{ + bool ret=(--_cnt==0); + if(ret) + delete this; + return ret; +} + +bool Node::isEqual(const Node& other) const +{ + const unsigned SPACEDIM=2; + bool ret=true; + for(unsigned i=0;i& track) const +{ + bool ret=isEqual(other); + if(ret) + track.push_back((Node *)&other); + return ret; +} + +void Node::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const +{ + stream << box.fitXForXFig(_coords[0],resolution) << " " << box.fitYForXFig(_coords[1],resolution) << " "; +} + +double Node::distanceWithSq(const Node& other) const +{ + return (_coords[0]-other._coords[0])*(_coords[0]-other._coords[0])+(_coords[1]-other._coords[1])*(_coords[1]-other._coords[1]); +} + +/*! + * WARNING different from 'computeAngle' method ! The returned value are not in the same interval ! + * Here in -Pi/2; Pi/2. Typically this method returns the same value by exchanging pt1 and pt2. + * Use in process of detection of a point in or not in polygon. + */ +double Node::computeSlope(const double *pt1, const double *pt2) +{ + double x=pt2[0]-pt1[0]; + double y=pt2[1]-pt1[1]; + double norm=sqrt(x*x+y*y); + double ret=EdgeArcCircle::safeAcos(fabs(x)/norm); + if( (x>=0. && y>=0.) || (x<0. && y<0.) ) + return ret; + else + return M_PI-ret; +} + +/*! + * WARNING different from 'computeSlope' method. Here angle in -Pi;Pi is returned. + * This method is anti-symetric. + */ +double Node::computeAngle(const double *pt1, const double *pt2) +{ + double x=pt2[0]-pt1[0]; + double y=pt2[1]-pt1[1]; + double norm=sqrt(x*x+y*y); + return EdgeArcCircle::getAbsoluteAngleOfNormalizedVect(x/norm,y/norm); +} + +/*! + * apply a Similarity transformation on this. + * @param xBary is the opposite of the X translation to do. + * @param yBary is the opposite of the Y translation to do. + * @param dimChar is the reduction factor. + */ +void Node::applySimilarity(double xBary, double yBary, double dimChar) +{ + _coords[0]=(_coords[0]-xBary)/dimChar; + _coords[1]=(_coords[1]-yBary)/dimChar; +} diff --git a/src/INTERP_KERNEL/Geometric2D/Node.hxx b/src/INTERP_KERNEL/Geometric2D/Node.hxx new file mode 100644 index 000000000..46957dac0 --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/Node.hxx @@ -0,0 +1,94 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __NODE_HXX__ +#define __NODE_HXX__ + +#include "Precision.hxx" +#include "INTERPKERNELGEOMETRIC2DDefines.hxx" + +#include +#include +#include + +namespace INTERP_KERNEL +{ + typedef enum + { + IN_1 = 7, + ON_1 = 8, + ON_LIM_1 = 12, + ON_TANG_1 = 9, + OUT_1 = 10, + UNKNOWN = 11 + } TypeOfLocInPolygon; + + class Bounds; + + /*! + * As nodes can be shared between edges it is dealed with ref counting. + */ + class INTERPKERNELGEOMETRIC2D_EXPORT Node + { + public: + Node(double x, double y); + Node(const double *coords); + Node(std::istream& stream); + void incrRef() const { _cnt++; } + bool decrRef(); + void initLocs() const { _loc=UNKNOWN; } + void setLoc(TypeOfLocInPolygon loc) const { _loc=loc; } + TypeOfLocInPolygon getLoc() const { return _loc; } + void declareIn() const { if(_loc==UNKNOWN) _loc=IN_1; } + void declareOn() const { if(_loc==UNKNOWN) _loc=ON_1; } + void declareOnLim() const { if(_loc==UNKNOWN || _loc==ON_1) _loc=ON_LIM_1; } + void declareOut() { if(_loc==UNKNOWN) _loc=OUT_1; } + void declareOnTangent() { _loc=ON_TANG_1; } + operator const double*() const { return _coords; } + bool isEqual(const Node& other) const; + //returns an angle in -Pi/2;Pi/2. + double getSlope(const Node& other) const; + bool isEqualAndKeepTrack(const Node& other, std::vector& track) const; + void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const; + double distanceWithSq(const Node& other) const; + double operator[](int i) const { return _coords[i]; } + //! use with caution + void setNewCoords(double x, double y) { _coords[0]=x; _coords[1]=y; } + //returns an angle in -Pi/2;Pi/2. + static double computeSlope(const double *pt1, const double *pt2); + //returns an angle in -Pi;Pi + static double computeAngle(const double *pt1, const double *pt2); + void applySimilarity(double xBary, double yBary, double dimChar); + static double dot(const double *vect1, const double *vect2) { return vect1[0]*vect2[0]+vect1[1]*vect2[1]; } + static double sign(double val) { if(val>=0) return 1.; else return -1.; } + static double norm(const double *vect) { return sqrt(vect[0]*vect[0]+vect[1]*vect[1]); } + static bool areDoubleEquals(double a, double b) { return fabs(a-b) < QUADRATIC_PLANAR::_precision; } + //! idem areDoubleEquals except that precision of comparison is modified. + static bool areDoubleEqualsWP(double a, double b, double k) { return fabs(a-b) < k*QUADRATIC_PLANAR::_precision; } + static double distanceBtw2Pt(const double *a, const double *b) { return sqrt((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])); } + static double distanceBtw2PtSq(const double *a, const double *b) { return (a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1]); } + protected: + ~Node(); + protected: + mutable unsigned char _cnt; + mutable TypeOfLocInPolygon _loc; + double _coords[2]; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Geometric2D/Precision.cxx b/src/INTERP_KERNEL/Geometric2D/Precision.cxx new file mode 100644 index 000000000..1e4f3510c --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/Precision.cxx @@ -0,0 +1,33 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "Precision.hxx" + +double INTERP_KERNEL::QUADRATIC_PLANAR::_precision=1e-14; + +double INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=1e-14; + +void INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(double precision) +{ + INTERP_KERNEL::QUADRATIC_PLANAR::_precision=precision; +} + +void INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(double precision) +{ + INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=precision; +} diff --git a/src/INTERP_KERNEL/Geometric2D/Precision.hxx b/src/INTERP_KERNEL/Geometric2D/Precision.hxx new file mode 100644 index 000000000..31fa8f60a --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/Precision.hxx @@ -0,0 +1,36 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __PRECISION_HXX__ +#define __PRECISION_HXX__ + +#include "INTERPKERNELGEOMETRIC2DDefines.hxx" + +namespace INTERP_KERNEL +{ + class INTERPKERNELGEOMETRIC2D_EXPORT QUADRATIC_PLANAR + { + public: + static double _precision; + static double _arc_detection_precision; + static void setPrecision(double precision); + static void setArcDetectionPrecision(double precision); + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Geometric2D/QuadraticPolygon.cxx b/src/INTERP_KERNEL/Geometric2D/QuadraticPolygon.cxx new file mode 100644 index 000000000..d8faa8a4c --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/QuadraticPolygon.cxx @@ -0,0 +1,553 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "QuadraticPolygon.hxx" +#include "ElementaryEdge.hxx" +#include "EdgeArcCircle.hxx" +#include "AbstractEdge.hxx" +#include "EdgeLin.hxx" +#include "Bounds.hxx" +#include "Edge.txx" + +#include +#include + +using namespace std; +using namespace INTERP_KERNEL; + +namespace INTERP_KERNEL +{ + const unsigned MAX_SIZE_OF_LINE_XFIG_FILE=1024; +} + +QuadraticPolygon::QuadraticPolygon(const char *file) +{ + char currentLine[MAX_SIZE_OF_LINE_XFIG_FILE]; + ifstream stream(file); + stream.exceptions(ios_base::eofbit); + try + { + do + stream.getline(currentLine,MAX_SIZE_OF_LINE_XFIG_FILE); + while(strcmp(currentLine,"1200 2")!=0); + do + { + Edge *newEdge=Edge::buildFromXfigLine(stream); + if(!empty()) + newEdge->changeStartNodeWith(back()->getEndNode()); + pushBack(newEdge); + } + while(1); + } + catch(ifstream::failure& e) + { + } + front()->changeStartNodeWith(back()->getEndNode()); +} + +QuadraticPolygon::~QuadraticPolygon() +{ +} + +QuadraticPolygon *QuadraticPolygon::buildLinearPolygon(std::vector& nodes) +{ + QuadraticPolygon *ret=new QuadraticPolygon; + int size=nodes.size(); + for(int i=0;ipushBack(new EdgeLin(nodes[i],nodes[(i+1)%size])); + nodes[i]->decrRef(); + } + return ret; +} + +QuadraticPolygon *QuadraticPolygon::buildArcCirclePolygon(std::vector& nodes) +{ + QuadraticPolygon *ret=new QuadraticPolygon; + int size=nodes.size(); + for(int i=0;ipushBack(new EdgeLin(nodes[i],nodes[(i+1)%(size/2)])); + else + ret->pushBack(new EdgeArcCircle(nodes[i],nodes[i+size/2],nodes[(i+1)%(size/2)])); + nodes[i]->decrRef(); nodes[i+size/2]->decrRef(); + } + return ret; +} + +void QuadraticPolygon::buildDbgFile(const std::vector& nodes, const char *fileName) +{ + ofstream file(fileName); + file << setprecision(16); + file << " double coords[]=" << endl << " { "; + for(vector::const_iterator iter=nodes.begin();iter!=nodes.end();iter++) + { + if(iter!=nodes.begin()) + file << "," << endl << " "; + file << (*(*iter))[0] << ", " << (*(*iter))[1]; + } + file << "};" << endl; +} + +void QuadraticPolygon::closeMe() const +{ + if(!front()->changeStartNodeWith(back()->getEndNode())) + throw(Exception("big error: not closed polygon...")); +} + +void QuadraticPolygon::circularPermute() +{ + if(_sub_edges.size()>1) + { + ElementaryEdge *first=_sub_edges.front(); + _sub_edges.pop_front(); + _sub_edges.push_back(first); + } +} + +void QuadraticPolygon::dumpInXfigFileWithOther(const ComposedEdge& other, const char *fileName) const +{ + ofstream file(fileName); + const int resolution=1200; + Bounds box; + box.prepareForAggregation(); + fillBounds(box); + other.fillBounds(box); + dumpInXfigFile(file,resolution,box); + other.ComposedEdge::dumpInXfigFile(file,resolution,box); +} + +void QuadraticPolygon::dumpInXfigFile(const char *fileName) const +{ + ofstream file(fileName); + const int resolution=1200; + Bounds box; + box.prepareForAggregation(); + fillBounds(box); + dumpInXfigFile(file,resolution,box); +} + +void QuadraticPolygon::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const +{ + stream << "#FIG 3.2 Produced by xfig version 3.2.5-alpha5" << endl; + stream << "Landscape" << endl; + stream << "Center" << endl; + stream << "Metric" << endl; + stream << "Letter" << endl; + stream << "100.00" << endl; + stream << "Single" << endl; + stream << "-2" << endl; + stream << resolution << " 2" << endl; + ComposedEdge::dumpInXfigFile(stream,resolution,box); +} + +/*! + * Warning contrary to intersectWith method this method is \b NOT const. 'this' and 'other' are modified after call of this method. + */ +double QuadraticPolygon::intersectWithAbs(QuadraticPolygon& other) +{ + double ret=0.; + double fact=normalize(&other); + vector polygs=intersectMySelfWith(other); + for(vector::iterator iter=polygs.begin();iter!=polygs.end();iter++) + { + ret+=fabs((*iter)->getArea()); + delete *iter; + } + return ret*fact*fact; +} + +/*! + * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. + * This is possible because loc attribute in Edge class is mutable. + * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. + */ +double QuadraticPolygon::intersectWith(const QuadraticPolygon& other) const +{ + double ret=0.; + vector polygs=intersectMySelfWith(other); + for(vector::iterator iter=polygs.begin();iter!=polygs.end();iter++) + { + ret+=fabs((*iter)->getArea()); + delete *iter; + } + return ret; +} + +/*! + * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. + * This is possible because loc attribute in Edge class is mutable. + * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. + */ +void QuadraticPolygon::intersectForPerimeter(const QuadraticPolygon& other, double& perimeterThisPart, double& perimeterOtherPart, double& perimeterCommonPart) const +{ + perimeterThisPart=0.; perimeterOtherPart=0.; perimeterCommonPart=0.; + QuadraticPolygon cpyOfThis(*this); + QuadraticPolygon cpyOfOther(other); int nbOfSplits=0; + splitPolygonsEachOther(cpyOfThis,cpyOfOther,nbOfSplits); + performLocatingOperation(cpyOfOther); + other.performLocatingOperation(cpyOfThis); + cpyOfThis.dispatchPerimeterExcl(perimeterThisPart,perimeterCommonPart); + cpyOfOther.dispatchPerimeterExcl(perimeterOtherPart,perimeterCommonPart); + perimeterCommonPart/=2.; +} + +/*! + * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. + * This is possible because loc attribute in Edge class is mutable. + * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. + * + * polThis.size()==this->size() and polOther.size()==other.size(). + * For each ElementaryEdge of 'this', the corresponding contribution in resulting polygon is in 'polThis'. + * For each ElementaryEdge of 'other', the corresponding contribution in resulting polygon is in 'polOther'. + * As consequence common part are counted twice (in polThis \b and in polOther). + */ +void QuadraticPolygon::intersectForPerimeterAdvanced(const QuadraticPolygon& other, std::vector< double >& polThis, std::vector< double >& polOther) const +{ + polThis.resize(size()); + polOther.resize(other.size()); + IteratorOnComposedEdge it1((QuadraticPolygon *)this); + int edgeId=0; + for(it1.first();!it1.finished();it1.next(),edgeId++) + { + ElementaryEdge* curE1=it1.current(); + QuadraticPolygon cpyOfOther(other); + QuadraticPolygon tmp; + tmp.pushBack(curE1->clone()); + int tmp2; + splitPolygonsEachOther(tmp,cpyOfOther,tmp2); + other.performLocatingOperation(tmp); + tmp.dispatchPerimeter(polThis[edgeId]); + } + // + IteratorOnComposedEdge it2((QuadraticPolygon *)&other); + edgeId=0; + for(it2.first();!it2.finished();it2.next(),edgeId++) + { + ElementaryEdge* curE2=it2.current(); + QuadraticPolygon cpyOfThis(*this); + QuadraticPolygon tmp; + tmp.pushBack(curE2->clone()); + int tmp2; + splitPolygonsEachOther(tmp,cpyOfThis,tmp2); + performLocatingOperation(tmp); + tmp.dispatchPerimeter(polOther[edgeId]); + } +} + + +/*! + * numberOfCreatedPointsPerEdge is resized to the number of edges of 'this'. + * This method returns in ordered maner the number of newly created points per edge. + * This method performs a split process between 'this' and 'other' that gives the result PThis. + * Then for each edges of 'this' this method counts how many edges in Pthis have the same id. + */ +void QuadraticPolygon::intersectForPoint(const QuadraticPolygon& other, std::vector< int >& numberOfCreatedPointsPerEdge) const +{ + numberOfCreatedPointsPerEdge.resize(size()); + IteratorOnComposedEdge it1((QuadraticPolygon *)this); + int edgeId=0; + for(it1.first();!it1.finished();it1.next(),edgeId++) + { + ElementaryEdge* curE1=it1.current(); + QuadraticPolygon cpyOfOther(other); + QuadraticPolygon tmp; + tmp.pushBack(curE1->clone()); + int tmp2; + splitPolygonsEachOther(tmp,cpyOfOther,tmp2); + numberOfCreatedPointsPerEdge[edgeId]=tmp.recursiveSize()-1; + } +} + +/*! + * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. + * This is possible because loc attribute in Edge class is mutable. + * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. + */ +std::vector QuadraticPolygon::intersectMySelfWith(const QuadraticPolygon& other) const +{ + QuadraticPolygon cpyOfThis(*this); + QuadraticPolygon cpyOfOther(other); int nbOfSplits=0; + splitPolygonsEachOther(cpyOfThis,cpyOfOther,nbOfSplits); + //At this point cpyOfThis and cpyOfOther have been splited at maximum edge so that in/out can been done. + performLocatingOperation(cpyOfOther); + return other.buildIntersectionPolygons(cpyOfThis,cpyOfOther); +} + +/*! + * This method is typically the first step of boolean operations between pol1 and pol2. + * This method perform the minimal splitting so that at the end each edges constituting pol1 are fully either IN or OUT or ON. + * @param pol1 IN/OUT param that is equal to 'this' when called. + */ +void QuadraticPolygon::splitPolygonsEachOther(QuadraticPolygon& pol1, QuadraticPolygon& pol2, int& nbOfSplits) +{ + IteratorOnComposedEdge it1(&pol1),it2(&pol2); + MergePoints merge; + ComposedEdge *c1=new ComposedEdge; + ComposedEdge *c2=new ComposedEdge; + for(it2.first();!it2.finished();it2.next()) + { + ElementaryEdge* curE2=it2.current(); + if(!curE2->isThereStartPoint()) + it1.first(); + else + it1=curE2->getIterator(); + for(;!it1.finished();) + { + + ElementaryEdge* curE1=it1.current(); + merge.clear(); nbOfSplits++; + if(curE1->getPtr()->intersectWith(curE2->getPtr(),merge,*c1,*c2)) + { + if(!curE1->getDirection()) c1->reverse(); + if(!curE2->getDirection()) c2->reverse(); + updateNeighbours(merge,it1,it2,c1,c2); + //Substitution of simple edge by sub-edges. + delete curE1; // <-- destroying simple edge coming from pol1 + delete curE2; // <-- destroying simple edge coming from pol2 + it1.insertElemEdges(c1,true);// <-- 2nd param is true to go next. + it2.insertElemEdges(c2,false);// <-- 2nd param is false to avoid to go next. + curE2=it2.current(); + // + it1.assignMySelfToAllElems(c2);//To avoid that others + SoftDelete(c1); + SoftDelete(c2); + c1=new ComposedEdge; + c2=new ComposedEdge; + } + else + { + updateNeighbours(merge,it1,it2,curE1,curE2); + it1.next(); + } + } + } + Delete(c1); + Delete(c2); +} + +void QuadraticPolygon::performLocatingOperation(QuadraticPolygon& pol2) const +{ + IteratorOnComposedEdge it(&pol2); + TypeOfEdgeLocInPolygon loc=FULL_ON_1; + for(it.first();!it.finished();it.next()) + { + ElementaryEdge *cur=it.current(); + loc=cur->locateFullyMySelf(*this,loc); + } +} + +/*! + * Given 2 polygons 'pol1' and 'pol2' (localized) the resulting polygons are returned. + * + * this : pol2 simplified. + * @param pol1 pol1 split. + * @param pol2 pol2 split. + */ +std::vector QuadraticPolygon::buildIntersectionPolygons(const QuadraticPolygon& pol1, const QuadraticPolygon& pol2) const +{ + vector ret; + list pol2Zip=pol2.zipConsecutiveInSegments(); + if(!pol2Zip.empty()) + closePolygons(pol2Zip,pol1,ret); + else + {//borders of pol2 do not cross pol1,and pol2 borders are outside of pol1. That is to say, either pol2 and pol1 + //do not overlap or pol1 is fully inside pol2. So in the first case no intersection, in the other case + //the intersection is pol1. + ElementaryEdge *e1FromPol1=pol1[0]; + TypeOfEdgeLocInPolygon loc=FULL_ON_1; + loc=e1FromPol1->locateFullyMySelf(*this,loc); + if(loc==FULL_IN_1) + ret.push_back(new QuadraticPolygon(pol1)); + } + return ret; +} + +/*! + * Returns parts of potentially non closed-polygons. Each returned polygons are not mergeable. + * this : pol2 split and locallized. + */ +std::list QuadraticPolygon::zipConsecutiveInSegments() const +{ + list ret; + IteratorOnComposedEdge it((ComposedEdge *)this); + int nbOfTurns=recursiveSize(); + int i=0; + if(!it.goToNextInOn(false,i,nbOfTurns)) + return ret; + i=0; + // + while(igetLoc(); + while(loc!=FULL_OUT_1 && iclone(); + tmp1->pushBack(tmp3); + it.nextLoop(); i++; + loc=it.current()->getLoc(); + } + if(tmp1->empty()) + { + delete tmp1; + continue; + } + ret.push_back(tmp1); + it.goToNextInOn(true,i,nbOfTurns); + } + return ret; +} + +/*! + * 'this' should be considered as pol2Simplified. + * @param pol2zip is a list of set of edges (openned polygon) coming from split polygon 2. + * @param pol1 is split pol1. + * @param results the resulting \b CLOSED polygons. + */ +void QuadraticPolygon::closePolygons(std::list& pol2Zip, const QuadraticPolygon& pol1, + std::vector& results) const +{ + bool directionKnownInPol1=false; + bool directionInPol1; + for(list::iterator iter=pol2Zip.begin();iter!=pol2Zip.end();) + { + if((*iter)->completed()) + { + results.push_back(*iter); + directionKnownInPol1=false; + iter=pol2Zip.erase(iter); + continue; + } + if(!directionKnownInPol1) + if(!(*iter)->amIAChanceToBeCompletedBy(pol1,*this,directionInPol1)) + { delete *iter; iter=pol2Zip.erase(iter); continue; } + else + directionKnownInPol1=true; + list::iterator iter2=iter; iter2++; + list::iterator iter3=(*iter)->fillAsMuchAsPossibleWith(pol1,iter2,pol2Zip.end(),directionInPol1); + if(iter3!=pol2Zip.end()) + { + (*iter)->pushBack(*iter3); + SoftDelete(*iter3); + pol2Zip.erase(iter3); + } + } +} + +/*! + * 'this' is expected to be set of edges (not closed) of pol2 split. + */ +bool QuadraticPolygon::amIAChanceToBeCompletedBy(const QuadraticPolygon& pol1Splitted,const QuadraticPolygon& pol2NotSplitted, bool& direction) +{ + IteratorOnComposedEdge it((QuadraticPolygon *)&pol1Splitted); + bool found=false; + Node *n=getEndNode(); + ElementaryEdge *cur=it.current(); + for(it.first();!it.finished() && !found;) + { + cur=it.current(); + found=(cur->getStartNode()==n); + if(!found) + it.next(); + } + if(!found) + throw Exception("Internal error : polygons uncompatible each others. Should never happend"); + //Ok we found correspondance between this and pol1. Searching for right direction to close polygon. + ElementaryEdge *e=_sub_edges.back(); + if(e->getLoc()==FULL_ON_1) + { + if(e->getPtr()==cur->getPtr()) + { + direction=false; + it.previousLoop(); + cur=it.current(); + Node *repr=cur->getPtr()->buildRepresentantOfMySelf(); + bool ret=pol2NotSplitted.isInOrOut(repr); + repr->decrRef(); + return ret; + } + else + { + direction=true; + Node *repr=cur->getPtr()->buildRepresentantOfMySelf(); + bool ret=pol2NotSplitted.isInOrOut(repr); + repr->decrRef(); + return ret; + } + } + else + direction=cur->locateFullyMySelfAbsolute(pol2NotSplitted)==FULL_IN_1; + return true; +} + +/*! + * This method fills as much as possible 'this' (part of pol2 split) with edges of 'pol1Splitted'. + */ +std::list::iterator QuadraticPolygon::fillAsMuchAsPossibleWith(const QuadraticPolygon& pol1Splitted, + std::list::iterator iStart, + std::list::iterator iEnd, + bool direction) +{ + IteratorOnComposedEdge it((QuadraticPolygon *)&pol1Splitted); + bool found=false; + Node *n=getEndNode(); + ElementaryEdge *cur; + for(it.first();!it.finished() && !found;) + { + cur=it.current(); + found=(cur->getStartNode()==n); + if(!found) + it.next(); + } + if(!direction) + it.previousLoop(); + Node *nodeToTest; + std::list::iterator ret; + do + { + cur=it.current(); + ElementaryEdge *tmp=cur->clone(); + if(!direction) + tmp->reverse(); + pushBack(tmp); + nodeToTest=tmp->getEndNode(); + direction?it.nextLoop():it.previousLoop(); + ret=checkInList(nodeToTest,iStart,iEnd); + if(completed()) + return iEnd; + } + while(ret==iEnd); + return ret; +} + +std::list::iterator QuadraticPolygon::checkInList(Node *n, std::list::iterator iStart, + std::list::iterator iEnd) +{ + for(list::iterator iter=iStart;iter!=iEnd;iter++) + if((*iter)->isNodeIn(n)) + return iter; + return iEnd; +} diff --git a/src/INTERP_KERNEL/Geometric2D/QuadraticPolygon.hxx b/src/INTERP_KERNEL/Geometric2D/QuadraticPolygon.hxx new file mode 100644 index 000000000..78977ecf5 --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2D/QuadraticPolygon.hxx @@ -0,0 +1,92 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __QUADRATICPOLYGON_HXX__ +#define __QUADRATICPOLYGON_HXX__ + +#include "INTERPKERNELGEOMETRIC2DDefines.hxx" + +#include "ComposedEdge.hxx" +#include "AbstractEdge.hxx" +#include "ElementaryEdge.hxx" + +#include +#include + +namespace INTERP_KERNEL +{ + class Edge; + class MergePoints; + + class INTERPKERNELGEOMETRIC2D_EXPORT QuadraticPolygon : public ComposedEdge + { + public: + QuadraticPolygon() { } + QuadraticPolygon(const QuadraticPolygon& other):ComposedEdge(other) { } + QuadraticPolygon(const char *fileName); + static QuadraticPolygon *buildLinearPolygon(std::vector& nodes); + static QuadraticPolygon *buildArcCirclePolygon(std::vector& nodes); + static void buildDbgFile(const std::vector& nodes, const char *fileName); + ~QuadraticPolygon(); + void closeMe() const; + void circularPermute(); + void dumpInXfigFile(const char *fileName) const; + void dumpInXfigFileWithOther(const ComposedEdge& other, const char *fileName) const; + //! Before intersecting as intersectWith a normalization is done. + double intersectWithAbs(QuadraticPolygon& other); + double intersectWith(const QuadraticPolygon& other) const; + std::vector intersectMySelfWith(const QuadraticPolygon& other) const; + void intersectForPerimeter(const QuadraticPolygon& other, double& perimeterThisPart, double& perimeterOtherPart, double& perimeterCommonPart) const; + void intersectForPerimeterAdvanced(const QuadraticPolygon& other, std::vector< double >& polThis, std::vector< double >& polOther) const; + void intersectForPoint(const QuadraticPolygon& other, std::vector< int >& numberOfCreatedPointsPerEdge) const; + public://Only public for tests reasons + void performLocatingOperation(QuadraticPolygon& pol2) const; + static void splitPolygonsEachOther(QuadraticPolygon& pol1, QuadraticPolygon& pol2, int& nbOfSplits); + std::vector buildIntersectionPolygons(const QuadraticPolygon& pol1, const QuadraticPolygon& pol2) const; + bool amIAChanceToBeCompletedBy(const QuadraticPolygon& pol1Splitted, const QuadraticPolygon& pol2NotSplitted, bool& direction); + protected: + std::list zipConsecutiveInSegments() const; + void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const; + void closePolygons(std::list& pol2Zip, const QuadraticPolygon& pol1, std::vector& results) const; + template + static void updateNeighbours(const MergePoints& merger, IteratorOnComposedEdge it1, IteratorOnComposedEdge it2, + const EDGES *e1, const EDGES *e2); + std::list::iterator fillAsMuchAsPossibleWith(const QuadraticPolygon& pol1Splitted, + std::list::iterator iStart, + std::list::iterator iEnd, + bool direction); + static std::list::iterator checkInList(Node *n, std::list::iterator iStart, + std::list::iterator iEnd); + }; +} + +namespace INTERP_KERNEL +{ + template + void QuadraticPolygon::updateNeighbours(const MergePoints& merger, IteratorOnComposedEdge it1, IteratorOnComposedEdge it2, + const EDGES *e1, const EDGES *e2) + { + it1.previousLoop(); it2.previousLoop(); + ElementaryEdge *curE1=it1.current(); ElementaryEdge *curE2=it2.current(); + curE1->changeEndNodeWith(e1->getStartNode()); curE2->changeEndNodeWith(e2->getStartNode()); + it1.nextLoop(); it1.nextLoop(); it2.nextLoop(); it2.nextLoop(); + curE1->changeStartNodeWith(e1->getEndNode()); curE2->changeStartNodeWith(e2->getEndNode()); + } +} + +#endif diff --git a/src/INTERP_KERNEL/Geometric2DIntersector.hxx b/src/INTERP_KERNEL/Geometric2DIntersector.hxx new file mode 100644 index 000000000..3bcda434c --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2DIntersector.hxx @@ -0,0 +1,50 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __GEOMETRIC2DINTERSECTOR_HXX__ +#define __GEOMETRIC2DINTERSECTOR_HXX__ + +#include "PlanarIntersectorP0P0.hxx" +#include "PlanarIntersectorP0P1.hxx" +#include "PlanarIntersectorP1P0.hxx" + +namespace INTERP_KERNEL +{ + class QuadraticPolygon; + + template class InterpType> + class Geometric2DIntersector : public InterpType > + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + Geometric2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double medianPlane, double precision, int orientation); + double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); + double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad); + private: + QuadraticPolygon *buildPolygonFrom(const std::vector& coords, NormalizedCellType type); + QuadraticPolygon *buildPolygonAFrom(ConnType cell, int nbOfPoints, NormalizedCellType type); + QuadraticPolygon *buildPolygonBFrom(ConnType cell, int nbOfPoints, NormalizedCellType type); + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Geometric2DIntersector.txx b/src/INTERP_KERNEL/Geometric2DIntersector.txx new file mode 100644 index 000000000..d997fa7be --- /dev/null +++ b/src/INTERP_KERNEL/Geometric2DIntersector.txx @@ -0,0 +1,122 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __GEOMETRIC2DINTERSECTOR_TXX__ +#define __GEOMETRIC2DINTERSECTOR_TXX__ + +#include "Geometric2DIntersector.hxx" +#include "PlanarIntersectorP0P0.txx" +#include "PlanarIntersectorP0P1.txx" +#include "PlanarIntersectorP1P0.txx" +#include "CellModel.hxx" + +#include "QuadraticPolygon.hxx" +#include "EdgeArcCircle.hxx" +#include "EdgeLin.hxx" +#include "Node.hxx" + +namespace INTERP_KERNEL +{ + template class InterpType> + Geometric2DIntersector::Geometric2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double medianPlane, double precision, int orientation): + InterpType >(meshT,meshS,dimCaracteristic, precision, medianPlane, true, orientation, 0) + { + QUADRATIC_PLANAR::_precision=dimCaracteristic*precision; + } + + template class InterpType> + double Geometric2DIntersector::intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS) + { + int orientation = 1; + std::vector CoordsT; + std::vector CoordsS; + PlanarIntersector::getRealCoordinates(icellT,icellS,nbNodesT,nbNodesS,CoordsT,CoordsS,orientation); + NormalizedCellType tT=PlanarIntersector::_meshT.getTypeOfElement(icellT); + NormalizedCellType tS=PlanarIntersector::_meshS.getTypeOfElement(icellS); + QuadraticPolygon *p1=buildPolygonFrom(CoordsT,tT); + QuadraticPolygon *p2=buildPolygonFrom(CoordsS,tS); + double ret=p1->intersectWith(*p2); + delete p1; delete p2; + return ret; + } + + template class InterpType> + double Geometric2DIntersector::intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad) + { + std::vector nodes(4); + nodes[0]=new Node(quadrangle[0],quadrangle[1]); + nodes[1]=new Node(quadrangle[SPACEDIM],quadrangle[SPACEDIM+1]); + nodes[2]=new Node(quadrangle[2*SPACEDIM],quadrangle[2*SPACEDIM+1]); + nodes[3]=new Node(quadrangle[3*SPACEDIM],quadrangle[3*SPACEDIM+1]); + int nbOfSourceNodes=sourceCoords.size()/SPACEDIM; + std::vector nodes2(nbOfSourceNodes); + for(int i=0;iintersectWith(*p2); + delete p1; delete p2; + return ret; + } + + template class InterpType> + QuadraticPolygon *Geometric2DIntersector::buildPolygonFrom(const std::vector& coords, NormalizedCellType type) + { + int nbNodes=coords.size()/SPACEDIM; + std::vector nodes(nbNodes); + for(int i=0;i class InterpType> + QuadraticPolygon *Geometric2DIntersector::buildPolygonAFrom(ConnType cell, int nbOfPoints, NormalizedCellType type) + { + const ConnType *startOfCellNodeConn=PlanarIntersector::_connectT+OTT::conn2C(PlanarIntersector::_connIndexT[OTT::ind2C(cell)]); + std::vector nodes(nbOfPoints); + for(int i=0;i::_coordsT+OTT::coo2C(startOfCellNodeConn[i])*SPACEDIM); + if(CellModel::getCellModel(type).isQuadratic()) + return QuadraticPolygon::buildLinearPolygon(nodes); + else + return QuadraticPolygon::buildArcCirclePolygon(nodes); + } + + template class InterpType> + QuadraticPolygon *Geometric2DIntersector::buildPolygonBFrom(ConnType cell, int nbOfPoints, NormalizedCellType type) + { + const ConnType *startOfCellNodeConn=PlanarIntersector::_connectS+OTT::conn2C(PlanarIntersector::_connIndexS[OTT::ind2C(cell)]); + std::vector nodes(nbOfPoints); + for(int i=0;i::_coordsS+OTT::coo2C(startOfCellNodeConn[i])*SPACEDIM); + if(type!=NORM_TRI6 && type!=NORM_QUAD8) + return QuadraticPolygon::buildLinearPolygon(nodes); + else + return QuadraticPolygon::buildArcCirclePolygon(nodes); + } +} + +#endif diff --git a/src/INTERP_KERNEL/INTERPKERNELDefines.hxx b/src/INTERP_KERNEL/INTERPKERNELDefines.hxx new file mode 100644 index 000000000..d89f5da03 --- /dev/null +++ b/src/INTERP_KERNEL/INTERPKERNELDefines.hxx @@ -0,0 +1,33 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERPKERNELDEFINES_HXX__ +#define __INTERPKERNELDEFINES_HXX__ + +//export symbols +#ifdef WIN32 +# ifdef INTERPKERNEL_EXPORTS +# define INTERPKERNEL_EXPORT __declspec(dllexport) +# else +# define INTERPKERNEL_EXPORT __declspec(dllimport) +# endif +#else +# define INTERPKERNEL_EXPORT +#endif + +#endif diff --git a/src/INTERP_KERNEL/InterpKernelMatrix.hxx b/src/INTERP_KERNEL/InterpKernelMatrix.hxx new file mode 100755 index 000000000..caa98a12e --- /dev/null +++ b/src/INTERP_KERNEL/InterpKernelMatrix.hxx @@ -0,0 +1,316 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERPKERNELMATRIX_HXX_ +#define __INTERPKERNELMATRIX_HXX__ + +#include "InterpolationUtils.hxx" + +#include +#include +#include +#include +#include + +namespace INTERP_KERNEL +{ + template + class Matrix; + + template + std::ostream& operator<<(std::ostream& in, const Matrix& m); + template + std::istream& operator>>(std::istream& in, Matrix& m); + + template + class Matrix + { + + class KeyComparator + { + public: + KeyComparator(int val):_val(val) { } + bool operator()(const typename std::pair& val) { return val.first==_val; } + protected: + int _val; + }; + + class Row : public std::vector< typename std::pair > + { + public: + Row():std::vector< typename std::pair >(){}; + Row (const Row& row) + { + this->resize(row.size()); + for (int i=0; isize(); i++) + (*this)[i]=row[i]; + } + Row& operator= (const Row& row) + { + this->resize(row.size()); + for (int i=0; isize(); i++) + (*this)[i]=row[i]; + return *this; + } + typename std::vector< std::pair >::const_iterator find(int elem) const + { + return std::find_if(std::vector< typename std::pair >::begin(),std::vector< typename std::pair >::end(),KeyComparator(elem)); + } + + void erase(int elem) { std::vector< typename std::pair >::erase(std::find_if(std::vector< typename std::pair >::begin(),std::vector< typename std::pair >::end(),KeyComparator(elem))); } + + void insert(const std::pair& myPair) { push_back(myPair); } + }; + + private: + unsigned int _nb_rows; + T* _coeffs; + unsigned int* _cols; + std::vector _ncols_offset; + std::vector< Row > _auxiliary_matrix; + friend std::ostream& operator<<<>(std::ostream& in, const Matrix& m); + friend std::istream& operator>><>(std::istream& in, Matrix& m); + bool _is_configured; + public: + typedef Row value_type; + public: + Matrix():_coeffs(0), _cols(0), _nb_rows(0), _is_configured(false) + { } + Matrix(int nbrows):_coeffs(0), _cols(0), _is_configured(false) + { _nb_rows=nbrows; } + Matrix(std::vector > & matrix) : + _coeffs(0), _cols(0), _is_configured(false) + { + _nb_rows=matrix.size(); + for (int i=0; i<_nb_rows; i++) + { + _auxiliary_matrix[i].resize(matrix[i].size()); + typename std::map::iterator it; + for (it=matrix[i].begin(); it != matrix[i].end(); it++) + _auxiliary_matrix[i].push_back(*it); + } + + } + /*!Copy constructor + */ + Matrix(const Matrix & m) + { + _is_configured=m._is_configured; + _nb_rows=m._nb_rows; + _auxiliary_matrix=m._auxiliary_matrix; + _ncols_offset=m._ncols_offset; + if (_is_configured) + { + int size=_ncols_offset[_nb_rows]; + _coeffs = new double[size]; + _cols = new uint[size]; + memcpy(_coeffs, m._coeffs, size*sizeof(double)); + memcpy(_cols, m._cols, size*sizeof(int)); + } + } + + ~Matrix() + { + delete[] _coeffs; + delete[] _cols; + } + + Matrix& operator=(const Matrix& m) + { + _is_configured=m._is_configured; + _nb_rows=m._nb_rows; + _auxiliary_matrix=m._auxiliary_matrix; + _ncols_offset=m._ncols_offset; + if (_is_configured) + { + int size=_ncols_offset[_nb_rows]; + _coeffs = new double[size]; + _cols = new uint[size]; + memcpy(_coeffs, m._coeffs, size*sizeof(double)); + memcpy(_cols, m._cols, size*sizeof(int)); + } + return this; + } + + /*! declares a method that specifies the number of rows */ + void resize(unsigned int nbrows) + { + _nb_rows=nbrows; + _auxiliary_matrix.resize(nbrows); + } + + /*! sets (i,j) coefficient to \a value */ + void setIJ(int irow, int icol, T value) + { + if (_is_configured) + throw Exception("filling a configured matrix"); + if (_auxiliary_matrix.empty()) + _auxiliary_matrix.resize(_nb_rows); + + for (uint i=0; i< _auxiliary_matrix[OTT::ind2C(irow)].size(); i++) + if (_auxiliary_matrix[OTT::ind2C(irow)][i].first == icol) + { + _auxiliary_matrix[OTT::ind2C(irow)][i].second = value; + return; + } + _auxiliary_matrix[OTT::ind2C(irow)].push_back(std::make_pair(icol, value)); + } + + /*! + + Matrix multiplies vector \a input and stores the result in + vector \a output. + The vector pointed by \a input must be dimensioned + to the number of columns while the vector pointed by output must be + dimensioned to the number of rows. + */ + void multiply(const T* const input, T* const output) + { + if (!_is_configured) + configure(); + + for (int i=0; i< _nb_rows; i++) + { + output[i]=0; + for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) { + int icol = _cols[j]; + output[i]+=input[icol]*_coeffs[j]; + } + } + } + + /*! This operation freezes the profile of the matrix + and puts it under a CSR form so that it becomes + efficient both in terms of memory occupation and + in terms of multiplication */ + + void configure() + { + _ncols_offset.resize(_nb_rows+1); + _ncols_offset[0]=0; + for (unsigned int i=0; i<_nb_rows; i++) + _ncols_offset[i+1]=_ncols_offset[i]+_auxiliary_matrix[i].size(); + int nbcoeffs= _ncols_offset[_nb_rows]; + _cols=new unsigned int[nbcoeffs]; + _coeffs=new T[nbcoeffs]; + unsigned int* cols_ptr=_cols; + T* coeffs_ptr=_coeffs; + for (unsigned int i=0; i<_nb_rows; i++) + { + for (unsigned int j=0; j<_auxiliary_matrix[i].size(); j++) + { + *cols_ptr++ = OTT::ind2C(_auxiliary_matrix[i][j].first); + *coeffs_ptr++ = _auxiliary_matrix[i][j].second; + } + } + _auxiliary_matrix.clear(); + _is_configured=true; + } + + /*! + * 0 <= irow < n + */ + Row &operator [] (unsigned int irow) + { + return _auxiliary_matrix[irow]; + } + + }; + + /*! output to an ascii file + only nonzero elements are written + - the first line contains the indexing (0 or 1) + - the second line contains the number of rows. + - for each row, a line contains: + - the number of nonzero coeffs + - and for each coeff : icol, value + + for instance, matrix + | 1.0 0.0 0.5 | + | 0.0 1.0 0.0 | + | 0.2 0.0 1.0 | + will be displayed in 0-indexing as + 0 + 3 + 2 0 1.0 2 0.5 + 1 1 1.0 + 2 0 0.2 2 1.0 + */ + + template + std::ostream& operator<<(std::ostream& out, const Matrix& m) + { + if (m._is_configured) + { + out << OTT::indFC(0) <::indFC(m._cols[j]) <<"\t"<::indFC(0) <<"\n"; + out << m._nb_rows <<"\n"; + for (uint i=0; i + std::istream& operator>>(std::istream& in, Matrix& m) + { + int index_base_test; + in >> index_base_test; + if (index_base_test!=OTT::indFC(0)) + { + std::cerr << "file index is "<> m._nb_rows; + m._auxiliary_matrix.resize(m._nb_rows); + for (uint i=0; i> ncols; + m._auxiliary_matrix[i].resize(ncols); + double value; + uint col; + for (uint j=0; j>col; + in>>value; + m._auxiliary_matrix[i].push_back(std::make_pair(col, value)); + } + } + return in; + } +} + +#endif diff --git a/src/INTERP_KERNEL/InterpKernelUtilities.hxx b/src/INTERP_KERNEL/InterpKernelUtilities.hxx new file mode 100644 index 000000000..6cd5dd991 --- /dev/null +++ b/src/INTERP_KERNEL/InterpKernelUtilities.hxx @@ -0,0 +1,37 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERPKERNELUTILITIES_HXX__ +#define __INTERPKERNELUTILITIES_HXX__ + +//! DON'T INCLUDE THIS FILE IN .h NOR IN .hxx FILES !!!!!!!!! +#ifdef _DEBUG_ +# define MESSAGE(chain) {HERE ; cerr << chain << endl ;} +#else +# define MESSAGE(chain) +#endif + +#ifdef _DEBUG_ +# define HERE {cout< (message) , __FILE__ , __LINE__ + +#endif diff --git a/src/INTERP_KERNEL/Interpolation.hxx b/src/INTERP_KERNEL/Interpolation.hxx new file mode 100644 index 000000000..57edda88e --- /dev/null +++ b/src/INTERP_KERNEL/Interpolation.hxx @@ -0,0 +1,48 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERPOLATION_HXX__ +#define __INTERPOLATION_HXX__ + +/** + * \mainpage + * Status : documentation of 3D - part of intersection matrix calculation more or less complete + * + * + */ +#include "INTERPKERNELDefines.hxx" +#include "InterpolationOptions.hxx" + +namespace INTERP_KERNEL +{ + template + class Interpolation : public InterpolationOptions + { + public: + Interpolation() { } + Interpolation(const InterpolationOptions& io) :InterpolationOptions(io){} + //interpolation of two triangular meshes. + template + int interpolateMeshes(const MyMeshType& mesh1, const MyMeshType& mesh2, MatrixType& result) + { return asLeaf().interpolateMeshes(mesh1,mesh2,result); } + protected: + TrueMainInterpolator& asLeaf() { return static_cast(*this); } + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Interpolation2D.hxx b/src/INTERP_KERNEL/Interpolation2D.hxx new file mode 100755 index 000000000..ba65a6e71 --- /dev/null +++ b/src/INTERP_KERNEL/Interpolation2D.hxx @@ -0,0 +1,39 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERPOLATION2D_HXX__ +#define __INTERPOLATION2D_HXX__ + +#include "InterpolationPlanar.hxx" + +namespace INTERP_KERNEL +{ + class Interpolation2D : public InterpolationPlanar + { + public: + Interpolation2D() { } + Interpolation2D(const InterpolationOptions& io):InterpolationPlanar(io) { } + public: + bool doRotate() const { return false; } + double medianPlane() const { return 0.; } + template + void performAdjustmentOfBB(PlanarIntersector* intersector, std::vector& bbox) const { } + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Interpolation2D.txx b/src/INTERP_KERNEL/Interpolation2D.txx new file mode 100644 index 000000000..3cdc0e118 --- /dev/null +++ b/src/INTERP_KERNEL/Interpolation2D.txx @@ -0,0 +1,26 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERPOLATION2D_TXX__ +#define __INTERPOLATION2D_TXX__ + +#include "Interpolation2D.hxx" + +#include "InterpolationPlanar.txx" + +#endif diff --git a/src/INTERP_KERNEL/Interpolation3D.hxx b/src/INTERP_KERNEL/Interpolation3D.hxx new file mode 100644 index 000000000..0d07dbd55 --- /dev/null +++ b/src/INTERP_KERNEL/Interpolation3D.hxx @@ -0,0 +1,40 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERPOLATION3D_HXX__ +#define __INTERPOLATION3D_HXX__ + +#include "Interpolation.hxx" +#include "NormalizedUnstructuredMesh.hxx" +#include "InterpolationOptions.hxx" + +namespace INTERP_KERNEL +{ + class Interpolation3D : public Interpolation + { + public: + Interpolation3D(); + Interpolation3D(const InterpolationOptions& io); + template + int interpolateMeshes(const MyMeshType& srcMesh, const MyMeshType& targetMesh, MatrixType& result, const char *method); + private: + SplittingPolicy _splitting_policy; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Interpolation3D.txx b/src/INTERP_KERNEL/Interpolation3D.txx new file mode 100644 index 000000000..3597aa137 --- /dev/null +++ b/src/INTERP_KERNEL/Interpolation3D.txx @@ -0,0 +1,318 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERPOLATION3D_TXX__ +#define __INTERPOLATION3D_TXX__ + +#include "Interpolation3D.hxx" +#include "MeshElement.txx" +#include "TransformedTriangle.hxx" +#include "PolyhedronIntersector.txx" +#include "PolyhedronIntersectorP0P1.txx" +#include "PolyhedronIntersectorP1P0.txx" +#include "Log.hxx" +/// If defined, use recursion to traverse the binary search tree, else use the BBTree class +#define USE_RECURSIVE_BBOX_FILTER + +#ifdef USE_RECURSIVE_BBOX_FILTER +#include "MeshRegion.txx" +#include "RegionNode.hxx" +#include + +#else // use BBTree class + +#include "BBTree.txx" + +#endif + +namespace INTERP_KERNEL +{ + /** + * \defgroup interpolation3D Interpolation3D + * \class Interpolation3D + * \brief Class used to calculate the volumes of intersection between the elements of two 3D meshes. + * + */ + /** + * Default constructor + * + */ + Interpolation3D::Interpolation3D() + { + } + Interpolation3D::Interpolation3D(const InterpolationOptions& io):Interpolation(io) + { + } + + /** + * Calculates the matrix of volumes of intersection between the elements of srcMesh and the elements of targetMesh. + * The calculation is done in two steps. First a filtering process reduces the number of pairs of elements for which the + * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the + * volume of intersection is calculated by an object of type Intersector3D for the remaining pairs, and entered into the + * intersection matrix. + * + * The matrix is partially sparse : it is a vector of maps of integer - double pairs. + * It can also be an INTERP_KERNEL::Matrix object. + * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless + * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements + * which have a non-zero intersection volume with the target element. The vector has indices running from + * 0 to (nb target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, + * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. + * + + * @param srcMesh 3-dimensional source mesh + * @param targetMesh 3-dimesional target mesh, containing only tetraedra + * @param result matrix in which the result is stored + * + */ + template + int Interpolation3D::interpolateMeshes(const MyMeshType& srcMesh, const MyMeshType& targetMesh, MatrixType& result, const char *method) + { + typedef typename MyMeshType::MyConnType ConnType; + // create MeshElement objects corresponding to each element of the two meshes + const unsigned long numSrcElems = srcMesh.getNumberOfElements(); + const unsigned long numTargetElems = targetMesh.getNumberOfElements(); + + LOG(2, "Source mesh has " << numSrcElems << " elements and target mesh has " << numTargetElems << " elements "); + + std::vector*> srcElems(numSrcElems); + std::vector*> targetElems(numTargetElems); + + std::map*, int> indices; + + for(unsigned long i = 0 ; i < numSrcElems ; ++i) + srcElems[i] = new MeshElement(i, srcMesh); + + for(unsigned long i = 0 ; i < numTargetElems ; ++i) + targetElems[i] = new MeshElement(i, targetMesh); + + Intersector3D* intersector=0; + std::string methC(method); + if(method=="P0P0") + intersector=new PolyhedronIntersector(targetMesh, srcMesh, getSplittingPolicy()); + else if(method=="P0P1") + intersector=new PolyhedronIntersectorP0P1(targetMesh, srcMesh, getSplittingPolicy()); + else if(method=="P1P0") + intersector=new PolyhedronIntersectorP1P0(targetMesh, srcMesh, getSplittingPolicy()); + else + throw Exception("Invalid method choosed must be in \"P0P0\", \"P0P1\"."); + // create empty maps for all source elements + result.resize(intersector->getNumberOfRowsOfResMatrix()); + +#ifdef USE_RECURSIVE_BBOX_FILTER + + /* + * Performs a depth-first search over srcMesh, using bounding boxes to recursively eliminate the elements of targetMesh + * which cannot intersect smaller and smaller regions of srcMesh. At each level, each region is divided in two, forming + * a binary search tree with leaves consisting of only one element of the source mesh together with the elements of the + * target mesh that can intersect it. The recursion is implemented with a stack of RegionNodes, each one containing a + * source region and a target region. Each region has an associated bounding box and a vector of pointers to the elements + * that belong to it. Each MeshElement contains a bounding box and the global number of the corresponding element in the mesh. + */ + + // create initial RegionNode and fill up its source region with all the source mesh elements and + // its target region with all the target mesh elements whose bounding box + // intersects that of the source region + + RegionNode* firstNode = new RegionNode(); + + MeshRegion& srcRegion = firstNode->getSrcRegion(); + + for(unsigned long i = 0 ; i < numSrcElems ; ++i) + { + srcRegion.addElement(srcElems[i], srcMesh); + } + + MeshRegion& targetRegion = firstNode->getTargetRegion(); + + for(unsigned long i = 0 ; i < numTargetElems ; ++i) + { + if(!srcRegion.isDisjointWithElementBoundingBox( *(targetElems[i]) )) + { + targetRegion.addElement(targetElems[i], targetMesh); + } + } + + // Using a stack, descend recursively, creating at each step two new RegionNodes having as source region the left and + // right part of the source region of the current node (created using MeshRegion::split()) and as target region all the + // elements of the target mesh whose bounding box intersects the corresponding part + // Continue until the source region contains only one element, at which point the intersection volumes are + // calculated with all the remaining target mesh elements and stored in the matrix if they are non-zero. + + std::stack< RegionNode* > nodes; + nodes.push(firstNode); + + while(!nodes.empty()) + { + RegionNode* currNode = nodes.top(); + nodes.pop(); + LOG(4, "Popping node "); + + if(currNode->getTargetRegion().getNumberOfElements() == 1) + { + // calculate volumes + LOG(4, " - One element"); + + MeshElement* targetElement = *(currNode->getTargetRegion().getBeginElements()); + std::vector intersectElems; + for(typename std::vector< MeshElement* >::const_iterator iter = currNode->getSrcRegion().getBeginElements();iter != currNode->getSrcRegion().getEndElements();++iter) + intersectElems.push_back((*iter)->getIndex()); + intersector->intersectCells(targetElement->getIndex(),intersectElems,result); + } + else // recursion + { + + LOG(4, " - Recursion"); + + RegionNode* leftNode = new RegionNode(); + RegionNode* rightNode = new RegionNode(); + + // split current source region + //} decide on axis + static BoundingBox::BoxCoord axis = BoundingBox::XMAX; + + currNode->getTargetRegion().split(leftNode->getTargetRegion(), rightNode->getTargetRegion(), axis, targetMesh); + + LOG(5, "After split, left target region has " << leftNode->getTargetRegion().getNumberOfElements() + << " elements and right target region has " << rightNode->getTargetRegion().getNumberOfElements() + << " elements"); + + // ugly hack to avoid problem with enum which does not start at 0 + // I guess I ought to implement ++ for it instead ... + // Anyway, it basically chooses the next axis, cyclically + axis = (axis != BoundingBox::ZMAX) ? static_cast(axis + 1) : BoundingBox::XMAX; + + // add source elements of current node that overlap the target regions of the new nodes + LOG(5, " -- Adding source elements"); + int numLeftElements = 0; + int numRightElements = 0; + for(typename std::vector*>::const_iterator iter = currNode->getSrcRegion().getBeginElements() ; + iter != currNode->getSrcRegion().getEndElements() ; ++iter) + { + LOG(6, " --- New target node"); + + if(!leftNode->getTargetRegion().isDisjointWithElementBoundingBox(**iter)) + { + leftNode->getSrcRegion().addElement(*iter, srcMesh); + ++numLeftElements; + } + + if(!rightNode->getTargetRegion().isDisjointWithElementBoundingBox(**iter)) + { + rightNode->getSrcRegion().addElement(*iter, srcMesh); + ++numRightElements; + } + + } + + LOG(5, "Left src region has " << numLeftElements << " elements and right src region has " + << numRightElements << " elements"); + + // push new nodes on stack + if(numLeftElements != 0) + { + nodes.push(leftNode); + } + else + { + delete leftNode; + } + + if(numRightElements != 0) + { + nodes.push(rightNode); + } + else + { + delete rightNode; + } + } + + // all nodes are deleted here + delete currNode; + + LOG(4, "Next iteration. Nodes left : " << nodes.size()); + } + +#else // Use BBTree + + // create BBTree structure + // - get bounding boxes + double bboxes[6 * numSrcElems]; + int srcElemIdx[numSrcElems]; + for(unsigned long i = 0; i < numSrcElems ; ++i) + { + // get source bboxes in right order + const BoundingBox* box = srcElems[i]->getBoundingBox(); + bboxes[6*i+0] = box->getCoordinate(BoundingBox::XMIN); + bboxes[6*i+1] = box->getCoordinate(BoundingBox::XMAX); + bboxes[6*i+2] = box->getCoordinate(BoundingBox::YMIN); + bboxes[6*i+3] = box->getCoordinate(BoundingBox::YMAX); + bboxes[6*i+4] = box->getCoordinate(BoundingBox::ZMIN); + bboxes[6*i+5] = box->getCoordinate(BoundingBox::ZMAX); + + // source indices have to begin with zero for BBox, I think + srcElemIdx[i] = srcElems[i]->getIndex(); + } + + BBTree<3,ConnType> tree(bboxes, srcElemIdx, 0, numSrcElems); + + // for each target element, get source elements with which to calculate intersection + // - calculate intersection by calling intersectCells + for(unsigned long i = 0; i < numTargetElems; ++i) + { + const BoundingBox* box = targetElems[i]->getBoundingBox(); + const int targetIdx = targetElems[i]->getIndex(); + + // get target bbox in right order + double targetBox[6]; + targetBox[0] = box->getCoordinate(BoundingBox::XMIN); + targetBox[1] = box->getCoordinate(BoundingBox::XMAX); + targetBox[2] = box->getCoordinate(BoundingBox::YMIN); + targetBox[3] = box->getCoordinate(BoundingBox::YMAX); + targetBox[4] = box->getCoordinate(BoundingBox::ZMIN); + targetBox[5] = box->getCoordinate(BoundingBox::ZMAX); + + std::vector intersectElems; + + tree.getIntersectingElems(targetBox, intersectElems); + + intersector->intersectCells(targetIdx,intersectElems,result); + } + +#endif + // free allocated memory + int ret=intersector->getNumberOfColsOfResMatrix(); + + delete intersector; + + for(unsigned long i = 0 ; i < numSrcElems ; ++i) + { + delete srcElems[i]; + } + for(unsigned long i = 0 ; i < numTargetElems ; ++i) + { + delete targetElems[i]; + } + return ret; + + } + +} + +#endif diff --git a/src/INTERP_KERNEL/Interpolation3DSurf.hxx b/src/INTERP_KERNEL/Interpolation3DSurf.hxx new file mode 100644 index 000000000..3055b158c --- /dev/null +++ b/src/INTERP_KERNEL/Interpolation3DSurf.hxx @@ -0,0 +1,50 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERPOLATION3DSURF_HXX__ +#define __INTERPOLATION3DSURF_HXX__ + +#include "InterpolationPlanar.hxx" +#include "InterpolationOptions.hxx" + +namespace INTERP_KERNEL +{ + class Interpolation3DSurf : public InterpolationPlanar + { + public: + Interpolation3DSurf(); + Interpolation3DSurf(const InterpolationOptions& io); + void setOptions(double precision, int printLevel, double medianPlane, + IntersectionType intersectionType, bool doRotate, int orientation=0); + + public: + bool doRotate() const { return _do_rotate; } + double medianPlane() const { return _median_plane; } + template + void performAdjustmentOfBB(PlanarIntersector* intersector, std::vector& bbox) const + { intersector->adjustBoundingBoxes(bbox,_surf_3D_adjustment_eps); } + protected: + bool _do_rotate; + double _median_plane; + double _surf_3D_adjustment_eps; + static const double DFT_MEDIAN_PLANE; + static const double DFT_SURF3D_ADJ_EPS; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Interpolation3DSurf.txx b/src/INTERP_KERNEL/Interpolation3DSurf.txx new file mode 100644 index 000000000..cf6eb1d2f --- /dev/null +++ b/src/INTERP_KERNEL/Interpolation3DSurf.txx @@ -0,0 +1,69 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERPOLATION3DSURF_TXX__ +#define __INTERPOLATION3DSURF_TXX__ + +#include "Interpolation3DSurf.hxx" +#include "InterpolationPlanar.txx" + +namespace INTERP_KERNEL +{ + const double Interpolation3DSurf::DFT_MEDIAN_PLANE=0.5; + const double Interpolation3DSurf::DFT_SURF3D_ADJ_EPS=1e-4; + + Interpolation3DSurf::Interpolation3DSurf():_do_rotate(true) + ,_median_plane(DFT_MEDIAN_PLANE) + ,_surf_3D_adjustment_eps(DFT_SURF3D_ADJ_EPS) + { + } + + Interpolation3DSurf::Interpolation3DSurf(const InterpolationOptions& io):InterpolationPlanar(io) + { + } + + + /** + \brief Function used to set the options for the intersection calculation + \details The following options can be modified: + -# Intersection_type: the type of algorithm to be used in the computation of the cell-cell intersections. + - Values: Triangle, Convex. + - Default: Triangle. + -# MedianPlane: Position of the median plane where both cells will be projected + - Values: between 0 and 1. + - Default: 0.5. + -# DoRotate: rotate the coordinate system such that the target cell is in the Oxy plane. + - Values: true (necessarilly if Intersection_type=Triangle), false. + - Default: true (as default Intersection_type=Triangle) + -# Precision: Level of precision of the computations is precision times the characteristic size of the mesh. + - Values: positive real number. + - Default: 1.0E-12. + -# PrintLevel: Level of verboseness during the computations. + - Values: interger between 0 and 3. + - Default: 0. + */ + void Interpolation3DSurf::setOptions(double precision, int printLevel, double medianPlane, + IntersectionType intersectionType, bool doRotate, int orientation) + { + InterpolationPlanar::setOptions(precision,printLevel,intersectionType, orientation); + _do_rotate=doRotate; + _median_plane=medianPlane; + } +} + +#endif diff --git a/src/INTERP_KERNEL/InterpolationOptions.hxx b/src/INTERP_KERNEL/InterpolationOptions.hxx new file mode 100644 index 000000000..d471101e7 --- /dev/null +++ b/src/INTERP_KERNEL/InterpolationOptions.hxx @@ -0,0 +1,82 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERPOLATIONOPTIONS_HXX__ +#define __INTERPOLATIONOPTIONS_HXX__ + + +namespace INTERP_KERNEL { + typedef enum { Triangulation, Convex, Geometric2D } IntersectionType; + /// Type describing the different ways in which the hexahedron can be split into tetrahedra. + /// The PLANAR_* policies persume that each face is to be considered planar, while the general + /// policies make no such hypothesis. The integer at the end gives the number of tetrahedra + /// that result from the split. + typedef enum { PLANAR_FACE_5 = 5, PLANAR_FACE_6 = 6, GENERAL_24 = 24, GENERAL_48 = 48 } SplittingPolicy; + + + class InterpolationOptions{ + private : + int _print_level ; + IntersectionType _intersection_type; + double _precision; + double _median_plane ; + bool _do_rotate ; + double _bounding_box_adjustment ; + int _orientation ; + SplittingPolicy _splitting_policy ; + + public: + InterpolationOptions() { init(); } + int getPrintLevel() const { return _print_level; } + void setPrintLevel(int pl) { _print_level=pl; } + + IntersectionType getIntersectionType() const { return InterpolationOptions::_intersection_type; } + void setIntersectionType(IntersectionType it) { InterpolationOptions::_intersection_type=it; } + + double getPrecision() const { return InterpolationOptions::_precision; } + void setPrecision(double p) { InterpolationOptions::_precision=p; } + + double getMedianPlane() { return InterpolationOptions::_median_plane; } + void setMedianPlane(double mp) { InterpolationOptions::_median_plane=mp; } + + bool getDoRotate() { return InterpolationOptions::_do_rotate; } + void setDoRotate( bool dr) { InterpolationOptions::_do_rotate = dr; } + + double getBoundingBoxAdjustment() { return InterpolationOptions::_bounding_box_adjustment; } + void setBoundingBoxAdjustment(double bba) { InterpolationOptions::_bounding_box_adjustment=bba; } + + int getOrientation() { return InterpolationOptions::_orientation; } + void setOrientation(int o) { InterpolationOptions::_orientation=o; } + + SplittingPolicy getSplittingPolicy() { return _splitting_policy; } + void setSplittingPolicy(SplittingPolicy sp) { _splitting_policy=sp; } + void init() + { + _print_level=0; + _intersection_type=Triangulation; + _precision=1e-12;; + _median_plane=0.5; + _do_rotate=true; + _bounding_box_adjustment=0.1; + _orientation=0; + _splitting_policy=GENERAL_48; + } + }; + +} +#endif diff --git a/src/INTERP_KERNEL/InterpolationPlanar.hxx b/src/INTERP_KERNEL/InterpolationPlanar.hxx new file mode 100755 index 000000000..f4321c95e --- /dev/null +++ b/src/INTERP_KERNEL/InterpolationPlanar.hxx @@ -0,0 +1,61 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERPOLATIONPLANAR_HXX__ +#define __INTERPOLATIONPLANAR_HXX__ + +#include "Interpolation.hxx" +#include "PlanarIntersector.hxx" +#include "NormalizedUnstructuredMesh.hxx" +#include "InterpolationOptions.hxx" + +namespace INTERP_KERNEL +{ + template + class InterpolationPlanar : public Interpolation< InterpolationPlanar > + { + private: + double _dim_caracteristic; + static const double DEFAULT_PRECISION; + + public: + InterpolationPlanar(); + InterpolationPlanar(const InterpolationOptions & io); + + // geometric precision, debug print level, coice of the median plane, intersection etc ... + void setOptions(double precision, int printLevel, + IntersectionType intersectionType, int orientation=0); + + // Main function to interpolate triangular and quadratic meshes + template + int interpolateMeshes(const MyMeshType& mesh1, const MyMeshType& mesh2, MatrixType& result, const char *method); + + public: + bool doRotate() const { return asLeafInterpPlanar().doRotate(); } + double medianPlane() const { return asLeafInterpPlanar().medianPlane(); } + template + void performAdjustmentOfBB(PlanarIntersector* intersector, std::vector& bbox) const + { return asLeafInterpPlanar().performAdjustmentOfBB(intersector,bbox); } + + protected: + RealPlanar& asLeafInterpPlanar() { return static_cast(*this); } + const RealPlanar& asLeafInterpPlanar() const { return static_cast< const RealPlanar& >(*this); } + }; +} + +#endif diff --git a/src/INTERP_KERNEL/InterpolationPlanar.txx b/src/INTERP_KERNEL/InterpolationPlanar.txx new file mode 100644 index 000000000..decaec360 --- /dev/null +++ b/src/INTERP_KERNEL/InterpolationPlanar.txx @@ -0,0 +1,276 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERPOLATIONPLANAR_TXX__ +#define __INTERPOLATIONPLANAR_TXX__ + +#include "InterpolationPlanar.hxx" +#include "InterpolationOptions.hxx" +#include "PlanarIntersector.hxx" +#include "PlanarIntersector.txx" +#include "TriangulationIntersector.hxx" +#include "TriangulationIntersector.txx" +#include "ConvexIntersector.hxx" +#include "ConvexIntersector.txx" +#include "Geometric2DIntersector.hxx" +#include "Geometric2DIntersector.txx" +#include "VectorUtils.hxx" +#include "BBTree.txx" + +#include + +namespace INTERP_KERNEL +{ + + template + const double InterpolationPlanar::DEFAULT_PRECISION=1.e-12; + + /** + * \defgroup interpolationPlanar InterpolationPlanar + * + * \class InterpolationPlanar + * \brief Class used to compute the coefficients of the interpolation matrix between + * two local meshes in two dimensions. Meshes can contain mixed triangular and quadrangular elements. + */ + template + InterpolationPlanar::InterpolationPlanar():_dim_caracteristic(1) + + { + } + + template + InterpolationPlanar::InterpolationPlanar(const InterpolationOptions& io):Interpolation< InterpolationPlanar >(io),_dim_caracteristic(1) + + { + } + + + /** + * \brief Function used to set the options for the intersection calculation + * \details The following options can be modified: + * -# Intersection_type: the type of algorithm to be used in the computation of the cell-cell intersections. + * - Values: Triangle, Convex. + * - Default: Triangle. + * -# Precision: Level of precision of the computations is precision times the characteristic size of the mesh. + * - Values: positive real number. + * - Default: 1.0E-12. + * -# PrintLevel: Level of verboseness during the computations. + * - Values: interger between 0 and 3. + * - Default: 0. + */ + template + void InterpolationPlanar::setOptions(double precision, int printLevel, IntersectionType intersectionType, int orientation) + { + InterpolationOptions::setPrecision(precision); + InterpolationOptions::setPrintLevel(printLevel); + InterpolationOptions::setIntersectionType(intersectionType); + InterpolationOptions::setOrientation(orientation); + } + + + /** \brief Main function to interpolate triangular or quadrangular meshes. + \details The algorithm proceeds in two steps: first a filtering process reduces the number of pairs of elements for which the + * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the + * volume of intersection is calculated by an object of type IntersectorPlanar for the remaining pairs, and entered into the + * intersection matrix. + * + * The matrix is partially sparse : it is a vector of maps of integer - double pairs. + * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless + * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements + * which have a non-zero intersection volume with the target element. The vector has indices running from + * 0 to (#target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, + * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. + * + + * @param myMeshS Planar source mesh + * @Param myMeshT Planar target mesh + * @return vector containing for each element i of the source mesh, a map giving for each element j + * of the target mesh which i intersects, the area of the intersection + * + */ + template + template + int InterpolationPlanar::interpolateMeshes(const MyMeshType& myMeshS, const MyMeshType& myMeshT, MatrixType& result, const char *method) + { + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + + long global_start =clock(); + int counter=0; + /***********************************************************/ + /* Check both meshes are made of triangles and quadrangles */ + /***********************************************************/ + + long nbMailleS=myMeshS.getNumberOfElements(); + long nbMailleT=myMeshT.getNumberOfElements(); + + /**************************************************/ + /* Search the characteristic size of the meshes */ + /**************************************************/ + + double BoxS[2*SPACEDIM]; myMeshS.getBoundingBox(BoxS); + double BoxT[2*SPACEDIM]; myMeshT.getBoundingBox(BoxT); + double diagonalS=getDistanceBtw2Pts(BoxS+SPACEDIM,BoxS); + double DimCaracteristicS=diagonalS/nbMailleS; + double diagonalT=getDistanceBtw2Pts(BoxT+SPACEDIM,BoxT); + double DimCaracteristicT=diagonalT/nbMailleT; + + _dim_caracteristic=std::min(DimCaracteristicS, DimCaracteristicT); + if (InterpolationOptions::getPrintLevel()>=1) + { + std::cout << " - Characteristic size of the source mesh : " << DimCaracteristicS << std::endl; + std::cout << " - Characteristic size of the target mesh: " << DimCaracteristicT << std::endl; + std::cout << "InterpolationPlanar::computation of the intersections" << std::endl; + } + + PlanarIntersector* intersector=0; + std::string meth(method); + if(meth=="P0P0") + { + switch (InterpolationOptions::getIntersectionType()) + { + case Triangulation: + intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, + InterpolationOptions::getPrecision(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getOrientation(), + InterpolationOptions::getPrintLevel()); + break; + case Convex: + intersector=new ConvexIntersector(myMeshT,myMeshS,_dim_caracteristic, + InterpolationOptions::getPrecision(), + InterpolationOptions::getDoRotate(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getOrientation(), + InterpolationOptions::getPrintLevel()); + break; + case Geometric2D: + intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrecision(), + InterpolationOptions::getOrientation()); + break; + } + } + else if(meth=="P0P1") + { + switch (InterpolationOptions::getIntersectionType()) + { + case Triangulation: + intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, + InterpolationOptions::getPrecision(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getOrientation(), + InterpolationOptions::getPrintLevel()); + break; + case Convex: + intersector=new ConvexIntersector(myMeshT,myMeshS,_dim_caracteristic, + InterpolationOptions::getPrecision(), + InterpolationOptions::getDoRotate(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getOrientation(), + InterpolationOptions::getPrintLevel()); + break; + case Geometric2D: + intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrecision(), + InterpolationOptions::getOrientation()); + break; + } + } + else if(meth=="P1P0") + { + switch (InterpolationOptions::getIntersectionType()) + { + case Triangulation: + intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, + InterpolationOptions::getPrecision(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getOrientation(), + InterpolationOptions::getPrintLevel()); + break; + case Convex: + intersector=new ConvexIntersector(myMeshT,myMeshS,_dim_caracteristic, + InterpolationOptions::getPrecision(), + InterpolationOptions::getDoRotate(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getOrientation(), + InterpolationOptions::getPrintLevel()); + break; + case Geometric2D: + intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrecision(), + InterpolationOptions::getOrientation()); + break; + } + } + else + throw INTERP_KERNEL::Exception("Invalid method specified ! Must be in : \"P0P0\" \"P0P1\" or \"P1P0\""); + /****************************************************************/ + /* Create a search tree based on the bounding boxes */ + /* Instanciate the intersector and initialise the result vector */ + /****************************************************************/ + + long start_filtering=clock(); + + std::vector bbox; + intersector->createBoundingBoxes(myMeshS,bbox); // create the bounding boxes + performAdjustmentOfBB(intersector,bbox); + BBTree my_tree(&bbox[0], 0, 0,nbMailleS);//creating the search structure + + long end_filtering=clock(); + + result.resize(intersector->getNumberOfRowsOfResMatrix());//on initialise. + + /****************************************************/ + /* Loop on the target cells - core of the algorithm */ + /****************************************************/ + long start_intersection=clock(); + long nbelem_type=myMeshT.getNumberOfElements(); + const ConnType *connIndxT=myMeshT.getConnectivityIndexPtr(); + for(int iT=0; iT intersecting_elems; + double bb[2*SPACEDIM]; + intersector->getElemBB(bb,myMeshT,OTT::indFC(iT),nb_nodesT); + my_tree.getIntersectingElems(bb, intersecting_elems); + intersector->intersectCells(iT,intersecting_elems,result); + counter+=intersecting_elems.size(); + intersecting_elems.clear(); + } + int ret=intersector->getNumberOfColsOfResMatrix(); + delete intersector; + + if (InterpolationOptions::getPrintLevel() >=1) + { + long end_intersection=clock(); + std::cout << "Filtering time= " << end_filtering-start_filtering << std::endl; + std::cout << "Intersection time= " << end_intersection-start_intersection << std::endl; + long global_end =clock(); + std::cout << "Number of computed intersections = " << counter << std::endl; + std::cout << "Global time= " << global_end - global_start << std::endl; + } + return ret; + } +} + +#endif diff --git a/src/INTERP_KERNEL/InterpolationUtils.hxx b/src/INTERP_KERNEL/InterpolationUtils.hxx new file mode 100644 index 000000000..f659d1929 --- /dev/null +++ b/src/INTERP_KERNEL/InterpolationUtils.hxx @@ -0,0 +1,872 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERPOLATIONUTILS_HXX__ +#define __INTERPOLATIONUTILS_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "InterpKernelException.hxx" + +#include "NormalizedUnstructuredMesh.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace INTERP_KERNEL +{ + template + class OTT//OffsetToolTrait + { + }; + + template + class OTT + { + public: + static ConnType indFC(ConnType i) { return i; } + static ConnType ind2C(ConnType i) { return i; } + static ConnType conn2C(ConnType i) { return i; } + static ConnType coo2C(ConnType i) { return i; } + }; + + template + class OTT + { + public: + static ConnType indFC(ConnType i) { return i+1; } + static ConnType ind2C(ConnType i) { return i-1; } + static ConnType conn2C(ConnType i) { return i-1; } + static ConnType coo2C(ConnType i) { return i-1; } + }; + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + /* calcul la surface d'un triangle */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + + inline double Surf_Tri(const double* P_1,const double* P_2,const double* P_3) + { + double A=(P_3[1]-P_1[1])*(P_2[0]-P_1[0])-(P_2[1]-P_1[1])*(P_3[0]-P_1[0]); + double Surface = 0.5*fabs(A); + return Surface; + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + /* fonction qui calcul le déterminant */ + /* de deux vecteur(cf doc CGAL). */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + + //fonction qui calcul le déterminant des vecteurs: P3P1 et P3P2 + //(cf doc CGAL). + + inline double mon_determinant(const double* P_1, + const double* P_2, + const double* P_3) + { + double mon_det=(P_1[0]-P_3[0])*(P_2[1]-P_3[1])-(P_2[0]-P_3[0])*(P_1[1]-P_3[1]); + return mon_det; + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + //calcul la norme du vecteur P1P2 + + inline double norme_vecteur(const double* P_1,const double* P_2) + { + double X=P_1[0]-P_2[0]; + double Y=P_1[1]-P_2[1]; + double norme=sqrt(X*X+Y*Y); + return norme; + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + /* calcul le cos et le sin de l'angle P1P2,P1P3 */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + + inline std::vector calcul_cos_et_sin(const double* P_1, + const double* P_2, + const double* P_3) + { + + std::vector Vect; + double P1_P2=norme_vecteur(P_1,P_2); + double P2_P3=norme_vecteur(P_2,P_3); + double P3_P1=norme_vecteur(P_3,P_1); + + double N=P1_P2*P1_P2+P3_P1*P3_P1-P2_P3*P2_P3; + double D=2.0*P1_P2*P3_P1; + double COS=N/D; + if (COS>1.0) COS=1.0; + if (COS<-1.0) COS=-1.0; + Vect.push_back(COS); + double V=mon_determinant(P_2,P_3,P_1); + double D_1=P1_P2*P3_P1; + double SIN=V/D_1; + if (SIN>1.0) SIN=1.0; + if (SIN<-1.0) SIN=-1.0; + Vect.push_back(SIN); + + return Vect; + + } + + /*! + * This method builds a quadrangle built with the first point of 'triIn' the barycenter of two edges starting or ending with + * the first point of 'triIn' and the barycenter of 'triIn'. + * + * @param triIn is a 6 doubles array in full interlace mode, that represents a triangle. + * @param quadOut is a 8 doubles array filled after the following call. + */ + template + inline void fillDualCellOfTri(const double *triIn, double *quadOut) + { + //1st point + std::copy(triIn,triIn+SPACEDIM,quadOut); + double tmp[SPACEDIM]; + std::transform(triIn,triIn+SPACEDIM,triIn+SPACEDIM,tmp,std::plus()); + //2nd point + std::transform(tmp,tmp+SPACEDIM,quadOut+SPACEDIM,std::bind2nd(std::multiplies(),0.5)); + std::transform(tmp,tmp+SPACEDIM,triIn+2*SPACEDIM,tmp,std::plus()); + //3rd point + std::transform(tmp,tmp+SPACEDIM,quadOut+2*SPACEDIM,std::bind2nd(std::multiplies(),1/3.)); + //4th point + std::transform(triIn,triIn+SPACEDIM,triIn+2*SPACEDIM,tmp,std::plus()); + std::transform(tmp,tmp+SPACEDIM,quadOut+3*SPACEDIM,std::bind2nd(std::multiplies(),0.5)); + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + /* calcul les coordonnées du barycentre d'un polygone */ + /* le vecteur en entrée est constitué des coordonnées */ + /* des sommets du polygone */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + + inline std::vector bary_poly(const std::vector& V) + { + std::vector Bary; + long taille=V.size(); + double x=0; + double y=0; + + for(long i=0;i::min() ) { + bc[0]=1; bc[1]=0; bc[2]=0; + return; + } + // matrix inverse + double t11 = T22, t12 = -T12, t21 = -T21, t22 = T11; + // vector + double r11 = p[0]-triaCoords[4], r12 = p[1]-triaCoords[5]; + // barycentric coordinates: mutiply matrix by vector + bc[0] = (t11 * r11 + t12 * r12)/Tdet; + bc[1] = (t21 * r11 + t22 * r12)/Tdet; + bc[2] = 1. - bc[0] - bc[1]; + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* Calculate barycentric coordinates of a point p */ + /* with respect to triangle or tetra verices. */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + + inline void barycentric_coords(const std::vector& n, const double* p, double* bc) + { + enum { _X, _Y, _Z }; + if ( n.size() == 3 ) // TRIA3 + { + // matrix 2x2 + double + T11 = n[0][_X]-n[2][_X], T12 = n[1][_X]-n[2][_X], + T21 = n[0][_Y]-n[2][_Y], T22 = n[1][_Y]-n[2][_Y]; + // matrix determinant + double Tdet = T11*T22 - T12*T21; + if ( std::fabs( Tdet ) < std::numeric_limits::min() ) { + bc[0]=1; bc[1]=bc[2]=0; // no solution + return; + } + // matrix inverse + double t11 = T22, t12 = -T12, t21 = -T21, t22 = T11; + // vector + double r11 = p[_X]-n[2][_X], r12 = p[_Y]-n[2][_Y]; + // barycentric coordinates: mutiply matrix by vector + bc[0] = (t11 * r11 + t12 * r12)/Tdet; + bc[1] = (t21 * r11 + t22 * r12)/Tdet; + bc[2] = 1. - bc[0] - bc[1]; + } + else // TETRA4 + { + bc[3]=0; // for no solution + + // Find bc by solving system of 3 equations using Gaussian elimination algorithm + // bc1*( x1 - x4 ) + bc2*( x2 - x4 ) + bc3*( x3 - x4 ) = px - x4 + // bc1*( y1 - y4 ) + bc2*( y2 - y4 ) + bc3*( y3 - y4 ) = px - y4 + // bc1*( z1 - z4 ) + bc2*( z2 - z4 ) + bc3*( z3 - z4 ) = px - z4 + const int nbCol=4, nbRow=3; + + double T[nbRow][nbCol]= + {{ n[0][_X]-n[3][_X], n[1][_X]-n[3][_X], n[2][_X]-n[3][_X], p[_X]-n[3][_X] }, + { n[0][_Y]-n[3][_Y], n[1][_Y]-n[3][_Y], n[2][_Y]-n[3][_Y], p[_Y]-n[3][_Y] }, + { n[0][_Z]-n[3][_Z], n[1][_Z]-n[3][_Z], n[2][_Z]-n[3][_Z], p[_Z]-n[3][_Z] }}; + + // make upper triangular matrix (forward elimination) + + int iR[nbRow] = { 0, 1, 2 }; + + for ( int i = 0; i < 2; ++i ) // nullify 2 rows + { + // swap rows to have max value of i-th column in i-th row + double max = std::fabs( T[ iR[i] ][i] ); + for ( int r = i+1; r < nbRow; ++r ) { + double t = std::fabs( T[ iR[r] ][i] ); + if ( t > max ) { + max = t; + std::swap( iR[r], iR[i] ); + } + } + if ( max < std::numeric_limits::min() ) { + bc[0]=1; bc[1]=bc[2]=bc[3]=0; + return; // no solution + } + // make 0 below T[i][i] (actually we do not modify i-th column) + double* tUpRow = T[ iR[i] ]; + for ( int r = i+1; r < nbRow; ++r ) { + double* tRow = T[ iR[r] ]; + double coef = tRow[ i ] / tUpRow[ i ]; + for ( int c = i+1; c < nbCol; ++c ) + tRow[ c ] -= tUpRow[ c ] * coef; + } + } + double* tRow = T[ iR[2] ]; + if ( std::fabs( tRow[ 2 ] ) < std::numeric_limits::min() ) { + bc[0]=1; bc[1]=bc[2]=bc[3]=0; + return; // no solution + } + tRow[ 3 ] /= tRow[ 2 ]; + + // calculate solution (back substitution) + + bc[ 2 ] = tRow[ 3 ]; + + tRow = T[ iR[1] ]; + bc[ 1 ] = (tRow[ 3 ] - bc[2]*tRow[ 2 ]) / tRow[ 1 ]; + + tRow = T[ iR[0] ]; + bc[ 0 ] = (tRow[ 3 ] - bc[2]*tRow[ 2 ] - bc[1]*tRow[ 1 ]) / tRow[ 0 ]; + + bc[ 3 ] = 1. - bc[0] - bc[1] - bc[2]; + } + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + /* calcul la surface d'un polygone. */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + + inline double Surf_Poly(const std::vector& Poly) + { + + double Surface=0; + for(unsigned long i=0; i<(Poly.size())/2-2; i++) + { + double Surf=Surf_Tri( &Poly[0],&Poly[2*(i+1)],&Poly[2*(i+2)] ); + Surface=Surface + Surf ; + } + return Surface ; + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + /* fonction qui teste si un point est dans une maille */ + /* point: P_0 */ + /* P_1, P_2, P_3 sommet des mailles */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + + inline bool point_dans_triangle(const double* P_0,const double* P_1, + const double* P_2,const double* P_3, + double eps) + { + + bool A=false; + double det_1=mon_determinant(P_1,P_3,P_0); + double det_2=mon_determinant(P_3,P_2,P_0); + double det_3=mon_determinant(P_2,P_1,P_0); + if( (det_1>=-eps && det_2>=-eps && det_3>=-eps) || (det_1<=eps && det_2<=eps && det_3<=eps) ) + { + A=true; + } + + return A; + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + /*fonction pour vérifier qu'un point n'a pas déja été considérer dans */ + /* le vecteur et le rajouter au vecteur sinon. */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + + inline void verif_point_dans_vect(const double* P, std::vector& V, double absolute_precision ) + { + long taille=V.size(); + bool isPresent=false; + for(long i=0;i& V, double dim_caracteristic, double precision) + { + + double absolute_precision = precision*dim_caracteristic; + bool A_1=INTERP_KERNEL::point_dans_triangle(P_1,P_4,P_5,P_6,absolute_precision); + if(A_1) + verif_point_dans_vect(P_1,V,absolute_precision); + bool A_2=INTERP_KERNEL::point_dans_triangle(P_2,P_4,P_5,P_6,absolute_precision); + if(A_2) + verif_point_dans_vect(P_2,V,absolute_precision); + bool A_3=INTERP_KERNEL::point_dans_triangle(P_3,P_4,P_5,P_6,absolute_precision); + if(A_3) + verif_point_dans_vect(P_3,V,absolute_precision); + } + + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* calcul de l'intersection de deux segments: segments P1P2 avec P3P4 */ + /* . Si l'intersection est non nulle et si celle-ci n'est */ + /* n'est pas déjà contenue dans Vect on la rajoute à Vect */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + + inline void inters_de_segment(const double * P_1,const double * P_2, + const double * P_3,const double * P_4, + std::vector& Vect, + double dim_caracteristic, double precision) + { + // calcul du déterminant de P_1P_2 et P_3P_4. + double det=(P_2[0]-P_1[0])*(P_4[1]-P_3[1])-(P_4[0]-P_3[0])*(P_2[1]-P_1[1]); + + double absolute_precision = dim_caracteristic*precision; + if(fabs(det)>absolute_precision) + { + double k_1=-((P_3[1]-P_4[1])*(P_3[0]-P_1[0])+(P_4[0]-P_3[0])*(P_3[1]-P_1[1]))/det; + + if (k_1 >= -absolute_precision && k_1 <= 1+absolute_precision) + //if( k_1 >= -precision && k_1 <= 1+precision) + { + double k_2= ((P_1[1]-P_2[1])*(P_1[0]-P_3[0])+(P_2[0]-P_1[0])*(P_1[1]-P_3[1]))/det; + + if (k_2 >= -absolute_precision && k_2 <= 1+absolute_precision) + //if( k_2 >= -precision && k_2 <= 1+precision) + { + double P_0[2]; + P_0[0]=P_1[0]+k_1*(P_2[0]-P_1[0]); + P_0[1]=P_1[1]+k_1*(P_2[1]-P_1[1]); + verif_point_dans_vect(P_0,Vect,absolute_precision); + } + } + } + } + + + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* calcul l'intersection de deux triangles */ + /* P_1, P_2, P_3: sommets du premier triangle */ + /* P_4, P_5, P_6: sommets du deuxième triangle */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + + inline void intersec_de_triangle(const double* P_1,const double* P_2, const double* P_3, + const double* P_4,const double* P_5,const double* P_6, + std::vector& Vect, double dim_caracteristic, double precision) + { + inters_de_segment(P_1,P_2,P_4,P_5,Vect, dim_caracteristic, precision); + inters_de_segment(P_1,P_2,P_5,P_6,Vect, dim_caracteristic, precision); + inters_de_segment(P_1,P_2,P_6,P_4,Vect, dim_caracteristic, precision); + inters_de_segment(P_2,P_3,P_4,P_5,Vect, dim_caracteristic, precision); + inters_de_segment(P_2,P_3,P_5,P_6,Vect, dim_caracteristic, precision); + inters_de_segment(P_2,P_3,P_6,P_4,Vect, dim_caracteristic, precision); + inters_de_segment(P_3,P_1,P_4,P_5,Vect, dim_caracteristic, precision); + inters_de_segment(P_3,P_1,P_5,P_6,Vect, dim_caracteristic, precision); + inters_de_segment(P_3,P_1,P_6,P_4,Vect, dim_caracteristic, precision); + rajou_sommet_triangl(P_1,P_2,P_3,P_4,P_5,P_6,Vect, dim_caracteristic, precision); + rajou_sommet_triangl(P_4,P_5,P_6,P_1,P_2,P_3,Vect, dim_caracteristic, precision); + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* fonction pour vérifier qu'un n°de maille n'a pas déja été considérer */ + /* dans le vecteur et le rajouter au vecteur sinon. */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + + inline void verif_maill_dans_vect(int Num, std::vector& V) + { + long taille=V.size(); + int A=0; + for(long i=0;itheta1, std::pair theta2) + { + double norm1 = sqrt(theta1.first*theta1.first +theta1.second*theta1.second); + double norm2 = sqrt(theta2.first*theta2.first +theta2.second*theta2.second); + + double epsilon = 1.e-12; + + if( norm1 < epsilon || norm2 < epsilon ) + std::cout << "Warning InterpolationUtils.hxx: AngleLess : Vector with zero norm, cannot define the angle !!!! " << std::endl; + + return theta1.second*(norm2 + theta2.first) < theta2.second*(norm1 + theta1.first); + + } + }; + + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + /* fonction pour reconstituer un polygone convexe à partir */ + /* d'un nuage de point. */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + + inline std::vector reconstruct_polygon(const std::vector& V) + { + + int taille=V.size(); + + //VB : why 6 ? + + if(taille<=6) + {return V;} + else + { + double *COS=new double[taille/2]; + double *SIN=new double[taille/2]; + //double *angle=new double[taille/2]; + std::vector Bary=bary_poly(V); + COS[0]=1.0; + SIN[0]=0.0; + //angle[0]=0.0; + for(int i=0; i Trigo=calcul_cos_et_sin(&Bary[0],&V[0],&V[2*(i+1)]); + COS[i+1]=Trigo[0]; + SIN[i+1]=Trigo[1]; + //if(SIN[i+1]>=0) + // {angle[i+1]=atan2(SIN[i+1],COS[i+1]);} + // else + // {angle[i+1]=-atan2(SIN[i+1],COS[i+1]);} + } + + //ensuite on ordonne les angles. + std::vector Pt_ordonne; + Pt_ordonne.reserve(taille); + // std::multimap Ordre; + std::multimap,int, AngleLess> CosSin; + for(int i=0;i::iterator mi; + std::multimap,int, AngleLess>::iterator micossin; + // for(mi=Ordre.begin();mi!=Ordre.end();mi++) + // { + // int j=(*mi).second; + // Pt_ordonne.push_back(V[2*j]); + // Pt_ordonne.push_back(V[2*j+1]); + // } + for(micossin=CosSin.begin();micossin!=CosSin.end();micossin++) + { + int j=(*micossin).second; + Pt_ordonne.push_back(V[2*j]); + Pt_ordonne.push_back(V[2*j+1]); + } + delete [] COS; + delete [] SIN; + // delete [] angle; + return Pt_ordonne; + } + } + + template + inline void getElemBB(double* bb, const double *coordsOfMesh, int iP, int nb_nodes) + { + bb[0]=std::numeric_limits::max(); + bb[1]=-std::numeric_limits::max(); + bb[2]=std::numeric_limits::max(); + bb[3]=-std::numeric_limits::max(); + bb[4]=std::numeric_limits::max(); + bb[5]=-std::numeric_limits::max(); + + for (int i=0; ibb[1])?x:bb[1]; + bb[2]=(ybb[3])?y:bb[3]; + bb[4]=(zbb[5])?z:bb[5]; + } + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* Computes the dot product of a and b */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + template + inline double dotprod( double * a, double * b) + { + double result=0; + for(int idim = 0; idim < dim ; idim++) result += a[idim]*b[idim]; + return result; + } + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* Computes the norm of vector v */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + template + inline double norm( double * v) + { + double result =0; + for(int idim =0; idim + inline double distance2( const double * a, const double * b) + { + double result =0; + for(int idim =0; idim + inline double distance2( T * a, int inda, T * b, int indb) + { + double result =0; + for(int idim =0; idim inline void crossprod( const double * A, const double * B, const double * C, double * V); + + template<> inline + void crossprod<2>( const double * A, const double * B, const double * C, double * V) + { + double AB[2]; + double AC[2]; + for(int idim =0; idim<2; idim++) AB[idim] = B[idim]-A[idim];//B-A + for(int idim =0; idim<2; idim++) AC[idim] = C[idim]-A[idim];//C-A; + + V[0]=determinant(AB,AC); + V[1]=0; + } + template<> inline + void crossprod<3>( const double * A, const double * B, const double * C, double * V) + { + double AB[3]; + double AC[3]; + for(int idim =0; idim<3; idim++) AB[idim] = B[idim]-A[idim];//B-A + for(int idim =0; idim<3; idim++) AC[idim] = C[idim]-A[idim];//C-A; + + V[0]=AB[1]*AC[2]-AB[2]*AC[1]; + V[1]=-AB[0]*AC[2]+AB[2]*AC[0]; + V[2]=AB[0]*AC[1]-AB[1]*AC[0]; + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* Checks wether point A is inside the quadrangle BCDE */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + + template inline double check_inside(const double* A,const double* B,const double* C,const double* D, + const double* E,double* ABC, double* ADE) + { + crossprod(A,B,C,ABC); + crossprod(A,D,E,ADE); + return dotprod(ABC,ADE); + } + + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* Computes the geometric angle (in [0,Pi]) between two non zero vectors AB and AC */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + template inline double angle(const double * A, const double * B, const double * C, double * n) + { + double AB[dim]; + double AC[dim]; + double orthAB[dim]; + + for(int idim =0; idim(AB); + for(int idim =0; idim(AC); + double AB_dot_AC=dotprod(AB,AC); + for(int idim =0; idim(orthAB); + + return 2*atan2(numer,denom); + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* Tells whether the frame constituted of vectors AB, AC and n is direct */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + template inline double direct_frame(const double * A, const double * B, const double * C, double * n); + template<> inline + double direct_frame<2>(const double * A, const double * B, const double * C, double * n) + { + double AB[2]; + double AC[2]; + for(int idim =0; idim<2; idim++) AB[idim] = B[idim]-A[idim];//B-A; + for(int idim =0; idim<2; idim++) AC[idim] = C[idim]-A[idim];//C-A; + + return determinant(AB,AC)*n[0]; + } + template<> inline + double direct_frame<3>(const double * A, const double * B, const double * C, double * n) + { + double AB[3]; + double AC[3]; + for(int idim =0; idim<3; idim++) AB[idim] = B[idim]-A[idim];//B-A; + for(int idim =0; idim<3; idim++) AC[idim] = C[idim]-A[idim];//C-A; + + return determinant(AB,AC,n)>0; + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* calcul l'intersection de deux polygones COPLANAIRES */ + /* en dimension DIM (2 ou 3). Si DIM=3 l'algorithme ne considère*/ + /* que les deux premières coordonnées de chaque point */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + template inline void intersec_de_polygone(const double * Coords_A, const double * Coords_B, + int nb_NodesA, int nb_NodesB, + std::vector& inter, + double dim_caracteristic, double precision) + { + for(int i_A = 1; i_A3) inter=INTERP_KERNEL::reconstruct_polygon(inter); + } + + /*_ _ _ _ _ _ _ _ _ + *_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + * fonctions qui calcule l'aire d'un polygone en dimension 2 ou 3 + *_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + template inline double polygon_area(std::vector& inter) + { + double result=0.; + double area[DIM]; + + for(int i = 1; i<(int)inter.size()/DIM-1; i++) + { + INTERP_KERNEL::crossprod(&inter[0],&inter[DIM*i],&inter[DIM*(i+1)],area); + result +=0.5*norm(area); + } + return result; + } + + template inline double polygon_area(std::deque& inter) + { + double result=0.; + double area[DIM]; + + for(int i = 1; i<(int)inter.size()/DIM-1; i++) + { + INTERP_KERNEL::crossprod(&inter[0],&inter[DIM*i],&inter[DIM*(i+1)],area); + result +=0.5*norm(area); + } + return result; + } + + /*! Computes the triple product (XA^XB).XC (in 3D)*/ + inline double triple_product(const double* A, const double*B, const double*C, const double*X) + { + double XA[3]; + XA[0]=A[0]-X[0]; + XA[1]=A[1]-X[1]; + XA[2]=A[2]-X[2]; + double XB[3]; + XB[0]=B[0]-X[0]; + XB[1]=B[1]-X[1]; + XB[2]=B[2]-X[2]; + double XC[3]; + XC[0]=C[0]-X[0]; + XC[1]=C[1]-X[1]; + XC[2]=C[2]-X[2]; + + return + (XA[1]*XB[2]-XA[2]*XB[1])*XC[0]+ + (XA[2]*XB[0]-XA[0]*XB[2])*XC[1]+ + (XA[0]*XB[1]-XA[1]*XB[0])*XC[2]; + } + + /*! Subroutine of checkEqualPolygins that tests if two list of nodes (not necessarily distincts) describe the same polygon, assuming they share a comon point.*/ + /*! Indexes istart1 and istart2 designate two points P1 in L1 and P2 in L2 that have identical coordinates. Generally called with istart1=0.*/ + /*! Integer sign ( 1 or -1) indicate the direction used in going all over L2. */ + template + bool checkEqualPolygonsOneDirection(T * L1, T * L2, int size1, int size2, int istart1, int istart2, double epsilon, int sign) + { + int i1 = istart1; + int i2 = istart2; + int i1next = ( i1 + 1 ) % size1; + int i2next = ( i2 + sign +size2) % size2; + + while(true) + { + while( i1next!=istart1 && distance2(L1,i1*dim, L1,i1next*dim) < epsilon ) i1next = ( i1next + 1 ) % size1; + while( i2next!=istart2 && distance2(L2,i2*dim, L2,i2next*dim) < epsilon ) i2next = ( i2next + sign +size2 ) % size2; + + if(i1next == istart1) + { + if(i2next == istart2) + return true; + else return false; + } + else + if(i2next == istart2) + return false; + else + { + if(distance2(L1,i1next*dim, L2,i2next*dim) > epsilon ) + return false; + else + { + i1 = i1next; + i2 = i2next; + i1next = ( i1 + 1 ) % size1; + i2next = ( i2 + sign + size2 ) % size2; + } + } + } + } + + /*! Tests if two list of nodes (not necessarily distincts) describe the same polygon.*/ + /*! Existence of multiple points in the list is considered.*/ + template + bool checkEqualPolygons(T * L1, T * L2, double epsilon) + { + if(L1==NULL || L2==NULL) + { + std::cout << "Warning InterpolationUtils.hxx:checkEqualPolygonsPointer: Null pointer " << std::endl; + throw(Exception("big error: not closed polygon...")); + } + + int size1 = (*L1).size()/dim; + int size2 = (*L2).size()/dim; + int istart1 = 0; + int istart2 = 0; + + while( istart2 < size2 && distance2(L1,istart1*dim, L2,istart2*dim) > epsilon ) istart2++; + + if(istart2 == size2) + { + return (size1 == 0) && (size2 == 0); + } + else + return checkEqualPolygonsOneDirection( L1, L2, size1, size2, istart1, istart2, epsilon, 1) + || checkEqualPolygonsOneDirection( L1, L2, size1, size2, istart1, istart2, epsilon, -1); + + } +} + + +#endif diff --git a/src/INTERP_KERNEL/Intersector3D.hxx b/src/INTERP_KERNEL/Intersector3D.hxx new file mode 100644 index 000000000..bf3df0b9f --- /dev/null +++ b/src/INTERP_KERNEL/Intersector3D.hxx @@ -0,0 +1,37 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERSECTOR3D_HXX__ +#define __INTERSECTOR3D_HXX__ + +#include "TargetIntersector.hxx" + +namespace INTERP_KERNEL +{ + template + class Intersector3D : public TargetIntersector + { + public: + Intersector3D(const MyMeshType& targetMesh, const MyMeshType& srcMesh); + protected: + const MyMeshType _target_mesh; + const MyMeshType _src_mesh; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Intersector3D.txx b/src/INTERP_KERNEL/Intersector3D.txx new file mode 100644 index 000000000..523ab8f7b --- /dev/null +++ b/src/INTERP_KERNEL/Intersector3D.txx @@ -0,0 +1,34 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERSECTOR3D_TXX__ +#define __INTERSECTOR3D_TXX__ + +#include "Intersector3D.hxx" + +namespace INTERP_KERNEL +{ + template + Intersector3D::Intersector3D(const MyMeshType& targetMesh, const MyMeshType& srcMesh):_target_mesh(targetMesh),_src_mesh(srcMesh) + { + } + + +} + +#endif diff --git a/src/INTERP_KERNEL/Intersector3DP0P0.hxx b/src/INTERP_KERNEL/Intersector3DP0P0.hxx new file mode 100644 index 000000000..f9cab3236 --- /dev/null +++ b/src/INTERP_KERNEL/Intersector3DP0P0.hxx @@ -0,0 +1,36 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERSECTOR3DP0P0_HXX__ +#define __INTERSECTOR3DP0P0_HXX__ + +#include "Intersector3D.hxx" + +namespace INTERP_KERNEL +{ + template + class Intersector3DP0P0 : public Intersector3D + { + public: + Intersector3DP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Intersector3DP0P0.txx b/src/INTERP_KERNEL/Intersector3DP0P0.txx new file mode 100644 index 000000000..9cb948242 --- /dev/null +++ b/src/INTERP_KERNEL/Intersector3DP0P0.txx @@ -0,0 +1,45 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERSECTOR3DP0P0_TXX__ +#define __INTERSECTOR3DP0P0_TXX__ + +#include "Intersector3DP0P0.hxx" +#include "Intersector3D.txx" + +namespace INTERP_KERNEL +{ + template + Intersector3DP0P0::Intersector3DP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh):Intersector3D(targetMesh,srcMesh) + { + } + + template + int Intersector3DP0P0::getNumberOfRowsOfResMatrix() const + { + return Intersector3D::_target_mesh.getNumberOfElements(); + } + + template + int Intersector3DP0P0::getNumberOfColsOfResMatrix() const + { + return Intersector3D::_src_mesh.getNumberOfElements(); + } +} + +#endif diff --git a/src/INTERP_KERNEL/Intersector3DP0P1.hxx b/src/INTERP_KERNEL/Intersector3DP0P1.hxx new file mode 100644 index 000000000..42dac7fce --- /dev/null +++ b/src/INTERP_KERNEL/Intersector3DP0P1.hxx @@ -0,0 +1,36 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERSECTOR3DP0P1_HXX__ +#define __INTERSECTOR3DP0P1_HXX__ + +#include "Intersector3D.hxx" + +namespace INTERP_KERNEL +{ + template + class Intersector3DP0P1 : public Intersector3D + { + public: + Intersector3DP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Intersector3DP0P1.txx b/src/INTERP_KERNEL/Intersector3DP0P1.txx new file mode 100644 index 000000000..ed1f4369e --- /dev/null +++ b/src/INTERP_KERNEL/Intersector3DP0P1.txx @@ -0,0 +1,45 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERSECTOR3DP0P1_TXX__ +#define __INTERSECTOR3DP0P1_TXX__ + +#include "Intersector3DP0P1.hxx" +#include "Intersector3D.txx" + +namespace INTERP_KERNEL +{ + template + Intersector3DP0P1::Intersector3DP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh):Intersector3D(targetMesh,srcMesh) + { + } + + template + int Intersector3DP0P1::getNumberOfRowsOfResMatrix() const + { + return Intersector3D::_target_mesh.getNumberOfNodes(); + } + + template + int Intersector3DP0P1::getNumberOfColsOfResMatrix() const + { + return Intersector3D::_src_mesh.getNumberOfElements(); + } +} + +#endif diff --git a/src/INTERP_KERNEL/Intersector3DP1P0.hxx b/src/INTERP_KERNEL/Intersector3DP1P0.hxx new file mode 100644 index 000000000..3735f7e11 --- /dev/null +++ b/src/INTERP_KERNEL/Intersector3DP1P0.hxx @@ -0,0 +1,36 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERSECTOR3DP1P0_HXX__ +#define __INTERSECTOR3DP1P0_HXX__ + +#include "Intersector3D.hxx" + +namespace INTERP_KERNEL +{ + template + class Intersector3DP1P0 : public Intersector3D + { + public: + Intersector3DP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/Intersector3DP1P0.txx b/src/INTERP_KERNEL/Intersector3DP1P0.txx new file mode 100644 index 000000000..8df0dfdc3 --- /dev/null +++ b/src/INTERP_KERNEL/Intersector3DP1P0.txx @@ -0,0 +1,45 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERSECTOR3DP1P0_TXX__ +#define __INTERSECTOR3DP1P0_TXX__ + +#include "Intersector3DP1P0.hxx" +#include "Intersector3D.txx" + +namespace INTERP_KERNEL +{ + template + Intersector3DP1P0::Intersector3DP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh):Intersector3D(targetMesh,srcMesh) + { + } + + template + int Intersector3DP1P0::getNumberOfRowsOfResMatrix() const + { + return Intersector3D::_target_mesh.getNumberOfElements(); + } + + template + int Intersector3DP1P0::getNumberOfColsOfResMatrix() const + { + return Intersector3D::_src_mesh.getNumberOfNodes(); + } +} + +#endif diff --git a/src/INTERP_KERNEL/Log.hxx b/src/INTERP_KERNEL/Log.hxx new file mode 100644 index 000000000..8880865b4 --- /dev/null +++ b/src/INTERP_KERNEL/Log.hxx @@ -0,0 +1,65 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef _LOG_H_ +#define _LOG_H_ + +/** + * \file Log.hxx + * \brief Simple pre-processor logging utility. + * + * Replaces LOG( lvl, x ) with "if(lvl <= LOG_LEVEL) std::cout << x << std::endl" when logging is active + * (LOG_LEVEL > 0 is defined). x is the level at which the message should be logged - if it is smaller or equal to + * LOG_LEVEL (which can be defined at compile-time for each file by passing option -DLOG_LEVEL=x to gcc) + * than the message is logged. + * + * + * + */ + +/// define LOG_LEVEL here if it is not already defined +#ifndef LOG_LEVEL +#define LOG_LEVEL 0 +#endif + +#if LOG_LEVEL > 0 + +#include + +/// write message msg to std::cout if x <= LOG_LEVEL +#define LOG(x, msg) if(x <= LOG_LEVEL) std::cout << msg << std::endl; +#define LOG3( x , msg1 , msg2 ) if(x <= LOG_LEVEL) std::cout << msg1, msg2 << std::endl; + +#else + +#define LOG( x , msg ) +#define LOG3( x , msg1 , msg2 ) + +#endif + + + + + + + + + + + +#endif diff --git a/src/INTERP_KERNEL/Makefile.am b/src/INTERP_KERNEL/Makefile.am new file mode 100644 index 000000000..025656c9e --- /dev/null +++ b/src/INTERP_KERNEL/Makefile.am @@ -0,0 +1,131 @@ +# Copyright (C) 2007-2008 CEA/DEN, 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. +# +# 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 +# +# MED files in memory +# File : Makefile.am +# Author : Vincent BERGEAUD (CEA/DEN/DANS/DM2S/SFME/LGLS) +# Module : MED +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +SUBDIRS = Bases Geometric2D . + +DIST_SUBDIRS = Bases Geometric2D + +lib_LTLIBRARIES = libinterpkernel.la + + +salomeinclude_HEADERS = \ +INTERPKERNELDefines.hxx \ +BoundingBox.hxx PolyhedronIntersector.hxx RegionNode.hxx\ +ConvexIntersector.hxx SplitterTetra.hxx Intersector3DP0P1.txx \ +Geometric2DIntersector.hxx Log.hxx TargetIntersector.hxx\ +CellModel.hxx TetraAffineTransform.hxx Intersector3DP1P0.hxx \ +InterpKernelMatrix.hxx MeshElement.hxx TransformedTriangle.hxx\ +Interpolation2D.hxx MeshRegion.hxx TransformedTriangleInline.hxx\ +Interpolation3D.hxx MeshUtils.hxx TranslationRotationMatrix.hxx\ +Interpolation3DSurf.hxx MeshRegion.txx TriangulationIntersector.hxx\ +Interpolation.hxx PlanarIntersector.hxx VectorUtils.hxx\ +InterpolationPlanar.hxx PolyhedronIntersectorP1P0.txx VTKNormalizedUnstructuredMesh.hxx\ +InterpolationUtils.hxx PolygonAlgorithms.hxx InterpolationOptions.hxx\ +BBTree.txx InterpolationPlanar.txx PlanarIntersector.txx\ +ConvexIntersector.txx PolyhedronIntersector.txx Intersector3DP1P0.txx\ +Geometric2DIntersector.txx SplitterTetra.txx PolygonAlgorithms.txx\ +Interpolation2D.txx TriangulationIntersector.txx PolyhedronIntersectorP1P0.hxx\ +Interpolation3DSurf.txx MeshElement.txx VTKNormalizedUnstructuredMesh.txx\ +Interpolation3D.txx PlanarIntersectorP0P0.hxx PlanarIntersectorP0P0.txx\ +PolyhedronIntersectorP0P1.hxx PolyhedronIntersectorP0P1.txx Intersector3D.hxx\ +Intersector3D.txx Intersector3DP0P1.hxx + + +# Libraries targets + +dist_libinterpkernel_la_SOURCES = \ + TransformedTriangle.cxx\ + TransformedTriangleIntersect.cxx\ + TransformedTriangleMath.cxx\ + BoundingBox.cxx \ + TetraAffineTransform.cxx\ + CellModel.cxx\ + UnitTetraIntersectionBary.cxx + +libinterpkernel_la_CPPFLAGS=-I$(srcdir)/Geometric2D -I$(srcdir)/Bases + +libinterpkernel_la_LDFLAGS= + +# the geom2D library is included in the interpkernel one +libinterpkernel_la_LIBADD= ./Geometric2D/libInterpGeometric2DAlg.la Bases/libinterpkernelbases.la + +AM_CPPFLAGS= $(libinterpkernel_la_CPPFLAGS) +LDADD= $(libinterpkernel_la_LDFLAGS) + +EXTRA_DIST += \ + BBTree.txx \ + BoundingBox.hxx \ + ConvexIntersector.hxx \ + ConvexIntersector.txx \ + Geometric2DIntersector.hxx \ + Geometric2DIntersector.txx \ + Geometric2DIntersector.hxx \ + Geometric2DIntersector.txx \ + InterpKernelMatrix.hxx \ + Interpolation2D.txx \ + Interpolation3D.txx \ + Interpolation3DSurf.txx \ + InterpolationPlanar.hxx \ + InterpolationPlanar.txx \ + InterpolationUtils.hxx \ + Intersector3D.hxx \ + Intersector3D.txx \ + Intersector3DP0P1.hxx \ + Intersector3DP0P1.txx \ + Intersector3DP1P0.hxx \ + Intersector3DP1P0.txx \ + PolyhedronIntersector.hxx \ + PolyhedronIntersector.txx \ + PolyhedronIntersectorP0P1.hxx \ + PolyhedronIntersectorP0P1.txx \ + SplitterTetra.hxx \ + SplitterTetra.txx \ + Log.hxx \ + MEDNormalizedUnstructuredMesh.hxx \ + MEDNormalizedUnstructuredMesh.txx \ + MeshElement.hxx \ + MeshElement.txx \ + MeshRegion.hxx \ + MeshRegion.txx \ + MeshUtils.hxx \ + PlanarIntersector.hxx \ + PlanarIntersector.txx \ + PlanarIntersectorP0P0.hxx \ + PlanarIntersectorP0P0.txx \ + PointLocatorAlgos.txx \ + PolygonAlgorithms.hxx \ + PolygonAlgorithms.txx \ + RegionNode.hxx \ + TargetIntersector.hxx \ + TestInterpKernel.cpp \ + TetraAffineTransform.hxx \ + TransformedTriangle.hxx \ + TransformedTriangleInline.hxx \ + TranslationRotationMatrix.hxx \ + TriangulationIntersector.hxx \ + TriangulationIntersector.txx \ + VTKNormalizedUnstructuredMesh.hxx \ + VTKNormalizedUnstructuredMesh.txx \ + VectorUtils.hxx diff --git a/src/INTERP_KERNEL/MeshElement.hxx b/src/INTERP_KERNEL/MeshElement.hxx new file mode 100644 index 000000000..ca64b5cd6 --- /dev/null +++ b/src/INTERP_KERNEL/MeshElement.hxx @@ -0,0 +1,86 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __MESHELEMENT_HXX__ +#define __MESHELEMENT_HXX__ + +#include "BoundingBox.hxx" + +namespace INTERP_KERNEL +{ + + /** + * \brief Class representing a single element of a mesh together with its bounding box. + * It gives access to the element's global number, type and bounding box and allows + * easy bounding box intersection tests between MeshElements and collections of MeshElement (MeshRegions) + */ + template + class MeshElement + { + + public: + template + MeshElement(const ConnType index, const MyMeshType& mesh); + + ~MeshElement(); + + ConnType getIndex() const { return _index; } + + unsigned char getNumberOfNodes() const { return _number; } + + const BoundingBox* getBoundingBox() const { return _box; } + + private: + /// disallow copying + MeshElement(const MeshElement& elem); + + /// disallow assignment + MeshElement& operator=(const MeshElement& elem); + + /// global number of the element + const ConnType _index; + + const unsigned char _number; + + /// bounding box of the element - does not change after having been initialised + BoundingBox* _box; + }; + + /** + * \brief Class defining an order for MeshElements based on their bounding boxes. + * The order defined between two elements is that between a given coordinate of + * their bounding boxes. For instance, if the order is based on YMIN, an element whose boxes + * has a smaller YMIN is sorted before one with a larger YMIN. + * + */ + class INTERPKERNEL_EXPORT ElementBBoxOrder + { + public : + + ElementBBoxOrder(BoundingBox::BoxCoord coord); + template + bool operator()(MeshElement* elem1, MeshElement* elem2); + + private : + /// BoundingBox coordinate (XMIN, XMAX, etc) on which to base the ordering + BoundingBox::BoxCoord _coord; + }; + +} + +#endif diff --git a/src/INTERP_KERNEL/MeshElement.txx b/src/INTERP_KERNEL/MeshElement.txx new file mode 100644 index 000000000..2d363a1b8 --- /dev/null +++ b/src/INTERP_KERNEL/MeshElement.txx @@ -0,0 +1,104 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __MESHELEMENT_TXX__ +#define __MESHELEMENT_TXX__ + +#include "MeshElement.hxx" + +#include "TetraAffineTransform.hxx" +#include "TransformedTriangle.hxx" +#include "MeshUtils.hxx" +#include "BoundingBox.hxx" +#include + +namespace INTERP_KERNEL +{ + + /** + * Constructor + * + * @param index global number of element in the mesh in C mode. + * @param mesh mesh that the element belongs to + */ + template + template + MeshElement::MeshElement(const ConnType index, const MyMeshType& mesh) + : _index(index), _box(0), _number(mesh.getNumberOfNodesOfElement(OTT::indFC(index))) + { + const double**vertices = new const double*[_number]; + + for(unsigned char i = 0 ; i < _number ; ++i) + vertices[i] = getCoordsOfNode(i , OTT::indFC(index), mesh); + + // create bounding box + _box = new BoundingBox(vertices,_number); + delete [] vertices; + } + + /** + * Destructor + * + */ + template + MeshElement::~MeshElement() + { + delete _box; + } + + + + ///////////////////////////////////////////////////////////////////// + /// ElementBBoxOrder ///////////// + ///////////////////////////////////////////////////////////////////// + /** + * Constructor + * + * @param coord BoundingBox coordinate (XMIN, XMAX, etc) on which to base the ordering + */ + ElementBBoxOrder::ElementBBoxOrder(BoundingBox::BoxCoord coord) + : _coord(coord) + { + } + + /** + * Comparison operator based on the bounding boxes of the elements + * + * @return true if the coordinate _coord of the bounding box of elem1 is + * strictly smaller than that of the bounding box of elem2 + */ + template + bool ElementBBoxOrder::operator()( MeshElement* elem1, MeshElement* elem2) + { + const BoundingBox* box1 = elem1->getBoundingBox(); + const BoundingBox* box2 = elem2->getBoundingBox(); + + assert(elem1 != 0); + assert(elem2 != 0); + assert(box1 != 0); + assert(box2 != 0); + + const double coord1 = box1->getCoordinate(_coord); + const double coord2 = box2->getCoordinate(_coord); + + return coord1 < coord2; + } + +} + +#endif diff --git a/src/INTERP_KERNEL/MeshRegion.hxx b/src/INTERP_KERNEL/MeshRegion.hxx new file mode 100644 index 000000000..fe0133909 --- /dev/null +++ b/src/INTERP_KERNEL/MeshRegion.hxx @@ -0,0 +1,92 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __MESHREGION_HXX__ +#define __MESHREGION_HXX__ + +#include "MeshElement.hxx" +#include "BoundingBox.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +#include + +namespace INTERP_KERNEL +{ + /** + * \brief Class representing a set of elements in a mesh together with their bounding box. + * It permits to split itself in two, which is used in the depth-first search filtering process. + * + */ + template + class MeshRegion + { + public: + + MeshRegion(); + + ~MeshRegion(); + + template + void addElement(MeshElement* const element, const MyMeshType& mesh); + + template + void split(MeshRegion& region1, MeshRegion& region2, BoundingBox::BoxCoord coord, const MyMeshType& mesh); + + bool isDisjointWithElementBoundingBox(const MeshElement& elem) const; + /** + * Accessor to beginning of elements vector + * + * @return constant iterator pointing at the beginning of the vector or elements + */ + typename std::vector< MeshElement* >::const_iterator getBeginElements() const { return _elements.begin(); } + + /** + * Accessor to end of elements vector + * + * @return constant iterator pointing at the end of the vector or elements + */ + typename std::vector< MeshElement* >::const_iterator getEndElements() const { return _elements.end(); } + + /** + * Gives information on how many elements are contained in the region. + * + * @return the number of elements contained in the region + */ + unsigned getNumberOfElements() const { return _elements.size(); } + + private: + + /// disallow copying + MeshRegion(const MeshRegion& m); + + /// disallow assignment + MeshRegion& operator=(const MeshRegion& m); + + /// Vector of pointers to contained MeshElements. + /// NB : these pointers are not owned by the region object, and are thus + /// neither allocated or liberated in this class. The elements must therefore be allocated and liberated outside the class. + std::vector< MeshElement* > _elements; + + /// BoundingBox containing all the nodes of all the elements in the region. + BoundingBox* _box; + + }; + +} + +#endif diff --git a/src/INTERP_KERNEL/MeshRegion.txx b/src/INTERP_KERNEL/MeshRegion.txx new file mode 100644 index 000000000..75b016203 --- /dev/null +++ b/src/INTERP_KERNEL/MeshRegion.txx @@ -0,0 +1,153 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __MESHREGION_TXX__ +#define __MESHREGION_TXX__ + +#include "MeshRegion.hxx" + +#include "MeshElement.txx" +#include "MeshUtils.hxx" + +namespace INTERP_KERNEL +{ + + /** + * Default constructor + * + */ + template + MeshRegion::MeshRegion():_box(0) + { + } + + /** + * Destructor + * + */ + template + MeshRegion::~MeshRegion() + { + delete _box; + } + + /** + * Adds an element to the region, updating the bounding box. If the bounding box does not yet + * exist, it is created here. This creation is delayed to make it possible to have empty MeshRegions + * + * @param element pointer to element to add to region + * @param mesh mesh to which element belongs + * + */ + template + template + void MeshRegion::addElement(MeshElement* const element, const MyMeshType& mesh) + { + _elements.push_back(element); + + const unsigned char numNodes = element->getNumberOfNodes(); + const ConnType elemIdx = element->getIndex(); + + if(_box == 0) + { + const double** pts = new const double*[numNodes]; + + // get coordinates of the nodes of the element + for(unsigned char i = 0 ; i < numNodes ; ++i) + { + pts[i] = getCoordsOfNode(i, OTT::indFC(elemIdx), mesh); + } + + _box = new BoundingBox(pts, numNodes); + delete [] pts; + + } else { + + for(unsigned char i = 0 ; i < numNodes ; ++i) + { + const double* pt = getCoordsOfNode(i, OTT::indFC(elemIdx), mesh); + _box->updateWithPoint(pt); + } + } + } + + /** + * Splits the region in two along the given axis, copying the elements with bounding boxes whose maximum + * coordinate along the axis are smaller than the middle of the bounding box of this region in region1. The + * rest of the elements are copied to region2. + * + * @param region1 region in which to store one half of this region + * @param region2 region in which to store the other of this region + * @param coord coordinate of BoundingBox to use when splitting the region + * @param mesh mesh to which region belongs + * + */ + template + template + void MeshRegion::split(MeshRegion& region1, MeshRegion& region2, BoundingBox::BoxCoord coord, const MyMeshType& mesh) + { + // create ordering + ElementBBoxOrder cmp(coord); + + // sort elements by their bounding boxes + std::sort(_elements.begin(), _elements.end(), cmp); + + // put the first half of the elements in region1 and the + // rest in region2 + typename std::vector< MeshElement *>::const_iterator iter = _elements.begin(); + int elemCount = 0; + + while(elemCount < static_cast(_elements.size() / 2)) + { + region1.addElement(*iter, mesh); + ++iter; + ++elemCount; + } + + while(iter != _elements.end()) + { + region2.addElement(*iter, mesh); + ++iter; + } + } + + /** + * Determines if a given element can intersect the elements of this region by + * testing whether the bounding box of the region intersects the bounding box of the element. + * Note that the test is only true in one direction : if the bounding boxes are disjoint, the + * element cannot intersect any of the elements in the region, but if they are not disjoint, the + * element may or may not do so. + * + * @param elem Element with which to test for disjoint-ness + * @return true if the bounding box of the element is disjoint with the bounding box of the region, false otherwise + */ + template + bool MeshRegion::isDisjointWithElementBoundingBox(const MeshElement& elem) const + { + const BoundingBox* elemBox = elem.getBoundingBox(); + + assert(_box != 0); + assert(elemBox != 0); + + return _box->isDisjointWith(*elemBox); + } + + +} + +#endif diff --git a/src/INTERP_KERNEL/MeshUtils.hxx b/src/INTERP_KERNEL/MeshUtils.hxx new file mode 100644 index 000000000..1b4b404d8 --- /dev/null +++ b/src/INTERP_KERNEL/MeshUtils.hxx @@ -0,0 +1,101 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __MESHUTILS_HXX__ +#define __MESHUTILS_HXX__ + +#include "InterpolationUtils.hxx" + +namespace INTERP_KERNEL +{ + /** + * Returns the global number of the node of an element. + * + * @param node the node for which the global number is sought (ALWAYS in C mode) + * @param element an element of the mesh (in numPol policy) + * @param mesh a mesh + * @return the node's global number so that (its coordinates in the coordinates array are at [SPACEDIM*globalNumber, SPACEDIM*globalNumber + 2] + */ + template + inline typename MyMeshType::MyConnType getGlobalNumberOfNode(typename MyMeshType::MyConnType node, typename MyMeshType::MyConnType element, const MyMeshType& mesh) + { + typedef typename MyMeshType::MyConnType ConnType; + const NumberingPolicy numPol=MyMeshType::My_numPol; + const ConnType elemIdx=OTT::conn2C(mesh.getConnectivityIndexPtr()[OTT::ind2C(element)]); + return OTT::coo2C(mesh.getConnectivityPtr()[elemIdx + node]); + } + + /** + * Returns the coordinates of a node of an element + * + * @param node the node for which the coordinates are sought. In C mode. + * @param element an element of the mesh. In mesh policy. + * @param mesh a mesh + * @return pointer to an array of 3 doubles containing the coordinates of the node + */ + template + inline const double* getCoordsOfNode(typename MyMeshType::MyConnType node, typename MyMeshType::MyConnType element, const MyMeshType& mesh) + { + typedef typename MyMeshType::MyConnType ConnType; + const ConnType connIdx = getGlobalNumberOfNode(node, element, mesh); + return mesh.getCoordinatesPtr()+MyMeshType::MY_SPACEDIM*connIdx; + } + + /** + * Returns the coordinates of a node of an element + * + * @param node the node for which the coordinates are sought. In C mode. + * @param element an element of the mesh. In mesh policy. + * @param mesh a mesh + * @param nodeId globale nodeId in whole mesh point of view in C mode. + * @return pointer to an array of 3 doubles containing the coordinates of the node + */ + template + inline const double* getCoordsOfNode2(typename MyMeshType::MyConnType node, typename MyMeshType::MyConnType element, const MyMeshType& mesh, typename MyMeshType::MyConnType& nodeId) + { + typedef typename MyMeshType::MyConnType ConnType; + nodeId= getGlobalNumberOfNode(node, element, mesh); + return mesh.getCoordinatesPtr()+MyMeshType::MY_SPACEDIM*nodeId; + } + + /** + * Returns the barycentric coordinates of a point within a triangle or tetrahedron + * + * @param point the point for which the barycentric coordinates are sought + * @param element an element of the mesh + * @param mesh a mesh + * @param barycentricCoords an array of 3 doubles containing the coordinates of the node + */ + template + inline void getBarycentricCoordinates(const double* point, + typename MyMeshType::MyConnType element, + const MyMeshType& mesh, + double* barycentricCoords) + { + std::vector nodes( NB_NODES ); + typedef typename MyMeshType::MyConnType ConnType; + for ( int node = 0; node < NB_NODES; ++node ) + { + nodes[ node ] = getCoordsOfNode( node, element, mesh ); + } + barycentric_coords( nodes, point, barycentricCoords ); + } + +} + +#endif diff --git a/src/INTERP_KERNEL/PlanarIntersector.hxx b/src/INTERP_KERNEL/PlanarIntersector.hxx new file mode 100644 index 000000000..9676000bc --- /dev/null +++ b/src/INTERP_KERNEL/PlanarIntersector.hxx @@ -0,0 +1,71 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __PLANARINTERSECTOR_HXX__ +#define __PLANARINTERSECTOR_HXX__ + +#include "TargetIntersector.hxx" + +namespace INTERP_KERNEL +{ + class TranslationRotationMatrix; + + template + class PlanarIntersector : public TargetIntersector + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + //! \addtogroup InterpKerGrpIntPlan @{ + PlanarIntersector(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double medianPlane, bool doRotate, int orientation, int printLevel); + //! @} + virtual ~PlanarIntersector(); + void createBoundingBoxes(const MyMeshType& mesh, std::vector& bbox); + void adjustBoundingBoxes(std::vector& bbox, double Surf3DAdjustmentEps); + inline void getElemBB(double* bb, const MyMeshType& mesh, ConnType iP, ConnType nb_nodes); + protected : + int projectionThis(double *Coords_A, double *Coords_B, int nb_NodesA, int nb_NodesB); + void getRealTargetCoordinates(ConnType icellT, std::vector& coordsT); + void getRealSourceCoordinates(ConnType icellS, std::vector& coordsS); + void getRealCoordinates(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS, std::vector& coordsT, std::vector& coordsS, int& orientation); + static int projection(double *Coords_A, double *Coords_B, + int nb_NodesA, int nb_NodesB, double epsilon, double median_plane, bool do_rotate); + static void rotate3DTriangle( double* PP1, double*PP2, double*PP3, + TranslationRotationMatrix& rotation_matrix); + protected: + const ConnType *_connectT; + const ConnType *_connectS; + const double *_coordsT; + const double *_coordsS; + const ConnType *_connIndexT; + const ConnType *_connIndexS; + const MyMeshType& _meshT; + const MyMeshType& _meshS; + double _dim_caracteristic; + double _precision; + double _median_plane; + bool _do_rotate; + int _orientation; + int _print_level; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/PlanarIntersector.txx b/src/INTERP_KERNEL/PlanarIntersector.txx new file mode 100644 index 000000000..df6593a01 --- /dev/null +++ b/src/INTERP_KERNEL/PlanarIntersector.txx @@ -0,0 +1,407 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __PLANARINTERSECTOR_TXX__ +#define __PLANARINTERSECTOR_TXX__ + +#include "PlanarIntersector.hxx" +#include "InterpolationUtils.hxx" +#include "TranslationRotationMatrix.hxx" + +#include +#include + +namespace INTERP_KERNEL +{ + template + PlanarIntersector::PlanarIntersector(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double medianPlane, bool doRotate, int orientation, int printLevel): + _meshT(meshT),_meshS(meshS), + _dim_caracteristic(dimCaracteristic),_precision(precision),_median_plane(medianPlane), + _do_rotate(doRotate),_orientation(orientation),_print_level(printLevel) + { + _connectT=meshT.getConnectivityPtr(); + _connectS=meshS.getConnectivityPtr(); + _connIndexT=meshT.getConnectivityIndexPtr(); + _connIndexS=meshS.getConnectivityIndexPtr(); + _coordsT=meshT.getCoordinatesPtr(); + _coordsS=meshS.getCoordinatesPtr(); + } + + template + PlanarIntersector::~PlanarIntersector() + { + } + + /*! + \brief creates the bounding boxes for all the cells of mesh \a mesh + + The method accepts mixed meshes (containing triangles and quadrangles). + The vector returned is of dimension 6*nb_elems with bounding boxes stored as xmin1, xmax1, ymin1, ymax1, zmin1, zmax1, xmin2, xmax2, ymin2,... + The returned pointer must be deleted by the calling code. + + \param mesh structure pointing to the mesh + \param bbox vector containing the bounding boxes + */ + template + void PlanarIntersector::createBoundingBoxes(const MyMeshType& mesh, std::vector& bbox) + { + /* We build the segment tree for locating possible matching intersections*/ + long nbelems = mesh.getNumberOfElements(); + bbox.resize(2*SPACEDIM* nbelems); + const double* coords = mesh.getCoordinatesPtr(); + const ConnType* conn = mesh.getConnectivityPtr(); + const ConnType* conn_index = mesh.getConnectivityIndexPtr(); + int ibox=0; + for(long icell=0; icell::max(); + bbox[2*SPACEDIM*ibox+2*idim+1] = -std::numeric_limits::max(); + } + //updating the bounding box with each node of the element + for (int j=0; j::coo2C(conn[OTT::conn2C(conn_index[icell]+j)]); + for(int idim=0; idimx)?bbox[ibox*2*SPACEDIM + 2*idim+1]:x; + } + } + ibox++; + } + } + + /*! + Computes the bouding box of a given element. iP in numPol mode. + */ + template + void PlanarIntersector::getElemBB(double* bb, const MyMeshType& mesh, ConnType iP, ConnType nb_nodes) + { + const double* coords = mesh.getCoordinatesPtr(); + const ConnType* conn_index = mesh.getConnectivityIndexPtr(); + const ConnType* conn = mesh.getConnectivityPtr(); + //initializing bounding box limits + for(int idim=0; idim::max(); + bb[2*idim+1] = -std::numeric_limits::max(); + } + + for (ConnType i=0; i::coo2C(conn[OTT::conn2C(conn_index[OTT::ind2C(iP)]+i)])); + for(int idim=0; idimbb[2*idim+1])?x:bb[2*idim+1]; + } + } + } + + /*! Readjusts a set of bounding boxes so that they are extended + in all dimensions for avoiding missing interesting intersections + + \param bbox vector containing the bounding boxes + */ + template + void PlanarIntersector::adjustBoundingBoxes(std::vector& bbox, double Surf3DAdjustmentEps) + { + /* We build the segment tree for locating possible matching intersections*/ + + long size = bbox.size()/(2*SPACEDIM); + for (int i=0; i::max(); + for(int idim=0; idim + void PlanarIntersector::getRealTargetCoordinates(ConnType icellT, std::vector& coordsT) + { + int nbNodesT=_connIndexT[OTT::ind2C(icellT)+1]-_connIndexT[OTT::ind2C(icellT)]; + coordsT.resize(SPACEDIM*nbNodesT); + for (ConnType iT=0; iT::coo2C(_connectT[OTT::conn2C(_connIndexT[OTT::ind2C(icellT)]+iT)])+idim]; + } + + /*! + * @param icellS id in source mesh in format of MyMeshType. + * @param coordsS output val that stores coordinates of the source cell automatically resized to the right length. + */ + template + void PlanarIntersector::getRealSourceCoordinates(ConnType icellS, std::vector& coordsS) + { + int nbNodesS=_connIndexS[OTT::ind2C(icellS)+1]-_connIndexS[OTT::ind2C(icellS)]; + coordsS.resize(SPACEDIM*nbNodesS); + for (ConnType iS=0; iS::coo2C(_connectS[OTT::conn2C(_connIndexS[OTT::ind2C(icellS)]+iS)])+idim]; + } + + /*! + * @param icellT id in target mesh in format of MyMeshType. + * @param icellS id in source mesh in format of MyMeshType. + * @param nbNodesT nb of nodes of the target cell. + * @param nbNodesS nb of nodes of the source cell. + * @param coordsT output val that stores coordinates of the target cell automatically resized to the right length. + * @param coordsS output val that stores coordinates of the source cell automatically resized to the right length. + * @param orientation is an output value too, only set if SPACEDIM==3. + */ + template + void PlanarIntersector::getRealCoordinates(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS, std::vector& coordsT, std::vector& coordsS, int& orientation) + { + /*double epsilon=_precision*_dim_caracteristic; + coordsT.resize(SPACEDIM*nbNodesT); + coordsS.resize(SPACEDIM*nbNodesS); + int nb_dist_NodesT=nbNodesT; + int nb_dist_NodesS=nbNodesS; + int i_last = nbNodesT - 1; + const double * Pi_last=_coordsT +_connectT[OTT::conn2C(_connIndexT[OTT::ind2C(icellT)]+i_last)]; + + for (int iT=0; iT::coo2C(_connectT[OTT::conn2C(_connIndexT[OTT::ind2C(icellT)]+iT)]); + if(distance2(Pi_last, PiT)>epsilon) + { + for (int idim=0; idim::coo2C(_connectS[OTT::conn2C(_connIndexS[OTT::ind2C(icellS)]+i_last)]); + for (int iS=0; iS::coo2C(_connectS[OTT::conn2C(_connIndexS[OTT::ind2C(icellS)]+iS)]); + if(distance2(Pi_last, PiS)>epsilon) + { + for (int idim=0; idim= 3) + { + std::cout << std::endl << "Cell coordinates (possibly after projection)" << std::endl; + std::cout << std::endl << "icellT= " << icellT << ", nb nodes T= " << nbNodesT << std::endl; + for(int iT =0; iT< nbNodesT; iT++) + {for (int idim=0; idim::coo2C(_connectT[OTT::conn2C(_connIndexT[OTT::ind2C(icellT)]+iT)])+idim]; + for (ConnType iS=0; iS::coo2C(_connectS[OTT::conn2C(_connIndexS[OTT::ind2C(icellS)]+iS)])+idim]; + } + + //project cells T and S on the median plane and rotate the median plane + if(SPACEDIM==3) + orientation = projectionThis(&coordsT[0], &coordsS[0], nbNodesT, nbNodesS); + + //DEBUG PRINTS + if(_print_level >= 3) + { + std::cout << std::endl << "Cell coordinates (possibly after projection)" << std::endl; + std::cout << std::endl << "icellT= " << icellT << ", nb nodes T= " << nbNodesT << std::endl; + for(int iT =0; iT< nbNodesT; iT++) + {for (int idim=0; idim + int PlanarIntersector::projectionThis(double *Coords_A, double *Coords_B, int nb_NodesA, int nb_NodesB) + { + return projection(Coords_A,Coords_B,nb_NodesA,nb_NodesB,_dim_caracteristic*_precision,_median_plane,_do_rotate); + } + + template + int PlanarIntersector::projection(double *Coords_A, double *Coords_B, + int nb_NodesA, int nb_NodesB, double epsilon, double median_plane, bool do_rotate) + { + double normal_A[3]={0,0,0}; + double normal_B[3]={0,0,0}; + double linear_comb[3]; + double proj; + bool same_orientation; + + //Find the normal to cells A and B + int i_A1=1; + while(i_A1(Coords_A,&Coords_A[SPACEDIM*i_A1])< epsilon) i_A1++; + int i_A2=i_A1+1; + crossprod(Coords_A, &Coords_A[SPACEDIM*i_A1], &Coords_A[SPACEDIM*i_A2],normal_A); + double normA = sqrt(dotprod(normal_A,normal_A)); + while(i_A2(Coords_A, &Coords_A[SPACEDIM*i_A1], &Coords_A[SPACEDIM*i_A2],normal_A); + i_A2++; + normA = sqrt(dotprod(normal_A,normal_A)); + + } + int i_B1=1; + while(i_B1(Coords_B,Coords_B+SPACEDIM*i_B1)< epsilon) i_B1++; + int i_B2=i_B1+1; + crossprod(Coords_B, Coords_B+SPACEDIM*i_B1, Coords_B+SPACEDIM*i_B2,normal_B); + double normB = sqrt(dotprod(normal_B,normal_B)); + while(i_B2(Coords_B, Coords_B+SPACEDIM*i_B1, Coords_B+SPACEDIM*i_B2,normal_B); + i_B2++; + normB = sqrt(dotprod(normal_B,normal_B)); + } + + if(i_A2(normal_A,normal_B)>=0; + + if(!same_orientation) + for(int idim =0; idim< SPACEDIM; idim++) normal_A[idim] *=-1; + + double normB= sqrt(dotprod(normal_B,normal_B)); + + for(int idim =0; idim< SPACEDIM; idim++) + linear_comb[idim] = median_plane*normal_A[idim]/normA + (1-median_plane)*normal_B[idim]/normB; + double norm= sqrt(dotprod(linear_comb,linear_comb)); + + //Necessarily: norm>epsilon, no need to check + for(int idim =0; idim< SPACEDIM; idim++) linear_comb[idim]/=norm; + + //Project the nodes of A and B on the median plane + for(int i_A=0; i_A(&Coords_A[SPACEDIM*i_A],linear_comb); + for(int idim =0; idim< SPACEDIM; idim++) + Coords_A[SPACEDIM*i_A+idim] -= proj*linear_comb[idim]; + } + for(int i_B=0; i_B(Coords_B+SPACEDIM*i_B,linear_comb); + for(int idim =0; idim< SPACEDIM; idim++) + Coords_B[SPACEDIM*i_B+idim] -= proj*linear_comb[idim]; + } + + //Buid the matrix sending A into the Oxy plane and apply it to A and B + if(do_rotate) + { + TranslationRotationMatrix rotation; + //rotate3DTriangle(Coords_A, &Coords_A[SPACEDIM*i_A1], &Coords_A[SPACEDIM*i_A2], rotation); + rotate3DTriangle(Coords_B, Coords_B+SPACEDIM*i_B1, Coords_B+SPACEDIM*i_B2, rotation); + for (int i=0; i(Coords_A,&Coords_A[i_A1])= " << distance2(Coords_A,&Coords_A[i_A1]) << std::endl; + std::cout << "abs(normal_A) = " << fabs(normal_A[0]) << " ; " <(&Coords_B[0],&Coords_B[i_B1])= " << distance2(Coords_B,Coords_B+i_B1) << std::endl; + std::cout << "normal_B = " << normal_B[0] << " ; " << normal_B[1] << " ; " << normal_B[2] << std::endl; + + return 1; + } + } + + template + void PlanarIntersector::rotate3DTriangle(double* PP1, double*PP2, double*PP3, + TranslationRotationMatrix& rotation_matrix) + { + //initializes + rotation_matrix.translate(PP1); + + double P2w[3]; + double P3w[3]; + P2w[0]=PP2[0]; P2w[1]=PP2[1];P2w[2]=PP2[2]; + P3w[0]=PP3[0]; P3w[1]=PP3[1];P3w[2]=PP3[2]; + + // translating to set P1 at the origin + for (int i=0; i<3; i++) + { + P2w[i]-=PP1[i]; + P3w[i]-=PP1[i]; + } + + // rotating to set P2 on the Oxy plane + TranslationRotationMatrix A; + A.rotate_x(P2w); + A.rotate_vector(P3w); + rotation_matrix.multiply(A); + + //rotating to set P2 on the Ox axis + TranslationRotationMatrix B; + B.rotate_z(P2w); + B.rotate_vector(P3w); + rotation_matrix.multiply(B); + + //rotating to set P3 on the Oxy plane + TranslationRotationMatrix C; + C.rotate_x(P3w); + rotation_matrix.multiply(C); + } +} + +#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx b/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx new file mode 100644 index 000000000..ba7be6a43 --- /dev/null +++ b/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx @@ -0,0 +1,49 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __PLANARINTERSECTORP0P0_HXX__ +#define __PLANARINTERSECTORP0P0_HXX__ + +#include "PlanarIntersector.hxx" + +namespace INTERP_KERNEL +{ + template + class PlanarIntersectorP0P0 : public PlanarIntersector + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + protected: + PlanarIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double medianPlane, bool doRotate, int orientation, int printLevel); + public: + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); + /*! + * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. + */ + double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS) { return asLeaf().intersectGeometry(icellT,icellS,nbNodesT,nbNodesS); } + protected: + ConcreteP0P0Intersector& asLeaf() { return static_cast(*this); } + }; +} + +#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx b/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx new file mode 100644 index 000000000..aa51627a0 --- /dev/null +++ b/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx @@ -0,0 +1,66 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +#ifndef __PLANARINTERSECTORP0P0_TXX__ +#define __PLANARINTERSECTORP0P0_TXX__ + +#include "PlanarIntersectorP0P0.hxx" + +namespace INTERP_KERNEL +{ + template + PlanarIntersectorP0P0::PlanarIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double precision, double medianPlane, + bool doRotate, int orientation, int printLevel): + PlanarIntersector(meshT,meshS,dimCaracteristic,precision,medianPlane,doRotate,orientation,printLevel) + { + } + + template + int PlanarIntersectorP0P0::getNumberOfRowsOfResMatrix() const + { + return PlanarIntersector::_meshT.getNumberOfElements(); + } + + template + int PlanarIntersectorP0P0::getNumberOfColsOfResMatrix() const + { + return PlanarIntersector::_meshS.getNumberOfElements(); + } + + template + void PlanarIntersectorP0P0::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) + { + int nbNodesT=PlanarIntersector::_connIndexT[icellT+1]-PlanarIntersector::_connIndexT[icellT]; + typename MyMatrix::value_type& resRow=res[icellT]; + for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) + { + int iS=*iter; + int nbNodesS=PlanarIntersector::_connIndexS[iS+1]-PlanarIntersector::_connIndexS[iS]; + double surf=intersectGeometry(OTT::indFC(icellT),OTT::indFC(iS),nbNodesT,nbNodesS); + //filtering out zero surfaces and badly oriented surfaces + // _orientation = -1,0,1 + // -1 : the intersection is taken into account if target and cells have different orientation + // 0 : the intersection is always taken into account + // 1 : the intersection is taken into account if target and cells have the same orientation + if (( surf > 0.0 && PlanarIntersector::_orientation >=0 ) || ( surf < 0.0 && PlanarIntersector::_orientation <=0 )) + resRow.insert(std::make_pair(OTT::indFC(iS),surf)); + } + } +} + +#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx b/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx new file mode 100644 index 000000000..964133cec --- /dev/null +++ b/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx @@ -0,0 +1,49 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __PLANARINTERSECTORP0P1_HXX__ +#define __PLANARINTERSECTORP0P1_HXX__ + +#include "PlanarIntersector.hxx" + +namespace INTERP_KERNEL +{ + template + class PlanarIntersectorP0P1 : public PlanarIntersector + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + protected: + PlanarIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double medianPlane, bool doRotate, int orientation, int printLevel); + public: + void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + /*! + * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. + */ + double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad) { return asLeaf().intersectGeometryWithQuadrangle(quadrangle,sourceCoords,isSourceQuad); } + protected: + ConcreteP0P1Intersector& asLeaf() { return static_cast(*this); } + }; +} + +#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx b/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx new file mode 100644 index 000000000..ac1969fce --- /dev/null +++ b/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx @@ -0,0 +1,106 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +#ifndef __PLANARINTERSECTORP0P1_TXX__ +#define __PLANARINTERSECTORP0P1_TXX__ + +#include "PlanarIntersectorP0P1.hxx" +#include "InterpolationUtils.hxx" +#include "CellModel.hxx" + +namespace INTERP_KERNEL +{ + template + PlanarIntersectorP0P1::PlanarIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double precision, double medianPlane, + bool doRotate, int orientation, int printLevel): + PlanarIntersector(meshT,meshS,dimCaracteristic,precision,medianPlane,doRotate,orientation,printLevel) + { + } + + template + int PlanarIntersectorP0P1::getNumberOfRowsOfResMatrix() const + { + return PlanarIntersector::_meshT.getNumberOfNodes(); + } + + template + int PlanarIntersectorP0P1::getNumberOfColsOfResMatrix() const + { + return PlanarIntersector::_meshS.getNumberOfElements(); + } + + /*! + * This methods split on the fly, into triangles in order to compute dual mesh of target cell (with icellT id in target mesh in C mode). + */ + template + void PlanarIntersectorP0P1::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) + { + int nbNodesT=PlanarIntersector::_connIndexT[icellT+1]-PlanarIntersector::_connIndexT[icellT]; + double triangle[9]; + double quadrangle[12]; + std::vector sourceCellCoords; + int orientation=1; + const ConnType *startOfCellNodeConn=PlanarIntersector::_connectT+OTT::conn2C(PlanarIntersector::_connIndexT[icellT]); + for(int nodeIdT=0;nodeIdT::coo2C(startOfCellNodeConn[nodeIdT]); + std::copy(PlanarIntersector::_coordsT+curNodeTInCmode*SPACEDIM, + PlanarIntersector::_coordsT+curNodeTInCmode*SPACEDIM+SPACEDIM,triangle); + typename MyMatrix::value_type& resRow=res[curNodeTInCmode]; + for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) + { + int iS=*iter; + PlanarIntersector::getRealSourceCoordinates(OTT::indFC(iS),sourceCellCoords); + for(int subTriT=1;subTriT<=nbNodesT-2;subTriT++) + { + std::copy(PlanarIntersector::_coordsT+OTT::coo2C(startOfCellNodeConn[(nodeIdT+subTriT)%nbNodesT])*SPACEDIM, + PlanarIntersector::_coordsT+OTT::coo2C(startOfCellNodeConn[(nodeIdT+subTriT)%nbNodesT])*SPACEDIM+SPACEDIM, + triangle+SPACEDIM); + std::copy(PlanarIntersector::_coordsT+OTT::coo2C(startOfCellNodeConn[(nodeIdT+subTriT+1)%nbNodesT])*SPACEDIM, + PlanarIntersector::_coordsT+OTT::coo2C(startOfCellNodeConn[(nodeIdT+subTriT+1)%nbNodesT])*SPACEDIM+SPACEDIM, + triangle+2*SPACEDIM); + fillDualCellOfTri(triangle,quadrangle); + std::vector sourceCellCoordsTmp(sourceCellCoords); + if(SPACEDIM==3) + orientation=PlanarIntersector::projectionThis(&sourceCellCoordsTmp[0],quadrangle,sourceCellCoords.size()/SPACEDIM,4); + NormalizedCellType tS=PlanarIntersector::_meshS.getTypeOfElement(iS); + double surf=orientation*intersectGeometryWithQuadrangle(quadrangle,sourceCellCoordsTmp,CellModel::getCellModel(tS).isQuadratic()); + //filtering out zero surfaces and badly oriented surfaces + // _orientation = -1,0,1 + // -1 : the intersection is taken into account if target and cells have different orientation + // 0 : the intersection is always taken into account + // 1 : the intersection is taken into account if target and cells have the same orientation + if (( surf > 0.0 && PlanarIntersector::_orientation >=0 ) || ( surf < 0.0 && PlanarIntersector::_orientation <=0 )) + { + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(iS)); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(OTT::indFC(iS),surf)); + else + { + double val=(*iterRes).second+surf; + resRow.erase(OTT::indFC(iS)); + resRow.insert(std::make_pair(OTT::indFC(iS),val)); + } + } + } + } + } + } +} + +#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx b/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx new file mode 100644 index 000000000..5c2f0934c --- /dev/null +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx @@ -0,0 +1,49 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __PLANARINTERSECTORP1P0_HXX__ +#define __PLANARINTERSECTORP1P0_HXX__ + +#include "PlanarIntersector.hxx" + +namespace INTERP_KERNEL +{ + template + class PlanarIntersectorP1P0 : public PlanarIntersector + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + protected: + PlanarIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double medianPlane, bool doRotate, int orientation, int printLevel); + public: + void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + /*! + * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. + */ + double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad) { return asLeaf().intersectGeometryWithQuadrangle(quadrangle,sourceCoords,isSourceQuad); } + protected: + ConcreteP1P0Intersector& asLeaf() { return static_cast(*this); } + }; +} + +#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx b/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx new file mode 100644 index 000000000..c4750c88b --- /dev/null +++ b/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx @@ -0,0 +1,101 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +#ifndef __PLANARINTERSECTORP1P0_TXX__ +#define __PLANARINTERSECTORP1P0_TXX__ + +#include "PlanarIntersectorP1P0.hxx" +#include "InterpolationUtils.hxx" + +namespace INTERP_KERNEL +{ + template + PlanarIntersectorP1P0::PlanarIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double precision, double medianPlane, + bool doRotate, int orientation, int printLevel): + PlanarIntersector(meshT,meshS,dimCaracteristic,precision,medianPlane,doRotate,orientation,printLevel) + { + } + + template + int PlanarIntersectorP1P0::getNumberOfRowsOfResMatrix() const + { + return PlanarIntersector::_meshT.getNumberOfElements(); + } + + template + int PlanarIntersectorP1P0::getNumberOfColsOfResMatrix() const + { + return PlanarIntersector::_meshS.getNumberOfNodes(); + } + + /*! + * This methods split on the fly, into triangles in order to compute dual mesh of target cell (with icellT id in target mesh in C mode). + */ + template + void PlanarIntersectorP1P0::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) + { + double triangle[9]; + double quadrangle[12]; + std::vector targetCellCoords; + int orientation=1; + PlanarIntersector::getRealTargetCoordinates(OTT::indFC(icellT),targetCellCoords); + NormalizedCellType tT=PlanarIntersector::_meshT.getTypeOfElement(icellT); + bool isTargetQuad=CellModel::getCellModel(tT).isQuadratic(); + typename MyMatrix::value_type& resRow=res[icellT]; + for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) + { + int iS=*iter; + int nbNodesS=PlanarIntersector::_connIndexS[iS+1]-PlanarIntersector::_connIndexS[iS]; + const ConnType *startOfCellNodeConn=PlanarIntersector::_connectS+OTT::conn2C(PlanarIntersector::_connIndexS[iS]); + for(int nodeIdS=0;nodeIdS::coo2C(startOfCellNodeConn[nodeIdS]); + std::copy(PlanarIntersector::_coordsS+curNodeSInCmode*SPACEDIM, + PlanarIntersector::_coordsS+curNodeSInCmode*SPACEDIM+SPACEDIM,triangle); + for(int subTriS=1;subTriS<=nbNodesS-2;subTriS++) + { + std::copy(PlanarIntersector::_coordsS+OTT::coo2C(startOfCellNodeConn[(nodeIdS+subTriS)%nbNodesS])*SPACEDIM, + PlanarIntersector::_coordsS+OTT::coo2C(startOfCellNodeConn[(nodeIdS+subTriS)%nbNodesS])*SPACEDIM+SPACEDIM, + triangle+SPACEDIM); + std::copy(PlanarIntersector::_coordsS+OTT::coo2C(startOfCellNodeConn[(nodeIdS+subTriS+1)%nbNodesS])*SPACEDIM, + PlanarIntersector::_coordsS+OTT::coo2C(startOfCellNodeConn[(nodeIdS+subTriS+1)%nbNodesS])*SPACEDIM+SPACEDIM, + triangle+2*SPACEDIM); + fillDualCellOfTri(triangle,quadrangle); + std::vector targetCellCoordsTmp(targetCellCoords); + if(SPACEDIM==3) + orientation=PlanarIntersector::projectionThis(&targetCellCoordsTmp[0],quadrangle,targetCellCoords.size()/SPACEDIM,4); + double surf=orientation*intersectGeometryWithQuadrangle(quadrangle,targetCellCoordsTmp,isTargetQuad); + if (( surf > 0.0 && PlanarIntersector::_orientation >=0 ) || ( surf < 0.0 && PlanarIntersector::_orientation <=0 )) + { + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(curNodeSInCmode)); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),surf)); + else + { + double val=(*iterRes).second+surf; + resRow.erase(OTT::indFC(curNodeSInCmode)); + resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),val)); + } + } + } + } + } + } +} + +#endif diff --git a/src/INTERP_KERNEL/PolygonAlgorithms.hxx b/src/INTERP_KERNEL/PolygonAlgorithms.hxx new file mode 100644 index 000000000..31c4557a2 --- /dev/null +++ b/src/INTERP_KERNEL/PolygonAlgorithms.hxx @@ -0,0 +1,93 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __POLYGONALGORITHMS_HXX__ +#define __POLYGONALGORITHMS_HXX__ + +#include +#include +#include + +namespace INTERP_KERNEL +{ + template + class VertexLess + { + public: + bool operator()(const double * P_1, const double * P_2) + { + for(int idim=0; idim P_2[idim]) return false; + } + return false; + } + }; + + template + class PolygonAlgorithms + { + public: + PolygonAlgorithms(double epsilon, double precision); + std::deque intersectConvexPolygons(const double* P_1,const double* P_2, int N1, int N2); + + //Not yet tested + int convexDecomposition(const double * P, int N, std::vector< std::map< int,int > >& components, + std::vector< int >& components_index, const double epsilon); + private: + void defineIndices(int& i_loc, int& i_next, int& i_prev, + const double *& Poly1, const double *& Poly2, + int& j1, int& j1_glob, int& j2, int& j2_glob, + int& j3, int& j3_glob, int& j4, int& j4_glob, + int& i_glob, int& i_next_glob, int& i_prev_glob, + const double * P_1, const double * P_2, + int N1, int N2, int sign); + void addCrossings( const double * A, const double * B, int i , int i_next, + const double * C, const double * D, int j1, int j2, + const double * E, const double * F, int j3, int j4, + const double * G); + void addCrossing0(const double * A, const double * B, int i, int i_next, + const double * C, const double * D, int j, int j_next); + void addCrossing( double * ABCD, std::pair< int,int > i_i_next, std::pair< int,int > j_j_next); + void addNewVertex( int i, int i_glob, int i_next_glob, int i_prev_glob, const double * P); + bool intersectSegmentSegment(const double * A, const double * B, const double * C, + const double * D, const double * E, double * V); + + + //Not yet tested + void convexDecomposition(const double* P, int N, double* n, std::vector< int > subP, int NsubP, + std::vector< std::map< int,int > >& components, std::vector< int >& components_index, + int& Ncomp, int sign, const double epsilon); + void convHull(const double *P, int N, double * n, std::map< int,int >& subP, + std::map< int,int >& not_in_hull, int& NsubP, const double epsilon); + private: + std::deque< double > _Inter;/* vertices of the intersection P1^P2 */ + std::vector< std::pair< int,int > > _End_segments; /* segments containing inter final edges */ + /* status list of segments (ending point, starting point) intersected by the sweeping line */ + /* and a boolean true if the ending point is in the intersection */ + std::multimap< int, std::pair< int,bool> > _Status; + bool _is_in_intersection; + bool _terminus; + double _vdouble[DIM]; + double _epsilon; + double _precision; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/PolygonAlgorithms.txx b/src/INTERP_KERNEL/PolygonAlgorithms.txx new file mode 100644 index 000000000..74fe484ae --- /dev/null +++ b/src/INTERP_KERNEL/PolygonAlgorithms.txx @@ -0,0 +1,821 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __POLYGONALGORITHMS_TXX__ +#define __POLYGONALGORITHMS_TXX__ + +#include "PolygonAlgorithms.hxx" +#include "InterpolationUtils.hxx" +#include +#include +#include + +namespace INTERP_KERNEL +{ + template + PolygonAlgorithms::PolygonAlgorithms(double epsilon, double precision)//: (0) + { + _is_in_intersection = false; + _epsilon = epsilon; + _precision = precision; + } + /*************************************************************/ + /* Computes the 3D intersection between two COPLANAR */ + /* Segments [A,B] and [C,D], stores the result in V. */ + /* If A belongs to [CD] then the vertex E (preceeding A) */ + /* is used to decide if the crossing is real. If A coincides */ + /* with C or D, a special treatment is performed */ + /*************************************************************/ + template + bool PolygonAlgorithms::intersectSegmentSegment(const double * A, const double * B, const double * C, + const double * D, const double * E, double * V) + { + double AB[DIM], DC[DIM], AC[DIM], det, t1, t2, inv_det; + + /******* Initialisation of the linear system t1*AB+t2*DC=AC ***********/ + for(int idim=0;idim_epsilon) + { + inv_det = 1/det; + t1 = determinant(AC,DC)*inv_det;//solves the linear system t1*AB+t2*DC=AC + t2 = determinant(AB,AC)*inv_det;//solves the linear system t1*AB+t2*DC=AC + } + else + { + switch(DIM) + { + case 2: + { + if(distance2(A,D)<_epsilon) + crossprod(A,C,E,_vdouble);//store the crossprod between vectors AC and AE (E=vertex preceding A) + return false;//case of paralell segments + } + case 3://beware AB and CD may belong to a vertical plane + det = determinant(&AB[1],&DC[1]);//determinant of the last two coefficients + if(fabs(det) > _epsilon) + { + inv_det = 1/det; + t1=(AC[1]*DC[2]-AC[2]*DC[1])*inv_det; + t2=(AB[1]*AC[2]-AB[2]*AC[1])*inv_det; + } + else //beware AB and CD may belong to a plane y = constant + { + det = AB[0]*DC[2]-AB[2]*DC[0]; + if(fabs(det) > _epsilon) + { + inv_det = 1/det; + t1=(AC[0]*DC[2]-AC[2]*DC[0])*inv_det; + t2=(AB[0]*AC[2]-AB[2]*AC[0])*inv_det; + } + else + { + if(distance2(A,D)<_epsilon) + crossprod(A,C,E,_vdouble);//store the crossprod between vectors AC and AE (E=vertex preceding A) + return false;//case of paralell segments + } + } + } + } + + if(t1>_precision && t1<1-_precision) + { + if( t2>_precision && t2<1-_precision) + { + for(int idim=0;idim_precision && t2<1-_precision)//vertex on an edge + { + double V12[DIM]; + double V34[DIM]; + crossprod(A,D,B,V12); + crossprod(A,D,E,V34); + double same_side =dotprod(V12, V34); + if( same_side < -_epsilon ) // <= epsilon or 0 ?//crossing + { + for(int idim=0;idim _epsilon ) _terminus= !_is_in_intersection;//reflexion + else //separation of overlaping edges + { + if(_Inter.empty() ) _terminus=true; + else if(!_is_in_intersection) + { + for(int idim=0;idim(A,C,E,_vdouble);//store the angle between vectors AC and AE (E=vertex preceding A) + else if(fabs(t2) <= _precision)//vertex on a vertex (A=C), second run + { + double Vdoublebis[DIM]; + //crossprod(A,C,E,_vdouble); + crossprod(A,B,D,Vdoublebis); + double in_between =dotprod(Vdoublebis,_vdouble); + if(in_between>_epsilon)//crossing + { + for(int idim=0;idim(Vdoublebis,Vdoublebis) > _epsilon) + //ie _vdouble=0, separation of overlaping edges at a double point + { + //crossprod(A,E,B,_vdouble); + if(dotprod(_vdouble,Vdoublebis) >=_epsilon )//crossing + { + if(_Inter.empty()) _terminus=true; + else if(!_is_in_intersection) + { + for(int idim=0;idim + inline void PolygonAlgorithms::addNewVertex( int i, int i_glob, int i_next_glob, int i_prev_glob, + const double * P) + { + /* Question:Should we add vertex i to the front or back ? */ + if( _End_segments[1].second == i_glob) + { + for(int idim=0;idim-1;idim--) _Inter.push_front(P[DIM*i+idim]); + _End_segments[0] = std::make_pair(i_glob, i_next_glob); + } + } + + /************************************************************/ + /* adds a crossing between two segments starting at i and j */ + /* to the double ended list inter in the correct order */ + /* according to endsegments, updates _End_segments */ + /************************************************************/ + template + inline void PolygonAlgorithms::addCrossing( double * ABCD, std::pair< int,int > i_i_next, + std::pair< int,int > j_j_next) + { + if(!_Inter.empty() ) + { + if(_End_segments[0] ==i_i_next) + { + for(int idim=DIM-1;idim>=0;idim--) _Inter.push_front(ABCD[idim]); + _terminus= (_End_segments[1]== j_j_next); + _End_segments[0] = j_j_next; + } + else + { + if( _End_segments[0]== j_j_next) + { + for(int idim=DIM-1;idim>=0;idim--) _Inter.push_front(ABCD[idim]); + _terminus= (_End_segments[1]== i_i_next); + _End_segments[0] = i_i_next; + } + else + { + for(int idim=0;idim + void PolygonAlgorithms::addCrossing0(const double * A, const double * B, int i, int i_next, + const double * C, const double * D, int j, int j_next) + { + double ABCD[DIM]; + if(intersectSegmentSegment(A,B,C,D,ABCD, ABCD)) + //fifth and sixth arguments are useless here + { + /* Updating _End_segments */ + std::pair< int,int > i_i_next = std::make_pair(i, i_next); + std::pair< int,int > j_j_next = std::make_pair(j, j_next); + if( _End_segments[0] == i_i_next) + { + for(int idim=DIM-1;idim>-1;idim--) _Inter.push_front(ABCD[idim]); + _End_segments[0] = j_j_next; + } + else + { + for(int idim=0;idim >::iterator mi =_Status.find(j_next); + ((* mi).second).second= !((* mi).second).second; + } + else _Status.insert(std::make_pair(i_next,std::make_pair(i,true))); + } + + /*******************************************************/ + /* adds the possible crossings between segments [A,B] (with end-point global indices i and i_next) */ + /*and segments [C,D] and [E,F] to the list inter and updates _End_segments */ + /* In cases of ambiguity, the vertex G is used to decide wether the crossing should be accepted */ + /*******************************************************/ + template + inline void PolygonAlgorithms::addCrossings( const double * A, const double * B, int i , int i_next, + const double * C, const double * D, int j1, int j2, + const double * E, const double * F, int j3, int j4, + const double * G) + { + double ABCD[DIM]; + double ABEF[DIM]; + std::multimap< int, std::pair< int,bool> >::iterator mi; + + if(intersectSegmentSegment(A,B,C,D,G,ABCD)) + { + if(intersectSegmentSegment(A,B,E,F,G,ABEF)) + { + VertexLess vl; + if (vl(ABCD,ABEF)) + { + addCrossing(ABCD, std::make_pair(i, i_next), std::make_pair(j1, j2)); + addCrossing(ABEF, std::make_pair(i, i_next), std::make_pair(j3, j4)); + } + else + { + addCrossing(ABEF, std::make_pair(i, i_next), std::make_pair(j3, j4)); + addCrossing(ABCD, std::make_pair(i, i_next), std::make_pair(j1, j2)); + } + _Status.insert(std::make_pair(i_next,std::make_pair(i, _is_in_intersection))); + mi=_Status.find(j2); + ((* mi).second).second= !((* mi).second).second; + mi=_Status.find(j4); + ((* mi).second).second= !((* mi).second).second; + } + else + { + addCrossing(ABCD, std::make_pair( i, i_next), std::make_pair(j1,j2)); + _Status.insert(std::make_pair(i_next,std::make_pair(i, !_is_in_intersection))); + mi=_Status.find(j2); + ((* mi).second).second= !((* mi).second).second; + } + } + else + { + if(intersectSegmentSegment(A,B,E,F,G, ABEF)) + { + addCrossing(ABEF, std::make_pair( i, i_next), std::make_pair( j3, j4)); + _Status.insert(std::make_pair(i_next,std::make_pair(i, !_is_in_intersection))); + mi=_Status.find(j4); + ((* mi).second).second= !((* mi).second).second; + } + else _Status.insert(std::make_pair(i_next,std::make_pair(i, _is_in_intersection))); + } + } + + + /* define various indices required in the function intersect_conv_polygon */ + /* vertices from the both polygons are supposed to be present in the status */ + template + inline void PolygonAlgorithms::defineIndices(int& i_loc, int& i_next, int& i_prev, + const double *& Poly1, const double *& Poly2, + int& j1, int& j1_glob, int& j2, int& j2_glob, + int& j3, int& j3_glob, int& j4, int& j4_glob, + int& i_glob, int& i_next_glob, int& i_prev_glob, + const double * P_1, const double * P_2, + int N1, int N2, int sign) + { + int N0, shift; + if(i_glob < N1) + { + N0 = N1; + shift = 0; + Poly1 = P_1; + Poly2 = P_2; + + std::multimap< int, std::pair< int,bool> >::reverse_iterator mi1=_Status.rbegin(); + j1_glob=((*mi1).second).first; + j1=j1_glob-N1; + j2_glob=(*mi1).first; + j2=j2_glob-N1; + mi1++; + j3_glob=((*mi1).second).first; + j3=j3_glob-N1; + j4_glob=(*mi1).first; + j4=j4_glob-N1; + } + else + { + N0 = N2; + shift = N1; + Poly1 = P_2; + Poly2 = P_1; + + std::multimap< int, std::pair< int,bool> >::iterator mi2= _Status.begin(); + j1_glob=((*mi2).second).first; + j1=j1_glob; + j2_glob=(*mi2).first; + j2=j2_glob; + mi2++; + j3_glob=((*mi2).second).first; + j3=j3_glob; + j4_glob=(*mi2).first; + j4=j4_glob; + } + i_loc = i_glob-shift; + i_next = (i_next_glob-shift+N0)%N0;//end-point of segment starting at i + i_prev = (i_prev_glob-shift+N0)%N0; + i_next_glob = i_next+shift; + i_prev_glob = i_prev+shift; + //warning: sign is either 1 or -1; + //To do: test and remove from Convex_intersecor.cxx + // while(distance2(&Poly1[DIM*i_loc],&Poly1[DIM*i_next])< _epsilon && i_next != i_loc) + // i_next =(i_next+sign+N0)%N0; + // while(distance2(&Poly1[DIM*i_loc],&Poly1[DIM*i_prev])< _epsilon && i_prev != i_loc) + // i_prev =(i_prev+sign+N0)%N0; + } + /*******************************************************/ + /* computes the vertices of the intersection of two COPLANAR */ + /* simple (no dble points)convex polygons using line sweep algorithm */ + /* P1 and P2 contain the 3D coordinates of the successive vertices */ + /*******************************************************/ + template + std::deque< double > PolygonAlgorithms::intersectConvexPolygons(const double* P_1,const double* P_2, + int N1, int N2) + { + int i_loc, i_glob, j1, j1_glob, j2,j2_glob, j3, j3_glob, j4,j4_glob, + i_prev, i_prev_glob, i_next, i_next_glob, nb_prev, sign, idim; + const double * Poly1, * Poly2; + bool four_neighbours=false; + _terminus = N1 < 3 || N2<3; + + /* list of future events ordered according to their coordinates (x,y,z) (lexicographical order) */ + std::multimap< const double *, int, VertexLess > mmap_events; + typename std::list< std::pair< const double *, int > >::iterator mi1,mi2; + + std::multimap< int, std::pair< int,bool> >::iterator mi; + + /********** Initalisation of events with P1 and P2 vertices ************/ + for(i_loc=0;i_loc > events(mmap_events.begin(),mmap_events.end()); + + if(!_terminus) + { + /******** Treatment of the first vertex ********/ + mi1=events.begin(); + i_glob = (* mi1).second; + bool which_start = i_glob < N1; + if(i_glob < N1){ i_next_glob = (i_glob +1)%N1; i_prev_glob = (i_glob -1+N1)%N1;} + else{ i_next_glob = (i_glob-N1+1)%N2 + N1;i_prev_glob = (i_glob-N1-1+N2)%N2 + N1;} + _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob, false))); + _Status.insert(std::make_pair(i_prev_glob,std::make_pair(i_glob, false))); + mi1++; + //std::cout<< "nb_prev= "<< 0 << " i_glob= " << i_glob << std::endl; + + /******* Loop until the second polygon is reached *******/ + while( !four_neighbours) + { + i_glob=(* mi1).second;//global index of vertex i + nb_prev = _Status.count(i_glob);//counts the number of segments ending at i + + //std::cout<< "nb_prev= "<< nb_prev << " i_glob= " << i_glob << std::endl; + switch (nb_prev) + { + case 1 : + mi=_Status.find(i_glob);// pointer to the segment ending at i + i_prev_glob = ((*mi).second).first;//starting point of the segment ending at i + i_next= (i_prev_glob - i_glob > 0) == (abs(i_prev_glob - i_glob) == 1) ? i_glob - 1 : i_glob + 1; + if(i_glob < N1) i_next_glob = (i_next +N1)%N1; + else i_next_glob = (i_next-N1+N2)%N2 + N1; + _Status.erase(mi); + _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob, false))); + mi1++; + break; + case 2 : + return _Inter; + case 0 : + if( (i_glob < N1) != which_start) + { + mi2=mi1; + mi2++; + /* detection of double points */ + if(distance2((* mi1).first, (*mi2).first) > _epsilon) + four_neighbours = true; + else /* Rare pothological case: */ + { + const std::pair< const double *, int > next_pt= *mi2; + events.erase(mi2); + mi1=events.insert(mi1,next_pt); + } + } + break; + default: + throw Exception("intersectConvexPolygon: sequence of nodes does not describe a simple polygon (1)"); + } + } + /******** Loop until a terminal point or crossing is reached ************/ + while( !_terminus) + { + //std::cout<< "nb_prev= "<< nb_prev<< " nb_inter= " << _Inter.size()/DIM << std::endl; + switch (nb_prev) + { + case 1 : + mi=_Status.find(i_glob);// pointer to the segment ending at i + i_prev_glob = ((*mi).second).first;//starting point of the segment ending at i + sign = (i_prev_glob - i_glob > 0) == (abs(i_prev_glob - i_glob) == 1) ? - 1 : + 1; + i_next_glob = i_glob+sign; + _is_in_intersection = ((*mi).second).second;//boolean that tells if i is in the intersection + _Status.erase(mi); + defineIndices(i_loc,i_next,i_prev, Poly1,Poly2, + j1,j1_glob,j2,j2_glob,j3,j3_glob,j4,j4_glob, + i_glob,i_next_glob,i_prev_glob, P_1,P_2, N1, N2, sign); + if( _is_in_intersection ) addNewVertex(i_loc, i_glob, i_next_glob, i_prev_glob, Poly1); + addCrossings(&Poly1[DIM*i_loc], &Poly1[DIM*i_next], i_glob, i_next_glob, + &Poly2[DIM*j1] , &Poly2[DIM*j2] , j1_glob,j2_glob, + &Poly2[DIM*j3] , &Poly2[DIM*j4] , j3_glob,j4_glob, &Poly1[DIM*i_prev]); + break; + case 2 : + if(!_Inter.empty()) + if(i_glob < N1) for(idim=0;idim(&Poly1[DIM*i_loc],&Poly2[DIM*j1],&Poly2[DIM*j2], + &Poly2[DIM*j3], &Poly2[DIM*j4],V12, V34); + _is_in_intersection=( inside < _epsilon ); // <= epsilon or 0 ? + + if(fabs(inside) > _epsilon)//vertex clearly inside or outside + { + //std::cout<<"coucou1" << std::endl; + if( _is_in_intersection) + { + for(int idim=0;idim(V34,V34) > _epsilon)//vertex i on edge (j1,j2), not on (j3,j4) + { + crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j2], &Poly1[DIM*i_next],Vnext); + crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j2], &Poly1[DIM*i_prev],Vprev); + is_inside_next= (dotprod(Vnext,V34)<0); + is_inside_prev= (dotprod(Vprev,V34)<0); + + if(!(is_inside_next || is_inside_prev)) return std::deque< double >(); + + if(is_inside_next) + { + _End_segments.push_back(std::make_pair(i_glob,i_next_glob)); + addCrossing0(&Poly1[DIM*i_loc], &Poly1[DIM*i_next], i_glob, i_next_glob, + &Poly2[DIM*j3] , &Poly2[DIM*j4] , j3_glob,j4_glob); + } + else + { + _End_segments.push_back(std::make_pair(j1_glob,j2_glob)); + _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob, false))); + mi=_Status.find(j2_glob); + ((* mi).second).second= !((* mi).second).second; + } + if(is_inside_prev) + { + _End_segments.push_back(std::make_pair(i_glob,i_prev_glob)); + addCrossing0(&Poly1[DIM*i_loc], &Poly1[DIM*i_prev], i_glob, i_prev_glob, + &Poly2[DIM*j3] , &Poly2[DIM*j4] , j3_glob,j4_glob); + } + else + { + _End_segments.push_back(std::make_pair(j1_glob,j2_glob)); + _Status.insert(std::make_pair(i_prev_glob,std::make_pair(i_glob, false))); + mi=_Status.find(j2_glob); + ((* mi).second).second= !((* mi).second).second; + } + } + else if(dotprod(V12,V12) > _epsilon)//vertex i on a edge (j3,j4), not on (j1,j2) + { + crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j4], &Poly1[DIM*i_next],Vnext); + crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j4], &Poly1[DIM*i_prev],Vprev); + is_inside_next= dotprod(Vnext,V12)<0; + is_inside_prev= dotprod(Vprev,V12)<0; + + if(!(is_inside_next || is_inside_prev)) return std::deque< double >(); + + if(is_inside_next) + { + _End_segments.push_back(std::make_pair(i_glob,i_next_glob)); + addCrossing0(&Poly1[DIM*i_loc], &Poly1[DIM*i_next], i_glob, i_next_glob, + &Poly2[DIM*j1] , &Poly2[DIM*j2] , j1_glob,j2_glob); + } + else + { + _End_segments.push_back(std::make_pair(j3_glob,j4_glob)); + _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob, false))); + mi=_Status.find(j4_glob); + ((* mi).second).second= ! ((* mi).second).second; + } + if(is_inside_prev) + { + _End_segments.push_back(std::make_pair(i_glob,i_prev_glob)); + addCrossing0(&Poly1[DIM*i_loc], &Poly1[DIM*i_prev], i_glob, i_prev_glob, + &Poly2[DIM*j1] , &Poly2[DIM*j2] , j1_glob,j2_glob); + } + else + { + _End_segments.push_back(std::make_pair(j3_glob,j4_glob)); + _Status.insert(std::make_pair(i_prev_glob,std::make_pair(i_glob, false))); + mi=_Status.find(j4_glob); + ((* mi).second).second= !((* mi).second).second; + } + } + else //vertices i, j1 and j3 share the same coordinates + { + crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j2], &Poly1[DIM*i_next],Vnext); + crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j2], &Poly1[DIM*i_prev],Vprev); + crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j4], &Poly1[DIM*i_next],V12); + crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j4], &Poly1[DIM*i_prev],V34); + + double inside_next= dotprod(Vnext,V12); + double inside_prev= dotprod(Vprev,V34); + double inside_j2 = dotprod(Vnext,Vprev); + double inside_j4 = dotprod(V12,V34); + + std::map > which_is_inside; + which_is_inside[inside_next] = std::make_pair(i_glob,i_next_glob); + which_is_inside[inside_prev] = std::make_pair(i_glob,i_prev_glob); + which_is_inside[inside_j2] = std::make_pair(j1_glob,j2_glob); + which_is_inside[inside_j4] = std::make_pair(j3_glob,j4_glob); + + std::map >::iterator min = which_is_inside.begin(); + std::map >::iterator minext = min; + minext++; + std::map >::reverse_iterator max = which_is_inside.rbegin(); + std::multimap< int, std::pair< int,bool> >::iterator j2_in_status = _Status.find(((*min).second).second); + std::multimap< int, std::pair< int,bool> >::iterator j4_in_status = _Status.find(((*minext).second).second); + + if((*min).first < -_epsilon) //there is someone clearly inside + { + _End_segments.push_back( (*min).second ); + _End_segments.push_back((* minext).second); + if(j2_in_status != _Status.end()) + ((*j2_in_status).second).second = ! ((*j2_in_status).second).second; + if(j4_in_status != _Status.end()) + ((*j4_in_status).second).second = ! ((*j4_in_status).second).second; + is_inside_next = ((*min).second).second == i_next_glob || ((*minext).second).second == i_next_glob; + is_inside_prev = ((*min).second).second == i_prev_glob || ((*minext).second).second == i_prev_glob; + } + else + if(fabs((*min).first) <= _epsilon) //nobody is clearly inside but two segments are superposed + { + if(fabs((*max).first) > _epsilon) + return std::deque< double >(); + else //all four segments are superposed + { + _End_segments.push_back(std::make_pair(i_glob,i_next_glob)); + _End_segments.push_back(std::make_pair(i_glob,i_prev_glob)); + is_inside_next= true; + is_inside_prev= true; + } + } + else //there is nobody inside + return std::deque< double >(); + + _Status.insert(std::make_pair(i_prev_glob,std::make_pair(i_glob,is_inside_prev))); + _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob,is_inside_next))); + } + } + } + break; + default: + std::cout << "Problem: nbprev= " << nb_prev << " ; i_glob = " << i_glob << std::endl; + throw Exception("intersectConvexPolygon: sequence of nodes does not describe a simple polygon (2)"); + } + mi1++; + i_glob=(* mi1).second;//global index of vertex i + nb_prev = _Status.count(i_glob); + } + } + return _Inter; + } + + /**************************************************************************/ + /* computes the convex hull of a polygon subP which is a sub polygon of P */ + /* P is the array of coordinates, subP is a map containing initially the indices of a subpolygon of P */ + /* in the end, subP contains only the elements belonging to the convex hull, and not_in_hull the others */ + /**************************************************************************/ + template + inline void PolygonAlgorithms::convHull(const double *P, int N, double * normal, + std::map< int,int >& subP, std::map< int,int >& not_in_hull, + int& NsubP, const double epsilon) + { + if(NsubP>3) + { + std::map< int,int >::iterator mi_prev = subP.begin(); + std::map< int,int >::iterator mi = mi_prev; + mi++; + std::map< int,int >::iterator mi_next = mi; + mi_next++; + double directframe=0.; + + /* Check if the polygon subP is positively oriented */ + std::map< int,int >::iterator mi1=mi; + while(mi1 != subP.end() && distance2(&P[DIM*(*subP.begin()).second],&P[DIM*(*mi1).second])< epsilon) + mi1++; + std::map< int,int >::iterator mi2=mi1; + while(mi2 != subP.end() && fabs(directframe)(&P[DIM* (*mi1).second], + &P[DIM* (*subP.begin()).second], + &P[DIM* (*mi2).second], normal); + mi2++; + } + if(directframe < 0) for(int idim=0; idim< DIM; idim++) normal[idim] *= -1; + + /* Core of the algorithm */ + while(mi_next != subP.end()) + { + directframe = direct_frame(&P[DIM* (*mi).second], + &P[DIM* (*mi_prev).second], + &P[DIM* (*mi_next).second], normal); + if(directframe > -epsilon){ + mi ++; + mi_prev++; + mi_next++; + } + else + { + not_in_hull.insert(*mi); + subP.erase(mi); + NsubP--; + mi--; + } + } + directframe = direct_frame(&P[DIM*(*mi).second], + &P[DIM*(*mi_prev).second], + &P[DIM*(*subP.begin()).second], normal); + if(directframe < -epsilon) + { + not_in_hull.insert(*mi); + subP.erase(mi); + NsubP--; + } + } + } + + template + void PolygonAlgorithms::convexDecomposition(const double * P, int N, double *normal, std::vector< int > subP, int NsubP, + std::vector< std::map< int,int > >& components, std::vector< int >& components_index, + int& Ncomp, int sign, const double epsilon) + { + int i; + std::map< int, int > hull; + std::map< int, int > not_in_hull; + std::map< int, int >::iterator mi, mj; + std::vector< int > reflex_region; + int Nreflex; + int i_xmax=0; + const double * xmax=&P[DIM*subP[0]]; + /* checking an extremal point of subP */ + for(i=0; i xmax) + { + i_xmax=i; + xmax=&P[DIM*subP[i]]; + } + } + /* renumbering of SubP elements for the convex hull*/ + for(i=0; i + int PolygonAlgorithms::convexDecomposition(const double * P, int N, std::vector< std::map< int,int > >& components, + std::vector< int >& components_index, const double epsilon) + { + int Ncomp=0; + std::vector< int > subP(N); + double normal[3]={0,0,0}; + + for(int i = 0; i(&P[0],&P[i1])< epsilon) i1++; + int i2=i1+1; + while(i2(normal,normal))(&P[i1], &P[0], &P[i2],normal); + i2++; + } + + convexDecomposition(P, N, normal, subP, N, components, components_index, Ncomp, 1, epsilon); + return Ncomp; + } +} + +#endif diff --git a/src/INTERP_KERNEL/PolyhedronIntersector.hxx b/src/INTERP_KERNEL/PolyhedronIntersector.hxx new file mode 100644 index 000000000..4cf4fb4ee --- /dev/null +++ b/src/INTERP_KERNEL/PolyhedronIntersector.hxx @@ -0,0 +1,63 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __POLYHEDRONINTERSECTOR_HXX__ +#define __POLYHEDRONINTERSECTOR_HXX__ + +#include "Intersector3DP0P0.hxx" +#include "SplitterTetra.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace INTERP_KERNEL +{ + + + /** + * \brief Class responsible for calculating intersection between a hexahedron target element and + * the source elements. + * + */ + template + class PolyhedronIntersector : public Intersector3DP0P0 + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + + PolyhedronIntersector(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy = GENERAL_24); + + ~PolyhedronIntersector(); + + void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); + + private: + void releaseArrays(); + private: + /// pointers to the SplitterTetra objects representing the tetrahedra + /// that result from the splitting of the hexahedron target cell + std::vector< SplitterTetra* > _tetra; + + SplitterTetra2 _split; + + }; +} + +#endif diff --git a/src/INTERP_KERNEL/PolyhedronIntersector.txx b/src/INTERP_KERNEL/PolyhedronIntersector.txx new file mode 100644 index 000000000..1d58f7a58 --- /dev/null +++ b/src/INTERP_KERNEL/PolyhedronIntersector.txx @@ -0,0 +1,94 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __POLYHEDRONINTERSECTOR_TXX__ +#define __POLYHEDRONINTERSECTOR_TXX__ + +#include "PolyhedronIntersector.hxx" +#include "Intersector3DP0P0.txx" +#include "MeshUtils.hxx" + +#include "SplitterTetra.txx" + +namespace INTERP_KERNEL +{ + + /** + * Constructor creating object from target cell global number + * The constructor first calculates the necessary nodes, + * (depending on the splitting policy) and then splits the hexahedron into + * tetrahedra, placing these in the internal vector _tetra. + * + * @param targetMesh mesh containing the target elements + * @param srcMesh mesh containing the source elements + * @param policy splitting policy to be used + */ + template + PolyhedronIntersector::PolyhedronIntersector(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy):Intersector3DP0P0(targetMesh,srcMesh),_split(targetMesh,srcMesh,policy) + { + } + + /** + * Destructor. + * Liberates the SplitterTetra objects and potential sub-node points that have been allocated. + * + */ + template + PolyhedronIntersector::~PolyhedronIntersector() + { + releaseArrays(); + } + + template + void PolyhedronIntersector::releaseArrays() + { + for(typename std::vector< SplitterTetra* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) + delete *iter; + _split.releaseArrays(); + _tetra.clear(); + } + + /** + * Calculates the volume of intersection of an element in the source mesh and the target element + * represented by the object. + * The calculation is performed by calling the corresponding method for + * each SplitterTetra object created by the splitting. + * + * @param targetCell in C mode. + * @param srcCells in C mode. + * + */ + template + void PolyhedronIntersector::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) + { + int nbOfNodesT=Intersector3D::_target_mesh.getNumberOfNodesOfElement(OTT::indFC(targetCell)); + releaseArrays(); + _split.splitTargetCell(targetCell,nbOfNodesT,_tetra); + for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) + { + double volume = 0.; + for(typename std::vector*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) + volume += (*iter)->intersectSourceCell(*iterCellS); + if(volume!=0.) + res[targetCell].insert(std::make_pair(OTT::indFC(*iterCellS), volume)); + } + _split.releaseArrays(); + } +} + +#endif diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.hxx b/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.hxx new file mode 100644 index 000000000..d025938d4 --- /dev/null +++ b/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.hxx @@ -0,0 +1,63 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __POLYHEDRONINTERSECTORP0P1_HXX__ +#define __POLYHEDRONINTERSECTORP0P1_HXX__ + +#include "Intersector3DP0P1.hxx" +#include "SplitterTetra.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace INTERP_KERNEL +{ + + + /** + * \brief Class responsible for calculating intersection between a hexahedron target element and + * the source elements. + * + */ + template + class PolyhedronIntersectorP0P1 : public Intersector3DP0P1 + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + + PolyhedronIntersectorP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy = GENERAL_24); + + ~PolyhedronIntersectorP0P1(); + + void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); + + private: + void releaseArrays(); + private: + /// pointers to the SplitterTetra objects representing the tetrahedra + /// that result from the splitting of the hexahedron target cell + std::vector< SplitterTetra* > _tetra; + + SplitterTetra2 _split; + + }; +} + +#endif diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.txx b/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.txx new file mode 100644 index 000000000..75de8e4c4 --- /dev/null +++ b/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.txx @@ -0,0 +1,112 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __POLYHEDRONINTERSECTORP0P1_TXX__ +#define __POLYHEDRONINTERSECTORP0P1_TXX__ + +#include "PolyhedronIntersectorP0P1.hxx" +#include "Intersector3DP0P1.txx" +#include "MeshUtils.hxx" + +#include "SplitterTetra.txx" + +namespace INTERP_KERNEL +{ + + /** + * Constructor creating object from target cell global number + * The constructor first calculates the necessary nodes, + * (depending on the splitting policy) and then splits the hexahedron into + * tetrahedra, placing these in the internal vector _tetra. + * + * @param targetMesh mesh containing the target elements + * @param srcMesh mesh containing the source elements + * @param policy splitting policy to be used + */ + template + PolyhedronIntersectorP0P1::PolyhedronIntersectorP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy):Intersector3DP0P1(targetMesh,srcMesh),_split(targetMesh,srcMesh,policy) + { + } + + /** + * Destructor. + * Liberates the SplitterTetra objects and potential sub-node points that have been allocated. + * + */ + template + PolyhedronIntersectorP0P1::~PolyhedronIntersectorP0P1() + { + releaseArrays(); + } + + template + void PolyhedronIntersectorP0P1::releaseArrays() + { + for(typename std::vector< SplitterTetra* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) + delete *iter; + _split.releaseArrays(); + _tetra.clear(); + } + + /** + * Calculates the volume of intersection of an element in the source mesh and the target element + * represented by the object. + * The calculation is performed by calling the corresponding method for + * each SplitterTetra object created by the splitting. + * + * @param targetCell in C mode. + * @param srcCells in C mode. + * + */ + template + void PolyhedronIntersectorP0P1::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) + { + SplitterTetra* subTetras[24]; + int nbOfNodesT=Intersector3D::_target_mesh.getNumberOfNodesOfElement(OTT::indFC(targetCell)); + releaseArrays(); + _split.splitTargetCell(targetCell,nbOfNodesT,_tetra); + for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) + { + for(typename std::vector*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) + { + (*iter)->splitIntoDualCells(subTetras); + for(int i=0;i<24;i++) + { + SplitterTetra *tmp=subTetras[i]; + double volume = tmp->intersectSourceCell(*iterCellS); + if(volume!=0.) + { + typename MyMatrix::value_type& resRow=res[tmp->getId(0)]; + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(*iterCellS)); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(OTT::indFC(*iterCellS),volume)); + else + { + double val=(*iterRes).second+volume; + resRow.erase(OTT::indFC(*iterCellS)); + resRow.insert(std::make_pair(OTT::indFC(*iterCellS),val)); + } + } + delete tmp; + } + } + } + } +} + +#endif diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.hxx b/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.hxx new file mode 100644 index 000000000..bf087314c --- /dev/null +++ b/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.hxx @@ -0,0 +1,63 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __POLYHEDRONINTERSECTORP1P0_HXX__ +#define __POLYHEDRONINTERSECTORP1P0_HXX__ + +#include "Intersector3DP1P0.hxx" +#include "SplitterTetra.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace INTERP_KERNEL +{ + + + /** + * \brief Class responsible for calculating intersection between a hexahedron target element and + * the source elements. + * + */ + template + class PolyhedronIntersectorP1P0 : public Intersector3DP1P0 + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + + PolyhedronIntersectorP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy = GENERAL_24); + + ~PolyhedronIntersectorP1P0(); + + void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); + + private: + void releaseArrays(); + private: + /// pointers to the SplitterTetra objects representing the tetrahedra + /// that result from the splitting of the hexahedron target cell + std::vector< SplitterTetra* > _tetra; + + SplitterTetra2 _split; + + }; +} + +#endif diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx b/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx new file mode 100644 index 000000000..486706873 --- /dev/null +++ b/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx @@ -0,0 +1,116 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __POLYHEDRONINTERSECTORP1P0_TXX__ +#define __POLYHEDRONINTERSECTORP1P0_TXX__ + +#include "PolyhedronIntersectorP1P0.hxx" +#include "Intersector3DP1P0.txx" +#include "MeshUtils.hxx" + +#include "SplitterTetra.txx" + +namespace INTERP_KERNEL +{ + + /** + * Constructor creating object from target cell global number + * The constructor first calculates the necessary nodes, + * (depending on the splitting policy) and then splits the hexahedron into + * tetrahedra, placing these in the internal vector _tetra. + * + * @param targetMesh mesh containing the target elements + * @param srcMesh mesh containing the source elements + * @param policy splitting policy to be used + * + * WARNING : in _split attribute, sourceMesh and targetMesh are switched in order to fit intersectCells feature. + */ + template + PolyhedronIntersectorP1P0::PolyhedronIntersectorP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy):Intersector3DP1P0(targetMesh,srcMesh),_split(srcMesh,targetMesh,policy) + { + } + + /** + * Destructor. + * Liberates the SplitterTetra objects and potential sub-node points that have been allocated. + * + */ + template + PolyhedronIntersectorP1P0::~PolyhedronIntersectorP1P0() + { + releaseArrays(); + } + + template + void PolyhedronIntersectorP1P0::releaseArrays() + { + for(typename std::vector< SplitterTetra* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) + delete *iter; + _split.releaseArrays(); + _tetra.clear(); + } + + /** + * Calculates the volume of intersection of an element in the source mesh and the target element + * represented by the object. + * The calculation is performed by calling the corresponding method for + * each SplitterTetra object created by the splitting. + * + * @param targetCell in C mode. + * @param srcCells in C mode. + * + * WARNING : for all methods on _split object source and target are switched ! + */ + template + void PolyhedronIntersectorP1P0::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) + { + SplitterTetra* subTetras[24]; + typename MyMatrix::value_type& resRow=res[targetCell]; + for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) + { + releaseArrays(); + int nbOfNodesS=Intersector3D::_src_mesh.getNumberOfNodesOfElement(OTT::indFC(*iterCellS)); + _split.splitTargetCell(*iterCellS,nbOfNodesS,_tetra); + for(typename std::vector*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) + { + (*iter)->splitIntoDualCells(subTetras); + for(int i=0;i<24;i++) + { + SplitterTetra *tmp=subTetras[i]; + double volume = tmp->intersectSourceCell(targetCell); + ConnType sourceNode=tmp->getId(0); + if(volume!=0.) + { + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(sourceNode)); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(OTT::indFC(sourceNode),volume)); + else + { + double val=(*iterRes).second+volume; + resRow.erase(OTT::indFC(*iterCellS)); + resRow.insert(std::make_pair(OTT::indFC(sourceNode),val)); + } + } + delete tmp; + } + } + } + } +} + +#endif diff --git a/src/INTERP_KERNEL/RegionNode.hxx b/src/INTERP_KERNEL/RegionNode.hxx new file mode 100644 index 000000000..caae98353 --- /dev/null +++ b/src/INTERP_KERNEL/RegionNode.hxx @@ -0,0 +1,67 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __REGIONNODE_HXX__ +#define __REGIONNODE_HXX__ + +#include "MeshRegion.hxx" + +namespace INTERP_KERNEL +{ + + /** + * \brief Class containing a tuplet of a source region and a target region. + * This is used as the object to put on the stack in the depth-first search + * in the bounding-box filtering process. + */ + template + class RegionNode + { + public: + + RegionNode() { } + + ~RegionNode() { } + + /** + * Accessor to source region + * + * @return reference to source region + */ + MeshRegion& getSrcRegion() { return _srcRegion; } + + /** + * Accessor to target region + * + * @return reference to target region + */ + MeshRegion& getTargetRegion() { return _targetRegion; } + + private: + + /// source region + MeshRegion _srcRegion; + + /// target region + MeshRegion _targetRegion; + + }; + +} + +#endif diff --git a/src/INTERP_KERNEL/SplitterTetra.hxx b/src/INTERP_KERNEL/SplitterTetra.hxx new file mode 100644 index 000000000..a5bec7efb --- /dev/null +++ b/src/INTERP_KERNEL/SplitterTetra.hxx @@ -0,0 +1,406 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __SPLITTERTETRA_HXX__ +#define __SPLITTERTETRA_HXX__ + +#include "TransformedTriangle.hxx" +#include "TetraAffineTransform.hxx" + +#include +#include +#include +#include +#ifdef WIN32 +# include +#else +# include +#endif + +#ifndef WIN32 +using __gnu_cxx::hash_map; +#else +using stdext::hash_map; +using stdext::hash_compare; +#endif + +namespace INTERP_KERNEL +{ + /** + * \brief Class representing a triangular face, used as key in caching hash map in SplitterTetra. + * + */ + class TriangleFaceKey + { + public: + + /** + * Constructor + * Sorts the given nodes (so that the order in which they are passed does not matter) and + * calculates a hash value for the key. + * + * @param node1 global number of the first node of the face + * @param node2 global number of the second node of the face + * @param node3 global number of the third node of the face + */ + TriangleFaceKey(int node1, int node2, int node3) + { + sort3Ints(_nodes, node1, node2, node3); + _hashVal = ( _nodes[0] + _nodes[1] + _nodes[2] ) % 29; + } + + /** + * Equality comparison operator. + * Compares this TriangleFaceKey object to another and determines if they represent the same face. + * + * @param key TriangleFaceKey with which to compare + * @return true if key has the same three nodes as this object, false if not + */ + bool operator==(const TriangleFaceKey& key) const + { + return _nodes[0] == key._nodes[0] && _nodes[1] == key._nodes[1] && _nodes[2] == key._nodes[2]; + } + + /** + * Returns a hash value for the object, based on its three nodes. + * This value is not unique for each face. + * + * @return a hash value for the object + */ + int hashVal() const + { + return _hashVal; + } + +#ifdef WIN32 + operator size_t () const + { + return _hashVal; + } +#endif + + inline void sort3Ints(int* sorted, int node1, int node2, int node3); + + private: + /// global numbers of the three nodes, sorted in ascending order + int _nodes[3]; + + /// hash value for the object, calculated in the constructor + int _hashVal; + }; + + /** + * Method to sort three integers in ascending order + * + * @param sorted int[3] array in which to store the result + * @param x1 first integer + * @param x2 second integer + * @param x3 third integer + */ + inline void TriangleFaceKey::sort3Ints(int* sorted, int x1, int x2, int x3) + { + if(x1 < x2) + { + if(x1 < x3) + { + // x1 is min + sorted[0] = x1; + sorted[1] = x2 < x3 ? x2 : x3; + sorted[2] = x2 < x3 ? x3 : x2; + } + else + { + // x3, x1, x2 + sorted[0] = x3; + sorted[1] = x1; + sorted[2] = x2; + } + } + else // x2 < x1 + { + if(x2 < x3) + { + // x2 is min + sorted[0] = x2; + sorted[1] = x1 < x3 ? x1 : x3; + sorted[2] = x1 < x3 ? x3 : x1; + } + else + { + // x3, x2, x1 + sorted[0] = x3; + sorted[1] = x2; + sorted[2] = x1; + } + } + } +} +#ifndef WIN32 +namespace __gnu_cxx +{ + + + /** + * \brief Template specialization of __gnu_cxx::hash function object for use with a __gnu_cxx::hash_map + * with TriangleFaceKey as key class. + * + */ + template<> + class hash + + { + public: + /** + * Operator() that returns the precalculated hashvalue of a TriangleFaceKey object. + * + * @param key a TriangleFaceKey object + * @return an integer hash value for key + */ + int operator()(const INTERP_KERNEL::TriangleFaceKey& key) const + { + return key.hashVal(); + } + }; +} +#else + struct TriangleFaceKeyComparator + { + bool operator()(const INTERP_KERNEL::TriangleFaceKey& key1, + const INTERP_KERNEL::TriangleFaceKey& key2 ) const + { + return key1.hashVal() < key2.hashVal(); + } + }; +#endif + +namespace INTERP_KERNEL +{ + + /** + * \brief Class calculating the volume of intersection between a tetrahedral target element and + * source elements with triangular or quadratilateral faces. + * + */ + template + class SplitterTetra + { + public: + + SplitterTetra(const MyMeshType& srcMesh, const double** tetraCorners, const typename MyMeshType::MyConnType *nodesId); + + ~SplitterTetra(); + + double intersectSourceCell(typename MyMeshType::MyConnType srcCell); + + typename MyMeshType::MyConnType getId(int id) { return _conn[id]; } + + void splitIntoDualCells(SplitterTetra **output); + + void splitMySelfForDual(double* output, int i, typename MyMeshType::MyConnType& nodeId); + + private: + // member functions + inline void createAffineTransform(const double** corners); + inline void checkIsOutside(const double* pt, bool* isOutside) const; + inline void calculateNode(typename MyMeshType::MyConnType globalNodeNum); + inline void calculateVolume(TransformedTriangle& tri, const TriangleFaceKey& key); + + + /// disallow copying + SplitterTetra(const SplitterTetra& t); + + /// disallow assignment + SplitterTetra& operator=(const SplitterTetra& t); + + // member variables + /// affine transform associated with this target element + TetraAffineTransform* _t; + + /// hash_map relating node numbers to transformed nodes, used for caching + hash_map< int , double* > _nodes; + + /// hash_map relating triangular faces to calculated volume contributions, used for caching + hash_map< TriangleFaceKey, double +#ifdef WIN32 + , hash_compare +#endif + > _volumes; + + /// reference to the source mesh + const MyMeshType& _src_mesh; + + // node id of the first node in target mesh in C mode. + typename MyMeshType::MyConnType _conn[4]; + + double _coords[12]; + }; + + /** + * Creates the affine transform _t from the corners of the tetrahedron. Used by the constructors + * + * @param corners double*[4] array containing pointers to four double[3] arrays with the + * coordinates of the corners of the tetrahedron + */ + template + inline void SplitterTetra::createAffineTransform(const double** corners) + { + // create AffineTransform from tetrahedron + _t = new TetraAffineTransform( corners ); + } + + /** + * Function used to filter out elements by checking if they belong to one of the halfspaces + * x <= 0, x >= 1, y <= 0, y >= 1, z <= 0, z >= 1, (indexed 0 - 7). The function updates an array of boolean variables + * which indicates whether the points that have already been checked are all in a halfspace. For each halfspace, + * the corresponding array element will be true if and only if it was true when the method was called and pt lies in the halfspace. + * + * @param pt double[3] containing the coordiantes of a transformed point + * @param isOutside bool[8] which indicate the results of earlier checks. + */ + template + inline void SplitterTetra::checkIsOutside(const double* pt, bool* isOutside) const + { + isOutside[0] = isOutside[0] && (pt[0] <= 0.0); + isOutside[1] = isOutside[1] && (pt[0] >= 1.0); + isOutside[2] = isOutside[2] && (pt[1] <= 0.0); + isOutside[3] = isOutside[3] && (pt[1] >= 1.0); + isOutside[4] = isOutside[4] && (pt[2] <= 0.0); + isOutside[5] = isOutside[5] && (pt[2] >= 1.0); + isOutside[6] = isOutside[6] && (1.0 - pt[0] - pt[1] - pt[2] <= 0.0); + isOutside[7] = isOutside[7] && (1.0 - pt[0] - pt[1] - pt[2] >= 1.0); + } + + /** + * Calculates the transformed node with a given global node number. + * Gets the coordinates for the node in _src_mesh with the given global number and applies TetraAffineTransform + * _t to it. Stores the result in the cache _nodes. The non-existance of the node in _nodes should be verified before + * calling. + * + * @param globalNodeNum global node number of the node in the mesh _src_mesh + * + */ + template + inline void SplitterTetra::calculateNode(typename MyMeshType::MyConnType globalNodeNum) + { + const double* node = _src_mesh.getCoordinatesPtr()+MyMeshType::MY_SPACEDIM*globalNodeNum; + double* transformedNode = new double[MyMeshType::MY_SPACEDIM]; + assert(transformedNode != 0); + _t->apply(transformedNode, node); + _nodes[globalNodeNum] = transformedNode; + } + + /** + * Calculates the volume contribution from the given TransformedTriangle and stores it with the given key in . + * Calls TransformedTriangle::calculateIntersectionVolume to perform the calculation. + * + * @param tri triangle for which to calculate the volume contribution + * @param key key associated with the face + */ + template + inline void SplitterTetra::calculateVolume(TransformedTriangle& tri, const TriangleFaceKey& key) + { + const double vol = tri.calculateIntersectionVolume(); + _volumes.insert(std::make_pair(key, vol)); + } + + template + class SplitterTetra2 + { + public: + SplitterTetra2(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy); + ~SplitterTetra2(); + void releaseArrays(); + void splitTargetCell(typename MyMeshType::MyConnType targetCell, typename MyMeshType::MyConnType nbOfNodesT, + typename std::vector< SplitterTetra* >& tetra); + void fiveSplit(const int* const subZone, typename std::vector< SplitterTetra* >& tetra); + void sixSplit(const int* const subZone, typename std::vector< SplitterTetra* >& tetra); + void calculateGeneral24Tetra(typename std::vector< SplitterTetra* >& tetra); + void calculateGeneral48Tetra(typename std::vector< SplitterTetra* >& tetra); + void calculateSubNodes(const MyMeshType& targetMesh, typename MyMeshType::MyConnType targetCell); + inline const double* getCoordsOfSubNode(typename MyMeshType::MyConnType node); + inline const double* getCoordsOfSubNode2(typename MyMeshType::MyConnType node, typename MyMeshType::MyConnType& nodeId); + template + inline void calcBarycenter(double* barycenter, const typename MyMeshType::MyConnType* pts); + private: + const MyMeshType& _target_mesh; + const MyMeshType& _src_mesh; + SplittingPolicy _splitting_pol; + /// vector of pointers to double[3] containing the coordinates of the + /// (sub) - nodes of split target cell + std::vector _nodes; + std::vector _node_ids; + }; + + /** + * Calculates the barycenter of n (sub) - nodes + * + * @param n number of nodes for which to calculate barycenter + * @param barycenter pointer to double[3] array in which to store the result + * @param pts pointer to int[n] array containing the (sub)-nodes for which to calculate the barycenter + */ + template + template + inline void SplitterTetra2::calcBarycenter(double* barycenter, const typename MyMeshType::MyConnType* pts) + { + barycenter[0] = barycenter[1] = barycenter[2] = 0.0; + for(int i = 0; i < n ; ++i) + { + const double* pt = getCoordsOfSubNode(pts[i]); + barycenter[0] += pt[0]; + barycenter[1] += pt[1]; + barycenter[2] += pt[2]; + } + + barycenter[0] /= n; + barycenter[1] /= n; + barycenter[2] /= n; + } + + /** + * Accessor to the coordinates of a given (sub)-node + * + * @param node local number of the (sub)-node 0,..,7 are the elements nodes, sub-nodes are numbered from 8,.. + * @return pointer to double[3] containing the coordinates of the nodes + */ + template + inline const double* SplitterTetra2::getCoordsOfSubNode(typename MyMeshType::MyConnType node) + { + // replace "at()" with [] for unsafe but faster access + return _nodes.at(node); + } + + /** + * Accessor to the coordinates of a given (sub)-node + * + * @param node local number of the (sub)-node 0,..,7 are the elements nodes, sub-nodes are numbered from 8,.. + * @param nodeId is an output that is node id in target whole mesh in C mode. + * @return pointer to double[3] containing the coordinates of the nodes + */ + template + const double* SplitterTetra2::getCoordsOfSubNode2(typename MyMeshType::MyConnType node, typename MyMeshType::MyConnType& nodeId) + { + const double *ret=_nodes.at(node); + if(node<8) + nodeId=_node_ids[node]; + else + nodeId=-1; + return ret; + } +} + +#endif diff --git a/src/INTERP_KERNEL/SplitterTetra.txx b/src/INTERP_KERNEL/SplitterTetra.txx new file mode 100644 index 000000000..d470e8b8b --- /dev/null +++ b/src/INTERP_KERNEL/SplitterTetra.txx @@ -0,0 +1,700 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __SPLITTERTETRA_TXX__ +#define __SPLITTERTETRA_TXX__ + +#include "SplitterTetra.hxx" + +#include "TetraAffineTransform.hxx" +#include "TransformedTriangle.hxx" +#include "MeshUtils.hxx" +#include "VectorUtils.hxx" +#include "CellModel.hxx" +#include "Log.hxx" + +#include +#include +#include +#include + +/// Smallest volume of the intersecting elements in the transformed space that will be returned as non-zero. +/// Since the scale is always the same in the transformed space (the target tetrahedron is unitary), this number is independent of the scale of the meshes. +#define SPARSE_TRUNCATION_LIMIT 1.0e-14 + +namespace INTERP_KERNEL +{ + + /** + * Constructor creating object from target cell global number + * + * @param srcMesh mesh containing the source elements + * @param targetMesh mesh containing the target elements + * @param targetCell global number of the target cell + * + */ + /*template + SplitterTetra::SplitterTetra(const MyMeshType& srcMesh, const MyMeshType& targetMesh, typename MyMeshType::MyConnType targetCell) + : _src_mesh(srcMesh), _t(0) + { + // get array of corners of target tetraedron + const double* tetraCorners[4]; + for(int i = 0 ; i < 4 ; ++i) + tetraCorners[i] = getCoordsOfNode(i, targetCell, targetMesh); + // create the affine transform + createAffineTransform(tetraCorners); + }*/ + + /*! + * output is expected to be allocated with 24*sizeof(void*) in order to store the 24 tetras. + * These tetras have to be deallocated. + */ + template + void SplitterTetra::splitIntoDualCells(SplitterTetra **output) + { + double tmp[12]; + const double *tmp2[4]={tmp,tmp+3,tmp+6,tmp+9}; + typename MyMeshType::MyConnType conn[4]={-1,-1,-1,-1}; + for(int i=0;i<24;i++) + { + splitMySelfForDual(tmp,i,conn[0]); + output[i]=new SplitterTetra(_src_mesh,tmp2,conn); + } + } + + /** + * Constructor creating object from the four corners of the tetrahedron. + * + * @param srcMesh mesh containing the source elements + * @param tetraCorners array of four pointers to double[3] arrays containing the coordinates of the + * corners of the tetrahedron + */ + template + SplitterTetra::SplitterTetra(const MyMeshType& srcMesh, const double** tetraCorners, const typename MyMeshType::MyConnType *nodesId) + : _t(0), _src_mesh(srcMesh) + { + std::copy(nodesId,nodesId+4,_conn); + _coords[0]=tetraCorners[0][0]; _coords[1]=tetraCorners[0][1]; _coords[2]=tetraCorners[0][2]; + _coords[3]=tetraCorners[1][0]; _coords[4]=tetraCorners[1][1]; _coords[5]=tetraCorners[1][2]; + _coords[6]=tetraCorners[2][0]; _coords[7]=tetraCorners[2][1]; _coords[8]=tetraCorners[2][2]; + _coords[9]=tetraCorners[3][0]; _coords[10]=tetraCorners[3][1]; _coords[11]=tetraCorners[3][2]; + // create the affine transform + createAffineTransform(tetraCorners); + } + + /*! + * This contructor is used to build part of 1/24th dual cell of tetraCorners. + * @param i is in 0..23 included. + * @param nodeId is the id of first node of this in target mesh in C mode. + */ + /*template + SplitterTetra::SplitterTetra(const MyMeshType& srcMesh, const double** tetraCorners, int i, typename MyMeshType::MyConnType nodeId) + : _t(0), _src_mesh(srcMesh), _conn(nodeId) + { + double *newCoords[4]; + splitMySelfForDual(tetraCorners,newCoords,i); + createAffineTransform(newCoords); + }*/ + + /** + * Destructor + * + * Deletes _t and the coordinates (double[3] vectors) in _nodes + * + */ + template + SplitterTetra::~SplitterTetra() + { + delete _t; + for(hash_map< int, double* >::iterator iter = _nodes.begin(); iter != _nodes.end() ; ++iter) + delete[] iter->second; + } + + /*! + * This method destroys the 4 pointers pointed by tetraCorners[0],tetraCorners[1],tetraCorners[2] and tetraCorners[3] + * @param i is in 0..23 included. + * @param output is expected to be sized of 12 in order to. + */ + template + void SplitterTetra::splitMySelfForDual(double* output, int i, typename MyMeshType::MyConnType& nodeId) + { + double *tmp[4]; + int offset=i/6; + nodeId=_conn[offset]; + tmp[0]=_coords+3*offset; tmp[1]=_coords+((offset+1)%4)*3; tmp[2]=_coords+((offset+2)%4)*3; tmp[3]=_coords+((offset+3)%4)*3; + int caseToTreat=i%6; + int case1=caseToTreat/2; + int case2=caseToTreat%2; + const int tab[3][2]={{1,2},{3,2},{1,3}}; + const int *curTab=tab[case1]; + double pt0[3]; pt0[0]=(tmp[curTab[case2]][0]+tmp[0][0])/2.; pt0[1]=(tmp[curTab[case2]][1]+tmp[0][1])/2.; pt0[2]=(tmp[curTab[case2]][2]+tmp[0][2])/2.; + double pt1[3]; pt1[0]=(tmp[0][0]+tmp[curTab[0]][0]+tmp[curTab[1]][0])/3.; pt1[1]=(tmp[0][1]+tmp[curTab[0]][1]+tmp[curTab[1]][1])/3.; pt1[1]=(tmp[0][2]+tmp[curTab[0]][2]+tmp[curTab[1]][2])/3.; + double pt2[3]; pt2[0]=(tmp[0][0]+tmp[1][0]+tmp[2][0]+tmp[3][0])/4.; pt2[1]=(tmp[0][1]+tmp[1][1]+tmp[2][1]+tmp[3][1])/4.; pt2[2]=(tmp[0][2]+tmp[1][2]+tmp[2][2]+tmp[3][2])/4.; + std::copy(pt1,pt1+3,output+case2*3); + std::copy(pt0,pt0+3,output+(abs(case2-1))*3); + std::copy(pt2,pt2+3,output+2*3); + std::copy(tmp[0],tmp[0]+3,output+3*3); + } + + /** + * Calculates the volume of intersection of an element in the source mesh and the target element. + * It first calculates the transformation that takes the target tetrahedron into the unit tetrahedron. After that, the + * faces of the source element are triangulated and the calculated transformation is applied + * to each triangle. The algorithm of Grandy, implemented in INTERP_KERNEL::TransformedTriangle is used + * to calculate the contribution to the volume from each triangle. The volume returned is the sum of these contributions + * divided by the determinant of the transformation. + * + * The class will cache the intermediary calculations of transformed nodes of source cells and volumes associated + * with triangulated faces to avoid having to recalculate these. + * + * @param element global number of the source element in C mode. + */ + template + double SplitterTetra::intersectSourceCell(typename MyMeshType::MyConnType element) + { + typedef typename MyMeshType::MyConnType ConnType; + const NumberingPolicy numPol=MyMeshType::My_numPol; + //{ could be done on outside? + // check if we have planar tetra element + if(_t->determinant() == 0.0) + { + // tetra is planar + LOG(2, "Planar tetra -- volume 0"); + return 0.0; + } + + // get type of cell + NormalizedCellType normCellType=_src_mesh.getTypeOfElement(OTT::indFC(element)); + const CellModel& cellModelCell=CellModel::getCellModel(normCellType); + unsigned nbOfNodes4Type=cellModelCell.getNumberOfNodes(); + // halfspace filtering + bool isOutside[8] = {true, true, true, true, true, true, true, true}; + bool isTargetOutside = false; + + // calculate the coordinates of the nodes + int *cellNodes=new int[nbOfNodes4Type]; + for(int i = 0;i global numbers too, but not sure it is worth it + const int globalNodeNum = getGlobalNumberOfNode(i, OTT::indFC(element), _src_mesh); + cellNodes[i]=globalNodeNum; + if(_nodes.find(globalNodeNum) == _nodes.end()) + { + //for(hash_map< int , double* >::iterator iter3=_nodes.begin();iter3!=_nodes.end();iter3++) + // std::cout << (*iter3).first << " "; + //std::cout << std::endl << "*** " << globalNodeNum << std::endl; + calculateNode(globalNodeNum); + } + + checkIsOutside(_nodes[globalNodeNum], isOutside); + } + + // halfspace filtering check + // NB : might not be beneficial for caching of triangles + for(int i = 0; i < 8; ++i) + { + if(isOutside[i]) + { + isTargetOutside = true; + } + } + + double totalVolume = 0.0; + + if(!isTargetOutside) + { + for(unsigned ii = 0 ; ii < cellModelCell.getNumberOfSons() ; ++ii) + { + NormalizedCellType faceType = cellModelCell.getSonType(ii); + const CellModel& faceModel=CellModel::getCellModel(faceType); + assert(faceModel.getDimension() == 2); + int *faceNodes=new int[faceModel.getNumberOfNodes()]; + cellModelCell.fillSonCellNodalConnectivity(ii,cellNodes,faceNodes); + switch(faceType) + { + case NORM_TRI3: + { + // create the face key + TriangleFaceKey key = TriangleFaceKey(faceNodes[0], faceNodes[1], faceNodes[2]); + + // calculate the triangle if needed + if(_volumes.find(key) == _volumes.end()) + { + TransformedTriangle tri(_nodes[faceNodes[0]], _nodes[faceNodes[1]], _nodes[faceNodes[2]]); + calculateVolume(tri, key); + totalVolume += _volumes[key]; + } else { + // count negative as face has reversed orientation + totalVolume -= _volumes[key]; + } + } + break; + + case NORM_QUAD4: + + // simple triangulation of faces along a diagonal : + // + // 2 ------ 3 + // | / | + // | / | + // | / | + // | / | + // | / | + // | / | + // 1 ------ 4 + // + //? not sure if this always works + { + // calculate the triangles if needed + + // local nodes 1, 2, 3 + TriangleFaceKey key1 = TriangleFaceKey(faceNodes[0], faceNodes[1], faceNodes[2]); + if(_volumes.find(key1) == _volumes.end()) + { + TransformedTriangle tri(_nodes[faceNodes[0]], _nodes[faceNodes[1]], _nodes[faceNodes[2]]); + calculateVolume(tri, key1); + totalVolume += _volumes[key1]; + } else { + // count negative as face has reversed orientation + totalVolume -= _volumes[key1]; + } + + // local nodes 1, 3, 4 + TriangleFaceKey key2 = TriangleFaceKey(faceNodes[0], faceNodes[2], faceNodes[3]); + if(_volumes.find(key2) == _volumes.end()) + { + TransformedTriangle tri(_nodes[faceNodes[0]], _nodes[faceNodes[2]], _nodes[faceNodes[3]]); + calculateVolume(tri, key2); + totalVolume += _volumes[key2]; + } + else + { + // count negative as face has reversed orientation + totalVolume -= _volumes[key2]; + } + } + break; + + default: + std::cout << "+++ Error : Only elements with triangular and quadratilateral faces are supported at the moment." << std::endl; + assert(false); + } + delete [] faceNodes; + } + } + delete [] cellNodes; + // reset if it is very small to keep the matrix sparse + // is this a good idea? + if(epsilonEqual(totalVolume, 0.0, SPARSE_TRUNCATION_LIMIT)) + { + totalVolume = 0.0; + } + + LOG(2, "Volume = " << totalVolume << ", det= " << _t->determinant()); + + // NB : fault in article, Grandy, [8] : it is the determinant of the inverse transformation + // that should be used (which is equivalent to dividing by the determinant) + return std::fabs(1.0 / _t->determinant() * totalVolume) ; + } + + //////////////////////////////////////////////////////// + + template + SplitterTetra2::SplitterTetra2(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy):_target_mesh(targetMesh),_src_mesh(srcMesh), + _splitting_pol(policy) + { + } + + template + SplitterTetra2::~SplitterTetra2() + { + releaseArrays(); + } + + template + void SplitterTetra2::releaseArrays() + { + // free potential sub-mesh nodes that have been allocated + if(_nodes.size()>=8) + { + std::vector::iterator iter = _nodes.begin() + 8; + while(iter != _nodes.end()) + { + delete[] *iter; + ++iter; + } + } + _nodes.clear(); + } + + /*! + * @param targetCell in C mode. + * @param tetra is the output result tetra containers. + */ + template + void SplitterTetra2::splitTargetCell(typename MyMeshType::MyConnType targetCell, typename MyMeshType::MyConnType nbOfNodesT, + typename std::vector< SplitterTetra* >& tetra) + { + typedef typename MyMeshType::MyConnType ConnType; + const NumberingPolicy numPol=MyMeshType::My_numPol; + const int numTetra = static_cast(_splitting_pol); + if(nbOfNodesT==4) + { + _nodes.resize(8); + _node_ids.resize(8); + tetra.reserve(1); + const double *nodes[4]; + int conn[4]; + for(int node = 0; node < 4 ; ++node) + { + nodes[node]=getCoordsOfNode2(node, OTT::indFC(targetCell),_target_mesh,conn[node]); + } + std::copy(conn,conn+4,_node_ids.begin()); + SplitterTetra* t = new SplitterTetra(_src_mesh, nodes,conn); + tetra.push_back(t); + return ; + } + + // pre-calculate nodes + calculateSubNodes(_target_mesh, OTT::indFC(targetCell)); + + tetra.reserve(numTetra); + _nodes.reserve(30); // we never have more than this + + switch(_splitting_pol) + { + case PLANAR_FACE_5: + { + const int subZone[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + fiveSplit(subZone,tetra); + } + break; + + case PLANAR_FACE_6: + { + const int subZone[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + sixSplit(subZone,tetra); + } + break; + + case GENERAL_24: + { + calculateGeneral24Tetra(tetra); + } + break; + + case GENERAL_48: + { + calculateGeneral48Tetra(tetra); + } + break; + default: + assert(false); + } + } + + /** + * Splits the hexahedron into five tetrahedra. + * This method adds five SplitterTetra objects to the vector tetra. + * + * @param subZone the local node numbers corresponding to the hexahedron corners - these are mapped onto {0,..,7}. Providing this allows the + * splitting to be reused on the subzones of the GENERAL_* types of splitting + */ + template + void SplitterTetra2::fiveSplit(const int* const subZone, typename std::vector< SplitterTetra* >& tetra) + { + // Schema according to which the splitting is performed. + // Each line represents one tetrahedron. The numbering is as follows : + // + // 7 ------ 6 + // /| /| + // / | / | + // 3 ------ 2 | + // | | | | + // | | | | + // | 4-----|- 5 + // | / | / + // 0 ------ 1 + + + static const int SPLIT_NODES_5[20] = + { + 0, 1, 5, 2, + 0, 4, 5, 7, + 0, 3, 7, 2, + 5, 6, 7, 2, + 0, 2, 5, 7 + }; + + // create tetrahedra + for(int i = 0; i < 5; ++i) + { + const double* nodes[4]; + int conn[4]; + for(int j = 0; j < 4; ++j) + { + nodes[j] = getCoordsOfSubNode2(subZone[ SPLIT_NODES_5[4*i+j] ],conn[j]); + } + SplitterTetra* t = new SplitterTetra(_src_mesh, nodes,conn); + tetra.push_back(t); + } + } + + /** + * Splits the hexahedron into six tetrahedra. + * This method adds six SplitterTetra objects to the vector tetra. + * + * @param subZone the local node numbers corresponding to the hexahedron corners - these are mapped onto {0,..,7}. Providing this allows the + * splitting to be reused on the subzones of the GENERAL_* types of splitting + */ + template + void SplitterTetra2::sixSplit(const int* const subZone, typename std::vector< SplitterTetra* >& tetra) + { + // Schema according to which the splitting is performed. + // Each line represents one tetrahedron. The numbering is as follows : + // + // 7 ------ 6 + // /| /| + // / | / | + // 3 ------ 2 | + // | | | | + // | | | | + // | 4-----|- 5 + // | / | / + // 0 ------ 1 + + static const int SPLIT_NODES_6[24] = + { + 0, 1, 5, 6, + 0, 2, 1, 6, + 0, 5, 4, 6, + 0, 4, 7, 6, + 0, 3, 2, 6, + 0, 7, 3, 6 + }; + + for(int i = 0; i < 6; ++i) + { + const double* nodes[4]; + int conn[4]; + for(int j = 0; j < 4; ++j) + { + nodes[j] = getCoordsOfSubNode2(subZone[ SPLIT_NODES_6[4*i+j] ],conn[j]); + } + SplitterTetra* t = new SplitterTetra(_src_mesh, nodes,conn); + tetra.push_back(t); + } + } + + /** + * Splits the hexahedron into 24 tetrahedra. + * The splitting is done by combining the barycenter of the tetrahedron, the barycenter of each face + * and the nodes of each edge of the face. This creates 6 faces * 4 edges / face = 24 tetrahedra. + * The submesh nodes introduced are the barycenters of the faces and the barycenter of the cell. + * + */ + template + void SplitterTetra2::calculateGeneral24Tetra(typename std::vector< SplitterTetra* >& tetra) + { + // The two nodes of the original mesh cell used in each tetrahedron. + // The tetrahedra all have nodes (cellCenter, faceCenter, edgeNode1, edgeNode2) + // For the correspondance of the nodes, see the GENERAL_48_SUB_NODES table in calculateSubNodes + static const int TETRA_EDGES[48] = + { + // face with center 9 + 0,1, + 1,5, + 5,4, + 4,0, + // face with center 10 + 0,1, + 1,2, + 2,3, + 3,0, + // face with center 11 + 0,4, + 4,7, + 7,3, + 3,0, + // face with center 12 + 1,5, + 5,6, + 6,2, + 2,1, + // face with center 13 + 5,6, + 6,7, + 7,4, + 4,5, + // face with center 14 + 2,6, + 6,7, + 7,3, + 3,2 + }; + + // nodes to use for tetrahedron + const double* nodes[4]; + int conn[4]; + // get the cell center + nodes[0] = getCoordsOfSubNode2(14,conn[0]); + + for(int faceCenterNode = 8; faceCenterNode < 14; ++faceCenterNode) + { + // get the face center + nodes[1] = getCoordsOfSubNode2(faceCenterNode,conn[1]); + for(int j = 0; j < 4; ++j) + { + const int row = 4*(faceCenterNode - 9) + j; + nodes[2] = getCoordsOfSubNode2(TETRA_EDGES[2*row],conn[2]); + nodes[3] = getCoordsOfSubNode2(TETRA_EDGES[2*row + 1],conn[3]); + + SplitterTetra* t = new SplitterTetra(_src_mesh, nodes, conn); + tetra.push_back(t); + } + } + } + + + /** + * Splits the hexahedron into 48 tetrahedra. + * The splitting is done by introducing the midpoints of all the edges + * and the barycenter of the element as submesh nodes. The 8 hexahedral subzones thus defined + * are then split into 6 tetrahedra each, as in Grandy, p. 449. The division of the subzones + * is done by calling sixSplit(). + * + */ + template + void SplitterTetra2::calculateGeneral48Tetra(typename std::vector< SplitterTetra* >& tetra) + { + // Define 8 hexahedral subzones as in Grandy, p449 + // the values correspond to the nodes that correspond to nodes 1,2,3,4,5,6,7,8 in the subcell + // For the correspondance of the nodes, see the GENERAL_48_SUB_NODES table in calculateSubNodes + static const int subZones[64] = + { + 0,8,21,12,9,20,26,22, + 8,1,13,21,20,10,23,26, + 12,21,16,3,22,26,25,17, + 21,13,2,16,26,23,18,25, + 9,20,26,22,4,11,24,14, + 20,10,23,26,11,5,15,24, + 22,26,25,17,14,24,19,7, + 26,23,18,25,24,15,6,19 + }; + + for(int i = 0; i < 8; ++i) + { + sixSplit(&subZones[8*i],tetra); + } + } + + /** + * Precalculates all the nodes. + * Retrieves the mesh nodes and allocates the necessary sub-mesh + * nodes according to the splitting policy used. + * This method is meant to be called once by the constructor. + * + * @param targetMesh the target mesh + * @param targetCell the global number of the cell that the object represents, in targetMesh mode. + * @param policy the splitting policy of the object + * + */ + template + void SplitterTetra2::calculateSubNodes(const MyMeshType& targetMesh, typename MyMeshType::MyConnType targetCell) + { + // retrieve real mesh nodes + _node_ids.resize(8); + for(int node = 0; node < 8 ; ++node) + { + // calculate only normal nodes + _nodes.push_back(getCoordsOfNode2(node, targetCell, targetMesh,_node_ids[node])); + } + + // create sub-mesh nodes if needed + switch(_splitting_pol) + { + case GENERAL_24: + { + // Each sub-node is the barycenter of 4 other nodes. + // For the faces, these are on the orignal mesh. + // For the barycenter, the four face sub-nodes are used. + static const int GENERAL_24_SUB_NODES[28] = + { + 0,1,4,5,// sub-node 9 (face) + 0,1,2,3,// sub-node 10 (face) + 0,3,4,7,// sub-node 11 (face) + 1,2,5,6,// sub-node 12 (face) + 4,5,6,7,// sub-node 13 (face) + 2,3,6,7,// sub-node 14 (face) + 9,10,11,12// sub-node 15 (cell) + }; + + for(int i = 0; i < 7; ++i) + { + double* barycenter = new double[3]; + calcBarycenter<4>(barycenter, &GENERAL_24_SUB_NODES[4*i]); + _nodes.push_back(barycenter); + } + } + break; + + case GENERAL_48: + { + // Each sub-node is the barycenter of two other nodes. + // For the edges, these lie on the original mesh. + // For the faces, these are the edge sub-nodes. + // For the cell these are two face sub-nodes. + static const int GENERAL_48_SUB_NODES[38] = + { + 0,1, // sub-node 9 (edge) + 0,4, // sub-node 10 (edge) + 1,5, // sub-node 11 (edge) + 4,5, // sub-node 12 (edge) + 0,3, // sub-node 13 (edge) + 1,2, // sub-node 14 (edge) + 4,7, // sub-node 15 (edge) + 5,6, // sub-node 16 (edge) + 2,3, // sub-node 17 (edge) + 3,7, // sub-node 18 (edge) + 2,6, // sub-node 19 (edge) + 6,7, // sub-node 20 (edge) + 8,11, // sub-node 21 (face) + 12,13, // sub-node 22 (face) + 9,17, // sub-node 23 (face) + 10,18, // sub-node 24 (face) + 14,15, // sub-node 25 (face) + 16,19, // sub-node 26 (face) + 20,25 // sub-node 27 (cell) + }; + + for(int i = 0; i < 19; ++i) + { + double* barycenter = new double[3]; + calcBarycenter<2>(barycenter, &GENERAL_48_SUB_NODES[2*i]); + _nodes.push_back(barycenter); + } + } + break; + + default: + break; + } + } +} + +#endif diff --git a/src/INTERP_KERNEL/TargetIntersector.hxx b/src/INTERP_KERNEL/TargetIntersector.hxx new file mode 100644 index 000000000..e9ff9e01f --- /dev/null +++ b/src/INTERP_KERNEL/TargetIntersector.hxx @@ -0,0 +1,58 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TARGETINTERSECTOR__HXX__ +#define __TARGETINTERSECTOR__HXX__ + +#include "INTERPKERNELDefines.hxx" + +#include + +namespace INTERP_KERNEL +{ + /** + * \brief Abstract base class of Intersector classes. + * These classes represent a target element and calculate its intersection + * with the source elements. + */ + template + class TargetIntersector + { + public: + typedef typename MyMeshType::MyConnType ConnType; + public: + /*! + * \addtogroup InterpKerGrpIntPlan + * @{ + */ + /*! + * Tool for cell intersection, result is always positive. + * @param icellT id of cell in target mesh in \b C \b mode. + * @param icellsS ids of cells in source mesh in \b C \b mode. + * @param res is an IN/OUT parameter that represents the icellTth row in final matrix, fed with at most icellsS elements. + */ + virtual void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) = 0; + //! @} + //Tool for cell filtering + virtual int getNumberOfRowsOfResMatrix() const = 0; + virtual int getNumberOfColsOfResMatrix() const = 0; + virtual ~TargetIntersector() { } + }; +} + +#endif diff --git a/src/INTERP_KERNEL/TetraAffineTransform.cxx b/src/INTERP_KERNEL/TetraAffineTransform.cxx new file mode 100644 index 000000000..21a42d0df --- /dev/null +++ b/src/INTERP_KERNEL/TetraAffineTransform.cxx @@ -0,0 +1,394 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "TetraAffineTransform.hxx" +#include "VectorUtils.hxx" + +#include +#include + +#include "Log.hxx" + +namespace INTERP_KERNEL +{ + ///////////////////////////////////////////////////////////////////////////////////////// + /// PUBLIC INTERFACE METHODS ////////////// + ///////////////////////////////////////////////////////////////////////////////////////// + + /** + * Constructor + * Create the TetraAffineTransform object from the tetrahedron + * with corners specified in pts. If the tetrahedron is degenerate or almost degenerate, + * construction succeeds, but the determinant of the transform is set to 0. + * + * @param pts a 4x3 matrix containing 4 points (pts[0], ..., pts[3]) of 3 coordinates each + */ + TetraAffineTransform::TetraAffineTransform(const double** pts) + { + + LOG(2,"Creating transform from tetraeder : "); + LOG(2, vToStr(pts[0]) << ", " << vToStr(pts[1]) << ", " << vToStr(pts[2]) << ", " << vToStr(pts[3])); + + // three last points -> linear transform + for(int i = 0; i < 3 ; ++i) + { + for(int j = 0 ; j < 3 ; ++j) + { + // NB we insert columns, not rows + _linear_transform[3*j + i] = (pts[i+1])[j] - (pts[0])[j]; + } + } + + // remember _linear_transform for the reverse transformation + memcpy( _back_linear_transform, _linear_transform, 9*sizeof(double)); + memcpy( _back_translation, pts[0], 3*sizeof(double)); + + calculateDeterminant(); + + LOG(3, "determinant before inverse = " << _determinant); + + // check that tetra is non-planar -> determinant is not zero + // otherwise set _determinant to zero to signal caller that transformation did not work + if(epsilonEqual(_determinant, 0.0)) + { + _determinant = 0.0; + return; + } + + // we need the inverse transform + invertLinearTransform(); + + // first point -> translation + // calculate here because translation takes place in "transformed space", + // or in other words b = -A*O where A is the linear transform + // and O is the position vector of the point that is mapped onto the origin + for(int i = 0 ; i < 3 ; ++i) + { + _translation[i] = -(_linear_transform[3*i]*(pts[0])[0] + _linear_transform[3*i+1]*(pts[0])[1] + _linear_transform[3*i+2]*(pts[0])[2]) ; + } + + // precalculate determinant (again after inversion of transform) + calculateDeterminant(); + +#ifdef INVERSION_SELF_CHECK + // debugging : check that applying the inversed transform to the original points + // gives us the unit tetrahedron + LOG(4, "transform determinant is " << _determinant); + LOG(4, "*Self-check : Applying transformation to original points ... "); + for(int i = 0; i < 4 ; ++i) + { + double v[3]; + apply(v, pts[i]); + LOG(4, vToStr(v)) + for(int j = 0; j < 3; ++j) + { + assert(epsilonEqual(v[j], (3*i+j == 3 || 3*i+j == 7 || 3*i+j == 11 ) ? 1.0 : 0.0)); + } + } + + LOG(4, " ok"); +#endif + } + + /** + * Calculates the transform of point srcPt and stores the result in destPt. + * If destPt == srcPt, then srcPt is overwritten safely. + * + * + * @param destPt double[3] in which to store the transformed point + * @param srcPt double[3] containing coordinates of points to be transformed + * + */ + void TetraAffineTransform::apply(double* destPt, const double* srcPt) const + { + double* dest = destPt; + + // are we self-allocating ? + const bool selfAllocation = (destPt == srcPt); + + if(selfAllocation) + { + // alloc temporary memory + dest = new double[3]; + + LOG(6, "Info : Self-affectation in TetraAffineTransform::apply"); + } + + for(int i = 0 ; i < 3 ; ++i) + { + // matrix - vector multiplication + dest[i] = _linear_transform[3*i] * srcPt[0] + _linear_transform[3*i + 1] * srcPt[1] + _linear_transform[3*i + 2] * srcPt[2]; + + // translation + dest[i] += _translation[i]; + } + + if(selfAllocation) + { + // copy result back to destPt + for(int i = 0 ; i < 3 ; ++i) + { + destPt[i] = dest[i]; + } + delete[] dest; + } + } + + /** + * Calculates the reverse transform of point srcPt and stores the result in destPt. + * If destPt == srcPt, then srcPt is overwritten safely. + * + * @param destPt double[3] in which to store the transformed point + * @param srcPt double[3] containing coordinates of points to be transformed + */ + void TetraAffineTransform::reverseApply(double* destPt, const double* srcPt) const + { + double* dest = destPt; + + // are we self-allocating ? + const bool selfAllocation = (destPt == srcPt); + + if(selfAllocation) + { + // alloc temporary memory + dest = new double[3]; + + LOG(6, "Info : Self-affectation in TetraAffineTransform::reverseApply"); + } + + for(int i = 0 ; i < 3 ; ++i) + { + // matrix - vector multiplication + dest[i] = _back_linear_transform[3*i] * srcPt[0] + _back_linear_transform[3*i + 1] * srcPt[1] + _back_linear_transform[3*i + 2] * srcPt[2]; + + // translation + dest[i] += _back_translation[i]; + } + + if(selfAllocation) + { + // copy result back to destPt + for(int i = 0 ; i < 3 ; ++i) + { + destPt[i] = dest[i]; + } + delete[] dest; + } + } + + /** + * Returns the determinant of the linear part A of the transform. + * + * @return determinant of the transform + * + */ + double TetraAffineTransform::determinant() const + { + return _determinant; + } + + /** + * Outputs to std::cout the matrix A and the vector b + * of the transform Ax + b + * + */ + void TetraAffineTransform::dump() const + { + using namespace std; + + std::cout << "A = " << std::endl << "["; + for(int i = 0; i < 3; ++i) + { + std::cout << _linear_transform[3*i] << ", " << _linear_transform[3*i + 1] << ", " << _linear_transform[3*i + 2]; + if(i != 2 ) std::cout << endl; + } + std::cout << "]" << endl; + + std::cout << "b = " << "[" << _translation[0] << ", " << _translation[1] << ", " << _translation[2] << "]" << endl; + } + + ///////////////////////////////////////////////////////////////////////////////////////// + /// PRIVATE METHODS ////////////// + ///////////////////////////////////////////////////////////////////////////////////////// + + /** + * Calculates the inverse of the matrix A, stored in _linear_transform + * by LU-factorization and substitution + * + */ + void TetraAffineTransform::invertLinearTransform() + { + //{ we copy the matrix for the lu-factorization + // maybe inefficient + double lu[9]; + for(int i = 0 ; i < 9; ++i) + { + lu[i] = _linear_transform[i]; + } + + // calculate LU factorization + int idx[3]; + factorizeLU(lu, idx); + + // calculate inverse by forward and backward substitution + // store in _linear_transform + // NB _linear_transform cannot be overwritten with lu in the loop + for(int i = 0 ; i < 3 ; ++i) + { + // form standard base vector i + const double b[3] = + { + int(i == 0), + int(i == 1), + int(i == 2) + }; + + LOG(6, "b = [" << b[0] << ", " << b[1] << ", " << b[2] << "]"); + + double y[3]; + forwardSubstitution(y, lu, b, idx); + + double x[3]; + backwardSubstitution(x, lu, y, idx); + + // copy to _linear_transform matrix + // NB : this is a column operation, so we cannot + // do this directly when we calculate x + for(int j = 0 ; j < 3 ; j++) + { + _linear_transform[3*j + i] = x[idx[j]]; + } + } + } + + /** + * Updates the member _determinant of the matrix A of the transformation. + * + */ + void TetraAffineTransform::calculateDeterminant() + { + const double subDet[3] = + { + _linear_transform[4] * _linear_transform[8] - _linear_transform[5] * _linear_transform[7], + _linear_transform[3] * _linear_transform[8] - _linear_transform[5] * _linear_transform[6], + _linear_transform[3] * _linear_transform[7] - _linear_transform[4] * _linear_transform[6] + }; + + _determinant = _linear_transform[0] * subDet[0] - _linear_transform[1] * subDet[1] + _linear_transform[2] * subDet[2]; + } + + + ///////////////////////////////////////////////// + /// Auxiliary methods for inverse calculation /// + ///////////////////////////////////////////////// + + + /** + * Calculates the LU-factorization of the matrix A (_linear_transform) + * and stores it in lu. Since partial pivoting is used, there are + * row swaps. This is represented by the index permutation vector idx : to access element + * (i,j) of lu, use lu[3*idx[i] + j] + * + * @param lu double[9] in which to store LU-factorization + * @param idx int[3] in which to store row permutation vector + */ + void TetraAffineTransform::factorizeLU(double* lu, int* idx) const + { + // 3 x 3 LU factorization + // initialise idx + for(int i = 0 ; i < 3 ; ++i) + { + idx[i] = i; + } + + for(int k = 0; k < 2 ; ++k) + { + + // find pivot + int i = k; + double max = std::fabs(lu[3*idx[k] + k]); + int row = i; + while(i < 3) + { + if(std::fabs(lu[3*idx[i] + k]) > max) + { + max = fabs(lu[3*idx[i] + k]); + row = i; + } + ++i; + } + + // swap rows in index vector + int tmp = idx[k]; + idx[k] = idx[row]; + idx[row] = tmp; + + // calculate row + for(int j = k + 1 ; j < 3 ; ++j) + { + // l_jk = u_jk / u_kk + lu[3*idx[j] + k] /= lu[3*idx[k] + k]; + for(int s = k + 1; s < 3 ; ++s) + { + // case s = k will always become zero, and then be replaced by + // the l-value + // there's no need to calculate this explicitly + + // u_js = u_js - l_jk * u_ks + lu[3*idx[j] + s] -= lu[3*idx[j] + k] * lu[3*idx[k] + s] ; + } + } + } + } + + /** + * Solves the system Lx = b, where L is lower unit-triangular (ones on the diagonal) + * + * @param x double[3] in which the solution is stored + * @param lu double[9] containing the LU-factorization + * @param b double[3] containing the right-hand side + * @param idx int[3] containing the permutation vector associated with lu + * + */ + void TetraAffineTransform::forwardSubstitution(double* x, const double* lu, const double* b, const int* idx) const + { + // divisions are not carried out explicitly because lu does not store + // the diagonal values of L, which are all 1 + // Compare with backwardSubstitution() + x[idx[0]] = ( b[idx[0]] ); // / lu[3*idx[0]] + x[idx[1]] = ( b[idx[1]] - lu[3*idx[1]] * x[idx[0]] ); // / lu[3*idx[1] + 1]; + x[idx[2]] = ( b[idx[2]] - lu[3*idx[2]] * x[idx[0]] - lu[3*idx[2] + 1] * x[idx[1]] ); // / lu[3*idx[2] + 2]; + } + + /** + * Solves the system Ux = b, where U is upper-triangular + * + * @param x double[3] in which the solution is stored + * @param lu double[9] containing the LU-factorization + * @param b double[3] containing the right-hand side + * @param idx int[3] containing the permutation vector associated with lu + * + */ + void TetraAffineTransform::backwardSubstitution(double* x, const double* lu, const double* b, const int* idx) const + { + x[idx[2]] = ( b[idx[2]] ) / lu[3*idx[2] + 2]; + x[idx[1]] = ( b[idx[1]] - lu[3*idx[1] + 2] * x[idx[2]] ) / lu[3*idx[1] + 1]; + x[idx[0]] = ( b[idx[0]] - lu[3*idx[0] + 1] * x[idx[1]] - lu[3*idx[0] + 2] * x[idx[2]] ) / lu[3*idx[0]]; + } + +} diff --git a/src/INTERP_KERNEL/TetraAffineTransform.hxx b/src/INTERP_KERNEL/TetraAffineTransform.hxx new file mode 100644 index 000000000..fecdc8d39 --- /dev/null +++ b/src/INTERP_KERNEL/TetraAffineTransform.hxx @@ -0,0 +1,80 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TETRA_AFFINE_TRANSFORM_HXX__ +#define __TETRA_AFFINE_TRANSFORM_HXX__ + +#include "INTERPKERNELDefines.hxx" + +#undef INVERSION_SELF_CHECK // debugging : check that calculated inverse is correct + +namespace INTERP_KERNEL +{ + /** + * \brief Class representing an affine transformation x -> Ax + b that transforms a given tetrahedron + * into the unit tetrahedron. + * + */ + class INTERPKERNEL_EXPORT TetraAffineTransform + { + + public: + TetraAffineTransform(const double** pts); + + void apply(double* destPt, const double* srcPt) const; + + void reverseApply(double* destPt, const double* srcPt) const; + + double determinant() const; + + void dump() const; + + private: + + void invertLinearTransform(); + + void calculateDeterminant(); + + void factorizeLU(double* lu, int* idx) const; + + void forwardSubstitution(double* x, const double* lu, const double* b, const int* idx) const; + + void backwardSubstitution(double* x, const double* lu, const double* b, const int* idx) const; + + // The affine transformation Ax + b is represented with _linear_transformation containing the elements of + // A in row-first ordering and _translation containing the elements of b + + /// 3x3 matrix A in affine transform x -> Ax + b + double _linear_transform[9]; + + /// 3x1 vector b in affine transform x -> Ax + b + double _translation[3]; + + /// The determinant of the matrix A is calculated at the construction of the object and cached. + double _determinant; + + /// 3x3 matrix AT is transposed A matrix used for y -> ATy - c transformation + double _back_linear_transform[9]; + + /// 3x1 vector c in affine transform y -> ATy - c + double _back_translation[3]; + + }; +} + +#endif diff --git a/src/INTERP_KERNEL/TransformedTriangle.cxx b/src/INTERP_KERNEL/TransformedTriangle.cxx new file mode 100644 index 000000000..b51772e14 --- /dev/null +++ b/src/INTERP_KERNEL/TransformedTriangle.cxx @@ -0,0 +1,669 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "TransformedTriangle.hxx" +#include "VectorUtils.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace INTERP_KERNEL +{ + + /** + * \brief Class representing a circular order of a set of points around their barycenter. + * It is used with the STL sort() algorithm to sort the point of the two polygons + * + */ + class ProjectedCentralCircularSortOrder + { + public: + + /// Enumeration of different planes to project on when calculating order + enum CoordType { XY, XZ, YZ }; + + /** + * Constructor + * + * @param barycenter double[3] containing the barycenter of the points to be compared + * @param type plane to project on when comparing. The comparison will not work if all the points are in a plane perpendicular + * to the plane being projected on + */ + ProjectedCentralCircularSortOrder(const double* barycenter, const CoordType type) + : _aIdx((type == YZ) ? 1 : 0), + _bIdx((type == XY) ? 1 : 2), + _a(barycenter[_aIdx]), + _b(barycenter[_bIdx]) + { + } + + /** + * Comparison operator. + * Compares the relative position between two points in their ordering around the barycenter. + * + * @param pt1 a double[3] representing a point + * @param pt2 a double[3] representing a point + * @return true if the angle of the difference vector between pt1 and the barycenter is greater than that + * of the difference vector between pt2 and the barycenter. + */ + bool operator()(const double* pt1, const double* pt2) + { + // calculate angles with the axis + const double ang1 = atan2(pt1[_aIdx] - _a, pt1[_bIdx] - _b); + const double ang2 = atan2(pt2[_aIdx] - _a, pt2[_bIdx] - _b); + + return ang1 > ang2; + } + + private: + /// index corresponding to first coordinate of plane on which points are projected + const int _aIdx; + + /// index corresponding to second coordinate of plane on which points are projected + const int _bIdx; + + /// value of first projected coordinate of the barycenter + const double _a; + + /// value of second projected coordinate of the barycenter + const double _b; + }; + + // ---------------------------------------------------------------------------------- + // TransformedTriangle PUBLIC + // ---------------------------------------------------------------------------------- + + /** + * Constructor + * + * The coordinates are copied to the internal member variables + * + * @param p array of three doubles containing coordinates of P + * @param q array of three doubles containing coordinates of Q + * @param r array of three doubles containing coordinates of R + */ + TransformedTriangle::TransformedTriangle(double* p, double* q, double* r) + : _is_double_products_calculated(false), _is_triple_products_calculated(false), _volume(0) + { + + for(int i = 0 ; i < 3 ; ++i) + { + // xyz coordinates + _coords[5*P + i] = p[i]; + _coords[5*Q + i] = q[i]; + _coords[5*R + i] = r[i]; + } + + // h coordinate + + _coords[5*P + 3] = 1 - p[0] - p[1] - p[2]; + _coords[5*Q + 3] = 1 - q[0] - q[1] - q[2]; + _coords[5*R + 3] = 1 - r[0] - r[1] - r[2]; + + // H coordinate + _coords[5*P + 4] = 1 - p[0] - p[1]; + _coords[5*Q + 4] = 1 - q[0] - q[1]; + _coords[5*R + 4] = 1 - r[0] - r[1]; + + // initialise rest of data + preCalculateDoubleProducts(); + + preCalculateTriangleSurroundsEdge(); + + preCalculateTripleProducts(); + + } + + /** + * Destructor + * + * Deallocates the memory used to store the points of the polygons. + * This memory is allocated in calculateIntersectionPolygons(). + */ + TransformedTriangle::~TransformedTriangle() + { + // delete elements of polygons + for(std::vector::iterator it = _polygonA.begin() ; it != _polygonA.end() ; ++it) + { + delete[] *it; + } + for(std::vector::iterator it = _polygonB.begin() ; it != _polygonB.end() ; ++it) + { + delete[] *it; + } + } + + /** + * Calculates the volume of intersection between the triangle and the + * unit tetrahedron. + * + * @return volume of intersection of this triangle with unit tetrahedron, + * as described in Grandy + * + */ + double TransformedTriangle::calculateIntersectionVolume() + { + // check first that we are not below z - plane + if(isTriangleBelowTetraeder()) + { + LOG(2, " --- Triangle is below tetraeder - V = 0.0"); + return 0.0; + } + + // get the sign of the volume - equal to the sign of the z-component of the normal + // of the triangle, u_x * v_y - u_y * v_x, where u = q - p and v = r - p + // if it is zero, the triangle is perpendicular to the z - plane and so the volume is zero +// const double uv_xy[4] = +// { +// _coords[5*Q] - _coords[5*P], _coords[5*Q + 1] - _coords[5*P + 1], // u_x, u_y +// _coords[5*R] - _coords[5*P], _coords[5*R + 1] - _coords[5*P + 1] // v_x, v_y +// }; + +// double sign = uv_xy[0] * uv_xy[3] - uv_xy[1] * uv_xy[2]; + int sign = isTriangleInclinedToFacet( OXY ); + + if(sign == 0 ) + { + LOG(2, " --- Triangle is perpendicular to z-plane - V = 0.0"); + return _volume = 0.0; + } + + + // normalize sign + //sign = sign > 0.0 ? 1.0 : -1.0; + + LOG(2, "-- Calculating intersection polygons ... "); + calculateIntersectionPolygons(); + + double barycenter[3]; + + // calculate volume under A + double volA = 0.0; + if(_polygonA.size() > 2) + { + LOG(2, "---- Treating polygon A ... "); + calculatePolygonBarycenter(A, barycenter); + sortIntersectionPolygon(A, barycenter); + volA = calculateVolumeUnderPolygon(A, barycenter); + LOG(2, "Volume is " << sign * volA); + } + + double volB = 0.0; + // if triangle is not in h = 0 plane, calculate volume under B + if(_polygonB.size() > 2 && !isTriangleInPlaneOfFacet(XYZ)) + { + LOG(2, "---- Treating polygon B ... "); + + calculatePolygonBarycenter(B, barycenter); + sortIntersectionPolygon(B, barycenter); + volB = calculateVolumeUnderPolygon(B, barycenter); + LOG(2, "Volume is " << sign * volB); + } + + LOG(2, "volA + volB = " << sign * (volA + volB) << std::endl << "***********"); + + return _volume = sign * (volA + volB); + + } + + // ---------------------------------------------------------------------------------- + // TransformedTriangle PRIVATE + // ---------------------------------------------------------------------------------- + + /** + * Calculates the intersection polygons A and B, performing the intersection tests + * and storing the corresponding points in the vectors _polygonA and _polygonB. + * + * @post _polygonA contains the intersection polygon A and _polygonB contains the + * intersection polygon B. + * + */ + void TransformedTriangle::calculateIntersectionPolygons() + { + assert(_polygonA.size() == 0); + assert(_polygonB.size() == 0); + // avoid reallocations in push_back() by pre-allocating enough memory + // we should never have more than 20 points + _polygonA.reserve(20); + _polygonB.reserve(20); + // -- surface intersections + // surface - edge + for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1)) + { + if(testSurfaceEdgeIntersection(edge)) + { + double* ptA = new double[3]; + calcIntersectionPtSurfaceEdge(edge, ptA); + _polygonA.push_back(ptA); + LOG(3,"Surface-edge : " << vToStr(ptA) << " added to A "); + if(edge >= XY) + { + double* ptB = new double[3]; + copyVector3(ptA, ptB); + _polygonB.push_back(ptB); + LOG(3,"Surface-edge : " << vToStr(ptB) << " added to B "); + } + + } + } + + // surface - ray + for(TetraCorner corner = X ; corner < NO_TET_CORNER ; corner = TetraCorner(corner + 1)) + { + if(testSurfaceRayIntersection(corner)) + { + double* ptB = new double[3]; + copyVector3(&COORDS_TET_CORNER[3 * corner], ptB); + _polygonB.push_back(ptB); + LOG(3,"Surface-ray : " << vToStr(ptB) << " added to B"); + } + } + + // -- segment intersections + for(TriSegment seg = PQ ; seg < NO_TRI_SEGMENT ; seg = TriSegment(seg + 1)) + { + + bool isZero[NO_DP]; + + // check beforehand which double-products are zero + for(DoubleProduct dp = C_YZ; dp < NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[dp] = (calcStableC(seg, dp) == 0.0); + } + + // segment - facet + for(TetraFacet facet = OYZ ; facet < NO_TET_FACET ; facet = TetraFacet(facet + 1)) + { + // is this test worth it? + const bool doTest = + !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet]] && + !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet + 1]] && + !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet + 2]]; + + if(doTest && testSegmentFacetIntersection(seg, facet)) + { + double* ptA = new double[3]; + calcIntersectionPtSegmentFacet(seg, facet, ptA); + _polygonA.push_back(ptA); + LOG(3,"Segment-facet : " << vToStr(ptA) << " added to A"); + if(facet == XYZ) + { + double* ptB = new double[3]; + copyVector3(ptA, ptB); + _polygonB.push_back(ptB); + LOG(3,"Segment-facet : " << vToStr(ptB) << " added to B"); + } + + } + } + + // segment - edge + for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1)) + { + const DoubleProduct edge_dp = DoubleProduct(edge); + + if(isZero[edge_dp] && testSegmentEdgeIntersection(seg, edge)) + { + double* ptA = new double[3]; + calcIntersectionPtSegmentEdge(seg, edge, ptA); + _polygonA.push_back(ptA); + LOG(3,"Segment-edge : " << vToStr(ptA) << " added to A"); + if(edge >= XY) + { + double* ptB = new double[3]; + copyVector3(ptA, ptB); + _polygonB.push_back(ptB); + } + } + } + + // segment - corner + for(TetraCorner corner = O ; corner < NO_TET_CORNER ; corner = TetraCorner(corner + 1)) + { + const bool doTest = + isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner] )] && + isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner+1] )] && + isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner+2] )]; + + if(doTest && testSegmentCornerIntersection(seg, corner)) + { + double* ptA = new double[3]; + copyVector3(&COORDS_TET_CORNER[3 * corner], ptA); + _polygonA.push_back(ptA); + LOG(3,"Segment-corner : " << vToStr(ptA) << " added to A"); + if(corner != O) + { + double* ptB = new double[3]; + _polygonB.push_back(ptB); + copyVector3(&COORDS_TET_CORNER[3 * corner], ptB); + LOG(3,"Segment-corner : " << vToStr(ptB) << " added to B"); + } + } + } + + // segment - ray + for(TetraCorner corner = X ; corner < NO_TET_CORNER ; corner = TetraCorner(corner + 1)) + { + if(isZero[DP_SEGMENT_RAY_INTERSECTION[7*(corner-1)]] && testSegmentRayIntersection(seg, corner)) + { + double* ptB = new double[3]; + copyVector3(&COORDS_TET_CORNER[3 * corner], ptB); + _polygonB.push_back(ptB); + LOG(3,"Segment-ray : " << vToStr(ptB) << " added to B"); + } + } + + // segment - halfstrip + for(TetraEdge edge = XY ; edge <= ZX ; edge = TetraEdge(edge + 1)) + { + +#if 0 + const int edgeIdx = int(edge) - 3; // offset since we only care for edges XY - ZX + const bool doTest = + !isZero[DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIdx]] && + !isZero[DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIdx+1]]; + + + if(doTest && testSegmentHalfstripIntersection(seg, edge)) +#endif + if(testSegmentHalfstripIntersection(seg, edge)) + { + double* ptB = new double[3]; + calcIntersectionPtSegmentHalfstrip(seg, edge, ptB); + _polygonB.push_back(ptB); + LOG(3,"Segment-halfstrip : " << vToStr(ptB) << " added to B"); + } + } + } + + // inclusion tests + for(TriCorner corner = P ; corner < NO_TRI_CORNER ; corner = TriCorner(corner + 1)) + { + // { XYZ - inclusion only possible if in Tetrahedron? + // tetrahedron + if(testCornerInTetrahedron(corner)) + { + double* ptA = new double[3]; + copyVector3(&_coords[5*corner], ptA); + _polygonA.push_back(ptA); + LOG(3,"Inclusion tetrahedron : " << vToStr(ptA) << " added to A"); + } + + // XYZ - plane + if(testCornerOnXYZFacet(corner)) + { + double* ptB = new double[3]; + copyVector3(&_coords[5*corner], ptB); + _polygonB.push_back(ptB); + LOG(3,"Inclusion XYZ-plane : " << vToStr(ptB) << " added to B"); + } + + // projection on XYZ - facet + if(testCornerAboveXYZFacet(corner)) + { + double* ptB = new double[3]; + copyVector3(&_coords[5*corner], ptB); + ptB[2] = 1 - ptB[0] - ptB[1]; + assert(epsilonEqual(ptB[0]+ptB[1]+ptB[2] - 1, 0.0)); + _polygonB.push_back(ptB); + LOG(3,"Projection XYZ-plane : " << vToStr(ptB) << " added to B"); + } + + } + + } + + /** + * Calculates the barycenters of the given intersection polygon. + * + * @pre the intersection polygons have been calculated with calculateIntersectionPolygons() + * + * @param poly one of the two intersection polygons + * @param barycenter array of three doubles where barycenter is stored + * + */ + void TransformedTriangle::calculatePolygonBarycenter(const IntersectionPolygon poly, double* barycenter) + { + LOG(3,"--- Calculating polygon barycenter"); + + // get the polygon points + std::vector& polygon = (poly == A) ? _polygonA : _polygonB; + + // calculate barycenter + const int m = polygon.size(); + + for(int j = 0 ; j < 3 ; ++j) + { + barycenter[j] = 0.0; + } + + if(m != 0) + { + for(int i = 0 ; i < m ; ++i) + { + const double* pt = polygon[i]; + for(int j = 0 ; j < 3 ; ++j) + { + barycenter[j] += pt[j] / double(m); + } + } + } + LOG(3,"Barycenter is " << vToStr(barycenter)); + } + + /** + * Sorts the given intersection polygon in circular order around its barycenter. + * @pre the intersection polygons have been calculated with calculateIntersectionPolygons() + * @post the vertices in _polygonA and _polygonB are sorted in circular order around their + * respective barycenters + * + * @param poly one of the two intersection polygons + * @param barycenter array of three doubles with the coordinates of the barycenter + * + */ + void TransformedTriangle::sortIntersectionPolygon(const IntersectionPolygon poly, const double* barycenter) + { + LOG(3,"--- Sorting polygon ..."); + + using INTERP_KERNEL::ProjectedCentralCircularSortOrder; + typedef ProjectedCentralCircularSortOrder SortOrder; // change is only necessary here and in constructor + typedef SortOrder::CoordType CoordType; + + // get the polygon points + std::vector& polygon = (poly == A) ? _polygonA : _polygonB; + + if(polygon.size() == 0) + return; + + // determine type of sorting + CoordType type = SortOrder::XY; + if(poly == A && !isTriangleInclinedToFacet( OXY )) // B is on h = 0 plane -> ok + { + // NB : the following test is never true if we have eliminated the + // triangles parallel to x == 0 and y == 0 in calculateIntersectionVolume(). + // We keep the test here anyway, to avoid interdependency. + + // is triangle inclined to x == 0 ? + if(isTriangleInclinedToFacet(OZX)) + { + type = SortOrder::XZ; + } + else //if(isTriangleParallelToFacet(OYZ)) + { + type = SortOrder::YZ; + } + } + + // create order object + SortOrder order(barycenter, type); + + // sort vector with this object + // NB : do not change place of first object, with respect to which the order + // is defined + sort((polygon.begin()), polygon.end(), order); + + LOG(3,"Sorted polygon is "); + for(size_t i = 0 ; i < polygon.size() ; ++i) + { + LOG(3,vToStr(polygon[i])); + } + + } + + /** + * Calculates the volume between the given polygon and the z = 0 plane. + * + * @pre the intersection polygones have been calculated with calculateIntersectionPolygons(), + * and they have been sorted in circular order with sortIntersectionPolygons(void) + * + * @param poly one of the two intersection polygons + * @param barycenter array of three doubles with the coordinates of the barycenter + * @return the volume between the polygon and the z = 0 plane + * + */ + double TransformedTriangle::calculateVolumeUnderPolygon(IntersectionPolygon poly, const double* barycenter) + { + LOG(2,"--- Calculating volume under polygon"); + + // get the polygon points + std::vector& polygon = (poly == A) ? _polygonA : _polygonB; + + double vol = 0.0; + const int m = polygon.size(); + + for(int i = 0 ; i < m ; ++i) + { + const double* ptCurr = polygon[i]; // pt "i" + const double* ptNext = polygon[(i + 1) % m]; // pt "i+1" (pt m == pt 0) + + const double factor1 = ptCurr[2] + ptNext[2] + barycenter[2]; + const double factor2 = + ptCurr[0]*(ptNext[1] - barycenter[1]) + + ptNext[0]*(barycenter[1] - ptCurr[1]) + + barycenter[0]*(ptCurr[1] - ptNext[1]); + vol += (factor1 * factor2) / 6.0; + } + + LOG(2,"Abs. Volume is " << vol); + return vol; + } + + + //////////////////////////////////////////////////////////////////////////////////// + // Detection of (very) degenerate cases ///////////// + //////////////////////////////////////////////////////////////////////////////////// + + /** + * Checks if the triangle lies in the plane of a given facet + * + * @param facet one of the facets of the tetrahedron + * @return true if PQR lies in the plane of the facet, false if not + */ + bool TransformedTriangle::isTriangleInPlaneOfFacet(const TetraFacet facet) const + { + + // coordinate to check + const int coord = static_cast(facet); + + for(TriCorner c = P ; c < NO_TRI_CORNER ; c = TriCorner(c + 1)) + { + if(_coords[5*c + coord] != 0.0) + { + return false; + } + } + + return true; + } + + /** + * Checks if the triangle is parallel to the given facet + * + * @param facet one of the facets of the unit tetrahedron + * @return true if triangle is parallel to facet, false if not + */ + bool TransformedTriangle::isTriangleParallelToFacet(const TetraFacet facet) const + { + // coordinate to check + const int coord = static_cast(facet); + return (_coords[5*P + coord] == _coords[5*Q + coord]) && (_coords[5*P + coord] == _coords[5*R + coord]); + } + + /** + * Checks if the triangle is not perpedicular to the given facet + * + * @param facet one of the facets of the unit tetrahedron + * @return zero if the triangle is perpendicular to the facet, + * else 1 or -1 depending on the sign of cross product of facet edges + */ + int TransformedTriangle::isTriangleInclinedToFacet(const TetraFacet facet) const + { + // coordinate to check + const int coord = static_cast(facet); + const int ind1 = ( coord+1 ) % 3, ind2 = ( coord+2 ) % 3; + const double uv_xy[4] = + { + // u_x, u_y + _coords[5*Q+ind1] - _coords[5*P+ind1], _coords[5*Q+ind2] - _coords[5*P+ind2], + // v_x, v_y + _coords[5*R+ind1] - _coords[5*P+ind1], _coords[5*R+ind2] - _coords[5*P+ind2] + }; + + double sign = uv_xy[0] * uv_xy[3] - uv_xy[1] * uv_xy[2]; + return (sign < 0.) ? -1 : (sign > 0.) ? 1 : 0; + } + + /** + * Determines whether the triangle is below the z-plane. + * + * @return true if the z-coordinate of the three corners of the triangle are all less than 0, false otherwise. + */ + bool TransformedTriangle::isTriangleBelowTetraeder() const + { + for(TriCorner c = P ; c < NO_TRI_CORNER ; c = TriCorner(c + 1)) + { + // check z-coords for all points + if(_coords[5*c + 2] >= 0.0) + { + return false; + } + } + return true; + } + + /** + * Prints the coordinates of the triangle to std::cout + * + */ + void TransformedTriangle::dumpCoords() const + { + std::cout << "Coords : "; + for(int i = 0 ; i < 3; ++i) + { + std::cout << vToStr(&_coords[5*i]) << ","; + } + std::cout << std::endl; + } + + } // NAMESPACE diff --git a/src/INTERP_KERNEL/TransformedTriangle.hxx b/src/INTERP_KERNEL/TransformedTriangle.hxx new file mode 100644 index 000000000..f8933724c --- /dev/null +++ b/src/INTERP_KERNEL/TransformedTriangle.hxx @@ -0,0 +1,375 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TRANSFORMED_TRIANGLE_HXX__ +#define __TRANSFORMED_TRIANGLE_HXX__ + +#include "INTERPKERNELDefines.hxx" + +#include + +// Levels : +// 1 - overview of algorithm + volume result +// 2 - algorithm detail +// 3 - intersection polygon results detail +// 4 - intersection polygon search detail +// higher -> misc. gory details of calculation + +#include "Log.hxx" + +namespace INTERP_TEST +{ + class TransformedTriangleTest; + class TransformedTriangleIntersectTest; +} + + +namespace INTERP_KERNEL +{ + + /** \class TransformedTriangle + * \brief Class representing one of the faces of the triangulated source polyhedron after having been transformed + * with the affine transform that takes the target tetrahedron to the unit tetrahedron. It contains the + * logic for calculating the volume of intersection between the triangle and the unit tetrahedron. + * + * \see TransformedTriangle.hxx + * + * Reference : J. Grandy, "Conservative Remapping and Region Overlays by Intersecting Arbitrary Polyhedra", + * Journal of Computational Physics (1999) + * + */ + + /** \file TransformedTriangle.hxx + * + * OVERVIEW of how the class works : (details can be found in the documentation of each method) + * + * Constructor : + * The constructor takes as arguments three pointers to double[3] vectors holding the transformed + * coordinates of the corners of the triangle. It copies their coordinates and then proceeds to pre-calculating certain + * entities used in the intersection calculation : the double products, triple products and the values of the function E + * (Grandy, [53]). + * + * calculateIntersectionVolume() : + * This is the only method in the public interface. It calculates the volume under the intersection polygons + * between the triangle and the unit tetrahedron, as described in Grandy, pp. 435-447. It does this by first calculating the + * intersection polygons A and B, with the method calculateIntersectionPolygons(). It then calculates the barycenter of each + * polygon in calculatePolygonBarycenter(), and sorts their points in a circular order around the barycenter in + * sortIntersecionPolygon(). The sorting is done with STL sort, using the order defined in the class + * ProjectedCentralCircularSortOrder. The volume under each polygon is then calculated with calculateVolumeUnderPolygon(), which + * implements formula [34] in Grandy. + * + * calculateIntersectionPolygons() : + * This method goes through all the possible ways in which the triangle can intersect the tetrahedron and tests for these + * types of intersections in accordance with the formulas described in Grandy. These tests are implemented in the test* - methods. + * The formulas in the article are stated for one case each only, while the calculation must take into account all cases. + * To this end, a number of tables, implemented as static const arrays of different types, are used. The tables + * mainly contain values of the different enumeration types described at the beginning of the class interface. For example, + * the formula Grandy gives for the segment-halfstrip intersection tests ([30]) is for use with the halfstrip above the zx edge. + * For the other two halfstrips (above the xy and yz edges), other double products are used, which + * are stored in the table DP_FOR_HALFSTRIP_INTERSECTION. This allows us to treat + * all the edges equally, avoiding switch() - statements. It is the careful choice of order of the enumeration types that makes this + * possible. Notably, there is a correspondance between the TetraEdge type and the DoubleProduct type (see Grandy, table III) that + * is used throughout the code, permitting statements such as DoubleProduct(some_edge) to work. + * When an intersection point has been detected it is calculated with a corresponding calc* - method in the cases where it + * is not known directly. It is then added to the polygon A and/or B as necessary. + * + * OPTIMIZE : + * If OPTIMIZE is defined, a large number of methods will be prefixed with inline and some optimizations concerning the tests + * with zero double products will be used. + */ + class INTERPKERNEL_EXPORT TransformedTriangle + { + + + public: + + friend class INTERP_TEST::TransformedTriangleTest; + friend class INTERP_TEST::TransformedTriangleIntersectTest; + /* + * Enumerations representing the different geometric elements of the unit tetrahedron + * and the triangle. The end element, NO_* gives the number of elements in the enumeration + * and can be used as end element in loops. + */ + + /// Corners of tetrahedron + enum TetraCorner { O = 0, X, Y, Z, NO_TET_CORNER }; + + /// Edges of tetrahedron + enum TetraEdge { OX = 0, OY, OZ, XY, YZ, ZX, H01, H10, NO_TET_EDGE }; + + /// Facets (faces) of tetrahedron + enum TetraFacet { OYZ = 0, OZX, OXY, XYZ, NO_TET_FACET }; + + /// Corners of triangle + enum TriCorner { P = 0, Q, R, NO_TRI_CORNER }; + + /// Segments (edges) of triangle + enum TriSegment { PQ = 0, QR, RP, NO_TRI_SEGMENT }; + + /// Intersection polygons + enum IntersectionPolygon{ A = 0, B, NO_INTERSECTION_POLYGONS }; + + /// Double products + /// NB : order corresponds to TetraEdges (Grandy, table III) + enum DoubleProduct { C_YZ = 0, C_ZX, C_XY, C_ZH, C_XH, C_YH, C_01, C_10, NO_DP }; + + TransformedTriangle(double* p, double* q, double* r); + ~TransformedTriangle(); + + double calculateIntersectionVolume(); + + void dumpCoords() const; + + // Queries of member values used by UnitTetraIntersectionBary + + const double* getCorner(TriCorner corner) const { return _coords + 5*corner; } + + const std::vector& getPolygonA() const { return _polygonA; } + + double getVolume() const { return _volume; } + + protected: + + TransformedTriangle() { } + + // ---------------------------------------------------------------------------------- + // High-level methods called directly by calculateIntersectionVolume() + // ---------------------------------------------------------------------------------- + void calculateIntersectionPolygons(); + + void calculatePolygonBarycenter(const IntersectionPolygon poly, double* barycenter); + + void sortIntersectionPolygon(const IntersectionPolygon poly, const double* barycenter); + + double calculateVolumeUnderPolygon(IntersectionPolygon poly, const double* barycenter); + + // ---------------------------------------------------------------------------------- + // Detection of degenerate triangles + // ---------------------------------------------------------------------------------- + + bool isTriangleInPlaneOfFacet(const TetraFacet facet) const; + + bool isTriangleParallelToFacet(const TetraFacet facet) const; + + int isTriangleInclinedToFacet(const TetraFacet facet) const; + + bool isTriangleBelowTetraeder() const; + + // ---------------------------------------------------------------------------------- + // Intersection test methods and intersection point calculations + // ---------------------------------------------------------------------------------- + + inline bool testSurfaceEdgeIntersection(const TetraEdge edge) const; + + void calcIntersectionPtSurfaceEdge(const TetraEdge edge, double* pt) const; + + inline bool testSegmentFacetIntersection(const TriSegment seg, const TetraFacet facet) const; + + void calcIntersectionPtSegmentFacet(const TriSegment seg, const TetraFacet facet, double* pt) const; + + bool testSegmentEdgeIntersection(const TriSegment seg, const TetraEdge edge) const; + + void calcIntersectionPtSegmentEdge(const TriSegment seg, const TetraEdge edge, double* pt) const ; + + bool testSegmentCornerIntersection(const TriSegment seg, const TetraCorner corner) const ; + + inline bool testSurfaceRayIntersection(const TetraCorner corner) const; + + bool testSegmentHalfstripIntersection(const TriSegment seg, const TetraEdge edg); + + void calcIntersectionPtSegmentHalfstrip(const TriSegment seg, const TetraEdge edge, double* pt) const; + + bool testSegmentRayIntersection(const TriSegment seg, const TetraCorner corner) const; + + inline bool testCornerInTetrahedron(const TriCorner corner) const; + + inline bool testCornerOnXYZFacet(const TriCorner corner) const; + + inline bool testCornerAboveXYZFacet(const TriCorner corner) const; + + // ---------------------------------------------------------------------------------- + // Utility methods used in intersection tests + // ---------------------------------------------------------------------------------- + + bool testTriangleSurroundsEdge(const TetraEdge edge) const; + + inline bool testEdgeIntersectsTriangle(const TetraEdge edge) const; + + inline bool testFacetSurroundsSegment(const TriSegment seg, const TetraFacet facet) const; + + inline bool testSegmentIntersectsFacet(const TriSegment seg, const TetraFacet facet) const; + + bool testSegmentIntersectsHPlane(const TriSegment seg) const; + + bool testSurfaceAboveCorner(const TetraCorner corner) const; + + bool testTriangleSurroundsRay(const TetraCorner corner) const; + + // ---------------------------------------------------------------------------------- + // Double and triple product calculations + // ---------------------------------------------------------------------------------- + + + + bool areDoubleProductsConsistent(const TriSegment seg) const; + + void preCalculateDoubleProducts(void); + + inline void resetDoubleProducts(const TriSegment seg, const TetraCorner corner); + + double calculateDistanceCornerSegment(const TetraCorner corner, const TriSegment seg) const; + + void preCalculateTripleProducts(void); + + double calculateAngleEdgeTriangle(const TetraEdge edge) const; + + inline double calcStableC(const TriSegment seg, const DoubleProduct dp) const; + + inline double calcStableT(const TetraCorner corner) const; + + inline double calcUnstableC(const TriSegment seg, const DoubleProduct dp) const; + + double calcTByDevelopingRow(const TetraCorner corner, const int row = 1, const bool project = false) const; + + // ---------------------------------------------------------------------------------- + // Member variables + // ---------------------------------------------------------------------------------- + protected: + + /// Array holding the coordinates of the triangle's three corners + /// order : + /// [ p_x, p_y, p_z, p_h, p_H, q_x, q_y, q_z, q_h, q_H, r_x, r_y, r_z, r_h, r_H ] + double _coords[15]; + + /// Flag showing whether the double products have been calculated yet + bool _is_double_products_calculated; + + /// Flag showing whether the triple products have been calculated yet + bool _is_triple_products_calculated; + + /// Array containing the 24 double products. + /// order : c^PQ_YZ, ... ,cPQ_10, ... c^QR_YZ, ... c^RP_YZ + /// following order in enumeration DoubleProduct + double _doubleProducts[24]; + + /// Array containing the 4 triple products. + /// order : t_O, t_X, t_Y, t_Z + double _tripleProducts[4]; + + /// Vector holding the points of the intersection polygon A. + /// these points are allocated in calculateIntersectionPolygons() and liberated in the destructor + std::vector _polygonA; + + /// Vector holding the points of the intersection polygon B. + /// These points are allocated in calculateIntersectionPolygons() and liberated in the destructor + std::vector _polygonB; + + /// Array holding the coordinates of the barycenter of the polygon A + /// This point is calculated in calculatePolygonBarycenter + double _barycenterA[3]; + + /// Array holding the coordinates of the barycenter of the polygon B + /// This point is calculated in calculatePolygonBarycenter + //double _barycenterB[3]; + + /// Array of flags indicating which of the four triple products have been correctly calculated. + /// Used for asserts in debug mode + bool _validTP[4]; + + /// calculated volume for use of UnitTetraIntersectionBary + double _volume; + + /** + * Calls TransformedTriangle::testTriangleSurroundsEdge for edges OX to ZX and stores the result in + * member variable array_triangleSurroundsEdgeCache. + * + */ + void preCalculateTriangleSurroundsEdge(); + + /// Array holding results of the test testTriangleSurroundsEdge() for all the edges. + /// These are calculated in preCalculateTriangleSurroundsEdge(). + bool _triangleSurroundsEdgeCache[NO_TET_EDGE]; + + // ---------------------------------------------------------------------------------- + // Constants + // ---------------------------------------------------------------------------------- + + // offsets : 0 -> x, 1 -> y, 2 -> z, 3 -> h, 4 -> H + // corresponds to order of double products in DoubleProduct + // so that offset[C_*] gives the right coordinate + static const int DP_OFFSET_1[8]; + static const int DP_OFFSET_2[8]; + + // the coordinates used in the expansion of triple products by a given row + // in constellation (corner, row-1) + // (0,1,2,3) <=> (x,y,z,h) + static const int COORDINATE_FOR_DETERMINANT_EXPANSION[12]; + + // contains the edge of the double product used when + // expanding the triple product determinant associated with each corner + // by a given row + static const DoubleProduct DP_FOR_DETERMINANT_EXPANSION[12]; + + // values used to decide how imprecise the double products + // should be to set them to 0.0 + static const long double MACH_EPS; // machine epsilon + static const long double MULT_PREC_F; // precision of multiplications (Grandy : f) + static const long double THRESHOLD_F; // threshold for zeroing (Grandy : F/f) + + static const double TRIPLE_PRODUCT_ANGLE_THRESHOLD; + + // correspondance facet - double product + // Grandy, table IV + static const DoubleProduct DP_FOR_SEG_FACET_INTERSECTION[12]; + + // signs associated with entries in DP_FOR_SEGMENT_FACET_INTERSECTION + static const double SIGN_FOR_SEG_FACET_INTERSECTION[12]; + + // coordinates of corners of tetrahedron + static const double COORDS_TET_CORNER[12]; + + // indices to use in tables DP_FOR_SEG_FACET_INTERSECTION and SIGN_FOR_SEG_FACET_INTERSECTION + // for the calculation of the coordinates (x,y,z) of the intersection points + // for Segment-Facet and Segment-Edge intersections + static const int DP_INDEX[12]; + + // correspondance edge - corners + static const TetraCorner CORNERS_FOR_EDGE[12]; + + // correspondance edge - facets + // facets shared by each edge + static const TetraFacet FACET_FOR_EDGE[12]; + + // correspondance edge - corners + static const TetraEdge EDGES_FOR_CORNER[12]; + + // double products used in segment-halfstrip test + static const DoubleProduct DP_FOR_HALFSTRIP_INTERSECTION[12]; + + // double products used in segment - ray test + static const DoubleProduct DP_SEGMENT_RAY_INTERSECTION[21]; + + }; + + // include definitions of inline methods + +#include "TransformedTriangleInline.hxx" +} + + +#endif diff --git a/src/INTERP_KERNEL/TransformedTriangleInline.hxx b/src/INTERP_KERNEL/TransformedTriangleInline.hxx new file mode 100644 index 000000000..0d7cacbc4 --- /dev/null +++ b/src/INTERP_KERNEL/TransformedTriangleInline.hxx @@ -0,0 +1,283 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TRANSFORMEDTRIANGLEINLINE_HXX__ +#define __TRANSFORMEDTRIANGLEINLINE_HXX__ + +// This file contains inline versions of some of the methods in the TransformedTriangle*.cxx files. +// It replaces those methods if OPTIMIZE is defined. +// NB : most of these methods have documentation in their corresponding .cxx - file. + +// ---------------------------------------------------------------------------------- +// Optimization methods. These are only defined and used if OPTIMIZE is defined. +// ----------------------------------------------------------------------------------- + + +inline void TransformedTriangle::preCalculateTriangleSurroundsEdge() +{ + for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1)) + { + _triangleSurroundsEdgeCache[edge] = testTriangleSurroundsEdge(edge); + } +} + + +// ---------------------------------------------------------------------------------- +// TransformedTriangle_math.cxx +// ---------------------------------------------------------------------------------- + +inline void TransformedTriangle::resetDoubleProducts(const TriSegment seg, const TetraCorner corner) +{ + // set the three corresponding double products to 0.0 + static const DoubleProduct DOUBLE_PRODUCTS[12] = + { + C_YZ, C_ZX, C_XY, // O + C_YZ, C_ZH, C_YH, // X + C_ZX, C_ZH, C_XH, // Y + C_XY, C_YH, C_XH // Z + }; + + for(int i = 0 ; i < 3 ; ++i) { + const DoubleProduct dp = DOUBLE_PRODUCTS[3*corner + i]; + + LOG(6, std::endl << "resetting inconsistent dp :" << dp << " for corner " << corner); + _doubleProducts[8*seg + dp] = 0.0; + }; +} + +inline double TransformedTriangle::calcStableC(const TriSegment seg, const DoubleProduct dp) const +{ + return _doubleProducts[8*seg + dp]; +} + +inline double TransformedTriangle::calcStableT(const TetraCorner corner) const +{ + // assert(_isTripleProductsCalculated); + // assert(_validTP[corner]); + return _tripleProducts[corner]; +} + +inline double TransformedTriangle::calcUnstableC(const TriSegment seg, const DoubleProduct dp) const +{ + + // find the points of the triangle + // 0 -> P, 1 -> Q, 2 -> R + const int pt1 = seg; + const int pt2 = (seg + 1) % 3; + + // find offsets + const int off1 = DP_OFFSET_1[dp]; + const int off2 = DP_OFFSET_2[dp]; + + return _coords[5*pt1 + off1] * _coords[5*pt2 + off2] - _coords[5*pt1 + off2] * _coords[5*pt2 + off1]; +} + +// ---------------------------------------------------------------------------------- +// TransformedTriangle_intersect.cxx +// ---------------------------------------------------------------------------------- +inline bool TransformedTriangle::testSurfaceEdgeIntersection(const TetraEdge edge) const +{ + return _triangleSurroundsEdgeCache[edge] && testEdgeIntersectsTriangle(edge); +} + +inline bool TransformedTriangle::testSegmentFacetIntersection(const TriSegment seg, const TetraFacet facet) const +{ + return testFacetSurroundsSegment(seg, facet) && testSegmentIntersectsFacet(seg, facet); +} + +inline bool TransformedTriangle::testSurfaceRayIntersection(const TetraCorner corner) const +{ + return testTriangleSurroundsRay( corner ) && testSurfaceAboveCorner( corner ); +} + +inline bool TransformedTriangle::testCornerInTetrahedron(const TriCorner corner) const +{ + const double pt[4] = + { + _coords[5*corner], // x + _coords[5*corner + 1], // y + _coords[5*corner + 2], // z + _coords[5*corner + 3] // z + }; + + for(int i = 0 ; i < 4 ; ++i) + { + if(pt[i] < 0.0 || pt[i] > 1.0) + { + return false; + } + } + return true; +} + +inline bool TransformedTriangle::testCornerOnXYZFacet(const TriCorner corner) const +{ +#if 0 + const double pt[4] = + { + _coords[5*corner], // x + _coords[5*corner + 1], // y + _coords[5*corner + 2], // z + _coords[5*corner + 3] // h + }; +#endif + const double* pt = &_coords[5*corner]; + + if(pt[3] != 0.0) + { + return false; + } + + for(int i = 0 ; i < 3 ; ++i) + { + if(pt[i] < 0.0 || pt[i] > 1.0) + { + return false; + } + } + return true; +} + +inline bool TransformedTriangle::testCornerAboveXYZFacet(const TriCorner corner) const +{ + const double x = _coords[5*corner]; + const double y = _coords[5*corner + 1]; + const double h = _coords[5*corner + 3]; + const double H = _coords[5*corner + 4]; + + return h < 0.0 && H >= 0.0 && x >= 0.0 && y >= 0.0; + +} + +inline bool TransformedTriangle::testEdgeIntersectsTriangle(const TetraEdge edge) const +{ + + // assert(edge < H01); + + // correspondance edge - triple products + // for edges OX, ..., ZX (Grandy, table III) + static const TetraCorner TRIPLE_PRODUCTS[12] = + { + X, O, // OX + Y, O, // OY + Z, O, // OZ + X, Y, // XY + Y, Z, // YZ + Z, X, // ZX + }; + + // Grandy, [16] + const double t1 = calcStableT(TRIPLE_PRODUCTS[2*edge]); + const double t2 = calcStableT(TRIPLE_PRODUCTS[2*edge + 1]); + + //? should equality with zero use epsilon? + LOG(5, "testEdgeIntersectsTriangle : t1 = " << t1 << " t2 = " << t2 ); + return (t1*t2 <= 0.0) && (t1 - t2 != 0.0); +} + +inline bool TransformedTriangle::testFacetSurroundsSegment(const TriSegment seg, const TetraFacet facet) const +{ +#if 0 + const double signs[3] = + { + SIGN_FOR_SEG_FACET_INTERSECTION[3*facet], + SIGN_FOR_SEG_FACET_INTERSECTION[3*facet + 1], + SIGN_FOR_SEG_FACET_INTERSECTION[3*facet + 2] + }; +#endif + + const double* signs = &SIGN_FOR_SEG_FACET_INTERSECTION[3*facet]; + const double c1 = signs[0]*calcStableC(seg, DP_FOR_SEG_FACET_INTERSECTION[3*facet]); + const double c2 = signs[1]*calcStableC(seg, DP_FOR_SEG_FACET_INTERSECTION[3*facet + 1]); + const double c3 = signs[2]*calcStableC(seg, DP_FOR_SEG_FACET_INTERSECTION[3*facet + 2]); + + return (c1*c3 > 0.0) && (c2*c3 > 0.0); +} + +inline bool TransformedTriangle::testSegmentIntersectsFacet(const TriSegment seg, const TetraFacet facet) const +{ + // use correspondance facet a = 0 <=> offset for coordinate a in _coords + // and also correspondance segment AB => corner A + const double coord1 = _coords[5*seg + facet]; + const double coord2 = _coords[5*( (seg + 1) % 3) + facet]; + + //? should we use epsilon-equality here in second test? + LOG(5, "coord1 : " << coord1 << " coord2 : " << coord2 ); + + return (coord1*coord2 <= 0.0) && (coord1 != coord2); +} + +inline bool TransformedTriangle::testSegmentIntersectsHPlane(const TriSegment seg) const +{ + // get the H - coordinates + const double coord1 = _coords[5*seg + 4]; + const double coord2 = _coords[5*( (seg + 1) % 3) + 4]; + //? should we use epsilon-equality here in second test? + LOG(5, "coord1 : " << coord1 << " coord2 : " << coord2 ); + + return (coord1*coord2 <= 0.0) && (coord1 != coord2); +} + +inline bool TransformedTriangle::testSurfaceAboveCorner(const TetraCorner corner) const +{ + // ? There seems to be an error in Grandy -> it should be C_XY instead of C_YZ in [28]. + // ? I haven't really figured out why, but it seems to work. + const double normal = calcStableC(PQ, C_XY) + calcStableC(QR, C_XY) + calcStableC(RP, C_XY); + + LOG(6, "surface above corner " << corner << " : " << "n = " << normal << ", t = [" << calcTByDevelopingRow(corner, 1, false) << ", " << calcTByDevelopingRow(corner, 2, false) << ", " << calcTByDevelopingRow(corner, 3, false) ); + LOG(6, "] - stable : " << calcStableT(corner) ); + + //? we don't care here if the triple product is "invalid", that is, the triangle does not surround one of the + // edges going out from the corner (Grandy [53]) + if(!_validTP[corner]) + { + return ( calcTByDevelopingRow(corner, 1, false) * normal ) >= 0.0; + } + else + { + return ( calcStableT(corner) * normal ) >= 0.0; + } +} + +inline bool TransformedTriangle::testTriangleSurroundsRay(const TetraCorner corner) const +{ + // assert(corner == X || corner == Y || corner == Z); + + // double products to use for the possible corners + static const DoubleProduct DP_FOR_RAY_INTERSECTION[4] = + { + DoubleProduct(0), // O - only here to fill out and make indices match + C_10, // X + C_01, // Y + C_XY // Z + }; + + const DoubleProduct dp = DP_FOR_RAY_INTERSECTION[corner]; + + const double cPQ = calcStableC(PQ, dp); + const double cQR = calcStableC(QR, dp); + const double cRP = calcStableC(RP, dp); + + //? NB here we have no correction for precision - is this good? + // Our authority Grandy says nothing + LOG(5, "dp in triSurrRay for corner " << corner << " = [" << cPQ << ", " << cQR << ", " << cRP << "]" ); + + return ( cPQ*cQR > 0.0 ) && ( cPQ*cRP > 0.0 ); + +} +#endif diff --git a/src/INTERP_KERNEL/TransformedTriangleIntersect.cxx b/src/INTERP_KERNEL/TransformedTriangleIntersect.cxx new file mode 100644 index 000000000..a8ea63b8b --- /dev/null +++ b/src/INTERP_KERNEL/TransformedTriangleIntersect.cxx @@ -0,0 +1,590 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "TransformedTriangle.hxx" +#include +#include +#include +#include +#include "VectorUtils.hxx" + +namespace INTERP_KERNEL +{ + + // ---------------------------------------------------------------------------------- + // Correspondance tables describing all the variations of formulas. + // ---------------------------------------------------------------------------------- + + /// \brief Correspondance between facets and double products. + /// + /// This table encodes Grandy, table IV. Use 3*facet + {0,1,2} as index + const TransformedTriangle::DoubleProduct TransformedTriangle::DP_FOR_SEG_FACET_INTERSECTION[12] = + { + C_XH, C_XY, C_ZX, // OYZ + C_YH, C_YZ, C_XY, // OZX + C_ZH, C_ZX, C_YZ, // OXY + C_XH, C_YH, C_ZH // XYZ + }; + + /// \brief Signs associated with entries in DP_FOR_SEGMENT_FACET_INTERSECTION. + /// + /// This table encodes Grandy, table IV. Use 3*facet + {0,1,2} as index + const double TransformedTriangle::SIGN_FOR_SEG_FACET_INTERSECTION[12] = + { + 1.0, 1.0, -1.0, + 1.0, 1.0, -1.0, + 1.0, 1.0, -1.0, + 1.0, 1.0, 1.0 + }; + + /// \brief Coordinates of corners of tetrahedron. + /// + /// Use 3*Corner + coordinate as index + const double TransformedTriangle::COORDS_TET_CORNER[12] = + { + 0.0, 0.0, 0.0, + 1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0 + }; + + /// \brief Indices to use in tables DP_FOR_SEG_FACET_INTERSECTION and SIGN_FOR_SEG_FACET_INTERSECTION + /// for the calculation of the coordinates (x,y,z) of the intersection points + /// for Segment-Facet and Segment-Edge intersections. + /// + /// Use 3*facet + coordinate as index. -1 indicates that the coordinate is 0. + const int TransformedTriangle::DP_INDEX[12] = + { + // x, y, z + -1, 1, 2, // OYZ + 5, -1, 4, // OZX + 7, 8, -1, // OXY + 9, 10, 11 // XYZ + }; + + /// \brief Correspondance edge - corners. + /// + /// Gives the two corners associated with each edge + /// Use 2*edge + {0, 1} as index + const TransformedTriangle::TetraCorner TransformedTriangle::CORNERS_FOR_EDGE[12] = + { + O, X, // OX + O, Y, // OY + O, Z, // OZ + X, Y, // XY + Y, Z, // YZ + Z, X // ZX + }; + + /// \brief Correspondance edge - facets. + /// + /// Gives the two facets shared by and edge. Use 2*facet + {0, 1} as index + const TransformedTriangle::TetraFacet TransformedTriangle::FACET_FOR_EDGE[12] = + { + OXY, OZX, // OX + OXY, OYZ, // OY + OZX, OYZ, // OZ + OXY, XYZ, // XY + OYZ, XYZ, // YZ + OZX, XYZ // ZX + }; + + /// \brief Correspondance corners - edges. + /// + /// Gives edges meeting at a given corner. Use 3*corner + {0,1,2} as index + const TransformedTriangle::TetraEdge TransformedTriangle::EDGES_FOR_CORNER[12] = + { + OX, OY, OZ, // O + OX, XY, ZX, // X + OY, XY, YZ, // Y + OZ, ZX, YZ // Z + }; + + /// \brief Double products to use in halfstrip intersection tests. + /// + /// Use 4*(offset_edge) + {0,1,2,3} as index. offset_edge = edge - 3 (so that XY -> 0, YZ -> 1, ZX -> 2) + /// Entries with offset 0 and 1 are for the first condition (positive product) + /// and those with offset 2 and 3 are for the second condition (negative product). + const TransformedTriangle::DoubleProduct TransformedTriangle::DP_FOR_HALFSTRIP_INTERSECTION[12] = + { + C_10, C_01, C_ZH, C_10, // XY + C_01, C_XY, C_XH, C_01, // YZ + C_XY, C_10, C_YH, C_XY // ZX + }; + + /// \brief Double products to use in segment-ray test. + /// + /// Use 7*corner_offset + {0,1,2,3,4,5,6} as index. corner_offset = corner - 1 (so that X -> 0, Y-> 1, Z->2) + /// Entries with offset 0 are for first condition (zero double product) and the rest are for condition 3 (in the same + /// order as in the article) + const TransformedTriangle::DoubleProduct TransformedTriangle::DP_SEGMENT_RAY_INTERSECTION[21] = + { + C_10, C_YH, C_ZH, C_01, C_XY, C_YH, C_XY, // X + C_01, C_XH, C_ZH, C_XY, C_10, C_ZH, C_10, // Y + C_XY, C_YH, C_XH, C_10, C_01, C_XH, C_01 // Z + }; + + /** + * Calculates the point of intersection between the given edge of the tetrahedron and the + * triangle PQR. (Grandy, eq [22]) + * + * @pre testSurfaceEdgeIntersection(edge) returns true + * @param edge edge of tetrahedron + * @param pt array of three doubles in which to store the coordinates of the intersection point + */ + void TransformedTriangle::calcIntersectionPtSurfaceEdge(const TetraEdge edge, double* pt) const + { + assert(edge < H01); + + // barycentric interpolation between points A and B + // : (x,y,z)* = (1-alpha)*A + alpha*B where + // alpha = t_A / (t_A - t_B) + + const TetraCorner corners[2] = + { + CORNERS_FOR_EDGE[2*edge], + CORNERS_FOR_EDGE[2*edge + 1] + }; + + // calculate alpha + const double tA = calcStableT(corners[0]); + const double tB = calcStableT(corners[1]); + const double alpha = tA / (tA - tB); + + // calculate point + LOG(4, "corner A = " << corners[0] << " corner B = " << corners[1] ); + LOG(4, "tA = " << tA << " tB = " << tB << " alpha= " << alpha ); + for(int i = 0; i < 3; ++i) + { + + pt[i] = (1 - alpha) * COORDS_TET_CORNER[3*corners[0] + i] + + alpha * COORDS_TET_CORNER[3*corners[1] + i]; +#if 0 + pt[i] = (1 - alpha) * getCoordinateForTetCorner() + + alpha * getCoordinateForTetCorner(); +#endif + LOG(6, pt[i] ); + assert(pt[i] >= 0.0); + assert(pt[i] <= 1.0); + } + } + + /** + * Calculates the point of intersection between the given segment of the triangle + * and the given facet of the tetrahedron. (Grandy, eq. [23]) + * + * @pre testSurfaceEdgeIntersection(seg, facet) returns true + * + * @param seg segment of the triangle + * @param facet facet of the tetrahedron + * @param pt array of three doubles in which to store the coordinates of the intersection point + */ + void TransformedTriangle::calcIntersectionPtSegmentFacet(const TriSegment seg, const TetraFacet facet, double* pt) const + { + // calculate s + double s = 0.0; + for(int i = 0; i < 3; ++i) + { + const DoubleProduct dp = DP_FOR_SEG_FACET_INTERSECTION[3*facet + i]; + const double sign = SIGN_FOR_SEG_FACET_INTERSECTION[3*facet + i]; + s -= sign * calcStableC(seg, dp); + } + + assert(s != 0.0); + + // calculate coordinates of intersection point + for(int i = 0 ; i < 3; ++i) + { + const int dpIdx = DP_INDEX[3*facet + i]; + + if(dpIdx < 0) + { + pt[i] = 0.0; + } + else + { + const DoubleProduct dp = DP_FOR_SEG_FACET_INTERSECTION[dpIdx]; + const double sign = SIGN_FOR_SEG_FACET_INTERSECTION[dpIdx]; + pt[i] = -( sign * calcStableC(seg, dp) ) / s; + + LOG(4, "SegmentFacetIntPtCalc : pt[" << i << "] = " << pt[i] ); + LOG(4, "c(" << seg << ", " << dp << ") = " << sign * calcStableC(seg, dp) ); + assert(pt[i] >= 0.0); + assert(pt[i] <= 1.0); + } + } + + } + + /** + * Tests if the given segment of the triangle intersects the given edge of the tetrahedron (Grandy, eq. [20] + * If the OPTIMIZE is defined, it does not do the test the double product that should be zero. + * @param seg segment of the triangle + * @param edge edge of tetrahedron + * @return true if the segment intersects the edge + */ + bool TransformedTriangle::testSegmentEdgeIntersection(const TriSegment seg, const TetraEdge edge) const + { + { + // check condition that the double products for one of the two + // facets adjacent to the edge has a positive product + bool isFacetCondVerified = false; + TetraFacet facet[2]; + for(int i = 0 ; i < 2 ; ++i) + { + facet[i] = FACET_FOR_EDGE[2*edge + i]; + + // find the two c-values -> the two for the other edges of the facet + int idx1 = 0 ; + int idx2 = 1; + DoubleProduct dp1 = DP_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx1]; + DoubleProduct dp2 = DP_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx2]; + + if(dp1 == DoubleProduct( edge )) + { + idx1 = 2; + dp1 = DP_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx1]; + } + else if(dp2 == DoubleProduct( edge )) + { + idx2 = 2; + dp2 = DP_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx2]; + } + + const double c1 = SIGN_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx1]*calcStableC(seg, dp1); + const double c2 = SIGN_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx2]*calcStableC(seg, dp2); + + //isFacetCondVerified = isFacetCondVerified || c1*c2 > 0.0; + if(c1*c2 > 0.0) + { + isFacetCondVerified = true; + } + } + + if(!isFacetCondVerified) + { + return false; + } + else + { + return testSegmentIntersectsFacet(seg, facet[0]) || testSegmentIntersectsFacet(seg, facet[1]); + } + } + } + + /** + * Calculates the point of intersection between the given segment of the triangle + * and the given edge of the tetrahedron. (Grandy, eq. [25]) + * + * @pre testSegmentEdgeIntersection(seg, edge) returns true + * + * @param seg segment of the triangle + * @param edge edge of the tetrahedron + * @param pt array of three doubles in which to store the coordinates of the intersection point + */ + void TransformedTriangle::calcIntersectionPtSegmentEdge(const TriSegment seg, const TetraEdge edge, double* pt) const + { + assert(edge < H01); + + // get the two facets associated with the edge + static const TetraFacet FACETS_FOR_EDGE[12] = + { + OXY, OZX, // OX + OXY, OYZ, // OY + OZX, OYZ, // OZ + OXY, XYZ, // XY + OYZ, XYZ, // YZ + OZX, XYZ // ZX + }; + + const TetraFacet facets[2] = + { + FACETS_FOR_EDGE[2*edge], + FACETS_FOR_EDGE[2*edge + 1] + }; + + // calculate s for the two edges + double s[2]; + for(int i = 0; i < 2; ++i) + { + s[i] = 0.0; + for(int j = 0; j < 3; ++j) + { + const DoubleProduct dp = DP_FOR_SEG_FACET_INTERSECTION[3*facets[i] + j]; + const double sign = SIGN_FOR_SEG_FACET_INTERSECTION[3*facets[i] + j]; + s[i] += sign * calcStableC(seg, dp); + } + } + + // calculate denominator + const double denominator = s[0]*s[0] + s[1]*s[1]; + + // calculate intersection point + for(int i = 0; i < 3; ++i) + { + // calculate double product values for the two faces + double c[2]; + for(int j = 0 ; j < 2; ++j) + { + const int dpIdx = DP_INDEX[3*facets[j] + i]; + const DoubleProduct dp = DP_FOR_SEG_FACET_INTERSECTION[dpIdx]; + const double sign = SIGN_FOR_SEG_FACET_INTERSECTION[dpIdx]; + c[j] = dpIdx < 0.0 ? 0.0 : sign * calcStableC(seg, dp); + } + + // pt[i] = (c1*s1 + c2*s2) / (s1^2 + s2^2) + + pt[i] = (c[0] * s[0] + c[1] * s[1]) / denominator; + + // strange bug with -O2 enabled : assertion fails when we don't have the following + // trace - line + //std::cout << "pt[i] = " << pt[i] << std::endl; + //assert(pt[i] >= 0.0); // check we are in tetraeder + //assert(pt[i] <= 1.0); + + } + } + + + /** + * Tests if the given segment of the triangle intersects the given corner of the tetrahedron. + * (Grandy, eq. [21]). If OPTIMIZE is defined, the double products that should be zero are not verified. + * + * @param seg segment of the triangle + * @param corner corner of the tetrahedron + * @return true if the segment intersects the corner + */ + bool TransformedTriangle::testSegmentCornerIntersection(const TriSegment seg, const TetraCorner corner) const + { + + + // facets meeting at a given corner + static const TetraFacet FACETS_FOR_CORNER[12] = + { + OXY, OYZ, OZX, // O + OZX, OXY, XYZ, // X + OYZ, XYZ, OXY, // Y + OZX, XYZ, OYZ // Z + }; + + // check segment intersect a facet + for(int i = 0 ; i < 3 ; ++i) + { + const TetraFacet facet = FACETS_FOR_CORNER[3*corner + i]; + if(testSegmentIntersectsFacet(seg, facet)) + { + return true; + } + } + + return false; + } + + /** + * Tests if the given segment of the triangle intersects the half-strip above the + * given edge of the h = 0 plane. (Grandy, eq. [30]) + * + * @param seg segment of the triangle + * @param edge edge of the h = 0 plane of the tetrahedron (XY, YZ, ZX) + * @return true if the upwards ray from the corner intersects the triangle. + */ + bool TransformedTriangle::testSegmentHalfstripIntersection(const TriSegment seg, const TetraEdge edge) + { + // get right index here to avoid "filling out" array + const int edgeIndex = static_cast(edge) - 3; + + // double products used in test + // products 1 and 2 for each edge -> first condition in Grandy [30] + // products 3 and 4 for each edge -> third condition + // NB : some uncertainty whether these last are correct + static const DoubleProduct DP_FOR_HALFSTRIP_INTERSECTION[12] = + { + C_10, C_01, C_ZH, C_10, // XY + C_01, C_XY, C_XH, C_01, // YZ + C_XY, C_10, C_YH, C_XY // ZX + }; + + // facets to use in second condition (S_m) + static const TetraFacet FACET_FOR_HALFSTRIP_INTERSECTION[3] = + { + NO_TET_FACET, // XY -> special case : test with plane H = 0 + OYZ, // YZ + OZX // ZX + }; + + const double cVals[4] = + { + calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex]), + calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex + 1]), + calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex + 2]), + calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex + 3]) + }; + + const TetraFacet facet = FACET_FOR_HALFSTRIP_INTERSECTION[edgeIndex]; + + + // special case : facet H = 0 + const bool cond2 = (facet == NO_TET_FACET) ? testSegmentIntersectsHPlane(seg) : testSegmentIntersectsFacet(seg, facet); + LOG(4, "Halfstrip tests (" << seg << ", " << edge << ") : " << (cVals[0]*cVals[1] < 0.0) << ", " << cond2 << ", " << (cVals[2]*cVals[3] > 0.0) ); + LOG(4, "c2 = " << cVals[2] << ", c3 = " << cVals[3] ); + + return (cVals[0]*cVals[1] < 0.0) && cond2 && (cVals[2]*cVals[3] > 0.0); + } + + /** + * Calculates the point of intersection between the given segment of the triangle + * and the halfstrip above the given edge of the tetrahedron. (Grandy, eq. [31]) + * + * @pre testSegmentHalfstripIntersection(seg, edge) returns true + * + * @param seg segment of the triangle + * @param edge edge of the tetrahedron defining the halfstrip + * @param pt array of three doubles in which to store the coordinates of the intersection point + */ + void TransformedTriangle::calcIntersectionPtSegmentHalfstrip(const TriSegment seg, const TetraEdge edge, double* pt) const + { + assert(edge > OZ); + assert(edge < H01); + + // get right index here to avoid "filling out" array + const int edgeIndex = static_cast(edge) - 3; + assert(edgeIndex >= 0); + assert(edgeIndex < 3); + + // Barycentric interpolation on the edge + // for edge AB : (x,y,z)* = (1-alpha) * A + alpha * B + // where alpha = cB / (cB - cA) + + const double cA = calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex]); + const double cB = calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex + 1]); + assert(cA != cB); + + const double alpha = cA / (cA - cB); + + for(int i = 0; i < 3; ++i) + { + const TetraCorner corners[2] = + { + CORNERS_FOR_EDGE[2*edge], + CORNERS_FOR_EDGE[2*edge + 1] + }; + + const double cornerCoords[2] = + { + COORDS_TET_CORNER[3*corners[0] + i], + COORDS_TET_CORNER[3*corners[1] + i] + }; + + pt[i] = (1 - alpha) * cornerCoords[0] + alpha * cornerCoords[1]; + LOG(6, pt[i] ); + assert(pt[i] >= 0.0); + assert(pt[i] <= 1.0); + } + assert(epsilonEqualRelative(pt[0] + pt[1] + pt[2], 1.0)); + } + + /** + * Tests if the given segment of triangle PQR intersects the ray pointing + * in the upwards z - direction from the given corner of the tetrahedron. (Grandy eq. [29]) + * If OPTIMIZE is defined, the double product that should be zero is not verified. + * + * @param seg segment of the triangle PQR + * @param corner corner of the tetrahedron on the h = 0 facet (X, Y, or Z) + * @return true if the upwards ray from the corner intersects the segment. + */ + bool TransformedTriangle::testSegmentRayIntersection(const TriSegment seg, const TetraCorner corner) const + { + assert(corner == X || corner == Y || corner == Z); + LOG(4, "Testing seg - ray intersection for seg = " << seg << ", corner = " << corner ); + + // readjust index since O is not used + const int cornerIdx = static_cast(corner) - 1; + + // facets to use + //? not sure this is correct + static const TetraFacet FIRST_FACET_SEGMENT_RAY_INTERSECTION[3] = + { + OZX, // X + OYZ, // Y + OZX, // Z + }; + + // cond 2 + const bool cond21 = testSegmentIntersectsFacet(seg, FIRST_FACET_SEGMENT_RAY_INTERSECTION[cornerIdx]); + const bool cond22 = (corner == Z) ? testSegmentIntersectsFacet(seg, OYZ) : testSegmentIntersectsHPlane(seg); + + if(!(cond21 || cond22)) + { + LOG(4, "SR fails at cond 2 : cond21 = " << cond21 << ", cond22 = " << cond22 ); + return false; + } + + // cond 3 + const double cVals[6] = + { + calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 1]), + calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 2]), + calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 3]), + calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 4]), + calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 5]), + calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 6]), + }; + + // cond. 3 + if(( (cVals[0] + cVals[1])*(cVals[2] - cVals[3]) - cVals[4]*cVals[5] ) >= 0.0) + { + LOG(4, "SR fails at cond 3 : " << (cVals[0] + cVals[1])*(cVals[2] - cVals[3]) - cVals[4]*cVals[5] ); + } + return ( (cVals[0] + cVals[1])*(cVals[2] - cVals[3]) - cVals[4]*cVals[5] ) < 0.0; + + } + + // ///////////////////////////////////////////////////////////////////////////////// + // Utility methods used in intersection tests /////////////// + // ///////////////////////////////////////////////////////////////////////////////// + /** + * Tests if the triangle PQR surrounds the axis on which the + * given edge of the tetrahedron lies. + * + * @param edge edge of tetrahedron + * @return true if PQR surrounds edge, false if not (see Grandy, eq. [53]) + */ + bool TransformedTriangle::testTriangleSurroundsEdge(const TetraEdge edge) const + { + // NB DoubleProduct enum corresponds to TetraEdge enum according to Grandy, table III + // so we can use the edge directly + + const double cPQ = calcStableC(PQ, DoubleProduct(edge)); + const double cQR = calcStableC(QR, DoubleProduct(edge)); + const double cRP = calcStableC(RP, DoubleProduct(edge)); + + LOG(5, "TriangleSurroundsEdge : edge = " << edge << " c = [" << cPQ << ", " << cQR << ", " << cRP << "]" ); + + // if two or more c-values are zero we disallow x-edge intersection + // Grandy, p.446 + const int numZeros = (cPQ == 0.0 ? 1 : 0) + (cQR == 0.0 ? 1 : 0) + (cRP == 0.0 ? 1 : 0); + + if(numZeros >= 2 ) + { + LOG(5, "TriangleSurroundsEdge test fails due to too many 0 dp" ); + } + + return (cPQ*cQR >= 0.0) && (cQR*cRP >= 0.0) && (cRP*cPQ >= 0.0) && numZeros < 2; + } + +} // NAMESPACE diff --git a/src/INTERP_KERNEL/TransformedTriangleMath.cxx b/src/INTERP_KERNEL/TransformedTriangleMath.cxx new file mode 100644 index 000000000..4dd23859c --- /dev/null +++ b/src/INTERP_KERNEL/TransformedTriangleMath.cxx @@ -0,0 +1,490 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "TransformedTriangle.hxx" +#include +#include +#include +#include +#include +#include +#include + +#include "VectorUtils.hxx" + +namespace INTERP_KERNEL +{ + + // ---------------------------------------------------------------------------------- + // Tables + // ---------------------------------------------------------------------------------- + + /// Table with first coordinate (a) used to calculate double product c^pq_ab = p_a * q_b - p_b * q_a (index to be used : DoubleProduct) + const int TransformedTriangle::DP_OFFSET_1[8] = {1, 2, 0, 2, 0, 1, 4, 1}; + + /// Table with second coordinate (b) used to calculate double product c^pq_ab = p_a * q_b - p_b * q_a (index to be used : DoubleProduct) + const int TransformedTriangle::DP_OFFSET_2[8] = {2, 0, 1, 3, 3, 3, 0, 4}; + + /// Coordinates used to calculate triple products by the expanding one of the three rows of the determinant (index to be used : 3*Corner + row) + const int TransformedTriangle::COORDINATE_FOR_DETERMINANT_EXPANSION[12] = + { + // row 1, 2, 3 + 0, 1, 2, // O + 3, 1, 2, // X + 0, 3, 2, // Y + 0, 1, 3 // Z + }; + + /// Double products used to calculate triple products by expanding one of the three rows of the determinant (index to be used : 3*Corner + row) + const TransformedTriangle::DoubleProduct TransformedTriangle::DP_FOR_DETERMINANT_EXPANSION[12] = + { + // row 1, 2, 3 + C_YZ, C_ZX, C_XY, // O + C_YZ, C_ZH, C_YH, // X + C_ZH, C_ZX, C_XH, // Y + C_YH, C_XH, C_XY // Z + }; + + /// The machine epsilon, used in precision corrections + const long double TransformedTriangle::MACH_EPS = std::numeric_limits::epsilon(); + + /// 4.0 * the machine epsilon, represents the precision of multiplication when performing corrections corrections ( f in Grandy ) + const long double TransformedTriangle::MULT_PREC_F = 4.0 * TransformedTriangle::MACH_EPS; + + /// Threshold for resetting double and triple products to zero; ( F / f in Grandy ) + const long double TransformedTriangle::THRESHOLD_F = 500.0; + + /// Threshold for what is considered a small enough angle to warrant correction of triple products by Grandy, [57] + const double TransformedTriangle::TRIPLE_PRODUCT_ANGLE_THRESHOLD = 0.1; + + // ---------------------------------------------------------------------------------- + // Double and triple product calculations + // ---------------------------------------------------------------------------------- + + /** + * Pre-calculates all double products for this triangle, and stores + * them internally. This method makes compensation for precision errors, + * and it is thus the "stable" double products that are stored. + * + */ + void TransformedTriangle::preCalculateDoubleProducts(void) + { + if(_is_double_products_calculated) + return; + + // -- calculate all unstable double products -- store in _doubleProducts + for(TriSegment seg = PQ ; seg <= RP ; seg = TriSegment(seg + 1)) + { + for(DoubleProduct dp = C_YZ ; dp <= C_10 ; dp = DoubleProduct(dp + 1)) + _doubleProducts[8*seg + dp] = calcUnstableC(seg, dp); + } + + std::map distances; + + // -- (1) for each segment : check that double products satisfy Grandy, [46] + // -- and make corrections if not + for(TriSegment seg = PQ ; seg <= RP ; seg = TriSegment(seg + 1)) + { + if(!areDoubleProductsConsistent(seg)) + { + LOG(4, "inconsistent! "); + for(TetraCorner corner = O ; corner <= Z ; corner = TetraCorner(corner + 1)) + { + // calculate distance corner - segment axis + const double dist = calculateDistanceCornerSegment(corner, seg); + distances.insert( std::make_pair( dist, corner ) ); + } + + // first element -> minimum distance + const TetraCorner minCorner = distances.begin()->second; + resetDoubleProducts(seg, minCorner); + distances.clear(); + } + } + + // -- (2) check that each double product statisfies Grandy, [47], else set to 0 + for(TriSegment seg = PQ ; seg <= RP ; seg = TriSegment(seg + 1)) + { + for(DoubleProduct dp = C_YZ ; dp <= C_10 ; dp = DoubleProduct(dp + 1)) + { + // find the points of the triangle + // 0 -> P, 1 -> Q, 2 -> R + const int pt1 = seg; + const int pt2 = (seg + 1) % 3; + + // find offsets + const int off1 = DP_OFFSET_1[dp]; + const int off2 = DP_OFFSET_2[dp]; + + const double term1 = _coords[5*pt1 + off1] * _coords[5*pt2 + off2]; + const double term2 = _coords[5*pt1 + off2] * _coords[5*pt2 + off1]; + + const long double delta = MULT_PREC_F * ( std::fabs(term1) + std::fabs(term2) ); + + if( epsilonEqual(_doubleProducts[8*seg + dp], 0.0, THRESHOLD_F * delta)) + { + // debug output +#if LOG_LEVEL >= 5 + if(_doubleProducts[8*seg + dp] != 0.0) + { + LOG(5, "Double product for (seg,dp) = (" << seg << ", " << dp << ") = " ); + LOG(5, std::fabs(_doubleProducts[8*seg + dp]) << " is imprecise, reset to 0.0" ); + } +#endif + + + _doubleProducts[8*seg + dp] = 0.0; + + } + } + } + + _is_double_products_calculated = true; + } + + /** + * Checks if the double products for a given segment are consistent, as defined by + * Grandy, [46]. + * + * @param seg Segment for which to check consistency of double products + * @return true if the double products are consistent, false if not + */ + bool TransformedTriangle::areDoubleProductsConsistent(const TriSegment seg) const + { + const double term1 = _doubleProducts[8*seg + C_YZ] * _doubleProducts[8*seg + C_XH]; + const double term2 = _doubleProducts[8*seg + C_ZX] * _doubleProducts[8*seg + C_YH]; + const double term3 = _doubleProducts[8*seg + C_XY] * _doubleProducts[8*seg + C_ZH]; + + LOG(2, "for seg " << seg << " consistency " << term1 + term2 + term3 ); + LOG(2, "term1 :" << term1 << " term2 :" << term2 << " term3: " << term3 ); + + const int num_zero = (term1 == 0.0 ? 1 : 0) + (term2 == 0.0 ? 1 : 0) + (term3 == 0.0 ? 1 : 0); + const int num_neg = (term1 < 0.0 ? 1 : 0) + (term2 < 0.0 ? 1 : 0) + (term3 < 0.0 ? 1 : 0); + const int num_pos = (term1 > 0.0 ? 1 : 0) + (term2 > 0.0 ? 1 : 0) + (term3 > 0.0 ? 1 : 0); + + assert( num_zero + num_neg + num_pos == 3 ); + + // calculated geometry is inconsistent if we have one of the following cases + // * one term zero and the other two of the same sign + // * two terms zero + // * all terms positive + // * all terms negative + if(((num_zero == 1 && num_neg != 1) || num_zero == 2 || (num_neg == 0 && num_zero != 3) || num_neg == 3 )) + { + LOG(4, "inconsistent dp found" ); + } + return !((num_zero == 1 && num_neg != 1) || num_zero == 2 || (num_neg == 0 && num_zero != 3) || num_neg == 3 ); + + } + + /** + * Calculate the shortest distance between a tetrahedron corner and a triangle segment. + * + * @param corner corner of the tetrahedron + * @param seg segment of the triangle + * @return shortest distance from the corner to the segment + */ + double TransformedTriangle::calculateDistanceCornerSegment(const TetraCorner corner, const TriSegment seg) const + { + // NB uses fact that TriSegment <=> TriCorner that is first point of segment (PQ <=> P) + const TriCorner ptP_idx = TriCorner(seg); + const TriCorner ptQ_idx = TriCorner( (seg + 1) % 3); + + const double ptP[3] = { _coords[5*ptP_idx], _coords[5*ptP_idx + 1], _coords[5*ptP_idx + 2] }; + const double ptQ[3] = { _coords[5*ptQ_idx], _coords[5*ptQ_idx + 1], _coords[5*ptQ_idx + 2] }; + + // coordinates of corner + const double ptTetCorner[3] = + { + COORDS_TET_CORNER[3*corner ], + COORDS_TET_CORNER[3*corner + 1], + COORDS_TET_CORNER[3*corner + 2] + }; + + // dist^2 = ( PQ x CP )^2 / |PQ|^2 where C is the corner point + + // difference vectors + const double diffPQ[3] = { ptQ[0] - ptP[0], ptQ[1] - ptP[1], ptQ[2] - ptP[2] }; + const double diffCornerP[3] = { ptP[0] - ptTetCorner[0], ptP[1] - ptTetCorner[1], ptP[2] - ptTetCorner[2] }; + + // cross product of difference vectors + double crossProd[3]; + cross(diffPQ, diffCornerP, crossProd); + + const double cross_squared = dot(crossProd, crossProd); + const double norm_diffPQ_squared = dot(diffPQ, diffPQ); + + assert(norm_diffPQ_squared != 0.0); + + return cross_squared / norm_diffPQ_squared; + } + + /** + * Pre-calculates all triple products for the tetrahedron with respect to + * this triangle, and stores them internally. This method takes into account + * the problem of errors due to cancellation. + * + */ + void TransformedTriangle::preCalculateTripleProducts(void) + { + if(_is_triple_products_calculated) + { + return; + } + + // find edge / row to use -> that whose edge makes the smallest angle to the triangle + // use a map to find the minimum + std::map anglesForRows; + + LOG(4, "Precalculating triple products" ); + for(TetraCorner corner = O ; corner <= Z ; corner = TetraCorner(corner + 1)) + { + LOG(6, "- Triple product for corner " << corner ); + + for(int row = 1 ; row < 4 ; ++row) + { + const DoubleProduct dp = DP_FOR_DETERMINANT_EXPANSION[3*corner + (row - 1)]; + + // get edge by using correspondance between Double Product and Edge + TetraEdge edge = TetraEdge(dp); + + // use edge only if it is surrounded by the surface + if( _triangleSurroundsEdgeCache[edge] ) + { + // -- calculate angle between edge and PQR + const double angle = calculateAngleEdgeTriangle(edge); + anglesForRows.insert(std::make_pair(angle, row)); + } + } + + if(anglesForRows.size() != 0) // we have found a good row + { + const double minAngle = anglesForRows.begin()->first; + const int minRow = anglesForRows.begin()->second; + + if(minAngle < TRIPLE_PRODUCT_ANGLE_THRESHOLD) + { + _tripleProducts[corner] = calcTByDevelopingRow(corner, minRow, true); + } + else + { + _tripleProducts[corner] = calcTByDevelopingRow(corner, minRow, false); + } + _validTP[corner] = true; + } + else + { + // this value will not be used + // we set it to whatever + LOG(6, "Triple product not calculated for corner " << corner ); + _tripleProducts[corner] = -3.14159265; + _validTP[corner] = false; + + } + anglesForRows.clear(); + + } + + _is_triple_products_calculated = true; + } + + /** + * Calculates the angle between an edge of the tetrahedron and the triangle + * + * @param edge edge of the tetrahedron + * @return angle between triangle and edge + */ + double TransformedTriangle::calculateAngleEdgeTriangle(const TetraEdge edge) const + { + // find normal to PQR - cross PQ and PR + const double pq[3] = + { + _coords[5*Q] - _coords[5*P], + _coords[5*Q + 1] - _coords[5*P + 1], + _coords[5*Q + 2] - _coords[5*P + 2] + }; + + const double pr[3] = + { + _coords[5*R] - _coords[5*P], + _coords[5*R + 1] - _coords[5*P + 1], + _coords[5*R + 2] - _coords[5*P + 2] + }; + + double normal[3]; + + cross(pq, pr, normal); + + static const double EDGE_VECTORS[18] = + { + 1.0, 0.0, 0.0, // OX + 0.0, 1.0, 0.0, // OY + 0.0, 0.0, 1.0, // OZ + -1.0, 1.0, 0.0, // XY + 0.0,-1.0, 1.0, // YZ + 1.0, 0.0,-1.0 // ZX + }; + + const double edgeVec[3] = { + EDGE_VECTORS[3*edge], + EDGE_VECTORS[3*edge + 1], + EDGE_VECTORS[3*edge + 2], + }; + + //return angleBetweenVectors(normal, edgeVec); + + const double lenNormal = norm(normal); + const double lenEdgeVec = norm(edgeVec); + const double dotProd = dot(normal, edgeVec); + + //? is this more stable? -> no subtraction + // return asin( dotProd / ( lenNormal * lenEdgeVec ) ) + 3.141592625358979 / 2.0; + return atan(1.0)*4.0 - acos( dotProd / ( lenNormal * lenEdgeVec ) ); + + } + + /** + * Calculates triple product associated with the given corner of tetrahedron, developing + * the determinant by the given row. The triple product gives the signed volume of + * the tetrahedron between this corner and the triangle PQR. If the flag project is true, + * one coordinate is projected out in order to eliminate errors in the intersection point + * calculation due to cancellation. + * + * @pre double products have already been calculated + * @param corner corner for which the triple product is calculated + * @param row row (1 <= row <= 3) used to calculate the determinant + * @param project indicates whether or not to perform projection as inidicated in Grandy, p.446 + * @return triple product associated with corner (see Grandy, [50]-[52]) + */ + double TransformedTriangle::calcTByDevelopingRow(const TetraCorner corner, const int row, const bool project) const + { + + // OVERVIEW OF CALCULATION + // --- sign before the determinant + // the sign used depends on the sign in front of the triple product (Grandy, [15]), + // and the convention used in the definition of the double products + + // the sign in front of the determinant gives the following schema for the three terms (I): + // corner/row 1 2 3 + // O (sign:+) + - + + // X (sign:-) - + - + // Y (sign:-) - + - + // Z (sign:-) - + - + + // the 2x2 determinants are the following (C_AB <=> A_p*B_q - B_p*A_q, etc) + // corner/row 1 2 3 + // O (sign:+) C_YZ C_XZ C_XY + // X (sign:-) C_YZ C_HZ C_HY + // Y (sign:-) C_HZ C_XZ C_XH + // Z (sign:-) C_YH C_XH C_XY + + // these are represented in DP_FOR_DETERMINANT_EXPANSION, + // except for the fact that certain double products are inversed (C_AB <-> C_BA) + + // comparing with the DOUBLE_PRODUCTS and using the fact that C_AB = -C_BA + // we deduce the following schema (II) : + // corner/row 1 2 3 + // O (sign:+) + - + + // X (sign:-) + - - + // Y (sign:-) - - + + // Z (sign:-) + + + + + // comparing the two schemas (I) and (II) gives us the following matrix of signs, + // putting 1 when the signs in (I) and (II) are equal and -1 when they are different : + + static const int SIGNS[12] = + { + 1, 1, 1, + -1,-1, 1, + 1,-1,-1, + -1, 1,-1 + }; + + // find the offsets of the rows of the determinant + const int offset = COORDINATE_FOR_DETERMINANT_EXPANSION[3 * corner + (row - 1)]; + + const DoubleProduct dp = DP_FOR_DETERMINANT_EXPANSION[3 * corner + (row - 1)]; + + const int sign = SIGNS[3 * corner + (row - 1)]; + + const double cQR = calcStableC(QR, dp); + const double cRP = calcStableC(RP, dp); + const double cPQ = calcStableC(PQ, dp); + + double alpha = 0.0; + + // coordinate to use for projection (Grandy, [57]) with edges + // OX, OY, OZ, XY, YZ, ZX in order : + // (y, z, x, h, h, h) + // for the first three we could also use {2, 0, 1} + static const int PROJECTION_COORDS[6] = { 1, 2, 0, 3, 3, 3 } ; + + const int coord = PROJECTION_COORDS[ dp ]; + + // coordinate values for P, Q and R + const double coordValues[3] = { _coords[5*P + coord], _coords[5*Q + coord], _coords[5*R + coord] }; + + if(project) + { + // products coordinate values with corresponding double product + const double coordDPProd[3] = { coordValues[0] * cQR, coordValues[1] * cRP, coordValues[2] * cPQ }; + + const double sumDPProd = coordDPProd[0] + coordDPProd[1] + coordDPProd[2]; + const double sumDPProdSq = dot(coordDPProd, coordDPProd); + + // alpha = sumDPProd / sumDPProdSq; + alpha = (sumDPProdSq != 0.0) ? sumDPProd / sumDPProdSq : 0.0; + } + + const double cQRbar = cQR * (1.0 - alpha * coordValues[0] * cQR); + const double cRPbar = cRP * (1.0 - alpha * coordValues[1] * cRP); + const double cPQbar = cPQ * (1.0 - alpha * coordValues[2] * cPQ); + + // check sign of barred products - should not change + // assert(cQRbar * cQR >= 0.0); + //assert(cRPbar * cRP >= 0.0); + //assert(cPQbar * cPQ >= 0.0); + + const double p_term = _coords[5*P + offset] * cQRbar; + const double q_term = _coords[5*Q + offset] * cRPbar; + const double r_term = _coords[5*R + offset] * cPQbar; + + // check that we are not so close to zero that numerical errors could take over, + // otherwise reset to zero (cf Grandy, p. 446) +#ifdef FIXED_DELTA + const double delta = FIXED_DELTA; +#else + const long double delta = MULT_PREC_F * (std::fabs(p_term) + std::fabs(q_term) + std::fabs(r_term)); +#endif + + if( epsilonEqual( p_term + q_term + r_term, 0.0, THRESHOLD_F * delta) ) + { + LOG(4, "Reset imprecise triple product for corner " << corner << " to zero" ); + return 0.0; + } + else + { + // NB : using plus also for the middle term compensates for a double product + // which is inversely ordered + LOG(6, "Triple product for corner " << corner << ", row " << row << " = " << sign*( p_term + q_term + r_term ) ); + return sign*( p_term + q_term + r_term ); + } + + } + +} diff --git a/src/INTERP_KERNEL/TranslationRotationMatrix.hxx b/src/INTERP_KERNEL/TranslationRotationMatrix.hxx new file mode 100644 index 000000000..8310ca704 --- /dev/null +++ b/src/INTERP_KERNEL/TranslationRotationMatrix.hxx @@ -0,0 +1,130 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TRANSLATIONROTATIONMATRIX_HXX__ +#define __TRANSLATIONROTATIONMATRIX_HXX__ + +#include + +namespace INTERP_KERNEL +{ + class TranslationRotationMatrix + { + + public: + + TranslationRotationMatrix() + { + unsigned i; + for(i=0;i class InterpType > + class TriangulationIntersector : public InterpType > + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + TriangulationIntersector(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double precision, double medianPlane, int orientation, int printLevel); + double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); + double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad); + }; +} + +#endif diff --git a/src/INTERP_KERNEL/TriangulationIntersector.txx b/src/INTERP_KERNEL/TriangulationIntersector.txx new file mode 100644 index 000000000..e40e4fe9e --- /dev/null +++ b/src/INTERP_KERNEL/TriangulationIntersector.txx @@ -0,0 +1,133 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TRIANGULATIONINTERSECTOR_TXX__ +#define __TRIANGULATIONINTERSECTOR_TXX__ + +#include "TriangulationIntersector.hxx" +#include "PlanarIntersectorP0P0.txx" +#include "PlanarIntersectorP0P1.txx" +#include "PlanarIntersectorP1P0.txx" + +#include "InterpolationUtils.hxx" +#include "PlanarIntersector.hxx" + +#include + +namespace INTERP_KERNEL +{ + template class InterpType> + TriangulationIntersector::TriangulationIntersector(const MyMeshType& meshT, const MyMeshType& meshS, + double DimCaracteristic, double Precision, + double MedianPlane, int orientation, int PrintLevel) + :InterpType >(meshT,meshS,DimCaracteristic, Precision, MedianPlane, true, orientation, PrintLevel) + { + if(PlanarIntersector::_print_level >= 1) + { + std::cout << " - intersection type = triangles " << std::endl; + if(SPACEDIM==3) std::cout << "_do_rotate = true"<< std::endl; + } + } + + template class InterpType> + double TriangulationIntersector::intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS) + { + double result = 0.; + int orientation = 1; + + //Obtain the coordinates of T and S + std::vector CoordsT; + std::vector CoordsS; + PlanarIntersector::getRealCoordinates(icellT,icellS,nbNodesT,nbNodesS,CoordsT,CoordsS,orientation); + //Compute the intersection area + double area[SPACEDIM]; + for(ConnType iT = 1; iT inter; + INTERP_KERNEL::intersec_de_triangle(&CoordsT[0],&CoordsT[SPACEDIM*iT],&CoordsT[SPACEDIM*(iT+1)], + &CoordsS[0],&CoordsS[SPACEDIM*iS],&CoordsS[SPACEDIM*(iS+1)], + inter, PlanarIntersector::_dim_caracteristic, + PlanarIntersector::_precision); + ConnType nb_inter=((ConnType)inter.size())/2; + if(nb_inter >3) inter=reconstruct_polygon(inter); + for(ConnType i = 1; i(&inter[0],&inter[2*i],&inter[2*(i+1)],area); + result +=0.5*fabs(area[0]); + } + //DEBUG prints + if(PlanarIntersector::_print_level >= 3) + { + std::cout << std::endl << "Number of nodes of the intersection = "<< nb_inter << std::endl; + for(ConnType i=0; i< nb_inter; i++) + {for (int idim=0; idim<2; idim++) std::cout << inter[2*i+idim] << " "; std::cout << std::endl; } + } + } + } + + //DEBUG PRINTS + if(PlanarIntersector::_print_level >= 3) + std::cout << std::endl <<"Intersection area = " << result << std::endl; + + return orientation*result; + } + + template class InterpType> + double TriangulationIntersector::intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad) + { + double result = 0.; + ConnType nbNodesS=sourceCoords.size()/SPACEDIM; + //Compute the intersection area + double area[SPACEDIM]; + for(ConnType iT = 1; iT<3; iT++) + { + for(ConnType iS = 1; iS inter; + INTERP_KERNEL::intersec_de_triangle(quadrangle,&quadrangle[SPACEDIM*iT],&quadrangle[SPACEDIM*(iT+1)], + &sourceCoords[0],&sourceCoords[SPACEDIM*iS],&sourceCoords[SPACEDIM*(iS+1)], + inter, PlanarIntersector::_dim_caracteristic, + PlanarIntersector::_precision); + ConnType nb_inter=((ConnType)inter.size())/2; + if(nb_inter >3) inter=reconstruct_polygon(inter); + for(ConnType i = 1; i(&inter[0],&inter[2*i],&inter[2*(i+1)],area); + result +=0.5*fabs(area[0]); + } + //DEBUG prints + if(PlanarIntersector::_print_level >= 3) + { + std::cout << std::endl << "Number of nodes of the intersection = "<< nb_inter << std::endl; + for(ConnType i=0; i< nb_inter; i++) + {for (int idim=0; idim<2; idim++) std::cout << inter[2*i+idim] << " "; std::cout << std::endl; } + } + } + } + + //DEBUG PRINTS + if(PlanarIntersector::_print_level >= 3) + std::cout << std::endl <<"Intersection area = " << result << std::endl; + + return result; + } +} + +#endif diff --git a/src/INTERP_KERNEL/UnitTetraIntersectionBary.cxx b/src/INTERP_KERNEL/UnitTetraIntersectionBary.cxx new file mode 100644 index 000000000..b3e2279eb --- /dev/null +++ b/src/INTERP_KERNEL/UnitTetraIntersectionBary.cxx @@ -0,0 +1,688 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +// File : UnitTetraIntersectionBary.cxx +// Created : Tue Dec 9 16:48:49 2008 +// Author : Edward AGAPOV (eap) + +#include "UnitTetraIntersectionBary.hxx" + +#include "VectorUtils.hxx" +#include "InterpolationUtils.hxx" +#include "VolSurfFormulae.hxx" + +#define NB_TETRA_SIDES 4 +#define NB_TETRA_NODES 4 + +using namespace std; + +namespace INTERP_KERNEL +{ + enum { _X=0, _Y, _Z }; + + inline bool samePoint( const double* p1, const double* p2 ) + { + return ( p1[0]==p2[0] && p1[1]==p2[1] && p1[2]==p2[2]); + } + + //================================================================================ + /*! + * \brief Creates a ready-to-use tool + */ + //================================================================================ + + UnitTetraIntersectionBary::UnitTetraIntersectionBary():TransformedTriangle() + { + _int_volume = 0; + //init(); + } + //================================================================================ + /*! + * \brief Initializes fields + */ + //================================================================================ + + void UnitTetraIntersectionBary::init() + { + _int_volume = 0; + _faces.clear(); + } + + //================================================================================ + /*! + * \brief Stores a part of triangle common with the unit tetrahedron + * \param triangle - triangle side of other cell + */ + //================================================================================ + + void UnitTetraIntersectionBary::addSide(const TransformedTriangle& triangle) + { + _int_volume += triangle.getVolume(); + + double triNormal[3], polyNormal[3]; + crossprod<3>( triangle.getCorner(P),triangle.getCorner(Q),triangle.getCorner(R), triNormal); + + const std::vector * pPolygonA = &triangle.getPolygonA(); + if ( pPolygonA->size() < 3 ) + { + if ( !epsilonEqual( triNormal[_Z], 0 )) + return; // not vertical triangle does not intersect the unit tetra + + // Vertical triangle. Use inherited methods of TransformedTriangle to + // calculate intesection polygon + *((TransformedTriangle*)this) = triangle; // copy triangle fields + _polygonA.clear(); + _polygonB.clear(); + calculateIntersectionPolygons(); + if (this->_polygonA.size() < 3) + return; + calculatePolygonBarycenter(A, _barycenterA); + sortIntersectionPolygon(A, _barycenterA); + pPolygonA = & _polygonA; + } + + // check if polygon orientation is same as the one of triangle + vector::const_iterator p = pPolygonA->begin(), pEnd = pPolygonA->end(); + double* p1 = *p++; + double* p2 = *p; + while ( samePoint( p1, p2 ) && ++p != pEnd ) + p2 = *p; + if ( p == pEnd ) + { + clearPolygons(); + return; + } + double* p3 = *p; + while ( samePoint( p2, p3 ) && ++p != pEnd ) + p3 = *p; + if ( p == pEnd ) + { + clearPolygons(); + return ; + } + crossprod<3>( p1, p2, p3, polyNormal ); + bool reverse = ( dotprod<3>( triNormal, polyNormal ) < 0.0 ); + + // store polygon + _faces.push_back( vector< double* > () ); + vector< double* >& faceCorner = _faces.back(); + faceCorner.resize( pPolygonA->size()/* + 1*/ ); + + int i = 0; + if ( reverse ) + { + vector::const_reverse_iterator polyF = pPolygonA->rbegin(), polyEnd; + for ( polyEnd = pPolygonA->rend(); polyF != polyEnd; ++i, ++polyF ) + if ( i==0 || !samePoint( *polyF, faceCorner[i-1] )) + copyVector3( *polyF, faceCorner[i] = new double[3] ); + else + --i; + } + else + { + vector::const_iterator polyF = pPolygonA->begin(), polyEnd; + for ( polyEnd = pPolygonA->end(); polyF != polyEnd; ++i, ++polyF ) + if ( i==0 || !samePoint( *polyF, faceCorner[i-1] )) + copyVector3( *polyF, faceCorner[i] = new double[3] ); + else + --i; + } + if ( i < 3 ) + { + clearPolygons(); // free memory of _polygonA + _polygonA = faceCorner; + _faces.pop_back(); + } + else + { + if ( i < (int)pPolygonA->size() ) + faceCorner.resize( i ); + } + +#ifdef DMP_ADDSIDE + cout << "**** addSide() " << _faces.size() << endl; + for ( int i = 0; i < faceCorner.size(); ++i ) + { + double* p = faceCorner[i]; + cout << i << ": ( " << p[0] << ", " << p[1] << ", " << p[2] << " )" << endl; + } +#endif + clearPolygons(); + } + + //================================================================================ + /*! + * \brief Computes and returns coordinates of barycentre + */ + //================================================================================ + + bool UnitTetraIntersectionBary::getBary(double* baryCenter) + { + baryCenter[0] = baryCenter[1] = baryCenter[2] = -1.0; + if ( addSideFaces() < NB_TETRA_SIDES ) + { + // tetra is not intersected + if ( _int_volume != 0.0 ) + { + // tetra is fully inside the other cell + baryCenter[0] = baryCenter[1] = baryCenter[2] = 0.25; + _int_volume = 0.16666666666666666; + return true; + } + return false; + } + // Algo: + // - pick up one point P among the summits of the polyhedron + // - for each face of the polyhedron which does not contain the point : + // - compute the barycenter of the volume obtained by forming the "pyramid" with + // the face as a base and point P as a summit + // - compute the volume of the "pyramid" + // - Add up all barycenter positions weighting them with the volumes. + + baryCenter[0] = baryCenter[1] = baryCenter[2] = 0.; + + list< vector< double* > >::iterator f = _faces.begin(), fEnd = _faces.end(); + double * P = f->at(0); + + for ( ++f; f != fEnd; ++f ) + { + vector< double* >& polygon = *f; + if ( polygon.empty() ) + continue; + + bool pBelongsToPoly = false; + vector::iterator v = polygon.begin(), vEnd = polygon.end(); + for ( ; !pBelongsToPoly && v != vEnd; ++v ) + pBelongsToPoly = samePoint( P, *v ); + if ( pBelongsToPoly ) + continue; + + // Compute the barycenter of the volume. Barycenter of pyramid is on line + // ( barycenter of polygon -> P ) with 1/4 of pyramid height from polygon. + + double bary[] = { 0, 0, 0 }; + + // base polygon bary + for ( v = polygon.begin(); v != vEnd ; ++v ) + { + double* p = *v; + bary[0] += p[0]; + bary[1] += p[1]; + bary[2] += p[2]; + } + bary[0] /= polygon.size(); + bary[1] /= polygon.size(); + bary[2] /= polygon.size(); + + // pyramid volume + double vol = 0; + for ( int i = 0; i < (int)polygon.size(); ++i ) + { + double* p1 = polygon[i]; + double* p2 = polygon[(i+1)%polygon.size()]; + vol += std::fabs( calculateVolumeForTetra( p1, p2, bary, P )); + } + + // put bary on the line ( barycenter of polygon -> P ) and multiply by volume + baryCenter[0] += ( bary[0] * 0.75 + P[0] * 0.25 ) * vol; + baryCenter[1] += ( bary[1] * 0.75 + P[1] * 0.25 ) * vol; + baryCenter[2] += ( bary[2] * 0.75 + P[2] * 0.25 ) * vol; + } + if ( _int_volume < 0. ) + _int_volume = -_int_volume; + baryCenter[0] /= _int_volume; + baryCenter[1] /= _int_volume; + baryCenter[2] /= _int_volume; + + return true; + } + + //================================================================================ + /*! + * \brief Add faces of the intersection polyhedron formed on faces of the + * unit tetrahedron by sides of already added faces + * \retval int - number of faces of intersection polyhedron + */ + //================================================================================ + + int UnitTetraIntersectionBary::addSideFaces() + { + int nbPolyhedraFaces = 0; + + if ( _faces.empty() ) + return nbPolyhedraFaces; + + // ------------------------------------------- + // Detect polygons laying on sides of a tetra + // ------------------------------------------- + + bool sideAdded[NB_TETRA_SIDES] = { false, false, false, false }; + int nbAddedSides = 0; + list< vector< double* > >::iterator f = _faces.begin(), fEnd = _faces.end(); + for ( ; f != fEnd; ++f ) + { + vector< double* >& polygon = *f; + double coordSum[3] = {0,0,0}; + for ( int i = 0; i < (int)polygon.size(); ++i ) + { + double* p = polygon[i]; + coordSum[0] += p[0]; + coordSum[1] += p[1]; + coordSum[2] += p[2]; + } + for ( int j = 0; j < 3 && !sideAdded[j]; ++j ) + { + if ( coordSum[j] == 0 ) + sideAdded[j] = bool( ++nbAddedSides ); + } + if ( !sideAdded[3] && + ( epsilonEqual( (coordSum[0]+coordSum[1]+coordSum[2]) / polygon.size(), 1. ))) + sideAdded[3] = bool( ++nbAddedSides ); + } + if ( nbAddedSides == NB_TETRA_SIDES ) + return nbAddedSides; + + // --------------------------------------------------------------------------------- + // Add segments of already added polygons to future polygonal faces on sides of tetra + // --------------------------------------------------------------------------------- + + int nbIntersectPolygs = _faces.size(); + + vector< double* > * sideFaces[ 4 ]; // future polygons on sides of tetra + for ( int i = 0; i < NB_TETRA_SIDES; ++i ) + { + sideFaces[ i ]=0; + if ( !sideAdded[ i ] ) + { + _faces.push_back( vector< double* > () ); + sideFaces[ i ] = &_faces.back(); + } + } + f = _faces.begin(), fEnd = _faces.end(); + for ( int iF = 0; iF < nbIntersectPolygs; ++f, ++iF ) // loop on added intersection polygons + { + vector< double* >& polygon = *f; + for ( int i = 0; i < (int)polygon.size(); ++i ) + { + // segment ends + double* p1 = polygon[i]; + double* p2 = polygon[(i+1)%polygon.size()]; + bool p1OnSide, p2OnSide;//, onZeroSide = false; + for ( int j = 0; j < 3; ++j ) + { + if ( !sideFaces[ j ] ) + continue; + p1OnSide = ( p1[j] == 0 ); + p2OnSide = ( p2[j] == 0 ); + if ( p1OnSide && p2OnSide ) + { + // segment p1-p2 is on j-th orthogonal side of tetra + sideFaces[j]->push_back( new double[3] ); + copyVector3( p1, sideFaces[j]->back() ); + sideFaces[j]->push_back( new double[3] ); + copyVector3( p2, sideFaces[j]->back() ); + //break; + } + } + // check if the segment p1-p2 is on the inclined side + if ( sideFaces[3] && + epsilonEqual( p1[_X] + p1[_Y] + p1[_Z], 1.0 ) && + epsilonEqual( p2[_X] + p2[_Y] + p2[_Z], 1.0 )) + { + sideFaces[3]->push_back( new double[3] ); + copyVector3( p1, sideFaces[3]->back() ); + sideFaces[3]->push_back( new double[3] ); + copyVector3( p2, sideFaces[3]->back() ); + } + } + } +#ifdef DMP_ADDSIDEFACES + cout << "**** after Add segments to sides " << endl; + for ( int i = 0; i < NB_TETRA_SIDES; ++i ) + { + cout << "\t Side " << i << endl; + if ( !sideFaces[i] ) + { + cout << "\t cut by triagle" << endl; + } + else + { + vector< double* >& sideFace = *sideFaces[i]; + for ( int i = 0; i < sideFace.size(); ++i ) + { + double* p = sideFace[i]; + cout << "\t" << i << ": ( " << p[0] << ", " << p[1] << ", " << p[2] << " )" << endl; + } + } + } +#endif + + // --------------------------------------------------------------------------- + // Make closed polygons on tetra sides by adding not cut off corners of tetra + // --------------------------------------------------------------------------- + + double origin[3] = { 0,0,0 }; + + // find corners of tetra cut off by triangles of other tetra + // --------------------------------------------------------- + + // corners are coded like this: index = 1*X + 2*Y + 3*Z + // (0,0,0) -> index == 0; (0,0,1) -> index == 3 + vector< int > cutOffCorners(NB_TETRA_NODES, false), passedCorners(NB_TETRA_NODES, false); + + int nbCutOffCorners = 0; + for ( int i = 0; i < 3; ++i ) // loop on orthogonal faces of the unit tetra + { + if ( !sideFaces[i] ) continue; + vector< double* >& sideFace = *sideFaces[i]; + + int nbPoints = sideFace.size(); + if ( nbPoints == 0 ) + continue; // not intersected face at all - no cut off corners can be detected + + int ind1 = (i+1)%3, ind2 = (i+2)%3; // indices of coords on i-th tetra side + + int nbCutOnSide = 0; + bool isSegmentOnEdge; + for ( int ip = 0; ip < nbPoints; ++ip ) + { + int isSegmentEnd = ( ip % 2 ); + + double* p = sideFace[ ip ]; + double* p2 = isSegmentEnd ? 0 : sideFace[ip+1]; + + if ( !isSegmentEnd ) + isSegmentOnEdge = false; // initialize + + int cutOffIndex = -1, passThIndex = -1;// no cut off neither pass through + int pCut[] = { 0,0,0 }, pPass[] = { 0,0,0 }; + + if ( p[ind1]==0.) + { + // point is in on orthogonal edge + if ( !isSegmentEnd && p2[ind1]==0 ) + isSegmentOnEdge = true; + + if ( !isSegmentOnEdge ) + { // segment ends are on different edges + pCut[ind2] = isSegmentEnd; // believe that cutting triangles are well oriented + cutOffIndex = pCut[0] + 2*pCut[1] + 3*pCut[2]; + } + if ( p[ind2]==0. || p[ind2]==1.) + { + pPass[ind2] = int(p[ind2]); + passThIndex = pPass[0] + 2*pPass[1] + 3*pPass[2]; + } + } + else if ( p[ind2]==0.) + { + // point is on orthogonal edge + if ( !isSegmentEnd && p2[ind2]==0 ) + isSegmentOnEdge = true; + if ( !isSegmentEnd ) + {// segment ends are on different edges + pCut[ind1] = 1-isSegmentEnd; + cutOffIndex = pCut[0] + 2*pCut[1] + 3*pCut[2]; + } + if ( p[ind1]==0. || p[ind1]==1.) + { + pPass[ind1] = int(p[ind1]); + passThIndex = pPass[0] + 2*pPass[1] + 3*pPass[2]; + } + } + else if ( epsilonEqual(p[ind1] + p[ind2], 1.0 )) + { + // point is on inclined edge + if ( !isSegmentEnd && epsilonEqual(p2[ind1] + p2[ind2], 1.0 )) + isSegmentOnEdge = true; + if ( !isSegmentOnEdge ) + { //segment ends are on different edges + pCut[ind1] = isSegmentEnd; + pCut[ind2] = 1-isSegmentEnd; + cutOffIndex = pCut[0] + 2*pCut[1] + 3*pCut[2]; + } + } + else + { + continue; + } + // remember cut off and passed through points + if ( passThIndex >= 0. ) + { + passedCorners[ passThIndex ] = true; + if ( cutOffCorners[ passThIndex ] ) + { + nbCutOffCorners--; + cutOffCorners[ passThIndex ] = false; + } + } + if ( cutOffIndex >= 0. ) + { + nbCutOnSide++; + if ( !passedCorners[ cutOffIndex ] && !cutOffCorners[ cutOffIndex ] ) + { + nbCutOffCorners++; + cutOffCorners[ cutOffIndex ] = true; + } + } + } // loop on points on a unit tetra side + + if ( nbCutOnSide == 0 && nbPoints <= 2 ) + continue; // one segment laying on edge at most + + if ( nbCutOffCorners == NB_TETRA_NODES ) + break; // all tetra corners are cut off + + if ( /*nbCutOnSide <= 2 &&*/ nbPoints >= 6 ) + { + // at least 3 segments - all corners of a side are cut off + for (int cutIndex = 0; cutIndex < NB_TETRA_NODES; ++cutIndex ) + if ( cutIndex != i+1 && !passedCorners[ cutIndex ] && !cutOffCorners[ cutIndex ]) + cutOffCorners[ cutIndex ] = bool ( ++nbCutOffCorners ); + } + + } // loop on orthogonal faces of tetra + + // check if all corners are cut off on the inclined tetra side + if ( sideFaces[ XYZ ] && sideFaces[ XYZ ]->size() >= 6 ) + { + for (int cutIndex = 1; cutIndex < NB_TETRA_NODES; ++cutIndex ) + if ( !passedCorners[ cutIndex ] && !cutOffCorners[ cutIndex ]) + cutOffCorners[ cutIndex ] = bool ( ++nbCutOffCorners ); + } + + // Add to faces on tetra sides the corners not cut off by segments of intersection polygons + // ---------------------------------------------------------------------------------- + if ( nbCutOffCorners > 0 ) + { + for ( int i = 0; i < NB_TETRA_SIDES; ++i ) + { + if ( !sideFaces[ i ] ) continue; + vector< double* >& sideFace = *sideFaces[i]; + + int excludeCorner = (i + 1) % NB_TETRA_NODES; + for ( int ic = 0; ic < NB_TETRA_NODES; ++ic ) + { + if ( !cutOffCorners[ ic ] && ic != excludeCorner ) + { + sideFace.push_back( new double[3] ); + copyVector3( origin, sideFace.back() ); + if ( ic ) + sideFace.back()[ ic-1 ] = 1.0; + } + } + } + } + +#ifdef DMP_ADDSIDEFACES + cout << "**** after Add corners to sides " << endl; + for ( int i = 0; i < NB_TETRA_SIDES; ++i ) + { + cout << "\t Side " << i << endl; + if ( !sideFaces[i] ) { + cout << "\t cut by triagle" << endl; + } + else + { + vector< double* >& sideFace = *sideFaces[i]; + for ( int i = 0; i < sideFace.size(); ++i ) + { + double* p = sideFace[i]; + cout << "\t" << i << ": ( " << p[0] << ", " << p[1] << ", " << p[2] << " )" << endl; + } + } + } + cout << "Cut off corners: "; + if ( nbCutOffCorners == 0 ) + cout << "NO"; + else + for ( int ic = 0; ic < NB_TETRA_NODES; ++ic ) + cout << cutOffCorners[ ic ]; + cout << endl; +#endif + // ------------------------------------------------------------------------ + // Sort corners of filled up faces on tetra sides and exclude equal points + // ------------------------------------------------------------------------ + + int iF = 0; + for ( f = _faces.begin(); f != fEnd; ++f, ++iF ) + { + vector< double* >& face = *f; + if ( face.size() >= 3 ) + { + clearPolygons(); // free memory of _polygonA + _polygonA = face; + face.clear(); + face.reserve( _polygonA.size() ); + if ( iF >= nbIntersectPolygs ) + { // sort points of side faces + calculatePolygonBarycenter( A, _barycenterA ); + setTriangleOnSide( iF - nbIntersectPolygs ); + sortIntersectionPolygon( A, _barycenterA ); + } + // exclude equal points + vector< double* >::iterator v = _polygonA.begin(), vEnd = _polygonA.end(); + face.push_back( *v ); + *v = 0; + for ( ++v; v != vEnd; ++v ) + { + double* pPrev = face.back(); + double* p = *v; + if ( !samePoint( p, pPrev )) + { + face.push_back( p ); + *v = 0; + } + } + } + if ( face.size() < 3 ) + { // size could decrease + clearPolygons(); // free memory of _polygonA + _polygonA = face; + face.clear(); + } + else + { + nbPolyhedraFaces++; + } + } +#ifdef DMP_ADDSIDEFACES + cout << "**** after HEALING all faces " << endl; + for (iF=0, f = _faces.begin(); f != fEnd; ++f, ++iF ) + { + cout << "\t Side " << iF << endl; + vector< double* >& sideFace = *f; + for ( int i = 0; i < sideFace.size(); ++i ) + { + double* p = sideFace[i]; + cout << "\t" << i << ": ( " << p[0] << ", " << p[1] << ", " << p[2] << " )" << endl; + } + } +#endif + return nbPolyhedraFaces; + } + + //================================================================================ + /*! + * \brief set corners of inherited TransformedTriangle as corners of i-th side of + * the Unit tetra. It is necessary to sort points of faces on sides of the unit + * tetrahedron using sortIntersectionPolygon(A) + */ + //================================================================================ + + void UnitTetraIntersectionBary::setTriangleOnSide(int iSide) + { + if ( iSide >= 3 ) + iSide = 0; + for(int i = 0 ; i < 3 ; ++i) + { + _coords[5*i] = _coords[5*i + 1] = _coords[5*i + 2] = 0.; + if ( i != iSide ) + _coords[5*i + i] = 1.; + } + } + + //================================================================================ + /*! + * \brief Free memory of polygons + */ + //================================================================================ + + void UnitTetraIntersectionBary::clearPolygons(bool andFaces) + { + for(vector::iterator it = _polygonA.begin() ; it != _polygonA.end() ; ++it) + { delete[] *it; + *it = 0; + } + for(vector::iterator it = _polygonB.begin() ; it != _polygonB.end() ; ++it) + { + delete[] *it; + *it = 0; + } + + _polygonA.clear(); + _polygonB.clear(); + + if ( andFaces ) + { + list< vector< double* > >::iterator f = this->_faces.begin(), fEnd = this->_faces.end(); + for ( ; f != fEnd; ++f ) + { + vector< double* >& polygon = *f; + for(vector::iterator it = polygon.begin() ; it != polygon.end() ; ++it) + { + delete[] *it; + *it = 0; + } + } + this->_faces.clear(); + } + } + + //================================================================================ + /*! + * \brief Destructor clears coordinates of faces + */ + //================================================================================ + + UnitTetraIntersectionBary::~UnitTetraIntersectionBary() + { + clearPolygons(/*andFaces=*/true ); + } + +} diff --git a/src/INTERP_KERNEL/UnitTetraIntersectionBary.hxx b/src/INTERP_KERNEL/UnitTetraIntersectionBary.hxx new file mode 100644 index 000000000..41aa72148 --- /dev/null +++ b/src/INTERP_KERNEL/UnitTetraIntersectionBary.hxx @@ -0,0 +1,76 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +// File : UnitTetraIntersectionBary.hxx +// Created : Tue Dec 9 16:06:33 2008 +// Author : Edward AGAPOV (eap) +#ifndef __UNITTETRAINTERSECTIONBARY_HXX__ +#define __UNITTETRAINTERSECTIONBARY_HXX__ + +#include "TransformedTriangle.hxx" +#include "INTERPKERNELDefines.hxx" + +#include +#include + +namespace INTERP_KERNEL +{ + class INTERPKERNEL_EXPORT UnitTetraIntersectionBary : protected TransformedTriangle + { + public: + UnitTetraIntersectionBary(); + + void init(); + /*! + * \brief Stores a part of triangle common with the unit tetrahedron + * \param triangle - triangle side of other cell, whose calculateIntersectionVolume() + * must have already been called + */ + void addSide(const TransformedTriangle& triangle); + + /*! + * \brief Computes and return coordinates of barycentre + */ + bool getBary(double* baryCenter); + + /*! + * \brief Returns volume of intersection + * \retval double - + */ + inline double getVolume() const { return _int_volume; } + + virtual ~UnitTetraIntersectionBary(); + + private: + + int addSideFaces(); + + void setTriangleOnSide(int i); + + void clearPolygons(bool andFaces=false); + + /// volume of intersection + double _int_volume; + + /// faces of intersection polyhedron + std::list< std::vector< double* > > _faces; + }; + +} + +#endif diff --git a/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.hxx b/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.hxx new file mode 100644 index 000000000..59dd9c984 --- /dev/null +++ b/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.hxx @@ -0,0 +1,54 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __VTKNORMALIZEDUNSTRUCTUREDMESH_HXX__ +#define __VTKNORMALIZEDUNSTRUCTUREDMESH_HXX__ + +#include "NormalizedUnstructuredMesh.hxx" + +#include "vtkType.h" + +class vtkUnstructuredGrid; + +template +class INTERPKERNEL_EXPORT VTKNormalizedUnstructuredMesh : public INTERP_KERNEL::GenericMesh +{ +public: + static const int MY_SPACEDIM=3; + static const int MY_MESHDIM=MESHDIM; + typedef vtkIdType MyConnType; + static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; +public: + VTKNormalizedUnstructuredMesh(vtkUnstructuredGrid *mesh); + ~VTKNormalizedUnstructuredMesh(); + void getBoundingBox(double *boundingBox) const; + NormalizedCellType getTypeOfElement(vtkIdType eltId) const; + unsigned long getNumberOfElements() const; + unsigned long getNumberOfNodes() const; + const vtkIdType *getConnectivityPtr() const; + const double *getCoordinatesPtr() const; + const vtkIdType *getConnectivityIndexPtr() const; + void ReleaseTempArrays(); +protected: + void putinMEDFormat() const; +protected: + vtkUnstructuredGrid *_mesh_in_vtk_mode; + mutable vtkIdType *_tmp_index_array; +}; + +#endif diff --git a/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.txx b/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.txx new file mode 100644 index 000000000..01a426f87 --- /dev/null +++ b/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.txx @@ -0,0 +1,132 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __VTKNORMALIZEDUNSTRUCTUREDMESH_TXX__ +#define __VTKNORMALIZEDUNSTRUCTUREDMESH_TXX__ + +#include "VTKNormalizedUnstructuredMesh.hxx" + +#include "vtkUnstructuredGrid.h" +#include "vtkCellArray.h" +#include "vtkPoints.h" + +template +VTKNormalizedUnstructuredMesh::VTKNormalizedUnstructuredMesh(vtkUnstructuredGrid *mesh):_mesh_in_vtk_mode(mesh), + _tmp_index_array(0) +{ +} + +template +VTKNormalizedUnstructuredMesh::~VTKNormalizedUnstructuredMesh() +{ + _mesh_in_vtk_mode->Delete(); + ReleaseTempArrays(); +} + +template +void VTKNormalizedUnstructuredMesh::getBoundingBox(double *boundingBox) const +{ + double tmp[6]; + _mesh_in_vtk_mode->GetBounds(tmp); + for(unsigned i=0;i<3;i++) + { + boundingBox[i]=tmp[2*i]; + boundingBox[3+i]=tmp[2*i+1]; + } +} + +template +NormalizedCellType VTKNormalizedUnstructuredMesh::getTypeOfElement(vtkIdType eltId) const +{ + int cellType=_mesh_in_vtk_mode->GetCellType(eltId); + int convTab[30]={0,0,0,0,0,(int)NORM_TRI3,0,(int)NORM_POLYGON,0,(int)NORM_QUAD4,(int)NORM_TETRA4,0,(int)NORM_HEXA8 + 0,(int)NORM_PYRA5,0,0,0,(int)NORM_TRI6,(int)NORM_QUAD8,}; +} + +template +unsigned long VTKNormalizedUnstructuredMesh::getNumberOfElements() const +{ + return _mesh_in_vtk_mode->GetNumberOfCells(); +} + +template +unsigned long VTKNormalizedUnstructuredMesh::getNumberOfNodes() const +{ + return _mesh_in_vtk_mode->GetNumberOfPoints(); +} + +template +const vtkIdType *VTKNormalizedUnstructuredMesh::getConnectivityPtr() const +{ + vtkIdType *ret=_mesh_in_vtk_mode->GetCells()->GetPointer(); + if(_tmp_index_array) + return ret; + else + { + putinMEDFormat(); + return ret; + } +} + +template +const double *VTKNormalizedUnstructuredMesh::getCoordinatesPtr() const +{ + return (const double *)_mesh_in_vtk_mode->GetPoints()->GetVoidPointer(0); +} + +template +const vtkIdType *VTKNormalizedUnstructuredMesh::getConnectivityIndexPtr() const +{ + if(_tmp_index_array) + return _tmp_index_array; + else + { + putinMEDFormat(); + return _tmp_index_array; + } +} + +template +void VTKNormalizedUnstructuredMesh::putinMEDFormat() const +{ + long nbOfElem=getNumberOfElements(); + _tmp_index_array=new vtkIdType[nbOfElem+1]; + _tmp_index_array[0]=0; + vtkIdType *coarseConn=_mesh_in_vtk_mode->GetCells()->GetPointer(); + long ptInCC=0; + vtkIdType *finalConn=coarseConn; + for(long i=0;i +void VTKNormalizedUnstructuredMesh::ReleaseTempArrays() +{ + delete [] _tmp_index_array; + _tmp_index_array=0; +} + +#endif diff --git a/src/INTERP_KERNEL/VectorUtils.hxx b/src/INTERP_KERNEL/VectorUtils.hxx new file mode 100644 index 000000000..469b46b53 --- /dev/null +++ b/src/INTERP_KERNEL/VectorUtils.hxx @@ -0,0 +1,161 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __VECTORUTILS_HXX__ +#define __VECTORUTILS_HXX__ + +#include +#include +#include +#include +#include + +/// Precision used for tests of 3D part of INTERP_KERNEL +#define VOL_PREC 1.0e-6 + +/// Default relative tolerance in epsilonEqualRelative +#define DEFAULT_REL_TOL 1.0e-6 + +/// Default absolute tolerance in epsilonEqual and epsilonEqualRelative +#define DEFAULT_ABS_TOL 5.0e-12 + +namespace INTERP_KERNEL +{ + /** + * @param a first point. Should point on a array of size at least equal to SPACEDIM. + * @param b second point. Should point on a array of size at least equal to SPACEDIM. + */ + template + inline double getDistanceBtw2Pts(const double *a, const double *b) + { + double ret2=0.; + for(int i=0;i + +namespace INTERP_KERNEL +{ + inline void calculateBarycenterDyn(const double **pts, int nbPts, + int dim, double *bary); + + inline double calculateAreaForPolyg(const double **coords, int nbOfPtsInPolygs, + int spaceDim); + + + // =========================== + // Calculate Area for triangle + // =========================== + inline double calculateAreaForTria(const double *p1, const double *p2, + const double *p3, int spaceDim) + { + double area ; + + if ( spaceDim == 2 ) + { + area = -((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1]))/2.0; + } + else + { + area = sqrt(((p2[1]-p1[1])*(p3[2]-p1[2]) - (p3[1]-p1[1])*(p2[2]-p1[2]))* + ((p2[1]-p1[1])*(p3[2]-p1[2]) - (p3[1]-p1[1])*(p2[2]-p1[2])) + + + ((p3[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p3[2]-p1[2]))* + ((p3[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p3[2]-p1[2])) + + + ((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1]))* + ((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1])))/2.0; + } + + return area ; + } + + // ============================= + // Calculate Area for quadrangle + // ============================= + inline double calculateAreaForQuad(const double *p1, const double *p2, + const double *p3, const double *p4, + int spaceDim) + { + double area ; + + if (spaceDim==2) + { + double a1 = (p2[0]-p1[0])/4.0, a2 = (p2[1]-p1[1])/4.0; + double b1 = (p3[0]-p4[0])/4.0, b2 = (p3[1]-p4[1])/4.0; + double c1 = (p3[0]-p2[0])/4.0, c2 = (p3[1]-p2[1])/4.0; + double d1 = (p4[0]-p1[0])/4.0, d2 = (p4[1]-p1[1])/4.0; + + area = - 4.0*( b1*c2 - c1*b2 + a1*c2 - c1*a2 + + b1*d2 - d1*b2 + a1*d2 - d1*a2); + } + else + { + area = (sqrt(((p2[1]-p1[1])*(p4[2]-p1[2]) - (p4[1]-p1[1])*(p2[2]-p1[2]))* + ((p2[1]-p1[1])*(p4[2]-p1[2]) - (p4[1]-p1[1])*(p2[2]-p1[2])) + + ((p4[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p4[2]-p1[2]))* + ((p4[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p4[2]-p1[2])) + + ((p2[0]-p1[0])*(p4[1]-p1[1]) - (p4[0]-p1[0])*(p2[1]-p1[1]))* + ((p2[0]-p1[0])*(p4[1]-p1[1]) - (p4[0]-p1[0])*(p2[1]-p1[1]))) + + + sqrt(((p4[1]-p3[1])*(p2[2]-p3[2]) - (p2[1]-p3[1])*(p4[2]-p3[2]))* + ((p4[1]-p3[1])*(p2[2]-p3[2]) - (p2[1]-p3[1])*(p4[2]-p3[2])) + + ((p2[0]-p3[0])*(p4[2]-p3[2]) - (p4[0]-p3[0])*(p2[2]-p3[2]))* + ((p2[0]-p3[0])*(p4[2]-p3[2]) - (p4[0]-p3[0])*(p2[2]-p3[2])) + + ((p4[0]-p3[0])*(p2[1]-p3[1]) - (p2[0]-p3[0])*(p4[1]-p3[1]))* + ((p4[0]-p3[0])*(p2[1]-p3[1]) - (p2[0]-p3[0])*(p4[1]-p3[1]))) + )/2.0; + } + + return area ; + } + + // ==================================== + // Calculate Normal Vector for Triangle + // ==================================== + inline void calculateNormalForTria(const double *p1, const double *p2, + const double *p3, double *normal) + { + normal[0] = ((p2[1]-p1[1])*(p3[2]-p1[2]) - (p3[1]-p1[1])*(p2[2]-p1[2]))/2.0; + normal[1] = ((p3[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p3[2]-p1[2]))/2.0; + normal[2] = ((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1]))/2.0; + } + + // ====================================== + // Calculate Normal Vector for Quadrangle + // ====================================== + inline void calculateNormalForQuad(const double *p1, const double *p2, + const double *p3, const double *p4, + double *normal) + { + double xnormal1 = (p2[1]-p1[1])*(p4[2]-p1[2]) - (p4[1]-p1[1])*(p2[2]-p1[2]); + double xnormal2 = (p4[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p4[2]-p1[2]); + double xnormal3 = (p2[0]-p1[0])*(p4[1]-p1[1]) - (p4[0]-p1[0])*(p2[1]-p1[1]); + double xarea = sqrt(xnormal1*xnormal1 + xnormal2*xnormal2 + xnormal3*xnormal3); + xnormal1 = xnormal1/xarea; + xnormal2 = xnormal2/xarea; + xnormal3 = xnormal3/xarea; + xarea = calculateAreaForQuad(p1,p2,p3,p4,3); + normal[0] = xnormal1*xarea ; + normal[1] = xnormal2*xarea ; + normal[2] = xnormal3*xarea ; + } + + // =================================== + // Calculate Normal Vector for Polygon + // =================================== + inline void calculateNormalForPolyg(const double **coords, int nbOfPtsInPolygs, + double *normal) + { + double coordOfBary[3]; + + calculateBarycenterDyn(coords,nbOfPtsInPolygs,3,coordOfBary); + double xnormal1 = (coords[0][1]-coords[1][1]) * (coordOfBary[2]-coords[1][2]) + - (coords[0][2]-coords[1][2]) * (coordOfBary[1]-coords[1][1]); + + double xnormal2 = (coords[0][2]-coords[1][2]) * (coordOfBary[0]-coords[1][0]) + - (coords[0][0]-coords[1][0]) * (coordOfBary[2]-coords[1][2]); + + double xnormal3 = (coords[0][0]-coords[1][0]) * (coordOfBary[1]-coords[1][1]) + - (coords[0][1]-coords[1][1]) * (coordOfBary[0]-coords[1][0]); + + double xarea=sqrt(xnormal1*xnormal1 + xnormal2*xnormal2 + xnormal3*xnormal3); + + if ( xarea < 1.e-6 ) + { + //std::string diagnosis"Can not calculate normal - polygon is singular"; + throw std::exception(); + } + + xnormal1 = -xnormal1/xarea; + xnormal2 = -xnormal2/xarea; + xnormal3 = -xnormal3/xarea; + xarea = calculateAreaForPolyg(coords,nbOfPtsInPolygs,3); + normal[0] = xnormal1*xarea ; + normal[1] = xnormal2*xarea ; + normal[2] = xnormal3*xarea ; + } + + // ========================== + // Calculate Area for Polygon + // ========================== + inline double calculateAreaForPolyg(const double **coords, int nbOfPtsInPolygs, + int spaceDim) + { + double ret=0.; + double coordOfBary[3]; + + calculateBarycenterDyn(coords,nbOfPtsInPolygs,spaceDim,coordOfBary); + for ( int i=0; i + inline double addComponentsOfVec(const double **pts, int rk) + { + return pts[N-1][rk]+addComponentsOfVec(pts,rk); + } + + template<> + inline double addComponentsOfVec<1>(const double **pts, int rk) + { + return pts[0][rk]; + } + + template + inline void calculateBarycenter(const double **pts, double *bary) + { + bary[DIM-1]=addComponentsOfVec(pts,DIM-1)/N; + calculateBarycenter(pts,bary); + } + + template<> + inline void calculateBarycenter<2,0>(const double **pts, double *bary) + { + } + + template<> + inline void calculateBarycenter<3,0>(const double **pts, double *bary) + { + } + + template<> + inline void calculateBarycenter<4,0>(const double **pts, double *bary) + { + } + + template<> + inline void calculateBarycenter<5,0>(const double **pts, double *bary) + { + } + + template<> + inline void calculateBarycenter<6,0>(const double **pts, double *bary) + { + } + + template<> + inline void calculateBarycenter<7,0>(const double **pts, double *bary) + { + } + + template<> + inline void calculateBarycenter<8,0>(const double **pts, double *bary) + { + } + + inline void calculateBarycenterDyn(const double **pts, int nbPts, + int dim, double *bary) + { + for(int i=0;i +#include +namespace INTERP_TEST +{ + + + void BBTreeTest::setUp() + { + } + + + void BBTreeTest::tearDown() + { + } + + /** + * Test that creates a tree in 2D and check that + * the results are correct in three + * cases : + * a non matching search + * a standard case + * a bbox overlapping the bboxes of the tree + */ + void BBTreeTest::test_BBTree() { + //bbox tree creation + const int N=10; + double* bbox=new double[4*N*N]; + for (int i=0; i tree(bbox,0,0,N*N); + std::vector elems; + + //box outside the tree + double bbox1[4]={-2.0, -1.0, 0.0, 1.0}; + tree.getIntersectingElems(bbox1,elems); + CPPUNIT_ASSERT_EQUAL(0,(int)elems.size()); + elems.clear(); + + //box intersecting 4 tree elems + double bbox2[4]={2.5, 3.5, 0.5, 1.5}; + tree.getIntersectingElems(bbox2,elems); + CPPUNIT_ASSERT_EQUAL(4,(int)elems.size()); + elems.clear(); + + //box exactly superimposed to two tree elems + double bbox3[4]={5.0,6.0,7.0,9.0}; + tree.getIntersectingElems(bbox3,elems); + CPPUNIT_ASSERT_EQUAL(2,(int)elems.size()); + elems.clear(); + + double xx[2]={1.0,1.0}; + tree.getElementsAroundPoint(xx,elems); + CPPUNIT_ASSERT_EQUAL(4,(int)elems.size()); + + delete[] bbox; + } + + +} diff --git a/src/INTERP_KERNELTest/BBTreeTest.hxx b/src/INTERP_KERNELTest/BBTreeTest.hxx new file mode 100644 index 000000000..8007e0ba8 --- /dev/null +++ b/src/INTERP_KERNELTest/BBTreeTest.hxx @@ -0,0 +1,57 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TU_BB_TREE_HXX__ +#define __TU_BB_TREE_HXX__ + +#include +#include "../BBTree.txx" + +namespace INTERP_TEST +{ + + /** + * \brief Test suite testing some of the low level methods of TransformedTriangle. + * + */ + class BBTreeTest : public CppUnit::TestFixture + { + + CPPUNIT_TEST_SUITE( BBTreeTest ); + CPPUNIT_TEST( test_BBTree ); + CPPUNIT_TEST_SUITE_END(); + + + public: + void setUp(); + + void tearDown(); + + // tests + void test_BBTree(); + + }; + + + + +} + + + +#endif diff --git a/src/INTERP_KERNELTest/BasicMainTest.hxx b/src/INTERP_KERNELTest/BasicMainTest.hxx new file mode 100644 index 000000000..8220e33a0 --- /dev/null +++ b/src/INTERP_KERNELTest/BasicMainTest.hxx @@ -0,0 +1,87 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef _BASICMAINTEST_HXX_ +#define _BASICMAINTEST_HXX_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +// ============================================================================ +/*! + * Main program source for Unit Tests with cppunit package does not depend + * on actual tests, so we use the same for all partial unit tests. + */ +// ============================================================================ + +int main(int argc, char* argv[]) +{ + // --- Create the event manager and test controller + CPPUNIT_NS::TestResult controller; + + // --- Add a listener that colllects test result + CPPUNIT_NS::TestResultCollector result; + controller.addListener( &result ); + + // --- Add a listener that print dots as test run. +#ifdef WIN32 + CPPUNIT_NS::TextTestProgressListener progress; +#else + CPPUNIT_NS::BriefTestProgressListener progress; +#endif + controller.addListener( &progress ); + + // --- Get the top level suite from the registry + + CPPUNIT_NS::Test *suite = + CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest(); + + // --- Adds the test to the list of test to run + + CPPUNIT_NS::TestRunner runner; + runner.addTest( suite ); + runner.run( controller); + + // --- Print test in a compiler compatible format. + + std::ofstream testFile; + testFile.open("UnitTestsResult", std::ios::out | std::ios::trunc); + //CPPUNIT_NS::CompilerOutputter outputter( &result, std::cerr ); + CPPUNIT_NS::CompilerOutputter outputter( &result, testFile ); + outputter.write(); + + // --- Run the tests. + + bool wasSucessful = result.wasSuccessful(); + testFile.close(); + + // --- Return error code 1 if the one of test failed. + + return wasSucessful ? 0 : 1; +} + +#endif diff --git a/src/INTERP_KERNELTest/CppUnitTest.cxx b/src/INTERP_KERNELTest/CppUnitTest.cxx new file mode 100644 index 000000000..cb37e28cf --- /dev/null +++ b/src/INTERP_KERNELTest/CppUnitTest.cxx @@ -0,0 +1,19 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "CppUnitTest.hxx" diff --git a/src/INTERP_KERNELTest/CppUnitTest.hxx b/src/INTERP_KERNELTest/CppUnitTest.hxx new file mode 100644 index 000000000..6ebb88e5b --- /dev/null +++ b/src/INTERP_KERNELTest/CppUnitTest.hxx @@ -0,0 +1,84 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TU_TEST_CPPUNIT_HXX__ +#define __TU_TEST_CPPUNIT_HXX__ + +#include + +/** + * \brief Class tested by TestBogusClass : not very useful + */ +class BogusClass { + friend class TestBogusClass; + +public: + BogusClass(double _x) : x(_x) {;} + + double getX() { return x; } + +private: + double x; +}; + +/** + * \brief Class used to figure out CppUnit : not very useful + * + */ +class TestBogusClass : public CppUnit::TestFixture +{ + + CPPUNIT_TEST_SUITE( TestBogusClass ); + CPPUNIT_TEST( test1 ); + CPPUNIT_TEST( test2 ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp() { + obj = new BogusClass(3.14); + } + + void tearDown() { + delete obj; + } + + void test1() { + // test something + CPPUNIT_ASSERT(obj->x == 3.14); + CPPUNIT_ASSERT(obj->getX() == obj->x); + } + + void test2() { + // test something else + obj->x += 2.6; + CPPUNIT_ASSERT(obj->getX() > 3.14); + } + +private: + BogusClass* obj; + +}; + + + + + + + + +#endif diff --git a/src/INTERP_KERNELTest/HexaTests.hxx b/src/INTERP_KERNELTest/HexaTests.hxx new file mode 100644 index 000000000..a7f0adf1e --- /dev/null +++ b/src/INTERP_KERNELTest/HexaTests.hxx @@ -0,0 +1,75 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __HEXA_TESTS_HXX_ +#define __HEXA_TESTS_HXX_ + +#include "InterpolationTestSuite.hxx" + +namespace INTERP_TEST +{ + /** + * \brief Class performing intersection tests on meshes with hexahedral elements. + * + */ + class HexaTests : public InterpolationTestSuite<3,3> + { + CPPUNIT_TEST_SUITE( HexaTests ); + + CPPUNIT_TEST( simpleHexaBox ); + //VB : slightly inaccurate so that it triggers a failure of the test + // should be investigated in the future + // CPPUNIT_TEST( reflexiveHexaBox ); + CPPUNIT_TEST( hexaBoxes ); + CPPUNIT_TEST( hexaBoxesMoved ); + + CPPUNIT_TEST_SUITE_END(); + + public: + + /// Intersection between two boxes, aligned with the axes.One has 60 hexahedral elements and the other has 39 tetrahedral elements + /// \brief Status : pass + void simpleHexaBox() + { + _testTools->intersectMeshes("BoxHexa1", "BoxTetra2", 65250, 1.0e-5); + } + + /// Intersection of a box with 60 hexahedral elements with itself + /// \brief Status : pass + void reflexiveHexaBox() + { + _testTools->intersectMeshes("BoxHexa1", "BoxHexa1", 204000); + } + + /// Intersection between two boxes, aligned with the axes.Both have hexahedral elements : one 36, the other 60 + /// \brief Status : pass + void hexaBoxes() + { + _testTools->intersectMeshes("BoxHexa1", "BoxHexa2", 65250); + } + + /// Intersection between two boxes in general position with hexahedral elements. One has 200 elements and the other 420. + /// \brief Status : fails - reason unknown. The matrix does not fulfil the transpose requirement : that W_AB = W_BA^T + void hexaBoxesMoved() + { + _testTools->intersectMeshes("MovedHexaBox1", "MovedHexaBox2", 65250); + } + + }; +} +#endif diff --git a/src/INTERP_KERNELTest/Interpolation3DTest.cxx b/src/INTERP_KERNELTest/Interpolation3DTest.cxx new file mode 100644 index 000000000..a538c6fdb --- /dev/null +++ b/src/INTERP_KERNELTest/Interpolation3DTest.cxx @@ -0,0 +1,348 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "Interpolation3DTest.hxx" +#include "MEDMEM_Mesh.hxx" + +#include +#include +#include +#include +#include + +#include "VectorUtils.hxx" + +#include "MEDMEM_Field.hxx" +#include "MEDMEM_Support.hxx" + +// levels : +// 1 - titles and volume results +// 2 - symmetry / diagonal results and intersection matrix output +// 3 - empty +// 4 - empty +// 5 - misc +#include "Log.hxx" + + +//#define VOL_PREC 1.0e-6 + +using namespace MEDMEM; +using namespace std; +using namespace INTERP_KERNEL; +using namespace MED_EN; + +double Interpolation3DTest::sumRow(const IntersectionMatrix& m, int i) const +{ + double vol = 0.0; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + if(iter->count(i) != 0.0) + { + map::const_iterator iter2 = iter->find(i); + vol += iter2->second; + } + } + return vol; +} + +double Interpolation3DTest::sumCol(const IntersectionMatrix& m, int i) const +{ + double vol = 0.0; + const std::map& col = m[i]; + for(map::const_iterator iter = col.begin() ; iter != col.end() ; ++iter) + { + vol += std::fabs(iter->second); + } + return vol; +} + + +void Interpolation3DTest::getVolumes(MESH& mesh, double* tab) const +{ + SUPPORT *sup=new SUPPORT(&mesh,"dummy",MED_CELL); + FIELD* f=mesh.getVolume(sup); + const double *tabS=f->getValue(); + std::copy(tabS,tabS+mesh.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS),tab) + delete sup; +} + +double Interpolation3DTest::sumVolume(const IntersectionMatrix& m) const +{ + + vector volumes; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + volumes.push_back(iter2->second); + // vol += std::abs(iter2->second); + } + } + + // sum in ascending order to avoid rounding errors + + sort(volumes.begin(), volumes.end()); + const double vol = accumulate(volumes.begin(), volumes.end(), 0.0); + + return vol; +} + +bool Interpolation3DTest::testVolumes(const IntersectionMatrix& m, MESH& sMesh, MESH& tMesh) const +{ + bool ok = true; + + // source elements + double* sVol = new double[sMesh.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS)]; + getVolumes(sMesh, sVol); + + for(int i = 0; i < sMesh.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS); ++i) + { + const double sum_row = sumRow(m, i+1); + if(!epsilonEqualRelative(sum_row, sVol[i], VOL_PREC)) + { + LOG(1, "Source volume inconsistent : vol of cell " << i << " = " << sVol[i] << " but the row sum is " << sum_row ); + ok = false; + } + LOG(1, "diff = " <::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + int j = iter2->first; + const double v1 = iter2->second; + //if(m2[j - 1].count(i+1) > 0) + // { + map theMap = m2.at(j-1); + const double v2 = theMap[i + 1]; + if(v1 != v2) + { + LOG(2, "V1( " << i << ", " << j << ") = " << v1 << " which is different from V2( " << j - 1 << ", " << i + 1 << ") = " << v2 << " | diff = " << v1 - v2 ); + if(!epsilonEqualRelative(v1, v2, VOL_PREC)) + { + LOG(2, "(" << i << ", " << j << ") fails"); + isSymmetric = false; + } + } + } + ++i; + } + if(!isSymmetric) + { + LOG(1, "*** matrices are not symmetric"); + } + return isSymmetric; +} + +bool Interpolation3DTest::testDiagonal(const IntersectionMatrix& m) const +{ + LOG(1, "Checking if matrix is diagonal" ); + int i = 1; + bool isDiagonal = true; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + int j = iter2->first; + const double vol = iter2->second; + if(vol != 0.0 && (i != j)) + { + LOG(2, "V( " << i - 1 << ", " << j << ") = " << vol << " which is not zero" ); + if(!epsilonEqual(vol, 0.0, VOL_PREC)) + { + LOG(2, "(" << i << ", " << j << ") fails"); + isDiagonal = false; + } + } + } + ++i; + } + if(!isDiagonal) + { + LOG(1, "*** matrix is not diagonal"); + } + return isDiagonal; +} + +void Interpolation3DTest::dumpIntersectionMatrix(const IntersectionMatrix& m) const +{ + int i = 0; + std::cout << "Intersection matrix is " << endl; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + + std::cout << "V(" << i << ", " << iter2->first << ") = " << iter2->second << endl; + + } + ++i; + } + std::cout << "Sum of volumes = " << sumVolume(m) << std::endl; +} + +void Interpolation3DTest::setUp() +{ + interpolator = new Interpolation3D(); +} + +void Interpolation3DTest::tearDown() +{ + delete interpolator; +} + +void Interpolation3DTest::calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) const +{ + const string dataBaseDir = getenv("MED_ROOT_DIR"); + const string dataDir = dataBaseDir + "/share/salome/resources/med/"; + + LOG(1, std::endl << "=== -> intersecting src = " << mesh1 << ", target = " << mesh2 ); + + LOG(5, "Loading " << mesh1 << " from " << mesh1path); + MESH sMesh(MED_DRIVER, dataDir+mesh1path, mesh1); + + LOG(5, "Loading " << mesh2 << " from " << mesh2path); + MESH tMesh(MED_DRIVER, dataDir+mesh2path, mesh2); + + m = interpolator->interpolateMeshes(sMesh, tMesh); + + // if reflexive, check volumes + if(strcmp(mesh1path,mesh2path) == 0) + { + const bool row_and_col_sums_ok = testVolumes(m, sMesh, tMesh); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Row or column sums incorrect", true, row_and_col_sums_ok); + } + + LOG(1, "Intersection calculation done. " << std::endl ); + +} + +void Interpolation3DTest::intersectMeshes(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, const double correctVol, const double prec, bool doubleTest) const +{ + LOG(1, std::endl << std::endl << "=============================" ); + + using std::string; + const string path1 = string(mesh1path) + string(mesh1); + const string path2 = string(mesh2path) + string(mesh2); + + const bool isTestReflexive = (path1.compare(path2) == 0); + + IntersectionMatrix matrix1; + calcIntersectionMatrix(mesh1path, mesh1, mesh2path, mesh2, matrix1); + +#if LOG_LEVEL >= 2 + dumpIntersectionMatrix(matrix1); +#endif + + std::cout.precision(16); + + const double vol1 = sumVolume(matrix1); + + if(!doubleTest) + { + LOG(1, "vol = " << vol1 <<" correctVol = " << correctVol ); + CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(correctVol, vol1)); + + if(isTestReflexive) + { + CPPUNIT_ASSERT_EQUAL_MESSAGE("Reflexive test failed", true, testDiagonal(matrix1)); + } + } + else + { + + IntersectionMatrix matrix2; + calcIntersectionMatrix(mesh2path, mesh2, mesh1path, mesh1, matrix2); + +#if LOG_LEVEL >= 2 + dumpIntersectionMatrix(matrix2); +#endif + + const double vol2 = sumVolume(matrix2); + + LOG(1, "vol1 = " << vol1 << ", vol2 = " << vol2 << ", correctVol = " << correctVol ); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(vol1, correctVol)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol2, prec * std::max(vol2, correctVol)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(vol1, vol2, prec * std::max(vol1, vol2)); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Symmetry test failed", true, testSymmetric(matrix1, matrix2)); + } + +} + + + diff --git a/src/INTERP_KERNELTest/Interpolation3DTest.hxx b/src/INTERP_KERNELTest/Interpolation3DTest.hxx new file mode 100644 index 000000000..77984859e --- /dev/null +++ b/src/INTERP_KERNELTest/Interpolation3DTest.hxx @@ -0,0 +1,51 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TU_INTERPOLATION_3D_TEST_HXX__ +#define __TU_INTERPOLATION_3D_TEST_HXX__ + +#include +#include "../Interpolation3D.hxx" + +#define ERR_TOL 1.0e-8 + +using MEDMEM::Interpolation3D; +class MEDMEM::MESH; + +/// \brief OBSOLETE - renamed Interpolation3DTestSuite +class Interpolation3DTest : public CppUnit::TestFixture +{ + +public: + void setUp() + { + _testTools = new MeshTestToolkit(); + } + + void tearDown() + { + delete _testTools; + } + +protected: + + MeshToolkit* _testTools; + +}; + +#endif diff --git a/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx b/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx new file mode 100644 index 000000000..6bafcb137 --- /dev/null +++ b/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx @@ -0,0 +1,79 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "InterpolationOptionsTest.hxx" +#include "MEDNormalizedUnstructuredMesh.hxx" +#include "Interpolation2D.hxx" +#include +#include + +namespace INTERP_TEST +{ + + + void InterpolationOptionsTest::setUp() + { + } + + + void InterpolationOptionsTest::tearDown() + { + } + + /** + * Test that creates a tree in 2D and check that + * the results are correct in three + * cases : + * a non matching search + * a standard case + * a bbox overlapping the bboxes of the tree + */ + void InterpolationOptionsTest::test_InterpolationOptions() { + string sourcename=getenv("MED_ROOT_DIR"); + sourcename +="/share/salome/resources/med/square1.med"; + MEDMEM::MESH source_mesh (MED_DRIVER,sourcename,"Mesh_2"); + + string targetname=getenv("MED_ROOT_DIR"); + targetname +="/share/salome/resources/med/square2.med"; + MEDMEM::MESH target_mesh (MED_DRIVER,targetname,"Mesh_3"); + + MEDMEM::SUPPORT source_support(&source_mesh,"on All support"); + MEDMEM::FIELD source_field(&source_support,1); + double* value=const_cast(source_field.getValue()); + for (int i=0; i target_field(&target_support,1); + double* targetvalue=const_cast(target_field.getValue()); + for (int i=0; i wrap_source_mesh(&source_mesh); + MEDNormalizedUnstructuredMesh<2,2> wrap_target_mesh(&target_mesh); + // Go for interpolation... + INTERP_KERNEL::Interpolation2D myInterpolator; + //optionnal call to parametrize your interpolation. First precision, tracelevel, intersector wanted. + myInterpolator.setPrecision(1e-7); + myInterpolator.setPrintLevel(1); + } + + +} diff --git a/src/INTERP_KERNELTest/InterpolationOptionsTest.hxx b/src/INTERP_KERNELTest/InterpolationOptionsTest.hxx new file mode 100644 index 000000000..1507f81e1 --- /dev/null +++ b/src/INTERP_KERNELTest/InterpolationOptionsTest.hxx @@ -0,0 +1,60 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TU_INTERPOLATIONOPTIONS_HXX__ +#define __TU_INTERPOLATIONOPTIONS_HXX__ + +#include +#include "../InterpolationOptions.hxx" +#include "MEDMEM_Field.hxx" + +namespace INTERP_TEST +{ + + /** + * \brief Test suite testing some of the low level methods of TransformedTriangle. + * + */ + class InterpolationOptionsTest : public CppUnit::TestFixture + { + + CPPUNIT_TEST_SUITE( InterpolationOptionsTest ); + CPPUNIT_TEST( test_InterpolationOptions ); + CPPUNIT_TEST_SUITE_END(); + + + public: + void setUp(); + + void tearDown(); + + // tests + void test_InterpolationOptions(); + + private: + + }; + + + + +} + + + +#endif diff --git a/src/INTERP_KERNELTest/InterpolationPlanarTestSuite.hxx b/src/INTERP_KERNELTest/InterpolationPlanarTestSuite.hxx new file mode 100644 index 000000000..729061e46 --- /dev/null +++ b/src/INTERP_KERNELTest/InterpolationPlanarTestSuite.hxx @@ -0,0 +1,128 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TU_INTERPOLATION_PLANAR_TEST_SUITE_HXX__ +#define __TU_INTERPOLATION_PLANAR_TEST_SUITE_HXX__ + +#include +#include +#include +#include + +using namespace std; + +namespace INTERP_TEST +{ + + /** + * \brief Base class for planar mesh intersection test suites. + * + */ + class InterpolationPlanarTestSuite : public CppUnit::TestFixture + { + + public: + double _Epsilon; + double _Precision; + + /** + * Sets up the test suite. + * + */ + void setUp() + { + _Epsilon = 1.e-6; + _Precision = 1.e-6; + } + void tearDown() {} + + // bool checkDequesEqual(std::deque< double > deque1, std::deque< double > deque2, double epsilon); + // bool checkVectorsEqual(std::vector< double > Vect1, std::vector< double > Vect2, double epsilon); + // void dequePrintOut(std::deque< double > deque1); + // void vectPrintOut(std::vector< double > vect); + // void tabPrintOut( const double * tab, int size); + + bool checkDequesEqual(std::deque< double > deque1, + std::deque< double > deque2, double epsilon) + { + int size1 = deque1.size(); + int size2 = deque2.size(); + bool are_equal = size1 == size2; + + if(are_equal) + for(int i = 0; i < size1 && are_equal; i++) + are_equal = fabs(deque1[i] - deque2[i]) < epsilon; + + return are_equal; + } + bool checkVectorsEqual(std::vector< double > vect1, + std::vector< double > vect2, double epsilon) + { + int size1 = vect1.size(); + int size2 = vect2.size(); + bool are_equal = size1 == size2; + + if(are_equal) + for(int i = 0; i < size1 && are_equal; i++) + are_equal = fabs(vect1[i] - vect2[i]) < epsilon; + + return are_equal; + } + void dequePrintOut(std::deque< double > deque1) + { + for(int i = 0; i< (int)deque1.size(); i++) + { + std::cerr << deque1[i] << " "; + } + std::cerr<< endl; + } + void vectPrintOut(std::vector< double > vect) + { + for(int i = 0; i< (int)vect.size(); i++) + { + std::cerr << vect[i] << " "; + } + std::cerr<< endl; + } + void tabPrintOut( const double * tab,int size) + { + for(int i = 0; i< size; i++) + { + std::cerr << tab[i] << " "; + } + std::cerr<< endl; + } + + /** + * Cleans up after the test suite. + * Liberates the MeshTestToolkit object used by the tests. + */ + // void tearDown() + // { + // delete _testTools; + // } + + + + // protected: + // /// MeshTestToolkit object to which the tests are delegated + // MeshTestToolkit* _testTools; + + }; +} +#endif diff --git a/src/INTERP_KERNELTest/InterpolationTestSuite.hxx b/src/INTERP_KERNELTest/InterpolationTestSuite.hxx new file mode 100644 index 000000000..a1151c754 --- /dev/null +++ b/src/INTERP_KERNELTest/InterpolationTestSuite.hxx @@ -0,0 +1,65 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TU_INTERPOLATION_TEST_SUITE_HXX__ +#define __TU_INTERPOLATION_TEST_SUITE_HXX__ + +#include "MeshTestToolkit.txx" + +#include + +namespace INTERP_TEST +{ + + /** + * \brief Base class for mesh intersection test suites. + * + */ + template + class InterpolationTestSuite : public CppUnit::TestFixture + { + + public: + /** + * Sets up the test suite. + * Creates the MeshTestToolkit object used by the tests. + * + */ + void setUp() + { + _testTools = new MeshTestToolkit(); + } + + /** + * Cleans up after the test suite. + * Liberates the MeshTestToolkit object used by the tests. + */ + void tearDown() + { + delete _testTools; + } + + + + protected: + /// MeshTestToolkit object to which the tests are delegated + MeshTestToolkit* _testTools; + + }; +} +#endif diff --git a/src/INTERP_KERNELTest/MEDMeshMaker.cxx b/src/INTERP_KERNELTest/MEDMeshMaker.cxx new file mode 100644 index 000000000..18fd7e873 --- /dev/null +++ b/src/INTERP_KERNELTest/MEDMeshMaker.cxx @@ -0,0 +1,100 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Meshing.hxx" + +MEDMEM::MESH* MEDMeshMaker(int dim, int nbedge, MED_EN::medGeometryElement type) +{ + MEDMEM::MESHING* mesh=new MEDMEM::MESHING(); + mesh->setSpaceDimension(dim); + int nbnodes; + int nbelems; + switch (dim) + { + case 2: + nbnodes=(nbedge+1)*(nbedge+1); + if(type==MED_EN::MED_QUAD4) + nbelems=(nbedge*nbedge); + else + throw MEDMEM::MEDEXCEPTION("MEDMeshMaker: type not impletmented"); + break; + case 3: + nbnodes=(nbedge+1)*(nbedge+1)*(nbedge+1); + if (type==MED_EN::MED_HEXA8) + nbelems= nbedge*nbedge*nbedge; + else + throw MEDMEM::MEDEXCEPTION("MEDMeshMaker: type not impletmented"); + break; + } + double* coords = new double[dim*nbnodes]; + int nz; + if (dim==2) nz =1; else nz=nbedge+1; + { + for (int ix=0; ix < nbedge+1; ix++) + for (int iy=0; iysetCoordinates(dim, nbnodes,coords,"CARTESIAN",MED_EN::MED_FULL_INTERLACE); + delete [] coords; + mesh->setNumberOfTypes(1,MED_EN::MED_CELL); + mesh->setTypes(&type,MED_EN::MED_CELL); + mesh->setNumberOfElements(&nbelems,MED_EN::MED_CELL); + + int* conn = new int [nbelems*(type%100)]; + if (dim==2) + { + for (int ix=0; ixsetConnectivity(conn, MED_EN::MED_CELL,type); + delete [] conn; + mesh->setMeshDimension(dim); + return mesh; +} diff --git a/src/INTERP_KERNELTest/MEDMeshMaker.hxx b/src/INTERP_KERNELTest/MEDMeshMaker.hxx new file mode 100644 index 000000000..d06aefd10 --- /dev/null +++ b/src/INTERP_KERNELTest/MEDMeshMaker.hxx @@ -0,0 +1,25 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "MEDMEM_define.hxx" +namespace MEDMEM +{ + class MESH; +} + +MEDMEM::MESH* MEDMeshMaker(int dim, int nbedge, MED_EN::medGeometryElement type); diff --git a/src/INTERP_KERNELTest/Makefile.am b/src/INTERP_KERNELTest/Makefile.am new file mode 100644 index 000000000..2d4c50b33 --- /dev/null +++ b/src/INTERP_KERNELTest/Makefile.am @@ -0,0 +1,102 @@ +# Copyright (C) 2007-2008 CEA/DEN, 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. +# +# 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 +# + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +lib_LTLIBRARIES = libInterpKernelTest.la + +salomeinclude_HEADERS = CppUnitTest.hxx \ + TransformedTriangleTest.hxx \ + TransformedTriangleIntersectTest.hxx \ + InterpolationTestSuite.hxx \ + SingleElementTetraTests.hxx \ + MultiElementTetraTests.hxx \ + HexaTests.hxx \ + MeshTestToolkit.hxx \ + MeshTestToolkit.txx \ + BBTreeTest.hxx \ + RemapperTest.hxx \ + SingleElementPlanarTests.hxx \ + MultiElement2DTests.hxx \ + InterpolationPlanarTestSuite.hxx \ + UnitTetraIntersectionBaryTest.hxx \ + PointLocatorTest.hxx \ + MEDMeshMaker.hxx \ + QuadraticPlanarInterpTest.hxx + +EXTRA_DIST += \ + BasicMainTest.hxx \ + Interpolation3DTest.cxx \ + Interpolation3DTest.hxx \ + MultiElement3DSurfTests.hxx \ + TestingUtils.hxx \ + perf_test.sh + +CLEANFILES = \ + UnitTestsResult + +dist_libInterpKernelTest_la_SOURCES= \ + CppUnitTest.cxx \ + TransformedTriangleTest.cxx \ + UnitTetraIntersectionBaryTest.cxx \ + TransformedTriangleIntersectTest.cxx \ + BBTreeTest.cxx \ + RemapperTest.cxx \ + SingleElementPlanarTests.cxx \ + PointLocatorTest.cxx \ + MEDMeshMaker.cxx \ + InterpolationOptionsTest.hxx \ + InterpolationOptionsTest.cxx \ + QuadraticPlanarInterpTest.cxx \ + QuadraticPlanarInterpTest2.cxx \ + QuadraticPlanarInterpTest3.cxx \ + QuadraticPlanarInterpTest4.cxx \ + QuadraticPlanarInterpTest5.cxx + +libInterpKernelTest_la_CPPFLAGS = @CPPUNIT_INCLUDES@ $(MED2_INCLUDES) $(HDF5_INCLUDES) \ + -I$(srcdir)/.. -I$(srcdir)/../MEDWrapper/V2_1/Core -I$(srcdir)/../MEDMEM \ + -I$(srcdir)/../INTERP_KERNEL -I$(srcdir)/../INTERP_KERNEL/Geometric2D \ + -I$(srcdir)/../INTERP_KERNEL/Bases -DOPTIMIZE -DLOG_LEVEL=0 + +libInterpKernelTest_la_LDFLAGS = @CPPUNIT_LIBS@ ../MEDWrapper/V2_1/Core/libmed_V2_1.la \ + ../INTERP_KERNEL/libinterpkernel.la ../INTERP_KERNEL/Geometric2D/libInterpGeometric2DAlg.la \ + ../MEDMEM/libmedmem.la -lm + +if MED_ENABLE_KERNEL + libInterpKernelTest_la_CPPFLAGS += ${KERNEL_CXXFLAGS} + libInterpKernelTest_la_LDFLAGS += ${KERNEL_LDFLAGS} -lSALOMELocalTrace +endif + +# Executables targets +bin_PROGRAMS = TestINTERP_KERNEL \ + PerfTest + +dist_TestINTERP_KERNEL_SOURCES = TestInterpKernel.cxx +dist_PerfTest_SOURCES = PerfTest.cxx + +LDADD = $(MED2_LIBS) $(libInterpKernelTest_la_LDFLAGS) \ + libInterpKernelTest.la +if MED_ENABLE_KERNEL + LDADD += -lSALOMEBasics +endif +AM_CPPFLAGS = $(libInterpKernelTest_la_CPPFLAGS) + +UNIT_TEST_PROG = TestInterpKernel + +check : tests \ No newline at end of file diff --git a/src/INTERP_KERNELTest/MeshTestToolkit.hxx b/src/INTERP_KERNELTest/MeshTestToolkit.hxx new file mode 100644 index 000000000..5f6b54a4d --- /dev/null +++ b/src/INTERP_KERNELTest/MeshTestToolkit.hxx @@ -0,0 +1,88 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TU_MESH_TEST_TOOLKIT_HXX__ +#define __TU_MESH_TEST_TOOLKIT_HXX__ + +#include "../Interpolation3D.hxx" +#include "../Interpolation3D.txx" +#include "../InterpolationPlanar.hxx" + +#include +#include + +#define ERR_TOL 1.0e-8 + +typedef std::vector > IntersectionMatrix; + +namespace INTERP_KERNEL +{ + class Interpolation3D; +} + + +namespace MEDMEM { + class MESH; +}; + +namespace INTERP_TEST +{ + /** + * \brief Class providing services for mesh intersection tests. + * + */ + template + class MeshTestToolkit + { + + public: + double _precision; + INTERP_KERNEL::IntersectionType _intersectionType;//Used only in the case MESHDIM==2 (planar intersections) + + MeshTestToolkit():_precision(1.e-6),_intersectionType(INTERP_KERNEL::Triangulation) {} + + ~MeshTestToolkit() {} + + void intersectMeshes(const char* mesh1, const char* mesh2, const double correctVol, const double prec = 1.0e-5, bool doubleTest = true) const; + + // 1.0e-5 here is due to limited precision of "correct" volumes calculated in Salome + void intersectMeshes(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, const double correctVol, const double prec = 1.0e-5, bool doubleTest = true) const; + + void dumpIntersectionMatrix(const IntersectionMatrix& m) const; + + double sumRow(const IntersectionMatrix& m, int i) const; + + double sumCol(const IntersectionMatrix& m, int i) const; + + void getVolumes( MEDMEM::MESH& mesh, double* tab) const; + + bool testVolumes(const IntersectionMatrix& m, MEDMEM::MESH& sMesh, MEDMEM::MESH& tMesh) const; + + double sumVolume(const IntersectionMatrix& m) const; + + bool areCompatitable( const IntersectionMatrix& m1, const IntersectionMatrix& m2) const; + + bool testTranspose(const IntersectionMatrix& m1, const IntersectionMatrix& m2) const; + + bool testDiagonal(const IntersectionMatrix& m) const; + + void calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) const; + + }; +} +#endif diff --git a/src/INTERP_KERNELTest/MeshTestToolkit.txx b/src/INTERP_KERNELTest/MeshTestToolkit.txx new file mode 100644 index 000000000..84bb2df8e --- /dev/null +++ b/src/INTERP_KERNELTest/MeshTestToolkit.txx @@ -0,0 +1,509 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "MEDNormalizedUnstructuredMesh.hxx" +#include "MEDNormalizedUnstructuredMesh.txx" + +#include "MeshTestToolkit.hxx" +#include "MEDMEM_Mesh.hxx" + +#include "Interpolation3DSurf.txx" +#include "Interpolation2D.txx" +#include "Interpolation3D.txx" + +#include +#include +#include +#include +#include + +//#include "VectorUtils.hxx" + +#include "MEDMEM_Field.hxx" +#include "MEDMEM_Support.hxx" + +// levels : +// 1 - titles and volume results +// 2 - symmetry / diagonal results and intersection matrix output +// 3 - empty +// 4 - empty +// 5 - misc +#include "Log.hxx" + +#include + +//#define VOL_PREC 1.0e-6 + +using namespace MEDMEM; +using namespace std; +using namespace MED_EN; +using namespace INTERP_KERNEL; + +namespace INTERP_TEST +{ + + /** + * Calculates the sum of a row of an intersection matrix + * + * @param m an intersection matrix + * @param i the index of the row (1 <= i <= no. rows) + * @return the sum of the values of row i + * + */ + template + double MeshTestToolkit::sumRow(const IntersectionMatrix& m, int i) const + { + double vol = 0.0; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + if(iter->count(i) != 0.0) + { + map::const_iterator iter2 = iter->find(i); + vol += fabs(iter2->second); + } + } + return vol; + } + + /** + * Calculates the sum of a column of an intersection matrix + * + * @param m an intersection matrix + * @param i the index of the column (0 <= i <= no. rows - 1) + * @return the sum of the values of column i + * + */ + template + double MeshTestToolkit::sumCol(const IntersectionMatrix& m, int i) const + { + double vol = 0.0; + const std::map& col = m[i]; + for(map::const_iterator iter = col.begin() ; iter != col.end() ; ++iter) + { + vol += fabs(iter->second); + } + return vol; + } + + /** + * Gets the volumes of the elements in a mesh. + * + * @param mesh the mesh + * @param tab pointer to double[no. elements of mesh] array in which to store the volumes + */ + template + void MeshTestToolkit::getVolumes(MEDMEM::MESH& mesh, double* tab) const + { + SUPPORT *sup=new SUPPORT(&mesh,"dummy",MED_CELL); + FIELD* f; + switch (MESHDIM) + { + case 2: + f=mesh.getArea(sup); + break; + case 3: + f=mesh.getVolume(sup); + break; + } + const double *tabS = f->getValue(); + std::copy(tabS,tabS+mesh.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS),tab); + delete sup; + delete f; + } + + /** + * Sums all the elements (volumes) of an intersection matrix + * + * @param m the intersection matrix + * @return the sum of the elements of m + */ + + template + double MeshTestToolkit::sumVolume(const IntersectionMatrix& m) const + { + + vector volumes; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + volumes.push_back(fabs(iter2->second)); + } + } + + // sum in ascending order to avoid rounding errors + + sort(volumes.begin(), volumes.end()); + const double vol = accumulate(volumes.begin(), volumes.end(), 0.0); + + return vol; + } + + /** + * Verifies if for a given intersection matrix the sum of each row is equal to the volumes + * of the corresponding source elements and the sum of each column is equal to the volumes + * of the corresponding target elements. This will be true as long as the meshes correspond + * to the same geometry. The equalities are in the "epsilon-sense", making sure the relative + * error is small enough. + * + * @param m the intersection matrix + * @param sMesh the source mesh + * @param tMesh the target mesh + * @return true if the condition is verified, false if not. + */ + template + bool MeshTestToolkit::testVolumes(const IntersectionMatrix& m, MEDMEM::MESH& sMesh, MEDMEM::MESH& tMesh) const + { + bool ok = true; + + // source elements + double* sVol = new double[sMesh.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS)]; + getVolumes(sMesh, sVol); + + for(int i = 0; i < sMesh.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS); ++i) + { + const double sum_row = sumRow(m, i+1); + if(!epsilonEqualRelative(sum_row, fabs(sVol[i]), _precision)) + { + LOG(1, "Source volume inconsistent : vol of cell " << i << " = " << sVol[i] << " but the row sum is " << sum_row ); + ok = false; + } + LOG(1, "diff = " < + bool MeshTestToolkit::testTranspose(const IntersectionMatrix& m1, const IntersectionMatrix& m2) const + { + + int i = 0; + bool isSymmetric = true; + + LOG(1, "Checking symmetry src - target" ); + isSymmetric = isSymmetric & areCompatitable(m1, m2) ; + LOG(1, "Checking symmetry target - src" ); + isSymmetric = isSymmetric & areCompatitable(m2, m1); + + for(IntersectionMatrix::const_iterator iter = m1.begin() ; iter != m1.end() ; ++iter) + { + for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + int j = iter2->first; + const double v1 = fabs(iter2->second); + //if(m2[j - 1].count(i+1) > 0) + // { + map theMap = m2.at(j-1); + const double v2 = fabs(theMap[i + 1]); + if(v1 != v2) + { + LOG(2, "V1( " << i << ", " << j << ") = " << v1 << " which is different from V2( " << j - 1 << ", " << i + 1 << ") = " << v2 << " | diff = " << v1 - v2 ); + if(!epsilonEqualRelative(v1, v2, _precision)) + { + LOG(2, "(" << i << ", " << j << ") fails"); + isSymmetric = false; + } + } + } + ++i; + } + if(!isSymmetric) + { + LOG(1, "*** matrices are not symmetric"); + } + return isSymmetric; + } + + /** + * Tests if an intersection matrix is diagonal. + * + * @param m the intersection matrix + * @return true if m is diagonal; false if not + * + */ + template + bool MeshTestToolkit::testDiagonal(const IntersectionMatrix& m) const + { + LOG(1, "Checking if matrix is diagonal" ); + int i = 1; + bool isDiagonal = true; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + int j = iter2->first; + const double vol = iter2->second; + if(vol != 0.0 && (i != j)) + { + LOG(2, "V( " << i - 1 << ", " << j << ") = " << vol << " which is not zero" ); + if(!epsilonEqual(vol, 0.0, _precision)) + { + LOG(2, "(" << i << ", " << j << ") fails"); + isDiagonal = false; + } + } + } + ++i; + } + if(!isDiagonal) + { + LOG(1, "*** matrix is not diagonal"); + } + return isDiagonal; + } + + /** + * Outputs the intersection matrix as a list of all its elements to std::cout. + * + * @param m the intersection matrix to output + */ + template + void MeshTestToolkit::dumpIntersectionMatrix(const IntersectionMatrix& m) const + { + int i = 0; + std::cout << "Intersection matrix is " << endl; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + + std::cout << "V(" << i << ", " << iter2->first << ") = " << iter2->second << endl; + + } + ++i; + } + std::cout << "Sum of volumes = " << sumVolume(m) << std::endl; + } + + /** + * Calculates the intersection matrix for two meshes. + * If the source and target meshes are the same, a CppUnit assertion raised if testVolumes() returns false. + * + * @param mesh1path the path to the file containing the source mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ + * @param mesh1 the name of the source mesh + * @param mesh2path the path to the file containing the target mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ + * @param mesh2 the name of the target mesh + * @param m intersection matrix in which to store the result of the intersection + */ + template + void MeshTestToolkit::calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) const + { + const string dataBaseDir = getenv("MED_ROOT_DIR"); + const string dataDir = dataBaseDir + string("/share/salome/resources/med/"); + + LOG(1, std::endl << "=== -> intersecting src = " << mesh1path << ", target = " << mesh2path ); + + LOG(5, "Loading " << mesh1 << " from " << mesh1path); + MESH sMesh(MED_DRIVER, dataDir+mesh1path, mesh1); + + LOG(5, "Loading " << mesh2 << " from " << mesh2path); + MESH tMesh(MED_DRIVER, dataDir+mesh2path, mesh2); + + MEDNormalizedUnstructuredMesh sMesh_wrapper(&sMesh); + MEDNormalizedUnstructuredMesh tMesh_wrapper(&tMesh); + + if (SPACEDIM==2 && MESHDIM==2) + { + Interpolation2D interpolator; + interpolator.setOptions(_precision, LOG_LEVEL, _intersectionType,1); + interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m,"P0P0"); + } + else if (SPACEDIM==3 && MESHDIM==2) + { + Interpolation3DSurf interpolator; + interpolator.setOptions(_precision,LOG_LEVEL, 0.5,_intersectionType,false,1); + interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m,"P0P0"); + } + else if (SPACEDIM==3 && MESHDIM==3) + { + Interpolation3D interpolator; + interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m,"P0P0"); + } + else + { + throw MEDEXCEPTION("Wrong dimensions"); + } + // if reflexive, check volumes + if(strcmp(mesh1path,mesh2path) == 0) + { + const bool row_and_col_sums_ok = testVolumes(m, sMesh, tMesh); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Row or column sums incorrect", true, row_and_col_sums_ok); + const bool is_diagonal =testDiagonal(m); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Self intersection matrix is not diagonal", true, is_diagonal); + } + + LOG(1, "Intersection calculation done. " << std::endl ); + + } + + /** + * Tests the intersection algorithm for two meshes. + * Depending on the nature of the meshes, different tests will be performed. The sum of the elements will + * be compared to the given total volume of the intersection in all cases. If the two meshes are the same, then + * it will be confirmed that the intersection matrix is diagonal, otherwise the intersection matrices will be + * calculated once which each mesh as source mesh, and it will be verified that the they are each others' transpose. + * + * @param mesh1path the path to the file containing the source mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ + * @param mesh1 the name of the source mesh + * @param mesh2path the path to the file containing the target mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ + * @param mesh2 the name of the target mesh + * @param correctVol the total volume of the intersection of the two meshes + * @param prec maximum relative error to be tolerated in volume comparisions + * @param doubleTest if false, only the test with mesh 1 as the source mesh and mesh 2 as the target mesh will be performed + * + */ + template + void MeshTestToolkit::intersectMeshes(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, const double correctVol, const double prec, bool doubleTest) const + { + LOG(1, std::endl << std::endl << "=============================" ); + + using std::string; + const string path1 = string(mesh1path) + string(mesh1); + const string path2 = string(mesh2path) + string(mesh2); + + const bool isTestReflexive = (path1.compare(path2) == 0); + + IntersectionMatrix matrix1; + calcIntersectionMatrix(mesh1path, mesh1, mesh2path, mesh2, matrix1); + +#if LOG_LEVEL >= 2 + dumpIntersectionMatrix(matrix1); +#endif + + std::cout.precision(16); + + const double vol1 = sumVolume(matrix1); + + if(!doubleTest) + { + LOG(1, "vol = " << vol1 <<" correctVol = " << correctVol ); + CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(correctVol, vol1)); + + if(isTestReflexive) + { + CPPUNIT_ASSERT_EQUAL_MESSAGE("Reflexive test failed", true, testDiagonal(matrix1)); + } + } + else + { + + IntersectionMatrix matrix2; + calcIntersectionMatrix(mesh2path, mesh2, mesh1path, mesh1, matrix2); + +#if LOG_LEVEL >= 2 + dumpIntersectionMatrix(matrix2); +#endif + + const double vol2 = sumVolume(matrix2); + + LOG(1, "vol1 = " << vol1 << ", vol2 = " << vol2 << ", correctVol = " << correctVol ); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("Symmetry test failed", true, testTranspose(matrix1, matrix2)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(vol1, correctVol)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol2, prec * std::max(vol2, correctVol)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(vol1, vol2, prec * std::max(vol1, vol2)); + } + + } + + /** + * Utility method used to facilitate the call to intersect meshes. + * It calls intersectMeshes, using "mesh1.med" as file name for the mesh with name "mesh1" and + * "mesh2.med" as file name for the mesh with name "mesh2". The rest of the arguments are passed + * along as they are. + * + * @param mesh1 the name of the source mesh + * @param mesh2 the name of the target mesh + * @param correctVol the total volume of the intersection of the two meshes + * @param prec maximum relative error to be tolerated in volume comparisions + * @param doubleTest if false, only the test with mesh 1 as the source mesh and mesh 2 as the target mesh will be performed + * + */ + template + void MeshTestToolkit::intersectMeshes(const char* mesh1, const char* mesh2, const double correctVol, const double prec, bool doubleTest) const + { + const string path1 = string(mesh1) + string(".med"); + std::cout << "here :" << path1 << std::endl; + const string path2 = string(mesh2) + string(".med"); + + intersectMeshes(path1.c_str(), mesh1, path2.c_str(), mesh2, correctVol, prec, doubleTest); + } + + +} diff --git a/src/INTERP_KERNELTest/MultiElement2DTests.hxx b/src/INTERP_KERNELTest/MultiElement2DTests.hxx new file mode 100644 index 000000000..2a9ae1153 --- /dev/null +++ b/src/INTERP_KERNELTest/MultiElement2DTests.hxx @@ -0,0 +1,62 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __MULTI_ELEMENT_2D_TESTS_HXX_ +#define __MULTI_ELEMENT_2D_TESTS_HXX_ + +#include "InterpolationTestSuite.hxx" + +namespace INTERP_TEST +{ + /** + * \brief Class testing algorithm by intersecting meshes of several + * polygonal elements - up to a few thousand. This serves to check the + * filtering methods and the matrix assemblage, as well as verifying + * that computation errors do not become unmanageable. It uses mehes of + * different geometries : triangle, quadrilateral. + * + */ + class MultiElement2DTests : public InterpolationTestSuite<2,2> + { + CPPUNIT_TEST_SUITE( MultiElement2DTests ); + + CPPUNIT_TEST(SymetryTranspose2DTest); + CPPUNIT_TEST(SelfIntersection2DTest); + + CPPUNIT_TEST_SUITE_END(); + + public: + void SymetryTranspose2DTest() + { + _testTools->_intersectionType=INTERP_KERNEL::Triangulation; + _testTools->intersectMeshes("square1.med", "Mesh_2","square2.med","Mesh_3", 10000.); + _testTools->_intersectionType=INTERP_KERNEL::Convex; + _testTools->intersectMeshes("square1.med", "Mesh_2","square2.med","Mesh_3", 10000.); + } + void SelfIntersection2DTest() + { + IntersectionMatrix m; + _testTools->_intersectionType=INTERP_KERNEL::Triangulation; + _testTools->calcIntersectionMatrix("square1.med", "Mesh_2","square1.med","Mesh_2", m); + _testTools->_intersectionType=INTERP_KERNEL::Convex; + _testTools->calcIntersectionMatrix("square1.med", "Mesh_2","square1.med","Mesh_2", m); + } + }; +} + +#endif diff --git a/src/INTERP_KERNELTest/MultiElement3DSurfTests.hxx b/src/INTERP_KERNELTest/MultiElement3DSurfTests.hxx new file mode 100644 index 000000000..0543d73d1 --- /dev/null +++ b/src/INTERP_KERNELTest/MultiElement3DSurfTests.hxx @@ -0,0 +1,62 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __MULTI_ELEMENT_3DSurf_TESTS_HXX_ +#define __MULTI_ELEMENT_3DSurf_TESTS_HXX_ + +#include "InterpolationTestSuite.hxx" + +namespace INTERP_TEST +{ + /** + * \brief Class testing algorithm by intersecting meshes of several + * polygonal elements - up to a few thousand. This serves to check the + * filtering methods and the matrix assemblage, as well as verifying + * that computation errors do not become unmanageable. It uses mehes of + * different geometries : triangle, quadrilateral. + * + */ + class MultiElement2DTests : public InterpolationTestSuite<3,2> + { + CPPUNIT_TEST_SUITE( MultiElement3DSurfTests ); + + CPPUNIT_TEST(SymetryTranspose3DSurfTest); + CPPUNIT_TEST(SelfIntersection3DSurfTest); + + CPPUNIT_TEST_SUITE_END(); + + public: + void SymetryTranspose3DSurfTest() + { + _testTools->_intersectionType=INTERP_KERNEL::Triangulation; + _testTools->intersectMeshes("square1.med", "Mesh_2","square2.med","Mesh_3", 10000.); + _testTools->_intersectionType=INTERP_KERNEL::Convex; + _testTools->intersectMeshes("square1.med", "Mesh_2","square2.med","Mesh_3", 10000.); + } + void SelfIntersection3DSurfTest() + { + IntersectionMatrix m; + _testTools->_intersectionType=INTERP_KERNEL::Triangulation; + _testTools->calcIntersectionMatrix("square1.med", "Mesh_2","square1.med","Mesh_2", m); + _testTools->_intersectionType=INTERP_KERNEL::Convex; + _testTools->calcIntersectionMatrix("square1.med", "Mesh_2","square1.med","Mesh_2", m); + } + }; +} + +#endif diff --git a/src/INTERP_KERNELTest/MultiElementTetraTests.hxx b/src/INTERP_KERNELTest/MultiElementTetraTests.hxx new file mode 100644 index 000000000..d8610688e --- /dev/null +++ b/src/INTERP_KERNELTest/MultiElementTetraTests.hxx @@ -0,0 +1,158 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __MULTI_ELEMENT_TETRA_TESTS_HXX_ +#define __MULTI_ELEMENT_TETRA_TESTS_HXX_ + +#include "InterpolationTestSuite.hxx" + +namespace INTERP_TEST +{ + /** + * \brief Class testing algorithm by intersecting meshes of several + * elements (all tetrahedra) - up to a few thousand. This serves to check the + * filtering methods and the matrix assemblage, as well as verifying + * that computation errors do not become unmanageable. It uses mehes of + * different geometries : tetrahedra, boxes and cylinders. + * + */ + class MultiElementTetraTests : public InterpolationTestSuite<3,3> + { + CPPUNIT_TEST_SUITE( MultiElementTetraTests ); + + CPPUNIT_TEST( tetraComplexIncluded ); + CPPUNIT_TEST( dividedUnitTetraSimplerReflexive ); + CPPUNIT_TEST( dividedUnitTetraReflexive ); + CPPUNIT_TEST( nudgedDividedUnitTetraSimpler ); + CPPUNIT_TEST( nudgedDividedUnitTetra ); + CPPUNIT_TEST( dividedGenTetra ); + CPPUNIT_TEST( tinyBoxReflexive ); + CPPUNIT_TEST( moderateBoxEvenSmallerReflexive ); + CPPUNIT_TEST( moderateBoxSmallReflexive ); + CPPUNIT_TEST( boxReflexive ); + CPPUNIT_TEST( boxReflexiveModerate ); + CPPUNIT_TEST( tetraBoxes ); + CPPUNIT_TEST( moderateBoxesSmaller ); + CPPUNIT_TEST( moderateBoxes ); + + CPPUNIT_TEST_SUITE_END(); + + public: + + /// Tetrahedron situated totally inside another + /// \brief Status : pass + void tetraComplexIncluded() + { + _testTools->intersectMeshes("ComplexIncludedTetra", "ComplexIncludingTetra", 17.0156); + } + + /// Unit tetrahedron divided in 4 elements intersecting itself. + /// \brief Status : pass + void dividedUnitTetraSimplerReflexive() + { + _testTools->intersectMeshes("DividedUnitTetraSimpler", "DividedUnitTetraSimpler", 0.1666667); + } + + /// Unit tetrahedron divided in 14 elements intersecting itself. + /// \brief Status : pass + void dividedUnitTetraReflexive() + { + _testTools->intersectMeshes("DividedUnitTetra", "DividedUnitTetra", 0.1666667); + } + + /// Unit tetrahedron divided in 4 elements intersecting slightly displaced version of itself. + /// \brief Status : pass + void nudgedDividedUnitTetraSimpler() + { + _testTools->intersectMeshes("NudgedDividedUnitTetraSimpler", "DividedUnitTetraSimpler", 0.150191); + } + + /// Unit tetrahedron divided in 14 elements intersecting slightly displaced version of itself. + /// \brief Status : pass + void nudgedDividedUnitTetra() + { + _testTools->intersectMeshes("NudgedDividedUnitTetra", "DividedUnitTetra", 0.150191); + } + + /// Two intersecting tetrahedra in general position, one with 23 elements, the other with 643 elements + /// \brief Status : pass + void dividedGenTetra() + { + _testTools->intersectMeshes("DividedGenTetra1", "DividedGenTetra2", 0.546329); + } + + /// Large box in general position with 12 elements intersecting itself + /// \brief Status : pass + void tinyBoxReflexive() + { + _testTools->intersectMeshes("TinyBox", "TinyBox", 979200); + } + + /// Small box in general position with 33 elements intersecting itself + /// \brief Status : pass + void boxReflexive() + { + _testTools->intersectMeshes("Box3", "Box3", 13.9954); + } + + /// Box in general position with 67 elements intersecting itself + /// \brief Status : pass + void moderateBoxEvenSmallerReflexive() + { + _testTools->intersectMeshes("BoxEvenSmaller1", "BoxEvenSmaller1", 1.44018e6); + } + + /// Box in general position with 544 elements intersecting itself + /// \brief Status : pass + void moderateBoxSmallReflexive() + { + _testTools->intersectMeshes("BoxModSmall1", "BoxModSmall1", 1.44018e6); + } + + /// Large box in general position with 2943 elements intersecting itself + /// \brief Status : pass + void boxReflexiveModerate() + { + _testTools->intersectMeshes("Box1Moderate", "Box1Moderate", 1.0e6); + } + + /// Two intersecting boxes in general position with 12 and 18 elements + /// \brief Status : pass + void tetraBoxes() + { + _testTools->intersectMeshes("Box1", "Box2", 124.197); + } + + /// Two intersecting boxes in general position with 430 and 544 elements + /// \brief Status : pass + void moderateBoxesSmaller() + { + _testTools->intersectMeshes("BoxModSmall1", "BoxModSmall2", 321853); + } + + /// Two intersecting boxes in general position with 2943 and 3068 elements + /// \brief Status : pass + void moderateBoxes() + { + _testTools->intersectMeshes("Box1Moderate", "Box2Moderate", 376856); + } + + }; +} + +#endif diff --git a/src/INTERP_KERNELTest/PerfTest.cxx b/src/INTERP_KERNELTest/PerfTest.cxx new file mode 100644 index 000000000..847aa31b1 --- /dev/null +++ b/src/INTERP_KERNELTest/PerfTest.cxx @@ -0,0 +1,158 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "Interpolation3D.hxx" +#include "Interpolation3D.txx" +#include "MeshTestToolkit.txx" +#include "Log.hxx" +#include "VectorUtils.hxx" + +#include "MEDMEM_Mesh.hxx" +#include "MEDNormalizedUnstructuredMesh.hxx" + +#include +#include + +using namespace MEDMEM; +using namespace MED_EN; + +/** + * \file PerfTest.cxx + * Test program which takes two meshes and calculates their intersection matrix. + * + * USAGE : PerfTest mesh1 mesh2 + * where mesh1 and mesh2 are the names of two meshes located in + * the files mesh1.med, mesh2.med in {$MED_ROOT_DIR}/share/salome/resources/med/ + * + */ + +namespace INTERP_TEST +{ + /** + * \brief Specialization of MeshTestToolkit for the purposes of performance testing. + * + */ + class PerfTestToolkit : public MeshTestToolkit<3,3> + { + + public: + + /** + * Calculates the intersection matrix for two meshes. + * Outputs the names of the meshes intersected, the number of elements in each mesh, + * the number of matrix elements and the number of non-zero matrix elements, etc. + * These values help to determine how well the filtering algorithm is working. + * + * @param mesh1path the path to the file containing the source mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ + * @param mesh1 the name of the source mesh + * @param mesh2path the path to the file containing the target mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ + * @param mesh2 the name of the target mesh + * @param m intersection matrix in which to store the result of the intersection + */ + void calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) + { + const string dataBaseDir = getenv("MED_ROOT_DIR"); + const string dataDir = dataBaseDir + "/share/salome/resources/med/"; + + LOG(1, std::endl << "=== -> intersecting src = " << mesh1 << ", target = " << mesh2 ); + + LOG(5, "Loading " << mesh1 << " from " << mesh1path); + const MESH sMesh(MED_DRIVER, dataDir+mesh1path, mesh1); + + + LOG(5, "Loading " << mesh2 << " from " << mesh2path); + const MESH tMesh(MED_DRIVER, dataDir+mesh2path, mesh2); + + MEDNormalizedUnstructuredMesh<3,3> sMesh_wrapper(&sMesh); + MEDNormalizedUnstructuredMesh<3,3> tMesh_wrapper(&tMesh); + + Interpolation3D interpolator; + interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m,"P0P0"); + + std::pair eff = countNumberOfMatrixEntries(m); + LOG(1, eff.first << " of " << numTargetElems * numSrcElems << " intersections calculated : ratio = " + << double(eff.first) / double(numTargetElems * numSrcElems)); + LOG(1, eff.second << " non-zero elements of " << eff.first << " total : filter efficiency = " + << double(eff.second) / double(eff.first)); + + LOG(1, "Intersection calculation done. " << std::endl ); + + } + + /** + * Counts the number of elements in an intersection matrix, and the number of these which are non-zero. + * + * @param m the intersection matrix + * @return pair containing as its first element the number of elements in m and as its second element the + * number these which are non-zero + */ + std::pair countNumberOfMatrixEntries(const IntersectionMatrix& m) + { + + int numElems = 0; + int numNonZero = 0; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + numElems += iter->size(); + for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + if(!INTERP_KERNEL::epsilonEqual(iter2->second, 0.0, VOL_PREC)) + { + ++numNonZero; + } + } + } + return std::make_pair(numElems, numNonZero); + } + + }; +} + +/** + * Main method of the program. + * Intersects the meshes and outputs some information about the calculation as well as the + * intersection matrix on std::cout. + * + * @param argc number of arguments given to the program (should be 3, the user giving 2 mesh names) + * @param argv vector to the arguments as strings. + */ +int main(int argc, char** argv) +{ + using INTERP_TEST::PerfTestToolkit; + + assert(argc == 3); + + // load meshes + const string mesh1 = argv[1]; + const string mesh2 = argv[2]; + + const string mesh1path = mesh1 + ".med"; + const string mesh2path = mesh2 + ".med"; + + IntersectionMatrix m; + + PerfTestToolkit testTools; + + testTools.calcIntersectionMatrix(mesh1path.c_str(), mesh1.c_str(), mesh2path.c_str(), mesh2.c_str(), m); + + testTools.dumpIntersectionMatrix(m); + + return 0; + +} + diff --git a/src/INTERP_KERNELTest/PointLocatorTest.cxx b/src/INTERP_KERNELTest/PointLocatorTest.cxx new file mode 100644 index 000000000..02629b4a6 --- /dev/null +++ b/src/INTERP_KERNELTest/PointLocatorTest.cxx @@ -0,0 +1,101 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "PointLocatorTest.hxx" +#include "PointLocator.hxx" +#include "MEDMeshMaker.hxx" + +#include +#include + +namespace INTERP_TEST +{ + + + void PointLocatorTest::setUp() + { + } + + + void PointLocatorTest::tearDown() + { + } + + /** + * Test that creates a tree in 2D and check that + * the results are correct in three + * cases : + * a non matching search + * a standard case + * a bbox overlapping the bboxes of the tree + */ + void PointLocatorTest::test_PointLocator() { + MEDMEM::MESH* mesh2D= MEDMeshMaker(2,2,MED_EN::MED_QUAD4); + INTERP_KERNEL::PointLocator pl(*mesh2D) ; + double x[2]={0.0,0.0}; + std::list elems = pl.locate(x); + CPPUNIT_ASSERT_EQUAL(1,(int)elems.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)(*(elems.begin()))); + elems.clear(); + + double x2[2]={0.25,0.25}; + elems = pl.locate(x2); + CPPUNIT_ASSERT_EQUAL(1,(int)elems.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)(*(elems.begin()))); + elems.clear(); + + double x3[2]={0.5,0.5}; + elems = pl.locate(x3); + CPPUNIT_ASSERT_EQUAL(4,(int)elems.size()); + elems.clear(); + + double x4[2]={-1.0,0.0}; + elems = pl.locate(x4); + CPPUNIT_ASSERT_EQUAL(0,(int)elems.size()); + elems.clear(); + delete mesh2D; + + MEDMEM::MESH* mesh3D= MEDMeshMaker(3,2,MED_EN::MED_HEXA8); + INTERP_KERNEL::PointLocator pl3(*mesh3D); + double xx[3]={0.0,0.0,0.0}; + elems = pl3.locate(xx); + CPPUNIT_ASSERT_EQUAL(1,(int)elems.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)*(elems.begin())); + elems.clear(); + + double xx2[3]={0.25,0.25,0.25}; + elems = pl3.locate(xx2); + CPPUNIT_ASSERT_EQUAL(1,(int)elems.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)*(elems.begin())); + elems.clear(); + + double xx3[3]={0.5,0.5,0.5}; + elems = pl3.locate(xx3); + CPPUNIT_ASSERT_EQUAL(8,(int)elems.size()); + elems.clear(); + + double xx4[3]={-1.0,0.0,0.0}; + elems = pl3.locate(x4); + CPPUNIT_ASSERT_EQUAL(0,(int)elems.size()); + elems.clear(); + delete mesh3D; + + } + + +} diff --git a/src/INTERP_KERNELTest/PointLocatorTest.hxx b/src/INTERP_KERNELTest/PointLocatorTest.hxx new file mode 100644 index 000000000..84c576e47 --- /dev/null +++ b/src/INTERP_KERNELTest/PointLocatorTest.hxx @@ -0,0 +1,57 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TU_POINTLOCATOR_HXX__ +#define __TU_POINTLOCATOR_HXX__ + +#include +#include "PointLocator.hxx" + +namespace INTERP_TEST +{ + + /** + * \brief Test suite testing some of the low level methods of TransformedTriangle. + * + */ + class PointLocatorTest : public CppUnit::TestFixture + { + + CPPUNIT_TEST_SUITE( PointLocatorTest ); + CPPUNIT_TEST( test_PointLocator ); + CPPUNIT_TEST_SUITE_END(); + + + public: + void setUp(); + + void tearDown(); + + // tests + void test_PointLocator(); + + }; + + + + +} + + + +#endif diff --git a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.cxx b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.cxx new file mode 100644 index 000000000..f556f3a4c --- /dev/null +++ b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.cxx @@ -0,0 +1,1023 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "QuadraticPlanarInterpTest.hxx" +#include "QuadraticPolygon.hxx" +#include "EdgeArcCircle.hxx" +#include "ElementaryEdge.hxx" +#include "ComposedEdge.hxx" +#include "EdgeLin.hxx" + +#include +#include + +using namespace std; +using namespace INTERP_KERNEL; + +static const double ADMISSIBLE_ERROR = 1.e-14; + +void QuadraticPlanarInterpTest::setUp() +{ +} + +void QuadraticPlanarInterpTest::tearDown() +{ +} + +void QuadraticPlanarInterpTest::cleanUp() +{ +} + +void QuadraticPlanarInterpTest::ReadWriteInXfigElementary() +{ + //Testing bounds calculation. For Seg2 + istringstream stream("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n3200 3400 4500 4700"); + EdgeLin *e1=new EdgeLin(stream); + Bounds bound=e1->getBounds(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.32,bound[0],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.45,bound[1],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.34,bound[2],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.47,bound[3],ADMISSIBLE_ERROR); + e1->decrRef(); + istringstream stream2("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n4500 4700 3200 3400"); + e1=new EdgeLin(stream2); + bound=e1->getBounds(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.32,bound[0],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.45,bound[1],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.34,bound[2],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.47,bound[3],ADMISSIBLE_ERROR); + e1->decrRef(); + //Testing bounds calculation For Arc of circle. + +} + +void QuadraticPlanarInterpTest::ReadWriteInXfigGlobal() +{ + string dataBaseDir(getenv("MED_ROOT_DIR")); + dataBaseDir+="/share/salome/resources/med/"; + string tmp; + tmp=dataBaseDir; tmp+="Pol1.fig"; + QuadraticPolygon pol1(tmp.c_str()); + pol1.dumpInXfigFile("Pol1_gen.fig"); + tmp=dataBaseDir; tmp+="Pol2.fig"; + QuadraticPolygon pol2(tmp.c_str()); + pol2.dumpInXfigFile("Pol2_gen.fig"); + tmp=dataBaseDir; tmp+="Pol3.fig"; + QuadraticPolygon pol3(tmp.c_str()); + pol3.dumpInXfigFile("Pol3_gen.fig"); + tmp=dataBaseDir; tmp+="Pol4.fig"; + QuadraticPolygon pol4(tmp.c_str()); + CPPUNIT_ASSERT_EQUAL(1,pol4.size()); + ElementaryEdge *edge1=dynamic_cast(pol4[0]); + CPPUNIT_ASSERT(edge1); + Edge *edge2=edge1->getPtr(); + EdgeArcCircle *edge=dynamic_cast(edge2); + CPPUNIT_ASSERT(edge); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.24375,edge->getRadius(),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.7857653289925404,edge->getAngle(),ADMISSIBLE_ERROR); + double center[2]; + edge->getCenter(center); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.48,center[0],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.48375,center[1],ADMISSIBLE_ERROR); + const double *start=*edge->getStartNode(); + Node *n1=new Node(start[0]+2*(center[0]-start[0]),start[1]+2*(center[1]-start[1])); + edge->changeMiddle(n1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.24375,edge->getRadius(),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.7857653289925404,edge->getAngle(),ADMISSIBLE_ERROR); + n1->decrRef(); + n1=new Node(center[0],center[1]+0.24375); + edge->changeMiddle(n1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.24375,edge->getRadius(),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.49741997818704586,edge->getAngle(),ADMISSIBLE_ERROR);//5.7857653289925404 + 2*PI + n1->decrRef(); + //A half circle. + EdgeArcCircle *e=new EdgeArcCircle(0.84,0.54,0.78,0.6,0.84,0.66); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.06,e->getRadius(),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.1415925921507317,e->getAngle(),1e-5); + e->decrRef(); + e=new EdgeArcCircle(0.84,0.54,0.9,0.6,0.84,0.66); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.06,e->getRadius(),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415925921507317,e->getAngle(),1e-5); + e->decrRef(); +} + +void QuadraticPlanarInterpTest::BasicGeometricTools() +{ + Node *n1=new Node(1.,1.); + Node *n2=new Node(4.,2.); + EdgeLin *e1=new EdgeLin(n1,n2); + double tmp[2]; + e1->getNormalVector(tmp); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.94868329805051377,tmp[1],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.31622776601683794,tmp[0],ADMISSIBLE_ERROR); + e1->decrRef(); + n1->decrRef(); n2->decrRef(); + n1=new Node(1.,1.); + n2=new Node(0.,4.); + e1=new EdgeLin(n1,n2); + double tmp2[2]; + e1->getNormalVector(tmp2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,Node::dot(tmp,tmp2),1e-10); + tmp[0]=0.5; tmp[1]=2.5; + CPPUNIT_ASSERT(e1->isNodeLyingOn(tmp)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,e1->getDistanceToPoint(tmp),1e-12); + tmp[1]=2.55; CPPUNIT_ASSERT(!e1->isNodeLyingOn(tmp)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0158113883008418,e1->getDistanceToPoint(tmp),1e-12); + tmp[0]=0.; tmp[1]=5.; + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,e1->getDistanceToPoint(tmp),1e-12); + EdgeArcCircle *e=new EdgeArcCircle(4.,3.,0.,5.,-5.,0.); + tmp[0]=-4.; tmp[1]=3.; + CPPUNIT_ASSERT(e->isNodeLyingOn(tmp)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,e->getDistanceToPoint(tmp),1e-12); + tmp[1]=3.1; CPPUNIT_ASSERT(!e->isNodeLyingOn(tmp)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6.0632371551998077e-2,e->getDistanceToPoint(tmp),1e-12); + tmp[0]=-4.; tmp[1]=-3.; + CPPUNIT_ASSERT(!e->isNodeLyingOn(tmp)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1622776601683795,e->getDistanceToPoint(tmp),1e-12); + e->decrRef(); + e1->decrRef(); + n1->decrRef(); n2->decrRef(); +} + +void QuadraticPlanarInterpTest::IntersectionBasics() +{ + //Testing intersection of Bounds. + istringstream stream1("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n3200 3400 4500 4800"); + EdgeLin *e1=new EdgeLin(stream1); + istringstream stream2("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n3200 3400 4500 4800"); + EdgeLin *e2=new EdgeLin(stream2); + Bounds *bound=e1->getBounds().amIIntersectingWith(e2->getBounds()); CPPUNIT_ASSERT(bound); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.32,(*bound)[0],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.45,(*bound)[1],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.34,(*bound)[2],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.48,(*bound)[3],ADMISSIBLE_ERROR); + delete bound; + e2->decrRef(); e1->decrRef(); + // + istringstream stream3("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n3000 7200 6000 3700"); + EdgeLin *e3=new EdgeLin(stream3); + istringstream stream4("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n4800 6600 7200 4200"); + EdgeLin *e4=new EdgeLin(stream4); + bound=e3->getBounds().amIIntersectingWith(e4->getBounds()); CPPUNIT_ASSERT(bound); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.48,(*bound)[0],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.6,(*bound)[1],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.42,(*bound)[2],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.66,(*bound)[3],ADMISSIBLE_ERROR); + delete bound; + e3->decrRef(); e4->decrRef(); +} + +void QuadraticPlanarInterpTest::EdgeLinUnitary() +{ + EdgeLin *e1=new EdgeLin(0.5,0.5,3.7,4.1); + Node *n=new Node(2.1,2.3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),0.5,1e-8); + n->decrRef(); + n=new Node(3.7,4.1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),1.,1e-8); + n->decrRef(); + n=new Node(0.5,0.5); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),0.,1e-8); + n->decrRef(); + n=new Node(-1.1,-1.3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),-0.5,1e-8); + n->decrRef(); + n=new Node(5.3,5.9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),1.5,1e-8); + n->decrRef(); e1->decrRef(); +} + +/*! + * Here two things are tested. + * 1 ) One the overlapping calculation capability of edge/edge intersector. + * 2 ) Then the capability to handle the case where 2 segs (whatever their type) are overlapped. + * All the configuration of full or part overlapping have been tested. + */ +void QuadraticPlanarInterpTest::IntersectionEdgeOverlapUnitarySegSeg() +{ + ComposedEdge& v1=*(new ComposedEdge); + ComposedEdge& v2=*(new ComposedEdge); + MergePoints v3; + //Testing merge of geometric equals seg2. + Edge *e1=new EdgeLin(0.5,0.5,1.,1.); Edge *e2=new EdgeLin(0.5,0.5,1.,1.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); + v1.clear(); v2.clear(); v3.clear(); + // - testing by adding some noise + e1->decrRef(); e1=new EdgeLin(0.5+5.e-15,0.5-5.e-15,1.,1.+7.e-15); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Testing merge of geometric equals seg2 but now with opposite direction + e1=new EdgeLin(0.5,0.5,0.7,0.7); e2=new EdgeLin(0.7+6.e-15,0.7-2.e-15,0.5+3.e-15,0.5-4.e-15); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && !v2[0]->getDirection());//compared 8 lines above !v2[0]->getDirection() + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 0 + //Test 1 - OUT_AFTER - OUT_AFTER | same dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.5,0.,2.,0.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 2 - INSIDE - OUT_AFTER | same dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.5,0.,1.5,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresicEqualDirSensitive(v2[0])); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 2 - INSIDE - OUT_AFTER | same dir. - 90° + e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.5,0.,1.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresicEqualDirSensitive(v2[0])); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 2 - INSIDE - OUT_AFTER | same dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.5,0.5,1.5,1.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresicEqualDirSensitive(v2[0])); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 2 - INSIDE - OUT_AFTER | opp. dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.5,1.5,0.5,0.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(!v1[1]->intresicEqualDirSensitive(v2[1]) && v1[1]->intresicEqual(v2[1])); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 3 - INSIDE - INSIDE | same dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.25,0.,0.75,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==v1[2]->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()== e1->getStartNode()); CPPUNIT_ASSERT(v1[2]->getEndNode()== e1->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 3 - INSIDE - INSIDE | same dir. - 90° + e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.25,0.,0.75); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==v1[2]->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()== e1->getStartNode()); CPPUNIT_ASSERT(v1[2]->getEndNode()== e1->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 3 - INSIDE - INSIDE | same dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.25,0.25,0.75,0.75); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==v1[2]->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()== e1->getStartNode()); CPPUNIT_ASSERT(v1[2]->getEndNode()== e1->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 3 - INSIDE - INSIDE | opp dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.75,0.75,0.25,0.25); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && !v1[1]->getDirection()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==v1[2]->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()== e1->getStartNode()); CPPUNIT_ASSERT(v1[2]->getEndNode()== e1->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getEndNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 3bis - INSIDE - INSIDE - Bis | opp dir. + double center[2]={0.,0.}; + double radius=1.; + e1=buildArcOfCircle(center,radius,-M_PI,0); e2=buildArcOfCircle(center,radius,-2*M_PI/3.+2*M_PI,-M_PI/3.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(5.*M_PI/3.,e2->getCurveLength(),1e-12);// To check that in the previous line +2.M_PI has done its job. + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[0]->getPtr())); CPPUNIT_ASSERT(v1[0]->getDirection()); CPPUNIT_ASSERT(!v2[0]->getDirection()); + CPPUNIT_ASSERT(v1[2]->intresincEqCoarse(v2[2]->getPtr())); CPPUNIT_ASSERT(v1[2]->getDirection()); CPPUNIT_ASSERT(!v2[2]->getDirection()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[1]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); + CPPUNIT_ASSERT(v1[1]->getStartNode()==e2->getStartNode()); + CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 3bis - INSIDE - INSIDE - Bis | same dir. + e1=buildArcOfCircle(center,radius,-M_PI,0); e2=buildArcOfCircle(center,radius,-M_PI/3.,-2*M_PI/3.+2*M_PI); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(5.*M_PI/3.,e2->getCurveLength(),1e-12);// To check that in the previous line +2.M_PI has done its job. + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[2]->getPtr())); CPPUNIT_ASSERT(v1[0]->getDirection()); CPPUNIT_ASSERT(v2[2]->getDirection()); + CPPUNIT_ASSERT(v1[2]->intresincEqCoarse(v2[0]->getPtr())); CPPUNIT_ASSERT(v1[2]->getDirection()); CPPUNIT_ASSERT(v2[0]->getDirection()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[1]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v1[1]->getStartNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getStartNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 3bis - INSIDE - INSIDE - Bis | opp dir. | e1<->e2 to test symetry + e1=buildArcOfCircle(center,radius,-M_PI,0); e2=buildArcOfCircle(center,radius,-2*M_PI/3.+2*M_PI,-M_PI/3.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(5.*M_PI/3.,e2->getCurveLength(),1e-12);// To check that in the previous line +2.M_PI has done its job. + CPPUNIT_ASSERT(e2->intersectWith(e1,v3,v2,v1)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[0]->getPtr())); CPPUNIT_ASSERT(!v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->getDirection()); + CPPUNIT_ASSERT(v1[2]->intresincEqCoarse(v2[2]->getPtr())); CPPUNIT_ASSERT(!v1[2]->getDirection()); CPPUNIT_ASSERT(v2[2]->getDirection()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-5); // << not maximal precision because node switching + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[1]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); + CPPUNIT_ASSERT(v1[1]->getStartNode()==e2->getStartNode()); + CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 3bis - INSIDE - INSIDE - Bis | same dir. | e1<->e2 to test symetry + e1=buildArcOfCircle(center,radius,-M_PI,0); e2=buildArcOfCircle(center,radius,-M_PI/3.,-2*M_PI/3.+2*M_PI); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(5.*M_PI/3.,e2->getCurveLength(),1e-12);// To check that in the previous line +2.M_PI has done its job. + CPPUNIT_ASSERT(e2->intersectWith(e1,v3,v2,v1)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[2]->getPtr())); CPPUNIT_ASSERT(v1[0]->getDirection()); CPPUNIT_ASSERT(v2[2]->getDirection()); + CPPUNIT_ASSERT(v1[2]->intresincEqCoarse(v2[0]->getPtr())); CPPUNIT_ASSERT(v1[2]->getDirection()); CPPUNIT_ASSERT(v2[0]->getDirection()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-5); // << not maximal precision because node switching + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[1]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v1[1]->getStartNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getStartNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 4 - OUT_BEFORE - OUT_BEFORE | same dir. - 0 ° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-1.,0.,-0.5,0.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 5 - OUT_BEFORE - INSIDE | same dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-0.5,0.,0.5,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresicEqualDirSensitive(v2[1])); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 5 - OUT_BEFORE - INSIDE | same dir. - 90° + e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0,-0.5,0.,0.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresicEqualDirSensitive(v2[1])); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 5 - OUT_BEFORE - INSIDE | same dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(-0.5,-0.5,0.5,0.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresicEqualDirSensitive(v2[1])); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 5 - OUT_BEFORE - INSIDE | opp dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.5,0.5,-0.5,-0.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(!v1[0]->intresicEqualDirSensitive(v2[0]) && v1[0]->intresicEqual(v2[0]) ); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 6 - OUT_BEFORE - OUT_AFTER | same dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-0.5,0.,1.5,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); + CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode() && v2[1]->getEndNode()==v2[2]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 6 - OUT_BEFORE - OUT_AFTER | same dir. - 90° + e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,-0.5,0.,1.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); + CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode() && v2[1]->getEndNode()==v2[2]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 6 - OUT_BEFORE - OUT_AFTER | same dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(-0.5,-0.5,1.5,1.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); + CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode() && v2[1]->getEndNode()==v2[2]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 6 - OUT_BEFORE - OUT_AFTER | opp dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.5,1.5,-0.5,-0.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); + CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && !v2[1]->getDirection()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode() && v2[1]->getEndNode()==v2[2]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 7 - END - OUT_AFTER | same dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.,0.,1.5,0.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 7 - END - OUT_AFTER | opp dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.5,0.,1.,0.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); + CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 8 - START - END | same dir. - 0° + e1=new EdgeLin(0.,0.,0.7,0.); e2=new EdgeLin(0.,0.,0.7,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 8 - START - END | same dir. - 90° + e1=new EdgeLin(0.,0.,0.,0.7); e2=new EdgeLin(0.,0.,0.,0.7); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 8 - START - END | same dir. - 45° + e1=new EdgeLin(0.,0.,0.7,0.7); e2=new EdgeLin(0.,0.,0.7,0.7); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 8 - START - END | opp. dir. - 45° + e1=new EdgeLin(0.,0.,0.7,0.7); e2=new EdgeLin(0.7,0.7,0.,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && !v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==e2->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 9 - OUT_BEFORE - START | same dir. + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-0.5,0.,0.,0.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); + CPPUNIT_ASSERT(e2->getEndNode()==e1->getStartNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 10 - START - OUT_AFTER | same dir. - 0° + e1=new EdgeLin(0.,0.,0.7,0.); e2=new EdgeLin(0.,0.,1.,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(v2[1]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 10 - START - OUT_AFTER | same dir. - 90° + e1=new EdgeLin(0.,0.,0.,0.7); e2=new EdgeLin(0.,0.,0.,1.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(v2[1]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 10 - START - OUT_AFTER | same dir. - 45° + e1=new EdgeLin(0.,0.,0.7,0.7); e2=new EdgeLin(0.,0.,1.,1.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(v2[1]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 10 - START - OUT_AFTER | opp dir. - 45° + e1=new EdgeLin(0.,0.,0.7,0.7); e2=new EdgeLin(1.,1.,0.,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && !v2[1]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getEndNode()); CPPUNIT_ASSERT(v2[1]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 11 - INSIDE - END | same dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.7,0.,1.,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 11 - INSIDE - END | same dir. - 90° + e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.7,0.,1.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 11 - INSIDE - END | same dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.7,0.7,1.,1.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 11 - INSIDE - END | opp dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.,1.,0.7,0.7); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getStartNode()); + CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && !v1[1]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 12 - OUT_BEFORE - END | same dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-0.5,0.,1.,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); + CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 12 - OUT_BEFORE - END | same dir. - 90° + e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,-0.5,0.,1.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); + CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 12 - OUT_BEFORE - END | same dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(-0.5,-0.5,1.,1.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); + CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 12 - OUT_BEFORE - END | opp dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.,1.,-0.5,-0.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && !v2[0]->getDirection()); + CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 13 - START - INSIDE | same dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.,0.,0.5,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e2) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e2->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 13 - START - INSIDE | same dir. - 90° + e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.,0.,0.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e2) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e2->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 13 - START - INSIDE | same dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.,0.,0.5,0.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e2) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e2->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 13 - START - INSIDE | opp dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.5,0.5,0.,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e2) && !v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e2->getEndNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 14 - INSIDE - START | same dir. + e1=buildArcOfCircle(center,radius,-M_PI,2.*M_PI); e2=buildArcOfCircle(center,radius,M_PI/3.,-M_PI); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.*M_PI/3.,e2->getCurveLength(),1e-12); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresicEqual(v2[0])); + CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[1]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getEndNode()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2*M_PI/3.,v1[0]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v2[0]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-12); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 14 - INSIDE - START | opp dir. + e1=buildArcOfCircle(center,radius,-M_PI,2.*M_PI); e2=buildArcOfCircle(center,radius,-M_PI,M_PI/3.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.*M_PI/3.,e2->getCurveLength(),1e-12); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(v2[1]->getPtr()) && !v2[1]->getDirection() && v1[1]->getDirection()); + CPPUNIT_ASSERT(v2[0]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[1]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2*M_PI/3.,v1[0]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v2[1]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[0]->getCurveLength(),1.e-12); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 15 - END - INSIDE | same dir. + e1=buildArcOfCircle(center,radius,-M_PI,2.*M_PI); e2=buildArcOfCircle(center,radius,0.,-4.*M_PI/3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.*M_PI/3.,e2->getCurveLength(),1e-12); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresicEqual(v2[1])); + CPPUNIT_ASSERT(v2[0]->getEndNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[1]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getStartNode()==e1->getEndNode()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[0]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[0]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.*M_PI/3.,v1[1]->getCurveLength(),1.e-12); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 15 - END - INSIDE | opp dir. + e1=buildArcOfCircle(center,radius,-M_PI,2.*M_PI); e2=buildArcOfCircle(center,radius,-4.*M_PI/3,0.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.*M_PI/3.,e2->getCurveLength(),1e-12); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[0]->getPtr()) && !v2[0]->getDirection() && v1[0]->getDirection()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[1]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[0]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.*M_PI/3.,v1[1]->getCurveLength(),1.e-12); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + // + ComposedEdge::Delete(&v1); + ComposedEdge::Delete(&v2); +} + +/*! + * Here there is test of cases where between 2 edges intersects only in points not on edge. + */ +void QuadraticPlanarInterpTest::IntersectionPointOnlyUnitarySegSeg() +{ + // 0° - classical + EdgeLin *e1=new EdgeLin(0.,0.,1.,0.); + EdgeLin *e2=new EdgeLin(0.3,0.3,0.5,-0.3); + ComposedEdge& v1=*(new ComposedEdge); + ComposedEdge& v2=*(new ComposedEdge); MergePoints v3; + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.4,(*v1[0]->getEndNode())[0],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,(*v1[0]->getEndNode())[1],ADMISSIBLE_ERROR); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + // 90° - classical + e1=new EdgeLin(0.,0.,0.,1.); + e2=new EdgeLin(-0.3,0.3,0.3,0.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,(*v1[0]->getEndNode())[0],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.4,(*v1[0]->getEndNode())[1],ADMISSIBLE_ERROR); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 1 - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.,0.,0.,1.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v3.isStart1(0)); CPPUNIT_ASSERT(v3.isStart2(0)); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 1 - 90° + e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.,1.,0.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v3.isStart1(0)); CPPUNIT_ASSERT(v3.isStart2(0)); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 1 - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.,0.,1.,-1.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v3.isStart1(0)); CPPUNIT_ASSERT(v3.isStart2(0)); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 2 + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.,1.,1.,0.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v3.isEnd1(0)); CPPUNIT_ASSERT(v3.isEnd2(0)); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 3 + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.,0.,1.,1.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v3.isEnd1(0)); CPPUNIT_ASSERT(v3.isStart2(0)); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 4 + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.,-1.,0.,0.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v3.isStart1(0)); CPPUNIT_ASSERT(v3.isEnd2(0)); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Intersection extremity of one edge and inside of other edge. 2 End. + e1=new EdgeLin(0.,0.,1.,0.); + e2=new EdgeLin(0.5,1.,0.5,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode() && v1[0]->getEndNode()==e2->getEndNode() && v1[1]->getStartNode()==e2->getEndNode() && v1[1]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getDirection() && v1[1]->getDirection()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Intersection extremity of one edge and inside of other edge. 2 Start. + e1=new EdgeLin(0.,0.,1.,0.); + e2=new EdgeLin(0.5,0.,0.5,1.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode() && v1[0]->getEndNode()==e2->getStartNode() && v1[1]->getStartNode()==e2->getStartNode() && v1[1]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getDirection() && v1[1]->getDirection()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Intersection extremity of one edge and inside of other edge. 1 Start. + e1=new EdgeLin(0.5,0.,0.5,1.); + e2=new EdgeLin(0.,0.,1.,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); + CPPUNIT_ASSERT(v2[0]->getStartNode()==e2->getStartNode() && v2[0]->getEndNode()==e1->getStartNode() && v2[1]->getStartNode()==e1->getStartNode() && v2[1]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getDirection() && v2[1]->getDirection()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Intersection extremity of one edge and inside of other edge. 1 End. + e1=new EdgeLin(0.5,1.,0.5,0.); + e2=new EdgeLin(0.,0.,1.,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); + CPPUNIT_ASSERT(v2[0]->getStartNode()==e2->getStartNode() && v2[0]->getEndNode()==e1->getEndNode() && v2[1]->getStartNode()==e1->getEndNode() && v2[1]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getDirection() && v2[1]->getDirection()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + ComposedEdge::Delete(&v2); + ComposedEdge::Delete(&v1); +} diff --git a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx new file mode 100644 index 000000000..da60159a8 --- /dev/null +++ b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx @@ -0,0 +1,201 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef _QUADRATICPLANARINTERPTEST_HXX_ +#define _QUADRATICPLANARINTERPTEST_HXX_ + +#include + +namespace INTERP_KERNEL +{ + class Node; + class EdgeArcCircle; + class QuadraticPolygon; + + class QuadraticPlanarInterpTest : public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE( QuadraticPlanarInterpTest ); + CPPUNIT_TEST( ReadWriteInXfigElementary ); + CPPUNIT_TEST( ReadWriteInXfigGlobal ); + CPPUNIT_TEST( BasicGeometricTools ); + CPPUNIT_TEST( IntersectionBasics ); + CPPUNIT_TEST( EdgeLinUnitary ); + CPPUNIT_TEST( IntersectionEdgeOverlapUnitarySegSeg ); + CPPUNIT_TEST( IntersectionPointOnlyUnitarySegSeg ); + CPPUNIT_TEST( IntersectArcCircleBase ); + CPPUNIT_TEST( IntersectArcCircleFull ); + CPPUNIT_TEST( IntersectArcCircleSegumentBase ); + CPPUNIT_TEST( checkInOutDetection ); + CPPUNIT_TEST( checkAssemblingBases1 ); + CPPUNIT_TEST( checkAssemblingBases2 ); + CPPUNIT_TEST( checkPolygonsIntersection1 ); + CPPUNIT_TEST( checkPolygonsIntersection2 ); + CPPUNIT_TEST( checkAreasCalculations ); + CPPUNIT_TEST( checkBarycenterCalculations ); + CPPUNIT_TEST( checkHighLevelFunctionTest1 ); + CPPUNIT_TEST( check1DInterpLin ); + CPPUNIT_TEST( checkEpsilonCoherency1 ); + CPPUNIT_TEST( checkNonRegression1 ); + CPPUNIT_TEST( checkNonRegression2 ); + CPPUNIT_TEST( checkNonRegression3 ); + CPPUNIT_TEST( checkNonRegression4 ); + CPPUNIT_TEST( checkNonRegression5 ); + CPPUNIT_TEST( checkNonRegression6 ); + CPPUNIT_TEST( checkNonRegression7 ); + CPPUNIT_TEST( checkNonRegression8 ); + CPPUNIT_TEST( checkNonRegression9 ); + CPPUNIT_TEST( checkNonRegression10 ); + CPPUNIT_TEST( checkNonRegression11 ); + CPPUNIT_TEST( checkNonRegression12 ); + CPPUNIT_TEST ( checkNonRegression13 ); + CPPUNIT_TEST ( checkNonRegression14 ); + CPPUNIT_TEST ( checkNonRegression15 ); + CPPUNIT_TEST ( checkNonRegression16 ); + CPPUNIT_TEST ( checkNonRegression17 ); + // + CPPUNIT_TEST ( checkNonRegressionOmar0000 ); + CPPUNIT_TEST ( checkNonRegressionOmar0001 ); + CPPUNIT_TEST ( checkNonRegressionOmar0002 ); + CPPUNIT_TEST ( checkNonRegressionOmar0003 ); + CPPUNIT_TEST ( checkNonRegressionOmar0004 ); + CPPUNIT_TEST ( checkNonRegressionOmar0005 ); + CPPUNIT_TEST ( checkNonRegressionOmar0006 ); + CPPUNIT_TEST ( checkNonRegressionOmar0007 ); + CPPUNIT_TEST ( checkNonRegressionOmar0008 ); + CPPUNIT_TEST ( checkNonRegressionOmar0009 ); + CPPUNIT_TEST ( checkNonRegressionOmar0010 ); + CPPUNIT_TEST ( checkNonRegressionOmar0011 ); + CPPUNIT_TEST ( checkNonRegressionOmar2511 ); + CPPUNIT_TEST ( checkNonRegressionOmar0012 ); + CPPUNIT_TEST ( checkNonRegressionOmar0013 ); + CPPUNIT_TEST ( checkNonRegressionOmar0014 ); + CPPUNIT_TEST ( checkNonRegressionOmar0015 ); + CPPUNIT_TEST ( checkNonRegressionOmar0016 ); + CPPUNIT_TEST ( checkNonRegressionOmar0017 ); + CPPUNIT_TEST ( checkNonRegressionOmar0018 ); + CPPUNIT_TEST ( checkNonRegressionOmar0019 ); + CPPUNIT_TEST ( checkNonRegressionOmar0020 ); + CPPUNIT_TEST ( checkNonRegressionOmar0021 ); + CPPUNIT_TEST ( checkNonRegressionOmar0022 ); + CPPUNIT_TEST ( checkNonRegressionOmar0023 ); + CPPUNIT_TEST ( checkNonRegressionOmar0024 ); + CPPUNIT_TEST ( checkNonRegressionOmar2524 ); + CPPUNIT_TEST ( checkNonRegressionOmar0025 ); + CPPUNIT_TEST ( checkNonRegressionOmar0026 ); + CPPUNIT_TEST ( checkNonRegressionOmar0027 ); + CPPUNIT_TEST ( checkNonRegressionOmar0028 ); + CPPUNIT_TEST ( checkNonRegressionOmar0029 ); + CPPUNIT_TEST ( checkNonRegressionOmar0030 ); + // + CPPUNIT_TEST( checkNormalize ); + CPPUNIT_TEST_SUITE_END(); + public: + void setUp(); + void tearDown(); + void cleanUp(); + // + void ReadWriteInXfigElementary(); + void ReadWriteInXfigGlobal(); + void BasicGeometricTools(); + void IntersectionBasics(); + void EdgeLinUnitary(); + void IntersectionEdgeOverlapUnitarySegSeg(); + void IntersectionPointOnlyUnitarySegSeg(); + // + void IntersectArcCircleBase(); + void IntersectArcCircleFull(); + void IntersectArcCircleSegumentBase(); + // + void checkInOutDetection(); + // + void checkAssemblingBases1(); + void checkAssemblingBases2(); + // + void checkPolygonsIntersection1(); + void checkPolygonsIntersection2(); + void checkAreasCalculations(); + void checkBarycenterCalculations(); + // + void checkHighLevelFunctionTest1(); + // + void check1DInterpLin(); + // + void checkEpsilonCoherency1(); + // + void checkNonRegression1(); + void checkNonRegression2(); + void checkNonRegression3(); + void checkNonRegression4(); + void checkNonRegression5(); + void checkNonRegression6(); + void checkNonRegression7(); + void checkNonRegression8(); + void checkNonRegression9(); + void checkNonRegression10(); + void checkNonRegression11(); + void checkNonRegression12(); + void checkNonRegression13(); + void checkNonRegression14(); + void checkNonRegression15(); + void checkNonRegression16(); + void checkNonRegression17(); + // + void checkNonRegressionOmar0000(); + void checkNonRegressionOmar0001(); + void checkNonRegressionOmar0002(); + void checkNonRegressionOmar0003(); + void checkNonRegressionOmar0004(); + void checkNonRegressionOmar0005(); + void checkNonRegressionOmar0006(); + void checkNonRegressionOmar0007(); + void checkNonRegressionOmar0008(); + void checkNonRegressionOmar0009(); + void checkNonRegressionOmar0010(); + void checkNonRegressionOmar0011(); + void checkNonRegressionOmar2511(); + void checkNonRegressionOmar0012(); + void checkNonRegressionOmar0013(); + void checkNonRegressionOmar0014(); + void checkNonRegressionOmar0015(); + void checkNonRegressionOmar0016(); + void checkNonRegressionOmar0017(); + void checkNonRegressionOmar0018(); + void checkNonRegressionOmar0019(); + void checkNonRegressionOmar0020(); + void checkNonRegressionOmar0021(); + void checkNonRegressionOmar0022(); + void checkNonRegressionOmar0023(); + void checkNonRegressionOmar0024(); + void checkNonRegressionOmar2524(); + void checkNonRegressionOmar0025(); + void checkNonRegressionOmar0026(); + void checkNonRegressionOmar0027(); + void checkNonRegressionOmar0028(); + void checkNonRegressionOmar0029(); + void checkNonRegressionOmar0030(); + // + void checkNormalize(); + private: + QuadraticPolygon *buildQuadraticPolygonCoarseInfo(const double *coords, const int *conn, int lgth); + EdgeArcCircle *buildArcOfCircle(const double *center, double radius, double alphaStart, double alphaEnd); + double btw2NodesAndACenter(const Node& n1, const Node& n2, const double *center); + void checkBasicsOfPolygons(QuadraticPolygon& pol1, QuadraticPolygon& pol2, bool checkDirection); + }; +} + +#endif diff --git a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest2.cxx b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest2.cxx new file mode 100644 index 000000000..026ce84ea --- /dev/null +++ b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest2.cxx @@ -0,0 +1,669 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "QuadraticPlanarInterpTest.hxx" +#include "QuadraticPolygon.hxx" +#include "EdgeArcCircle.hxx" +#include "EdgeLin.hxx" + +#include +#include +#include + +using namespace std; +using namespace INTERP_KERNEL; + +static const double ADMISSIBLE_ERROR = 1.e-14; + +void QuadraticPlanarInterpTest::IntersectArcCircleBase() +{ + double center[2]={0.5,0.5}; + double radius=0.3; + EdgeArcCircle *e1=buildArcOfCircle(center,radius,M_PI/4.,M_PI/3.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(M_PI/3),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(M_PI/4),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(M_PI/4),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(M_PI/3),ADMISSIBLE_ERROR); + e1->decrRef(); + // + e1=buildArcOfCircle(center,radius,M_PI/3.,M_PI/2.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(M_PI/2),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(M_PI/3),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(M_PI/3),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(M_PI/2),ADMISSIBLE_ERROR); + e1->decrRef(); + // + e1=buildArcOfCircle(center,radius,M_PI/3.,3.*M_PI/4.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(3*M_PI/4),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(M_PI/3),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(3*M_PI/4),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(M_PI/2),ADMISSIBLE_ERROR);//<< + e1->decrRef(); + // + e1=buildArcOfCircle(center,radius,3*M_PI/4,7*M_PI/8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(7*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(3*M_PI/4),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(7*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(3*M_PI/4),ADMISSIBLE_ERROR); + e1->decrRef(); + // + e1=buildArcOfCircle(center,radius,7.*M_PI/8.,9.*M_PI/8.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(M_PI),ADMISSIBLE_ERROR);//<< + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(7*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(9*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(7*M_PI/8),ADMISSIBLE_ERROR); + e1->decrRef(); + // + e1=buildArcOfCircle(center,radius,9.*M_PI/8.,11.*M_PI/8.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(9*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(11*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(11*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(9*M_PI/8),ADMISSIBLE_ERROR); + e1->decrRef(); + // + e1=buildArcOfCircle(center,radius,11.*M_PI/8.,7.*M_PI/4.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(11*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(7*M_PI/4),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(3*M_PI/2),ADMISSIBLE_ERROR);//<< + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(7*M_PI/4),ADMISSIBLE_ERROR); + e1->decrRef(); + // + e1=buildArcOfCircle(center,radius,7.*M_PI/4.,15.*M_PI/8.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(7*M_PI/4),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(15*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(7*M_PI/4),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(15*M_PI/8),ADMISSIBLE_ERROR); + e1->decrRef(); + // + e1=buildArcOfCircle(center,radius,-M_PI/8.,M_PI/4.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(M_PI/4),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(0.),ADMISSIBLE_ERROR); //<< + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(15*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(M_PI/4),ADMISSIBLE_ERROR); + e1->decrRef(); + // + // ArcCArcCIntersector + // + TypeOfLocInEdge where1,where2; + vector v4; + MergePoints v3; + EdgeArcCircle *e2; + ArcCArcCIntersector *intersector=0; + for(unsigned k=0;k<8;k++) + { + e1=buildArcOfCircle(center,radius,M_PI/4.+k*M_PI/4.,M_PI/3.+k*M_PI/4.); + e2=buildArcOfCircle(center,radius,M_PI/4.+k*M_PI/4.,M_PI/3.+k*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); + CPPUNIT_ASSERT(where1==START && where2==END); + delete intersector; v3.clear(); e2->decrRef(); + // + e2=buildArcOfCircle(center,radius,7*M_PI/24.+k*M_PI/4.,M_PI/3.+k*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); + CPPUNIT_ASSERT(where1==INSIDE && where2==END); + delete intersector; v3.clear(); e2->decrRef(); + // + e2=buildArcOfCircle(center,radius,M_PI/4.+k*M_PI/4.,7*M_PI/24.+k*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); + CPPUNIT_ASSERT(where1==START && where2==INSIDE); + delete intersector; v3.clear(); e2->decrRef(); + // + e2=buildArcOfCircle(center,radius,13.*M_PI/48.+k*M_PI/4.,15*M_PI/48.+k*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); + CPPUNIT_ASSERT(where1==INSIDE && where2==INSIDE); + delete intersector; v3.clear(); e2->decrRef(); + // + e2=buildArcOfCircle(center,radius,-M_PI/4.+k*M_PI/4.,M_PI/6.+k*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); + CPPUNIT_ASSERT(where1==OUT_BEFORE && where2==OUT_BEFORE); + delete intersector; v3.clear(); e2->decrRef(); + // + e2=buildArcOfCircle(center,radius,0+k*M_PI/4.,5*M_PI/6.+k*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); + CPPUNIT_ASSERT(where1==OUT_BEFORE && where2==OUT_AFTER); + delete intersector; v3.clear(); e2->decrRef(); + e1->decrRef(); + } + // Ok now let's see intersection only. 2 intersections R1 > R2 ; dist(circle1,circle2)>R1; Opposite order. + for(unsigned k=0;k<8;k++) + { + center[0]=0.; center[1]=0.; + double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,3.,(k-1)*M_PI/4.,(k+1)*M_PI/4.); + e2=buildArcOfCircle(center2,1.,M_PI+(k-1)*M_PI/4.,M_PI+(k+1)*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); + CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); + CPPUNIT_ASSERT_DOUBLES_EQUAL(btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),0.35587863972199624,1e-10); + for(vector::iterator iter=v4.begin();iter!=v4.end();iter++) + (*iter)->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // Ok now let's see intersection only. 2 intersections R1 > R2 ; dist(circle1,circle2)>R1; Same order. + for(unsigned k=0;k<7;k++) + { + center[0]=0.; center[1]=0.; + double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,3.,(k-1)*M_PI/4.,(k+1)*M_PI/4.); + e2=buildArcOfCircle(center2,1.,M_PI+(k+1)*M_PI/4.,M_PI+(k-1)*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); + CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); + CPPUNIT_ASSERT_DOUBLES_EQUAL(btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),0.35587863972199624,1e-10); + for(vector::iterator iter=v4.begin();iter!=v4.end();iter++) + (*iter)->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // 2 intersections R1>R2 ; dist(circle1,circle2)areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); + CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); + CPPUNIT_ASSERT_DOUBLES_EQUAL(btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),0.6793851523346941,1e-10); + for(vector::iterator iter=v4.begin();iter!=v4.end();iter++) + (*iter)->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // 2 intersections R1>R2 ; dist(circle1,circle2)areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); + CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); + CPPUNIT_ASSERT_DOUBLES_EQUAL(btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),0.6793851523346941,1e-10); + for(vector::iterator iter=v4.begin();iter!=v4.end();iter++) + (*iter)->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // Ok now let's see intersection only. 2 intersections R1 < R2 ; dist(circle1,circle2)>R2; Opposite order. + for(unsigned k=0;k<1;k++) + { + double center2[2]; center[0]=0.; center[1]=0.; + center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,1.,(k-1)*M_PI/4.,(k+1)*M_PI/4.); + e2=buildArcOfCircle(center2,3.,M_PI+(k-1)*M_PI/4.,M_PI+(k+1)*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); + CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.1195732971845034,btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),1e-10); + for(vector::iterator iter=v4.begin();iter!=v4.end();iter++) + (*iter)->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // Ok now let's see intersection only. 2 intersections R1 < R2 ; dist(circle1,circle2)>R2; same order. + for(unsigned k=0;k<8;k++) + { + double center2[2]; center[0]=0.; center[1]=0.; + center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,1.,(k+1)*M_PI/4.,(k-1)*M_PI/4.); + e2=buildArcOfCircle(center2,3.,M_PI+(k-1)*M_PI/4.,M_PI+(k+1)*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); + CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.1195732971845034,btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),1e-10); + for(vector::iterator iter=v4.begin();iter!=v4.end();iter++) + (*iter)->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // Ok now let's see intersection only. 2 intersections R1 < R2 ; dist(circle1,circle2)areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); + CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.0844420190512074,btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),1e-10); + for(vector::iterator iter=v4.begin();iter!=v4.end();iter++) + (*iter)->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // Ok now let's see intersection only. 2 intersections R1 < R2 ; dist(circle1,circle2)areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); + CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.0844420190512074,btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),1e-10); + for(vector::iterator iter=v4.begin();iter!=v4.end();iter++) + (*iter)->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // Tangent intersection + QUADRATIC_PLANAR::setPrecision(1e-5); + for(unsigned k=0;k<8;k++) + { + double center2[2]; center[0]=0.; center[1]=0.; + center2[0]=4.*cos(k*M_PI/4.); center2[1]=4.*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,1.,(k+1)*M_PI/4.,(k-1)*M_PI/4.); + e2=buildArcOfCircle(center2,3.,M_PI+(k-1)*M_PI/4.,M_PI+(k+1)*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); // order has no sence here because v4.size() expected to 1 but for valgrind serenity test. + CPPUNIT_ASSERT_EQUAL(1,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + for(vector::iterator iter=v4.begin();iter!=v4.end();iter++) + (*iter)->decrRef(); + v4.clear(); v4.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + QUADRATIC_PLANAR::setPrecision(1e-14); + // Extremities # 1 + for(unsigned k=0;k<8;k++) + { + center[0]=0.; center[1]=0.; + double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,3.,k*M_PI/4.-0.17793931986099812,k*M_PI/4.+0.17793931986099812); + e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.-0.55978664859225125,M_PI+k*M_PI/4.+0.55978664859225125); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(!intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT_EQUAL(0,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(e1->getStartNode()==e2->getEndNode()); CPPUNIT_ASSERT(e2->getStartNode()==e1->getEndNode()); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + for(unsigned k=0;k<8;k++) + { + center[0]=0.; center[1]=0.; + double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,3.,k*M_PI/4.-0.17793931986099812,k*M_PI/4.+0.17793931986099812); + e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.55978664859225125,M_PI+k*M_PI/4.-0.55978664859225125); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(!intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT_EQUAL(0,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==e1->getEndNode()); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // Extremities # 2 + for(unsigned k=0;k<8;k++) + { + center[0]=0.; center[1]=0.; + double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,3.,k*M_PI/4.-0.17793931986099812,k*M_PI/4.+0.17793931986099812); + e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.55978664859225125,M_PI+k*M_PI/4.-0.7); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); + CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(1,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v4[0]); + v4[0]->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // Extremities # 3 + for(unsigned k=0;k<8;k++) + { + center[0]=0.; center[1]=0.; + double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,3.,k*M_PI/4.-0.17793931986099812,k*M_PI/4.+0.17793931986099812); + e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.7,M_PI+k*M_PI/4.-0.7); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(e1->getStartNode()==v4[0]); CPPUNIT_ASSERT(e1->getEndNode()==v4[1]); + v4[0]->decrRef(); v4[1]->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // Extremities # 4 + for(unsigned k=0;k<8;k++) + { + center[0]=0.; center[1]=0.; + double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + Node *nodeS=new Node(center[0]+3.*cos(k*M_PI/4.-0.17793931986099812),center[1]+3.*sin(k*M_PI/4.-0.17793931986099812)); + Node *nodeE=new Node(center[0]+3.*cos(k*M_PI/4.),center[1]+3.*sin(k*M_PI/4.)); + double angle=k*M_PI/4.-0.17793931986099812; + angle=angle>M_PI?angle-2.*M_PI:angle; + e1=new EdgeArcCircle(nodeS,nodeE,//Problem of precision 1e-14 to easily reached. + center,3.,angle,0.17793931986099812); + nodeS->decrRef(); nodeE->decrRef(); + e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.7,M_PI+k*M_PI/4.-0.7); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(1,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(e1->getStartNode()==v4[0]); + v4[0]->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + //Extremities # 5 + for(unsigned k=0;k<8;k++) + { + center[0]=0.; center[1]=0.; + double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + Node *nodeS=new Node(center[0]+3.*cos(k*M_PI/4.-0.17793931986099812),center[1]+3.*sin(k*M_PI/4.-0.17793931986099812)); + Node *nodeE=new Node(center[0]+3.*cos(k*M_PI/4.)+0.5,center[1]+3.*sin(k*M_PI/4.)); + double angle=k*M_PI/4.-0.17793931986099812; + angle=angle>M_PI?angle-2.*M_PI:angle; + e1=new EdgeArcCircle(nodeS,nodeE,//Problem of precision 1e-14 to easily reached. + center,3.,angle,0.67793931986099812); + nodeS->decrRef(); nodeE->decrRef(); + e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.7,M_PI+k*M_PI/4.-0.7); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(e1->getStartNode()==v4[0]); + v4[0]->decrRef(); v4[1]->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } +} + +void QuadraticPlanarInterpTest::IntersectArcCircleFull() +{ + double center1[2]; center1[0]=0.; center1[1]=0.; double radius1=3.; + double center2[2]; center2[0]=0.75; center2[1]=-2.6; double radius2=1.; + EdgeArcCircle *e1=buildArcOfCircle(center1,radius1,-M_PI/3.,4.*M_PI/3.); + EdgeArcCircle *e2=buildArcOfCircle(center2,radius2,0.,M_PI/2.); + MergePoints commonNode; + QuadraticPolygon pol1; QuadraticPolygon pol2; + QuadraticPolygon pol3; QuadraticPolygon pol4; + pol3.pushBack(e1); pol4.pushBack(e2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol3.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol4.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(19.6648305849,pol3.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.8146018366,pol4.getArea(),1e-6); + CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol1,pol2)); + CPPUNIT_ASSERT_EQUAL(2,pol1.size()); + CPPUNIT_ASSERT_EQUAL(2,pol2.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(19.6648305849,pol1.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.8146018366,pol2.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol1.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol2.getPerimeter(),1e-6); + // + e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); + e2=buildArcOfCircle(center2,radius2,0.,M_PI/2.); + commonNode.clear(); + QuadraticPolygon pol5; QuadraticPolygon pol6; + QuadraticPolygon pol7; QuadraticPolygon pol8; + pol7.pushBack(e1); pol8.pushBack(e2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol7.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol8.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol7.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.8146018366,pol8.getArea(),1e-6); + CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol5,pol6)); + CPPUNIT_ASSERT_EQUAL(2,pol5.size()); + CPPUNIT_ASSERT_EQUAL(2,pol6.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol5.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.8146018366,pol6.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol5.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol6.getPerimeter(),1e-6); + // + center2[0]=3.5; center2[1]=0.; + e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); + e2=buildArcOfCircle(center2,radius2,M_PI/2.,3*M_PI/2.); + commonNode.clear(); + QuadraticPolygon pol9; QuadraticPolygon pol10; + QuadraticPolygon pol11; QuadraticPolygon pol12; + pol11.pushBack(e1); pol12.pushBack(e2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol11.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol12.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol11.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol12.getArea(),1e-6); + CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol9,pol10)); + CPPUNIT_ASSERT_EQUAL(3,pol9.size()); + CPPUNIT_ASSERT_EQUAL(3,pol10.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol9.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol10.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol9.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol10.getArea(),1e-6); + // + center2[0]=0.; center2[1]=0.; radius2=radius1; + e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); + e2=buildArcOfCircle(center2,radius2,M_PI/3.,2*M_PI/3.); + commonNode.clear(); + QuadraticPolygon pol13; QuadraticPolygon pol14; + QuadraticPolygon pol15; QuadraticPolygon pol16; + pol15.pushBack(e1); pol16.pushBack(e2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol15.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol16.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol15.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.6095032974147,pol16.getArea(),1e-6); + CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol13,pol14)); + CPPUNIT_ASSERT_EQUAL(3,pol13.size()); + CPPUNIT_ASSERT_EQUAL(1,pol14.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol13.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol13.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol14.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.6095032974147,pol14.getArea(),1e-6); + // + e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); + e2=buildArcOfCircle(center2,radius2,2*M_PI/3.,M_PI/3.); + commonNode.clear(); + QuadraticPolygon pol17; QuadraticPolygon pol18; + QuadraticPolygon pol19; QuadraticPolygon pol20; + pol19.pushBack(e1); pol20.pushBack(e2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol19.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol20.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol19.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-8.6095032974147,pol20.getArea(),1e-6); + CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol17,pol18)); + CPPUNIT_ASSERT_EQUAL(3,pol17.size()); + CPPUNIT_ASSERT_EQUAL(1,pol18.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol17.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol17.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol18.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-8.6095032974147,pol18.getArea(),1e-6); + //no intersection #1 + center2[0]=4.277; center2[1]=-4.277; + e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); + e2=buildArcOfCircle(center2,radius2,M_PI/4.,5*M_PI/4.); + QuadraticPolygon polTemp1; QuadraticPolygon polTemp2; + CPPUNIT_ASSERT(!e1->intersectWith(e2,commonNode,polTemp1,polTemp2)); + e1->decrRef(); e2->decrRef(); + //no intersection #2 + center2[0]=1.; center2[1]=-1.; radius2=0.2; + e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); + e2=buildArcOfCircle(center2,radius2,M_PI/4.,5*M_PI/4.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,commonNode,polTemp1,polTemp2)); + e1->decrRef(); e2->decrRef(); +} + +void QuadraticPlanarInterpTest::IntersectArcCircleSegumentBase() +{ + double center[2]={2.,2.}; + EdgeArcCircle *e1=buildArcOfCircle(center,2.3,M_PI/4.,5.*M_PI/4.); + EdgeLin *e2=new EdgeLin(-1.3,1.,3.,5.3); + EdgeIntersector *intersector=new ArcCSegIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + vector v4; + MergePoints v3; + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[0])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.3,(*v4[0])[1],1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.3,(*v4[1])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[1])[1],1e-10); + v4[0]->decrRef(); v4[1]->decrRef(); e2->decrRef(); v3.clear(); v4.clear(); delete intersector; + // + e2=new EdgeLin(3.,5.3,-1.3,1.); + intersector=new ArcCSegIntersector(*e1,*e2); + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[0])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.3,(*v4[0])[1],1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.3,(*v4[1])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[1])[1],1e-10); + v4[0]->decrRef(); v4[1]->decrRef(); e2->decrRef(); v3.clear(); v4.clear(); delete intersector; + // tangent intersection + e2=new EdgeLin(-1.,4.3,3.,4.3); + intersector=new ArcCSegIntersector(*e1,*e2); + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(1,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[0])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.3,(*v4[0])[1],1e-10); + v4[0]->decrRef(); e2->decrRef(); v3.clear(); delete intersector; + // no intersection + e2=new EdgeLin(-2.,-2.,-1.,-3.); + intersector=new ArcCSegIntersector(*e1,*e2); + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); CPPUNIT_ASSERT(obvious && !areOverlapped); + e2->decrRef(); v3.clear(); delete intersector; + // + e1->decrRef(); +} + +QuadraticPolygon *QuadraticPlanarInterpTest::buildQuadraticPolygonCoarseInfo(const double *coords, const int *conn, int lgth) +{ + vector nodes; + for(int i=0;i +#include +#include + +using namespace std; +using namespace INTERP_KERNEL; + + +void QuadraticPlanarInterpTest::checkInOutDetection() +{ + Node *n1=new Node(0.,0.); + Node *n2=new Node(1.,0.); + Node *n3=new Node(0.5,1.); + EdgeLin *e1=new EdgeLin(n1,n2); + EdgeLin *e2=new EdgeLin(n2,n3); + EdgeLin *e3=new EdgeLin(n3,n1); + ComposedEdge *tri=new ComposedEdge; + tri->pushBack(e1); tri->pushBack(e2); tri->pushBack(e3); + // + Node *where=new Node(0.4,0.1); + CPPUNIT_ASSERT(tri->isInOrOut(where)); where->decrRef(); + where=new Node(-0.1,1.); + CPPUNIT_ASSERT(!tri->isInOrOut(where)); where->decrRef(); + where=new Node(0.6,-0.1); + CPPUNIT_ASSERT(!tri->isInOrOut(where)); where->decrRef(); + //Clean-up + n1->decrRef(); n2->decrRef(); n3->decrRef(); + ComposedEdge::Delete(tri); +} + +/*! + * Check Iterators mechanism. + */ +void QuadraticPlanarInterpTest::checkAssemblingBases1() +{ + Node *n1=new Node(0.,0.); + Node *n2=new Node(0.1,0.); EdgeLin *e1_2=new EdgeLin(n1,n2); + Node *n3=new Node(0.2,0.); EdgeLin *e2_3=new EdgeLin(n2,n3); + Node *n4=new Node(0.3,0.); EdgeLin *e3_4=new EdgeLin(n3,n4); + Node *n5=new Node(0.4,0.); EdgeLin *e4_5=new EdgeLin(n4,n5); + Node *n6=new Node(0.5,0.); EdgeLin *e5_6=new EdgeLin(n5,n6); + Node *n7=new Node(0.6,0.); EdgeLin *e6_7=new EdgeLin(n6,n7); + Node *n8=new Node(0.7,0.); EdgeLin *e7_8=new EdgeLin(n7,n8); + Node *n9=new Node(0.8,0.); EdgeLin *e8_9=new EdgeLin(n8,n9); + Node *n10=new Node(0.9,0.); EdgeLin *e9_10=new EdgeLin(n9,n10); + Node *n11=new Node(1.,0.); EdgeLin *e10_11=new EdgeLin(n10,n11); + Node *n12=new Node(0.5,1.); EdgeLin *e11_12=new EdgeLin(n11,n12); + EdgeLin *e12_1=new EdgeLin(n12,n1); + //Only one level + e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_7->incrRef(); + e7_8->incrRef(); e8_9->incrRef(); e9_10->incrRef(); e10_11->incrRef(); e11_12->incrRef(); e12_1->incrRef(); + ComposedEdge *c=new ComposedEdge; + c->pushBack(e1_2); c->pushBack(e2_3); c->pushBack(e3_4); c->pushBack(e4_5); c->pushBack(e5_6); c->pushBack(e6_7); + c->pushBack(e7_8); c->pushBack(e8_9); c->pushBack(e9_10); c->pushBack(e10_11); c->pushBack(e11_12); c->pushBack(e12_1); + CPPUNIT_ASSERT_EQUAL(12,c->recursiveSize()); + IteratorOnComposedEdge it(c); + CPPUNIT_ASSERT(it.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it.finished()); + it.next(); CPPUNIT_ASSERT(it.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it.finished()); + it.next(); it.next(); CPPUNIT_ASSERT(it.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it.finished()); + it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it.finished()); + it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it.finished()); + it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it.finished()); + it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it.finished()); + it.next(); CPPUNIT_ASSERT(it.finished()); + it.first(); CPPUNIT_ASSERT(it.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it.finished()); + it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it.finished()); + it.nextLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it.finished()); + it.last(); CPPUNIT_ASSERT(it.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it.finished()); + //Multi-Level + ComposedEdge::Delete(c); + //(e1_2, (e2_3,(e3_4, e4_5, e5_6, e6_7, (e7_8, e8_9 ), ( e9_10 , e10_11 ), e11_12 ),e12_1 ) ) + e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_7->incrRef(); + e7_8->incrRef(); e8_9->incrRef(); e9_10->incrRef(); e10_11->incrRef(); e11_12->incrRef(); e12_1->incrRef(); + ComposedEdge *c2_2_4=new ComposedEdge; c2_2_4->pushBack(e7_8); c2_2_4->pushBack(e8_9); + ComposedEdge *c2_2_5=new ComposedEdge; c2_2_5->pushBack(e9_10); c2_2_5->pushBack(e10_11); + ComposedEdge *c2_2=new ComposedEdge; c2_2->pushBack(e3_4); c2_2->pushBack(e4_5); c2_2->pushBack(e5_6); c2_2->pushBack(e6_7); c2_2->pushBack(c2_2_4); c2_2->pushBack(c2_2_5); c2_2->pushBack(e11_12); + ComposedEdge *c2=new ComposedEdge; c2->pushBack(e2_3); c2->pushBack(c2_2); c2->pushBack(e12_1); + c=new ComposedEdge; c->pushBack(e1_2); c->pushBack(c2); CPPUNIT_ASSERT_EQUAL(12,c->recursiveSize()); + IteratorOnComposedEdge it2(c); + CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); + it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); + it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); + it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); + it2.next(); CPPUNIT_ASSERT(it2.finished()); + it2.first(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); + it2.last(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); + it2.first(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it2.finished()); + // substitutions. + /*it2.first(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); + ElementaryEdge *&tmp=it2.current(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); + ComposedEdge *c1=new ComposedEdge; Node *n1_bis=new Node(0.,0.05); EdgeLin *e1_1bis=new EdgeLin(n1,n1_bis); EdgeLin *e1bis_2=new EdgeLin(n1_bis,n2); e1_1bis->incrRef(); e1bis_2->incrRef(); + c1->pushBack(e1_1bis); c1->pushBack(e1bis_2); delete tmp; tmp=(ElementaryEdge *)c1; CPPUNIT_ASSERT_EQUAL(13,c->recursiveSize()); + CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished());// here testing capability of Iterator.'current' method to deal with change of hierarchy. + it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1bis_2); CPPUNIT_ASSERT(!it2.finished()); + it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1bis_2); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e11_12); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e10_11); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e9_10); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e8_9); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e7_8); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e6_7); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e5_6); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1bis_2); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); + //go forward + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1bis_2); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e5_6); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e6_7); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e7_8); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e8_9); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e9_10); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e10_11); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e11_12); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished());*/ + ComposedEdge::SoftDelete(c2_2_4); + ComposedEdge::SoftDelete(c2_2_5); + ComposedEdge::SoftDelete(c2_2); + ComposedEdge::SoftDelete(c2); + ComposedEdge::Delete(c); + //clean-up + //e1_1bis->decrRef(); e1bis_2->decrRef(); + e1_2->decrRef(); e2_3->decrRef(); e3_4->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_7->decrRef(); + e7_8->decrRef(); e8_9->decrRef(); e9_10->decrRef(); e10_11->decrRef(); e11_12->decrRef(); e12_1->decrRef(); + //n1_bis->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + n7->decrRef(); n8->decrRef(); n9->decrRef(); n10->decrRef(); n11->decrRef(); n12->decrRef(); +} + +/*! + * Check splitting of 2 polygons. After this operation, all ElementaryEdge are either in/out/on. + */ +void QuadraticPlanarInterpTest::checkAssemblingBases2() +{ + //The "most" basic test1 + Node *n1=new Node(0.,0.); Node *n4=new Node(0.,-0.3); + Node *n2=new Node(1.,0.); Node *n5=new Node(1.,-0.3); + Node *n3=new Node(0.5,1.); Node *n6=new Node(0.5,0.7); + EdgeLin *e1_2=new EdgeLin(n1,n2); EdgeLin *e4_5=new EdgeLin(n4,n5); + EdgeLin *e2_3=new EdgeLin(n2,n3); EdgeLin *e5_6=new EdgeLin(n5,n6); + EdgeLin *e3_1=new EdgeLin(n3,n1); EdgeLin *e6_4=new EdgeLin(n6,n4); + // + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); + QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); + QuadraticPolygon pol2; pol2.pushBack(e4_5); pol2.pushBack(e5_6); pol2.pushBack(e6_4); + QuadraticPolygon cpyPol1(pol1); int nbOfSplits=0; + cpyPol1.splitPolygonsEachOther(pol1,pol2,nbOfSplits); + CPPUNIT_ASSERT_EQUAL(5,pol1.recursiveSize()); + CPPUNIT_ASSERT_EQUAL(5,pol2.recursiveSize());CPPUNIT_ASSERT_EQUAL(15,nbOfSplits); + checkBasicsOfPolygons(pol1,pol2,true); + CPPUNIT_ASSERT(pol2[1]->getEndNode()==pol1[1]->getEndNode()); + CPPUNIT_ASSERT(pol2[1]->getEndNode()->getLoc()==ON_1); + CPPUNIT_ASSERT(pol2[3]->getEndNode()==pol1[0]->getEndNode()); + CPPUNIT_ASSERT(pol2[3]->getEndNode()->getLoc()==ON_1); + cpyPol1.performLocatingOperation(pol2); + ElementaryEdge *tmp=dynamic_cast(pol2[0]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e4_5); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + tmp=dynamic_cast(pol2[1]); CPPUNIT_ASSERT(tmp); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + tmp=dynamic_cast(pol2[2]); CPPUNIT_ASSERT(tmp); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_IN_1); + tmp=dynamic_cast(pol2[3]); CPPUNIT_ASSERT(tmp); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_IN_1); + tmp=dynamic_cast(pol2[4]); CPPUNIT_ASSERT(tmp); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + //clean-up for test1 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + + //Deeper test some extremities of pol2 are on edges of pol1. + + n1=new Node(0.,0.); n4=new Node(1.5,-0.5); + n2=new Node(1.,0.); n5=new Node(0.5,0.); + n3=new Node(0.5,1.); n6=new Node(0.75,0.5); Node *n7=new Node(2.,0.5); + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); + EdgeLin *e5_4=new EdgeLin(n5,n4); EdgeLin *e4_7=new EdgeLin(n4,n7); EdgeLin *e7_6=new EdgeLin(n7,n6); EdgeLin *e6_5=new EdgeLin(n6,n5); + // + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e5_4->incrRef(); e4_7->incrRef(); e7_6->incrRef(); e6_5->incrRef(); + QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_1); + QuadraticPolygon pol4; pol4.pushBack(e5_4); pol4.pushBack(e4_7); pol4.pushBack(e7_6); pol4.pushBack(e6_5); + QuadraticPolygon cpyPol3(pol3); nbOfSplits=0; + cpyPol3.splitPolygonsEachOther(pol3,pol4,nbOfSplits); + CPPUNIT_ASSERT_EQUAL(5,pol3.recursiveSize()); + CPPUNIT_ASSERT_EQUAL(4,pol4.recursiveSize());CPPUNIT_ASSERT_EQUAL(16,nbOfSplits); + checkBasicsOfPolygons(pol3,pol4,true); + CPPUNIT_ASSERT(pol4[0]->getStartNode()==pol3[0]->getEndNode()); CPPUNIT_ASSERT(pol4[0]->getStartNode()==n5); + CPPUNIT_ASSERT(n5->getLoc()==ON_LIM_1); + CPPUNIT_ASSERT(pol4[2]->getEndNode()==pol3[2]->getEndNode()); CPPUNIT_ASSERT(pol4[2]->getEndNode()==n6); + CPPUNIT_ASSERT(n6->getLoc()==ON_LIM_1); + cpyPol3.performLocatingOperation(pol4); + tmp=dynamic_cast(pol4[1]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e4_7); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + tmp=dynamic_cast(pol4[3]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e6_5); + tmp=dynamic_cast(pol4[0]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e5_4); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + tmp=dynamic_cast(pol4[2]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e7_6); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + tmp=dynamic_cast(pol4[3]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e6_5); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_IN_1); + //clean-up for test2 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e5_4->decrRef(); e4_7->decrRef(); e7_6->decrRef(); e6_5->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); n7->decrRef(); + + //Test with one edge of pol2 is included in pol1. + + n1=new Node(0.,0.); n4=new Node(-0.5,0.); + n2=new Node(1.,0.); n5=new Node(0.,-1.); + n3=new Node(0.5,1.); n6=new Node(0.5,0.); + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); + e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); + QuadraticPolygon pol5; pol5.pushBack(e1_2); pol5.pushBack(e2_3); pol5.pushBack(e3_1); + QuadraticPolygon pol6; pol6.pushBack(e4_5); pol6.pushBack(e5_6); pol6.pushBack(e6_4); + QuadraticPolygon cpyPol5(pol5); nbOfSplits=0; + cpyPol5.splitPolygonsEachOther(pol5,pol6,nbOfSplits); + CPPUNIT_ASSERT_EQUAL(4,pol5.recursiveSize()); + CPPUNIT_ASSERT_EQUAL(4,pol6.recursiveSize()); CPPUNIT_ASSERT_EQUAL(13,nbOfSplits); + checkBasicsOfPolygons(pol5,pol6,false); + CPPUNIT_ASSERT(pol6[2]->getStartNode()==pol5[0]->getEndNode()); CPPUNIT_ASSERT(pol6[2]->getStartNode()==n6); + CPPUNIT_ASSERT(n6->getLoc()==ON_LIM_1); + CPPUNIT_ASSERT(pol6[2]->getEndNode()==pol5[0]->getStartNode()); CPPUNIT_ASSERT(pol5[0]->getStartNode()==n1); + CPPUNIT_ASSERT(n1->getLoc()==ON_LIM_1); + cpyPol5.performLocatingOperation(pol6); + tmp=dynamic_cast(pol6[0]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e4_5); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + tmp=dynamic_cast(pol6[1]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e5_6); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + tmp=dynamic_cast(pol6[2]); CPPUNIT_ASSERT(tmp); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_ON_1); + tmp=dynamic_cast(pol6[3]); CPPUNIT_ASSERT(tmp); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + //clean-up test3 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + + //Test of full overlapped polygons. + + n1=new Node(0.,0.); n4=new Node(0.,0.); + n2=new Node(1.,0.); n5=new Node(1.,0.); + n3=new Node(0.5,1.); n6=new Node(0.5,1.); + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); + e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); + QuadraticPolygon pol7; pol7.pushBack(e1_2); pol7.pushBack(e2_3); pol7.pushBack(e3_1); + QuadraticPolygon pol8; pol8.pushBack(e4_5); pol8.pushBack(e5_6); pol8.pushBack(e6_4); + QuadraticPolygon cpyPol7(pol7); nbOfSplits=0; + cpyPol7.splitPolygonsEachOther(pol7,pol8,nbOfSplits); + tmp=dynamic_cast(pol8[0]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e1_2); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_ON_1); + tmp=dynamic_cast(pol8[1]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e2_3); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_ON_1); + tmp=dynamic_cast(pol8[2]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e3_1); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_ON_1); + //clean-up test4 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); +} + +void QuadraticPlanarInterpTest::checkBasicsOfPolygons(QuadraticPolygon& pol1, QuadraticPolygon& pol2, bool checkDirection) +{ + IteratorOnComposedEdge it1(&pol1),it2(&pol2); it1.previousLoop(); it2.previousLoop(); + Node *nIter1=it1.current()->getEndNode(); Node *nIter2=it2.current()->getEndNode(); + for(it2.first();!it2.finished();it2.next()) + { + CPPUNIT_ASSERT(nIter2==it2.current()->getStartNode()); + if(checkDirection) + CPPUNIT_ASSERT(it2.current()->getDirection()); + nIter2=it2.current()->getEndNode(); + } + for(it1.first();!it1.finished();it1.next()) + { + CPPUNIT_ASSERT(nIter1==it1.current()->getStartNode()); + if(checkDirection) + CPPUNIT_ASSERT(it1.current()->getDirection()); + nIter1=it1.current()->getEndNode(); + } +} diff --git a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest4.cxx b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest4.cxx new file mode 100644 index 000000000..cffd067b6 --- /dev/null +++ b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest4.cxx @@ -0,0 +1,1659 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "QuadraticPlanarInterpTest.hxx" +#include "QuadraticPolygon.hxx" +#include "ElementaryEdge.hxx" +#include "EdgeArcCircle.hxx" +#include "EdgeLin.hxx" + +#include +#include +#include +#include + +using namespace std; +using namespace INTERP_KERNEL; + +void QuadraticPlanarInterpTest::checkPolygonsIntersection1() +{ + //The "most" basic test1 + Node *n1=new Node(0.,0.); Node *n4=new Node(0.,-0.3); + Node *n2=new Node(1.,0.); Node *n5=new Node(1.,-0.3); + Node *n3=new Node(0.5,1.); Node *n6=new Node(0.5,0.7); + EdgeLin *e1_2=new EdgeLin(n1,n2); EdgeLin *e4_5=new EdgeLin(n4,n5); + EdgeLin *e2_3=new EdgeLin(n2,n3); EdgeLin *e5_6=new EdgeLin(n5,n6); + EdgeLin *e3_1=new EdgeLin(n3,n1); EdgeLin *e6_4=new EdgeLin(n6,n4); + // + vector result; + for(int k=0;k<2;k++) + for(int i=0;i<3;i++) + { + for(int j=0;j<1;j++) + { + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); + QuadraticPolygon pol1; pol1.circularPermute(); pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); + for(int i1=0;i1recursiveSize()); + double tmp1=0.,tmp2=0.,tmp3=0.; + pol1.intersectForPerimeter(pol2,tmp1,tmp2,tmp3); + vector v1,v2; + vector v3; + pol1.intersectForPerimeterAdvanced(pol2,v1,v2);//no common edge + pol1.intersectForPoint(pol2,v3); + CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v3.size()); + if(k==0) + { + CPPUNIT_ASSERT_EQUAL(2,v3[(3-i)%3]); + CPPUNIT_ASSERT_EQUAL(0,v3[(4-i)%3]); + CPPUNIT_ASSERT_EQUAL(0,v3[(5-i)%3]); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.7,v1[(3-i)%3],1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,v1[(4-i)%3],1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,v1[(5-i)%3],1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,v2[0],1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.78262379212492639,v2[1],1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.78262379212492639,v2[2],1.e-14); + } + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.7,tmp1,1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5652475842498528,tmp2,1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,tmp3,1.e-14);//no common edge + delete result[0]; + } + } + //clean-up for test1 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + + //Deeper test some extremities of pol2 are on edges of pol1. + + n1=new Node(0.,0.); n4=new Node(1.5,-0.5); + n2=new Node(1.,0.); n5=new Node(0.5,0.); + n3=new Node(0.5,1.); n6=new Node(0.75,0.5); Node *n7=new Node(2.,0.5); + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); + EdgeLin *e5_4=new EdgeLin(n5,n4); EdgeLin *e4_7=new EdgeLin(n4,n7); EdgeLin *e7_6=new EdgeLin(n7,n6); EdgeLin *e6_5=new EdgeLin(n6,n5); + // + for(int k=0;k<2;k++) + for(int i=0;i<3;i++) + { + for(int j=0;j<4;j++) + { + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e5_4->incrRef(); e4_7->incrRef(); e7_6->incrRef(); e6_5->incrRef(); + QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_1); + for(int i1=0;i1recursiveSize()); + delete result[0]; + } + } + //clean-up for test2 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e5_4->decrRef(); e4_7->decrRef(); e7_6->decrRef(); e6_5->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); n7->decrRef(); + + //Test with one edge of pol2 is included in pol1. + + n1=new Node(0.,0.); n4=new Node(-0.5,0.); + n2=new Node(1.,0.); n5=new Node(0.,-1.); + n3=new Node(0.5,1.); n6=new Node(0.5,0.); + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); + e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); + for(int k=0;k<2;k++) + for(int i=0;i<3;i++) + { + for(int j=0;j<3;j++) + { + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); + QuadraticPolygon pol5; pol5.pushBack(e1_2); pol5.pushBack(e2_3); pol5.pushBack(e3_1); + for(int i1=0;i1decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + + //Test of full overlapped polygons. + + n1=new Node(0.,0.); n4=new Node(0.,0.); + n2=new Node(1.,0.); n5=new Node(1.,0.); + n3=new Node(0.5,1.); n6=new Node(0.5,1.); + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); + e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); + for(int k=0;k<2;k++) + for(int i=0;i<3;i++) + { + for(int j=0;j<3;j++) + { + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); + QuadraticPolygon pol7; pol7.pushBack(e1_2); pol7.pushBack(e2_3); pol7.pushBack(e3_1); + for(int i1=0;i1recursiveSize()); + delete result[0]; + double tmp1=0.,tmp2=0.,tmp3=0.; + pol7.intersectForPerimeter(pol8,tmp1,tmp2,tmp3); + vector v1,v2; + pol7.intersectForPerimeterAdvanced(pol8,v1,v2);//only common edges. + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,v1[0]+v1[1]+v1[2],1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,v2[0]+v2[1]+v2[2],1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,tmp1,1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,tmp2,1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,tmp3,1.e-14); + } + } + //clean-up test4 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + + //Test of closing process + + n1=new Node(0.,0.); n4=new Node(0.539,-0.266); + n2=new Node(1.,0.); n5=new Node(1.039,0.6); + n3=new Node(0.5,1.); n6=new Node(-0.077,0.667); + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); + e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); + for(int k=0;k<2;k++) + for(int i=0;i<3;i++) + { + for(int j=0;j<3;j++) + { + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); + QuadraticPolygon pol9; pol9.pushBack(e1_2); pol9.pushBack(e2_3); pol9.pushBack(e3_1); + for(int i1=0;i1recursiveSize()); + delete result[0]; + } + } + //clean-up test5 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + + // Full in case + + n1=new Node(0.,0.); n4=new Node(0.3,0.1); + n2=new Node(1.,0.); n5=new Node(0.7,0.1); + n3=new Node(0.5,1.); n6=new Node(0.5,0.7); + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); + e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); + for(int k=0;k<2;k++) + for(int i=0;i<3;i++) + { + for(int j=0;j<3;j++) + { + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); + QuadraticPolygon pol11; pol11.pushBack(e1_2); pol11.pushBack(e2_3); pol11.pushBack(e3_1); + for(int i1=0;i1recursiveSize()); + delete result[0]; + } + } + //clean-up test6 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + + // Full out case + + n1=new Node(0.,0.); n4=new Node(-2,0.); + n2=new Node(1.,0.); n5=new Node(-1.,0.); + n3=new Node(0.5,1.); n6=new Node(-1.5,1.); + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); + e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); + for(int k=0;k<2;k++) + for(int i=0;i<3;i++) + { + for(int j=0;j<3;j++) + { + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); + QuadraticPolygon pol13; pol13.pushBack(e1_2); pol13.pushBack(e2_3); pol13.pushBack(e3_1); + for(int i1=0;i1decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + + //Multi polygons + + n1=new Node(0.,0.); + n2=new Node(1.,0.); + n3=new Node(1.,1.); + n4=new Node(0.,1.); + // + n5=new Node(0.2,0.7); + n6=new Node(0.4,0.7); + n7=new Node(0.4,1.3); + Node *n8=new Node(0.6,1.3); + Node *n9=new Node(0.6,0.7); + Node *n10=new Node(0.9,0.7); + Node *n11=new Node(0.9,2.); + Node *n12=new Node(0.2,2.); + // + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); Edge *e3_4=new EdgeLin(n3,n4); Edge *e4_1=new EdgeLin(n4,n1); + e5_6=new EdgeLin(n5,n6); Edge *e6_7=new EdgeLin(n6,n7); Edge *e7_8=new EdgeLin(n7,n8); Edge *e8_9=new EdgeLin(n8,n9); Edge *e9_10=new EdgeLin(n9,n10); Edge *e10_11=new EdgeLin(n10,n11); + Edge *e11_12=new EdgeLin(n11,n12); Edge *e12_1=new EdgeLin(n12,n5); + // + for(int k=0;k<2;k++) + for(int i=0;i<4;i++) + { + for(int j=0;j<8;j++) + { + e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_1->incrRef(); e5_6->incrRef(); e6_7->incrRef(); e7_8->incrRef(); e8_9->incrRef(); e9_10->incrRef(); e10_11->incrRef(); e11_12->incrRef(); e12_1->incrRef(); + QuadraticPolygon pol15; pol15.pushBack(e1_2); pol15.pushBack(e2_3); pol15.pushBack(e3_4); pol15.pushBack(e4_1); + for(int i1=0;i1recursiveSize()); CPPUNIT_ASSERT_EQUAL(4,result[1]->recursiveSize()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.15,result[0]->getArea()+result[1]->getArea(),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.03,fabs(result[0]->getArea()-result[1]->getArea()),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.15,pol15.intersectWith(pol16),1e-10); + delete result[0]; delete result[1]; + } + } + //clean-up test8 + e1_2->decrRef(); e2_3->decrRef(); e3_4->decrRef(); e4_1->decrRef(); e5_6->decrRef(); e6_7->decrRef(); e7_8->decrRef(); e8_9->decrRef(); e9_10->decrRef(); e10_11->decrRef(); e11_12->decrRef(); e12_1->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); n7->decrRef(); n8->decrRef(); n9->decrRef(); n10->decrRef(); n11->decrRef(); n12->decrRef(); +} + +/*! + * Testing case where a polygon pol1 is included in an onother polygon pol2. + */ +void QuadraticPlanarInterpTest::checkPolygonsIntersection2() +{ + Node *n1=new Node(0.,0.); Node *n4=new Node(0.2,0.2); + Node *n2=new Node(1.,0.); Node *n5=new Node(0.8,0.2); + Node *n3=new Node(0.5,1.); Node *n6=new Node(0.5,0.8); + Edge *e1_2=new EdgeLin(n1,n2); Edge *e4_5=new EdgeLin(n4,n5); + Edge *e2_3=new EdgeLin(n2,n3); Edge *e5_6=new EdgeLin(n5,n6); + Edge *e3_1=new EdgeLin(n3,n1); Edge *e6_4=new EdgeLin(n6,n4); + // + QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); + QuadraticPolygon pol2; pol2.pushBack(e4_5); pol2.pushBack(e5_6); pol2.pushBack(e6_4); + vector result=pol1.intersectMySelfWith(pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)result.size()); + CPPUNIT_ASSERT_EQUAL(3,result[0]->recursiveSize()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.18,result[0]->getArea(),1e-10); + delete result[0]; + result.clear(); + pol1.initLocations(); + pol2.initLocations(); + result=pol2.intersectMySelfWith(pol1); + CPPUNIT_ASSERT_EQUAL(1,(int)result.size()); + CPPUNIT_ASSERT_EQUAL(3,result[0]->recursiveSize()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.18,result[0]->getArea(),1e-10); + delete result[0]; + //clean-up + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); +} + +void QuadraticPlanarInterpTest::checkAreasCalculations() +{ + Node *n1=new Node(0.,0.); + Node *n2=new Node(1.,0.); + Node *n3=new Node(0.5,1.); + Edge *e1_2=new EdgeLin(n1,n2); + Edge *e2_3=new EdgeLin(n2,n3); + Edge *e3_1=new EdgeLin(n3,n1); + // + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); + QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,pol1.getArea(),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,pol1.getPerimeter(),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.61803398874989479,pol1.getHydraulicDiameter(),1e-10); + pol1.reverse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.5,pol1.getArea(),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,pol1.getPerimeter(),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.61803398874989479,pol1.getHydraulicDiameter(),1e-10); + //clean-up + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); + + //case 2 + + n1=new Node(0.,0.); + n2=new Node(1.,0.); + Node *n3m=new Node(1.5,0.5); + n3=new Node(1.,1.); + Node *n4=new Node(0.,1.); + e1_2=new EdgeLin(n1,n2); + e2_3=new EdgeArcCircle(n2,n3m,n3); + Edge *e3_4=new EdgeLin(n3,n4); + Edge *e4_1=new EdgeLin(n4,n1); + // + for(int k=0;k<8;k++) + { + n2->setNewCoords(cos(k*M_PI/4),sin(k*M_PI/4)); + n3->setNewCoords(sqrt(2.)*cos((k+1)*M_PI/4),sqrt(2.)*sin((k+1)*M_PI/4)); + n3m->setNewCoords(1.5811388300841898*cos(0.3217505543966423+k*M_PI/4),1.5811388300841898*sin(0.3217505543966423+k*M_PI/4)); + n4->setNewCoords(cos(k*M_PI/4+M_PI/2),sin(k*M_PI/4+M_PI/2)); + e1_2->update(n3m); e2_3->update(n3m); e3_4->update(n3m); e4_1->update(n3m); + e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_1->incrRef(); + QuadraticPolygon pol2; pol2.pushBack(e1_2); pol2.pushBack(e2_3); pol2.pushBack(e3_4); pol2.pushBack(e4_1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.3926990816987241,pol2.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5707963267948966,pol2.getPerimeter(),1e-6); + pol2.reverse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.3926990816987241,pol2.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5707963267948966,pol2.getPerimeter(),1e-6); + } + //clean-up case2 + e1_2->decrRef(); e2_3->decrRef(); e3_4->decrRef(); e4_1->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n3m->decrRef(); n4->decrRef(); + + //case 3 + + const double radius1=0.7; + const double radius2=0.9; + n1=new Node(1.+radius1*cos(-2.*M_PI/3.),1.+radius1*sin(-2.*M_PI/3.)); + n2=new Node(1.+radius1*cos(-M_PI/3.),1.+radius1*sin(-M_PI/3.)); + Node *n2m=new Node(1.+radius1*cos(M_PI/2.),1.+radius1*sin(M_PI/2.)); + n3=new Node(1.+radius2*cos(-M_PI/3.),1.+radius2*sin(-M_PI/3.)); + n3m=new Node(1.+radius2*cos(M_PI/2.),1.+radius2*sin(M_PI/2.)); + n4=new Node(1.+radius2*cos(-2.*M_PI/3.),1.+radius2*sin(-2.*M_PI/3.)); + e1_2=new EdgeArcCircle(n1,n2m,n2); + e2_3=new EdgeLin(n2,n3); + e3_4=new EdgeArcCircle(n3,n3m,n4); + e4_1=new EdgeLin(n4,n1); + // + e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_1->incrRef(); + QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_4); pol3.pushBack(e4_1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.83775804095727857,pol3.getArea(),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.7775804095727832,pol3.getPerimeter(),1e-10); + pol3.reverse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.83775804095727857,pol3.getArea(),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.7775804095727832,pol3.getPerimeter(),1e-10); + //clean-up case3 + e1_2->decrRef(); e2_3->decrRef(); e3_4->decrRef(); e4_1->decrRef(); + n1->decrRef(); n2->decrRef(); n2m->decrRef(); n3->decrRef(); n3m->decrRef(); n4->decrRef(); +} + +void QuadraticPlanarInterpTest::checkBarycenterCalculations() +{ + Node *n1=new Node(3.,7.); + Node *n2=new Node(5.,7.); + Node *n3=new Node(4.,8.); + Edge *e1_2=new EdgeLin(n1,n2); + Edge *e2_3=new EdgeLin(n2,n3); + Edge *e3_1=new EdgeLin(n3,n1); + // + double bary[2]; + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); + QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); + bary[0]=0.; bary[1]=0.; + e1_2->getBarycenterOfZone(bary); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-56.,bary[0],1.e-10); + bary[0]=0.; bary[1]=0.; + e2_3->getBarycenterOfZone(bary); + CPPUNIT_ASSERT_DOUBLES_EQUAL(33.66666666666667,bary[0],1.e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(28.16666666666667,bary[1],1.e-10); + bary[0]=0.; bary[1]=0.; + e3_1->getBarycenterOfZone(bary); + CPPUNIT_ASSERT_DOUBLES_EQUAL(26.333333333333336,bary[0],1.e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(28.1666666666667,bary[1],1.e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,pol1.getArea(),1e-10); + pol1.getBarycenter(bary); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.,bary[0],1.e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.333333333333333,bary[1],1.e-10); + // + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); + QuadraticPolygon pol4; pol4.pushBack(e3_1,false); pol4.pushBack(e2_3,false); pol4.pushBack(e1_2,false); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.,pol4.getArea(),1e-10); + pol4.getBarycenter(bary); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.,bary[0],1.e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.333333333333333,bary[1],1.e-10); + //clean-up + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); + //Inverting polygon + n1=new Node(3.,7.); + n2=new Node(5.,7.); + n3=new Node(4.,8.); + e1_2=new EdgeLin(n1,n3); + e2_3=new EdgeLin(n3,n2); + e3_1=new EdgeLin(n2,n1); + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); + QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_1); + bary[0]=0.; bary[1]=0.; + pol3.getBarycenter(bary); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.,pol3.getArea(),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.,bary[0],1.e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.333333333333333,bary[1],1.e-10); + //clean-up + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); + // + double center[2]={3.,7.}; + e1_2=buildArcOfCircle(center,4.,M_PI/3.,4.*M_PI/3.); + bary[0]=0.; bary[1]=0.; + e1_2->getBarycenterOfZone(bary); + CPPUNIT_ASSERT_DOUBLES_EQUAL(131.685410765053,bary[0],1.e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(303.262521934362,bary[1],1.e-10); + n1=new Node(0.99999999999999822,3.5358983848622465); + n2=new Node(5.,10.4641016151377544); + Edge *e2_1=new EdgeLin(n1,n2); + // + e1_2->incrRef(); e2_1->incrRef(); + QuadraticPolygon pol2; pol2.pushBack(e1_2); pol2.pushBack(e2_1); + pol2.getBarycenter(bary); + CPPUNIT_ASSERT_DOUBLES_EQUAL(25.132741228718345,pol2.getArea(),1e-10); + //4*radius/(3.*pi) + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5297896122085546,bary[0],1.e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8488263631567756,bary[1],1.e-10); + //clean-up + e1_2->decrRef(); e2_1->decrRef(); + n1->decrRef(); n2->decrRef(); +} + +/*! + * Testing user interface high level function. + */ +void QuadraticPlanarInterpTest::checkHighLevelFunctionTest1() +{ + QUADRATIC_PLANAR::setPrecision(1e-12); + QUADRATIC_PLANAR::setArcDetectionPrecision(1e-9); + double coords[]={ + 8.8334591186000004, 5.0999999999999996, + 7.1014083111000001, 6.0999999999999996, + 7.8334591186000004, 6.8320508074999999, + 7.9674337149000003, 5.5999999999999996, + 7.4192455562999999, 6.5142135623000001, + 8.3334591186000004, 5.9660254036999998 + }; + vector nodes; + nodes.push_back(new Node(coords)); + nodes.push_back(new Node(coords+2)); + nodes.push_back(new Node(coords+4)); + nodes.push_back(new Node(coords+6)); + nodes.push_back(new Node(coords+8)); + nodes.push_back(new Node(coords+10)); + QuadraticPolygon *pol=QuadraticPolygon::buildArcCirclePolygon(nodes); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.04719755,pol->getArea(),1e-5); + CPPUNIT_ASSERT_EQUAL(3,pol->size()); + ElementaryEdge *e0=dynamic_cast((*pol)[0]); + ElementaryEdge *e1=dynamic_cast((*pol)[1]); + ElementaryEdge *e2=dynamic_cast((*pol)[0]); + CPPUNIT_ASSERT(e0); CPPUNIT_ASSERT(e1); CPPUNIT_ASSERT(e2); + CPPUNIT_ASSERT(dynamic_cast(e0->getPtr()));//<- testing detection of colinearity + CPPUNIT_ASSERT(dynamic_cast(e1->getPtr())); + CPPUNIT_ASSERT(dynamic_cast(e2->getPtr()));//<- testing detection of colinearity + nodes.clear(); + delete pol; + nodes.push_back(new Node(coords)); + nodes.push_back(new Node(coords+4)); + nodes.push_back(new Node(coords+2)); + nodes.push_back(new Node(coords+10)); + nodes.push_back(new Node(coords+8)); + nodes.push_back(new Node(coords+6)); + pol=QuadraticPolygon::buildArcCirclePolygon(nodes); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.04719755,pol->getArea(),1e-5); + CPPUNIT_ASSERT_EQUAL(3,pol->size()); + e0=dynamic_cast((*pol)[0]); + e1=dynamic_cast((*pol)[1]); + e2=dynamic_cast((*pol)[0]); + CPPUNIT_ASSERT(e0); CPPUNIT_ASSERT(e1); CPPUNIT_ASSERT(e2); + CPPUNIT_ASSERT(dynamic_cast(e0->getPtr()));//<- testing detection of colinearity + CPPUNIT_ASSERT(dynamic_cast(e1->getPtr())); + CPPUNIT_ASSERT(dynamic_cast(e2->getPtr()));//<- testing detection of colinearity + delete pol; + const double coords2[]={ + 0.,0., + 1.5,0., + 1.5,1., + 0.,1. + }; + nodes.clear(); + nodes.push_back(new Node(coords2)); + nodes.push_back(new Node(coords2+2)); + nodes.push_back(new Node(coords2+4)); + nodes.push_back(new Node(coords2+6)); + pol=QuadraticPolygon::buildLinearPolygon(nodes); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,pol->getArea(),1e-12); + double tmp[2],tmp2; + pol->getBarycenter(tmp,tmp2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.75,tmp[0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,tmp[1],1e-12); + delete pol; + const double coords3[]={ + 1.0999999999000001, -1.9052558882999999, + 1.9052558881999999, -1.0999999999000001, + 1.7320508075000001, -0.99999999989999999, + 0.99999999989999999, -1.7320508075000001, + 1.5556349186, -1.5556349185, + 1.8186533478, -1.0499999999, + 1.4142135623000001, -1.4142135623000001, + 1.0499999999, -1.8186533479 + }; + nodes.clear(); + nodes.push_back(new Node(coords3)); + nodes.push_back(new Node(coords3+2)); + nodes.push_back(new Node(coords3+4)); + nodes.push_back(new Node(coords3+6)); + nodes.push_back(new Node(coords3+8)); + nodes.push_back(new Node(coords3+10)); + nodes.push_back(new Node(coords3+12)); + nodes.push_back(new Node(coords3+14)); + pol=QuadraticPolygon::buildArcCirclePolygon(nodes); + pol->getBarycenter(tmp,tmp2); + delete pol; + QUADRATIC_PLANAR::setPrecision(1e-14); +} + +void QuadraticPlanarInterpTest::check1DInterpLin() +{ + QUADRATIC_PLANAR::setPrecision(1e-7); + QUADRATIC_PLANAR::setArcDetectionPrecision(1e-9); + const int NB_OF_CELL_AXIAL_1=30; + static const double Z_VALS_1[NB_OF_CELL_AXIAL_1+1]= + { -0.1550 , -0.1356, -0.1162, -0.0969, -0.0775 ,-0.0581, -0.0387, -0.0194, 0.0000 , 0.0500, + 0.1000 , 0.1500 , 0.2000 , 0.2500, 0.3000, 0.3500, 0.4000, 0.4500, 0.5000, 0.5500, + 0.6000, 0.6500, 0.7000, 0.7194, 0.7388, 0.7581, 0.7775, 0.7969, 0.8163, 0.8356, + 0.8550}; + vector zLev1(Z_VALS_1,Z_VALS_1+NB_OF_CELL_AXIAL_1+1); + + const int NB_OF_CELL_AXIAL_2=46; + static const double Z_VALS_2[NB_OF_CELL_AXIAL_2+1]= + { -0.3050 ,-0.2863,-0.2675,-0.2488,-0.2300,-0.2113,-0.1925,-0.1738,-0.1550,-0.1356 + , -0.1162,-0.0969,-0.0775,-0.0581,-0.0387,-0.0194,0.0000, 0.0500, 0.1 ,0.15 + , 0.20, 0.25, 0.30, 0.350 ,0.40 ,0.450 ,0.500 , 0.550, 0.600 ,0.650 ,0.700 + , 0.7194 ,0.7388 ,0.7581 ,0.7775 ,0.7969 ,0.8163 ,0.8356, 0.8550 + , 0.8738 ,0.8925 ,0.9113 ,0.9300 ,0.9488 ,0.9675 ,0.9863, 1.0050}; + vector zLev2(Z_VALS_2,Z_VALS_2+NB_OF_CELL_AXIAL_2+1); + map > m; + Edge::interpolate1DLin(zLev1,zLev2,m); + CPPUNIT_ASSERT_EQUAL(30,(int)m.size()); + double ret=0; + for(int i=0;i<30;i++) + { + CPPUNIT_ASSERT_EQUAL(1,(int)m[i].size()); + CPPUNIT_ASSERT(m[i][8+i] > 0.15); + ret+=m[i][8+i]; + } + CPPUNIT_ASSERT_DOUBLES_EQUAL(ret,30.,1e-12); + // + m.clear(); + const int NB_OF_CELL_AXIAL_3=13; + static const double Z_VALS_3[NB_OF_CELL_AXIAL_3+1]={ + 0.,0.01,0.05,0.10,0.15,0.20,0.25,0.30, + 0.35,0.40,0.45,0.50,0.55,0.60 }; + vector zLev3(Z_VALS_3,Z_VALS_3+NB_OF_CELL_AXIAL_3+1); + Edge::interpolate1DLin(zLev3,zLev1,m); + CPPUNIT_ASSERT_EQUAL(13,(int)m.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,m[0][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,m[1][8],1e-12); + for(int i=0;i<11;i++) + { + CPPUNIT_ASSERT_EQUAL(1,(int)m[i+2].size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,m[i+2][i+9],1e-12); + } + QUADRATIC_PLANAR::setPrecision(1e-14); +} + +/*! + * This test looks if intersectors are in coherency. + */ +void QuadraticPlanarInterpTest::checkEpsilonCoherency1() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-12); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); + + const double pol1[]={ + -2.1083388455000001, 1.2172499999999999, + -1.7320508075000001, 1, + -1.9201948265, 1.108625 + }; + + const double pol2[]={ + -2.2379999998, 0, + -1.9381648534, 1.1189999998, + -2.1617419990000002, 0.57923702298000002, + -1.9381648534, 1.1189999998, + -1.9909924031999999, 1.1494999999, + -1.9645786283, 1.1342499998 + }; + // + Node *n1=new Node(pol1[0],pol1[1]); + Node *n2=new Node(pol1[2],pol1[3]); + Node *n3; + // + Edge *e1=new EdgeLin(n1,n2); n1->decrRef(); n2->decrRef(); + n1=new Node(pol2[0],pol2[1]); + n2=new Node(pol2[4],pol2[5]); + n3=new Node(pol2[2],pol2[3]); + Edge *e2=new EdgeArcCircle(n1,n2,n3); n1->decrRef(); n2->decrRef(); n3->decrRef(); + e2->decrRef(); + e1->decrRef(); +} + +/*! + * Tests to avoid regressions : Basic one. + */ +void QuadraticPlanarInterpTest::checkNonRegression1() +{ + const double coords1[]= + { + 16.1732057215, -25.110999999800001, + 16.02555485246479, -25.340997988918762 + }; + Node *nS1=new Node(coords1); + Node *nE1=new Node(coords1+2); + const double radius1=2.902; + const double angleS1=-0.49999999950907054; const double angleL1=-0.0942156629996692; + const double center1[2]={13.66, -23.66}; + EdgeArcCircle *e1=new EdgeArcCircle(nS1,nE1,center1,radius1,angleS1,angleL1); + // + const double coords2[]= + { + 16.041579804000001, -25.350249998999999, + 16.367740958999999, -24.132999999999999 + }; + Node *nS2=new Node(coords2); + Node *nE2=new Node(coords2+2); + const double radius2=2.4345; + const double angleS2=-0.523598776190207; const double angleL2=0.5235987755846041; + const double center2[]={ 13.933240960547204, -24.132999998525658 }; + EdgeArcCircle *e2=new EdgeArcCircle(nS2,nE2,center2,radius2,angleS2,angleL2); + MergePoints merge; + QuadraticPolygon c1,c2; + e1->intersectWith(e2,merge,c1,c2); + CPPUNIT_ASSERT_EQUAL(2,c1.size()); CPPUNIT_ASSERT_EQUAL(2,c2.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCurveLength(),c1.getPerimeter(),1e-5); + //clean-up + nS1->decrRef(); nE1->decrRef(); nS2->decrRef(); nE2->decrRef(); e1->decrRef(); e2->decrRef(); +} + +void QuadraticPlanarInterpTest::checkNonRegression2() +{ + QUADRATIC_PLANAR::setPrecision(1e-12); + QUADRATIC_PLANAR::setArcDetectionPrecision(1e-9); + double coords1[]= + { + 15.141499999899999, -26.226033271399999, + 16.226033271199999, -25.141499999800001, + 16.1732057215, -25.110999999800001, + 15.110999999899999, -26.1732057217, + 15.755157392699999, -25.755157392499999, + 16.199619496299999, -25.126249999799999, + 15.7120238788, -25.712023879099998, + 15.126249999899999, -26.199619496499999 + }; + double coords2[]= + { + 15.933240959000001, -24.132999999999999, + 15.665291765999999, -25.132999998999999, + 16.041579804000001, -25.350249998999999, + 16.367740958999999, -24.132999999999999, + 15.865092611, -24.650638091000001, + 15.853435785, -25.241624998999999, + 16.284787383000001, -24.763094964, + 16.150490958999999, -24.132999999999999 + }; + vector nodes1; + nodes1.push_back(new Node(coords1)); + nodes1.push_back(new Node(coords1+2)); + nodes1.push_back(new Node(coords1+4)); + nodes1.push_back(new Node(coords1+6)); + nodes1.push_back(new Node(coords1+8)); + nodes1.push_back(new Node(coords1+10)); + nodes1.push_back(new Node(coords1+12)); + nodes1.push_back(new Node(coords1+14)); + QuadraticPolygon *pol1=QuadraticPolygon::buildArcCirclePolygon(nodes1); + vector nodes2; + nodes2.push_back(new Node(coords2)); + nodes2.push_back(new Node(coords2+2)); + nodes2.push_back(new Node(coords2+4)); + nodes2.push_back(new Node(coords2+6)); + nodes2.push_back(new Node(coords2+8)); + nodes2.push_back(new Node(coords2+10)); + nodes2.push_back(new Node(coords2+12)); + nodes2.push_back(new Node(coords2+14)); + QuadraticPolygon *pol2=QuadraticPolygon::buildArcCirclePolygon(nodes2); + vector v=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00173945,v[0]->getArea(),1e-7); + delete v[0]; + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00173945,pol1->intersectWith(*pol2),1e-7); + delete pol1; + delete pol2; +} + +/*! + * Tests to avoid regressions : Basic one. + */ +void QuadraticPlanarInterpTest::checkNonRegression3() +{ + const double coords1[]= + { + 10.962340811000001, -22.417749999000002, + 12.217990959, -21.162099852000001 + }; + Node *nS1=new Node(coords1); + Node *nE1=new Node(coords1+2); + const double radius1=3.4304999897666599; + const double angleS1=2.6179938783536514; const double angleL1=-0.52359877711901204; + const double center1[2]={13.933240950441375, -24.132999992807399}; + EdgeArcCircle *e1=new EdgeArcCircle(nS1,nE1,center1,radius1,angleS1,angleL1); + // + const double coords2[]= + { + 11.1467942784, -22.2090000002, + 11.0939667286, -22.178500000099998 + }; + Node *nS2=new Node(coords2); + Node *nE2=new Node(coords2+2); + EdgeLin *e2=new EdgeLin(nS2,nE2); + MergePoints merge; + QuadraticPolygon c1,c2; + CPPUNIT_ASSERT(e1->intersectWith(e2,merge,c1,c2)); + CPPUNIT_ASSERT_EQUAL(2,c1.size()); + CPPUNIT_ASSERT_EQUAL(2,c2.size()); + ElementaryEdge *tmp1=dynamic_cast(c1.front()); CPPUNIT_ASSERT(tmp1); + EdgeArcCircle *tmp2=dynamic_cast(tmp1->getPtr()); CPPUNIT_ASSERT(tmp2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.6179938783536514,tmp2->getAngle0(),1e-14); + //clean-up + nS1->decrRef(); nE1->decrRef(); nS2->decrRef(); nE2->decrRef(); e1->decrRef(); e2->decrRef(); +} + +void QuadraticPlanarInterpTest::checkNonRegression4() +{ + QUADRATIC_PLANAR::setPrecision(1e-12); + QUADRATIC_PLANAR::setArcDetectionPrecision(1e-9); + double coords1[]= + { + 10.962340811000001, -22.417749999000002, + 12.217990959, -21.162099852000001, + 12.051990958999999, -20.874579418, + 10.674820377, -22.251749999000001, + 11.507511146000001, -21.707270185999999, + 12.134990959, -21.018339635, + 11.272751694, -21.472510735, + 10.818580594, -22.334749999 + }; + + double coords2[]= + { + 10.758000000199999, -23.66, + 11.1467942784, -22.2090000002, + 11.0939667286, -22.178500000099998, + 10.696999999999999, -23.66, + 10.856883252299999, -22.908907131159999, + 11.1203805035, -22.1937500001, + 10.797961776699999, -22.893119169449999, + 10.727500000099999, -23.66 + }; + vector nodes1; + nodes1.push_back(new Node(coords1)); + nodes1.push_back(new Node(coords1+2)); + nodes1.push_back(new Node(coords1+4)); + nodes1.push_back(new Node(coords1+6)); + nodes1.push_back(new Node(coords1+8)); + nodes1.push_back(new Node(coords1+10)); + nodes1.push_back(new Node(coords1+12)); + nodes1.push_back(new Node(coords1+14)); + QuadraticPolygon *pol1=QuadraticPolygon::buildArcCirclePolygon(nodes1); + vector nodes2; + nodes2.push_back(new Node(coords2)); + nodes2.push_back(new Node(coords2+2)); + nodes2.push_back(new Node(coords2+4)); + nodes2.push_back(new Node(coords2+6)); + nodes2.push_back(new Node(coords2+8)); + nodes2.push_back(new Node(coords2+10)); + nodes2.push_back(new Node(coords2+12)); + nodes2.push_back(new Node(coords2+14)); + QuadraticPolygon *pol2=QuadraticPolygon::buildArcCirclePolygon(nodes2); + vector v=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00164773941455998,v[0]->getArea(),1e-7); + delete v[0]; + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00164773941455998,pol1->intersectWith(*pol2),1e-7); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegression5() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-12); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); + double coords1[]= + { + -1.7320508075000001, 1, + -1, 1.7320508075000001 , + -1.2172499999999999, 2.1083388455000001, + -2.1083388455000001, 1.2172499999999999, + -1.4142135623000001, 1.4142135623000001, + -1.108625, 1.9201948265, + -1.7214514588000001, 1.7214514588000001, + -1.9201948265, 1.108625}; + + double coords2[]= + { + -2.2379999998, 0, + -1.9381648534, 1.1189999998, + -1.9909924031999999, 1.1494999999, + -2.2989999998999999, 0, + -2.1617419990000002, 0.57923702298000002, + -1.9645786283, 1.1342499998, + -2.2206634745999998, 0.59502498461999997, + -2.2684999997999999, 0}; + //Edge1_of_pol2 inter Edge4_of_pol1 = {-1.9381648533711939, 1.1189999998498941} + //Edge4_of_pol1 _angle = -0.523598775922546, _angle0 = -3.1415926535897931, _radius = 2.2379999983074721, _center = {-1.4925279436059493e-09, 1.3300635705141101e-10}} + vector nodes1; + nodes1.push_back(new Node(coords1)); + nodes1.push_back(new Node(coords1+2)); + nodes1.push_back(new Node(coords1+4)); + nodes1.push_back(new Node(coords1+6)); + nodes1.push_back(new Node(coords1+8)); + nodes1.push_back(new Node(coords1+10)); + nodes1.push_back(new Node(coords1+12)); + nodes1.push_back(new Node(coords1+14)); + QuadraticPolygon *pol1=QuadraticPolygon::buildArcCirclePolygon(nodes1); + vector nodes2; + nodes2.push_back(new Node(coords2)); + nodes2.push_back(new Node(coords2+2)); + nodes2.push_back(new Node(coords2+4)); + nodes2.push_back(new Node(coords2+6)); + nodes2.push_back(new Node(coords2+8)); + nodes2.push_back(new Node(coords2+10)); + nodes2.push_back(new Node(coords2+12)); + nodes2.push_back(new Node(coords2+14)); + QuadraticPolygon *pol2=QuadraticPolygon::buildArcCirclePolygon(nodes2); + vector v=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(0,(int)v.size()); + //CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00164773941455998,v[0]->getArea(),1e-7); + //delete v[0]; + //CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00164773941455998,pol1->intersectWith(*pol2),1e-7); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegression6() +{ + QUADRATIC_PLANAR::setPrecision(1e-12); + QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); + double coords1[]= + { + 10.962340811000001, -22.417749999000002, + 12.217990959, -21.162099852000001, + 12.051990958999999, -20.874579418, + 10.674820377, -22.251749999000001, + 11.507511146000001, -21.707270185999999, + 12.134990959, -21.018339635, + 11.272751694, -21.472510735, + 10.818580594, -22.334749999 + }; + double coords2[]= + { 10.426, -23.66, + 10.859273844199999, -22.043000000100001, + 10.806446294799999, -22.012500000199999, + 10.3650000002, -23.66, + 10.536195877799999, -22.822979208099998, + 10.832860069499999, -22.027750000200001, + 10.477274402499999, -22.80719124657, + 10.3955000001, -23.66}; + vector nodes1; + nodes1.push_back(new Node(coords1)); + nodes1.push_back(new Node(coords1+2)); + nodes1.push_back(new Node(coords1+4)); + nodes1.push_back(new Node(coords1+6)); + nodes1.push_back(new Node(coords1+8)); + nodes1.push_back(new Node(coords1+10)); + nodes1.push_back(new Node(coords1+12)); + nodes1.push_back(new Node(coords1+14)); + QuadraticPolygon *pol1=QuadraticPolygon::buildArcCirclePolygon(nodes1); + vector nodes2; + nodes2.push_back(new Node(coords2)); + nodes2.push_back(new Node(coords2+2)); + nodes2.push_back(new Node(coords2+4)); + nodes2.push_back(new Node(coords2+6)); + nodes2.push_back(new Node(coords2+8)); + nodes2.push_back(new Node(coords2+10)); + nodes2.push_back(new Node(coords2+12)); + nodes2.push_back(new Node(coords2+14)); + QuadraticPolygon *pol2=QuadraticPolygon::buildArcCirclePolygon(nodes2); + vector v=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(v[0]->getArea(),0.0150659,1e-7); + delete v[0]; + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegression7() +{ + QUADRATIC_PLANAR::setPrecision(1e-5); + QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); + double coords1[]= + { + -2., 0, + -1.7320508075000001, 1, + -2.1083388455000001, 1.2172499999999999, + -2.4344999999999999, 0, + -1.9318516525603098, 0.51763809027157182, + -1.9201948265, 1.108625, + -2.3515464241024469, 0.63009496529570408, + -2.2172499999999999, 0 + }; + double coords2[]= + { -2.3369999999000002, 0, + -2.0239013684999998, 1.1684999999000001, + -2.1927763221999998, 1.2659999998, + -2.5319999998, 0, + -2.2573686559260442, 0.60486010843437632, + -2.1083388453499996, 1.2172499998499999, + -2.445724191994314, 0.65532982205982326, + -2.4344999998499999, 0 }; + vector nodes1; + nodes1.push_back(new Node(coords1)); + nodes1.push_back(new Node(coords1+2)); + nodes1.push_back(new Node(coords1+4)); + nodes1.push_back(new Node(coords1+6)); + nodes1.push_back(new Node(coords1+8)); + nodes1.push_back(new Node(coords1+10)); + nodes1.push_back(new Node(coords1+12)); + nodes1.push_back(new Node(coords1+14)); + QuadraticPolygon *pol1=QuadraticPolygon::buildArcCirclePolygon(nodes1); + vector nodes2; + nodes2.push_back(new Node(coords2)); + nodes2.push_back(new Node(coords2+2)); + nodes2.push_back(new Node(coords2+4)); + nodes2.push_back(new Node(coords2+6)); + nodes2.push_back(new Node(coords2+8)); + nodes2.push_back(new Node(coords2+10)); + nodes2.push_back(new Node(coords2+12)); + nodes2.push_back(new Node(coords2+14)); + QuadraticPolygon *pol2=QuadraticPolygon::buildArcCirclePolygon(nodes2); + vector v=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.121795,v[0]->getArea(),1.e-6); + delete v[0]; + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegression8() +{ + QUADRATIC_PLANAR::setPrecision(1e-3); + QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); + double coords1[]= + { + -13.933240959000001, -28.559499999, + -16.146490959000001, -27.966461449000001, + -16.383240958999998, -28.376524478, + -13.933240959000001, -29.032999999000001, + -15.078903461873765, -28.408670669106311, + -16.264865958999998, -28.1714929635, + -15.201454280317435, -28.866036547696734, + -13.933240959000001, -28.796249999 }; + double coords2[]= + { -16.382999999950002, -28.376524478457149, + -13.933000000014729, -29.03299999982551, + -13.93300000006697, -28.793999999915993, + -16.263500000000001, -28.169544407039268, + -15.201213320921273, -28.866036548734634, + -13.933000000040851, -28.913499999870751, + -15.139355569325469, -28.635180276305853, + -16.323249999975001, -28.273034442748209 }; + vector nodes1; + nodes1.push_back(new Node(coords1)); + nodes1.push_back(new Node(coords1+2)); + nodes1.push_back(new Node(coords1+4)); + nodes1.push_back(new Node(coords1+6)); + nodes1.push_back(new Node(coords1+8)); + nodes1.push_back(new Node(coords1+10)); + nodes1.push_back(new Node(coords1+12)); + nodes1.push_back(new Node(coords1+14)); + QuadraticPolygon *pol1=QuadraticPolygon::buildArcCirclePolygon(nodes1); + vector nodes2; + nodes2.push_back(new Node(coords2)); + nodes2.push_back(new Node(coords2+2)); + nodes2.push_back(new Node(coords2+4)); + nodes2.push_back(new Node(coords2+6)); + nodes2.push_back(new Node(coords2+8)); + nodes2.push_back(new Node(coords2+10)); + nodes2.push_back(new Node(coords2+12)); + nodes2.push_back(new Node(coords2+14)); + QuadraticPolygon *pol2=QuadraticPolygon::buildArcCirclePolygon(nodes2); + vector v=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.598232,v[0]->getArea(),1.e-6); + delete v[0]; + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegression9() +{ + QUADRATIC_PLANAR::setPrecision(1e-7); + QUADRATIC_PLANAR::setArcDetectionPrecision(1e-8); + double coords1[]= + { + -0.04476229252902969, -0.085118027765365603, + -0.046952683430894329, -0.085704941238358354, + -0.046952683430894329, -0.088063823748058725, + -0.043582851274179504, -0.087160879944491371, + -0.045818853668170414, -0.085555669718918592, + -0.046952683430894329, -0.086884382493208526, + -0.045208329947517549, -0.087834175256748526, + -0.044172571901604597, -0.086139453854928494 }; + + double coords2[]= + { -0.05065868681155701, -0.087744551996665671, + -0.046951871439587615, -0.088737790182236015, + -0.046951871439683469, -0.088063823751059062, + -0.050321703596054014, -0.087160879946116557, + -0.0488706602695924, -0.08848517684025306, + -0.046951871439635542, -0.088400806966647538, + -0.048696224921445964, -0.087834175258503858, + -0.050490195203805516, -0.087452715971391121}; + + vector nodes1; + nodes1.push_back(new Node(coords1)); + nodes1.push_back(new Node(coords1+2)); + nodes1.push_back(new Node(coords1+4)); + nodes1.push_back(new Node(coords1+6)); + nodes1.push_back(new Node(coords1+8)); + nodes1.push_back(new Node(coords1+10)); + nodes1.push_back(new Node(coords1+12)); + nodes1.push_back(new Node(coords1+14)); + QuadraticPolygon *pol1=QuadraticPolygon::buildArcCirclePolygon(nodes1); + vector nodes2; + nodes2.push_back(new Node(coords2)); + nodes2.push_back(new Node(coords2+2)); + nodes2.push_back(new Node(coords2+4)); + nodes2.push_back(new Node(coords2+6)); + nodes2.push_back(new Node(coords2+8)); + nodes2.push_back(new Node(coords2+10)); + nodes2.push_back(new Node(coords2+12)); + nodes2.push_back(new Node(coords2+14)); + QuadraticPolygon *pol2=QuadraticPolygon::buildArcCirclePolygon(nodes2); + vector v=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(0,(int)v.size()); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegression10() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords1[]= + { -0.002269581957210453, -0.09851030343724453, + -0.004268022334182935, -0.1059685844580936, + -0.002777851483521377, -0.1023709937816271}; + double coords2[]= + { -0.004114727297178323, -0.1049870239624718, + -0.003544545103522544, -0.1053162188055505}; + Node *n1_1=new Node(coords1); + Node *n2_1=new Node(coords1+2); + Node *n3_1=new Node(coords1+4); + Node *n1_2=new Node(coords2); + Node *n2_2=new Node(coords2+2); + EdgeArcCircle *e1=new EdgeArcCircle(n1_1,n3_1,n2_1); + EdgeLin *e2=new EdgeLin(n1_2,n2_2); + MergePoints merge; + ComposedEdge *c1=new ComposedEdge; + ComposedEdge *c2=new ComposedEdge; + CPPUNIT_ASSERT(e1->intersectWith(e2,merge,*c1,*c2)); + CPPUNIT_ASSERT_EQUAL(2,c1->size()); + CPPUNIT_ASSERT_EQUAL(2,c2->size()); + ComposedEdge::Delete(c1); ComposedEdge::Delete(c2); + n1_1->decrRef(); n2_1->decrRef(); n3_1->decrRef(); + n1_2->decrRef(); n2_2->decrRef(); + e1->decrRef(); e2->decrRef(); +} + +void QuadraticPlanarInterpTest::checkNonRegression11() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords1[]= + { -0.002269581957210453, -0.09851030343724453, + -0.004268022334182935, -0.1059685844580936, + -0.002886178753789801, -0.1067663922211958, + -0.0006739664310059821, -0.09851030343724453, + -0.002777851483521377, -0.1023709937816271, + -0.003577100543986368, -0.1063674883396447, + -0.001236605237717319, -0.1027839694676665, + -0.001471774194108217, -0.09851030343724453}; + double coords2[]= + { -0.003544545103522544, -0.1053162188055505, + -0.001941023322604723, -0.09851030343724451, + -0.002598140593501099, -0.09851030343724451, + -0.004114727297178323, -0.1049870239624718, + -0.002347317802266182, -0.1020064358043286, + -0.002269581958052911, -0.09851030343724451, + -0.002982346712452072, -0.1018362598405457, + -0.003829636200350435, -0.1051516213840111}; + + vector nodes1; + nodes1.push_back(new Node(coords1)); + nodes1.push_back(new Node(coords1+2)); + nodes1.push_back(new Node(coords1+4)); + nodes1.push_back(new Node(coords1+6)); + nodes1.push_back(new Node(coords1+8)); + nodes1.push_back(new Node(coords1+10)); + nodes1.push_back(new Node(coords1+12)); + nodes1.push_back(new Node(coords1+14)); + QuadraticPolygon *pol1=QuadraticPolygon::buildArcCirclePolygon(nodes1); + vector nodes2; + nodes2.push_back(new Node(coords2)); + nodes2.push_back(new Node(coords2+2)); + nodes2.push_back(new Node(coords2+4)); + nodes2.push_back(new Node(coords2+6)); + nodes2.push_back(new Node(coords2+8)); + nodes2.push_back(new Node(coords2+10)); + nodes2.push_back(new Node(coords2+12)); + nodes2.push_back(new Node(coords2+14)); + QuadraticPolygon *pol2=QuadraticPolygon::buildArcCirclePolygon(nodes2); + vector v=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.28973e-06,v[0]->getArea(),1.e-11); + delete v[0]; + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegression12() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-6); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords1[]= + { -0.5032251558760915, -0.8716087994449138, + -0.4695268343089433, -0.8806382374805872, + -0.4695268343089433, -0.8570494123835835, + -0.4914307433275896, -0.8511802776536561, + -0.4869703691141082, -0.8783417525751493, + -0.4695268343089433, -0.8688438249320853, + -0.480865131947653, -0.8555566971861125, + -0.4973279496018406, -0.8613945385492849}; + + double coords2[]= + { -0.5065868681155701, -0.8774455199666568, + -0.4695187143958762, -0.8873779018223601, + -0.4695187143968347, -0.8806382375105907, + -0.5032170359605401, -0.8716087994611657, + -0.488706602695924, -0.8848517684025307, + -0.4695187143963554, -0.8840080696664754, + -0.4869622492144596, -0.8783417525850385, + -0.5049019520380551, -0.8745271597139112}; + + vector nodes1; + nodes1.push_back(new Node(coords1)); + nodes1.push_back(new Node(coords1+2)); + nodes1.push_back(new Node(coords1+4)); + nodes1.push_back(new Node(coords1+6)); + nodes1.push_back(new Node(coords1+8)); + nodes1.push_back(new Node(coords1+10)); + nodes1.push_back(new Node(coords1+12)); + nodes1.push_back(new Node(coords1+14)); + QuadraticPolygon *pol1=QuadraticPolygon::buildArcCirclePolygon(nodes1); + vector nodes2; + nodes2.push_back(new Node(coords2)); + nodes2.push_back(new Node(coords2+2)); + nodes2.push_back(new Node(coords2+4)); + nodes2.push_back(new Node(coords2+6)); + nodes2.push_back(new Node(coords2+8)); + nodes2.push_back(new Node(coords2+10)); + nodes2.push_back(new Node(coords2+12)); + nodes2.push_back(new Node(coords2+14)); + QuadraticPolygon *pol2=QuadraticPolygon::buildArcCirclePolygon(nodes2); + vector v=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,v[0]->getArea(),1.e-6); + delete v[0]; + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegression13() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-6); + + double coords_1[194]={ + 0, 0, 0.304375, -7.454791178893722e-17, 0.2152256265236553, -0.2152256265236555, -5.591093384170291e-17, -0.304375, + -0.2152256265236555, -0.2152256265236554, -0.304375, 3.727395589446861e-17, -0.2152256265236554, 0.2152256265236554, 1.86369779472343e-17, 0.304375, + 0.2152256265236554, 0.2152256265236554, 0.60875, -1.490958235778744e-16, 0.5624116654162459, -0.2329585394522483, 0.4304512530473107, -0.4304512530473109, + 0.2329585394522485, -0.5624116654162458, -1.118218676834058e-16, -0.60875, -0.2329585394522482, -0.5624116654162459, -0.4304512530473109, -0.4304512530473108, + -0.5624116654162459, -0.2329585394522483, -0.60875, 7.454791178893722e-17, -0.5624116654162458, 0.2329585394522485, -0.4304512530473108, 0.4304512530473109, + -0.2329585394522484, 0.5624116654162458, 3.727395589446861e-17, 0.60875, 0.2329585394522485, 0.5624116654162458, 0.4304512530473109, 0.4304512530473108, + 0.5624116654162458, 0.2329585394522484, 0.913125, -2.236437353668116e-16, 0.645676879570966, -0.6456768795709663, -1.677328015251087e-16, -0.913125, + -0.6456768795709663, -0.6456768795709661, -0.913125, 1.118218676834058e-16, -0.6456768795709661, 0.6456768795709662, 5.591093384170291e-17, 0.913125, + 0.6456768795709662, 0.6456768795709661, 1.2175, -2.981916471557489e-16, 1.124823330832492, -0.4659170789044966, 0.8609025060946214, -0.8609025060946218, + 0.4659170789044971, -1.124823330832492, -2.236437353668116e-16, -1.2175, -0.4659170789044965, -1.124823330832492, -0.8609025060946218, -0.8609025060946216, + -1.124823330832492, -0.4659170789044967, -1.2175, 1.490958235778744e-16, -1.124823330832492, 0.465917078904497, -0.8609025060946216, 0.8609025060946217, + -0.4659170789044967, 1.124823330832492, 7.454791178893722e-17, 1.2175, 0.4659170789044969, 1.124823330832492, 0.8609025060946217, 0.8609025060946216, + 1.124823330832492, 0.4659170789044968, 1.521875, -3.727395589446861e-16, 1.076128132618277, -1.076128132618277, -2.795546692085146e-16, -1.521875, + -1.076128132618277, -1.076128132618277, -1.521875, 1.86369779472343e-16, -1.076128132618277, 1.076128132618277, 9.318488973617152e-17, 1.521875, + 1.076128132618277, 1.076128132618277, 1.82625, -4.472874707336233e-16, 1.687234996248738, -0.6988756183567448, 1.291353759141932, -1.291353759141933, + 0.6988756183567456, -1.687234996248737, -3.354656030502175e-16, -1.82625, -0.6988756183567447, -1.687234996248738, -1.291353759141933, -1.291353759141932, + -1.687234996248738, -0.6988756183567449, -1.82625, 2.236437353668116e-16, -1.687234996248737, 0.6988756183567454, -1.291353759141932, 1.291353759141932, + -0.6988756183567451, 1.687234996248737, 1.118218676834058e-16, 1.82625, 0.6988756183567453, 1.687234996248737, 1.291353759141932, 1.291353759141932, + 1.687234996248737, 0.6988756183567452, 2.130625, -5.218353825225606e-16, 1.506579385665588, -1.506579385665588, -3.913765368919204e-16, -2.130625, + -1.506579385665588, -1.506579385665588, -2.130625, 2.609176912612803e-16, -1.506579385665588, 1.506579385665588, 1.304588456306401e-16, 2.130625, + 1.506579385665588, 1.506579385665588, 2.435, -5.963832943114977e-16, 2.249646661664984, -0.9318341578089931, 1.721805012189243, -1.721805012189244, + 0.9318341578089941, -2.249646661664983, -4.472874707336233e-16, -2.435, -0.9318341578089929, -2.249646661664984, -1.721805012189244, -1.721805012189243, + -2.249646661664984, -0.9318341578089934, -2.435, 2.981916471557489e-16, -2.249646661664983, 0.9318341578089939, -1.721805012189243, 1.721805012189243, + -0.9318341578089935, 2.249646661664983, 1.490958235778744e-16, 2.435, 0.9318341578089938, 2.249646661664983, 1.721805012189243, 1.721805012189243, + 2.249646661664983, 0.9318341578089936 }; + + int tab6_1[48]={ + 0, 9, 11, 1, 10, 2, 0, 11, 13, 2, 12, 3, 0, 13, 15, 3, 14, 4, 0, 15, + 17, 4, 16, 5, 0, 17, 19, 5, 18, 6, 0, 19, 21, 6, 20, 7, 0, 21, 23, 7, + 22, 8, 0, 23, 9, 8, 24, 1 }; + + int tab8_1[192]={ + 9, 33, 35, 11, 25, 34, 26, 10, 11, 35, 37, 13, 26, 36, 27, 12, 13, 37, 39, 15, + 27, 38, 28, 14, 15, 39, 41, 17, 28, 40, 29, 16, 17, 41, 43, 19, 29, 42, 30, 18, + 19, 43, 45, 21, 30, 44, 31, 20, 21, 45, 47, 23, 31, 46, 32, 22, 23, 47, 33, 9, + 32, 48, 25, 24, 33, 57, 59, 35, 49, 58, 50, 34, 35, 59, 61, 37, 50, 60, 51, 36, + 37, 61, 63, 39, 51, 62, 52, 38, 39, 63, 65, 41, 52, 64, 53, 40, 41, 65, 67, 43, + 53, 66, 54, 42, 43, 67, 69, 45, 54, 68, 55, 44, 45, 69, 71, 47, 55, 70, 56, 46, + 47, 71, 57, 33, 56, 72, 49, 48, 57, 81, 83, 59, 73, 82, 74, 58, 59, 83, 85, 61, + 74, 84, 75, 60, 61, 85, 87, 63, 75, 86, 76, 62, 63, 87, 89, 65, 76, 88, 77, 64, + 65, 89, 91, 67, 77, 90, 78, 66, 67, 91, 93, 69, 78, 92, 79, 68, 69, 93, 95, 71, + 79, 94, 80, 70, 71, 95, 81, 57, 80, 96, 73, 72 }; + + double coords_2[20]={ + 0.5159941860137611, 0, 0, -0.5159941860137611, -0.5159941860137611, 0, 0, 0.5159941860137611, + 0.6684941860137611, 0, 0, -0.6684941860137611, -0.6684941860137611, 0, 0, 0.6684941860137611, + 0.5922441860137611, 0, -0.5922441860137611, 0 }; + + int tab8_2[16]={ + 0, 4, 6, 2, 8, 5, 9, 1, 2, 6, 4, 0, 9, 7, 8, 3 }; + + double perimeterFromPol1,perimeterFromPol2,perimeterFromPol1AndPol2; + + const int *work1=tab6_1; + for(int i=0;i<8;i++,work1+=6) + { + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords_1,work1,6); + const int *work2=tab8_2; + for(int j=0;j<2;j++,work2+=8) + { + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords_2,work2,8); + //vector tmp; + //pol1->intersectForPoint(*pol2,tmp); + pol1->intersectForPerimeter(*pol2,perimeterFromPol1,perimeterFromPol2,perimeterFromPol1AndPol2); + //pol1->intersectMySelfWith(*pol2); + delete pol2; + } + delete pol1; + } + work1=tab8_1; + for(int i=0;i<24;i++,work1+=8) + { + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords_1,work1,8); + const int *work2=tab8_2; + for(int j=0;j<2;j++,work2+=8) + { + + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords_2,work2,8); + //vector tmp; + //pol1->intersectForPoint(*pol2,tmp); + pol1->intersectForPerimeter(*pol2,perimeterFromPol1,perimeterFromPol2,perimeterFromPol1AndPol2); + delete pol2; + } + delete pol1; + } +} + +/*! + Some overlapping cases for intersectForPoint. +*/ +void QuadraticPlanarInterpTest::checkNonRegression14() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-6); + + double coords[72]={ + 1.,0.,1.3,0.,-1.3,0.,-1.,0.,1.15,0.,0.,1.3,-1.15,0.,0.,1., + -0.91923881554251186,-0.91923881554251186,-0.91923881554251186,0.91923881554251186,-1.0606601717798214,1.0606601717798214,-1.0606601717798214,-1.0606601717798214,-1.5,0., + -0.98994949366116658,-0.98994949366116658,-0.98994949366116658,0.98994949366116658, + 0.91923881554251186,0.91923881554251186,1.0606601717798214,1.0606601717798214,0.98994949366116658,0.98994949366116658, 0., 1.5, + -0.83562389259250125,0.99585777605467141, -0.65, 1.1258330249197703, -1.2216004070216808, 0.44462618632336953, -1.1258330249197703, 0.65, + -0.74564936725635955, 1.0648976575756897, -1.6770646146510724, 1.4072242996141826, -1.1782001231476449, 0.54940374026290939, -1.5873847317707279, 0.74020965686300877, + -1.1782001231476449, 0.54940374026290939, -1.0648976575756894, 0.74564936725635977, -1.2950531075192693, -0.11330246557195534, -1.2950531075192693, 0.11330246557195565, + -1.1258330249197703, 0.65, -2.1146554070041046, 0.56662020857685746, -1.6918048488667423, 0.45331774300490169, + 0.,-1.3,0.,-1.5 + }; + int tab[48]={ + 0,1,2,3,4,5,6,7, + 8,9,10,11,2,14,12,13, + 9,15,16,10,5,17,18,14, + 9,15,16,10,34,17,35,14, + 19,20,21,22,23,24,25,26, + 27,28,29,30,31,32,2,33 + }; + QuadraticPolygon *pol1,*pol2; + vector goalOfTest; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab,8); + // Level 1 + pol2=buildQuadraticPolygonCoarseInfo(coords,tab+8,8); + pol1->intersectForPoint(*pol2,goalOfTest); + const int res1[4]={0,1,0,0}; + CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); + CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res1)); + delete pol2; + // Level 2 + pol2=buildQuadraticPolygonCoarseInfo(coords,tab+16,8); + pol1->intersectForPoint(*pol2,goalOfTest); + const int res2[4]={0,2,0,0}; + CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); + CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res2)); + delete pol2; + //Level 2 bis + pol2=buildQuadraticPolygonCoarseInfo(coords,tab+24,8); + pol1->intersectForPoint(*pol2,goalOfTest); + const int res2Bis[4]={0,2,0,0}; + CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); + CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res2Bis)); + delete pol2; + // Level 3 + pol2=buildQuadraticPolygonCoarseInfo(coords,tab+40,8); + pol1->intersectForPoint(*pol2,goalOfTest); + const int res3[4]={0,3,0,0}; + CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); + CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res3)); + delete pol2; + // Level 4 + pol2=buildQuadraticPolygonCoarseInfo(coords,tab+32,8); + pol1->intersectForPoint(*pol2,goalOfTest); + const int res4[4]={0,4,0,0}; + CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); + CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res4)); + delete pol2; + // + delete pol1; +} + +/*! + * This test is one of the most complicated intersection configuration. + */ +void QuadraticPlanarInterpTest::checkNonRegression15() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-6); + + double coords[72]={ + 1.,0.,1.3,0.,-1.3,0.,-1.,0.,1.15,0.,0.,1.3,-1.15,0.,0.,1., + -0.91923881554251186,-0.91923881554251186,-0.91923881554251186,0.91923881554251186,-1.0606601717798214,1.0606601717798214,-1.0606601717798214,-1.0606601717798214,-1.5,0., + -0.98994949366116658,-0.98994949366116658,-0.98994949366116658,0.98994949366116658, + 0.91923881554251186,0.91923881554251186,1.0606601717798214,1.0606601717798214,0.98994949366116658,0.98994949366116658, 0., 1.5, + -0.83562389259250125,0.99585777605467141, -0.65, 1.1258330249197703, -1.2216004070216808, 0.44462618632336953, -1.1258330249197703, 0.65, + -0.74564936725635955, 1.0648976575756897, -1.6770646146510724, 1.4072242996141826, -1.1782001231476449, 0.54940374026290939, -1.5873847317707279, 0.74020965686300877, + -1.1782001231476449, 0.54940374026290939, -1.0648976575756894, 0.74564936725635977, -1.2950531075192693, -0.11330246557195534, -1.2950531075192693, 0.11330246557195565, + -1.1258330249197703, 0.65, -2.1146554070041046, 0.56662020857685746, -1.6918048488667423, 0.45331774300490169, + 0.,-1.3,0.,-1.5 + }; + + int tab[24]={ + 0,1,2,3,4,5,6,7, + 9,15,16,10,7,17,5,14, + 9,10,16,15,14,5,17,7 + }; + + const double RefLgth=3.88995883524451; + const double RefArea=0.383185168001075; + // + QuadraticPolygon *pol1,*pol2; + //pol1 and pol2 in same orientation + pol1=buildQuadraticPolygonCoarseInfo(coords,tab,8); + pol2=buildQuadraticPolygonCoarseInfo(coords,tab+8,8); + vector res=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT_EQUAL(4,res[0]->recursiveSize()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(RefLgth,res[0]->getPerimeter(),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(RefArea,res[0]->getArea(),1e-12); + delete res[0]; + //pol1 and pol2 in same orientation but inversing intersection call pol1<->pol2 + res=pol2->intersectMySelfWith(*pol1); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT_EQUAL(4,res[0]->recursiveSize()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(RefLgth,res[0]->getPerimeter(),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(RefArea,res[0]->getArea(),1e-12); + delete res[0]; + delete pol2; + //pol1 and pol2 in opposite orientation + pol2=buildQuadraticPolygonCoarseInfo(coords,tab+16,8); + res=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT_EQUAL(4,res[0]->recursiveSize()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(RefLgth,res[0]->getPerimeter(),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-RefArea,res[0]->getArea(),1e-12); + delete res[0]; + //pol1 and pol2 in opposite orientation but inversing intersection call pol1<->pol2 + res=pol2->intersectMySelfWith(*pol1); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT_EQUAL(4,res[0]->recursiveSize()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(RefLgth,res[0]->getPerimeter(),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(RefArea,res[0]->getArea(),1e-12); + delete res[0]; + delete pol2; + // + delete pol1; +} + +class DoubleEqual +{ +public: + DoubleEqual(double eps):_eps(eps) { } + bool operator()(double x, double y) { return fabs(x-y)<_eps; } +private: + double _eps; +}; + +/*! + * This test is to see the reuse of a polygon in intersect* methods. initLocation needed ... + */ +void QuadraticPlanarInterpTest::checkNonRegression16() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords1[194]={ + 0, 0, 0.304375, 0, 0.2152256265236554, 0.2152256265236554, 1.86369779472343e-17, 0.304375, + -0.2152256265236554, 0.2152256265236554, -0.304375, 3.727395589446861e-17, -0.2152256265236555, -0.2152256265236554, -5.591093384170291e-17, -0.304375, + 0.2152256265236553, -0.2152256265236555, 0.60875, 0, 0.5624116654162458, 0.2329585394522484, 0.4304512530473109, 0.4304512530473108, + 0.2329585394522485, 0.5624116654162458, 3.727395589446861e-17, 0.60875, -0.2329585394522484, 0.5624116654162458, -0.4304512530473108, 0.4304512530473109, + -0.5624116654162458, 0.2329585394522485, -0.60875, 7.454791178893722e-17, -0.5624116654162459, -0.2329585394522483, -0.4304512530473109, -0.4304512530473108, + -0.2329585394522482, -0.5624116654162459, -1.118218676834058e-16, -0.60875, 0.2329585394522485, -0.5624116654162458, 0.4304512530473107, -0.4304512530473109, + 0.5624116654162459, -0.2329585394522483, 0.913125, 0, 0.6456768795709662, 0.6456768795709661, 5.591093384170291e-17, 0.913125, + -0.6456768795709661, 0.6456768795709662, -0.913125, 1.118218676834058e-16, -0.6456768795709663, -0.6456768795709661, -1.677328015251087e-16, -0.913125, + 0.645676879570966, -0.6456768795709663, 1.2175, 0, 1.124823330832492, 0.4659170789044968, 0.8609025060946217, 0.8609025060946216, + 0.4659170789044969, 1.124823330832492, 7.454791178893722e-17, 1.2175, -0.4659170789044967, 1.124823330832492, -0.8609025060946216, 0.8609025060946217, + -1.124823330832492, 0.465917078904497, -1.2175, 1.490958235778744e-16, -1.124823330832492, -0.4659170789044967, -0.8609025060946218, -0.8609025060946216, + -0.4659170789044965, -1.124823330832492, -2.236437353668116e-16, -1.2175, 0.4659170789044971, -1.124823330832492, 0.8609025060946214, -0.8609025060946218, + 1.124823330832492, -0.4659170789044966, 1.521875, 0, 1.076128132618277, 1.076128132618277, 9.318488973617152e-17, 1.521875, + -1.076128132618277, 1.076128132618277, -1.521875, 1.86369779472343e-16, -1.076128132618277, -1.076128132618277, -2.795546692085146e-16, -1.521875, + 1.076128132618277, -1.076128132618277, 1.82625, 0, 1.687234996248737, 0.6988756183567452, 1.291353759141932, 1.291353759141932, + 0.6988756183567453, 1.687234996248737, 1.118218676834058e-16, 1.82625, -0.6988756183567451, 1.687234996248737, -1.291353759141932, 1.291353759141932, + -1.687234996248737, 0.6988756183567454, -1.82625, 2.236437353668116e-16, -1.687234996248738, -0.6988756183567449, -1.291353759141933, -1.291353759141932, + -0.6988756183567447, -1.687234996248738, -3.354656030502175e-16, -1.82625, 0.6988756183567456, -1.687234996248737, 1.291353759141932, -1.291353759141933, + 1.687234996248738, -0.6988756183567448, 2.130625, 0, 1.506579385665588, 1.506579385665588, 1.304588456306401e-16, 2.130625, + -1.506579385665588, 1.506579385665588, -2.130625, 2.609176912612803e-16, -1.506579385665588, -1.506579385665588, -3.913765368919204e-16, -2.130625, + 1.506579385665588, -1.506579385665588, 2.435, 0, 2.249646661664983, 0.9318341578089936, 1.721805012189243, 1.721805012189243, + 0.9318341578089938, 2.249646661664983, 1.490958235778744e-16, 2.435, -0.9318341578089935, 2.249646661664983, -1.721805012189243, 1.721805012189243, + -2.249646661664983, 0.9318341578089939, -2.435, 2.981916471557489e-16, -2.249646661664984, -0.9318341578089934, -1.721805012189244, -1.721805012189243, + -0.9318341578089929, -2.249646661664984, -4.472874707336233e-16, -2.435, 0.9318341578089941, -2.249646661664983, 1.721805012189243, -1.721805012189244, + 2.249646661664984, -0.9318341578089931, }; + + int tab1_8[192]={ + 11, 35, 33, 9, 26, 34, 25, 10, 13, 37, 35, 11, 27, 36, 26, 12, 15, 39, 37, 13, + 28, 38, 27, 14, 17, 41, 39, 15, 29, 40, 28, 16, 19, 43, 41, 17, 30, 42, 29, 18, + 21, 45, 43, 19, 31, 44, 30, 20, 23, 47, 45, 21, 32, 46, 31, 22, 9, 33, 47, 23, + 25, 48, 32, 24, 35, 59, 57, 33, 50, 58, 49, 34, 37, 61, 59, 35, 51, 60, 50, 36, + 39, 63, 61, 37, 52, 62, 51, 38, 41, 65, 63, 39, 53, 64, 52, 40, 43, 67, 65, 41, + 54, 66, 53, 42, 45, 69, 67, 43, 55, 68, 54, 44, 47, 71, 69, 45, 56, 70, 55, 46, + 33, 57, 71, 47, 49, 72, 56, 48, 59, 83, 81, 57, 74, 82, 73, 58, 61, 85, 83, 59, + 75, 84, 74, 60, 63, 87, 85, 61, 76, 86, 75, 62, 65, 89, 87, 63, 77, 88, 76, 64, + 67, 91, 89, 65, 78, 90, 77, 66, 69, 93, 91, 67, 79, 92, 78, 68, 71, 95, 93, 69, + 80, 94, 79, 70, 57, 81, 95, 71, 73, 96, 80, 72, }; + + double coords2[20]={ + 2.435, 0, 0, -2.435, -2.435, 0, 0, 2.435, + 2.6925, 0, 0, -2.6925, -2.6925, 0, 0, 2.6925, + 2.56375, 0, -2.56375, 0, }; + + int tab2_8[16]={ 0, 4, 6, 2, 8, 5, 9, 1, 2, 6, 4, 0, 9, 7, 8, 3 }; + + QuadraticPolygon *pol1,*pol2; + //pol1 and pol2 in same orientation + vector test1,test2; + for(int ii=0;ii<24;ii++) + { + pol1=buildQuadraticPolygonCoarseInfo(coords1,tab1_8+8*ii,8); + for(int jj=0;jj<2;jj++) + { + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab2_8+jj*8,8); + // + vector v1,v2; + pol1->initLocations(); + pol1->intersectForPerimeterAdvanced(*pol2,v1,v2); + if(ii==16 && jj==1) + test1=v1; + if(ii==20 && jj==1) + test2=v1; + delete pol2; + } + delete pol1; + } + const double test1_res[4]={0.,1.9124445278727873,0.,0.}; + CPPUNIT_ASSERT(std::equal(test1.begin(),test1.end(),test1_res,DoubleEqual(1e-10))); + const double test2_res[4]={0.,0.,0.,0.}; + CPPUNIT_ASSERT(std::equal(test2.begin(),test2.end(),test2_res,DoubleEqual(1e-10))); +} + +/*! + * This test checks overlapped intersections END-INSIDE and INSIDE-START with same and opposite orientation. + */ +void QuadraticPlanarInterpTest::checkNonRegression17() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -1., 0., 1., 0. , 1.5, 0., -1.5, 0., + 0. , 1., 1.25, 0., 0., 1.5, -1.25, 0.}; + + double coords2[16]={ + 0.70710678118654757, 0.70710678118654757, -1., 0., -1.25, 0., 0.88388347648318444, 0.88388347648318444, + 0., -1., -1.125, 0., 0., -1.25, 0.79549512883486606, 0.79549512883486606 }; + + double coords3[16]={ + 0.70710678118654757, 0.70710678118654757, 0.88388347648318444, 0.88388347648318444, -1.25, 0., -1., 0., + 0.79549512883486606, 0.79549512883486606, 0., -1.25, -1.125, 0., 0., -1. }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.22089323345553233,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.22089323345553233,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords3,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.22089323345553233,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords3,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.22089323345553233,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNormalize() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-14); + Node *n1=new Node(0.,0.); Node *n4=new Node(0.,-3.); + Node *n2=new Node(10.,0.); Node *n5=new Node(10.,-3.); + Node *n3=new Node(5.,10.); Node *n6=new Node(5.,7.); + EdgeLin *e1_2=new EdgeLin(n1,n2); EdgeLin *e4_5=new EdgeLin(n4,n5); + EdgeLin *e2_3=new EdgeLin(n2,n3); EdgeLin *e5_6=new EdgeLin(n5,n6); + EdgeLin *e3_1=new EdgeLin(n3,n1); EdgeLin *e6_4=new EdgeLin(n6,n4); + // + QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); + QuadraticPolygon pol2; pol2.pushBack(e4_5); pol2.pushBack(e5_6); pol2.pushBack(e6_4); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + double area1Start=pol1.getArea(); + double fact=pol1.normalize(&pol2); + double area1End=pol1.getArea(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(area1Start,area1End*fact*fact,1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(13.,fact,1.e-14); + double area=pol1.intersectWith(pol2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(24.5,area*fact*fact,1e-14); + // + n1=new Node(0.,0.); n4=new Node(0.,-3.); + n2=new Node(10.,0.); n5=new Node(10.,-3.); + n3=new Node(5.,10.); n6=new Node(5.,7.); + e1_2=new EdgeLin(n1,n2); e4_5=new EdgeLin(n4,n5); + e2_3=new EdgeLin(n2,n3); e5_6=new EdgeLin(n5,n6); + e3_1=new EdgeLin(n3,n1); e6_4=new EdgeLin(n6,n4); + QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_1); + QuadraticPolygon pol4; pol4.pushBack(e4_5); pol4.pushBack(e5_6); pol4.pushBack(e6_4); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(24.5,pol3.intersectWithAbs(pol4),1.e-14); + // Ok testing EdgeArcCircle update. + double center[2]={5.,5.}; + double radius=300.; + EdgeArcCircle *e1=buildArcOfCircle(center,radius,M_PI/4.,M_PI/3.); + const Bounds& b=e1->getBounds(); + double x,y,fact2; + fact2=b.getCaracteristicDim(); + b.getBarycenter(x,y); + CPPUNIT_ASSERT_DOUBLES_EQUAL(78.539816339744817,e1->getCurveLength(),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15106.061037591669,e1->getAreaOfZone(),1e-10); + e1->getStartNode()->applySimilarity(x,y,fact2); + e1->getEndNode()->applySimilarity(x,y,fact2); + e1->applySimilarity(x,y,fact2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(62.132034355964237,fact2,1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.2640792652913602,e1->getCurveLength(),1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.034741420428165526,e1->getAreaOfZone(),1e-13); + e1->decrRef(); +} diff --git a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx new file mode 100644 index 000000000..88b70d2e0 --- /dev/null +++ b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx @@ -0,0 +1,1168 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "QuadraticPlanarInterpTest.hxx" +#include "QuadraticPolygon.hxx" +#include "ElementaryEdge.hxx" +#include "EdgeArcCircle.hxx" +#include "EdgeLin.hxx" + +#include +#include +#include +#include + +using namespace std; +using namespace INTERP_KERNEL; + +class DoubleEqual +{ +public: + DoubleEqual(double eps):_eps(eps) { } + bool operator()(double x, double y) { return fabs(x-y)<_eps; } +private: + double _eps; +}; + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0000() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.383022221559489, 0.3213938048432697, -0.5745333323392334, 0.4820907072649046, 0.5745333323392335, 0.4820907072649044, 0.383022221559489, 0.3213938048432696, + -0.4787777769493612, 0.4017422560540872, 4.592273826833915e-17, 0.75, 0.4787777769493612, 0.401742256054087, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + -0.383022221559489, -0.1786061951567303, -0.5745333323392334, -0.01790929273509539, 0.5745333323392335, -0.01790929273509556, 0.383022221559489, -0.1786061951567304, + -0.4787777769493612, -0.0982577439459128, 4.592273826833915e-17, 0.25, 0.4787777769493612, -0.09825774394591297, 3.061515884555943e-17, 0 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0001() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.383022221559489, 0.3213938048432697, -0.5745333323392334, 0.4820907072649046, 0.5745333323392335, 0.4820907072649044, 0.383022221559489, 0.3213938048432696, + -0.4787777769493612, 0.4017422560540872, 4.592273826833915e-17, 0.75, 0.4787777769493612, 0.401742256054087, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + -0.383022221559489, 0.3213938048432697, -0.5745333323392334, 0.4820907072649046, 0.5745333323392335, 0.4820907072649044, 0.383022221559489, 0.3213938048432696, + -0.4787777769493612, 0.4017422560540872, 4.592273826833915e-17, 0.75, 0.4787777769493612, 0.401742256054087, 3.061515884555943e-17, 0.5 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.272708,pol1->intersectWith(*pol2),1.e-6); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.272708,pol2->intersectWith(*pol1),1.e-6); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0002() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.383022221559489, 0.3213938048432697, -0.5745333323392334, 0.4820907072649046, 0.5745333323392335, 0.4820907072649044, 0.383022221559489, 0.3213938048432696, + -0.4787777769493612, 0.4017422560540872, 4.592273826833915e-17, 0.75, 0.4787777769493612, 0.401742256054087, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + -0.4979288880273356, 0.4178119462962507, -0.6128355544951823, 0.5142300877492316, 0.6128355544951825, 0.5142300877492314, 0.4979288880273357, 0.4178119462962505, + -0.555382221261259, 0.4660210170227412, 4.898425415289509e-17, 0.8, 0.5553822212612591, 0.466021017022741, 3.979970649922726e-17, 0.65 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.122173,pol1->intersectWith(*pol2),1.e-6); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.122173,pol2->intersectWith(*pol1),1.e-6); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0003() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.3535533905932737, 0.3535533905932738, -0.5303300858899106, 0.5303300858899107, 0.5303300858899107, 0.5303300858899106, 0.3535533905932738, 0.3535533905932737, + -0.4419417382415922, 0.4419417382415922, 4.592273826833915e-17, 0.75, 0.4419417382415922, 0.4419417382415922, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + -0.4979288880273356, 0.4178119462962507, -0.6128355544951823, 0.5142300877492316, 0.6128355544951825, 0.5142300877492314, 0.4979288880273357, 0.4178119462962505, + -0.555382221261259, 0.4660210170227412, 4.898425415289509e-17, 0.8, 0.5553822212612591, 0.466021017022741, 3.979970649922726e-17, 0.65 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol1->intersectWith(*pol2),1.e-6); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol2->intersectWith(*pol1),1.e-6); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0004() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.4596194077712559, 0.4596194077712559, -0.5303300858899106, 0.5303300858899107, 0.5303300858899107, 0.5303300858899106, 0.4596194077712559, 0.4596194077712559, + -0.4949747468305832, 0.4949747468305833, 4.592273826833915e-17, 0.75, 0.4949747468305833, 0.4949747468305832, 3.979970649922726e-17, 0.65 }; + + double coords2[16]={ + -0.383022221559489, 0.3213938048432697, -0.6128355544951823, 0.5142300877492316, 0.6128355544951825, 0.5142300877492314, 0.383022221559489, 0.3213938048432696, + -0.4979288880273356, 0.4178119462962507, 4.898425415289509e-17, 0.8, 0.4979288880273357, 0.4178119462962505, 3.061515884555943e-17, 0.5 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol1->intersectWith(*pol2),1.e-6); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol2->intersectWith(*pol1),1.e-6); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0005() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.383022221559489, 0.3213938048432697, -0.6128355544951823, 0.5142300877492316, 0.6128355544951825, 0.5142300877492314, 0.383022221559489, 0.3213938048432696, + -0.4979288880273356, 0.4178119462962507, 4.898425415289509e-17, 0.8, 0.4979288880273357, 0.4178119462962505, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + -0.4596194077712559, 0.4596194077712559, -0.5303300858899106, 0.5303300858899107, 0.5303300858899107, 0.5303300858899106, 0.4596194077712559, 0.4596194077712559, + -0.4949747468305832, 0.4949747468305833, 4.592273826833915e-17, 0.75, 0.4949747468305833, 0.4949747468305832, 3.979970649922726e-17, 0.65 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol1->intersectWith(*pol2),1.e-6); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol2->intersectWith(*pol1),1.e-6); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0006() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.383022221559489, 0.3213938048432697, -0.5362311101832845, 0.4499513267805776, 0.5362311101832846, 0.4499513267805774, 0.383022221559489, 0.3213938048432696, + -0.4596266658713867, 0.3856725658119237, 4.28612223837832e-17, 0.7, 0.4596266658713868, 0.3856725658119236, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + -0.1811733315717646, 0.6761480784023478, -0.2070552360820167, 0.7727406610312547, 0.2070552360820166, 0.7727406610312547, 0.1811733315717645, 0.6761480784023478, + -0.1941142838268906, 0.7244443697168013, 4.898425415289509e-17, 0.8, 0.1941142838268906, 0.7244443697168013, 4.28612223837832e-17, 0.7 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + vector val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.366519,0.,0.}; + double test2_res[4]={0.,0.,0.,0.366519}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0007() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.383022221559489, 0.3213938048432697, -0.5362311101832845, 0.4499513267805776, 0.5362311101832846, 0.4499513267805774, 0.383022221559489, 0.3213938048432696, + -0.4596266658713867, 0.3856725658119237, 4.28612223837832e-17, 0.7, 0.4596266658713868, 0.3856725658119236, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + -0.4499513267805775, 0.5362311101832846, -0.5142300877492315, 0.6128355544951825, -0.1389185421335442, 0.7878462024097664, -0.1215537243668512, 0.6893654271085455, + -0.4820907072649045, 0.5745333323392335, -0.3380946093925595, 0.7250462296293201, -0.1302361332501977, 0.738605814759156, -0.2958327832184895, 0.634415450925655 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + vector val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.366519,0.,0.}; + double test2_res[4]={0.,0.,0.,0.366519}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0008() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.383022221559489, 0.3213938048432697, -0.5362311101832845, 0.4499513267805776, 0.5362311101832846, 0.4499513267805774, 0.383022221559489, 0.3213938048432696, + -0.4596266658713867, 0.3856725658119237, 4.28612223837832e-17, 0.7, 0.4596266658713868, 0.3856725658119236, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + -0.6344154509256549, 0.2958327832184896, -0.72504622962932, 0.3380946093925596, -0.4588611490808367, 0.6553216354311937, -0.401503505445732, 0.5734064310022944, + -0.6797308402774874, 0.3169636963055246, -0.6128355544951823, 0.5142300877492316, -0.4301823272632844, 0.614364033216744, -0.5362311101832845, 0.4499513267805776 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + vector val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.18326,0.,0.}; + double test2_res[4]={0.,0.,0.,0.18326}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-5))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-5))); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0009() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.3863703305156274, -0.1035276180410081, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512604, 0.3863703305156274, -0.1035276180410083, + -0.4346666218300808, -0.1164685702961342, 1.416374613080751e-16, 0.5, 0.4346666218300808, -0.1164685702961343, 1.133099690464601e-16, 0.4 }; + double coords2[16]={ + 0.5, -1.224606353822377e-16, 0.6, -1.469527624586853e-16, -0.6, 7.347638122934263e-17, -0.5, 6.123031769111886e-17, + 0.55, -1.347066989204615e-16, -1.102145718440139e-16, -0.6, -0.55, 6.735334946023075e-17, -9.184547653667829e-17, -0.5 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0010() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.3863703305156274, -0.1035276180410081, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512604, 0.3863703305156274, -0.1035276180410083, +-0.4346666218300808, -0.1164685702961342, 1.416374613080751e-16, 0.5, 0.4346666218300808, -0.1164685702961343, 1.133099690464601e-16, 0.4 }; + double coords2[16]={ + 0.4346666218300808, -0.1164685702961343, 0.579555495773441, -0.1552914270615124, -0.579555495773441, -0.1552914270615122, -0.4346666218300808, -0.1164685702961342, +0.5071110588017609, -0.1358799986788234, -1.102145718440139e-16, -0.6, -0.507111058801761, -0.1358799986788232, -8.266092888301047e-17, -0.45 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0011() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.3863703305156274, -0.1035276180410081, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512604, 0.3863703305156274, -0.1035276180410083, +-0.4346666218300808, -0.1164685702961342, 1.416374613080751e-16, 0.5, 0.4346666218300808, -0.1164685702961343, 1.133099690464601e-16, 0.4 }; + double coords2[16]={ + 0.4829629131445342, -0.1294095225512603, 0.579555495773441, -0.1552914270615124, -0.579555495773441, -0.1552914270615122, -0.4829629131445342, -0.1294095225512602, +0.5312592044589877, -0.1423504748063864, -1.102145718440139e-16, -0.6, -0.5312592044589877, -0.1423504748063862, -9.184547653667829e-17, -0.5 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + double val1,val2,val3; + pol1->intersectForPerimeter(*pol2,val1,val2,val3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val1,1.e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val2,1.e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val3,1.e-13); + vector val4,val5; + pol1->intersectForPerimeterAdvanced(*pol2,val4,val5); + double test1_res[4]={0.,0.,0.,0.}; + CPPUNIT_ASSERT(std::equal(val4.begin(),val4.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val5.begin(),val5.end(),test1_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + pol1->intersectForPerimeter(*pol2,val1,val2,val3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val1,1.e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val2,1.e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val3,1.e-13); + val4.clear(); val5.clear(); + pol1->intersectForPerimeterAdvanced(*pol2,val4,val5); + CPPUNIT_ASSERT(std::equal(val4.begin(),val4.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val5.begin(),val5.end(),test1_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar2511() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.3863703305156274, -0.1035276180410081, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512604, 0.3863703305156274, -0.1035276180410083, + -0.4346666218300808, -0.1164685702961342, 1.416374613080751e-16, 0.5, 0.4346666218300808, -0.1164685702961343, 1.133099690464601e-16, 0.4, }; + + double coords2[16]={ + 0.579555495773441, -0.1552914270615124, -0.579555495773441, -0.1552914270615122, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512603, + -1.102145718440139e-16, -0.6, -0.5312592044589877, -0.1423504748063862, -9.184547653667829e-17, -0.5, 0.5312592044589877, -0.1423504748063864, }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + double val1,val2,val3; + pol1->intersectForPerimeter(*pol2,val1,val2,val3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val1,1.e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val2,1.e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val3,1.e-13); + vector val4,val5; + pol1->intersectForPerimeterAdvanced(*pol2,val4,val5); + double test1_res[4]={0.,0.,0.,0.}; + CPPUNIT_ASSERT(std::equal(val4.begin(),val4.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val5.begin(),val5.end(),test1_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + pol1->intersectForPerimeter(*pol2,val1,val2,val3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val1,1.e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val2,1.e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val3,1.e-13); + val4.clear(); val5.clear(); + pol1->intersectForPerimeterAdvanced(*pol2,val4,val5); + CPPUNIT_ASSERT(std::equal(val4.begin(),val4.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val5.begin(),val5.end(),test1_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0012() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, + -1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; + + double coords2[16]={ + 6.123031769111886e-18, 1.85, 1.224606353822377e-17, 1.95, 1.224606353822377e-17, 1.55, 6.123031769111886e-18, 1.65, + 9.18454765366783e-18, 1.9, 0.2, 1.75, 9.18454765366783e-18, 1.6, 0.1, 1.75 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + vector val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.05,0.}; + double test2_res[4]={0.,0.,0.05,0.}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + vector val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,0,1,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0013() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, + -1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; + + double coords2[16]={ + 6.123031769111886e-18, 1.7, 1.224606353822377e-17, 1.8, 1.224606353822377e-17, 1.4, 6.123031769111886e-18, 1.5, + 9.18454765366783e-18, 1.75, 0.2, 1.6, 9.18454765366783e-18, 1.45, 0.1, 1.6 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + vector val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.1,0.}; + double test2_res[4]={0.,0.,0.1,0.}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + vector val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,0,2,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0014() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, +-1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; + double coords2[16]={ + 6.123031769111886e-18, 1.55, 1.224606353822377e-17, 1.65, 1.224606353822377e-17, 1.25, 6.123031769111886e-18, 1.35, +9.18454765366783e-18, 1.6, 0.2, 1.45, 9.18454765366783e-18, 1.3, 0.1, 1.45 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + vector val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.15,0.}; + double test2_res[4]={0.05,0.,0.1,0.}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + vector val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,0,3,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0015() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, +-1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; + double coords2[16]={ + 6.123031769111886e-18, 1.4, 1.224606353822377e-17, 1.5, 1.224606353822377e-17, 1.1, 6.123031769111886e-18, 1.2, +9.18454765366783e-18, 1.45, 0.2, 1.3, 9.18454765366783e-18, 1.15, 0.1, 1.3 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + vector val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.2,0.}; + double test2_res[4]={0.1,0.,0.1,0.}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + vector val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,0,4,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0016() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, +-1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; + double coords2[16]={ + 6.123031769111886e-18, 1.25, 1.224606353822377e-17, 1.35, 1.224606353822377e-17, 0.95, 6.123031769111886e-18, 1.05, +9.18454765366783e-18, 1.3, 0.2, 1.15, 9.18454765366783e-18, 0.9999999999999999, 0.1, 1.15 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + vector val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.15,0.}; + double test2_res[4]={0.1,0.,0.05,0.}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + vector val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,0,3,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0017() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, + -1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; + + double coords2[16]={ + 6.123031769111886e-18, 1.1, 1.224606353822377e-17, 1.2, 1.224606353822377e-17, 0.8, 6.123031769111886e-18, 0.9, + 9.18454765366783e-18, 1.15, 0.2, 1, 9.18454765366783e-18, 0.85, 0.1, 1 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + vector val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.1,0.}; + double test2_res[4]={0.1,0.,0.,0.}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + vector val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,0,2,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0018() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, + -1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; + + double coords2[16]={ + 6.123031769111886e-18, 0.95, 1.224606353822377e-17, 1.05, 1.224606353822377e-17, 0.6499999999999999, 6.123031769111886e-18, 0.75, + 9.18454765366783e-18, 1, 0.2, 0.85, 9.18454765366783e-18, 0.7, 0.1, 0.85 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + vector val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.05,0.}; + double test2_res[4]={0.05,0.,0.,0.}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + vector val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,0,1,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0019() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, + -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + 0.9500000000000001, 1.836909530733566e-17, 0.8, 3.673819061467131e-17, 1.4, 0, 1.25, 0, + 0.8750000000000001, 2.755364296100349e-17, 1.1, 0.3, 1.325, 0, 1.1, 0.15 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0020() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, + -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + 0.05000000000000002, 1.836909530733566e-17, -0.09999999999999998, 3.673819061467131e-17, 0.5, 0, 0.35, 0, + -0.02499999999999997, 2.755364296100349e-17, 0.2, 0.3, 0.425, 0, 0.2, 0.15 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + vector val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.,0.}; + double test2_res[4]={0.,0.,0.,0.}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); + delete pol1; + delete pol2; + vector val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,0,0,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0021() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, + -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + -1, -0.07999999999999999, -1.15, -0.07999999999999996, -0.55, -0.08, -0.7, -0.08, + -1.075, -0.07999999999999997, -0.85, 0.22, -0.625, -0.08, -0.85, 0.06999999999999999 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0311485,pol1->intersectWith(*pol2),1.e-7); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0311485,pol2->intersectWith(*pol1),1.e-7); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + vector val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.162251,0.151523,0.,0.}; + double test2_res[4]={0.,0.311383,0.,0.0978193}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); + delete pol1; + delete pol2; + vector val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={2,2,0,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} +void QuadraticPlanarInterpTest::checkNonRegressionOmar0022() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, + -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + 0.15, -0.07999999999999999, 0, -0.07999999999999996, 0.6, -0.08, 0.45, -0.08, + 0.07500000000000001, -0.07999999999999997, 0.3, 0.22, 0.5249999999999999, -0.08, 0.3, 0.06999999999999999 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00902229,pol1->intersectWith(*pol2),1.e-8); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00902229,pol2->intersectWith(*pol1),1.e-8); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0023() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, + -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5, }; + + double coords2[16]={ + 0.4156854249492381, 0.5656854249492381, 0.2656854249492381, 0.5656854249492381, 0.8656854249492381, 0.5656854249492381, 0.7156854249492381, 0.5656854249492381, + 0.3406854249492381, 0.5656854249492381, 0.5656854249492381, 0.8656854249492381, 0.7906854249492381, 0.5656854249492381, 0.5656854249492381, 0.7156854249492381 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0215659,pol1->intersectWith(*pol2),1.e-7); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0215659,pol2->intersectWith(*pol1),1.e-7); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0024() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, +-0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; + double coords2[16]={ + 0.5656854249492381, 0.5656854249492381, 0.4156854249492382, 0.5656854249492381, 1.015685424949238, 0.5656854249492381, 0.8656854249492382, 0.5656854249492381, +0.4906854249492382, 0.5656854249492381, 0.7156854249492381, 0.8656854249492381, 0.9406854249492381, 0.5656854249492381, 0.7156854249492381, 0.7156854249492381 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00877657,pol1->intersectWith(*pol2),1.e-8); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00877657,pol2->intersectWith(*pol1),1.e-8); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar2524() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, +-0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; + double coords2[16]={ + 0.4156854249492382, 0.5656854249492381, 1.015685424949238, 0.5656854249492381, 0.8656854249492382, 0.5656854249492381, 0.5656854249492381, 0.5656854249492381, +0.7156854249492381, 0.8656854249492381, 0.9406854249492381, 0.5656854249492381, 0.7156854249492381, 0.7156854249492381, 0.4906854249492382, 0.5656854249492381 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00877657,pol1->intersectWith(*pol2),1.e-8); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00877657,pol2->intersectWith(*pol1),1.e-8); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0025() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, + -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + 0.715685424949238, 0.5656854249492381, 0.565685424949238, 0.5656854249492381, 1.165685424949238, 0.5656854249492381, 1.015685424949238, 0.5656854249492381, + 0.6406854249492381, 0.5656854249492381, 0.8656854249492381, 0.8656854249492381, 1.090685424949238, 0.5656854249492381, 0.8656854249492381, 0.7156854249492381 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + // + vector val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,1,0,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0026() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, + -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; + + double coords2[16]={ + 0.1, 0.95, 0.2, 0.95, -0.2, 0.95, -0.1, 0.95, + 0.15, 0.95, 1.224606353822377e-17, 0.75, -0.15, 0.95, 6.123031769111886e-18, 0.85 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + // + vector val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,1,0,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0027() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, + -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; + + double coords2[16]={ + -0.1, 0.7, -0.2, 0.7, 0.2, 0.7, 0.1, 0.7, + -0.15, 0.7, 1.224606353822377e-17, 0.8999999999999999, 0.15, 0.7, 6.123031769111886e-18, 0.7999999999999999 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00712309,pol1->intersectWith(*pol2),1.e-8); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00712309,pol2->intersectWith(*pol1),1.e-8); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + vector val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.222704,0.,0.}; + double test2_res[4]={0.1,0.0465335,0.1,0.092554}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); + delete pol1; + delete pol2; + vector val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,4,0,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0028() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, + -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; + + double coords2[16]={ + -0.07071067811865477, 0.4792893218813453, -0.1414213562373095, 0.4085786437626905, 0.1414213562373095, 0.6914213562373095, 0.07071067811865477, 0.6207106781186548, + -0.1060660171779822, 0.4439339828220179, -0.1414213562373095, 0.6914213562373096, 0.1060660171779822, 0.6560660171779822, -0.07071067811865475, 0.6207106781186548 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0471239,pol1->intersectWith(*pol2),1.e-7); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0471239,pol2->intersectWith(*pol1),1.e-7); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + vector val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.,0.}; + double test2_res[4]={0.1,0.628319,0.1,0.314159}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); + delete pol1; + delete pol2; + vector val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,1,0,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0029() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, + -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; + + double coords2[16]={ + -0.07071067811865477, 0.1292893218813453, -0.1414213562373095, 0.05857864376269051, 0.1414213562373095, 0.3414213562373095, 0.07071067811865477, 0.2707106781186548, + -0.1060660171779822, 0.09393398282201787, -0.1414213562373095, 0.3414213562373095, 0.1060660171779822, 0.3060660171779822, -0.07071067811865475, 0.2707106781186548 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + vector val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.,0.}; + double test2_res[4]={0.,0.,0.,0.}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + vector val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,0,0,1}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0030() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, + -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; + + double coords2[16]={ + -0.4889087296526012, 0.3889087296526012, -0.5889087296526012, 0.3889087296526012, -0.1889087296526012, 0.3889087296526012, -0.2889087296526012, 0.3889087296526012, + -0.5389087296526012, 0.3889087296526012, -0.3889087296526012, 0.5889087296526012, -0.2389087296526012, 0.3889087296526012, -0.3889087296526012, 0.4889087296526012 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0471239,pol1->intersectWith(*pol2),1.e-7); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0471239,pol2->intersectWith(*pol1),1.e-7); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + vector val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.,0.}; + double test2_res[4]={0.1,0.628319,0.1,0.314159}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); + delete pol1; + delete pol2; + vector val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,1,0,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} diff --git a/src/INTERP_KERNELTest/RemapperTest.cxx b/src/INTERP_KERNELTest/RemapperTest.cxx new file mode 100644 index 000000000..2e361c12f --- /dev/null +++ b/src/INTERP_KERNELTest/RemapperTest.cxx @@ -0,0 +1,96 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "RemapperTest.hxx" +#include "Remapper.hxx" + +#include +#include + +namespace INTERP_TEST +{ + + + void RemapperTest::setUp() + { + } + + + void RemapperTest::tearDown() + { + } + + /** + * Test that creates a tree in 2D and check that + * the results are correct in three + * cases : + * a non matching search + * a standard case + * a bbox overlapping the bboxes of the tree + */ + void RemapperTest::test_Remapper() { + string sourcename=getenv("MED_ROOT_DIR"); + sourcename +="/share/salome/resources/med/square1.med"; + MEDMEM::MESH source_mesh (MED_DRIVER,sourcename,"Mesh_2"); + + string targetname=getenv("MED_ROOT_DIR"); + targetname +="/share/salome/resources/med/square2.med"; + MEDMEM::MESH target_mesh (MED_DRIVER,targetname,"Mesh_3"); + + MEDMEM::SUPPORT source_support(&source_mesh,"on All support"); + MEDMEM::FIELD source_field(&source_support,1); + double* value=const_cast(source_field.getValue()); + for (int i=0; i target_field(&target_support,1); + double* targetvalue=const_cast(target_field.getValue()); + for (int i=0; i *source_areas=source_mesh.getArea(&source_support); + MEDMEM::FIELD *target_areas=target_mesh.getArea(&target_support); + absField(*source_areas); //absolute value + absField(*target_areas); //absolute value + + //target square is in reverse order as compared to initial square + double source_integral=source_field.normL2(1,source_areas); + double target_integral=target_field.normL2(1,target_areas); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(source_integral,target_integral,1e-10); + delete source_areas; + delete target_areas; + + } + + void RemapperTest::absField(MEDMEM::FIELD& field) + { + double* areas=const_cast(field.getValue()); + for (int i=0; i< field.getNumberOfValues();i++) + { + areas[i]=fabs(areas[i]); + } + } + +} diff --git a/src/INTERP_KERNELTest/RemapperTest.hxx b/src/INTERP_KERNELTest/RemapperTest.hxx new file mode 100644 index 000000000..bd58b533b --- /dev/null +++ b/src/INTERP_KERNELTest/RemapperTest.hxx @@ -0,0 +1,60 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TU_REMAPPER_HXX__ +#define __TU_REMAPPER_HXX__ + +#include +#include "Remapper.hxx" +#include "MEDMEM_Field.hxx" + +namespace INTERP_TEST +{ + + /** + * \brief Test suite testing some of the low level methods of TransformedTriangle. + * + */ + class RemapperTest : public CppUnit::TestFixture + { + + CPPUNIT_TEST_SUITE( RemapperTest ); + CPPUNIT_TEST( test_Remapper ); + CPPUNIT_TEST_SUITE_END(); + + + public: + void setUp(); + + void tearDown(); + + // tests + void test_Remapper(); + + private: + void absField(MEDMEM::FIELD&); + }; + + + + +} + + + +#endif diff --git a/src/INTERP_KERNELTest/SingleElementPlanarTests.cxx b/src/INTERP_KERNELTest/SingleElementPlanarTests.cxx new file mode 100644 index 000000000..89f2b5689 --- /dev/null +++ b/src/INTERP_KERNELTest/SingleElementPlanarTests.cxx @@ -0,0 +1,1045 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "SingleElementPlanarTests.hxx" +#include "InterpolationUtils.hxx" +#include "PolygonAlgorithms.hxx" +#include "PolygonAlgorithms.txx" +#include "InterpolationPlanarTestSuite.hxx" +#include + +using namespace INTERP_KERNEL; + +namespace INTERP_TEST +{ + const double _Epsilon = 1.e-12; + const double _Precision = 1.e-12; + const double _losange1[8] = { 1,0, 0,1, -1,0, 0,-1 }; + const double _losange2[8] = { 2,0, 1,1, 0,0, 1,-1 }; + const double _losange3[8] = {2.5,0.5,1.5,1.5,0.5,0.5,1.5,-0.5 }; + const double _square1[8] = { -1,-1, -1,1, 1,1, 1,-1}; + const double _square2[8] = {1,-0.25,0,-0.25,0,0.25,1,0.25 }; + const double _losange4[8] = { 3,0, 2,1, 1,0, 2,-1 }; + const double _losange5[8] = { 1.5,0, 0,1.5,-1.5,0, 0,-1.5 }; + const double _losange6[12]= { 2,0, 1,1, 0.5,0.5,0,0, 0.5,-0.5, 1,-1 }; + const double _losange7[10]= { 1,0, 0,1, -1,0, 0,-1, 0.5,-0.5 }; + const double _square3[10] = { -1,-1, -1,1, 0.5,1, 1,1, 1,-1, }; + const double _square4[8] = {-0.5,-1,-0.5,1,1.5,1,1.5,-1 }; + const double _square5[10] = { -1,-1, -1,1, 0,1, 1,1, 1,-1 }; + const double _losange8[8] = { 0,1, 1,-1, 0,-1.5,-0.5,-1 }; + const double _losange9[8] = {0.5,0, 0,1, -1.5,0, 0,-1 }; + const double _hexagon1[12]= { -2,0, -1,-1, 1,-1, 2,0, 1,1, -1,1 }; + const double _hexagon2[12]= {-1.5,0.5,-1,-1, 1,-1, 2,1, 1,1, -1,1 }; + const double _hexagon3[12]= { -2,2, -1,1, 1,1, 2,2, 1,3, -1,3 }; + const double _square6[8] = { -1,1, -1,3, 0.5,3,0.5,1 }; + const double _losange10[8]= { 0,-1, 1,-2, 0,-3, -1,-2 }; + const double _triangle1[6]= {0.5,0, 1,1, 0,1 }; + const double _triangle2[6]= { 0,0.5, 0,-0.5,1.5,0 }; + const double _triangle3[9]= {-1,2,0, 1,2,0, 0,2,1 }; + const double _triangle4[9]= {1./2,2,0, 1, 2, 1, 1, 2, 0.5 }; + const double _parallel1[8] = {-1,0, -0.5,1, 0.5,1, 0,0}; + const double _parallel2[8]= {-0.5,1, 0,0, 1.,0, 0.5,1 }; + const double _parallel3[8]= {-0.5,-1, 0,0, 1,0, 0.5,-1}; + const double _triangle5[6]= { 0,0, 0,0.5, 0.5,0.5 }; + const double _triangle6[6]= { 1./3,1./3, 1./3,2./3, 2./3,2./3 }; + const double _triangle7[6]= {0.5,2, 1,1, 0,1 }; + const double _triangle8[6]= {22.4601,35.2129, 13.9921,34.693, 18.2853,26.2812 }; + const double _triangle9[6]= {13.9921,34.693, 22.4601,35.2129, 18.2785,42.3869 }; + const double _triangle10[6]= {84.8575,98.2042, 80,100, 82.2601,95.7202}; + const double _triangle11[6]= {80,100, 76.6659,91.9804, 85.3912,92.5061 }; + + // Two diamonds intersecting without degeneracy (two distinct crossing points) + // /\ /\ + // / \/ \ + // / /\ \ + // / / \ \ + // \ \ / / + // \ \/ / + // \ /\ / + // \/ \/ + + + // \brief Status : pass + void SingleElementPlanarTests::diamondsBasic() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange2,4,4); + deque< double > expected_result; + + expected_result.push_back(0.5);expected_result.push_back(-0.5); + expected_result.push_back(0);expected_result.push_back(0); + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(1);expected_result.push_back(0); + + CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + + void SingleElementPlanarTests::diamondsBasic_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange2,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + expected_result.push_back(1);expected_result.push_back(0); + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(0);expected_result.push_back(0); + expected_result.push_back(0.5);expected_result.push_back(-0.5); + + CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + + + // Two diamonds with overlapping edges in an exclusion configuration + // /\ + // / \ + // /\ / \ + // / \/ \ + // / \ / + // / \ / + // \ /\ / + // \ / \/ + // \ / + // \/ + // \brief Status : pass + void SingleElementPlanarTests::tangentDiamonds() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange3,4,4); + deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Diamond exclusion tangency test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::tangentDiamonds_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange3,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(1);expected_result.push_back(0); + + CPPUNIT_ASSERT_MESSAGE("Diamond exclusion tangency test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two tangent squares with overlapping edges, in an inclusion configuration + // _____________ + // | | + // | _______| + // | | | + // | |_______| + // | | + // |_____________| + + // \brief Status : pass + void SingleElementPlanarTests::tangentSquares() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_square2,4,4); + deque< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(0.25); + expected_result.push_back(0.);expected_result.push_back(-0.25); + expected_result.push_back(1.);expected_result.push_back(-0.25); + expected_result.push_back(1.);expected_result.push_back(0.25); + + CPPUNIT_ASSERT_MESSAGE("Squares inclusion tangency test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::tangentSquares_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square1,_square2,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(0.25); + expected_result.push_back(0.25);expected_result.push_back(0.25); + expected_result.push_back(1./6);expected_result.push_back(1./6); + expected_result.push_back(0.);expected_result.push_back(0.25); + expected_result.push_back(0.);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(-0.25); + expected_result.push_back(1.);expected_result.push_back(-0.25); + + CPPUNIT_ASSERT_MESSAGE("Squares inclusion tangency test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two diamonds sharing a vertex in an exclusion configuration + // /\ /\ + // / \ / \ + // / \ / \ + // / \/ \ + // \ /\ / + // \ / \ / + // \ / \ / + // \/ \/ + + + // \brief Status : pass + void SingleElementPlanarTests::diamondsSharingVertex1() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange4,4,4); + deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Diamond sharing (1) vertex test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::diamondsSharingVertex1_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange4,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + expected_result.push_back(1.);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Diamonds sharing (1) vertex test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two identical squares + // _____________ + // | | + // | | + // | | + // | | + // | | + // |_____________| + + // \brief Status : pass + void SingleElementPlanarTests::identicalSquares() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_square1,4,4); + deque< double > expected_result; + + expected_result.push_back(-1.);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::identicalSquares_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square1,_square1,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-1.); + + CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + // Square and diamond intersecting with no degeneracy + // /\ + // / \ + // / \ + // __/______\__ + // | / \ | + // |/ \| + // / \ + // /| |\ + // \| |/ + // \ / + // |\ /| + // |_\________/_| + // \ / + // \ / + // \ / + // \/ + // \brief Status : pass + void SingleElementPlanarTests::squareAndDiamondBasic() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_losange5,4,4); + deque< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(0.5); + expected_result.push_back(0.5);expected_result.push_back(1.); + expected_result.push_back(-0.5);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(0.5); + expected_result.push_back(-1.);expected_result.push_back(-0.5); + expected_result.push_back(-0.5);expected_result.push_back(-1.); + expected_result.push_back(0.5);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-0.5); + + CPPUNIT_ASSERT_MESSAGE("Square and diamond basic test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::squareAndDiamondBasic_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square1,_losange5,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(0.); + expected_result.push_back(1.);expected_result.push_back(0.5); + expected_result.push_back(0.75);expected_result.push_back(0.75); + expected_result.push_back(0.5);expected_result.push_back(1.); + expected_result.push_back(0.);expected_result.push_back(0.); + expected_result.push_back(-0.5);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(0.5); + expected_result.push_back(-1.);expected_result.push_back(0.); + expected_result.push_back(-1.);expected_result.push_back(-0.5); + expected_result.push_back(-0.75);expected_result.push_back(-0.75); + expected_result.push_back(-0.5);expected_result.push_back(-1.); + expected_result.push_back(0.5);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-0.5); + + + CPPUNIT_ASSERT_MESSAGE("Square and diamond basic test failed (TRIANGULATION), maybe not significant (0,0) should be removed", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + // square and diamond intersecting at four degenerated pointss + // ______ + // | /\ | + // | / \ | + // |/ \| + // |\ /| + // | \ / | + // |__\/__| + // \brief Status : pass + + void SingleElementPlanarTests::squareAndDiamondCritical() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_losange1,4,4); + deque< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(-1.); + expected_result.push_back(-1.);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(1.);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Square and diamond critical tangency test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::squareAndDiamondCritical_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square1,_losange1,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(0);expected_result.push_back(0); + expected_result.push_back(-1.);expected_result.push_back(0.); + expected_result.push_back(-0.5);expected_result.push_back(-0.5); + expected_result.push_back(0.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Square and diamond basic test failed (TRIANGULATION) maybe not significant (0,0) should be removed", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + // Two diamonds intersecting at one vertex on edge and one double vertex + // /\ /\ + // / \ / \ + // / ¤ \ + // / / \ \ + // \ \ / / + // \ * / + // \ / \ / + // \/ \/ + + + // \brief Status : pass + void SingleElementPlanarTests::diamondsCritical() + { + + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_losange6,_losange7,6,5); + deque< double > expected_result; + + expected_result.push_back(0.5);expected_result.push_back(-0.5); + expected_result.push_back(0.5);expected_result.push_back(-0.5); + expected_result.push_back(0);expected_result.push_back(0); + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(1);expected_result.push_back(0); + + CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::diamondsCritical_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange6,_losange7,6,5,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(1);expected_result.push_back(0); + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(0);expected_result.push_back(0); + expected_result.push_back(0.5);expected_result.push_back(-0.5); + + CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two tangent squares with starting and ending vertices on edges + // _____ ___.___ ______ + // | | | | + // | | | | + // | | | | + // | | | | + // | | | | + // |_____|_______|______| + + // \brief Status : pass + void SingleElementPlanarTests::quadranglesCritical() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_square4,_square3,4,5); + deque< double > expected_result; + + expected_result.push_back(-0.5);expected_result.push_back(1.); + expected_result.push_back(-0.5);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("Critical quadrangles with tangency test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::quadranglesCritical_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square4,_square3,4,5,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(0.5); + expected_result.push_back(1.);expected_result.push_back(1.); + expected_result.push_back(0.5);expected_result.push_back(1.); + expected_result.push_back(-0.5);expected_result.push_back(1.); + expected_result.push_back(-0.5);expected_result.push_back(-1./3); + expected_result.push_back(-0.5);expected_result.push_back(-0.5); + expected_result.push_back(-0.5);expected_result.push_back(-1.); + + CPPUNIT_ASSERT_MESSAGE("Critical quadrangles with tangency test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + + + // square and diamond crossing and tangency at double vertices, starting vertex on edge + // _____.____ + // | / \ | + // | / \ | + // | / \ | + // |_/_______\| + // \ / + // \ / + // \ / + // \ / + // \brief Status : pass + void SingleElementPlanarTests::quadrangleAndDiamondCritical() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_square5,_losange8,5,4); + deque< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(-0.5);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-1.); + + CPPUNIT_ASSERT_MESSAGE("Square and diamond critical tangency test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::quadrangleAndDiamondCritical_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square5,_losange8,5,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(1./3);expected_result.push_back(1./3); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(0.);expected_result.push_back(0.); + expected_result.push_back(-1./3);expected_result.push_back(-1./3); + expected_result.push_back(-0.5);expected_result.push_back(-1.); + expected_result.push_back(0.);expected_result.push_back(-1.); + + CPPUNIT_ASSERT_MESSAGE("Square and diamond critical tangency test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } // square and diamond intersecting at four degenerated pointss + // + // ²/²\ + // ² / ² \ + // ² / ² \ + // ² \ ² / + // ² \ ² / + // ²\²/ + // \brief Status : pass + + void SingleElementPlanarTests::diamondsCritical2() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange9,4,4); + deque< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(-1.); + expected_result.push_back(0.);expected_result.push_back(-1.); + expected_result.push_back(-1.);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(0.5);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Diamonds with crossing at double vertex test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::diamondsCritical2_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange9,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(-1.); + expected_result.push_back(0.5);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Diamonds with crossing at double vertex test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two tangent hexagons with double vertices and a critical starting vertex on edge + // _________ + // / \²²² + // ² \² + // / \ + // / ² ² \ + // \ / + // \ ² ² / + // \ / + // \²_______²/ + + + // \brief Status : pass + void SingleElementPlanarTests::hexagonsCritical1() + { + + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_hexagon1,_hexagon2,6,6); + deque< double > expected_result; + + expected_result.push_back(5./3);expected_result.push_back(1./3); + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(-1.);expected_result.push_back(-1.); + expected_result.push_back(-1.5);expected_result.push_back(0.5); + expected_result.push_back(-1.);expected_result.push_back(1.); + expected_result.push_back(1.);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("First hexagon critical crossing test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::hexagonsCritical1_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_hexagon1,_hexagon2,6,6,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(-1.);expected_result.push_back(1.); + expected_result.push_back(-1.5);expected_result.push_back(0.5); + expected_result.push_back(-8./7);expected_result.push_back(2./7); + expected_result.push_back(-1.4);expected_result.push_back(0.2); + expected_result.push_back(-4./3);expected_result.push_back(0.); + expected_result.push_back(-2./3);expected_result.push_back(0.); + expected_result.push_back(-1.25);expected_result.push_back(-0.25); + expected_result.push_back(-1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(1.5);expected_result.push_back(0.); + expected_result.push_back(5./3);expected_result.push_back(1./3); + expected_result.push_back(1.125);expected_result.push_back(0.875); + expected_result.push_back(1.);expected_result.push_back(1.); + expected_result.push_back(0.25);expected_result.push_back(0.75); + + CPPUNIT_ASSERT_MESSAGE("First hexagon critical crossing test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two tangent hexagons with double vertices and a critical starting vertex on edge + // _______ + // / \ + // / \ + // \ / + // \_______/ + // / \ + // / \ + // \ / + // \_______/ + + + // \brief Status : pass + void SingleElementPlanarTests::hexagonsCritical2() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_hexagon1,_hexagon3,6,6); + deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Second hexagon critical crossing test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::hexagonsCritical2_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_hexagon1,_hexagon3,6,6,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + expected_result.push_back(1.);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("Second hexagon critical crossing test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Square and quadrilateron with outer tangency + // ________ + // | | + // | | + // | | + // |________|___ + // | | + // | | + // | | + // | | + // | | + // |____________| + + // \brief Status : pass + void SingleElementPlanarTests::squareAndQuadrangleCritical() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_square6,4,4); + deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (CONVEX)", (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::squareAndQuadrangleCritical_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square1,_square6,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + expected_result.push_back(-1.);expected_result.push_back(1.); + expected_result.push_back(0.5);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + // Two diamonds sharing a vertex in an exclusion configuration + // /\ + // / \ + // / \ + // / \ + // \ / + // \ / + // \ / + // \/ + // /\ + // / \ + // / \ + // / \ + // \ / + // \ / + // \ / + // \/ + + + // \brief Status : pass + void SingleElementPlanarTests:: diamondsSharingVertex2() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange10,4,4); + deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Diamond sharing vertex (2) test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests:: diamondsSharingVertex2_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange10,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + expected_result.push_back(0.);expected_result.push_back(-1.); + + CPPUNIT_ASSERT_MESSAGE("Diamond sharing vertex (2) test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Triangle and diamond with a critical crossing at double starting vertex + // ____ + // /|\ / + // / | \/ + // / | /\ + // / |/ \ + // \ / + // \ / + // \ / + // \ / + + // \brief Status : pass + void SingleElementPlanarTests:: triangleAndDiamondCritical() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_triangle1,4,3); + deque< double > expected_result; + + expected_result.push_back(2./3);expected_result.push_back(1./3); + expected_result.push_back(0.5);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("Triangle and diamonds critical test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests:: triangleAndDiamondCritical_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_triangle1,4,3,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(2./3);expected_result.push_back(1./3); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(0.5);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Triangle and diamonds critical test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Basic triangle and square intersection (two distinct points) + // __________ + // | | + // | |\ | + // | | \| + // | | \ + // | | |\ + // | | |/ + // | | / + // | | /| + // | |/ | + // |__________| + + // \brief Status : pass + void SingleElementPlanarTests::triangleAndSquareBasic() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_triangle2,4,3); + deque< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(1./6); + expected_result.push_back(1.);expected_result.push_back(-1./6); + expected_result.push_back(0.);expected_result.push_back(-0.5); + expected_result.push_back(0.);expected_result.push_back(0.5); + + CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + + void SingleElementPlanarTests::triangleAndSquareBasic_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square1,_triangle2,4,3,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(1./6); + expected_result.push_back(0.375);expected_result.push_back(0.375); + expected_result.push_back(0.);expected_result.push_back(0.5); + expected_result.push_back(0.);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(-0.5); + expected_result.push_back(1.);expected_result.push_back(-1./6); + + CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + // Two triangles with a starting vertex on edge + + // /\ ²²²² + // / ² ² + // / ² ² + // /__²___\ + + // \brief Status : pass + void SingleElementPlanarTests::trianglesCritical() + { + INTERP_KERNEL::PolygonAlgorithms<3> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_triangle3,_triangle4,3,3); + deque< double > expected_result; + + expected_result.push_back(2./3);expected_result.push_back(2.);expected_result.push_back(1./3); + expected_result.push_back(0.5);expected_result.push_back(2.);expected_result.push_back(0.); + expected_result.push_back(0.75);expected_result.push_back(2.);expected_result.push_back(0.25); + + CPPUNIT_ASSERT_MESSAGE("Triangles critical test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,3>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::trianglesCritical_Triangulation() + { + vector< double > actual_result; + double _triangle3rotated[6],_triangle4rotated[6]; + for (int i=0; i<3; i++)_triangle3rotated[2*i] = _triangle3[3*i]; + for (int i=0; i<3; i++)_triangle3rotated[2*i+1] = _triangle3[3*i+2]; + for (int i=0; i<3; i++)_triangle4rotated[2*i] = _triangle4[3*i]; + for (int i=0; i<3; i++)_triangle4rotated[2*i+1] = _triangle4[3*i+2]; + + INTERP_KERNEL::intersec_de_polygone<2>(_triangle3rotated,_triangle4rotated,3,3,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(0.5);expected_result.push_back(0.); + expected_result.push_back(2./3);expected_result.push_back(1./3); + expected_result.push_back(0.75);expected_result.push_back(0.25); + + CPPUNIT_ASSERT_MESSAGE("Triangles critical test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two tangent paralellograms intersecting at 3 double vertices (one being a starting vertex) + // _______ + // /\ /\ + // / \ / \ + // / \ / \ + // /______\/______\ + + + // \brief Status : pass + void SingleElementPlanarTests::paralellogramsCritical1() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_parallel1,_parallel2,4,4); + deque< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(0.); + expected_result.push_back(-0.5);expected_result.push_back(1.); + expected_result.push_back(0.5);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test (1) failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::paralellogramsCritical1_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_parallel1,_parallel2,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(0.25);expected_result.push_back(0.5); + expected_result.push_back(0.5);expected_result.push_back(1.); + expected_result.push_back(0.);expected_result.push_back(2./3); + expected_result.push_back(-0.5);expected_result.push_back(1.); + expected_result.push_back(-0.25);expected_result.push_back(0.5); + expected_result.push_back(0.);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test (1) failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two paralellograms sharing a vertex in an exclusion configuration + // ________ + // / / + // / / + // / / + // /_______/_______ + // / / + // / / + // / / + // /_______/ + + + // \brief Status : pass + void SingleElementPlanarTests::paralellogramsCritical2() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_parallel1,_parallel3,4,4); + deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::paralellogramsCritical2_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_parallel1,_parallel3,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two triangles in a tangency configuration with a starting vertex on edge + + // _____ + // | / + // __|___/ + // | | / + // | | / + // | |/ + // | / + // | / + // |/ + + // \brief Status : pass + void SingleElementPlanarTests::trianglesTangencyCritical() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_triangle5,_triangle6,3,3); + deque< double > expected_result; + + expected_result.push_back(1./3);expected_result.push_back(1./2); + expected_result.push_back(1./3);expected_result.push_back(1./3); + expected_result.push_back(1./2);expected_result.push_back(1./2); + + CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::trianglesTangencyCritical_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_triangle5,_triangle6,3,3,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + + expected_result.push_back(1./3);expected_result.push_back(1./2); + expected_result.push_back(1./2);expected_result.push_back(1./2); + expected_result.push_back(1./3);expected_result.push_back(1./3); + + CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two triangles with double starting point in an outer tangency configuration + // /\ + // / \ + // / \ + // /______\ + // \ / + // \ / + // \ / + // \/ + + + // \brief Status : pass + void SingleElementPlanarTests::trianglesTangencyCritical2() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_triangle1,_triangle7,3,3); + deque< double > expected_result; + + // if(!checkDequesEqual(actual_result,expected_result, _Epsilon)) + // { + // cerr<< "CPP_UNIT expected result= " << endl; + // dequePrintOut(expected_result); + // cerr<< "CPP_UNIT actual result= " << endl; + // dequePrintOut(actual_result); + // } + + CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (2) test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::trianglesTangencyCritical2_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_triangle1,_triangle7,3,3,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + expected_result.push_back(1.);expected_result.push_back(1.); + expected_result.push_back(0.);expected_result.push_back(1.); + + // if(!checkVectorsEqual(actual_result,expected_result, _Epsilon)) + // { + // cerr<< "CPP_UNIT expected result= " << endl; + // vectPrintOut(expected_result); + // cerr<< "CPP_UNIT actual result= " << endl; + // vectPrintOut(actual_result); + // } + + CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (2) test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + // \brief Status : pass + void SingleElementPlanarTests::trianglesTangencyCritical3() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_triangle8,_triangle9,3,3); + deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (3) test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::trianglesTangencyCritical3_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_triangle8,_triangle9,3,3,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + expected_result.push_back(22.4601);expected_result.push_back(35.2129); + expected_result.push_back(13.9921);expected_result.push_back(34.693); + + CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (3) test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::trianglesTangencyCritical4() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + deque< double > actual_result = intersector.intersectConvexPolygons(_triangle10,_triangle11,3,3); + + deque< double > expected_result; + expected_result.push_back(82.745193090443536);expected_result.push_back(96.184114390029166); + expected_result.push_back(82.260099999999994);expected_result.push_back(95.720200000000006); + expected_result.push_back(80);expected_result.push_back(100.); + + + CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (4) test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::trianglesTangencyCritical4_Triangulation() + { + vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_triangle10,_triangle11,3,3,actual_result,_Epsilon/_Precision, _Precision ); + + vector< double > expected_result; + expected_result.push_back(80);expected_result.push_back(100.); + expected_result.push_back(82.745193090443536);expected_result.push_back(96.184114390029166); + expected_result.push_back(82.260099999999994);expected_result.push_back(95.720200000000006); + + CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (4) test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); + } + +} diff --git a/src/INTERP_KERNELTest/SingleElementPlanarTests.hxx b/src/INTERP_KERNELTest/SingleElementPlanarTests.hxx new file mode 100644 index 000000000..ad0a420cd --- /dev/null +++ b/src/INTERP_KERNELTest/SingleElementPlanarTests.hxx @@ -0,0 +1,138 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __SINGLE_ELEMENT_PLANAR_TESTS_HXX_ +#define __SINGLE_ELEMENT_PLANAR_TESTS_HXX_ + +#include "InterpolationPlanarTestSuite.hxx" + +namespace INTERP_TEST +{ + /** + * \brief Class testing algorithm by intersecting simple meshes having only one planar element each. + * This serves mainly to verify that the volume calculations between elements is correct. + * + */ + class SingleElementPlanarTests : public InterpolationPlanarTestSuite + { + CPPUNIT_TEST_SUITE( SingleElementPlanarTests ); + + CPPUNIT_TEST( diamondsBasic ); + CPPUNIT_TEST( tangentDiamonds ); + CPPUNIT_TEST( tangentSquares ); + CPPUNIT_TEST( diamondsSharingVertex1 ); + CPPUNIT_TEST( identicalSquares ); + CPPUNIT_TEST( squareAndDiamondBasic ); + CPPUNIT_TEST( squareAndDiamondCritical ); + CPPUNIT_TEST( diamondsCritical ); + CPPUNIT_TEST( quadranglesCritical ); + CPPUNIT_TEST( quadrangleAndDiamondCritical ); + CPPUNIT_TEST( diamondsCritical2 ); + CPPUNIT_TEST( hexagonsCritical1 ); + CPPUNIT_TEST( hexagonsCritical2 ); + CPPUNIT_TEST( squareAndQuadrangleCritical ); + CPPUNIT_TEST( diamondsSharingVertex2 ); + CPPUNIT_TEST( triangleAndDiamondCritical ); + CPPUNIT_TEST( triangleAndSquareBasic ); + CPPUNIT_TEST( trianglesCritical ); + CPPUNIT_TEST( paralellogramsCritical1 ); + CPPUNIT_TEST( paralellogramsCritical2 ); + CPPUNIT_TEST( trianglesTangencyCritical ); + CPPUNIT_TEST( trianglesTangencyCritical2 ); + CPPUNIT_TEST( trianglesTangencyCritical3 ); + CPPUNIT_TEST( trianglesTangencyCritical4 ); + CPPUNIT_TEST( diamondsBasic_Triangulation ); + CPPUNIT_TEST( tangentDiamonds_Triangulation ); + CPPUNIT_TEST( tangentSquares_Triangulation ); + CPPUNIT_TEST( diamondsSharingVertex1_Triangulation ); + CPPUNIT_TEST( identicalSquares_Triangulation ); + CPPUNIT_TEST( squareAndDiamondBasic_Triangulation ); + CPPUNIT_TEST( squareAndDiamondCritical_Triangulation ); + CPPUNIT_TEST( diamondsCritical_Triangulation ); + CPPUNIT_TEST( quadranglesCritical_Triangulation ); + CPPUNIT_TEST( quadrangleAndDiamondCritical_Triangulation ); + CPPUNIT_TEST( diamondsCritical2_Triangulation ); + CPPUNIT_TEST( hexagonsCritical1_Triangulation ); + CPPUNIT_TEST( hexagonsCritical2_Triangulation ); + CPPUNIT_TEST( squareAndQuadrangleCritical_Triangulation ); + CPPUNIT_TEST( diamondsSharingVertex2_Triangulation ); + CPPUNIT_TEST( triangleAndDiamondCritical_Triangulation ); + CPPUNIT_TEST( triangleAndSquareBasic_Triangulation ); + CPPUNIT_TEST( trianglesCritical_Triangulation ); + CPPUNIT_TEST( paralellogramsCritical1_Triangulation ); + CPPUNIT_TEST( paralellogramsCritical2_Triangulation ); + CPPUNIT_TEST( trianglesTangencyCritical_Triangulation ); + CPPUNIT_TEST( trianglesTangencyCritical2_Triangulation ); + CPPUNIT_TEST( trianglesTangencyCritical3_Triangulation ); + CPPUNIT_TEST( trianglesTangencyCritical4_Triangulation ); + + CPPUNIT_TEST_SUITE_END(); + + public: + + void diamondsBasic(); + void tangentDiamonds(); + void tangentSquares(); + void diamondsSharingVertex1(); + void identicalSquares(); + void squareAndDiamondBasic(); + void squareAndDiamondCritical(); + void diamondsCritical(); + void quadranglesCritical(); + void quadrangleAndDiamondCritical(); + void diamondsCritical2(); + void hexagonsCritical1(); + void hexagonsCritical2(); + void squareAndQuadrangleCritical(); + void diamondsSharingVertex2(); + void triangleAndDiamondCritical(); + void triangleAndSquareBasic(); + void trianglesCritical(); + void paralellogramsCritical1(); + void paralellogramsCritical2(); + void trianglesTangencyCritical(); + void trianglesTangencyCritical2(); + void trianglesTangencyCritical3(); + void trianglesTangencyCritical4(); + void diamondsBasic_Triangulation(); + void tangentDiamonds_Triangulation(); + void tangentSquares_Triangulation(); + void diamondsSharingVertex1_Triangulation(); + void identicalSquares_Triangulation(); + void squareAndDiamondBasic_Triangulation(); + void squareAndDiamondCritical_Triangulation(); + void diamondsCritical_Triangulation(); + void quadranglesCritical_Triangulation(); + void quadrangleAndDiamondCritical_Triangulation(); + void diamondsCritical2_Triangulation(); + void hexagonsCritical1_Triangulation(); + void hexagonsCritical2_Triangulation(); + void squareAndQuadrangleCritical_Triangulation(); + void diamondsSharingVertex2_Triangulation(); + void triangleAndDiamondCritical_Triangulation(); + void triangleAndSquareBasic_Triangulation(); + void trianglesCritical_Triangulation(); + void paralellogramsCritical1_Triangulation(); + void paralellogramsCritical2_Triangulation(); + void trianglesTangencyCritical_Triangulation(); + void trianglesTangencyCritical2_Triangulation(); + void trianglesTangencyCritical3_Triangulation(); + void trianglesTangencyCritical4_Triangulation(); + }; +} +#endif diff --git a/src/INTERP_KERNELTest/SingleElementTetraTests.hxx b/src/INTERP_KERNELTest/SingleElementTetraTests.hxx new file mode 100644 index 000000000..f5e22b464 --- /dev/null +++ b/src/INTERP_KERNELTest/SingleElementTetraTests.hxx @@ -0,0 +1,169 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __SINGLE_ELEMENT_TETRA_TESTS_HXX_ +#define __SINGLE_ELEMENT_TETRA_TESTS_HXX_ + +#include "InterpolationTestSuite.hxx" + +namespace INTERP_TEST +{ + /** + * \brief Class testing algorithm by intersecting simple meshes having only one element each. This serves mainly to verify that + * the volume calculations between elements is correct. + * + */ + class SingleElementTetraTests : public InterpolationTestSuite<3,3> + { + CPPUNIT_TEST_SUITE( SingleElementTetraTests ); + + CPPUNIT_TEST( tetraReflexiveUnit ); + CPPUNIT_TEST( tetraReflexiveGeneral ); + CPPUNIT_TEST( tetraNudgedSimpler ); + CPPUNIT_TEST( tetraNudged ); + CPPUNIT_TEST( tetraCorner ); + CPPUNIT_TEST( tetraSimpleIncluded ); + CPPUNIT_TEST( tetraDegenEdge ); + CPPUNIT_TEST( tetraDegenFace ); + CPPUNIT_TEST( tetraDegenTranslatedInPlane ); + CPPUNIT_TEST( tetraHalfstripOnly ); + CPPUNIT_TEST( tetraHalfstripOnly2 ); + CPPUNIT_TEST( tetraSimpleHalfstripOnly ); + CPPUNIT_TEST( generalTetra ); + CPPUNIT_TEST( trickyTetra1 ); + // CPPUNIT_TEST( inconsistentTetra ); + + CPPUNIT_TEST_SUITE_END(); + + public: + + /// Unit tetrahedron mesh intersecting itself + /// \brief Status : pass + void tetraReflexiveUnit() + { + _testTools->intersectMeshes("UnitTetra", "UnitTetra", 1.0/6.0); + } + + /// Tetrahedron mesh with itself + /// \brief Status : pass + void tetraReflexiveGeneral() + { + _testTools->intersectMeshes("GeneralTetra", "GeneralTetra", 0.428559); + } + + /// Unit tetrahedron mesh intersecting slightly displaced copy of itself + /// \brief Status : pass + void tetraNudged() + { + _testTools->intersectMeshes("UnitTetra", "NudgedTetra", 0.142896); + } + + /// Single-element unit tetrahedron mesh intersecting even slightly displaced (along one axis only) copy of itself + /// \brief Status : pass + void tetraNudgedSimpler() + { + _testTools->intersectMeshes("UnitTetra", "NudgedSimpler", 0.152112); + } + + /// Tetrahedron intersecting unit tetrahedron with in non-degenerate way around corner O + /// \brief Status : pass + void tetraCorner() + { + _testTools->intersectMeshes("UnitTetra", "CornerTetra", 0.0135435); + } + + /// Tetrahedron situated totally inside another + /// \brief Status : pass + void tetraSimpleIncluded() + { + _testTools->intersectMeshes("SimpleIncludedTetra", "SimpleIncludingTetra", 17.0156); + } + + /// Displaced unit tetrahedron intersecting another unit tetrahedron with which it shares an edge + /// \brief Status : pass + void tetraDegenEdge() + { + _testTools->intersectMeshes("UnitTetraDegenT", "DegenEdgeXY", 0.0); + } + + /// Displaced unit tetrahedron intersecting another unit tetrahedron with which it shares a face + /// \brief Status : pass + void tetraDegenFace() + { + _testTools->intersectMeshes("UnitTetraDegenT", "DegenFaceXYZ", 0.0); + } + + /// Displaced unit tetrahedron intersecting another unit tetrahedron with which it shares a part of the face XYZ + /// \brief Status : pass + void tetraDegenTranslatedInPlane() + { + _testTools->intersectMeshes("UnitTetraDegenT", "DegenTranslatedInPlane", 0.0571667); + } + + /// Tetrahedron having only half-strip intersections with the unit tetrahedron + /// \brief Status : pass, but does not really test what it should - does not check that the intersections are detected. No longer needed. + void tetraHalfstripOnly() + { + // NB this test is not completely significant : we should also verify that + // there are triangles on the element that give a non-zero volume + _testTools->intersectMeshes("HalfstripOnly", "UnitTetra", 0.0); + } + + /// Tetrahedron having only half-strip intersections with the unit tetrahedron + /// \brief Status : pass, but does not really test what it should - does not check that the intersections are detected. No longer needed. + void tetraHalfstripOnly2() + { + // NB this test is not completely significant : we should also verify that + // there are triangles on the element that give a non-zero volume + _testTools->intersectMeshes("HalfstripOnly2", "UnitTetra", 0.0); + } + + /// Tetrahedron having only half-strip intersections with the unit tetrahedron + /// \brief Status : pass, but does not really test what it should - does not check that the intersections are detected. No longer needed. + void tetraSimpleHalfstripOnly() + { + // NB this test is not completely significant : we should also verify that + // there are triangles on the element that give a non-zero volume + _testTools->intersectMeshes("SimpleHalfstripOnly", "UnitTetra", 0.0); + } + + /// Two intersecting tetrahedra situated in a general position in space + /// \brief Status : pass + void generalTetra() + { + _testTools->intersectMeshes("GenTetra1", "GenTetra2", 4.91393); + } + + /// Tetrahedron which is in a tricky position relative to unit tetrahedron. + /// \brief Status : pass + void trickyTetra1() + { + _testTools->intersectMeshes("UnitTetra", "TrickyTetra1", 0.0); + } + + /// Two large tetrahedra which nearly share part of an edge and intersect at the origin. Created with goal of getting the as-of-yet uncovered "consistency" test + /// part of the correction of double products covered. However, it does not succeed with this. + /// \brief Status : fails, but is quite far-fetched as far as typical use cases are concerned + void inconsistentTetra() + { + _testTools->intersectMeshes("LargeUnitTetra.med", "LargeUnitTetra", "LargeInconsistentTetra.med", "LargeInconsistent", 7.86231e7); + } + + }; +} +#endif diff --git a/src/INTERP_KERNELTest/TestInterpKernel.cxx b/src/INTERP_KERNELTest/TestInterpKernel.cxx new file mode 100644 index 000000000..41501ea7e --- /dev/null +++ b/src/INTERP_KERNELTest/TestInterpKernel.cxx @@ -0,0 +1,53 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "CppUnitTest.hxx" +#include "TransformedTriangleTest.hxx" +#include "UnitTetraIntersectionBaryTest.hxx" +#include "TransformedTriangleIntersectTest.hxx" +#include "MultiElementTetraTests.hxx" +#include "SingleElementTetraTests.hxx" +#include "HexaTests.hxx" +#include "BBTreeTest.hxx" +#include "PointLocatorTest.hxx" +#include "RemapperTest.hxx" +#include "MultiElement2DTests.hxx" +#include "SingleElementPlanarTests.hxx" +#include "QuadraticPlanarInterpTest.hxx" +#include "InterpolationOptionsTest.hxx" +using namespace INTERP_TEST; + +//--- Registers the fixture into the 'registry' + +CPPUNIT_TEST_SUITE_REGISTRATION( HexaTests ); +CPPUNIT_TEST_SUITE_REGISTRATION( MultiElementTetraTests ); +CPPUNIT_TEST_SUITE_REGISTRATION( SingleElementTetraTests ); +CPPUNIT_TEST_SUITE_REGISTRATION( TransformedTriangleIntersectTest ); +CPPUNIT_TEST_SUITE_REGISTRATION( TransformedTriangleTest ); +CPPUNIT_TEST_SUITE_REGISTRATION( UnitTetraIntersectionBaryTest ); +CPPUNIT_TEST_SUITE_REGISTRATION( BBTreeTest); +CPPUNIT_TEST_SUITE_REGISTRATION( RemapperTest); +CPPUNIT_TEST_SUITE_REGISTRATION( PointLocatorTest); +CPPUNIT_TEST_SUITE_REGISTRATION( MultiElement2DTests ); +CPPUNIT_TEST_SUITE_REGISTRATION( SingleElementPlanarTests ); +CPPUNIT_TEST_SUITE_REGISTRATION( QuadraticPlanarInterpTest ); +CPPUNIT_TEST_SUITE_REGISTRATION( InterpolationOptionsTest ); + +// --- generic Main program from KERNEL_SRC/src/Basics/Test + +#include "BasicMainTest.hxx" diff --git a/src/INTERP_KERNELTest/TestingUtils.hxx b/src/INTERP_KERNELTest/TestingUtils.hxx new file mode 100644 index 000000000..1057f58c2 --- /dev/null +++ b/src/INTERP_KERNELTest/TestingUtils.hxx @@ -0,0 +1,308 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef _TESTING_UTILS_HXX_ +#define _TESTING_UTILS_HXX_ + +#include "Interpolation3D.hxx" +#include "MEDMEM_Mesh.hxx" + +#include +#include +#include +#include +#include + +#include "VectorUtils.hxx" + +// levels : +// 1 - titles and volume results +// 2 - symmetry / diagonal results and intersection matrix output +// 3 - empty +// 4 - empty +// 5 - misc +#include "Log.hxx" + +using namespace MEDMEM; +using namespace std; +using namespace INTERP_KERNEL; +using namespace MED_EN; + + +double sumVolume(const IntersectionMatrix& m) +{ + + vector volumes; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + volumes.push_back(iter2->second); + // vol += std::fabs(iter2->second); + } + } + + // sum in ascending order to avoid rounding errors + + sort(volumes.begin(), volumes.end()); + const double vol = accumulate(volumes.begin(), volumes.end(), 0.0); + + return vol; +} + +#if 0 + +bool areCompatitable(const IntersectionMatrix& m1, const IntersectionMatrix& m2) +{ + bool compatitable = true; + int i = 0; + for(IntersectionMatrix::const_iterator iter = m1.begin() ; iter != m1.end() ; ++iter) + { + for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + int j = iter2->first; + if(m2.at(j-1).count(i+1) == 0) + { + if(!epsilonEqual(iter2->second, 0.0, VOL_PREC)) + { + LOG(2, "V1( " << i << ", " << j << ") exists, but V2( " << j - 1 << ", " << i + 1 << ") " << " does not " ); + LOG(2, "(" << i << ", " << j << ") fails"); + compatitable = false; + } + } + } + ++i; + } + if(!compatitable) + { + LOG(1, "*** matrices are not compatitable"); + } + return compatitable; +} + +bool testSymmetric(const IntersectionMatrix& m1, const IntersectionMatrix& m2) +{ + + int i = 0; + bool isSymmetric = true; + + LOG(1, "Checking symmetry src - target" ); + isSymmetric = isSymmetric & areCompatitable(m1, m2) ; + LOG(1, "Checking symmetry target - src" ); + isSymmetric = isSymmetric & areCompatitable(m2, m1); + + for(IntersectionMatrix::const_iterator iter = m1.begin() ; iter != m1.end() ; ++iter) + { + for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + int j = iter2->first; + const double v1 = iter2->second; + //if(m2[j - 1].count(i+1) > 0) + // { + map theMap = m2.at(j-1); + const double v2 = theMap[i + 1]; + if(v1 != v2) + { + LOG(2, "V1( " << i << ", " << j << ") = " << v1 << " which is different from V2( " << j - 1 << ", " << i + 1 << ") = " << v2 << " | diff = " << v1 - v2 ); + if(!epsilonEqualRelative(v1, v2, VOL_PREC)) + { + LOG(2, "(" << i << ", " << j << ") fails"); + isSymmetric = false; + } + } + } + ++i; + } + if(!isSymmetric) + { + LOG(1, "*** matrices are not symmetric"); + } + return isSymmetric; +} + +bool testDiagonal(const IntersectionMatrix& m) +{ + LOG(1, "Checking if matrix is diagonal" ); + int i = 1; + bool isDiagonal = true; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + int j = iter2->first; + const double vol = iter2->second; + if(vol != 0.0 && (i != j)) + { + LOG(2, "V( " << i - 1 << ", " << j << ") = " << vol << " which is not zero" ); + if(!epsilonEqual(vol, 0.0, VOL_PREC)) + { + LOG(2, "(" << i << ", " << j << ") fails"); + isDiagonal = false; + } + } + } + ++i; + } + if(!isDiagonal) + { + LOG(1, "*** matrix is not diagonal"); + } + return isDiagonal; +} + +#endif + +void dumpIntersectionMatrix(const IntersectionMatrix& m) +{ + int i = 0; + std::cout << "Intersection matrix is " << endl; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + + std::cout << "V(" << i << ", " << iter2->first << ") = " << iter2->second << endl; + + } + ++i; + } + std::cout << "Sum of volumes = " << sumVolume(m) << std::endl; +} + +std::pair countNumberOfMatrixEntries(const IntersectionMatrix& m) +{ + + int numElems = 0; + int numNonZero = 0; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + numElems += iter->size(); + for(map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + if(!epsilonEqual(iter2->second, 0.0, VOL_PREC)) + { + ++numNonZero; + } + } + } + return std::make_pair(numElems, numNonZero); +} + + +void calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) +{ + const string dataBaseDir = getenv("MED_ROOT_DIR"); + const string dataDir = dataBaseDir + "/share/salome/resources/med/"; + + LOG(1, std::endl << "=== -> intersecting src = " << mesh1 << ", target = " << mesh2 ); + + LOG(5, "Loading " << mesh1 << " from " << mesh1path); + const MESH sMesh(MED_DRIVER, dataDir+mesh1path, mesh1); + const int numSrcElems = sMesh.getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS); + LOG(1, "Source mesh has " << numSrcElems << " elements"); + + + LOG(5, "Loading " << mesh2 << " from " << mesh2path); + const MESH tMesh(MED_DRIVER, dataDir+mesh2path, mesh2); + const int numTargetElems = tMesh.getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS); + + LOG(1, "Target mesh has " << numTargetElems << " elements"); + + Interpolation3D* interpolator = new Interpolation3D(); + + m = interpolator->interpolateMeshes(sMesh, tMesh); + + std::pair eff = countNumberOfMatrixEntries(m); + LOG(1, eff.first << " of " << numTargetElems * numSrcElems << " intersections calculated : ratio = " + << double(eff.first) / double(numTargetElems * numSrcElems)); + LOG(1, eff.second << " non-zero elements of " << eff.first << " total : filter efficiency = " + << double(eff.second) / double(eff.first)); + + delete interpolator; + + LOG(1, "Intersection calculation done. " << std::endl ); + +} + + + + + + + + +#if 0 +void intersectMeshes(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, const double correctVol, const double prec, bool doubleTest) +{ + LOG(1, std::endl << std::endl << "=============================" ); + + using std::string; + const string path1 = string(mesh1path) + string(mesh1); + const string path2 = string(mesh2path) + string(mesh2); + + const bool isTestReflexive = (path1.compare(path2) == 0); + + IntersectionMatrix matrix1; + calcIntersectionMatrix(mesh1path, mesh1, mesh2path, mesh2, matrix1); + +#if LOG_LEVEL >= 2 + dumpIntersectionMatrix(matrix1); +#endif + + std::cout.precision(16); + + const double vol1 = sumVolume(matrix1); + + if(!doubleTest) + { + LOG(1, "vol = " << vol1 <<" correctVol = " << correctVol ); + // CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(correctVol, vol1)); + + if(isTestReflexive) + { + // CPPUNIT_ASSERT_EQUAL_MESSAGE("Reflexive test failed", true, testDiagonal(matrix1)); + } + } + else + { + + IntersectionMatrix matrix2; + calcIntersectionMatrix(mesh2path, mesh2, mesh1path, mesh1, matrix2); + +#if LOG_LEVEL >= 2 + dumpIntersectionMatrix(matrix2); +#endif + + const double vol2 = sumVolume(matrix2); + + LOG(1, "vol1 = " << vol1 << ", vol2 = " << vol2 << ", correctVol = " << correctVol ); + + // CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(vol1, correctVol)); + // CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol2, prec * std::max(vol2, correctVol)); + // CPPUNIT_ASSERT_DOUBLES_EQUAL(vol1, vol2, prec * std::max(vol1, vol2)); + // CPPUNIT_ASSERT_EQUAL_MESSAGE("Symmetry test failed", true, testSymmetric(matrix1, matrix2)); + } + +} + + + +#endif + + +#endif diff --git a/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.cxx b/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.cxx new file mode 100644 index 000000000..500af44c0 --- /dev/null +++ b/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.cxx @@ -0,0 +1,2283 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "TransformedTriangleIntersectTest.hxx" +#include + +#include "Log.hxx" + +/// macro to test for zero double products outside the segment-edge intersection test method +/// as is done in TransformedTriangle when OPTIMIZE is defined +#define TEST_ZERO_DP_EDGE(seg, edge) isZero[TT::NO_DP*int(seg) + int(DoubleProduct(edge))] + +/// macro to test for zero double products outside the segment-corner intersection test method +/// as is done in TransformedTriangle when OPTIMIZE is defined +#define TEST_ZERO_DP_CORNER(seg, corner) \ + isZero[DoubleProduct(TT::NO_DP*int(seg) + TT::EDGES_FOR_CORNER[3*corner] )] && \ + isZero[DoubleProduct(TT::NO_DP*int(seg) + TT::EDGES_FOR_CORNER[3*corner+1] )] && \ + isZero[DoubleProduct(TT::NO_DP*int(seg) + TT::EDGES_FOR_CORNER[3*corner+2] )] + +/// macro to test for zero double products outside the segment-ray intersection test method +/// as is done in TransformedTriangle when OPTIMIZE is defined +#define TEST_ZERO_DP_RAY(seg, corner) isZero[TT::NO_DP*int(seg) + TT::DP_SEGMENT_RAY_INTERSECTION[7*(corner-1)]] + +using namespace INTERP_KERNEL; + +namespace INTERP_TEST +{ + + //////////////////////////////////////////////////////////////////////////////////////////////////////// + /// \class TransformedTriangleIntersectTest + /// \brief Class testing the intersection detection methods of TransformedTriangle. + /// + /// This class contains unit tests for the intersection methods of the TransformedTriangle class. + //////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Each method in the class runs all the intersection tests with some triangle. The goal is to cover all + /// the different types of intersections between a triangle and a tetrahedron. The table below gives a + /// a summary of what is being tested. Before each method, there is also a summary of what how the + /// triangle in the method intersects the unit tetrahedron. + /// + /// Since performing all tests would require a large number of triangles, we have limited our coverage to + /// be such that each column and each row in the table below has at least one entry for each type of + /// intersection. The intersection forumlae are totally symmetric with respect to changing the segment + /// (PQ, QR, or RP) of the triangle, so they only enter in a very simple way in the code. Testing + /// all these cases is therefore of low priority. + //////////////////////////////////////////////////////////////////////////////////////////////////////// + /// + //////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Intersections tested (number indicates first triangle which contains the intersection): + ///
+  /// -----------------------------------------------------------------------------------------------------
+  /// CI  ->  P: 3      Q: 4     R: 7
+  /// COH ->  P: 9      Q: 8     R: 10
+  /// CAH ->  P: 4      Q: 10    R: 9
+  /// -----------------------------------------------------------------------------------------------------
+  /// SF  ->  (PQ, OZX) : 1   (PQ, OYZ) : 2   (PQ, OXY) : 1   (PQ, XYZ) : 3
+  ///     ->  (QR, OZX) : 8   (QR, OYZ) : -   (QR, OXY) : 4   (QR, XYZ) : 7
+  ///     ->  (RP, OZX) : 1   (RP, OYZ) : 3   (RP, OXY) : 7   (RP, XYZ) : 1
+  /// -----------------------------------------------------------------------------------------------------
+  /// SE  ->  (PQ, OX)  : 11  (PQ, OY)  : -   (PQ, OZ)  : 12  (PQ, XY)  : 2   (PQ, ZX)  : -  (PQ, YZ)  : 10
+  ///     ->  (QR, OX)  : -   (QR, OY)  : -   (QR, OZ)  : -   (QR, XY)  : -   (QR, ZX)  : 9  (QR, YZ)  : -
+  ///     ->  (RP, OX)  : -   (RP, OY)  : 12  (RP, OZ)  : -   (RP, XY)  : -   (RP, ZX)  : -  (RP, YZ)  : -
+  /// -----------------------------------------------------------------------------------------------------
+  /// SC  ->  (PQ, O)   : -   (PQ, X)   : -   (PQ, Y)   : 8   (PQ, Z)   : -
+  ///     ->  (QR, O)   : -   (QR, X)   : 2   (QR, Y)   : -   (QR, Z)   : 13
+  ///     ->  (RP, O)   : 11  (RP, X)   : -   (RP, Y)   : -   (RP, Z)   : -
+  /// -----------------------------------------------------------------------------------------------------
+  /// SHS ->  (PQ, XY)  : 3   (PQ, ZX)  : -   (PQ, YZ)  : 13
+  ///     ->  (QR, XY)  : 3   (QR, ZX)  : 5   (QR, YZ)  : 3
+  ///     ->  (RP, XY)  : 1   (RP, ZX)  : 4   (RP, YZ)  : -
+  /// -----------------------------------------------------------------------------------------------------
+  /// SR  ->  (PQ, X)   : 6   (PQ, Y)   : 5   (PQ, Z)   : -
+  ///     ->  (QR, X)   : -   (QR, Y)   : -   (QR, Z)   : 6
+  ///     ->  (RP, X)   : -   (RP, Y)   : -   (RP, Z)   : -
+  /// -----------------------------------------------------------------------------------------------------
+  /// TE  ->  OX : 4   OY : 7    OZ : 8     XY : 1     ZX : 4    YZ : 3
+  /// -----------------------------------------------------------------------------------------------------
+  /// TR  ->  X  : 7    Y : 6     Z : 5
+  /// -----------------------------------------------------------------------------------------------------
+  /// 
+ //////////////////////////////////////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Key to triangle descriptions : + /// CI = Triangle corner contained in tetrahedron + /// COH = Triangle corner on h = 0 face of tetrahedron + /// CAH = Triangle corner above h = 0 face of tetrahedron in z-direction + /// SF = Segment - facet intersection + /// SE = Segment - edge intersection + /// SC = Segment - corner intersection + /// SHS = Segment - halfstrip intersection + /// SR = Segment - ray intersection + /// TE = Tetrahedron edge intersects triangle (surface - edge intersection) + /// TR = Surface - ray intersection + /// + /// In the descriptions for each triangle, square brackets indicate superfluous but allowed intersections + /// that arise as by-products of for instance segment-corner intersections. + /// E.g. A segment - corner intersection can imply three surface - edge intersections + /// Since these "extra" intersections arise under special circumstances, they are not counted in the + /// table above + //////////////////////////////////////////////////////////////////////////////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Triangle 1 has the following intersections + ///
+  /// CI     -
+  /// COH    -
+  /// CAH    -
+  /// SF     (PQ, OXY), (PQ, OZX), (RP, XYZ), (RP, OZX)
+  /// SE     -
+  /// SC     - 
+  /// SHS    (RP, XY)
+  /// SR     - 
+  /// TE     XY
+  /// TR     - 
+  /// 
+ /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle1() + { + LOG(1, "+++++++ Testing triangle 1" ); + + typedef TransformedTriangle TT; + + double coords[9] = + { + 0.4,-0.5, 0.5, // P + 0.4, 2.5,-1.0, // Q + 0.4, 2.5, 0.5 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT(tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + + } + + /// Triangle 2 has the following intersections + ///
+  /// CI     -
+  /// COH    -
+  /// CAH    -
+  /// SF     (PQ, OYZ)
+  /// SE     (PQ, XY)
+  /// SC     (QR, X)
+  /// SHS    -
+  /// SR     - 
+  /// TE     [OX, OZ, ZX]
+  /// TR     - 
+  /// 
+ /// \brief Status: pass + void TransformedTriangleIntersectTest::testTriangle2() + { + LOG(1, "+++++++ Testing triangle 2" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + -0.5, 0.5, 0.25, // P + 1.5, 0.5,-0.25, // Q + -0.5,-1.5, 0.75 // R + }; + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + /// Triangle 3 has the following intersections + ///
+  /// CI     P
+  /// COH    -
+  /// CAH    -
+  /// SF     (PQ, XYZ), (RP, OYZ)
+  /// SE     -
+  /// SC     -
+  /// SHS    (PQ, XY), (QR, YZ), (QR, XY)
+  /// SR     - 
+  /// TE     YZ
+  /// TR     - 
+  /// 
+ /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle3() + { + LOG(1, "+++++++ Testing triangle 3" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + 0.35, 0.15, 0.1, // P + 0.8, 0.8, 0.8, // Q + -0.4, 0.3, 0.9 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + /// Triangle 4 has the following intersections + ///
+  /// CI     Q
+  /// COH    -
+  /// CAH    P
+  /// SF     (PQ, XYZ), (QR, OXY)
+  /// SE     -
+  /// SC     -
+  /// SHS    (RP, ZX)
+  /// SR     - 
+  /// TE     (OX, ZX)
+  /// TR     - 
+  /// 
+ /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle4() + { + LOG(1, "+++++++ Testing triangle 4" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + 0.3, 0.3, 1.8, // P + 0.75, 0.1, 0.1, // Q + 0.2, -1.3, -1.4 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + /// Triangle 5 has the following intersections + ///
+  /// CI     -
+  /// COH    -
+  /// CAH    -
+  /// SF     -
+  /// SE     -
+  /// SC     -
+  /// SHS    (QR, ZX), (QR, XY)
+  /// SR     (PQ, Y)
+  /// TE     -
+  /// TR     Z
+  /// 
+ /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle5() + { + LOG(1, "+++++++ Testing triangle 5" ); + + typedef TransformedTriangle TT; + + double coords[9] = + { + -0.5, 0.5, 2.3, // P + 0.5, 1.5, 2.8, // Q + 0.5, -2.6, 1.3 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + /// Triangle 6 has the following intersections + ///
+  /// CI     -
+  /// COH    -
+  /// CAH    -
+  /// SF     -
+  /// SE     -
+  /// SC     -
+  /// SHS    -
+  /// SR     (PQ, X), (QR, Z) 
+  /// TE     -
+  /// TR     Y 
+  /// 
+ /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle6() + { + LOG(1, "+++++++ Testing triangle 6" ); + + typedef TransformedTriangle TT; + + double coords[9] = + { + 1.5, 0.5, 1.35, // P + 0.5, -0.5, 2.1, // Q + -3.0, 3.0, -0.5 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + /// Triangle 7 has the following intersections + ///
+  /// CI     R
+  /// COH    -
+  /// CAH    -
+  /// SF     (RP, OXY),(QR,XYZ)
+  /// SE     -
+  /// SC     -
+  /// SHS    (QR, XY)
+  /// SR     - 
+  /// TE     OX, ZX
+  /// TR     X 
+  /// 
+ /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle7() + { + + LOG(1, "+++++++ Testing triangle 7" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + -2.3, -1.5, -2.5, // P + 3.1, 0.15, 0.8, // Q + 0.3, 0.4, 0.2 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + /// Triangle 8 has the following intersections + ///
+  /// CI     [Q] 
+  /// COH    Q
+  /// CAH    -
+  /// SF     (QR, OZX), [ (QR, XYZ) ]
+  /// SE     -
+  /// SC     (PQ,Y)
+  /// SHS    -
+  /// SR     - 
+  /// TE     OZ, [YZ,OY,XY]
+  /// TR     - 
+  /// 
+ /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle8() + { + LOG(1, "+++++++ Testing triangle 8" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + -0.75, 3.25, -1.5, // P + 0.25, 0.25, 0.5, // Q + -0.1, -0.4, 0.9 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + /// Triangle 9 has the following intersections + ///
+  /// CI     [P]
+  /// COH    P
+  /// CAH    R
+  /// SF     (PQ, OZX), [(PQ, XYZ), (RP,XYZ)]
+  /// SE     (QR, ZX)
+  /// SC     -
+  /// SHS    -
+  /// SR     - 
+  /// TE     [ZX]
+  /// TR     - 
+  /// 
+ /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle9() + { + LOG(1, "+++++++ Testing triangle 9" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + 0.6, 0.2, 0.2, // P + 0.3, -0.2, 0.8, // Q + 0.1, 0.2, 0.8 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + + /// Triangle 10 has the following intersections + ///
+  /// CI     [R]
+  /// COH    R
+  /// CAH    Q
+  /// SF     (RP, OYZ), [ (RP, XYZ), (QR, XYZ) ]
+  /// SE     (PQ, YZ)
+  /// SC     -
+  /// SHS    -
+  /// SR     - 
+  /// TE     [YZ]
+  /// TR     - 
+  /// 
+ /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle10() + { + LOG(1, "+++++++ Testing triangle 10" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + -0.1, 0.3, 0.6, // P + 0.1, 0.1, 1.0, // Q + 0.4, 0.3, 0.3 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + /// Triangle 11 has the following intersections + ///
+  /// CI     Q, R
+  /// COH    -
+  /// CAH    -
+  /// SF     -
+  /// SE     (PQ, OX)
+  /// SC     (RP, O)
+  /// SHS    -
+  /// SR     - 
+  /// TE     [OY, OZ]
+  /// TR     - 
+  /// 
+ /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle11() + { + LOG(1, "+++++++ Testing triangle 11" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + -0.2, -0.2, -0.2, // P + 0.2, 0.1, 0.1, // Q + 0.3, 0.3, 0.3 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(true, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + + /// Triangle 12 has the following intersections + ///
+  /// CI     -
+  /// COH    -
+  /// CAH    -
+  /// SF     (QR, OXY), (QR, OZX)
+  /// SE     (RP, OY), (PQ, OZ)
+  /// SC     -
+  /// SHS    -
+  /// SR     - 
+  /// TE     [OY], [OZ]
+  /// TR     - 
+  /// 
+ /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle12() + { + LOG(1, "+++++++ Testing triangle 12" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + -0.2, 0.2, 0.2, // P + 0.2, -0.2, 0.3, // Q + 0.6, 0.6, -0.6 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + + /// Triangle 13 has the following intersections + ///
+  /// CI     -
+  /// COH    -
+  /// CAH    -
+  /// SF     (QR, OYZ), (PQ, OXY), (PQ, XYZ)
+  /// SE     -
+  /// SC     (QR, Z)
+  /// SHS    (PQ, YZ)
+  /// SR     - 
+  /// TE     [OZ, YZ, ZX]
+  /// TR     - 
+  /// 
+ /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle13() + { + LOG(1, "+++++++ Testing triangle 13" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + -0.2, 0.3, 5.0, // P + 0.2, 0.1, -1.0, // Q + -0.2, -0.1, 3.0 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + +} // NAMESPACE + + + + + + + +///// TEMPLATE /////////////////////////////// + + + +#if 0 +// Triangle x has the following intersections +// CI - +// COH - +// CAH - +// SF - +// SE - +// SC - +// SHS - +// SR - +// TE - +// TR - + +void TransformedTriangleIntersectTest::testTriangleX() +{ + LOG(1, "+++++++ Testing triangle X" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + 0.0, 0.0, 0.0, // P + 0.0, 0.0, 0.0, // Q + 0.0, 0.0, 0.0 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; +} +#endif diff --git a/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.hxx b/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.hxx new file mode 100644 index 000000000..752c0508c --- /dev/null +++ b/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.hxx @@ -0,0 +1,91 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TU_TRANSFORMED_TRIANGLE_INTERSECT_HXX__ +#define __TU_TRANSFORMED_TRIANGLE_INTERSECT_HXX__ + +#include +#include "../TransformedTriangle.hxx" + +namespace INTERP_TEST +{ + + class TransformedTriangleIntersectTest : public CppUnit::TestFixture + { + + CPPUNIT_TEST_SUITE( TransformedTriangleIntersectTest ); + + CPPUNIT_TEST( testTriangle1 ); + CPPUNIT_TEST( testTriangle2 ); + CPPUNIT_TEST( testTriangle3 ); + CPPUNIT_TEST( testTriangle4 ); + CPPUNIT_TEST( testTriangle5 ); + CPPUNIT_TEST( testTriangle6 ); + CPPUNIT_TEST( testTriangle7 ); + CPPUNIT_TEST( testTriangle8 ); + CPPUNIT_TEST( testTriangle9 ); + CPPUNIT_TEST( testTriangle10 ); + CPPUNIT_TEST( testTriangle11 ); + CPPUNIT_TEST( testTriangle12 ); + CPPUNIT_TEST( testTriangle13 ); + + CPPUNIT_TEST_SUITE_END(); + + typedef INTERP_KERNEL::TransformedTriangle::TriSegment TriSegment; + typedef INTERP_KERNEL::TransformedTriangle::DoubleProduct DoubleProduct; + + public: + + void testTriangle1(); + + void testTriangle2(); + + void testTriangle3(); + + void testTriangle4(); + + void testTriangle5(); + + void testTriangle6(); + + void testTriangle7(); + + void testTriangle8(); + + void testTriangle9(); + + void testTriangle10(); + + void testTriangle11(); + + void testTriangle12(); + + void testTriangle13(); + + private: + + }; + +} + + + + + + +#endif diff --git a/src/INTERP_KERNELTest/TransformedTriangleTest.cxx b/src/INTERP_KERNELTest/TransformedTriangleTest.cxx new file mode 100644 index 000000000..e668dbc03 --- /dev/null +++ b/src/INTERP_KERNELTest/TransformedTriangleTest.cxx @@ -0,0 +1,354 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "TransformedTriangleTest.hxx" + +#include + +using namespace INTERP_KERNEL; + +namespace INTERP_TEST +{ + + /** + * Creates the TransformedTriangle objects used by the tests. + * + */ + void TransformedTriangleTest::setUp() + { + // tri1 -> no unstable double products - no changes brought about by preCalculateDoubleProducts + // this allows the testing of calcUnstableT + // tri2 -> unstable double products - for testing calcStableC / preCalculateDoubleProducts + + // triangle to test unstable C and T calculations + p1[0] = -1.5 ; p1[1] = 0.5; p1[2] = 0.5; + q1[0] = 2.0 ; q1[1] = 0.4; q1[2] = 0.6; + r1[0] = 1.0 ; r1[1] = 2.4; r1[2] = 1.2; + hp1 = 1 - p1[0] - p1[1] - p1[2]; + hq1 = 1 - q1[0] - q1[1] - q1[2]; + hr1 = 1 - r1[0] - r1[1] - r1[2]; + Hp1 = 1 - p1[0] - p1[1]; + Hq1 = 1 - q1[0] - q1[1]; + Hr1 = 1 - r1[0] - r1[1]; + + // std::cout <_coords[i], ERR_TOL); + CPPUNIT_ASSERT_DOUBLES_EQUAL(good_values2[i], tri2->_coords[i], ERR_TOL); + } + + CPPUNIT_ASSERT_EQUAL(true, tri1->_is_double_products_calculated); + CPPUNIT_ASSERT_EQUAL(true, tri2->_is_double_products_calculated); + } + + /// Tests the calculation of double products (without the corrections) + /// \brief Status : pass + void TransformedTriangleTest::test_calcUnstableC() { + typedef TransformedTriangle::TriSegment TriSegment; + + // test that the correct c-values are calculated + + double correct_c_vals[24] = + { + p1[0] * q1[1] - p1[1] * q1[0], + p1[1] * q1[2] - p1[2] * q1[1], + p1[2] * q1[0] - p1[0] * q1[2], + p1[0] * hq1 - hp1 * q1[0], + p1[1] * hq1 - hp1 * q1[1], + p1[2] * hq1 - hp1 * q1[2], + Hp1 * q1[0] - p1[0] * Hq1, + p1[1] * Hq1 - Hp1 * q1[1], + q1[0] * r1[1] - q1[1] * r1[0], + q1[1] * r1[2] - q1[2] * r1[1], + q1[2] * r1[0] - q1[0] * r1[2], + q1[0] * hr1 - hq1 * r1[0], + q1[1] * hr1 - hq1 * r1[1], + q1[2] * hr1 - hq1 * r1[2], + Hq1 * r1[0] - q1[0] * Hr1, + q1[1] * Hr1 - Hq1 * r1[1], + r1[0]*p1[1]-r1[1]*p1[0], + r1[1]*p1[2]-r1[2]*p1[1], + r1[2]*p1[0]-r1[0]*p1[2], + r1[0] * hp1 - hr1 * p1[0], + r1[1] * hp1 - hr1 * p1[1], + r1[2] * hp1 - hr1 * p1[2], + Hr1 * p1[0] - r1[0] * Hp1, + r1[1] * Hp1 - Hr1 * p1[1] + }; + + double c_vals[3 * 8]; + for(TriSegment seg = TransformedTriangle::PQ ; seg <= TransformedTriangle::RP ; seg = TriSegment(seg + 1)) { + + c_vals[seg*8 + 0] = tri1->calcUnstableC(seg, TransformedTriangle::C_XY); + c_vals[seg*8 + 1] = tri1->calcUnstableC(seg, TransformedTriangle::C_YZ); + c_vals[seg*8 + 2] = tri1->calcUnstableC(seg, TransformedTriangle::C_ZX); + c_vals[seg*8 + 3] = tri1->calcUnstableC(seg, TransformedTriangle::C_XH); + c_vals[seg*8 + 4] = tri1->calcUnstableC(seg, TransformedTriangle::C_YH); + c_vals[seg*8 + 5] = tri1->calcUnstableC(seg, TransformedTriangle::C_ZH); + c_vals[seg*8 + 6] = tri1->calcUnstableC(seg, TransformedTriangle::C_01); + c_vals[seg*8 + 7] = tri1->calcUnstableC(seg, TransformedTriangle::C_10); + + } + + for(int i = 0 ; i < 3*8 ; ++i) { + CPPUNIT_ASSERT_DOUBLES_EQUAL( correct_c_vals[i], c_vals[i], ERR_TOL ); + } + + + } + + /// Tests the calculation of triple products (without corrections) + /// \brief Status : pass + void TransformedTriangleTest::test_calcUnstableT() + { + typedef TransformedTriangle::TetraCorner TetraCorner; + + // correct values calculated by determinants (Grandy, [15]) + const double correct_t_vals[4] = + { + p1[0]*(q1[1]*r1[2] - q1[2]*r1[1]) - + q1[0]*(p1[1]*r1[2] - p1[2]*r1[1]) + + r1[0]*(p1[1]*q1[2] - p1[2]*q1[1]), + + -(hp1*(q1[1]*r1[2] - q1[2]*r1[1]) - + hq1*(p1[1]*r1[2] - p1[2]*r1[1]) + + hr1*(p1[1]*q1[2] - p1[2]*q1[1])), + + -(p1[0]*(hq1*r1[2] - q1[2]*hr1) - + q1[0]*(hp1*r1[2] - p1[2]*hr1) + + r1[0]*(hp1*q1[2] - p1[2]*hq1)), + + -(p1[0]*(q1[1]*hr1 - r1[1]*hq1) - + q1[0]*(p1[1]*hr1 - r1[1]*hp1) + + r1[0]*(p1[1]*hq1 - q1[1]*hp1)) + }; + + + // test that triple products are correctly calculated + for(TetraCorner corner = TransformedTriangle::O ; corner <= TransformedTriangle::Z ; corner = TetraCorner(corner + 1)) + { + + for(int row = 1 ; row < 4 ; ++row) + { + const double t = tri1->calcTByDevelopingRow(corner, row, false); + // std::cout << std::endl << " Corner = " << corner << " Row = " << row << " got: " << t << + // " expected: " << correct_t_vals[corner]<< std::endl; + CPPUNIT_ASSERT_DOUBLES_EQUAL(correct_t_vals[corner], t, ERR_TOL); + } + } + } + + /// Tests the consistency correction + /// \brief Status : fails because it is not significant - the consistency correction is not brought into play + void TransformedTriangleTest::test_calcStableC_Consistency() + { + + typedef TransformedTriangle::TriSegment TriSegment; + typedef TransformedTriangle::TetraCorner TetraCorner; + + // grandy, eq 14 + double correct_c_vals[24] = + { + p2[0] * q2[1] - p2[1] * q2[0], + p2[1] * q2[2] - p2[2] * q2[1], + p2[2] * q2[0] - p2[0] * q2[2], + p2[0] * hq2 - hp2 * q2[0], + p2[1] * hq2 - hp2 * q2[1], + p2[2] * hq2 - hp2 * q2[2], + Hp2 * q2[0] - p2[0] * Hq2, + p2[1] * Hq2 - Hp2 * q2[1], + q2[0] * r2[1] - q2[1] * r2[0], + q2[1] * r2[2] - q2[2] * r2[1], + q2[2] * r2[0] - q2[0] * r2[2], + q2[0] * hr2 - hq2 * r2[0], + q2[1] * hr2 - hq2 * r2[1], + q2[2] * hr2 - hq2 * r2[2], + Hq2 * r2[0] - q2[0] * Hr2, + q2[1] * Hr2 - Hq2 * r2[1], + r2[0]*p2[1]-r2[1]*p2[0], + r2[1]*p2[2]-r2[2]*p2[1], + r2[2]*p2[0]-r2[0]*p2[2], + r2[0] * hp2 - hr2 * p2[0], + r2[1] * hp2 - hr2 * p2[1], + r2[2] * hp2 - hr2 * p2[2], + Hr2 * p2[0] - r2[0] * Hp2, + r2[1] * Hp2 - Hr2 * p2[1] + }; + + + // number of inconsistent cases found : + // should be (at least) 1 for the test to be meaningful + int num_cases = 0; + + // find unstable products to check for consistency (Grandy [46]) + for(TriSegment seg = TransformedTriangle::PQ ; seg <= TransformedTriangle::RP ; seg = TriSegment(seg + 1)) + { + const double c_xy = tri2->calcUnstableC(seg, TransformedTriangle::C_XY); + const double c_yz = tri2->calcUnstableC(seg, TransformedTriangle::C_YZ); + const double c_zx = tri2->calcUnstableC(seg, TransformedTriangle::C_ZX); + const double c_xh = tri2->calcUnstableC(seg, TransformedTriangle::C_XH); + const double c_yh = tri2->calcUnstableC(seg, TransformedTriangle::C_YH); + const double c_zh = tri2->calcUnstableC(seg, TransformedTriangle::C_ZH); + + const int num_zero = (c_yz*c_xh == 0.0 ? 1 : 0) + (c_zx*c_yh == 0.0 ? 1 : 0) + (c_xy*c_zh == 0.0 ? 1 : 0); + const int num_neg = (c_yz*c_xh < 0.0 ? 1 : 0) + (c_zx*c_yh < 0.0 ? 1 : 0) + (c_xy*c_zh < 0.0 ? 1 : 0); + + if((num_zero == 1 && num_neg != 1) || num_zero == 2 || num_neg == 0 && num_zero !=3 || num_neg == 3 ) + { + ++num_cases; + + double min_dist = -1.0; // initialised first time through loop + TetraCorner min_corner = TransformedTriangle::O; + + for(TetraCorner corner = TransformedTriangle::O ; corner <= TransformedTriangle::Z ; corner = TetraCorner(corner + 1)) + { + // calculate distance from each corner of tetraeder to the segment + // formula : ( (Q-P) x (P - corner) )^2 / norm(Q-P)^2 + + const double ptP[3] = { tri2->_coords[5*seg], tri2->_coords[5*seg + 1], tri2->_coords[5*seg + 2] }; + const double ptQ[3] = { tri2->_coords[5*( (seg+1) % 3)], tri2->_coords[5*( (seg+1) % 3) + 1], tri2->_coords[5*( (seg+1) % 3) + 2] }; + const double ptCorner[3] = { + corner == TransformedTriangle::X ? 1.0 : 0.0, + corner == TransformedTriangle::Y ? 1.0 : 0.0, + corner == TransformedTriangle::Z ? 1.0 : 0.0, + }; + + const double diff_21[3] = { ptQ[0] - ptP[0], ptQ[1] - ptP[1], ptQ[2] - ptP[2] }; + const double diff_1_corner[3] = { ptP[0] - ptCorner[0], ptP[1] - ptCorner[1], ptP[2] - ptCorner[2] }; + + const double cross[3] = { + diff_21[1]*diff_1_corner[2] - diff_21[2]*diff_1_corner[1], + diff_21[2]*diff_1_corner[0] - diff_21[0]*diff_1_corner[2], + diff_21[0]*diff_1_corner[1] - diff_21[1]*diff_1_corner[0] + }; + + const double cross_sq = cross[0]*cross[0] + cross[1]*cross[1] + cross[2]*cross[2]; + + const double norm_pq = diff_21[0]*diff_21[0] + diff_21[1]*diff_21[1] + diff_21[2]*diff_21[2]; + + if(corner == TransformedTriangle::O || (cross_sq / norm_pq) < min_dist) + { + min_dist = cross_sq / norm_pq; + min_corner = corner; + } + } + + // now check if the corresponding double products are zero + static const DoubleProduct DOUBLE_PRODUCTS[12] = + { + TransformedTriangle::C_YZ, TransformedTriangle::C_XY, TransformedTriangle::C_ZX, // O + TransformedTriangle::C_ZH, TransformedTriangle::C_YZ, TransformedTriangle::C_YH, // X + TransformedTriangle::C_ZH, TransformedTriangle::C_ZX, TransformedTriangle::C_XH, // Y + TransformedTriangle::C_XY, TransformedTriangle::C_YH, TransformedTriangle::C_XH // Z + }; + + for(int i = 0; i < 3 ; ++i) + { + DoubleProduct dp = DOUBLE_PRODUCTS[3*min_corner + i]; + // std::cout << std::endl << "in test inconsistent (seg,dp) :(" << seg <<", " << dp << ")" << std::endl; + CPPUNIT_ASSERT_EQUAL(0.0, tri2->calcStableC(seg, dp)); + correct_c_vals[8*seg + dp] = 0.0; + } + } + + } + + if(num_cases < 1) + { + CPPUNIT_FAIL("Consistency test not pertinent"); + } + + // std::cout << std::endl << "Number of geometric inconsistencies : " << num_cases << std::endl; + + // check that all other double products have right value too + double c_vals[8*3]; + + for(TriSegment seg = TransformedTriangle::PQ ; seg <= TransformedTriangle::RP ; seg = TriSegment(seg + 1)) { + + c_vals[seg*8 + 0] = tri2->calcStableC(seg, TransformedTriangle::C_XY); + c_vals[seg*8 + 1] = tri2->calcStableC(seg, TransformedTriangle::C_YZ); + c_vals[seg*8 + 2] = tri2->calcStableC(seg, TransformedTriangle::C_ZX); + c_vals[seg*8 + 3] = tri2->calcStableC(seg, TransformedTriangle::C_XH); + c_vals[seg*8 + 4] = tri2->calcStableC(seg, TransformedTriangle::C_YH); + c_vals[seg*8 + 5] = tri2->calcStableC(seg, TransformedTriangle::C_ZH); + c_vals[seg*8 + 6] = tri2->calcStableC(seg, TransformedTriangle::C_01); + c_vals[seg*8 + 7] = tri2->calcStableC(seg, TransformedTriangle::C_10); + + } + + for(int i = 0 ; i < 24 ; ++i) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(correct_c_vals[i], c_vals[i], ERR_TOL); + } + } + +} diff --git a/src/INTERP_KERNELTest/TransformedTriangleTest.hxx b/src/INTERP_KERNELTest/TransformedTriangleTest.hxx new file mode 100644 index 000000000..c3ff65de7 --- /dev/null +++ b/src/INTERP_KERNELTest/TransformedTriangleTest.hxx @@ -0,0 +1,87 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TU_TRANSFORMED_TRIANGLE_HXX__ +#define __TU_TRANSFORMED_TRIANGLE_HXX__ + +#include +#include "../TransformedTriangle.hxx" + +#define ERR_TOL 1.0e-8 + +using INTERP_KERNEL::TransformedTriangle; + +namespace INTERP_TEST +{ + + /** + * \brief Test suite testing some of the low level methods of TransformedTriangle. + * + */ + class TransformedTriangleTest : public CppUnit::TestFixture + { + + CPPUNIT_TEST_SUITE( TransformedTriangleTest ); + CPPUNIT_TEST( test_constructor ); + CPPUNIT_TEST( test_calcUnstableC ); + CPPUNIT_TEST( test_calcUnstableT ); + //removed because the test fails to enter the desired code branch + // CPPUNIT_TEST( test_calcStableC_Consistency ); + CPPUNIT_TEST_SUITE_END(); + + typedef INTERP_KERNEL::TransformedTriangle::TriSegment TriSegment; + typedef INTERP_KERNEL::TransformedTriangle::DoubleProduct DoubleProduct; + + public: + void setUp(); + + void tearDown(); + + // tests + void test_constructor(); + + void test_calcUnstableC(); + + void test_calcUnstableT(); + + void test_calcStableC_Consistency(); + + double p1[3], q1[3], r1[3]; + double hp1, hq1, hr1; + double Hp1, Hq1, Hr1; + + double p2[3], q2[3], r2[3]; + double hp2, hq2, hr2; + double Hp2, Hq2, Hr2; + + double stable_c2[24]; + + private: + TransformedTriangle* tri1; + TransformedTriangle* tri2; + + }; + + + + +} + + + +#endif diff --git a/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.cxx b/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.cxx new file mode 100644 index 000000000..c92b25e5e --- /dev/null +++ b/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.cxx @@ -0,0 +1,293 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +// File : UnitTetraIntersectionBaryTest.cxx +// Created : Thu Dec 11 15:54:41 2008 +// Author : Edward AGAPOV (eap) +#include "UnitTetraIntersectionBaryTest.hxx" + +#include "UnitTetraIntersectionBary.hxx" +#include "TetraAffineTransform.hxx" +#include "InterpolationUtils.hxx" + +#include + +using namespace INTERP_KERNEL; +using namespace std; + +namespace INTERP_TEST +{ + void fill_UnitTetraIntersectionBary(UnitTetraIntersectionBary& bary, double nodes[][3]) + { + int faceConn[4][3] = { { 0, 2, 1 }, + { 0, 1, 3 }, + { 1, 2, 3 }, + { 3, 2, 0 } }; + bary.init(); + for ( int i = 0; i < 4; ++i ) { + int* faceNodes = faceConn[ i ]; + TransformedTriangle tri(nodes[faceNodes[0]], nodes[faceNodes[1]], nodes[faceNodes[2]]); + tri.calculateIntersectionVolume(); + bary.addSide( tri ); + } + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_1() + { + // cutting tetra coincides with the unit one + double nodes[4][3] = { { 0.0, 0.0, 0.0 }, + { 1.0, 0.0, 0.0 }, + { 0.0, 1.0, 0.0 }, + { 0.0, 0.0, 1.0 } }; + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.166667, vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[0], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[1], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[2], 1e-5); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_2() + { + // cutting tetra fully include the unit one + double nodes[4][3] = { {-0.1,-0.1,-0.1 }, + { 1.5,-0.1,-0.1 }, + {-0.1, 1.5,-0.1 }, + {-0.1,-0.1, 1.5 } }; + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.166667, vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[0], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[1], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[2], 1e-5); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_3() + { + // cutting tetra is same as the unit one but moved up by 0.5 + double nodes[4][3] = { { 0.0, 0.0, 0.5 }, + { 1.0, 0.0, 0.5 }, + { 0.0, 1.0, 0.5 }, + { 0.0, 0.0, 1.5 } }; + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.020833333333333332, vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125, baryCenter[0], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125, baryCenter[1], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.625, baryCenter[2], 1e-5); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_4() + { + // same as previous but no cutting sides lay on the sides of unit tetra + double nodes[4][3] = { {-0.2,-0.2, 0.5 }, + { 1.0, 0.0, 0.5 }, + { 0.0, 1.0, 0.5 }, + { 0.0, 0.0, 2.0 } }; + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.020833333333333332, vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125, baryCenter[0], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125, baryCenter[1], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.625, baryCenter[2], 1e-5); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_5() + { + // cutting tetra is similar and parallel to the UT but moved (-0.1,-0.1,-0.1) + double nodes[4][3] = { {-0.1,-0.1,-0.1 }, + { 1.1,-0.1,-0.1 }, + {-0.1, 1.1,-0.1 }, + {-0.1,-0.1, 1.1 } }; + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.1215, vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.225, baryCenter[0], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.225, baryCenter[1], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.225, baryCenter[2], 1e-5); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_6() + { + // cutting tetra is deeped into the UT with one corner + double nodes[4][3] = { { 0.2, 0.2, 0.2 }, + { 1.0, 0.2, 0.2 }, + { 0.9, 1.0, 0.2 }, + { 0.9, 9.0, 1.0 } }; + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.000441855, vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.353463 , baryCenter[0], 1e-5 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.33877 , baryCenter[1], 1e-5 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.207767 , baryCenter[2], 1e-5 ); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_7() + { + // cutting tetra passes through the UT with one corner + double nodes[4][3] = { {-0.2, 0.2, 0.2 }, + { 1.0, 0.2, 0.2 }, + { 0.9, 1.0, 0.2 }, + { 0.9, 0.9, 1.0 } }; + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0103501, vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.215578 , baryCenter[0], 1e-5 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.341363 , baryCenter[1], 1e-5 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.263903 , baryCenter[2], 1e-5 ); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_8() + { + // cutting tetra passes through the UT with one edge + double nodes[4][3] = { { 0.5, 0.2, -0.2 }, // O + {-0.5,-0.2, -0.2 }, // OX + { 1.0,-0.5, -0.2 }, // OY + { 0.5, 0.2, 1.5 } };//OZ + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0349217, vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.332275 , baryCenter[0], 1e-2 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0565892 , baryCenter[1], 1e-3 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.308713 , baryCenter[2], 1e-2 ); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_9() + { + // cutting tetra touches the UT at an edge, intersection volume == 0 + double nodes[4][3] = { { 1.0, 0.0, 0.0 }, // 0 + {-1.0, 2.0, 2.0 }, // OX + {-1.0,-2.0, 2.0 }, // OY + { 1.0, 0.0, 2.0 } };//OZ + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( !ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, vol, 1e-15); + CPPUNIT_ASSERT_DOUBLES_EQUAL( -1. , baryCenter[0], 1e-5 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( -1. , baryCenter[1], 1e-5 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( -1. , baryCenter[2], 1e-5 ); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_10() + { + // cutting tetra fully includes theUT and touches it at an edge + double nodes[4][3] = { { 1.0, 0.0, 0.0 }, // 0 + {-1.0,-4.0, 2.0 }, // OX + {-1.0, 4.0, 2.0 }, // OY + { 1.0, 0.0,-2.0 } };//OZ + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.166667, vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[0], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[1], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[2], 1e-5); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_11() + { + // cutting tetra intersects the UT and touches it at an edge + double nodes[4][3] = { { 1.0, 0.0, 0.0 }, // 0 + {-1.0,-4.0, 2.0 }, // OX + {-1.0, 4.0, 2.0 }, // OY + {-1.0, 0.0,-1.0 } };//OZ + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.15873 , vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.250000, baryCenter[0], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.230952, baryCenter[1], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.260714, baryCenter[2], 1e-5); + } + + void UnitTetraIntersectionBaryTest::test_TetraAffineTransform_reverseApply() + { + double nodes[4][3] = { {-4.0, 9.0, 3.0 }, + {11.0, 0.0, 2.0 }, + { 0.0, 0.0, 0.0 }, + { 2.0, 1.0,10.0 }}; + // double pSrc[3] = { -4.0, 9.0, 3.0 }; + double pSrc[3] = { 40., -20., 100. }; + double pDest[] = {1,1,1}; + const double* n[4] = { &nodes[0][0], &nodes[1][0], &nodes[2][0], &nodes[3][0] }; + TetraAffineTransform a(&n[0]); + a.apply( pDest, pSrc ); + a.reverseApply( pDest, pDest ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( pSrc[0], pDest[0], 1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL( pSrc[1], pDest[1], 1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL( pSrc[2], pDest[2], 1e-12); + } + + void UnitTetraIntersectionBaryTest::test_barycentric_coords() + { + // compute barycentric coordinates + double nodes[4][3] = { {11.0, 0.0, 2.0 }, + {-4.0, 9.0, 3.0 }, + { 0.0, 0.0, 0.0 }, + { 6.0, 1.0,10.0 }}; + vector n (4); + n[0] = &nodes[0][0]; + n[1] = &nodes[1][0]; + n[2] = &nodes[2][0]; + n[3] = &nodes[3][0]; + double p [3] = { 2, 2, 5 }, bc[4]; + barycentric_coords(n, p, bc); + double bcSum = 0; + double p2 [3] = { 0,0,0 }; + for ( int i = 0; i < 4; ++i ) { + bcSum += bc[i]; + p2[0] += bc[i]*n[i][0]; + p2[1] += bc[i]*n[i][1]; + p2[2] += bc[i]*n[i][2]; + } + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., bcSum, 1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL( p[0], p2[0], 1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL( p[1], p2[1], 1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL( p[2], p2[2], 1e-12); + } +} diff --git a/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.hxx b/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.hxx new file mode 100644 index 000000000..26c1be3fd --- /dev/null +++ b/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.hxx @@ -0,0 +1,67 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +// File : UnitTetraIntersectionBaryTests.hxx +// Created : Thu Nov 6 17:11:27 2008 +// Author : Edward AGAPOV (eap) +#ifndef __UNITTETRAINTERSECTIONBARYTEST_HXX__ +#define __UNITTETRAINTERSECTIONBARYTEST_HXX__ + +#include + +namespace INTERP_TEST +{ + /** + * \brief Test suite testing UnitTetraIntersectionBary class. + * + */ + class UnitTetraIntersectionBaryTest : public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE( UnitTetraIntersectionBaryTest ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_1 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_2 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_3 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_4 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_5 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_6 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_7 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_8 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_9 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_10 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_11 ); + CPPUNIT_TEST( test_TetraAffineTransform_reverseApply ); + CPPUNIT_TEST( test_barycentric_coords ); + CPPUNIT_TEST_SUITE_END(); + public: + void test_UnitTetraIntersectionBary_1(); + void test_UnitTetraIntersectionBary_2(); + void test_UnitTetraIntersectionBary_3(); + void test_UnitTetraIntersectionBary_4(); + void test_UnitTetraIntersectionBary_5(); + void test_UnitTetraIntersectionBary_6(); + void test_UnitTetraIntersectionBary_7(); + void test_UnitTetraIntersectionBary_8(); + void test_UnitTetraIntersectionBary_9(); + void test_UnitTetraIntersectionBary_10(); + void test_UnitTetraIntersectionBary_11(); + void test_TetraAffineTransform_reverseApply(); + void test_barycentric_coords(); + }; +} + +#endif diff --git a/src/INTERP_KERNELTest/perf_test.sh b/src/INTERP_KERNELTest/perf_test.sh new file mode 100755 index 000000000..1a087b4a6 --- /dev/null +++ b/src/INTERP_KERNELTest/perf_test.sh @@ -0,0 +1,165 @@ +#!/bin/bash +# Copyright (C) 2007-2008 CEA/DEN, 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. +# +# 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 +# +# should be run from the build directory, so that ./PerfTest is available +# output file +# +RES_FILE=perf_OPTIMIZE + +#outputs lines of form : +#"no. source elems no. target elems user time" +function test_pair { + echo -n $1 | sed 's/\(PerfCyl\)\([0-9]*\)/\2/' | sed 's/\(PerfBoxT\)\([0-9]*\)/\2/' | sed 's/\(PerfBox\)\([0-9]*\)/\2/' >> $RES_FILE + echo -n " " >> $RES_FILE + echo -n $2 | sed 's/\(PerfCyl\)\([0-9]*\)/\2/' | sed 's/\(PerfBoxT\)\([0-9]*\)/\2/' | sed 's/\(PerfBox\)\([0-9]*\)/\2/' >> $RES_FILE + echo -n " " >> $RES_FILE + time -o $RES_FILE --append -f"%U" ./PerfTest $1 $2 + echo +} + +function test_box_box { +echo PerfBox PerfBox >> $RES_FILE + +test_pair PerfBox1495 PerfBox1495 +test_pair PerfBox2506 PerfBox2506 +test_pair PerfBox5708 PerfBox5708 +test_pair PerfBox13461 PerfBox13461 +test_pair PerfBox30808 PerfBox30808 +test_pair PerfBox47176 PerfBox47176 + +test_pair PerfBox1495 PerfBox2506 +test_pair PerfBox1495 PerfBox5708 +test_pair PerfBox1495 PerfBox13461 +test_pair PerfBox1495 PerfBox30808 +test_pair PerfBox1495 PerfBox47176 + +test_pair PerfBox2506 PerfBox5708 +test_pair PerfBox2506 PerfBox13461 +test_pair PerfBox2506 PerfBox30808 +test_pair PerfBox2506 PerfBox47176 + +test_pair PerfBox5708 PerfBox13461 +test_pair PerfBox5708 PerfBox30808 +test_pair PerfBox5708 PerfBox47176 + +test_pair PerfBox13461 PerfBox30808 +test_pair PerfBox13461 PerfBox47176 + +test_pair PerfBox30808 PerfBox47176 + +} + +function test_cyl_cyl { +echo PerfCyl PerfCyl >> $RES_FILE + +test_pair PerfCyl1047 PerfCyl1047 +test_pair PerfCyl3020 PerfCyl3020 +test_pair PerfCyl6556 PerfCyl6556 +test_pair PerfCyl9766 PerfCyl9766 +test_pair PerfCyl25745 PerfCyl25745 +test_pair PerfCyl47601 PerfCyl47601 + +test_pair PerfCyl1047 PerfCyl3020 +test_pair PerfCyl1047 PerfCyl6556 +test_pair PerfCyl1047 PerfCyl9766 +test_pair PerfCyl1047 PerfCyl25745 +test_pair PerfCyl1047 PerfCyl47601 + +test_pair PerfCyl3020 PerfCyl6556 +test_pair PerfCyl3020 PerfCyl9766 +test_pair PerfCyl3020 PerfCyl25745 +test_pair PerfCyl3020 PerfCyl47601 + +test_pair PerfCyl6556 PerfCyl9766 +test_pair PerfCyl6556 PerfCyl25745 +test_pair PerfCyl6556 PerfCyl47601 + +test_pair PerfCyl9766 PerfCyl25745 +test_pair PerfCyl9766 PerfCyl47601 + +test_pair PerfCyl25745 PerfCyl47601 + +} + +function test_box_cyl { + echo PerfBox PerfCyl >> $RES_FILE + test_pair PerfBox1495 PerfCyl1047 + test_pair PerfBox1495 PerfCyl3020 + test_pair PerfBox1495 PerfCyl6556 + test_pair PerfBox1495 PerfCyl9766 + test_pair PerfBox1495 PerfCyl25745 + test_pair PerfBox1495 PerfCyl47601 + + test_pair PerfBox2506 PerfCyl1047 + test_pair PerfBox2506 PerfCyl3020 + test_pair PerfBox2506 PerfCyl6556 + test_pair PerfBox2506 PerfCyl9766 + test_pair PerfBox2506 PerfCyl25745 + test_pair PerfBox2506 PerfCyl47601 + + test_pair PerfBox5708 PerfCyl1047 + test_pair PerfBox5708 PerfCyl3020 + test_pair PerfBox5708 PerfCyl6556 + test_pair PerfBox5708 PerfCyl9766 + test_pair PerfBox5708 PerfCyl25745 + test_pair PerfBox5708 PerfCyl47601 + + test_pair PerfBox13461 PerfCyl1047 + test_pair PerfBox13461 PerfCyl3020 + test_pair PerfBox13461 PerfCyl6556 + test_pair PerfBox13461 PerfCyl9766 + test_pair PerfBox13461 PerfCyl25745 + test_pair PerfBox13461 PerfCyl47601 + + test_pair PerfBox30808 PerfCyl1047 + test_pair PerfBox30808 PerfCyl3020 + test_pair PerfBox30808 PerfCyl6556 + test_pair PerfBox30808 PerfCyl9766 + test_pair PerfBox30808 PerfCyl25745 + test_pair PerfBox30808 PerfCyl47601 + + test_pair PerfBox47176 PerfCyl1047 + test_pair PerfBox47176 PerfCyl3020 + test_pair PerfBox47176 PerfCyl6556 + test_pair PerfBox47176 PerfCyl9766 + test_pair PerfBox47176 PerfCyl25745 + test_pair PerfBox47176 PerfCyl47601 +} + +function test_box_transbox { + echo PerfBox PerfBoxT >> $RES_FILE + test_pair PerfBox1495 PerfBoxT1493 + test_pair PerfBox2506 PerfBoxT2676 + test_pair PerfBox5708 PerfBoxT5717 + test_pair PerfBox13461 PerfBoxT12469 + test_pair PerfBox30808 PerfBoxT29019 + test_pair PerfBox47176 PerfBoxT47278 +} + + + +#functions to execute : + +echo PerfTest execution on `date` > $RES_FILE +test_box_cyl +test_box_box +test_cyl_cyl +test_box_transbox + +cat $RES_FILE \ No newline at end of file diff --git a/src/MED/MED_test1.py b/src/MED/MED_test1.py index ee5810b29..3546ed5c3 100755 --- a/src/MED/MED_test1.py +++ b/src/MED/MED_test1.py @@ -1,31 +1,30 @@ -# MED MED : implemetation of MED idl descriptions +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# 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 # +# MED MED : implemetation of MED idl descriptions # File : MED_test1.py # Author : # Module : MED # $Header$ - +# import salome med=salome.lcc.FindOrLoadComponent("FactoryServer", "MED") @@ -35,9 +34,9 @@ import os #befor running this script, please be sure about the path the file fileName # filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") fileName="pointe.med" -fileTout=filePath+fileName +fileTout=os.path.join(filePath,fileName) print fileTout diff --git a/src/MED/MED_test2.py b/src/MED/MED_test2.py index 9f1776cb4..5715f9572 100755 --- a/src/MED/MED_test2.py +++ b/src/MED/MED_test2.py @@ -1,38 +1,37 @@ -# MED MED : implemetation of MED idl descriptions +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# 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 # +# MED MED : implemetation of MED idl descriptions # File : MED_test2.py # Author : # Module : MED # $Header$ - +# import salome import SALOME import os filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" -medFile=filePath+"mesh.med" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") +medFile=os.path.join(filePath, "mesh.med") med=salome.lcc.FindOrLoadComponent("FactoryServer", "MED") @@ -50,7 +49,7 @@ except SALOME.SALOME_Exception, ex: print mesh.getName() print mesh.getNumberOfNodes() -medFile = filePath+"pointe.med" +medFile = os.path.join(filePath,"pointe.med") try: field=med.readFieldInFile(medFile,salome.myStudyName,"fieldcelldouble",-1,-1) except SALOME.SALOME_Exception, ex: diff --git a/src/MED/Makefile.am b/src/MED/Makefile.am index 319dee829..76d71c2f0 100644 --- a/src/MED/Makefile.am +++ b/src/MED/Makefile.am @@ -1,6 +1,6 @@ -# MED MED : implemetation of MED idl descriptions +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # # This library is free software; you can redistribute it and/or @@ -17,10 +17,10 @@ # 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # +# MED MED : implemetation of MED idl descriptions # - include $(top_srcdir)/adm_local/unix/make_common_starter.am lib_LTLIBRARIES= libMEDEngine.la @@ -28,14 +28,14 @@ lib_LTLIBRARIES= libMEDEngine.la dist_libMEDEngine_la_SOURCES= Med_Gen_i.cxx Med_Gen_Driver_i.cxx salomeinclude_HEADERS = Med_Gen_i.hxx Med_Gen_Driver_i.hxx -libMEDEngine_la_CPPFLAGS= @CAS_CPPFLAGS@ $(MED2_INCLUDES) $(HDF5_INCLUDES) ${KERNEL_CXXFLAGS} @CORBA_CXXFLAGS@ @CORBA_INCLUDES@ \ +libMEDEngine_la_CPPFLAGS= $(MED2_INCLUDES) $(HDF5_INCLUDES) ${KERNEL_CXXFLAGS} @CORBA_CXXFLAGS@ @CORBA_INCLUDES@ \ -I$(srcdir)/../MEDMEM_I -I$(top_builddir)/salome_adm/unix -I$(top_builddir)/idl \ -I$(srcdir)/../MEDMEM -I$(srcdir)/../MEDWrapper/V2_1/Core libMEDEngine_la_LDFLAGS=\ $(top_builddir)/idl/libSalomeIDLMED.la \ ../MEDMEM_I/libMEDMEMImpl.la \ - ${KERNEL_LDFLAGS} -lTOOLSDS -lSalomeHDFPersist + ${KERNEL_LDFLAGS} -lTOOLSDS -lSalomeHDFPersist -lSalomeContainer # ${KERNEL_LDFLAGS} \ # @CORBA_LIBS@ \ # @CAS_OCAF@ \ diff --git a/src/MED/Med_Gen_Driver_i.cxx b/src/MED/Med_Gen_Driver_i.cxx index c8a06cbfd..7669838bc 100755 --- a/src/MED/Med_Gen_Driver_i.cxx +++ b/src/MED/Med_Gen_Driver_i.cxx @@ -1,6 +1,6 @@ -// MED MED : implemetation of MED idl descriptions +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // // This library is free software; you can redistribute it and/or @@ -19,12 +19,11 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// +// MED MED : implemetation of MED idl descriptions // File : Med_Gen_Driver_i.cxx // Author : Paul RASCLE, EDF // Module : MED -// $Header$ - +// #include "Med_Gen_Driver_i.hxx" #include "MEDMEM_Mesh_i.hxx" @@ -52,9 +51,6 @@ #include #include -#include -#include - #include using namespace std; @@ -183,8 +179,8 @@ namespace { bool isMultiFile, bool isAscii) { - const char* LOC = "Med_Gen_Driver_i::Save"; - BEGIN_OF(LOC); + const char* LOC = "Med_Gen_Driver_i::Save"; + BEGIN_OF(LOC); // Write all MEDMEM objects in one med file because of problems with // reference to external mesh when writting field in a separate file. @@ -283,7 +279,7 @@ namespace { SALOMEDS_Tool::RemoveTemporaryFiles(aPath.c_str(), aSeq.in(), true); } // Return the created byte stream - END_OF(LOC); + END_OF(LOC); return aStreamFile._retn(); } // end of saveStudy() @@ -539,7 +535,7 @@ char* Med_Gen_Driver_i::IORToLocalPersistentID (SALOMEDS::SObject_ptr theSObject CORBA::Boolean isMultiFile, CORBA::Boolean isASCII) { - const char * LOC = "Med_Gen_Driver_i::IORToLocalPersistentID"; + const char* LOC = "Med_Gen_Driver_i::IORToLocalPersistentID"; BEGIN_OF(LOC); SCRUTE(IORString); @@ -623,7 +619,7 @@ char* Med_Gen_Driver_i::LocalPersistentIDToIOR (SALOMEDS::SObject_ptr theSObject CORBA::Boolean isASCII) throw(SALOME::SALOME_Exception) { - const char * LOC = "Med_Gen_Driver_i::LocalPersistentIDToIOR"; + const char* LOC = "Med_Gen_Driver_i::LocalPersistentIDToIOR"; BEGIN_OF(LOC); // all object are restored in Load() if their name in study coincides @@ -652,6 +648,10 @@ char* Med_Gen_Driver_i::LocalPersistentIDToIOR (SALOMEDS::SObject_ptr theSObject aMeshName[aMeshNameLen-1] = 0; try { object = med->getMeshByName( aMeshName.c_str() ); + if ( CORBA::is_nil( object )) { + aMeshName = healName( aMeshName ); + object = med->getMeshByName( aMeshName.c_str() ); + } } catch (const std::exception & ex) { SCRUTE(ex.what()); @@ -669,6 +669,10 @@ char* Med_Gen_Driver_i::LocalPersistentIDToIOR (SALOMEDS::SObject_ptr theSObject // Get a field that is already read try { object = med->getField( aFieldName.c_str(), anIterNumber, aNumOrdre ); + if ( CORBA::is_nil( object )) { + aFieldName = healName( aFieldName ); + object = med->getField( aFieldName.c_str(), anIterNumber, aNumOrdre ); + } } catch (const std::exception & ex) { SCRUTE(ex.what()); @@ -686,6 +690,10 @@ char* Med_Gen_Driver_i::LocalPersistentIDToIOR (SALOMEDS::SObject_ptr theSObject if ( type == "SUPPORT" ) { try { object = med_i->getSupport( meshName, medEntity ); + if ( CORBA::is_nil( object )) { + meshName = healName( meshName ); + object = med_i->getSupport( meshName, medEntity ); + } } catch (const std::exception & ex) { SCRUTE(ex.what()); @@ -697,6 +705,10 @@ char* Med_Gen_Driver_i::LocalPersistentIDToIOR (SALOMEDS::SObject_ptr theSObject SALOME_MED::MESH_var mesh; try { mesh = med->getMeshByName( meshName.c_str() ); + if ( mesh->_is_nil() ) { + meshName = healName( meshName ); + mesh = med->getMeshByName( meshName.c_str() ); + } } catch (const std::exception & ex) { SCRUTE(ex.what()); @@ -704,17 +716,20 @@ char* Med_Gen_Driver_i::LocalPersistentIDToIOR (SALOMEDS::SObject_ptr theSObject SALOME::INTERNAL_ERROR); } if ( !mesh->_is_nil() ) { + string healedName = healName( name ); try { if ( type == "FAMILY" ) { SALOME_MED::Family_array_var families = mesh->getFamilies( medEntity ); for ( int i = 0; CORBA::is_nil(object) && i <= families->length(); ++i ) - if ( families[ i ]->getName() == name ) + if ( families[ i ]->getName() == name || + families[ i ]->getName() == healedName ) object = SALOME_MED::FAMILY::_duplicate( families[ i ]); } else { SALOME_MED::Group_array_var groups = mesh->getGroups( medEntity ); for ( int i = 0; CORBA::is_nil(object) && i <= groups->length(); ++i ) - if ( groups[ i ]->getName() == name ) + if ( groups[ i ]->getName() == name || + groups[ i ]->getName() == healedName ) object = SALOME_MED::GROUP::_duplicate( groups[ i ]); } } diff --git a/src/MED/Med_Gen_Driver_i.hxx b/src/MED/Med_Gen_Driver_i.hxx index a0110fcf8..56ebdcf7f 100644 --- a/src/MED/Med_Gen_Driver_i.hxx +++ b/src/MED/Med_Gen_Driver_i.hxx @@ -1,6 +1,6 @@ -// MED MED : implemetation of MED idl descriptions +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // // This library is free software; you can redistribute it and/or @@ -19,11 +19,11 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// +// MED MED : implemetation of MED idl descriptions // File : Med_Gen_Driver_i.hxx // Author : Paul RASCLE, EDF // Module : MED - +// #ifndef _MED_GEN_DRIVER_I_HXX_ #define _MED_GEN_DRIVER_I_HXX_ diff --git a/src/MED/Med_Gen_i.cxx b/src/MED/Med_Gen_i.cxx index 8af700ac5..4f573d3b0 100755 --- a/src/MED/Med_Gen_i.cxx +++ b/src/MED/Med_Gen_i.cxx @@ -1,6 +1,6 @@ -// MED MED : implemetation of MED idl descriptions +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // // This library is free software; you can redistribute it and/or @@ -19,12 +19,12 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// +// MED MED : implemetation of MED idl descriptions // File : Med_Gen_i.cxx // Author : Paul RASCLE, EDF // Module : MED // $Header$ - +// #include "Med_Gen_i.hxx" #include "MEDMEM_Mesh.hxx" @@ -55,9 +55,6 @@ #include #include -#include -#include - #include using namespace std; @@ -265,7 +262,8 @@ void Med_Gen_i::readStructFileWithFieldType (const char* fileName, { beginService("Med_Gen_i::readStructFileWithFieldType"); - BEGIN_OF("Med_Gen_i::readStructFileWithFieldType (const char* fileName,const char* studyName)"); + const char* LOC = "Med_Gen_i::readStructFileWithFieldType (const char* fileName,const char* studyName)"; + BEGIN_OF(LOC); SCRUTE(fileName); SALOMEDS::Study_var myStudy = studyName2Study(studyName) ; @@ -295,7 +293,7 @@ void Med_Gen_i::readStructFileWithFieldType (const char* fileName, } endService("Med_Gen_i::readStructFileWithFieldType"); - END_OF("Med_Gen_i::readStructFileWithFieldType (const char* fileName,const char* studyName)"); + END_OF(LOC); } //============================================================================= diff --git a/src/MED/Med_Gen_i.hxx b/src/MED/Med_Gen_i.hxx index 59158af75..03fe445fd 100644 --- a/src/MED/Med_Gen_i.hxx +++ b/src/MED/Med_Gen_i.hxx @@ -1,6 +1,6 @@ -// MED MED : implemetation of MED idl descriptions +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // // This library is free software; you can redistribute it and/or @@ -19,11 +19,11 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// +// MED MED : implemetation of MED idl descriptions // File : Med_Gen_i.hxx // Author : Paul RASCLE, EDF // Module : MED - +// #ifndef _MED_GEN_I_HXX_ #define _MED_GEN_I_HXX_ diff --git a/src/MED/Med_Gen_test.py b/src/MED/Med_Gen_test.py index 1750d498c..9347e1ab4 100644 --- a/src/MED/Med_Gen_test.py +++ b/src/MED/Med_Gen_test.py @@ -1,27 +1,29 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# -#################################################################################################### +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +#################################################################################################### # Test the Med Component: mounting in Memory a .med file and trying to get information through # the CORBA Med API -# #################################################################################################### +# import string import salome @@ -130,9 +132,9 @@ medComp=salome.lcc.FindOrLoadComponent("FactoryServer", "MED") import os filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") -filePathName = filePath + fileName +filePathName = os.path.join(filePath, fileName) print "Reading the .med file ",filePathName," and pushing corba objects in the SALOME study" medComp.readStructFileWithFieldType(filePathName,salome.myStudyName) diff --git a/src/MED/testMedAlliances.py b/src/MED/testMedAlliances.py index a30672609..3d5149ba4 100755 --- a/src/MED/testMedAlliances.py +++ b/src/MED/testMedAlliances.py @@ -1,9 +1,30 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# import salome import SALOME import os filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") import string @@ -156,7 +177,7 @@ med = salome.lcc.FindOrLoadComponent("FactoryServer", "MED") for i in range(nbOfFiles): medFile = medFiles[i] print "Testing with the file ",medFile - medFile = filePath + medFile + medFile = os.path.join(filePath, medFile) med.readStructFile(medFile,salome.myStudyName) print "END of the Pyhton script ..... Ctrl D to exit" diff --git a/src/MED/testMedAlliances1.py b/src/MED/testMedAlliances1.py index bbd2a004b..6e309f90b 100755 --- a/src/MED/testMedAlliances1.py +++ b/src/MED/testMedAlliances1.py @@ -1,9 +1,30 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# import salome import SALOME import os filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") import string @@ -156,7 +177,7 @@ med=salome.lcc.FindOrLoadComponent("FactoryServer", "MED") for i in range(nbOfFiles): medFile = medFiles[i] print "Testing with the file ",medFile - medFile = filePath + medFile + medFile = os.path.join(filePath, medFile) med.readStructFileWithFieldType(medFile,salome.myStudyName) print "END of the Pyhton script ..... Ctrl D to exit" diff --git a/src/MEDCoupling/MEDCouplingField.cxx b/src/MEDCoupling/MEDCouplingField.cxx new file mode 100644 index 000000000..2139675a7 --- /dev/null +++ b/src/MEDCoupling/MEDCouplingField.cxx @@ -0,0 +1,49 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "MEDCouplingField.hxx" +#include "MEDCouplingMesh.hxx" + +using namespace ParaMEDMEM; + +void MEDCouplingField::updateTime() +{ + if(_mesh) + updateTimeWith(*_mesh); +} + +void MEDCouplingField::setMesh(MEDCouplingMesh *mesh) +{ + if(mesh!=_mesh) + { + if(_mesh) + _mesh->decrRef(); + _mesh=mesh; + if(_mesh) + { + _mesh->incrRef(); + updateTimeWith(*_mesh); + } + } +} + +MEDCouplingField::~MEDCouplingField() +{ + if(_mesh) + _mesh->decrRef(); +} diff --git a/src/MEDCoupling/MEDCouplingField.hxx b/src/MEDCoupling/MEDCouplingField.hxx new file mode 100644 index 000000000..c8e880a77 --- /dev/null +++ b/src/MEDCoupling/MEDCouplingField.hxx @@ -0,0 +1,61 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __PARAMEDMEM_MEDCOUPLINGFIELD_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGFIELD_HXX__ + +#include "RefCountObject.hxx" +#include "InterpKernelException.hxx" + +#include + +namespace ParaMEDMEM +{ + class MEDCouplingMesh; + + class MEDCouplingField : public RefCountObject + { + public: + virtual void checkCoherency() const throw(INTERP_KERNEL::Exception) = 0; + void setMesh(MEDCouplingMesh *mesh); + void setTime(double val) { _time=val; } + double getTime() const { return _time; } + void setDtIt(int dt, int it) { _dt=dt; _it=it; } + void getDtIt(int& dt, int& it) { dt=_dt; it=_it; } + MEDCouplingMesh *getMesh() const { return _mesh; } + void setName(const char *name) { _name=name; } + void setDescription(const char *desc) { _desc=desc; } + const char *getName() const { return _name.c_str(); } + TypeOfField getEntity() const { return _type; } + protected: + void updateTime(); + protected: + MEDCouplingField(TypeOfField type):_time(0.),_dt(-1),_it(-1),_mesh(0),_type(type) { } + virtual ~MEDCouplingField(); + protected: + std::string _name; + std::string _desc; + double _time; + int _dt; + int _it; + MEDCouplingMesh *_mesh; + const TypeOfField _type; + }; +} + +#endif diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx new file mode 100644 index 000000000..b13a9ec1e --- /dev/null +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -0,0 +1,116 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMesh.hxx" + +#include + +using namespace ParaMEDMEM; + +MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(TypeOfField type) +{ + return new MEDCouplingFieldDouble(type); +} + +MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type):MEDCouplingField(type),_array(0) +{ +} + +MEDCouplingFieldDouble::~MEDCouplingFieldDouble() +{ + if(_array) + _array->decrRef(); +} + +void MEDCouplingFieldDouble::checkCoherency() const throw(INTERP_KERNEL::Exception) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("Field invalid because no mesh specified !"); + if(!_array) + throw INTERP_KERNEL::Exception("Field invalid because no values set !"); + if(_type==ON_CELLS) + { + if(_mesh->getNumberOfCells()!=_array->getNumberOfTuples()) + { + std::ostringstream message; + message << "Field on cells invalid because there are " << _mesh->getNumberOfCells(); + message << " cells in mesh and " << _array->getNumberOfTuples() << " tuples in field !"; + throw INTERP_KERNEL::Exception(message.str().c_str()); + } + } + else if(_type==ON_NODES) + { + if(_mesh->getNumberOfNodes()!=_array->getNumberOfTuples()) + { + std::ostringstream message; + message << "Field on nodes invalid because there are " << _mesh->getNumberOfNodes(); + message << " cells in mesh and " << _array->getNumberOfTuples() << " tuples in field !"; + throw INTERP_KERNEL::Exception(message.str().c_str()); + } + } + else + throw INTERP_KERNEL::Exception("Field of undifined type !!!"); +} + +void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId) +{ + double *ptr=_array->getPointer(); + ptr+=compoId; + int nbOfComp=_array->getNumberOfComponents(); + int nbOfTuple=_array->getNumberOfTuples(); + for(int i=0;igetNumberOfComponents(); +} + +int MEDCouplingFieldDouble::getNumberOfTuples() const throw(INTERP_KERNEL::Exception) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("Impossible to retrieve number of tuples because no mesh specified !"); + if(_type==ON_CELLS) + return _mesh->getNumberOfCells(); + else if(_type==ON_NODES) + return _mesh->getNumberOfNodes(); + else + throw INTERP_KERNEL::Exception("Impossible to retrieve number of tuples because type of entity not implemented yet !"); +} + +void MEDCouplingFieldDouble::updateTime() +{ + MEDCouplingField::updateTime(); + if(_array) + updateTimeWith(*_array); +} + +void MEDCouplingFieldDouble::setArray(DataArrayDouble *array) +{ + if(array!=_array) + { + if(_array) + _array->decrRef(); + _array=array; + if(_array) + _array->incrRef(); + declareAsNew(); + } +} diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.hxx b/src/MEDCoupling/MEDCouplingFieldDouble.hxx new file mode 100644 index 000000000..82de9c3bd --- /dev/null +++ b/src/MEDCoupling/MEDCouplingFieldDouble.hxx @@ -0,0 +1,48 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __PARAMEDMEM_MEDCOUPLINGFIELDDOUBLE_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGFIELDDOUBLE_HXX__ + +#include "MEDCouplingField.hxx" +#include "MemArray.hxx" + +namespace ParaMEDMEM +{ + class MEDCouplingFieldDouble : public MEDCouplingField + { + public: + static MEDCouplingFieldDouble *New(TypeOfField type); + void checkCoherency() const throw(INTERP_KERNEL::Exception); + double getIJ(int tupleId, int compoId) const { return _array->getIJ(tupleId,compoId); } + void setArray(DataArrayDouble *array); + DataArrayDouble *getArray() const { return _array; } + //! \b temporary + void applyLin(double a, double b, int compoId); + int getNumberOfComponents() const; + int getNumberOfTuples() const throw(INTERP_KERNEL::Exception); + void updateTime(); + private: + MEDCouplingFieldDouble(TypeOfField type); + ~MEDCouplingFieldDouble(); + private: + DataArrayDouble *_array; + }; +} + +#endif diff --git a/src/MEDCoupling/MEDCouplingMesh.hxx b/src/MEDCoupling/MEDCouplingMesh.hxx new file mode 100644 index 000000000..78c1913a9 --- /dev/null +++ b/src/MEDCoupling/MEDCouplingMesh.hxx @@ -0,0 +1,45 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __PARAMEDMEM_MEDCOUPLINGMESH_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGMESH_HXX__ + +#include "RefCountObject.hxx" +#include "InterpKernelException.hxx" + +namespace ParaMEDMEM +{ + class MEDCouplingMesh : public RefCountObject + { + public: + void setName(const char *name) { _name=name; } + const char *getName() const { return _name.c_str(); } + virtual void checkCoherency() const throw(INTERP_KERNEL::Exception) = 0; + virtual bool isStructured() const = 0; + virtual int getNumberOfCells() const = 0; + virtual int getNumberOfNodes() const = 0; + virtual int getSpaceDimension() const = 0; + virtual int getMeshDimension() const = 0; + protected: + virtual ~MEDCouplingMesh() { } + private: + std::string _name; + }; +} + +#endif diff --git a/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx b/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx new file mode 100644 index 000000000..82c402f84 --- /dev/null +++ b/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx @@ -0,0 +1,57 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_HXX__ +#define __MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_HXX__ + +#include "NormalizedUnstructuredMesh.hxx" + +namespace ParaMEDMEM +{ + class MEDCouplingUMesh; +} + +template +class MEDCouplingNormalizedUnstructuredMesh : public INTERP_KERNEL::GenericMesh +{ +public: + static const int MY_SPACEDIM=SPACEDIM; + static const int MY_MESHDIM=MESHDIM; + typedef int MyConnType; + static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; +public: + MEDCouplingNormalizedUnstructuredMesh(ParaMEDMEM::MEDCouplingUMesh *mesh); + void getBoundingBox(double *boundingBox) const; + INTERP_KERNEL::NormalizedCellType getTypeOfElement(int eltId) const; + unsigned char getNumberOfNodesOfElement(int eltId) const; + unsigned long getNumberOfElements() const; + unsigned long getNumberOfNodes() const; + const int *getConnectivityPtr() const; + const double *getCoordinatesPtr() const; + const int *getConnectivityIndexPtr() const; + void ReleaseTempArrays(); + ~MEDCouplingNormalizedUnstructuredMesh(); +private: + void prepare(); +private: + ParaMEDMEM::MEDCouplingUMesh *_mesh; + int *_conn_for_interp; + int *_conn_index_for_interp; +}; + +#endif diff --git a/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx b/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx new file mode 100644 index 000000000..745137a96 --- /dev/null +++ b/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx @@ -0,0 +1,142 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_TXX__ +#define __MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_TXX__ + +#include "MEDCouplingNormalizedUnstructuredMesh.hxx" + +#include "MEDCouplingUMesh.hxx" +#include "MemArray.hxx" + +template +MEDCouplingNormalizedUnstructuredMesh::MEDCouplingNormalizedUnstructuredMesh(ParaMEDMEM::MEDCouplingUMesh *mesh):_mesh(mesh) +{ + if(_mesh) + _mesh->incrRef(); + prepare(); +} + +template +void MEDCouplingNormalizedUnstructuredMesh::getBoundingBox(double *boundingBox) const +{ + for(int i=0;i::max(); + boundingBox[SPACEDIM+i]=-std::numeric_limits::max(); + } + ParaMEDMEM::DataArrayDouble *array=_mesh->getCoords(); + const double *ptr=array->getPointer(); + int nbOfPts=array->getNbOfElems()/SPACEDIM; + for(int j=0;j*work) + boundingBox[j]=*work; + if(boundingBox[j+SPACEDIM]<*work) + boundingBox[j+SPACEDIM]=*work; + } + } +} + +template +INTERP_KERNEL::NormalizedCellType MEDCouplingNormalizedUnstructuredMesh::getTypeOfElement(int eltId) const +{ + return _mesh->getTypeOfCell(eltId); +} + +template +unsigned char MEDCouplingNormalizedUnstructuredMesh::getNumberOfNodesOfElement(int eltId) const +{ + return _mesh->getNumberOfNodesInCell(eltId); +} + +template +unsigned long MEDCouplingNormalizedUnstructuredMesh::getNumberOfElements() const +{ + return _mesh->getNumberOfCells(); +} + +template +unsigned long MEDCouplingNormalizedUnstructuredMesh::getNumberOfNodes() const +{ + return _mesh->getNumberOfNodes(); +} + +template +const int *MEDCouplingNormalizedUnstructuredMesh::getConnectivityPtr() const +{ + return _conn_for_interp; +} + +template +const double *MEDCouplingNormalizedUnstructuredMesh::getCoordinatesPtr() const +{ + ParaMEDMEM::DataArrayDouble *array=_mesh->getCoords(); + return array->getPointer(); +} + +template +const int *MEDCouplingNormalizedUnstructuredMesh::getConnectivityIndexPtr() const +{ + return _conn_index_for_interp; +} + +template +void MEDCouplingNormalizedUnstructuredMesh::ReleaseTempArrays() +{ + delete [] _conn_for_interp; + delete [] _conn_index_for_interp; + _conn_for_interp=0; + _conn_index_for_interp=0; +} + +template +MEDCouplingNormalizedUnstructuredMesh::~MEDCouplingNormalizedUnstructuredMesh() +{ + if(_mesh) + _mesh->decrRef(); + ReleaseTempArrays(); +} + +template +void MEDCouplingNormalizedUnstructuredMesh::prepare() +{ + int nbOfCell=_mesh->getNumberOfCells(); + int initialConnSize=_mesh->getNodalConnectivity()->getNbOfElems(); + _conn_for_interp=new int[initialConnSize-nbOfCell]; + _conn_index_for_interp=new int[nbOfCell+1]; + _conn_index_for_interp[0]=0; + const int *work_conn=_mesh->getNodalConnectivity()->getPointer()+1; + const int *work_conn_index=_mesh->getNodalConnectivityIndex()->getPointer(); + int *work_conn_for_interp=_conn_for_interp; + int *work_conn_index_for_interp=_conn_index_for_interp; + for(int i=0;idecrRef(); + if(_y_array) + _y_array->decrRef(); + if(_z_array) + _z_array->decrRef(); +} + +MEDCouplingSMesh *MEDCouplingSMesh::New() +{ + return new MEDCouplingSMesh; +} + +void MEDCouplingSMesh::updateTime() +{ + if(_x_array) + updateTimeWith(*_x_array); + if(_y_array) + updateTimeWith(*_y_array); + if(_z_array) + updateTimeWith(*_z_array); +} + +void MEDCouplingSMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) +{ + const char msg0[]="Invalid "; + const char msg1[]=" array ! Must contain more than 1 element."; + if(_x_array) + if(_x_array->getNbOfElems()<2) + { + std::ostringstream os; os << msg0 << 'X' << msg1; + throw INTERP_KERNEL::Exception(os.str().c_str()); + } + if(_y_array) + if(_y_array->getNbOfElems()<2) + { + std::ostringstream os; os << msg0 << 'Y' << msg1; + throw INTERP_KERNEL::Exception(os.str().c_str()); + } + if(_z_array) + if(_z_array->getNbOfElems()<2) + { + std::ostringstream os; os << msg0 << 'Z' << msg1; + throw INTERP_KERNEL::Exception(os.str().c_str()); + } +} + +bool MEDCouplingSMesh::isStructured() const +{ + return true; +} + +int MEDCouplingSMesh::getNumberOfCells() const +{ + int ret=1; + if(_x_array) + ret*=_x_array->getNbOfElems()-1; + if(_y_array) + ret*=_y_array->getNbOfElems()-1; + if(_z_array) + ret*=_z_array->getNbOfElems()-1; + return ret; +} + +int MEDCouplingSMesh::getNumberOfNodes() const +{ + int ret=1; + if(_x_array) + ret*=_x_array->getNbOfElems(); + if(_y_array) + ret*=_y_array->getNbOfElems(); + if(_z_array) + ret*=_z_array->getNbOfElems(); + return ret; +} + +int MEDCouplingSMesh::getSpaceDimension() const +{ + int ret=0; + if(_x_array) + ret++; + if(_y_array) + ret++; + if(_z_array) + ret++; + return ret; +} + +int MEDCouplingSMesh::getMeshDimension() const +{ + int ret=0; + if(_x_array) + ret++; + if(_y_array) + ret++; + if(_z_array) + ret++; + return ret; +} + +DataArrayDouble *MEDCouplingSMesh::getCoordsAt(int i) const throw(INTERP_KERNEL::Exception) +{ + switch(i) + { + case 0: + return _x_array; + case 1: + return _y_array; + case 2: + return _z_array; + default: + throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2."); + } +} + +void MEDCouplingSMesh::setCoords(DataArrayDouble *coordsX, DataArrayDouble *coordsY, DataArrayDouble *coordsZ) +{ + if(_x_array) + _x_array->decrRef(); + _x_array=coordsX; + if(_x_array) + _x_array->incrRef(); + if(_y_array) + _y_array->decrRef(); + _y_array=coordsY; + if(_y_array) + _y_array->incrRef(); + if(_z_array) + _z_array->decrRef(); + _z_array=coordsZ; + if(_z_array) + _z_array->incrRef(); + declareAsNew(); +} + diff --git a/src/MEDCoupling/MEDCouplingSMesh.hxx b/src/MEDCoupling/MEDCouplingSMesh.hxx new file mode 100644 index 000000000..d782107db --- /dev/null +++ b/src/MEDCoupling/MEDCouplingSMesh.hxx @@ -0,0 +1,53 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __PARAMEDMEM_MEDCOUPLINGSMESH_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGSMESH_HXX__ + +#include "MEDCouplingMesh.hxx" + +namespace ParaMEDMEM +{ + class DataArrayDouble; + + class MEDCouplingSMesh : public MEDCouplingMesh + { + public: + static MEDCouplingSMesh *New(); + void updateTime(); + void checkCoherency() const throw(INTERP_KERNEL::Exception); + bool isStructured() const; + int getNumberOfCells() const; + int getNumberOfNodes() const; + int getSpaceDimension() const; + int getMeshDimension() const; + DataArrayDouble *getCoordsAt(int i) const throw(INTERP_KERNEL::Exception); + void setCoords(DataArrayDouble *coordsX, + DataArrayDouble *coordsY=0, + DataArrayDouble *coordsZ=0); + private: + MEDCouplingSMesh(); + ~MEDCouplingSMesh(); + private: + DataArrayDouble *_x_array; + DataArrayDouble *_y_array; + DataArrayDouble *_z_array; + }; +} + +#endif diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx new file mode 100644 index 000000000..379f326ae --- /dev/null +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -0,0 +1,219 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "MEDCouplingUMesh.hxx" +#include "CellModel.hxx" + +#include + +using namespace ParaMEDMEM; + +MEDCouplingUMesh *MEDCouplingUMesh::New() +{ + return new MEDCouplingUMesh; +} + +void MEDCouplingUMesh::updateTime() +{ + if(_nodal_connec) + { + updateTimeWith(*_nodal_connec); + } + if(_nodal_connec_index) + { + updateTimeWith(*_nodal_connec_index); + } + if(_coords) + { + updateTimeWith(*_coords); + } +} + +MEDCouplingUMesh::MEDCouplingUMesh():_iterator(-1),_mesh_dim(-1), + _nodal_connec(0),_nodal_connec_index(0),_coords(0) +{ +} + +void MEDCouplingUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) +{ + for(std::set::const_iterator iter=_types.begin();iter!=_types.end();iter++) + { + if(INTERP_KERNEL::CellModel::getCellModel(*iter).getDimension()!=_mesh_dim) + { + std::ostringstream message; + message << "Mesh invalid because dimension is " << _mesh_dim << " and there is presence of cell(s) with type " << (*iter); + throw INTERP_KERNEL::Exception(message.str().c_str()); + } + } +} + +void MEDCouplingUMesh::setMeshDimension(unsigned meshDim) +{ + _mesh_dim=meshDim; + declareAsNew(); +} + +void MEDCouplingUMesh::allocateCells(int nbOfCells) +{ + if(_nodal_connec_index) + { + _nodal_connec_index->decrRef(); + } + if(_nodal_connec) + { + _nodal_connec->decrRef(); + } + + _nodal_connec_index=DataArrayInt::New(); + _nodal_connec_index->alloc(nbOfCells+1,1); + int *pt=_nodal_connec_index->getPointer(); + pt[0]=0; + _nodal_connec=DataArrayInt::New(); + _nodal_connec->alloc(2*nbOfCells,1); + _iterator=0; + _types.clear(); + declareAsNew(); +} + +void MEDCouplingUMesh::setCoords(DataArrayDouble *coords) +{ + if( coords != _coords ) + { + if (_coords) + _coords->decrRef(); + _coords=coords; + if(_coords) + _coords->incrRef(); + declareAsNew(); + } +} + +void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell) +{ + int *pt=_nodal_connec_index->getPointer(); + int idx=pt[_iterator]; + + _nodal_connec->writeOnPlace(idx,type,nodalConnOfCell,size); + _types.insert(type); + pt[++_iterator]=idx+size+1; +} + +void MEDCouplingUMesh::finishInsertingCells() +{ + int *pt=_nodal_connec_index->getPointer(); + int idx=pt[_iterator]; + + _nodal_connec->reAlloc(idx); + _nodal_connec_index->reAlloc(_iterator+1); + _iterator=-1; +} + +INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::getTypeOfCell(int cellId) const +{ + int *ptI=_nodal_connec_index->getPointer(); + int *pt=_nodal_connec->getPointer(); + return (INTERP_KERNEL::NormalizedCellType) pt[ptI[cellId]]; +} + +int MEDCouplingUMesh::getNumberOfNodesInCell(int cellId) const +{ + int *ptI=_nodal_connec_index->getPointer(); + return ptI[cellId+1]-ptI[cellId]-1; +} + +void MEDCouplingUMesh::setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes) +{ + if(_nodal_connec!=conn) + { + if(_nodal_connec) + _nodal_connec->decrRef(); + _nodal_connec=conn; + if(_nodal_connec) + _nodal_connec->incrRef(); + } + if(_nodal_connec_index!=connIndex) + { + if(_nodal_connec_index) + _nodal_connec_index->decrRef(); + _nodal_connec_index=connIndex; + if(_nodal_connec_index) + _nodal_connec_index->incrRef(); + } + if(isComputingTypes) + computeTypes(); +} + +MEDCouplingUMesh::~MEDCouplingUMesh() +{ + if(_nodal_connec) + _nodal_connec->decrRef(); + if(_nodal_connec_index) + _nodal_connec_index->decrRef(); + if(_coords) + _coords->decrRef(); +} + +void MEDCouplingUMesh::computeTypes() +{ + if(_nodal_connec && _nodal_connec_index) + { + _types.clear(); + const int *conn=_nodal_connec->getPointer(); + const int *connIndex=_nodal_connec_index->getPointer(); + int nbOfElem=_nodal_connec_index->getNbOfElems()-1; + for(const int *pt=connIndex;pt!=connIndex+nbOfElem;pt++) + _types.insert((INTERP_KERNEL::NormalizedCellType)conn[*pt]); + } +} + +bool MEDCouplingUMesh::isStructured() const +{ + return false; +} + +int MEDCouplingUMesh::getNumberOfCells() const +{ + if(_nodal_connec_index) + if(_iterator==-1) + return _nodal_connec_index->getNumberOfTuples()-1; + else + return _iterator; + else + throw INTERP_KERNEL::Exception("Unable to get number of cells because no coordinates specified !"); +} + +int MEDCouplingUMesh::getNumberOfNodes() const +{ + if(_coords) + return _coords->getNumberOfTuples(); + else + throw INTERP_KERNEL::Exception("Unable to get number of nodes because no coordinates specified !"); +} + +int MEDCouplingUMesh::getSpaceDimension() const +{ + if(_coords) + return _coords->getNumberOfComponents(); + else + throw INTERP_KERNEL::Exception("Unable to get space dimension because no coordinates specified !"); +} + +int MEDCouplingUMesh::getMeshLength() const +{ + return _nodal_connec->getNbOfElems(); +} diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx new file mode 100644 index 000000000..4fbbf3df5 --- /dev/null +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -0,0 +1,68 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __PARAMEDMEM_MEDCOUPLINGUMESH_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGUMESH_HXX__ + +#include "MEDCouplingMesh.hxx" +#include "MemArray.hxx" + +#include + +namespace ParaMEDMEM +{ + class MEDCouplingUMesh : public MEDCouplingMesh + { + public: + static MEDCouplingUMesh *New(); + void updateTime(); + void checkCoherency() const throw(INTERP_KERNEL::Exception); + void setMeshDimension(unsigned meshDim); + void allocateCells(int nbOfCells); + void setCoords(DataArrayDouble *coords); + DataArrayDouble *getCoords() const { return _coords; } + void insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell); + void finishInsertingCells(); + const std::set getAllTypes() const { return _types; } + void setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes=true); + DataArrayInt *getNodalConnectivity() const { return _nodal_connec; } + DataArrayInt *getNodalConnectivityIndex() const { return _nodal_connec_index; } + INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; + int getNumberOfNodesInCell(int cellId) const; + bool isStructured() const; + int getNumberOfCells() const; + int getNumberOfNodes() const; + int getSpaceDimension() const; + int getMeshDimension() const { return _mesh_dim; } + int getMeshLength() const; + private: + MEDCouplingUMesh(); + ~MEDCouplingUMesh(); + void computeTypes(); + private: + //! this iterator stores current position in _nodal_connec array. + mutable int _iterator; + unsigned _mesh_dim; + DataArrayInt *_nodal_connec; + DataArrayInt *_nodal_connec_index; + DataArrayDouble *_coords; + std::set _types; + }; +} + +#endif diff --git a/src/MEDCoupling/Makefile.am b/src/MEDCoupling/Makefile.am new file mode 100644 index 000000000..ea0f7153b --- /dev/null +++ b/src/MEDCoupling/Makefile.am @@ -0,0 +1,68 @@ +# Copyright (C) 2007-2008 CEA/DEN, 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. +# +# 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 +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +if CPPUNIT_IS_OK + SUBDIRS = . Test +endif + +# first '.' says that this folder must be compiled before Test (MEDMEM/Test uses MEDMEM) + +lib_LTLIBRARIES = libmedcoupling.la + + +salomeinclude_HEADERS = \ +MEDCouplingFieldDouble.hxx MEDCouplingMesh.hxx MEDCouplingUMesh.hxx TimeLabel.hxx \ +MEDCouplingField.hxx MEDCouplingNormalizedUnstructuredMesh.hxx MemArray.hxx \ +MEDCouplingNormalizedUnstructuredMesh.txx MemArray.txx RefCountObject.hxx \ +MEDCouplingSMesh.hxx + +# Libraries targets + +dist_libmedcoupling_la_SOURCES = \ + MEDCouplingField.cxx MEDCouplingFieldDouble.cxx \ + MEDCouplingUMesh.cxx MemArray.cxx TimeLabel.cxx \ + MEDCouplingSMesh.cxx + +libmedcoupling_la_LDFLAGS= + +libmedcoupling_la_CPPFLAGS= @CXXTMPDPTHFLAGS@ \ + -I$(srcdir) -I$(srcdir)/../INTERP_KERNEL/Bases -I$(srcdir)/../INTERP_KERNEL + +# the geom2D library is included in the interpkernel one +libmedcoupling_la_LIBADD= ../INTERP_KERNEL/libinterpkernel.la + +AM_CPPFLAGS= $(libinterpkernel_la_CPPFLAGS) +LDADD= $(libinterpkernel_la_LDFLAGS) +if MED_ENABLE_KERNEL + LDADD+=-lSALOMEBasics +endif + +EXTRA_DIST += \ + MEDCouplingFieldDouble.hxx \ + MEDCouplingMesh.hxx \ + MEDCouplingUMesh.hxx \ + MEDCouplingSMesh.hxx \ + TimeLabel.hxx \ + MEDCouplingField.hxx \ + MEDCouplingNormalizedUnstructuredMesh.hxx \ + MemArray.hxx \ + MEDCouplingNormalizedUnstructuredMesh.txx \ + MemArray.txx \ + RefCountObject.hxx diff --git a/src/MEDCoupling/MemArray.cxx b/src/MEDCoupling/MemArray.cxx new file mode 100644 index 000000000..90d43a8fe --- /dev/null +++ b/src/MEDCoupling/MemArray.cxx @@ -0,0 +1,82 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "MemArray.txx" + +using namespace ParaMEDMEM; + +void DataArray::setName(const char *name) +{ + _name=name; +} + +DataArrayDouble *DataArrayDouble::New() +{ + return new DataArrayDouble; +} + +void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) +{ + _nb_of_tuples=nbOfTuple; + _info_on_compo.resize(nbOfCompo); + _mem.alloc(nbOfCompo*_nb_of_tuples); + declareAsNew(); +} + +void DataArrayDouble::reAlloc(int nbOfTuples) +{ + _mem.reAlloc(_info_on_compo.size()*nbOfTuples); + _nb_of_tuples=nbOfTuples; + declareAsNew(); +} + +void DataArrayDouble::useArray(double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) +{ + _nb_of_tuples=nbOfTuple; + _info_on_compo.resize(nbOfCompo); + _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo); + declareAsNew(); +} + +DataArrayInt *DataArrayInt::New() +{ + return new DataArrayInt; +} + +void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) +{ + _nb_of_tuples=nbOfTuple; + _info_on_compo.resize(nbOfCompo); + _mem.alloc(nbOfCompo*_nb_of_tuples); + declareAsNew(); +} + +void DataArrayInt::useArray(int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo) +{ + _nb_of_tuples=nbOfTuple; + _info_on_compo.resize(nbOfCompo); + _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo); + declareAsNew(); +} + +void DataArrayInt::reAlloc(int nbOfTuples) +{ + _mem.reAlloc(_info_on_compo.size()*nbOfTuples); + _nb_of_tuples=nbOfTuples; + declareAsNew(); +} diff --git a/src/MEDCoupling/MemArray.hxx b/src/MEDCoupling/MemArray.hxx new file mode 100644 index 000000000..b8c9c4e38 --- /dev/null +++ b/src/MEDCoupling/MemArray.hxx @@ -0,0 +1,116 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __PARAMEDMEM_MEMARRAY_HXX__ +#define __PARAMEDMEM_MEMARRAY_HXX__ + +#include "RefCountObject.hxx" + +#include +#include + +namespace ParaMEDMEM +{ + template + class MemArray + { + public: + MemArray():_nb_of_elem(-1),_ownership(false),_pointer(0),_dealloc(CPP_DEALLOC) { } + T *getPointer() const { return _pointer; } + MemArray &operator=(const MemArray& other); + T operator[](int id) const { return _pointer[id]; } + T& operator[](int id) { return _pointer[id]; } + void alloc(int nbOfElements); + void reAlloc(int newNbOfElements); + void useArray(void *array, bool ownership, DeallocType type, int nbOfElem); + void writeOnPlace(int id, T element0, const T *others, int sizeOfOthers); + ~MemArray() { destroy(); } + private: + void destroy(); + static void destroyPointer(T *pt, DeallocType type); + private: + int _nb_of_elem; + bool _ownership; + T *_pointer; + DeallocType _dealloc; + }; + + class DataArray : public RefCountObject + { + public: + void setName(const char *name); + std::string getName() const { return _name; } + std::string getInfoOnComponent(int i) const { return _info_on_compo[i]; } + void setInfoOnComponent(int i, const char *info) { _info_on_compo[i]=info; } + int getNumberOfComponents() const { return _info_on_compo.size(); } + int getNumberOfTuples() const { return _nb_of_tuples; } + int getNbOfElems() const { return _info_on_compo.size()*_nb_of_tuples; } + protected: + DataArray():_nb_of_tuples(-1) { } + protected: + int _nb_of_tuples; + std::string _name; + std::vector _info_on_compo; + }; +} + +#include "MemArray.txx" + +namespace ParaMEDMEM +{ + class DataArrayDouble : public DataArray + { + public: + static DataArrayDouble *New(); + void alloc(int nbOfTuple, int nbOfCompo); + //!alloc or useArray should have been called before. + void reAlloc(int nbOfTuples); + double getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; } + void setIJ(int tupleId, int compoId, double newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; } + double *getPointer() const { return _mem.getPointer(); } + void useArray(double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); + void writeOnPlace(int id, double element0, const double *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); } + //! nothing to do here because this class does not aggregate any TimeLabel instance. + void updateTime() { } + private: + DataArrayDouble() { } + private: + MemArray _mem; + }; + + class DataArrayInt : public DataArray + { + public: + static DataArrayInt *New(); + void alloc(int nbOfTuple, int nbOfCompo); + //!alloc or useArray should have been called before. + void reAlloc(int nbOfTuples); + int getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; } + int *getPointer() const { return _mem.getPointer(); } + void useArray(int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); + void writeOnPlace(int id, int element0, const int *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); } + //! nothing to do here because this class does not aggregate any TimeLabel instance. + void updateTime() { } + private: + DataArrayInt() { } + private: + MemArray _mem; + }; +} + +#endif diff --git a/src/MEDCoupling/MemArray.txx b/src/MEDCoupling/MemArray.txx new file mode 100644 index 000000000..8c858bd1f --- /dev/null +++ b/src/MEDCoupling/MemArray.txx @@ -0,0 +1,112 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __PARAMEDMEM_MEMARRAY_TXX__ +#define __PARAMEDMEM_MEMARRAY_TXX__ + +#include "MemArray.hxx" +#include "NormalizedUnstructuredMesh.hxx" +#include "InterpKernelException.hxx" + +#include +#include + +namespace ParaMEDMEM +{ + template + void MemArray::useArray(void *array, bool ownership, DeallocType type, int nbOfElem) + { + _nb_of_elem=nbOfElem; + destroy(); + _pointer=(T *)array; + _ownership=ownership; + _dealloc=type; + } + + template + void MemArray::writeOnPlace(int id, T element0, const T *others, int sizeOfOthers) + { + if(id+sizeOfOthers>=_nb_of_elem) + reAlloc(2*_nb_of_elem+sizeOfOthers+1); + _pointer[id]=element0; + memcpy(_pointer+id+1,others,sizeOfOthers*sizeof(T)); + } + + template + void MemArray::alloc(int nbOfElements) + { + destroy(); + _nb_of_elem=nbOfElements; + _pointer=new T[_nb_of_elem]; + _ownership=true; + _dealloc=CPP_DEALLOC; + } + + template + void MemArray::reAlloc(int newNbOfElements) + { + T *pointer=new T[newNbOfElements]; + memcpy(pointer,_pointer,std::min(_nb_of_elem,newNbOfElements)*sizeof(int)); + destroyPointer(_pointer,_dealloc); + _pointer=pointer; + _nb_of_elem=newNbOfElements; + _ownership=true; + _dealloc=CPP_DEALLOC; + } + + template + void MemArray::destroyPointer(T *pt, DeallocType type) + { + switch(type) + { + case CPP_DEALLOC: + { + delete [] pt; + return ; + } + case C_DEALLOC: + { + free(pt); + return ; + } + default: + std::stringstream stream; + stream << "Invalid deallocation requested for pointer " << pt; + throw INTERP_KERNEL::Exception(stream.str().c_str()); + } + } + + template + void MemArray::destroy() + { + if(_ownership) + destroyPointer(_pointer,_dealloc); + _pointer=0; + _ownership=false; + } + + template + MemArray &MemArray::operator=(const MemArray& other) + { + alloc(other._nb_of_elem); + memcpy(_pointer,other._pointer,_nb_of_elem*sizeof(T)); + return *this; + } +} + +#endif diff --git a/src/MEDCoupling/RefCountObject.hxx b/src/MEDCoupling/RefCountObject.hxx new file mode 100644 index 000000000..ca28fd1bf --- /dev/null +++ b/src/MEDCoupling/RefCountObject.hxx @@ -0,0 +1,51 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __PARAMEDMEM_REFCOUNTOBJECT_HXX__ +#define __PARAMEDMEM_REFCOUNTOBJECT_HXX__ + +#include "TimeLabel.hxx" + +namespace ParaMEDMEM +{ + typedef enum + { + C_DEALLOC = 2, + CPP_DEALLOC = 3 + } DeallocType; + + typedef enum + { + ON_CELLS = 0, + ON_NODES = 1 + } TypeOfField; + + class RefCountObject : public TimeLabel + { + public: + RefCountObject():_cnt(1) { } + bool decrRef() { bool ret=((--_cnt)==0); if(ret)delete this; return ret; } + void incrRef() { _cnt++; } + protected: + virtual ~RefCountObject() { } + private: + int _cnt; + }; +} + +#endif diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest.cxx new file mode 100644 index 000000000..2284bc8e9 --- /dev/null +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest.cxx @@ -0,0 +1,435 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "MEDCouplingBasicsTest.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MemArray.hxx" +#include "Interpolation2D.txx" +#include "Interpolation3DSurf.txx" + +#include "MEDCouplingNormalizedUnstructuredMesh.txx" + +#include + +using namespace std; +using namespace ParaMEDMEM; + +void MEDCouplingBasicsTest::testMesh() +{ + const int nbOfCells=6; + const int nbOfNodes=12; + + double coords[3*nbOfNodes]={ + 0.024155, 0.04183768725682622, -0.305, 0.04831000000000001, -1.015761910347357e-17, -0.305, 0.09662000000000001, -1.832979297858306e-18, + -0.305, 0.120775, 0.04183768725682623, -0.305, 0.09662000000000001, 0.08367537451365245, -0.305, 0.04831000000000001, + 0.08367537451365246, -0.305, 0.024155, 0.04183768725682622, -0.2863, 0.04831000000000001, -1.015761910347357e-17, -0.2863, + 0.09662000000000001, -1.832979297858306e-18, -0.2863, 0.120775, 0.04183768725682623, -0.2863, 0.09662000000000001, 0.08367537451365245, + -0.2863, 0.04831000000000001, 0.08367537451365246, -0.2863, }; + + int tab4[4*nbOfCells]={ + 1, 2, 8, 7, 2, 3, 9, 8, 3, 4, 10, 9, 4, 5, 11, 10, 5, 0, 6, 11, + 0, 1, 7, 6, }; + + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(8); + const int *curConn=tab4; + for(int i=0;iinsertNextCell(INTERP_KERNEL::NORM_QUAD4,4,curConn); + mesh->finishInsertingCells(); + CPPUNIT_ASSERT_EQUAL(30,mesh->getNodalConnectivity()->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(nbOfCells,mesh->getNumberOfCells()); + //test 0 - no copy no ownership + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->useArray(coords,false,CPP_DEALLOC,nbOfNodes,3); + mesh->setCoords(myCoords); + mesh->setCoords(myCoords); + myCoords->decrRef(); + CPPUNIT_ASSERT_EQUAL(nbOfCells,mesh->getNumberOfCells()); + mesh->checkCoherency(); + //test 1 - no copy ownership C++ + myCoords=DataArrayDouble::New(); + double *tmp=new double[3*nbOfNodes]; + copy(coords,coords+3*nbOfNodes,tmp); + myCoords->useArray(tmp,true,CPP_DEALLOC,nbOfNodes,3); + mesh->setCoords(myCoords); + myCoords->decrRef(); + CPPUNIT_ASSERT_EQUAL(nbOfCells,mesh->getNumberOfCells()); + mesh->checkCoherency(); + //test 2 - no copy ownership C + myCoords=DataArrayDouble::New(); + tmp=(double *)malloc(3*nbOfNodes*sizeof(double)); + copy(coords,coords+3*nbOfNodes,tmp); + myCoords->useArray(tmp,true,C_DEALLOC,nbOfNodes,3); + mesh->setCoords(myCoords); + myCoords->decrRef(); + CPPUNIT_ASSERT_EQUAL(nbOfNodes,mesh->getNumberOfNodes()); + mesh->checkCoherency(); + //test 3 - copy. + myCoords=DataArrayDouble::New(); + myCoords->alloc(nbOfNodes,3); + tmp=myCoords->getPointer(); + copy(coords,coords+3*nbOfNodes,tmp); + // test 3 bis deepcopy + DataArrayDouble *myCoords2=DataArrayDouble::New(); + *myCoords2=*myCoords; + myCoords2->decrRef(); + // + mesh->setCoords(myCoords); + myCoords->decrRef(); + CPPUNIT_ASSERT_EQUAL(nbOfNodes,mesh->getNumberOfNodes()); + mesh->checkCoherency(); + //test 4 - Field on cells + MEDCouplingFieldDouble *fieldOnCells=MEDCouplingFieldDouble::New(ON_CELLS); + fieldOnCells->setMesh(mesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(nbOfCells,9); + fieldOnCells->setArray(array); + tmp=array->getPointer(); + array->decrRef(); + fill(tmp,tmp+9*nbOfCells,7.); + fieldOnCells->declareAsNew(); + fieldOnCells->checkCoherency(); + fieldOnCells->decrRef(); + //clean-up + mesh->decrRef(); +} + +void MEDCouplingBasicsTest::test2DInterpP0P0_1() +{ + MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + vector > res; + INTERP_KERNEL::IntersectionType types[3]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Convex, INTERP_KERNEL::Geometric2D}; + for(int i=0;i<3;i++) + { + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(types[i]); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); + res.clear(); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTest::test2DInterpP0P1_1() +{ + MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + vector > res; + INTERP_KERNEL::IntersectionType types[3]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Convex, INTERP_KERNEL::Geometric2D}; + for(int i=0;i<3;i++) + { + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(types[i]); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); + CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333329,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[5][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333329,res[6][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[7][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[8][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[8][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.25,sumAll(res),1e-12); + res.clear(); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTest::test2DInterpP1P0_1() +{ + MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + vector > res; + INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; + for(int i=0;i<2;i++) + { + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(types[i]); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[3][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333333,res[1][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333333,res[2][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666667,res[3][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[2][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[3][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[4][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); + res.clear(); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTest::test3DSurfInterpP0P0_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3DSurf myInterpolator; + vector > res; + INTERP_KERNEL::IntersectionType types[3]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Convex, INTERP_KERNEL::Geometric2D}; + for(int i=0;i<3;i++) + { + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(types[i]); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2),res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2),res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2),res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2),res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2),res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2),res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2),res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2),sumAll(res),1e-12); + res.clear(); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTest::test3DSurfInterpP0P1_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3DSurf myInterpolator; + vector > res; + INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; + for(int i=0;i<2;i++) + { + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(types[i]); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); + CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2),res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2),res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2),res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333329*sqrt(2),res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2),res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2),res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2),res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2),res[5][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333329*sqrt(2),res[6][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2),res[7][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2),res[8][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2),res[8][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.25*sqrt(2),sumAll(res),1e-12); + res.clear(); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTest::test3DSurfInterpP1P0_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3DSurf myInterpolator; + vector > res; + INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; + for(int i=0;i<2;i++) + { + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(types[i]); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2),res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2),res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2),res[3][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333333*sqrt(2),res[1][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333333*sqrt(2),res[2][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666667*sqrt(2),res[3][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2),res[2][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2),res[3][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2),res[4][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2),sumAll(res),1e-12); + res.clear(); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTest::test3DInterpP0P0_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); + //clean up + sourceMesh->decrRef(); +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DSourceMesh_1() +{ + double sourceCoords[8]={-0.3,-0.3, 0.7,-0.3, -0.3,0.7, 0.7,0.7}; + int sourceConn[6]={0,3,1,0,2,3}; + MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); + sourceMesh->setMeshDimension(2); + sourceMesh->allocateCells(2); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn+3); + sourceMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,2); + std::copy(sourceCoords,sourceCoords+8,myCoords->getPointer()); + sourceMesh->setCoords(myCoords); + myCoords->decrRef(); + return sourceMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMesh_1() +{ + double targetCoords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + int targetConn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(5); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(9,2); + std::copy(targetCoords,targetCoords+18,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfSourceMesh_1() +{ + double sourceCoords[12]={-0.3,-0.3,0.5, 0.7,-0.3,1.5, -0.3,0.7,0.5, 0.7,0.7,1.5}; + int sourceConn[6]={0,3,1,0,2,3}; + MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); + sourceMesh->setMeshDimension(2); + sourceMesh->allocateCells(2); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn+3); + sourceMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,3); + std::copy(sourceCoords,sourceCoords+12,myCoords->getPointer()); + sourceMesh->setCoords(myCoords); + myCoords->decrRef(); + return sourceMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfTargetMesh_1() +{ + double targetCoords[27]={-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5}; + int targetConn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(5); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(9,3); + std::copy(targetCoords,targetCoords+27,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSourceMesh_1() +{ + double sourceCoords[27]={ 0.0, 0.0, 200.0, 0.0, 0.0, 0.0, 0.0, 200.0, 200.0, 0.0, 200.0, 0.0, 200.0, 0.0, 200.0, + 200.0, 0.0, 0.0, 200.0, 200.0, 200.0, 200.0, 200.0, 0.0, 100.0, 100.0, 100.0 }; + int sourceConn[48]={8,1,7,3, 6,0,8,2, 7,4,5,8, 6,8,4,7, 6,8,0,4, 6,8,7,3, 8,1,3,0, 4,1,5,8, 1,7,5,8, 0,3,8,2, 8,1,0,4, 3,6,8,2}; + MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); + sourceMesh->setMeshDimension(3); + sourceMesh->allocateCells(12); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+4); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+8); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+12); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+16); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+20); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+24); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+28); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+32); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+36); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+40); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+44); + sourceMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(9,3); + std::copy(sourceCoords,sourceCoords+12,myCoords->getPointer()); + sourceMesh->setCoords(myCoords); + myCoords->decrRef(); + return sourceMesh; +} + +double MEDCouplingBasicsTest::sumAll(const std::vector< std::map >& matrix) +{ + double ret=0.; + for(std::vector< std::map >::const_iterator iter=matrix.begin();iter!=matrix.end();iter++) + for(std::map::const_iterator iter2=(*iter).begin();iter2!=(*iter).end();iter2++) + ret+=(*iter2).second; + return ret; +} diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx new file mode 100644 index 000000000..0f0ab1210 --- /dev/null +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx @@ -0,0 +1,62 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __MEDCOUPLINGBASICSTEST_HXX__ +#define __MEDCOUPLINGBASICSTEST_HXX__ + +#include + +#include +#include + +namespace ParaMEDMEM +{ + class MEDCouplingUMesh; + + class MEDCouplingBasicsTest : public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE(MEDCouplingBasicsTest); + CPPUNIT_TEST( testMesh ); + CPPUNIT_TEST( test2DInterpP0P0_1 ); + CPPUNIT_TEST( test2DInterpP0P1_1 ); + CPPUNIT_TEST( test2DInterpP1P0_1 ); + CPPUNIT_TEST( test3DSurfInterpP0P0_1 ); + CPPUNIT_TEST( test3DSurfInterpP0P1_1 ); + CPPUNIT_TEST( test3DSurfInterpP1P0_1 ); + CPPUNIT_TEST( test3DInterpP0P0_1 ); + CPPUNIT_TEST_SUITE_END(); + public: + void testMesh(); + void test2DInterpP0P0_1(); + void test2DInterpP0P1_1(); + void test2DInterpP1P0_1(); + void test3DSurfInterpP0P0_1(); + void test3DSurfInterpP0P1_1(); + void test3DSurfInterpP1P0_1(); + void test3DInterpP0P0_1(); + private: + MEDCouplingUMesh *build2DSourceMesh_1(); + MEDCouplingUMesh *build2DTargetMesh_1(); + MEDCouplingUMesh *build3DSurfSourceMesh_1(); + MEDCouplingUMesh *build3DSurfTargetMesh_1(); + MEDCouplingUMesh *build3DSourceMesh_1(); + double sumAll(const std::vector< std::map >& matrix); + }; +} + +#endif diff --git a/src/MEDCoupling/Test/Makefile.am b/src/MEDCoupling/Test/Makefile.am new file mode 100755 index 000000000..2f46f4f93 --- /dev/null +++ b/src/MEDCoupling/Test/Makefile.am @@ -0,0 +1,27 @@ +# Copyright (C) 2007-2008 CEA/DEN, 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. +# +# 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 + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +bin_PROGRAMS= TestMEDCoupling + +TestMEDCoupling_CPPFLAGS=@CPPUNIT_INCLUDES@ -I$(srcdir)/.. -I$(srcdir)/../../INTERP_KERNEL/Bases -I$(srcdir)/../../INTERP_KERNELTest -I$(srcdir)/../../INTERP_KERNEL -I$(srcdir)/../../INTERP_KERNEL/Geometric2D + +TestMEDCoupling_LDFLAGS = @CPPUNIT_LIBS@ ../libmedcoupling.la + +dist_TestMEDCoupling_SOURCES = TestMEDCoupling.cxx MEDCouplingBasicsTest.cxx diff --git a/src/MEDCoupling/Test/TestMEDCoupling.cxx b/src/MEDCoupling/Test/TestMEDCoupling.cxx new file mode 100644 index 000000000..1bcef8375 --- /dev/null +++ b/src/MEDCoupling/Test/TestMEDCoupling.cxx @@ -0,0 +1,24 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "CppUnitTest.hxx" +#include "MEDCouplingBasicsTest.hxx" + +CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTest ); + +#include "BasicMainTest.hxx" diff --git a/src/MEDCoupling/TimeLabel.cxx b/src/MEDCoupling/TimeLabel.cxx new file mode 100644 index 000000000..df03416ec --- /dev/null +++ b/src/MEDCoupling/TimeLabel.cxx @@ -0,0 +1,44 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "TimeLabel.hxx" + +using namespace ParaMEDMEM; + +unsigned int TimeLabel::GLOBAL_TIME=0; + +TimeLabel::TimeLabel():_time(GLOBAL_TIME++) +{ +} + + TimeLabel& TimeLabel::operator=(const TimeLabel& other) +{ + _time=GLOBAL_TIME++; + return *this; +} + +void TimeLabel::declareAsNew() +{ + _time=GLOBAL_TIME++; +} + +void TimeLabel::updateTimeWith(const TimeLabel& other) +{ + if(_time + + + + + + + @default + + ICO_TB_EXPLORE + explore_med_file.png + + + ICO_TB_FIELDSEL + field_selection.png + + + ICO_TB_MESHSEL + mesh_selection.png + + + + diff --git a/src/MEDGUI/MED_msg_en.po b/src/MEDGUI/MED_msg_en.po index e6348cf98..f5116d868 100644 --- a/src/MEDGUI/MED_msg_en.po +++ b/src/MEDGUI/MED_msg_en.po @@ -1,29 +1,28 @@ -# MED MEDGUI : MED component GUI implemetation +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# 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 # +# MED MEDGUI : MED component GUI implemetation # File : MED_msg_en.po # Module : MED - +# msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" @@ -77,7 +76,7 @@ msgid "TOP_MESHSEL" msgstr "Mesh selection" msgid "MEN_MESHSEL" -msgstr "Mesh selection" +msgstr "Mesh Selection" msgid "STB_MESHSEL" msgstr "Read a mesh" @@ -86,7 +85,7 @@ msgid "TOP_FIELDSEL" msgstr "Field selection" msgid "MEN_FIELDSEL" -msgstr "Field selection" +msgstr "Field Selection" msgid "STB_FIELDSEL" msgstr "Read a field" @@ -122,7 +121,7 @@ msgid "TOP_POPUPTEST" msgstr "Popup test" msgid "MEN_POPUPTEST" -msgstr "Popup test" +msgstr "Popup Test" msgid "STB_POPUPTEST" msgstr "Popup test" diff --git a/src/MEDGUI/MED_msg_en.ts b/src/MEDGUI/MED_msg_en.ts new file mode 100644 index 000000000..a572c3007 --- /dev/null +++ b/src/MEDGUI/MED_msg_en.ts @@ -0,0 +1,170 @@ + + + + + + + @default + + MED_BUT_OK + OK + + + MED_INF_FIELDNAME + Please enter the name of the field you want to read + + + MED_INF_MESHNAME + Please enter the name of the mesh you want to read + + + MED_INF_NOIOR + Object has no IOR + + + MED_INF_NOTIMPL + Not Implemented for this Object + + + MED_WRN_WARNING + Warning + + + MEN_SHOW + Show + + + MEN_DUMPMESH + Dump Mesh + + + MEN_DUMPSUBMESH + Dump SubMesh + + + MEN_HIDE + Hide + + + MEN_EXPLORE + Explore Med File + + + MEN_FIELDSEL + Field Selection + + + MEN_MESHSEL + Mesh Selection + + + MEN_POPUPTEST + Popup Test + + + STB_SHOW + Show + + + STB_DUMPMESH + dump Mesh + + + STB_DUMPSUBMESH + dump Mesh + + + STB_HIDE + Hide + + + STB_EXPLORE + Explore Med File + + + STB_FIELDSEL + Read a field + + + STB_MESHSEL + Read a mesh + + + STB_POPUPTEST + Popup test + + + TB_MED + Med Toolbar + + + TOP_SHOW + Show + + + TOP_DUMPMESH + Dump Mesh + + + TOP_DUMPSUBMESH + Dump SubMesh + + + TOP_HIDE + Hide + + + TOP_EXPLORE + Explore Med File + + + TOP_FIELDSEL + Field selection + + + TOP_MESHSEL + Mesh selection + + + TOP_POPUPTEST + Popup test + + + + MedGUI + + MED_MEN_ALL_FILES + All Files ( * ) + + + MED_MEN_IMPORT + Import + + + MED_MEN_IMPORT_MED + MED Files ( *.med ) + + + + diff --git a/src/MEDGUI/MED_msg_fr.po b/src/MEDGUI/MED_msg_fr.po index dbd99fc0a..d6fd4d162 100644 --- a/src/MEDGUI/MED_msg_fr.po +++ b/src/MEDGUI/MED_msg_fr.po @@ -1,29 +1,28 @@ -# MED MEDGUI : MED component GUI implemetation +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# 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 # +# MED MEDGUI : MED component GUI implemetation # File : MED_msg_fr.po # Module : MED - +# msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" diff --git a/src/MEDGUI/MED_msg_fr.ts b/src/MEDGUI/MED_msg_fr.ts new file mode 100644 index 000000000..9d36adefa --- /dev/null +++ b/src/MEDGUI/MED_msg_fr.ts @@ -0,0 +1,28 @@ + + + + + + + diff --git a/src/MEDGUI/Makefile.am b/src/MEDGUI/Makefile.am index 5c04834c4..ac82800e7 100644 --- a/src/MEDGUI/Makefile.am +++ b/src/MEDGUI/Makefile.am @@ -1,6 +1,6 @@ -# MED MEDGUI : MED component GUI implemetation +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # # This library is free software; you can redistribute it and/or @@ -17,18 +17,17 @@ # 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 +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # +# MED MEDGUI : MED component GUI implemetation # - include $(top_srcdir)/adm_local/unix/make_common_starter.am # Libraries targets lib_LTLIBRARIES= libMED.la -dist_libMED_la_SOURCES= MedGUI.cxx MedGUI_Selection.cxx +dist_libMED_la_SOURCES = MedGUI_Selection.h MedGUI.h MedGUI.cxx MedGUI_Selection.cxx MOC_FILES= MedGUI_moc.cxx nodist_libMED_la_SOURCES= $(MOC_FILES) -EXTRA_DIST+= MedGUI_Selection.h MedGUI.h libMED_la_CPPFLAGS= $(QT_INCLUDES) $(VTK_INCLUDES) @CAS_CPPFLAGS@ $(PYTHON_INCLUDES) \ ${KERNEL_CXXFLAGS} ${GUI_CXXFLAGS} ${BOOST_CPPFLAGS} \ @@ -36,9 +35,10 @@ libMED_la_CPPFLAGS= $(QT_INCLUDES) $(VTK_INCLUDES) @CAS_CPPFLAGS@ $(PYTHON_INCLU -I$(top_builddir)/idl -I$(top_builddir)/salome_adm/unix libMED_la_LDFLAGS= \ + $(QT_MT_LIBS) $(CAS_KERNEL) \ ../../idl/libSalomeIDLMED.la \ - $(KERNEL_LDFLAGS) -lSalomeLifeCycleCORBA \ - $(GUI_LDFLAGS) -lSalomeApp + $(KERNEL_LDFLAGS) -lSalomeLifeCycleCORBA -lOpUtil -lSALOMELocalTrace \ + $(GUI_LDFLAGS) -lSalomeApp -lCAM -lLightApp -lqtx -lsuit -lSalomeObject # .po files to transform in .qm nodist_salomeres_DATA= \ diff --git a/src/MEDGUI/MedGUI.cxx b/src/MEDGUI/MedGUI.cxx index 56f980685..51e142430 100644 --- a/src/MEDGUI/MedGUI.cxx +++ b/src/MEDGUI/MedGUI.cxx @@ -1,6 +1,6 @@ -// MED MEDGUI : MED component GUI implemetation +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // // This library is free software; you can redistribute it and/or @@ -17,13 +17,12 @@ // 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 -// -// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// MED MEDGUI : MED component GUI implemetation // File : MedGUI.cxx // Module : MED - +// #include "MedGUI.h" // SALOME Includes @@ -50,21 +49,14 @@ #include -#include +#include +#include +#include +#include -//#include "SMESH_TypeFilter.hxx" #include -// QT Includes -#include - -//VRV: porting on Qt 3.0.5 -#if QT_VERSION >= 0x030005 -#include -#endif -//VRV: porting on Qt 3.0.5 - using namespace std; static CORBA::ORB_var _orb; @@ -76,40 +68,7 @@ static CORBA::ORB_var _orb; //============================================================================= MedGUI::MedGUI() : SalomeApp_Module( "MED" ) -{} - -//============================================================================= -/*! - * - */ -//============================================================================= -void MedGUI::createPopupItem( const int id, - const QString& clients, - const QString& types, - const QString& theRule, - const int pId ) { - int parentId = pId; - if( pId!=-1 ) - parentId = popupMgr()->actionId( action( pId ) ); - - if( !popupMgr()->contains( popupMgr()->actionId( action( id ) ) ) ) - popupMgr()->insert( action( id ), parentId, 0 ); - - QChar lc = QtxPopupMgr::Selection::defEquality(); - QString rule = "(%1)"; - if( !types.isEmpty() ) - rule += " and (%2) and (%3)"; - - rule = rule.arg( QString( "client in {%1}" ).arg( clients ) ); - - if( !types.isEmpty() ) - { - rule = rule.arg( QString( "%1>0" ).arg( QtxPopupMgr::Selection::defSelCountParam() ) ); - rule = rule.arg( QString( "%1type in {%2}" ).arg( lc ).arg( types ) ); - } - rule += theRule; - popupMgr()->setRule( action( id ), rule, true ); } void MedGUI::createMedAction( const int id, const QString& po_id, const QString& icon_id ) @@ -117,16 +76,29 @@ void MedGUI::createMedAction( const int id, const QString& po_id, const QString& QWidget* parent = application()->desktop(); SUIT_ResourceMgr* mgr = application()->resourceMgr(); - QPixmap pix; QIconSet icon; + QPixmap pix; + QIcon icon; if( !icon_id.isEmpty() ) - pix = mgr->loadPixmap( "MED", tr( icon_id ) ); + pix = mgr->loadPixmap( "MED", tr( (const char*)icon_id.toLatin1() ) ); // else // pix = mgr->loadPixmap( "MED", tr( QString( "ICO_" )+po_id ) ); if ( !pix.isNull() ) - icon = QIconSet( pix ); - - createAction( id, tr( "TOP_" + po_id ), icon, tr( "MEN_" + po_id ), tr( "STB_" + po_id ), 0, parent, false, this, SLOT( onGUIEvent() ) ); + icon = QIcon( pix ); + + createAction( id, + tr( (const char*)("TOP_" + po_id).toLatin1() ), + icon, + tr( (const char*)("MEN_" + po_id).toLatin1() ), + tr( (const char*)("STB_" + po_id).toLatin1() ), + 0, + parent, + false, + this, + SLOT( onGUIEvent() ) ); + + if ( action( id ) ) + action( id )->setObjectName( QString( "Action %1" ).arg( id ) ); } //============================================================================= @@ -138,11 +110,11 @@ void MedGUI::initialize( CAM_Application* app ) { SalomeApp_Module::initialize( app ); - QWidget* parent = application()->desktop(); + //QWidget* parent = application()->desktop(); - createMedAction( 931, "MESHSEL" ); - createMedAction( 932, "FIELDSEL" ); - createMedAction( 933, "EXPLORE" ); + createMedAction( 931, "MESHSEL", "ICO_TB_MESHSEL" ); + createMedAction( 932, "FIELDSEL", "ICO_TB_FIELDSEL" ); + createMedAction( 933, "EXPLORE", "ICO_TB_EXPLORE" ); createMedAction( 934, "DUMPMESH" ); createMedAction( 935, "DUMPSUBMESH" ); // createMedAction( 8031, "POPUPTEST" ); @@ -164,24 +136,6 @@ void MedGUI::initialize( CAM_Application* app ) createTool( 4031, medTb ); createTool( 4032, medTb ); createTool( 4033, medTb ); - -// QString OB = "'ObjectBrowser'", -// View = QString("'%1'").arg( "VTKViewer" /* SVTK_Viewer::Type()*/ ); - -// createPopupItem( 8031, View, "", "" ); -// createPopupItem( 9002, OB, "", "" ); -// createPopupItem( 903, OB, "", "" ); -} - -void MedGUI::contextMenuPopup( const QString& client, QPopupMenu* menu, QString& /*title*/ ) -{ - MedGUI_Selection sel; - SalomeApp_Application* app = dynamic_cast( application() ); - if( app ) - { - sel.init( client, app->selectionMgr() ); - popupMgr()->updatePopup( menu, &sel ); - } } QString MedGUI::engineIOR() const @@ -198,22 +152,24 @@ QString MedGUI::engineIOR() const void MedGUI::windows( QMap& mappa ) const { - mappa.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::DockLeft ); - mappa.insert( SalomeApp_Application::WT_PyConsole, Qt::DockBottom ); + mappa.clear(); + mappa.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea ); + mappa.insert( SalomeApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea ); } - //============================================================================= /*! * */ //============================================================================= +#include +#include void MedGUI::onGUIEvent() { - const QObject* obj = sender(); - if ( !obj || !obj->inherits( "QAction" ) ) + const QtxAction* obj = qobject_cast(sender()); + if ( !obj ) return; - int id = actionId((QAction*)obj); + int id = actionId( obj ); if ( id != -1 ) OnGUIEvent( id ); } @@ -323,26 +279,26 @@ bool MedGUI::OnGUIEvent (int theCommandID) // Selection du Maillage if (!file.isEmpty() ) { - SCRUTE(file); + SCRUTE((const char*)file.toLatin1()); QString meshName; - meshName = QInputDialog::getText( QString( tr("MED_INF_MESHNAME") ), + meshName = QInputDialog::getText( application()->desktop(), + tr("MED_INF_MESHNAME"), QString::null, - //VRV: porting on Qt 3.0.5 -#if QT_VERSION >= 0x030005 QLineEdit::Normal, -#endif - //VRV: porting on Qt 3.0.5 - QString::null, &ok); - if ( ! meshName.isEmpty()) + QString::null, + &ok ); + if ( ok && !meshName.isEmpty() ) { try { - medgen->readMeshInFile(file.latin1(),myStudyName,meshName); + medgen->readMeshInFile( (const char*)file.toLatin1(), + (const char*)myStudyName.toLatin1(), + (const char*)meshName.toLatin1() ); if (myActiveStudy->studyDS()->GetProperties()->IsLocked()) { - SUIT_MessageBox::warn1 (application()->desktop(), - QObject::tr("WRN_WARNING"), - QObject::tr("WRN_STUDY_LOCKED"), - QObject::tr("BUT_OK")); + SUIT_MessageBox::warning ( application()->desktop(), + tr("WRN_WARNING"), + tr("WRN_STUDY_LOCKED") ); + //QObject::tr("BUT_OK")); by default } } catch (const SALOME::SALOME_Exception & S_ex) @@ -366,10 +322,14 @@ bool MedGUI::OnGUIEvent (int theCommandID) // load MED engine SALOME_MED::MED_Gen_ptr medgen = InitMedGen(); - + // Selection du Fichier + QString anInitialPath = ""; + if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() ) + anInitialPath = QDir::currentPath(); + file = SUIT_FileDlg::getFileName(application()->desktop(), - "", + anInitialPath, filtersList, tr("MED_MEN_IMPORT"), true); @@ -377,26 +337,28 @@ bool MedGUI::OnGUIEvent (int theCommandID) // Selection du Maillage if (!file.isEmpty() ) { - SCRUTE(file); + SCRUTE((const char*)file.toLatin1()); QString fieldName; - fieldName = QInputDialog::getText( - QString( tr("MED_INF_FIELDNAME") ), QString::null, - //VRV: porting on Qt 3.0.5 -#if QT_VERSION >= 0x030005 - QLineEdit::Normal, -#endif - //VRV: porting on Qt 3.0.5 - QString::null, &ok); - if ( ! fieldName.isEmpty()) + fieldName = QInputDialog::getText( application()->desktop(), + tr("MED_INF_FIELDNAME"), + QString::null, + QLineEdit::Normal, + QString::null, + &ok ); + if ( ok && !fieldName.isEmpty()) { try { - medgen->readFieldInFile(file.latin1(),myStudyName,fieldName,-1,-1); + medgen->readFieldInFile( (const char*)file.toLatin1(), + (const char*)myStudyName.toLatin1(), + (const char*)fieldName.toLatin1(), + -1, + -1 ); if (myActiveStudy->studyDS()->GetProperties()->IsLocked()) { - SUIT_MessageBox::warn1 (application()->desktop(), - QObject::tr("WRN_WARNING"), - QObject::tr("WRN_STUDY_LOCKED"), - QObject::tr("BUT_OK")); + SUIT_MessageBox::warning ( application()->desktop(), + tr("WRN_WARNING"), + tr("WRN_STUDY_LOCKED") ); + //tr("BUT_OK")); by default } } catch (const SALOME::SALOME_Exception & S_ex) @@ -420,18 +382,23 @@ bool MedGUI::OnGUIEvent (int theCommandID) SALOME_MED::MED_Gen_ptr medgen = InitMedGen(); // Selection du Fichier + QString anInitialPath = ""; + if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() ) + anInitialPath = QDir::currentPath(); + file = SUIT_FileDlg::getFileName(application()->desktop(), - "", + anInitialPath, filtersList, tr("MED_MEN_IMPORT"), true); if (!file.isEmpty() ) { - SCRUTE(file); + SCRUTE((const char*)file.toLatin1()); try { // medgen->readStructFile(file.latin1(),myStudyName); - medgen->readStructFileWithFieldType(file.latin1(),myStudyName); + medgen->readStructFileWithFieldType((const char*)file.toLatin1(), + (const char*)myStudyName.toLatin1()); MESSAGE("Ouais on est la !!!!"); @@ -439,10 +406,10 @@ bool MedGUI::OnGUIEvent (int theCommandID) MESSAGE("Ouais on est la 1 !!!!"); - SUIT_MessageBox::warn1 (application()->desktop(), - QObject::tr("WRN_WARNING"), - QObject::tr("WRN_STUDY_LOCKED"), - QObject::tr("BUT_OK")); + SUIT_MessageBox::warning (application()->desktop(), + tr("WRN_WARNING"), + tr("WRN_STUDY_LOCKED") ); + //QObject::tr("BUT_OK")); by default } } catch (const SALOME::SALOME_Exception & S_ex) @@ -488,38 +455,23 @@ bool MedGUI::OnGUIEvent (int theCommandID) anIOR = anAttr; aMesh = SALOME_MED::MESH::_narrow( _orb->string_to_object(anIOR->Value().c_str()) ); if ( aMesh->_is_nil() ) - { - // aM = SMESH::SMESH_Mesh::_narrow(_orb->string_to_object(anIOR->Value())); - // if ( aM->_is_nil() ) - // { - // QAD_MessageBox::warn1 - // ( QAD_Application::getDesktop(), - // tr ("MED_WRN_WARNING"), - // tr ("MED_INF_NOTIMPL"), - // tr ("MED_BUT_OK") ); - // break; - // } - // aMesh = aM->GetMEDMesh(); - if ( aMesh->_is_nil() ) - { - SUIT_MessageBox::warn1 - ( application()->desktop(), - tr ("MED_WRN_WARNING"), - tr ("MED_INF_NOTIMPL"), - tr ("MED_BUT_OK") ); - break; - } - } + { + SUIT_MessageBox::warning + ( application()->desktop(), + tr ("MED_WRN_WARNING"), + tr ("MED_INF_NOTIMPL") ); + break; + } DumpMesh( aMesh ); //Sel->ClearFilters() ; } else { - SUIT_MessageBox::warn1 + SUIT_MessageBox::warning ( application()->desktop(), tr ("MED_WRN_WARNING"), - tr ("MED_INF_NOIOR"), - tr ("MED_BUT_OK") ); + tr ("MED_INF_NOIOR") ); + //tr ("MED_BUT_OK") ); by default break; } } @@ -556,34 +508,14 @@ bool MedGUI::OnGUIEvent (int theCommandID) if (aMorSM->FindAttribute(anAttr, "AttributeIOR")) { anIOR = anAttr; - // aSubM = SMESH::SMESH_subMesh::_narrow( _orb->string_to_object(anIOR->Value()) ); - // if ( aSubM->_is_nil() ) - // { - // aFam=SALOME_MED::FAMILY::_narrow( _orb->string_to_object(anIOR->Value())); - // if ( aFam->_is_nil() ) - // { - // QAD_MessageBox::warn1 - // ( QAD_Application::getDesktop(), - // tr ("MED_WRN_WARNING"), - // tr ("MED_INF_NOTIMPL"), - // tr ("MED_BUT_OK") ); - // break; - // } - // DumpSubMesh( aFam ); - // } - // else - // { - // DumpSubMesh( aSubM ); - //Sel->ClearFilters() ; - // } } else { - SUIT_MessageBox::warn1 + SUIT_MessageBox::warning ( application()->desktop(), tr ("MED_WRN_WARNING"), - tr ("MED_INFNOIOR"), - tr ("MED_BUT_OK") ); + tr ("MED_INFNOIOR") ); + // tr ("MED_BUT_OK") ); by default break; } } @@ -635,53 +567,6 @@ bool MedGUI::OnKeyPress (QKeyEvent* pe, return true; } -//============================================================================= -/*! - * - */ -//============================================================================= -/*bool MedGUI::SetSettings () -{ - MESSAGE("MedGUI::SetSettings"); - return true; -}*/ - -//============================================================================= -/*! - * - */ -//============================================================================= -/*bool MedGUI::CustomPopup ( QPopupMenu* popup, - const QString & theContext, - const QString & theParent, - const QString & theObject ) -{ - MESSAGE("MedGUI::CustomPopup"); - popup->clear(); - return true; -}*/ - -//============================================================================= -/*! - * - */ -//============================================================================= -/*bool MedGUI::ActiveStudyChanged() -{ - return true; -}*/ - -//============================================================================= -/*! - * - */ -//============================================================================= -/*void MedGUI::DefinePopup( QString & theContext, QString & theParent, QString & theObject ) -{ - theObject = ""; - theContext = ""; -} -*/ //============================================================================= /*! * @@ -754,26 +639,6 @@ bool MedGUI::DumpMesh( SALOME_MED::MESH_var MEDMesh) return true; } -//============================================================================= -/*! - * - */ -//============================================================================= -// bool MedGUI::DumpSubMesh( SMESH::SMESH_subMesh_ptr aSubMesh ) -// { -// if ( aSubMesh->_is_nil() ) -// return false; - -// SALOME_MED::FAMILY_var Fam = aSubMesh->GetFamily(); -// if ( Fam->_is_nil() ) -// return false; - -// SALOME_MED::long_array_var tabnoeuds=Fam->getNumber(SALOME_MED::MED_NONE); -// for (int l=0;llength();l++) -// SCRUTE(tabnoeuds[l]); - -// return true; -// } //============================================================================= /*! * diff --git a/src/MEDGUI/MedGUI.h b/src/MEDGUI/MedGUI.h index c555b748b..32fbcee39 100644 --- a/src/MEDGUI/MedGUI.h +++ b/src/MEDGUI/MedGUI.h @@ -1,12 +1,28 @@ -// MED MEDGUI : MED component GUI implemetation +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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. // -// Copyright (C) 2003 CEA/DEN, EDF R&D +// 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 // +// MED MEDGUI : MED component GUI implemetation // File : MEDGUI.h // Module : MED - +// #ifndef _MEDGUI_H_ #define _MEDGUI_H_ @@ -15,7 +31,6 @@ #include #include CORBA_CLIENT_HEADER(MED_Gen) -//#include CORBA_CLIENT_HEADER(SMESH_Mesh) #include CORBA_SERVER_HEADER(SALOMEDS_Attributes) class MedGUI: public SalomeApp_Module @@ -25,18 +40,18 @@ class MedGUI: public SalomeApp_Module public: MedGUI(); - virtual void initialize ( CAM_Application* ); - virtual QString engineIOR() const; - virtual void windows( QMap& mappa ) const; - virtual bool OnGUIEvent (int theCommandID); - virtual bool OnKeyPress (QKeyEvent* pe, SUIT_ViewWindow* ); - virtual bool OnMousePress (QMouseEvent* pe, SUIT_ViewWindow* ); - virtual bool OnMouseMove (QMouseEvent* pe, SUIT_ViewWindow* ); + virtual void initialize( CAM_Application* ); + virtual QString engineIOR() const; + virtual void windows( QMap& mappa ) const; + + virtual bool OnGUIEvent(int theCommandID); + virtual bool OnKeyPress(QKeyEvent* pe, SUIT_ViewWindow* ); + virtual bool OnMousePress(QMouseEvent* pe, SUIT_ViewWindow* ); + virtual bool OnMouseMove(QMouseEvent* pe, SUIT_ViewWindow* ); void createMedAction( const int, const QString&, const QString& = "" ); - void createPopupItem( const int, const QString&, const QString&, const QString& = "", const int = -1 ); - virtual void contextMenuPopup( const QString&, QPopupMenu*, QString& ); + //virtual void contextMenuPopup( const QString&, QMenu*, QString& ); //virtual bool SetSettings (); //virtual bool CustomPopup ( QAD_Desktop* parent, QPopupMenu* popup, const QString & theContext, @@ -47,7 +62,6 @@ public: /*static*/ SALOME_MED::MED_Gen_ptr InitMedGen() const; static bool DumpMesh( SALOME_MED::MESH_var aMesh ); - // static bool DumpSubMesh( SMESH::SMESH_subMesh_ptr aSubMesh ) ; static bool DumpSubMesh( SALOME_MED::FAMILY_var Fam ) ; static void setOrb(); diff --git a/src/MEDGUI/MedGUI_Selection.cxx b/src/MEDGUI/MedGUI_Selection.cxx index 7f0928250..eb605fc68 100644 --- a/src/MEDGUI/MedGUI_Selection.cxx +++ b/src/MEDGUI/MedGUI_Selection.cxx @@ -1,23 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // - #include "MedGUI_Selection.h" //======================================================================= diff --git a/src/MEDGUI/MedGUI_Selection.h b/src/MEDGUI/MedGUI_Selection.h index 9d14bb947..bb2d21513 100644 --- a/src/MEDGUI/MedGUI_Selection.h +++ b/src/MEDGUI/MedGUI_Selection.h @@ -1,6 +1,6 @@ -// MED MEDGUI_Selection +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // // This library is free software; you can redistribute it and/or @@ -17,15 +17,14 @@ // 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 -// -// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// MED MEDGUI_Selection // File : MEDGUI_Selection.h // Author : Alexander SOLOVYOV // Module : MED // $Header$ - +// #ifndef MEDGUI_SELECTION_HeaderFile #define MEDGUI_SELECTION_HeaderFile diff --git a/src/MEDMEM/DataTest/constituedump.sh b/src/MEDMEM/DataTest/constituedump.sh index 4e421b772..bfbafb0d0 100644 --- a/src/MEDMEM/DataTest/constituedump.sh +++ b/src/MEDMEM/DataTest/constituedump.sh @@ -1,29 +1,28 @@ #!/bin/sh +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # +# 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. # +# 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 # # File : constituedump.sh # Module : MED - +# cd Data for i in `ls *.med` do diff --git a/src/MEDMEM/DataTest/testreadCoordinate.sh b/src/MEDMEM/DataTest/testreadCoordinate.sh index 53f2958a9..2c751c237 100755 --- a/src/MEDMEM/DataTest/testreadCoordinate.sh +++ b/src/MEDMEM/DataTest/testreadCoordinate.sh @@ -1,29 +1,28 @@ #!/bin/sh +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # +# 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. # +# 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 # # File : testreadCoordinate.sh # Module : MED - +# SALOME=${HOME}/V08 SALOME_LIB=${SALOME}/Build/lib SALOME_PATH=${SALOME}/Build/MED/src/MEDMEM diff --git a/src/MEDMEM/DataTest/testreadEntete.sh b/src/MEDMEM/DataTest/testreadEntete.sh index f4620d7e6..db0de3978 100755 --- a/src/MEDMEM/DataTest/testreadEntete.sh +++ b/src/MEDMEM/DataTest/testreadEntete.sh @@ -1,29 +1,28 @@ #!/bin/sh +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # +# 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. # +# 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 # # File : testreadEntete.sh # Module : MED - +# SALOME=${HOME}/V08 SALOME_LIB=${SALOME}/Build/lib SALOME_PATH=${SALOME}/Build/MED/src/MEDMEM diff --git a/src/MEDMEM/DataTest/tous.sh b/src/MEDMEM/DataTest/tous.sh index 279384362..e7081cdb8 100755 --- a/src/MEDMEM/DataTest/tous.sh +++ b/src/MEDMEM/DataTest/tous.sh @@ -1,27 +1,27 @@ -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # +# 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. +# +# 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 # # File : tous.sh # Module : MED - +# SALOME=${HOME}/V08 SALOME_LIB=${SALOME}/Build/lib SALOME_PATH=${SALOME}/Build/MED/src/MEDMEM diff --git a/src/MEDMEM/Doxyfile_med_devel.in b/src/MEDMEM/Doxyfile_med_devel.in index b727dc588..ffef6aefd 100644 --- a/src/MEDMEM/Doxyfile_med_devel.in +++ b/src/MEDMEM/Doxyfile_med_devel.in @@ -1,8 +1,29 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# # Doxyfile 0.1 - #--------------------------------------------------------------------------- # General configuration options #--------------------------------------------------------------------------- +# PROJECT_NAME = "Med Memory Developpers'" PROJECT_NUMBER = @VERSION@ OUTPUT_DIRECTORY = doc_ref_devel diff --git a/src/MEDMEM/Doxyfile_med_user.in b/src/MEDMEM/Doxyfile_med_user.in index 23fd40fcc..a5e792188 100644 --- a/src/MEDMEM/Doxyfile_med_user.in +++ b/src/MEDMEM/Doxyfile_med_user.in @@ -1,8 +1,29 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# # Doxyfile 0.1 - #--------------------------------------------------------------------------- # General configuration options #--------------------------------------------------------------------------- +# PROJECT_NAME = "Med Memory Users'" PROJECT_NUMBER = @VERSION@ OUTPUT_DIRECTORY = doc_ref_user diff --git a/src/MEDMEM/MEDMEM.hxx b/src/MEDMEM/MEDMEM.hxx index 5017496e5..aa0f7cd3a 100755 --- a/src/MEDMEM/MEDMEM.hxx +++ b/src/MEDMEM/MEDMEM.hxx @@ -1,28 +1,28 @@ -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. +// +// 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 // // File : MEDMEM.hxx // Author : Alexander A. BORODIN // Module : MED - +// #ifndef _MEDMEM_HXX_ #define _MEDMEM_HXX_ diff --git a/src/MEDMEM/MEDMEM_Array.hxx b/src/MEDMEM/MEDMEM_Array.hxx index 0315653b1..6153209a2 100644 --- a/src/MEDMEM/MEDMEM_Array.hxx +++ b/src/MEDMEM/MEDMEM_Array.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef __MEDARRAY_H__ #define __MEDARRAY_H__ @@ -129,13 +131,13 @@ template inline MEDARRAY::MEDARRAY(): _valuesFull(), _valuesNo(), _valuesDefault(), _valuesOther() { -}; +} // ------------------ template inline MEDARRAY::~MEDARRAY() { -}; +} // ------------------ @@ -158,7 +160,7 @@ template MEDARRAY::MEDARRAY(const int ld_values, _valuesFull(), _valuesNo(), _valuesDefault(),_valuesOther() { - // BEGIN_OF("constructor MEDARRAY::MEDARRAY(const int, const int, const medModeSwitch)"); + // BEGIN_OF_MED("constructor MEDARRAY::MEDARRAY(const int, const int, const medModeSwitch)"); // if ld_values < 1 or length_values < 1 // throws an exception @@ -176,18 +178,18 @@ template MEDARRAY::MEDARRAY(const int ld_values, } else { - ASSERT (_mode == MED_EN::MED_NO_INTERLACE); + ASSERT_MED (_mode == MED_EN::MED_NO_INTERLACE); _valuesNo.set(length_values*ld_values); _valuesDefault.set((T*)_valuesNo); } - ASSERT( (T*)_valuesDefault != NULL); -// SCRUTE((T*)_valuesDefault); -// SCRUTE((T*)_valuesOther); -// SCRUTE((T*)_valuesNo); -// SCRUTE((T*)_valuesFull); + ASSERT_MED( (T*)_valuesDefault != NULL); +// SCRUTE_MED((T*)_valuesDefault); +// SCRUTE_MED((T*)_valuesOther); +// SCRUTE_MED((T*)_valuesNo); +// SCRUTE_MED((T*)_valuesFull); - // END_OF("constructor MEDARRAY::MEDARRAY(const int, const int, const medModeSwitch ()"); + // END_OF_MED("constructor MEDARRAY::MEDARRAY(const int, const int, const medModeSwitch ()"); } // ------------------ @@ -207,7 +209,7 @@ template MEDARRAY::MEDARRAY( T*values, _valuesFull(),_valuesNo(), _valuesDefault(),_valuesOther() { - // BEGIN_OF("constructor MEDARRAY::MEDARRAY(T* values, const int, const int, const medModeSwitch)"); + // BEGIN_OF_MED("constructor MEDARRAY::MEDARRAY(T* values, const int, const int, const medModeSwitch)"); // if ld_values < 1 or length_values < 1, we could not allocate // throws an exception @@ -237,7 +239,7 @@ template MEDARRAY::MEDARRAY( T*values, } else { - ASSERT (_mode == MED_EN::MED_NO_INTERLACE); + ASSERT_MED (_mode == MED_EN::MED_NO_INTERLACE); if(shallowCopy) { if(ownershipOfValues) @@ -253,13 +255,13 @@ template MEDARRAY::MEDARRAY( T*values, _valuesNo.set(_ldValues*length_values,values); _valuesDefault.set((T*)_valuesNo); } - ASSERT( (T*)_valuesDefault != NULL); -// SCRUTE((T*)_valuesDefault); -// SCRUTE((T*)_valuesOther); -// SCRUTE((T*)_valuesNo); -// SCRUTE((T*)_valuesFull); + ASSERT_MED( (T*)_valuesDefault != NULL); +// SCRUTE_MED((T*)_valuesDefault); +// SCRUTE_MED((T*)_valuesOther); +// SCRUTE_MED((T*)_valuesNo); +// SCRUTE_MED((T*)_valuesFull); - // END_OF("constructor MEDARRAY::MEDARRAY(T* values, const int, const int, const medModeSwitch)"); + // END_OF_MED("constructor MEDARRAY::MEDARRAY(T* values, const int, const int, const medModeSwitch)"); } // ------------------ @@ -276,13 +278,13 @@ template MEDARRAY::MEDARRAY(MEDARRAY const & m ): _valuesDefault((const T*)m._valuesDefault), _valuesOther((const T*)m._valuesOther) { - // BEGIN_OF("constructor MEDARRAY::MEDARRAY(MEDARRAY const & m)"); - ASSERT( (T*)_valuesDefault != NULL); -// SCRUTE((T*)_valuesDefault); -// SCRUTE((T*)_valuesOther); -// SCRUTE((T*)_valuesNo); -// SCRUTE((T*)_valuesFull); - // END_OF("constructor MEDARRAY::MEDARRAY(MEDARRAY const & m)"); + // BEGIN_OF_MED("constructor MEDARRAY::MEDARRAY(MEDARRAY const & m)"); + ASSERT_MED( (T*)_valuesDefault != NULL); +// SCRUTE_MED((T*)_valuesDefault); +// SCRUTE_MED((T*)_valuesOther); +// SCRUTE_MED((T*)_valuesNo); +// SCRUTE_MED((T*)_valuesFull); + // END_OF_MED("constructor MEDARRAY::MEDARRAY(MEDARRAY const & m)"); } /*! This constructor allocates a new array and does a copy of values @@ -301,7 +303,7 @@ template MEDARRAY::MEDARRAY(MEDARRAY const & p,bool copyOther ): _valuesDefault(), _valuesOther() { - // BEGIN_OF("Constructeur deepCopy MEDARRAY::MEDARRAY(MEDARRAY const & m,bool copyOther"); + // BEGIN_OF_MED("Constructeur deepCopy MEDARRAY::MEDARRAY(MEDARRAY const & m,bool copyOther"); // PG : Non, s'il n'y a rien, on test et on ne copie rien, c'est tout ! @@ -323,7 +325,7 @@ template MEDARRAY::MEDARRAY(MEDARRAY const & p,bool copyOther ): } else { - ASSERT (_mode == MED_EN::MED_NO_INTERLACE); + ASSERT_MED (_mode == MED_EN::MED_NO_INTERLACE); _valuesNo.set(p._ldValues*p._lengthValues,(const T*)p._valuesNo); _valuesDefault.set((T*)_valuesNo); if (copyOther) @@ -342,13 +344,13 @@ template MEDARRAY::MEDARRAY(MEDARRAY const & p,bool copyOther ): template MEDARRAY & MEDARRAY::operator = (const MEDARRAY & m) { - // BEGIN_OF("Operator = MEDARRAY"); + // BEGIN_OF_MED("Operator = MEDARRAY"); _ldValues=m._ldValues; _lengthValues=m._lengthValues; _mode=m._mode; - // SCRUTE(_mode); + // SCRUTE_MED(_mode); if ((const T*) m._valuesFull !=NULL) _valuesFull.set(_ldValues*_lengthValues,(const T*) m._valuesFull); @@ -363,7 +365,7 @@ template MEDARRAY & MEDARRAY::operator = (const MEDARRAY & m) _valuesDefault.set((T*) _valuesFull); _valuesOther.set((T*) _valuesNo); } else { - ASSERT (_mode == MED_EN::MED_NO_INTERLACE); + ASSERT_MED (_mode == MED_EN::MED_NO_INTERLACE); //PN : pour enlever les warning compilateur //_valuesDefault.set((const T*) _valuesNo); //_valuesOther.set((const T*) _valuesFull); @@ -371,12 +373,12 @@ template MEDARRAY & MEDARRAY::operator = (const MEDARRAY & m) _valuesOther.set((T*) _valuesFull); } -// SCRUTE((T*)_valuesDefault); -// SCRUTE((T*)_valuesOther); -// SCRUTE((T*)_valuesNo); -// SCRUTE((T*)_valuesFull); +// SCRUTE_MED((T*)_valuesDefault); +// SCRUTE_MED((T*)_valuesOther); +// SCRUTE_MED((T*)_valuesNo); +// SCRUTE_MED((T*)_valuesFull); - // END_OF("Operator = MEDARRAY"); + // END_OF_MED("Operator = MEDARRAY"); return *this; } @@ -408,7 +410,7 @@ template MEDARRAY & MEDARRAY::shallowCopy(const MEDARRAY & m) template inline int MEDARRAY::getLeadingValue() const { return _ldValues; -}; +} // ------------------ @@ -416,7 +418,7 @@ template inline int MEDARRAY::getLeadingValue() const template inline int MEDARRAY::getLengthValue() const { return _lengthValues; -}; +} // ------------------ @@ -426,7 +428,7 @@ template inline int MEDARRAY::getLengthValue() const The pointer can be used to set values */ template const T* MEDARRAY::get(const MED_EN::medModeSwitch mode) { - // BEGIN_OF("MEDARRAY::get(const medModeSwitch mode)"); + // BEGIN_OF_MED("MEDARRAY::get(const medModeSwitch mode)"); if ((T*)_valuesDefault == NULL) { throw MEDEXCEPTION("MEDARRAY::get(mode) : No values defined !"); @@ -475,7 +477,7 @@ template const T* MEDARRAY::getRow(const int i) { calculateOther(); } - ASSERT((T*)_valuesFull != NULL); + ASSERT_MED((T*)_valuesFull != NULL); // PN pour enlever les warning compilateurs //const T* ptr = (const T*)_valuesFull + (i-1)*_ldValues; @@ -508,7 +510,7 @@ template const T* MEDARRAY::getColumn(const int j) if ((T*)_valuesNo == NULL) { - ASSERT(((T*) _valuesDefault)==((T*) _valuesFull)); + ASSERT_MED(((T*) _valuesDefault)==((T*) _valuesFull)); calculateOther(); } //PN pour enlever les warning compilateur @@ -576,7 +578,7 @@ template inline MED_EN::medModeSwitch MEDARRAY::getMode() const // template void MEDARRAY::set(const medModeSwitch mode, const T* value) // { -// BEGIN_OF("MEDARRAY::set(mode,value)"); +// BEGIN_OF_MED("MEDARRAY::set(mode,value)"); // _mode = mode; // if ( _mode == MED_FULL_INTERLACE) @@ -587,20 +589,20 @@ template inline MED_EN::medModeSwitch MEDARRAY::getMode() const // } // else // { -// ASSERT (_mode == MED_NO_INTERLACE); +// ASSERT_MED (_mode == MED_NO_INTERLACE); // _valuesNo.set(value); // _valuesDefault.set((T*)_valuesNo); // _valuesFull.set(0); // } // _valuesOther.set(0); -// END_OF("MEDARRAY::set(mode,i,value)"); +// END_OF_MED("MEDARRAY::set(mode,i,value)"); // } // set with duplication because we don't know were value come and // MEDARRAY must have properties on it !!!! template void MEDARRAY::set(const MED_EN::medModeSwitch mode, const T* value) { - // BEGIN_OF("MEDARRAY::set(mode,value)"); + // BEGIN_OF_MED("MEDARRAY::set(mode,value)"); _mode = mode; if ( _mode == MED_EN::MED_FULL_INTERLACE) @@ -611,14 +613,14 @@ template void MEDARRAY::set(const MED_EN::medModeSwitch mode, const } else { - ASSERT (_mode == MED_EN::MED_NO_INTERLACE); + ASSERT_MED (_mode == MED_EN::MED_NO_INTERLACE); _valuesNo.set(_ldValues*_lengthValues,value); _valuesDefault.set((T*)_valuesNo); _valuesFull.set(0); } _valuesOther.set(0); - // END_OF("MEDARRAY::set(mode,i,value)"); + // END_OF_MED("MEDARRAY::set(mode,i,value)"); } /*! This function clears the other mode of representation if it exists @@ -645,7 +647,7 @@ template void MEDARRAY::clearOtherMode() Throws exception if i < 1 or i > _lengthValues */ template void MEDARRAY::setI(const int i, const T* value) { - // BEGIN_OF("MEDARRAY::setI(i,value)"); + // BEGIN_OF_MED("MEDARRAY::setI(i,value)"); if ((T*)_valuesDefault == NULL) { @@ -676,7 +678,7 @@ template void MEDARRAY::setI(const int i, const T* value) } } - // END_OF("MEDARRAY::setI(i,value)"); + // END_OF_MED("MEDARRAY::setI(i,value)"); } // ------------------ @@ -685,7 +687,7 @@ template void MEDARRAY::setI(const int i, const T* value) Throws exception if i < 1 or i > _lengthValues */ template void MEDARRAY::setJ(const int j, const T* value) { - // BEGIN_OF("MEDARRAY::setJ(j,value)"); + // BEGIN_OF_MED("MEDARRAY::setJ(j,value)"); if (( T*)_valuesDefault == NULL) { throw MEDEXCEPTION("MEDARRAY::setJ(j) : No values defined !"); @@ -713,7 +715,7 @@ template void MEDARRAY::setJ(const int j, const T* value) _valuesNo[k+_lengthValues*(j-1)] = value[k]; } } - // END_OF("MEDARRAY::setJ(j,value)"); + // END_OF_MED("MEDARRAY::setJ(j,value)"); } // ------------------ @@ -756,7 +758,7 @@ template void MEDARRAY::setIJ(const int i, const int j, const T val Throws exception if no value are setted */ template void MEDARRAY::calculateOther() { - // BEGIN_OF("MEDARRAY::calculateOther()"); + // BEGIN_OF_MED("MEDARRAY::calculateOther()"); if ((T*)_valuesDefault == NULL) { throw MEDEXCEPTION("MEDARRAY::calculateOther() : No values defined !"); @@ -772,7 +774,7 @@ template void MEDARRAY::calculateOther() } else { - ASSERT( _mode==MED_EN::MED_FULL_INTERLACE); + ASSERT_MED( _mode==MED_EN::MED_FULL_INTERLACE); _valuesNo.set((T*)_valuesOther); } @@ -790,7 +792,7 @@ template void MEDARRAY::calculateOther() } } } - // END_OF("MEDARRAY::calculateOther()"); + // END_OF_MED("MEDARRAY::calculateOther()"); } } //End of namespace MEDMEM diff --git a/src/MEDMEM/MEDMEM_ArrayConvert.hxx b/src/MEDMEM/MEDMEM_ArrayConvert.hxx index 891fe50b7..864faa944 100644 --- a/src/MEDMEM/MEDMEM_ArrayConvert.hxx +++ b/src/MEDMEM/MEDMEM_ArrayConvert.hxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #ifndef MEDMEM_ARRAY_CONVERT_HXX #define MEDMEM_ARRAY_CONVERT_HXX @@ -53,7 +56,7 @@ ArrayConvert( return myArray; -}; +} template MEDMEM_Array * @@ -87,7 +90,7 @@ ArrayConvert( return myArray; -}; +} template MEDMEM_Array * @@ -155,7 +158,7 @@ ArrayConvert2No( return myArray; -}; +} template MEDMEM_Array * @@ -181,7 +184,7 @@ ArrayConvert( return myArray; -}; +} template MEDMEM_Array * @@ -233,7 +236,7 @@ ArrayConvert2No( return myArray; -}; +} template MEDMEM_Array * @@ -259,7 +262,7 @@ ArrayConvert( return myArray; -}; +} diff --git a/src/MEDMEM/MEDMEM_ArrayInterface.hxx b/src/MEDMEM/MEDMEM_ArrayInterface.hxx index 62c170aa0..12241a2cc 100644 --- a/src/MEDMEM/MEDMEM_ArrayInterface.hxx +++ b/src/MEDMEM/MEDMEM_ArrayInterface.hxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #ifndef MEDMEM_ARRAYINTERFACE_HXX #define MEDMEM_ARRAYINTERFACE_HXX diff --git a/src/MEDMEM/MEDMEM_AsciiFieldDriver.hxx b/src/MEDMEM/MEDMEM_AsciiFieldDriver.hxx index 1d64a4af8..209821c72 100644 --- a/src/MEDMEM/MEDMEM_AsciiFieldDriver.hxx +++ b/src/MEDMEM/MEDMEM_AsciiFieldDriver.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef ASCII_FIELD_DRIVER_HXX #define ASCII_FIELD_DRIVER_HXX @@ -102,7 +104,7 @@ namespace MEDMEM { template ASCII_FIELD_DRIVER():GENDRIVER(), _ptrField((FIELD)MED_NULL), - _fileName("") {}; + _fileName("") {} template ASCII_FIELD_DRIVER(const string & fileName, FIELD * ptrField, @@ -176,7 +178,10 @@ namespace MEDMEM { FIELD * ptrField, MED_EN::med_sort_direc direction, const char *priority) - :GENDRIVER(fileName,MED_EN::MED_ECRI),_ptrField((FIELD*)ptrField),_fileName(fileName),_direc(direction) + :GENDRIVER(fileName, MED_EN::WRONLY, ASCII_DRIVER), + _ptrField((FIELD*)ptrField), + _fileName(fileName), + _direc(direction) { _nbComponents=_ptrField->getNumberOfComponents(); if(_nbComponents<=0) @@ -199,7 +204,7 @@ namespace MEDMEM { for(i=_spaceDimension-1;i>=0;i--) { char c=toupper(priority[i]); - if(int(c-'X')>(_spaceDimension-1)) + if(int(c-'X')>(_spaceDimension-1) || int(c-'X')<0) throw MEDEXCEPTION("ASCII_FIELD_DRIVER : Invalid priority definition"); _code<<=2; _code+=c-'X'; @@ -209,9 +214,16 @@ namespace MEDMEM { template - ASCII_FIELD_DRIVER::ASCII_FIELD_DRIVER(const ASCII_FIELD_DRIVER& other) - :_ptrField(other._ptrField),_fileName(other._fileName),_direc(other._direc),_mesh(other._mesh),_nbComponents(other._nbComponents), - _code(other._code),_spaceDimension(other._spaceDimension),_support(other._support) + ASCII_FIELD_DRIVER::ASCII_FIELD_DRIVER(const ASCII_FIELD_DRIVER& other): + GENDRIVER(ASCII_DRIVER), + _ptrField(other._ptrField), + _fileName(other._fileName), + _direc(other._direc), + _mesh(other._mesh), + _nbComponents(other._nbComponents), + _code(other._code), + _spaceDimension(other._spaceDimension), + _support(other._support) { } @@ -221,12 +233,17 @@ namespace MEDMEM { if (_file.is_open()) throw MEDEXCEPTION("ASCII_FIELD_DRIVER::open() : file is already open !"); _file.open(_fileName.c_str(),ofstream::out | ofstream::app); + // for MEDMEMTest_AsciiFieldDriver.cxx:208 : + // must throw because the file is opened + //CPPUNIT_ASSERT_MED_THROW(aDriver1->setFileName("anyfile2"), MEDEXCEPTION); + _status = _file.is_open() ? MED_OPENED : MED_INVALID; } template void ASCII_FIELD_DRIVER::close() { _file.close(); + _status = MED_CLOSED; } template diff --git a/src/MEDMEM/MEDMEM_CellModel.cxx b/src/MEDMEM/MEDMEM_CellModel.cxx index 7b3393609..16a40b904 100644 --- a/src/MEDMEM/MEDMEM_CellModel.cxx +++ b/src/MEDMEM/MEDMEM_CellModel.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // /* File MEDMEM_CellModel.cxx @@ -28,6 +30,19 @@ using namespace std; using namespace MEDMEM; using namespace MED_EN; +CELLMODEL_Map *CELLMODEL_Map::_singleton=0; + +const MEDMEM::CELLMODEL& CELLMODEL_Map::retrieveCellModel(MED_EN::medGeometryElement type) +{ + return CELLMODEL_Map::getInstance()->getCellModel(type); +} + +CELLMODEL_Map *CELLMODEL_Map::getInstance() +{ + if(!_singleton) _singleton=new CELLMODEL_Map; + return _singleton; +} + CELLMODEL::CELLMODEL(medGeometryElement t) { // init first all to nothing @@ -41,7 +56,7 @@ CELLMODEL::CELLMODEL(medGeometryElement t) //_numberOfonstituentsType=(int*)NULL ; _constituentsType=(medGeometryElement**)NULL ; - MESSAGE("CELLMODEL : constructeur pour le type " << t); + MESSAGE_MED("CELLMODEL : constructeur pour le type " << t); switch (t) { case MED_POINT1 : { diff --git a/src/MEDMEM/MEDMEM_CellModel.hxx b/src/MEDMEM/MEDMEM_CellModel.hxx index 47181c4f0..578bdf3dd 100644 --- a/src/MEDMEM/MEDMEM_CellModel.hxx +++ b/src/MEDMEM/MEDMEM_CellModel.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // /* File MEDMEM_CellModel.hxx @@ -184,9 +186,9 @@ inline CELLMODEL::CELLMODEL(const CELLMODEL &m) } inline CELLMODEL::~CELLMODEL() { - // MESSAGE("CELLMODEL::~CELLMODEL() destroying the cell"); + // MESSAGE_MED("CELLMODEL::~CELLMODEL() destroying the cell"); clean() ; -}; +} inline CELLMODEL & CELLMODEL::operator=(const CELLMODEL &m) { clean() ; @@ -238,6 +240,36 @@ inline MED_EN::medGeometryElement CELLMODEL::getConstituentType(int dim,int num) return _constituentsType[dim-1][num-1]; } +/*!: Utility class for storing cell models. Avoids calling the cellmodel constructor too +often. +*/ +class MEDMEM_EXPORT CELLMODEL_Map +{ +public: + static const MEDMEM::CELLMODEL& retrieveCellModel(MED_EN::medGeometryElement type); +private: + static CELLMODEL_Map *getInstance(); + static CELLMODEL_Map *_singleton; + std::map _cell_models; + + CELLMODEL_Map(){ + _cell_models.insert(make_pair(MED_EN::MED_TRIA3,CELLMODEL(MED_EN::MED_TRIA3))); + _cell_models.insert(make_pair(MED_EN::MED_QUAD4,CELLMODEL(MED_EN::MED_QUAD4))); + _cell_models.insert(make_pair(MED_EN::MED_TETRA4,CELLMODEL(MED_EN::MED_TETRA4))); + _cell_models.insert(make_pair(MED_EN::MED_HEXA8,CELLMODEL(MED_EN::MED_HEXA8))); + _cell_models.insert(make_pair(MED_EN::MED_PYRA5,CELLMODEL(MED_EN::MED_PYRA5))); + _cell_models.insert(make_pair(MED_EN::MED_PENTA6,CELLMODEL(MED_EN::MED_PENTA6))); + + }; + ~CELLMODEL_Map(){ if(_singleton) delete _singleton;}; + + const MEDMEM::CELLMODEL& getCellModel(MED_EN::medGeometryElement type) + { + return _cell_models[type]; + }; + +}; + }//End of namespace MEDMEM #endif /* CELLMODEL_HXX */ diff --git a/src/MEDMEM/MEDMEM_Compatibility21_22.cxx b/src/MEDMEM/MEDMEM_Compatibility21_22.cxx new file mode 100644 index 000000000..1a4edc8ac --- /dev/null +++ b/src/MEDMEM/MEDMEM_Compatibility21_22.cxx @@ -0,0 +1,97 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_Compatibility21_22.hxx" + +using namespace MEDMEM; +using namespace MED_EN; + +//================================================================================ +/*! + * \brief return file mode access corresponding to MED_EN::med_mode_acces in given med version + * \param mode - either MED_LECT, MED_ECRI or MED_REMP + * \param medVersion - V21 or V22 or ?? + * \retval int - file mode access + * + * To be used in MEDouvrir() call + */ +//================================================================================ + +int MEDMEM::getMedAccessMode(MED_EN::med_mode_acces mode, + MED_EN::medFileVersion medVersion) + throw (MEDEXCEPTION) +{ + switch ( medVersion ) { + case V21: +/* + from MEDouvrir.c: + switch(mode_acces) + { + case MED_LECT : + if (access(nom,F_OK)) + return -1; + else + if ((fid = _MEDfichierOuvrir(nom,mode_acces)) < 0) + return -1; + break; + + case MED_ECRI : + if (access(nom,F_OK)) + { + if ((fid = _MEDfichierCreer(nom)) < 0) + return -1; + } + else + if ((fid = _MEDfichierOuvrir(nom,mode_acces)) < 0) + return -1; + break; + + case MED_REMP : + if ((fid = _MEDfichierCreer(nom)) < 0) + return -1; + break; +*/ + switch ( mode ) { + case MED_EN::WRONLY: return med_2_1::MED_ECRI; + case MED_EN::RDONLY: return med_2_1::MED_LECT; + case MED_EN::RDWR: return med_2_1::MED_ECRI; //REMP; -- pb with RDWR drivers + default: + throw MEDEXCEPTION("getMedAccessMode(): Wrong access mode"); + } + case V22: +/* + from med.h: + MED_LECTURE : Ouverture en lecture seule + MED_LECTURE_ECRITURE : Ouverture en lecture/ecriture, si un élément existe il est écrasé + MED_LECTURE_AJOUT : Ouverture en lecture/ecriture, si un élément existe une erreur est générée + MED_CREATION : Créer le fichier s'il n'existe pas, l'écrase sinon +*/ + switch ( mode ) { + case MED_EN::WRONLY: return med_2_3::MED_LECTURE_ECRITURE;// be coherent with V21 /*MED_CREATION;*/ + case MED_EN::RDONLY: return med_2_3::MED_LECTURE; + case MED_EN::RDWR: return med_2_3::MED_LECTURE_ECRITURE; + default: + throw MEDEXCEPTION("getMedAccessMode(): Wrong access mode"); + } + default:; + } + throw MEDEXCEPTION("getMedAccessMode(): Unknown med version"); +} diff --git a/src/MEDMEM/MEDMEM_Compatibility21_22.hxx b/src/MEDMEM/MEDMEM_Compatibility21_22.hxx index e2c028d6e..42cca671e 100644 --- a/src/MEDMEM/MEDMEM_Compatibility21_22.hxx +++ b/src/MEDMEM/MEDMEM_Compatibility21_22.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // /* Include file managing the compatibility @@ -70,4 +72,15 @@ namespace med_2_3 { #define MED_TAILLE_PNOM21 8 #define MED_TAILLE_PNOM22 16 +//#include "MEDMEM_define.hxx" +#include "MEDMEM_MedVersion.hxx" + +namespace MEDMEM { + + MEDMEM_EXPORT int getMedAccessMode(MED_EN::med_mode_acces mode, + MED_EN::medFileVersion medVersion) + throw (MEDEXCEPTION); + +} + #endif /* COMPATIBILITY_21_22_HXX */ diff --git a/src/MEDMEM/MEDMEM_ConnectZone.cxx b/src/MEDMEM/MEDMEM_ConnectZone.cxx index 51013a37a..ad1d3562c 100644 --- a/src/MEDMEM/MEDMEM_ConnectZone.cxx +++ b/src/MEDMEM/MEDMEM_ConnectZone.cxx @@ -1,5 +1,26 @@ - +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// // few STL include files +// #include // few Med Memory include files diff --git a/src/MEDMEM/MEDMEM_ConnectZone.hxx b/src/MEDMEM/MEDMEM_ConnectZone.hxx index 93e8bd56f..fc34b893c 100644 --- a/src/MEDMEM/MEDMEM_ConnectZone.hxx +++ b/src/MEDMEM/MEDMEM_ConnectZone.hxx @@ -1,4 +1,26 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// // File: MEDMEM_ConnectZone.hxx Author: Nadir Bouhamou (CEA Saclay) +// # ifndef __CONNECTZONE_HXX__ # define __CONNECTZONE_HXX__ diff --git a/src/MEDMEM/MEDMEM_Connectivity.cxx b/src/MEDMEM/MEDMEM_Connectivity.cxx index bc5ab298a..60839a5b5 100644 --- a/src/MEDMEM/MEDMEM_Connectivity.cxx +++ b/src/MEDMEM/MEDMEM_Connectivity.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_Connectivity.hxx" #include "MEDMEM_Family.hxx" @@ -26,6 +28,7 @@ #include "MEDMEM_ModulusArray.hxx" #include "MEDMEM_STRING.hxx" +#include "MEDMEM_Utilities.hxx" #include using namespace std; @@ -88,11 +91,15 @@ CONNECTIVITY::CONNECTIVITY(medEntityMesh Entity /* =MED_CELL */) : _reverseNodalConnectivity((MEDSKYLINEARRAY*)NULL), _reverseDescendingConnectivity((MEDSKYLINEARRAY*)NULL), _neighbourhood((MEDSKYLINEARRAY*)NULL), - _constituent((CONNECTIVITY*)NULL) + _constituent((CONNECTIVITY*)NULL), + _isDescendingConnectivityPartial(false) { - MESSAGE("CONNECTIVITY(medEntityMesh Entity=MED_CELL)"); + const char* LOC = "CONNECTIVITY(medEntityMesh Entity=MED_CELL)"; + BEGIN_OF_MED(LOC); + MESSAGE_MED("CONNECTIVITY(medEntityMesh Entity=MED_CELL)"); _count = new int[1]; _count[0]=1; + END_OF_MED(LOC); } /*! @@ -115,9 +122,10 @@ CONNECTIVITY::CONNECTIVITY(int numberOfTypes,medEntityMesh Entity /* =MED_CELL * _reverseNodalConnectivity((MEDSKYLINEARRAY*)NULL), _reverseDescendingConnectivity((MEDSKYLINEARRAY*)NULL), _neighbourhood((MEDSKYLINEARRAY*)NULL), - _constituent((CONNECTIVITY*)NULL) + _constituent((CONNECTIVITY*)NULL), + _isDescendingConnectivityPartial(false) { - MESSAGE("CONNECTIVITY(int numberOfTypes,medEntityMesh Entity=MED_CELL)"); + MESSAGE_MED("CONNECTIVITY(int numberOfTypes,medEntityMesh Entity=MED_CELL)"); _geometricTypes = new medGeometryElement[numberOfTypes]; _type = new CELLMODEL[numberOfTypes]; _count = new int[numberOfTypes+1]; @@ -134,7 +142,8 @@ CONNECTIVITY::CONNECTIVITY (const CONNECTIVITY & m): _typeConnectivity (m._typeConnectivity), _numberOfTypes (m._numberOfTypes), _entityDimension (m._entityDimension), - _numberOfNodes (m._numberOfNodes) + _numberOfNodes (m._numberOfNodes), + _isDescendingConnectivityPartial(m._isDescendingConnectivityPartial) { if (m._geometricTypes != NULL) { @@ -219,7 +228,7 @@ CONNECTIVITY::CONNECTIVITY (const CONNECTIVITY & m): CONNECTIVITY::~CONNECTIVITY() //----------------------------// { - MESSAGE("Destructeur de CONNECTIVITY()"); + MESSAGE_MED("Destructeur de CONNECTIVITY()"); if (_geometricTypes != NULL) delete [] _geometricTypes; @@ -269,7 +278,10 @@ void CONNECTIVITY::setConstituent(CONNECTIVITY * Constituent) _constituent->setConstituent(Constituent); } else - _constituent = Constituent; + { + delete _constituent; + _constituent = Constituent; + } } /*! Duplicated Types array in CONNECTIVITY object. */ @@ -301,8 +313,13 @@ void CONNECTIVITY::setCount(const int * Count, const medEntityMesh Entity) { if (Entity == _entity) { - if (_numberOfTypes==0) - throw MEDEXCEPTION("Number of Types was not set before setting counts"); + // this exception was added at 1.18.2.2.2.4 for NPAL17043: "Correction of + // MEDMEM CPPUNIT tests. Integrated a work of V. Bergeaud and A. Geay." + // and removed for PAL19744: "regression in MEDMEM_Connectivity.cxx" + // Commenting this exception at least looks safe as the case + // _numberOfTypes==0 is previewed here + //if (_numberOfTypes==0) + // throw MEDEXCEPTION("Number of Types was not set before setting counts"); int * index = new int[Count[_numberOfTypes]]; index[0]=1; _count[0]=1; @@ -366,7 +383,7 @@ void CONNECTIVITY::setPolygonsConnectivity(medConnectivity ConnectivityType, med //--------------------------------------------------------------------// { const char* LOC = "CONNECTIVITY::setPolygonsConnectivity"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_entity == Entity) { @@ -410,7 +427,7 @@ void CONNECTIVITY::setPolyhedronConnectivity(medConnectivity ConnectivityType, c //--------------------------------------------------------------------// { const char* LOC = "CONNECTIVITY::setPolyhedronConnectivity"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_entity == MED_CELL) { @@ -474,7 +491,7 @@ bool CONNECTIVITY::existConnectivityWithPoly (MED_EN::medConnectivity connectivi void CONNECTIVITY::calculateConnectivity(medConnectivity ConnectivityType, medEntityMesh Entity) //------------------------------------------------------------------------------------------// { - MESSAGE("CONNECTIVITY::calculateConnectivity"); + MESSAGE_MED("CONNECTIVITY::calculateConnectivity"); // a temporary limitation due to calculteDescendingConnectivity function !!! if ((_entityDimension==3) & (Entity==MED_EDGE)) @@ -660,7 +677,7 @@ const int * MEDMEM::CONNECTIVITY::getConnectivity(medConnectivity ConnectivityTy //------------------------------------------------------------------------------------------------------------------// { const char * LOC = "CONNECTIVITY::getConnectivity"; - // BEGIN_OF(LOC); + // BEGIN_OF_MED(LOC); MEDSKYLINEARRAY * Connectivity; if (Entity==_entity) { @@ -700,7 +717,7 @@ int CONNECTIVITY::getConnectivityLength(medConnectivity ConnectivityType, medEnt //------------------------------------------------------------------------------------------------------------------// { const char * LOC = "CONNECTIVITY::getConnectivity"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); MEDSKYLINEARRAY * Connectivity; if (Entity==_entity) { @@ -722,7 +739,12 @@ int CONNECTIVITY::getConnectivityLength(medConnectivity ConnectivityType, medEnt else { for (int i=0; i<_numberOfTypes; i++) if (_geometricTypes[i]==Type) - return (_count[i+1]-_count[i])*getType(Type).getNumberOfNodes(); + // issue 19983 + //return (_count[i+1]-_count[i])*getType(Type).getNumberOfNodes(); + { + const int *ind=Connectivity->getIndex(); + return ind[_count[i+1]-1]-ind[_count[i]-1]; + } throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" : Type not found !")); } else @@ -775,7 +797,7 @@ const int* CONNECTIVITY::getPolygonsConnectivity(medConnectivity ConnectivityTyp //-------------------------------------------------------------// { const char* LOC = "CONNECTIVITY::getPolygonsConnectivity"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); MEDSKYLINEARRAY* Connectivity; if (Entity == _entity) @@ -807,7 +829,7 @@ const int* CONNECTIVITY::getPolygonsConnectivityIndex(medConnectivity Connectivi //-------------------------------------------------------------// { const char* LOC = "CONNECTIVITY::getPolygonsConnectivityIndex"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); MEDSKYLINEARRAY* Connectivity; if (Entity == _entity) @@ -863,7 +885,7 @@ const int* CONNECTIVITY::getPolyhedronConnectivity(medConnectivity ConnectivityT //--------------------------------------------------------------// { const char* LOC = "CONNECTIVITY::getPolyhedronConnectivity"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_entity == MED_CELL) //polyhedron can only be MED_CELL { @@ -906,7 +928,7 @@ const int* CONNECTIVITY::getPolyhedronFacesIndex() const //---------------------------------------------------------------// { const char* LOC = "CONNECTIVITY::getPolyhedronFacesIndex"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_entity == MED_CELL) //polyhedron can only be MED_CELL { @@ -937,7 +959,7 @@ const int* CONNECTIVITY::getPolyhedronIndex(medConnectivity ConnectivityType) co //--------------------------------------------------------------// { const char* LOC = "CONNECTIVITY::getPolyhedronIndex"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_entity == MED_CELL) //polyhedron can only be MED_CELL { @@ -1025,7 +1047,7 @@ int CONNECTIVITY::getNumberOfNodesInType(medGeometryElement Type) const //------------------------------------------------------------------------// { const char * LOC = "CONNECTIVITY::getNumberOfNodesInType"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if ((Type==MED_ALL_ELEMENTS) || (Type==MED_NONE)) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" : medGeometryElement must be different of MED_ALL_ELEMENTS and MED_NONE!")); @@ -1059,7 +1081,6 @@ int CONNECTIVITY::getNumberOfSubCellInType(medGeometryElement Type) const int CONNECTIVITY::getNumberOf(medEntityMesh Entity, medGeometryElement Type) const //-----------------------------------------------------------------------------------// { - //const char * LOC = "CONNECTIVITY::getNumberOf"; if (Entity==_entity) { if (Type==MED_EN::MED_NONE) return 0; // not defined ! @@ -1165,6 +1186,9 @@ const int* CONNECTIVITY::getReverseDescendingConnectivity() // we need descending connectivity calculateDescendingConnectivity(); + if (_reverseDescendingConnectivity==NULL) + _reverseDescendingConnectivity=_descending->makeReverseArray(); + return _reverseDescendingConnectivity->getValue(); } @@ -1196,17 +1220,19 @@ void CONNECTIVITY::calculateNodalConnectivity() } } + + /*! If not yet done, calculate the nodal Connectivity and the reverse nodal Connectivity*/ //---------------------------------------------------// void CONNECTIVITY::calculateReverseNodalConnectivity() //---------------------------------------------------// { - const char * LOC = "CONNECTIVITY::calculateReverseNodalConnectivity : "; - BEGIN_OF(LOC); + const char* LOC = "CONNECTIVITY::calculateReverseNodalConnectivity : "; + BEGIN_OF_MED(LOC); - SCRUTE(_nodal); - SCRUTE(_reverseNodalConnectivity); + SCRUTE_MED(_nodal); + SCRUTE_MED(_reverseNodalConnectivity); if (_nodal==NULL) calculateNodalConnectivity(); @@ -1284,30 +1310,61 @@ void CONNECTIVITY::calculateReverseNodalConnectivity() reverse_nodal_connectivity_index, reverse_nodal_connectivity,true); } - END_OF(LOC); + END_OF_MED(LOC); } /*! If not yet done, calculate the Descending Connectivity */ //-------------------------------------------------// void CONNECTIVITY::calculateDescendingConnectivity() //-------------------------------------------------// - { +{ const char * LOC = "CONNECTIVITY::calculateDescendingConnectivity() : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_descending==NULL && _polygonsDescending==NULL && _polyhedronDescending==NULL) + { + if (_nodal==NULL && _polygonsNodal==NULL && _polyhedronNodal==NULL) { - if (_nodal==NULL && _polygonsNodal==NULL && _polyhedronNodal==NULL) - { - MESSAGE(LOC<<"No connectivity found !"); - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No connectivity found !")); - } - // calcul _descending from _nodal - // we need CONNECTIVITY for constituent + MESSAGE_MED(LOC<<"No connectivity found !"); + throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No connectivity found !")); + } + // calcul _descending from _nodal + // we need CONNECTIVITY for constituent - if (_constituent != NULL) - // throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"ERROR : No descending connectivity defined, but constituent exist !")); - MESSAGE(LOC<<": No descending connectivity defined, but constituent exist !"); + if (_constituent != NULL && _constituent->_nodal != NULL) + { + calculatePartialDescendingConnectivity(); + } + else + { + calculateFullDescendingConnectivity(_entity); + } + } +} + +/*! If not yet done, calculate the full Descending Connectivity */ +//-------------------------------------------------// +void CONNECTIVITY::calculateFullDescendingConnectivity(MED_EN::medEntityMesh Entity) +//-------------------------------------------------// +{ + const char * LOC = "CONNECTIVITY::calculateFullDescendingConnectivity() : "; + BEGIN_OF_MED(LOC); + if (_entity != Entity) + { + if (_constituent == NULL) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Entity not found !")); + _constituent->calculateFullDescendingConnectivity(Entity); + } + else + { + if (_descending==NULL && _polygonsDescending==NULL && _polyhedronDescending==NULL || + _isDescendingConnectivityPartial ) + { + if (_nodal==NULL && _polygonsNodal==NULL && _polyhedronNodal==NULL) + { + MESSAGE_MED(LOC<<"No connectivity found !"); + throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No connectivity found !")); + } delete _constituent; _constituent=0; if (_entityDimension == 3) @@ -1316,7 +1373,7 @@ void CONNECTIVITY::calculateDescendingConnectivity() _constituent = new CONNECTIVITY(MED_EDGE); else { - MESSAGE(LOC<<"We are in 1D"); + MESSAGE_MED(LOC<<"We are in 1D"); return; } @@ -1397,6 +1454,8 @@ void CONNECTIVITY::calculateDescendingConnectivity() _constituent->_geometricTypes = new medGeometryElement[_constituent->_numberOfTypes]; _constituent->_type = new CELLMODEL[_constituent->_numberOfTypes]; //CCRT _constituent->_count = new med_int[_constituent->_numberOfTypes+1]; + if(_constituent->_count) + delete [] _constituent->_count; _constituent->_count = new int[_constituent->_numberOfTypes+1]; _constituent->_count[0]=1; med_int* tmp_NumberOfConstituentsForeachType = new med_int[_constituent->_numberOfTypes+1]; @@ -1531,7 +1590,7 @@ void CONNECTIVITY::calculateDescendingConnectivity() break; } if (!find2) - MESSAGE(LOC<<"ERROR ERROR ERROR ERROR ERROR : we find any subcell !!!"); // exception ? + MESSAGE_MED(LOC<<"ERROR ERROR ERROR ERROR ERROR : we find any subcell !!!"); // exception ? } } else { ReverseDescendingConnectivityValue[(TotalNumberOfSubCell-1)*2+1]=0; @@ -1858,22 +1917,264 @@ void CONNECTIVITY::calculateDescendingConnectivity() &Reversedescendingconnectivityindex[0], &Reversedescendingconnectivityvalue[0]); //// + _isDescendingConnectivityPartial = false; } - END_OF(LOC); + END_OF_MED(LOC); } +} + +void CONNECTIVITY::addToDescendingConnectivity(const set& nodes, + multimap& descending, + int iglobal_cell, + const CONNECTIVITY_HashMap & face_map ) +{ + int dimension = getEntityDimension(); + vector signature (dimension); + set::const_iterator iter=nodes.begin(); + for (int i=0; i< dimension;i++) + { + signature[i]=*iter; + iter++; + } + + + CONNECTIVITY_HashMap::const_iterator itermap=face_map.find(signature); + CONNECTIVITY_HashMap::const_iterator iterend=face_map.end(); + + + if (itermap!=iterend) + descending.insert(make_pair(iglobal_cell,itermap->second)); + +} + +/*! This method calculates the descending connectivity without creating missing elements. It only maps the constituent elements that are described in the nodal representation. +For instance, let us consider the following mesh with no MED_EDGE elements on the inner edges. + ++----1----+----2----+ +| | | +8 1 | 2 3 +| | | ++---------+---------+ +| | | +7 3 | 4 4 +| | | ++----6----+----5----+ + + +calculatePartialDescendingConnectivity() +will return +1:1,8 +2:2,3 +3:6,7 +4:4,5 + +whereas calculateDescendingConnectivity() +will create new edges, renumbering existing ones and return +1:1,2,3,4 +2:5,6,7,2 +3:3,8,9,10 +4:7,11,12,8 + ++----1----+----5----+ +| | | +4 1 2 2 6 +| | | ++----3----+----7----+ +| | | +10 3 8 4 11 +| | | ++----9----+----12---+ +*/ + +void CONNECTIVITY::calculatePartialDescendingConnectivity() +{ + //////////////////////////////////////////////////////////////////////////// + // First stage : creating hash_map referencing faces with the triplet + // of the lowest order nodes as a key and the global face number as a value + + CONNECTIVITY_HashMap face_map; + const medGeometryElement* face_types = _constituent->getGeometricTypes(_constituent->getEntity()); + int nbface_types=_constituent->getNumberOfTypes(_constituent->getEntity()); + int iglobal_face=1; + + int dimension = getEntityDimension(); + + //classical types + for (int itype=0; itypegetNumberOf(_constituent->getEntity(),face_type); + for (int iface=0;iface nodes; + const int* index=_constituent->_nodal->getIndex(); + const int* conn=_constituent->_nodal->getValue(); + for (int inode=0;inode signature (dimension); + set::iterator iter=nodes.begin(); + for (int i=0; i< dimension;i++) + { + signature[i]=*iter; + iter++; + } + face_map.insert(make_pair(signature,iglobal_face)); + iglobal_face++; + } + } + + //polygons + if (dimension==3 && _polygonsNodal!=0) + { + int nbfaces=_constituent->getNumberOfPolygons(); + for (int iface=0;iface nodes; + const int* index=_constituent->_polygonsNodal->getIndex(); + int nbnodes=index[iface+1]-index[iface]; + const int* conn=_constituent->_polygonsNodal->getValue(); + for (int inode=0;inode signature (dimension); + set::iterator iter=nodes.begin(); + for (int i=0; i< dimension;i++) + { + signature[i]=*iter; + iter++; + } + face_map.insert(make_pair(signature,iglobal_face)); + iglobal_face++; + } + } + + //////////////////////////////////////////////////////////////////////////// + //Second stage : going through all the faces of the cells and + // connecting them to the hash_map created in the first stage + + multimap descending; //map storing the descending connectivity + + //classical types + int nbcell_types=getNumberOfTypes(_entity); + const medGeometryElement* cell_types=getGeometricTypes(_entity); + int iglobal_cell=1; + for (int itype=0; itype nodes; + const int* local_index=cellmodel.getNodesConstituent(1,iface+1); + medGeometryElement face_type = cellmodel.getConstituentType(1,iface+1); + const int* index=_nodal->getIndex(); + const int* conn=_nodal->getValue(); + int nbnodes=face_type%100; + for (int inode=0;inodegetIndex(); + const int* conn = _polygonsNodal->getValue(); + + for (int icell=0;icell nodes; + if (iface+1!=nbfaces) + { + nodes.insert(conn[index[icell]-1+iface]); + nodes.insert(conn[index[icell]-1+iface+1]); + } + else + { + nodes.insert(conn[index[icell]-1+iface]); + nodes.insert(conn[index[icell]-1]); + } + addToDescendingConnectivity(nodes,descending,iglobal_cell,face_map); + } + iglobal_cell++; + } + } + + //polyhedra case + if (dimension==3 && _polyhedronNodal!=0) + { + int nbcells = getNumberOfElementsWithPoly(_entity,MED_POLYHEDRA); + const MED_EN::med_int* index = _polyhedronNodal->getPolyhedronIndex(); + const MED_EN::med_int* conn = _polyhedronNodal->getNodes(); + const MED_EN::med_int* face_index = _polyhedronNodal->getFacesIndex(); + + for (int icell = 0; icell < nbcells; icell++) + { + for (int iface = face_index[icell]; iface < face_index[icell+1]; iface++) + { + set nodes; + for (int inode = index[iface-1]; iface < index[iface]; iface++) + nodes.insert(conn[inode-1]); + addToDescendingConnectivity(nodes,descending,iglobal_cell,face_map); + } + iglobal_cell++; + } + } + + + //////////////////////////////////////////////////////////////////////////// + // Third stage : reorganizing the descending data to store it in a medskylinearray + + vector index; + vector value; + index.push_back(1); + + //the number of cells is given by the number + //obtained by browsing all the cell types + int nb_cells = iglobal_cell-1; + + for (int icell=0; icell< nb_cells;icell++) + { + multimap::iterator beginning_of_range = descending.lower_bound(icell); + multimap::iterator end_of_range = descending.upper_bound(icell); + int nb=0; + for (multimap::iterator iter2 = beginning_of_range; iter2!=end_of_range;iter2++) + { + value.push_back(iter2->second); + nb++; + } + index.push_back(index[index.size()-1]+nb); + } + _descending=new MEDSKYLINEARRAY(index.size()-1,value.size(),&index[0],&value[0]); + _isDescendingConnectivityPartial = true; +} + /*! Not implemented yet */ //--------------------------------------------------------------------// void CONNECTIVITY::calculateNeighbourhood(CONNECTIVITY &myConnectivity) //--------------------------------------------------------------------// { - const char * LOC = "CONNECTIVITY::calculateNeighbourhood(CONNECTIVITY &myConnectivity) : "; - BEGIN_OF(LOC); + const char* LOC = "CONNECTIVITY::calculateNeighbourhood(CONNECTIVITY &myConnectivity) : "; + BEGIN_OF_MED(LOC); - MESSAGE(LOC<<"method not yet implemented " << myConnectivity._entity); + MESSAGE_MED(PREFIX_MED<<"method not yet implemented " << myConnectivity._entity); // Mesh dimension ! - END_OF(LOC); + END_OF_MED(LOC); return; } @@ -1888,7 +2189,7 @@ medGeometryElement CONNECTIVITY::getElementType(medEntityMesh Entity,int globalN //--------------------------------------------------------------------// { const char * LOC = "medGeometryElement CONNECTIVITY::getElementType(medEntityMesh Entity, int globalNumber) const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); int globalNumberMin = 1; int globalNumberMax ; @@ -1914,7 +2215,7 @@ medGeometryElement CONNECTIVITY::getElementType(medEntityMesh Entity,int globalN throw MEDEXCEPTION(LOCALIZED("getElementType : Entity not defined !")); throw MEDEXCEPTION(LOCALIZED("getElementType : Wrong Number !")); - END_OF(LOC); + END_OF_MED(LOC); } /*! @@ -2174,12 +2475,12 @@ int **CONNECTIVITY::getNodesPerFaceOfPolyhedron(int polyhedronId, int& nbOfFaces int CONNECTIVITY::getNumberOfTypesWithPoly(MED_EN::medEntityMesh Entity) const { - SCRUTE(_entity); - SCRUTE(Entity); + SCRUTE_MED(_entity); + SCRUTE_MED(Entity); if (_entity==Entity) { - SCRUTE(_numberOfTypes); - SCRUTE(getNumberOfPolyType()); + SCRUTE_MED(_numberOfTypes); + SCRUTE_MED(getNumberOfPolyType()); return _numberOfTypes+getNumberOfPolyType(); } else if (_constituent!=NULL) @@ -2246,7 +2547,8 @@ MED_EN::medGeometryElement * CONNECTIVITY::getGeometricTypesWithPoly(MED_EN::med { if(_constituent) return _constituent->getGeometricTypesWithPoly(Entity); - throw MEDEXCEPTION("_constituent required to evaluate getGeometricTypesWithPoly"); + else + return 0; } } diff --git a/src/MEDMEM/MEDMEM_Connectivity.hxx b/src/MEDMEM/MEDMEM_Connectivity.hxx index f976e1cde..9a58bcfc2 100644 --- a/src/MEDMEM/MEDMEM_Connectivity.hxx +++ b/src/MEDMEM/MEDMEM_Connectivity.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef CONNECTIVITY_HXX #define CONNECTIVITY_HXX @@ -23,17 +25,32 @@ #include #include - +#include +#include #include "MEDMEM_Utilities.hxx" #include "MEDMEM_Exception.hxx" #include "MEDMEM_define.hxx" #include "MEDMEM_PolyhedronArray.hxx" #include "MEDMEM_CellModel.hxx" +#ifndef WNT +#include +#else +#include +#endif + +#ifndef WNT +using namespace __gnu_cxx; +#else +using namespace std; +using stdext::hash_map; +#endif namespace MEDMEM { class MEDSKYLINEARRAY; class FAMILY; class GROUP; + class CONNECTIVITY; + MEDMEM_EXPORT ostream & operator<<(ostream &os, CONNECTIVITY &my); /*! This class deals with all type of connectivity .\n @@ -44,6 +61,29 @@ class GROUP; class MEDMEM_EXPORT CONNECTIVITY /* ------------------------------------------- */ { + + class myHashFn + { + public: + size_t operator()(const vector& key) const + { + size_t sum=0; + for (int i=0; i<(int)key.size(); i++) + sum+=key[i]; + return sum; + } +#ifdef WNT + static const size_t bucket_size = 4; + static const size_t min_buckets = 8; + bool operator()(const vector& key1, const vector& key2) const + { + return ::size_t()(key1) < ::size_t()(key2); + } +#endif + }; + + typedef hash_map,int, myHashFn > CONNECTIVITY_HashMap; + /* ---------------------- */ /* Class Attributs */ /* ---------------------- */ @@ -55,19 +95,19 @@ protected: MED_EN::medConnectivity _typeConnectivity; /*! count of differents cells types used by the mesh */ - int _numberOfTypes; + int _numberOfTypes; /*! array of all med_geometric_type used by MESH. */ MED_EN::medGeometryElement* _geometricTypes; /*! map indexed by med_geometric_type which contains the different 'CellModel' used by MESH. */ - CELLMODEL * _type; + CELLMODEL * _type; /*! contains the dimension of the entity */ - int _entityDimension; + int _entityDimension; /*! needed by calculateReverseNodalConnectivity */ - int _numberOfNodes; + int _numberOfNodes; /*! array of size _numberOfTypes+1 which gives for each cell type the first @@ -78,7 +118,7 @@ protected: ( 0 <= i < _numberOfTypes ). Note that _count[_numberOfTypes] returns total cells count + 1 */ - int * _count; + int * _count; /*! pointer to an array which stores the nodal connectivity */ MEDSKYLINEARRAY* _nodal; @@ -108,7 +148,10 @@ protected: MEDSKYLINEARRAY* _neighbourhood; /*! connectivity of sub cell if descendant connectivity is calculated */ - CONNECTIVITY * _constituent; + CONNECTIVITY * _constituent; + /*! is descending connectivity computed by + calculatePartialDescendingConnectivity() */ + bool _isDescendingConnectivityPartial; /* -------------------- */ /* Class Methods */ @@ -127,6 +170,13 @@ private: does nothing if already exists, else evaluates _descending from _nodal */ void calculateDescendingConnectivity(); + + void calculatePartialDescendingConnectivity(); + void addToDescendingConnectivity( const set& nodes, + multimap& descending, + int iglobal_cell , + const CONNECTIVITY_HashMap & ); + /*! private method :\n does nothing if already exists, else evaluates from _descending */ @@ -180,7 +230,7 @@ public: throw (MEDEXCEPTION); inline void setNumberOfNodes(int NumberOfNodes); - + inline int getNumberOfNodes(); inline int getEntityDimension() const; inline void setEntityDimension(int EntityDimension); @@ -199,20 +249,22 @@ public: int NumberOfFaces=0); inline bool existConnectivity (MED_EN::medConnectivity connectivityType, - MED_EN::medEntityMesh Entity) const; + MED_EN::medEntityMesh Entity) const; bool existConnectivityWithPoly (MED_EN::medConnectivity connectivityType, - MED_EN::medEntityMesh Entity) const; + MED_EN::medEntityMesh Entity) const; virtual bool existPolygonsConnectivity (MED_EN::medConnectivity connectivityType, - MED_EN::medEntityMesh Entity) const; + MED_EN::medEntityMesh Entity) const; virtual bool existPolyhedronConnectivity (MED_EN::medConnectivity connectivityType, - MED_EN::medEntityMesh Entity) const; + MED_EN::medEntityMesh Entity) const; + + virtual void calculateConnectivity (MED_EN::medConnectivity connectivityType, + MED_EN::medEntityMesh Entity); - virtual void calculateConnectivity (MED_EN::medConnectivity connectivityType, - MED_EN::medEntityMesh Entity); + virtual void calculateFullDescendingConnectivity(MED_EN::medEntityMesh Entity); - virtual void updateFamily (const vector& myFamilies); + virtual void updateFamily (const vector& myFamilies); inline MED_EN::medEntityMesh getEntity () const; @@ -284,6 +336,8 @@ public: const int* getNeighbourhood() const; void invertConnectivityForAFace(int faceId, const int *nodalConnForFace, bool polygonFace=false); bool deepCompare(const CONNECTIVITY& other) const; + + }; /*----------------------*/ /* Methodes Inline */ @@ -304,14 +358,14 @@ inline MED_EN::medEntityMesh CONNECTIVITY::getEntity() const inline int CONNECTIVITY::getNumberOfTypes(MED_EN::medEntityMesh Entity) const //-----------------------------------------------------------------------// { - MESSAGE("CONNECTIVITY::getNumberOfTypes : Entity = "< (this))->calculateDescendingConnectivity(); @@ -321,7 +375,7 @@ inline int CONNECTIVITY::getNumberOfTypes(MED_EN::medEntityMesh Entity) const return 0 ; } - SCRUTE(_entityDimension); + SCRUTE_MED(_entityDimension); if (_entityDimension != 2 && _entityDimension != 3) return 0; @@ -408,7 +462,7 @@ inline bool CONNECTIVITY::existPolygonsConnectivity(MED_EN::medConnectivity Conn { if (_entity == Entity) { - MESSAGE("existPolygonsConnectivity : _entity == Entity = "< struct hash< std::vector > { +// size_t operator()(const std::vector& input) { +// size_t sum=0; +// for (int i=0; i #include +#include #include "MEDMEM_PointerOf.hxx" #include "MEDMEM_Exception.hxx" @@ -65,10 +68,12 @@ protected: mutable MEDARRAY _coordinate; /*! PointerOf to an array of size spaceDimension storing axes names*/ - PointerOf _coordinateName; + //PointerOf _coordinateName; + vector _coordinateName; /*! PointerOf to an array of size spaceDimension storing units */ - PointerOf _coordinateUnit; + //PointerOf _coordinateUnit; + vector _coordinateUnit; /*! PointerOf to an array of size NumberOfNodes : optional nodes numbers */ PointerOf _nodeNumber; @@ -115,6 +120,6 @@ public : const string * getCoordinatesUnits() const; string getCoordinateUnit(int Axis) const; }; -}; +} #endif /* COORDINATE_HXX */ diff --git a/src/MEDMEM/MEDMEM_DriverFactory.cxx b/src/MEDMEM/MEDMEM_DriverFactory.cxx index 32c2f0ace..436c0f47a 100644 --- a/src/MEDMEM/MEDMEM_DriverFactory.cxx +++ b/src/MEDMEM/MEDMEM_DriverFactory.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_DriverFactory.hxx" #include "MEDMEM_MedMedDriver.hxx" @@ -96,18 +98,17 @@ GENDRIVER *DRIVERFACTORY::buildDriverForMesh(driverTypes driverType, case MED_DRIVER : { switch(access) { - case MED_LECT : { + case RDONLY : { ret = new MED_MESH_RDONLY_DRIVER(fileName, mesh); ret->setMeshName(driverName); return ret; } - case MED_CREA : - case MED_ECRI : { + case WRONLY : { ret = new MED_MESH_WRONLY_DRIVER(fileName, mesh, access); ret->setMeshName(driverName); return ret; } - case MED_REMP : { + case RDWR : { ret = new MED_MESH_RDWR_DRIVER(fileName, mesh); ret->setMeshName(driverName); return ret; @@ -121,13 +122,12 @@ GENDRIVER *DRIVERFACTORY::buildDriverForMesh(driverTypes driverType, case GIBI_DRIVER : { switch(access) { - case MED_LECT : { + case RDONLY : { ret=new GIBI_MESH_RDONLY_DRIVER(fileName,mesh); return ret; } - case MED_REMP : - case MED_CREA : - case MED_ECRI : { + case RDWR : + case WRONLY :{ throw MED_EXCEPTION ("access mode other than MED_LECT has been specified with the GIBI_DRIVER type which is not allowed because GIBI_DRIVER is only a read access driver"); } default: @@ -139,13 +139,12 @@ GENDRIVER *DRIVERFACTORY::buildDriverForMesh(driverTypes driverType, case PORFLOW_DRIVER : { switch(access) { - case MED_LECT : { + case RDONLY : { ret=new PORFLOW_MESH_RDONLY_DRIVER(fileName,mesh); return ret; } - case MED_CREA : - case MED_REMP : - case MED_ECRI : { + case RDWR : + case WRONLY : { throw MED_EXCEPTION ("access mode other than MED_LECT has been specified with the PORFLOW_DRIVER type which is not allowed because PORFLOW_DRIVER is only a read access driver"); } default: @@ -157,16 +156,15 @@ GENDRIVER *DRIVERFACTORY::buildDriverForMesh(driverTypes driverType, case ENSIGHT_DRIVER : { switch(access) { - case MED_LECT : { + case RDONLY : { ret=new ENSIGHT_MESH_RDONLY_DRIVER(fileName,mesh); return ret; } - case MED_ECRI : { + case WRONLY : { ret=new ENSIGHT_MESH_WRONLY_DRIVER(fileName,mesh); return ret; } - case MED_CREA : - case MED_REMP : { + case RDWR : { throw MED_EXCEPTION ("not yet implemented"); return ret; } @@ -179,12 +177,11 @@ GENDRIVER *DRIVERFACTORY::buildDriverForMesh(driverTypes driverType, case VTK_DRIVER : { switch(access) { - case MED_LECT : { + case RDONLY : { throw MED_EXCEPTION ("access mode other than MED_ECRI or MED_REMPT has been specified with the VTK_DRIVER type which is not allowed because VTK_DRIVER is only a write access driver"); } - case MED_CREA : - case MED_REMP : - case MED_ECRI : { + case RDWR : + case WRONLY : { ret=new VTK_MESH_DRIVER(fileName,mesh); return ret; } @@ -214,16 +211,15 @@ GENDRIVER *DRIVERFACTORY::buildDriverForMed(driverTypes driverType, case MED_DRIVER : { switch(access) { - case MED_LECT : { + case RDONLY : { ret=new MED_MED_RDONLY_DRIVER(fileName,med); break ; } - case MED_CREA : - case MED_ECRI : { + case WRONLY : { ret=new MED_MED_WRONLY_DRIVER(fileName,med); break ; } - case MED_REMP : { + case RDWR : { ret=new MED_MED_RDWR_DRIVER(fileName,med); break ; } @@ -236,15 +232,14 @@ GENDRIVER *DRIVERFACTORY::buildDriverForMed(driverTypes driverType, case VTK_DRIVER : { switch(access) { - case MED_LECT : { + case RDONLY : { throw MED_EXCEPTION ("access mode other than MED_ECRI or MED_REMPT has been specified with the VTK_DRIVER type which is not allowed because VTK_DRIVER is only a write access driver"); } - case MED_CREA : - case MED_ECRI : { + case WRONLY : { ret=new VTK_MED_DRIVER(fileName,med); break ; } - case MED_REMP : { + case RDWR : { ret=new VTK_MED_DRIVER(fileName,med); break ; } @@ -257,16 +252,15 @@ GENDRIVER *DRIVERFACTORY::buildDriverForMed(driverTypes driverType, case ENSIGHT_DRIVER : { switch(access) { - case MED_LECT : { + case RDONLY : { ret=new ENSIGHT_MED_RDONLY_DRIVER(fileName,med); break ; } - case MED_CREA : - case MED_ECRI : { + case WRONLY : { ret=new ENSIGHT_MED_WRONLY_DRIVER(fileName,med); break ; } - case MED_REMP : { + case RDWR : { throw MED_EXCEPTION ("not yet implemented"); break ; } @@ -311,28 +305,27 @@ GENDRIVER * DRIVERFACTORY::buildMedDriverFromFile(const string & fileName, version = DRIVERFACTORY::globalMedFileVersionForWriting; } - MESSAGE("buildMedDriverFromFile version of the file " << version); + MESSAGE_MED("buildMedDriverFromFile version of the file " << version); GENDRIVER * driver; switch(access) { - case MED_LECT : { + case RDONLY : { if (version == V21) driver = new MED_MED_RDONLY_DRIVER21(fileName,ptrMed); else if (version == V22) driver = new MED_MED_RDONLY_DRIVER22(fileName,ptrMed); return driver; } - case MED_CREA : - case MED_ECRI : { + case WRONLY : { if (version == V21) driver = new MED_MED_WRONLY_DRIVER21(fileName,ptrMed); else if (version == V22) driver = new MED_MED_WRONLY_DRIVER22(fileName,ptrMed); return driver; } - case MED_REMP : { + case RDWR : { if (version == V21) driver = new MED_MED_RDWR_DRIVER21(fileName,ptrMed); else if (version == V22) @@ -359,28 +352,27 @@ GENDRIVER * DRIVERFACTORY::buildMeshDriverFromFile(const string & fileName, version = DRIVERFACTORY::globalMedFileVersionForWriting; } - MESSAGE("buildMeshDriverFromFile version of the file " << version); + MESSAGE_MED("buildMeshDriverFromFile version of the file " << version); GENDRIVER * driver; switch(access) { - case MED_LECT : { + case RDONLY : { if (version == V21) driver = new MED_MESH_RDONLY_DRIVER21(fileName,ptrMesh); else if (version == V22) driver = new MED_MESH_RDONLY_DRIVER22(fileName,ptrMesh); return driver; } - case MED_CREA : - case MED_ECRI : { + case WRONLY : { if (version == V21) driver = new MED_MESH_WRONLY_DRIVER21(fileName,ptrMesh); else if (version == V22) driver = new MED_MESH_WRONLY_DRIVER22(fileName,ptrMesh,access); return driver; } - case MED_REMP : { + case RDWR : { if (version == V21) driver = new MED_MESH_RDWR_DRIVER21(fileName,ptrMesh); else if (version == V22) @@ -399,11 +391,11 @@ GENDRIVER * DRIVERFACTORY::buildConcreteMedDriverForMesh(const std::string & fil { GENDRIVER * driver; - MESSAGE("buildConcreteMedDriverForMesh version of the file " << version); + MESSAGE_MED("buildConcreteMedDriverForMesh version of the file " << version); switch(access) { - case MED_LECT : { + case RDONLY : { if (version == V21) driver = new MED_MESH_RDONLY_DRIVER21(fileName,ptrMesh); else if (version == V22) @@ -411,8 +403,7 @@ GENDRIVER * DRIVERFACTORY::buildConcreteMedDriverForMesh(const std::string & fil driver->setMeshName(driverName); return driver; } - case MED_CREA : - case MED_ECRI : { + case WRONLY : { if (version == V21) driver = new MED_MESH_WRONLY_DRIVER21(fileName,ptrMesh); else if (version == V22) @@ -420,7 +411,7 @@ GENDRIVER * DRIVERFACTORY::buildConcreteMedDriverForMesh(const std::string & fil driver->setMeshName(driverName); return driver; } - case MED_REMP : { + case RDWR : { if (version == V21) driver = new MED_MESH_RDWR_DRIVER21(fileName,ptrMesh); else if (version == V22) diff --git a/src/MEDMEM/MEDMEM_DriverFactory.hxx b/src/MEDMEM/MEDMEM_DriverFactory.hxx index 945b88e61..9a08d6e90 100644 --- a/src/MEDMEM/MEDMEM_DriverFactory.hxx +++ b/src/MEDMEM/MEDMEM_DriverFactory.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef DRIVERFACTORY_HXX #define DRIVERFACTORY_HXX @@ -90,12 +92,12 @@ namespace MEDMEM { } } -#include "MEDMEM_EnsightFieldDriver.hxx" #include "MEDMEM_VtkFieldDriver.hxx" #include "MEDMEM_MedFieldDriver.hxx" #include "MEDMEM_MedFieldDriver21.hxx" #include "MEDMEM_MedFieldDriver22.hxx" #include "MEDMEM_AsciiFieldDriver.hxx" +#include "MEDMEM_EnsightFieldDriver.hxx" namespace MEDMEM { template @@ -110,15 +112,15 @@ namespace MEDMEM { case MED_DRIVER : { switch(access) { - case MED_EN::MED_LECT : { + case MED_EN::RDONLY : { ret = new MED_FIELD_RDONLY_DRIVER(fileName,field); break; } - case MED_EN::MED_ECRI : { + case MED_EN::WRONLY : { ret= new MED_FIELD_WRONLY_DRIVER(fileName,field); break; } - case MED_EN::MED_REMP : { + case MED_EN::RDWR : { ret = new MED_FIELD_RDWR_DRIVER(fileName,field); break; } @@ -131,15 +133,15 @@ namespace MEDMEM { case ENSIGHT_DRIVER : { switch(access) { - case MED_EN::MED_LECT : { - ret = new ENSIGHT_FIELD_RDONLY_DRIVER(fileName,field); + case MED_EN::RDONLY : { + ret = new ENSIGHT_FIELD_RDONLY_DRIVER(fileName,field); break; } - case MED_EN::MED_ECRI : { - ret=new ENSIGHT_FIELD_WRONLY_DRIVER(fileName,field); + case MED_EN::WRONLY : { + ret=new ENSIGHT_FIELD_WRONLY_DRIVER(fileName,field); break; } - case MED_EN::MED_REMP : { + case MED_EN::RDWR : { throw MED_EXCEPTION ("not yet implemented"); break ; } @@ -152,15 +154,15 @@ namespace MEDMEM { case VTK_DRIVER : { switch(access) { - case MED_EN::MED_LECT : { + case MED_EN::RDONLY : { throw MED_EXCEPTION ("access mode other than MED_ECRI and MED_REMP has been specified with the VTK_DRIVER type which is not allowed because VTK_DRIVER is only a write access driver"); break; } - case MED_EN::MED_ECRI : { + case MED_EN::WRONLY : { ret=new VTK_FIELD_DRIVER(fileName,field); break; } - case MED_EN::MED_REMP : { + case MED_EN::RDWR : { ret=new VTK_FIELD_DRIVER(fileName,field); break ; } @@ -183,7 +185,7 @@ namespace MEDMEM { case ASCII_DRIVER : { switch(access) { - case MED_EN::MED_ECRI : { + case MED_EN::WRONLY : { ret=new ASCII_FIELD_DRIVER(fileName,field); break; } @@ -219,27 +221,27 @@ namespace MEDMEM { version = DRIVERFACTORY::globalMedFileVersionForWriting; } - MESSAGE("buildFieldDriverFromFile version of the file " << version); + MESSAGE_MED("buildFieldDriverFromFile version of the file " << version); GENDRIVER * driver; switch(access) { - case MED_EN::MED_LECT : { + case MED_EN::RDONLY : { if (version == MED_EN::V21) driver = new MED_FIELD_RDONLY_DRIVER21(fileName,ptrField); else if (version == MED_EN::V22) driver = new MED_FIELD_RDONLY_DRIVER22(fileName,ptrField); return driver; } - case MED_EN::MED_ECRI : { + case MED_EN::WRONLY : { if (version == MED_EN::V21) driver = new MED_FIELD_WRONLY_DRIVER21(fileName,ptrField); else if (version == MED_EN::V22) driver = new MED_FIELD_WRONLY_DRIVER22(fileName,ptrField); return driver; } - case MED_EN::MED_REMP : { + case MED_EN::RDWR : { if (version == MED_EN::V21) driver = new MED_FIELD_RDWR_DRIVER21(fileName,ptrField); else if (version == MED_EN::V22) @@ -258,27 +260,27 @@ namespace MEDMEM { MED_EN::medFileVersion version) { - MESSAGE("buildConcreteMedDriverForField version of the file " << version); + MESSAGE_MED("buildConcreteMedDriverForField version of the file " << version); GENDRIVER * driver; switch(access) { - case MED_EN::MED_LECT : { + case MED_EN::RDONLY : { if (version == MED_EN::V21) driver = new MED_FIELD_RDONLY_DRIVER21(fileName,ptrField); else if (version == MED_EN::V22) driver = new MED_FIELD_RDONLY_DRIVER22(fileName,ptrField); return driver; } - case MED_EN::MED_ECRI : { + case MED_EN::WRONLY : { if (version == MED_EN::V21) driver = new MED_FIELD_WRONLY_DRIVER21(fileName,ptrField); else if (version == MED_EN::V22) driver = new MED_FIELD_WRONLY_DRIVER22(fileName,ptrField); return driver; } - case MED_EN::MED_REMP : { + case MED_EN::RDWR : { if (version == MED_EN::V21) driver = new MED_FIELD_RDWR_DRIVER21(fileName,ptrField); else if (version == MED_EN::V22) diff --git a/src/MEDMEM/MEDMEM_DriverTools.cxx b/src/MEDMEM/MEDMEM_DriverTools.cxx index c5d512ea7..d5e9db4a0 100644 --- a/src/MEDMEM/MEDMEM_DriverTools.cxx +++ b/src/MEDMEM/MEDMEM_DriverTools.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_DriverTools.hxx" #include "MEDMEM_STRING.hxx" @@ -23,6 +25,8 @@ #include "MEDMEM_Mesh.hxx" #include "MEDMEM_Group.hxx" #include "MEDMEM_Field.hxx" +#include "MEDMEM_InterpolationHighLevelObjects.hxx" + #include #include @@ -33,37 +37,78 @@ using namespace MED_EN; namespace MEDMEM { +// avoid coping sortedNodeIDs +_maille::_maille(const _maille& ma) + : sommets(ma.sommets), geometricType(ma.geometricType), _ordre(ma._ordre), + reverse(ma.reverse), sortedNodeIDs(0) +{ +} + // Cet opérateur permet d'ordonner les mailles dans un set suivant l'ordre requis par MED bool _maille::operator < (const _maille& ma) const { // si le type géométrique differe, la comparaison est basée dessus - // sinon on se base sur une comparaison des numéros de sommets - if(geometricType==ma.geometricType) + // sinon on se base sur une comparaison des numéros de sommets + // we compare _mailles of only same geometricType due to maillageByType usage + size_t l=sommets.size(); + if ( dimension() > 3 ) { // poly + size_t l2 = ma.sommets.size(); + if ( l != l2 ) + return l < l2; + } + const int* v1 = getSortedNodes(); + const int* v2 = ma.getSortedNodes(); + for ( const int* vEnd = v1 + l; v1 < vEnd; ++v1, ++v2 ) + if(*v1 != *v2) + return *v1 < *v2; + return false; // cas d'égalité + +// if(geometricType==ma.geometricType) +// { +// // construction de deux vecteur temporaire contenant les numeros de sommets +// // pour faire le tri et les comparaisons +// size_t l=sommets.size(); +// if ( dimension() > 3 ) { // poly +// size_t l2 = ma.sommets.size(); +// if ( l != l2 ) +// return l < l2; +// } +// std::vector v1(l); +// std::vector v2(l); +// for (unsigned int i=0; i!=l; ++i) +// { +// v1[i]=nodeNum(i); +// v2[i]=ma.nodeNum(i); +// } +// std::sort(v1.begin(), v1.end()); +// std::sort(v2.begin(), v2.end()); +// for(std::vector::const_iterator i1=v1.begin(), i2=v2.begin(); i1!=v1.end(); ++i1, ++i2) +// if(*i1 != *i2) +// return *i1 < *i2; +// return false; // cas d'égalité +// } +// else +// return geometricType v1(l); - std::vector v2(l); - for (unsigned int i=0; i!=l; ++i) - { - v1[i]=sommets[i]->second.number; - v2[i]=ma.sommets[i]->second.number; - } - std::sort(v1.begin(), v1.end()); - std::sort(v2.begin(), v2.end()); - for(std::vector::const_iterator i1=v1.begin(), i2=v2.begin(); i1!=v1.end(); ++i1, ++i2) - if(*i1 != *i2) - return *i1 < *i2; - return false; // cas d'égalité + sortedNodeIDs = new int[ l ]; + + for (size_t i=0; i!=l; ++i) + sortedNodeIDs[i]=nodeID(i); + std::sort( sortedNodeIDs, sortedNodeIDs + l ); } - else - return geometricType= 0 && i < sommets.size() ); + ASSERT_MED ( i >= 0 && i < sommets.size() ); int i2 = ( i + 1 == sommets.size() ) ? 0 : i + 1; if ( reverse ) return make_pair( sommets[i2]->first, sommets[i]->first ); @@ -75,9 +120,9 @@ _link _maille::link(int i) const MED_EN::medEntityMesh _maille::getEntity(const int meshDimension) const throw (MEDEXCEPTION) { const char * LOC = "_maille::getEntity(const int meshDimension)" ; -// BEGIN_OF(LOC); +// BEGIN_OF_MED(LOC); - int mailleDimension = this->dimension(); + int mailleDimension = this->dimensionWithPoly(); medEntityMesh entity; if (mailleDimension == meshDimension) entity = MED_CELL; @@ -98,17 +143,36 @@ MED_EN::medEntityMesh _maille::getEntity(const int meshDimension) const throw (M } return entity; -//END_OF(LOC); +//END_OF_MED(LOC); }; +void _maillageByDimIterator::init(const int dim, const bool convertPoly ) +{ + myIt = myImed->maillageByType.begin(); + myEnd = myImed->maillageByType.end(); + myDim = dim; + myConvertPoly = convertPoly; + nbRemovedByType = & myImed->nbRemovedByType; +} + std::ostream& operator << (std::ostream& os, const _maille& ma) { - os << "maille " << ma.ordre << " (" << ma.geometricType << ") : < "; - std::vector< std::map::iterator >::const_iterator i=ma.sommets.begin(); - os << (*i++)->second.number ; - for( ; i!=ma.sommets.end(); ++i) - os << ", " << (*i)->second.number; - os << " >"; + os << "maille " << ma.ordre() << " (" << ma.geometricType << ") : < "; + os << ma.nodeNum(0); + for( int i=1; i!=ma.sommets.size(); ++i) + os << ", " << ma.nodeNum( i ); + os << " > sortedNodeIDs: "; + if ( ma.sortedNodeIDs ) { + os << "< "; + for( int i=0; i!=ma.sommets.size(); ++i) + os << ( i ? ", " : "" ) << ma.sortedNodeIDs[ i ]; + os << " >"; + } + else { + os << "NULL"; + } + if ( ma.isMerged() ) + os << " MERGED "; return os; } @@ -121,7 +185,7 @@ std::ostream& operator << (std::ostream& os, const _groupe& gr) os << std::endl << " -> liste des "<< gr.mailles.size() << " mailles : " << std::endl; - _groupe::mailleIter i1=gr.mailles.begin(); + _groupe::TMailleIter i1=gr.mailles.begin(); int l; for(l = 0; l < DUMP_LINES_LIMIT && i1!=gr.mailles.end(); i1++, l++) os << setw(3) << l+1 << " " << *(*i1) << std::endl; @@ -130,7 +194,7 @@ std::ostream& operator << (std::ostream& os, const _groupe& gr) os << " ... skip " << gr.mailles.size() - l << " mailles" << endl; os << " relocMap, size=" << gr.relocMap.size() << endl; - map::const_iterator it = gr.relocMap.begin(); + map::const_iterator it = gr.relocMap.begin(); for ( l = 0; l < DUMP_LINES_LIMIT && it != gr.relocMap.end(); ++it, ++l ) os << " (" << it->first << "," << it->second << ")"; if ( gr.relocMap.size() > 0 ) @@ -174,31 +238,35 @@ std::ostream& operator << (std::ostream& os, const _fieldBase * f) std::ostream& operator << (std::ostream& os, const _intermediateMED& mi) { - os << "Set des " << mi.maillage.size() << " mailles : " << std::endl; - std::set<_maille>::const_iterator i=mi.maillage.begin(); - int l; - for( l = 0; l < DUMP_LINES_LIMIT && i!=mi.maillage.end(); ++i, ++l) - os << setw(3) << l+1 << " " <<*i << std::endl; - if ( l == DUMP_LINES_LIMIT ) - os << " ... skip " << mi.maillage.size() - l << " mailles" << endl; - - os << std::endl << "Vector des " << mi.groupes.size() << " groupes : " << std::endl; - for (unsigned int k=0; k!=mi.groupes.size(); k++) - os << std::setw(3) << k << " " << mi.groupes[k] << std::endl; - - os << std::endl << "map des " << mi.points.size() << " noeuds : " << std::endl; - std::map::const_iterator j=mi.points.begin(); - for( l = 0; l < DUMP_LINES_LIMIT && j!=mi.points.end(); ++j, ++l) - os << j->second << std::endl; + int l; + _maillageByDimIterator maIt( mi ); + while ( const set<_maille >* maillage = maIt.nextType() ) + { + os << "Set des " << maillage->size() + << " mailles of type " << maIt.type() << ": "<< std::endl; + std::set<_maille>::const_iterator i=maillage->begin(); + for( l = 0; l < DUMP_LINES_LIMIT && i!=maillage->end(); ++i, ++l) + os << setw(3) << l+1 << " " <<*i << std::endl; if ( l == DUMP_LINES_LIMIT ) - os << " ... skip " << mi.points.size() - l << " noeuds" << endl; - - os << endl << mi.fields.size() << " fields:" << endl; - std::list<_fieldBase* >::const_iterator fIt = mi.fields.begin(); - for ( l = 0; fIt != mi.fields.end(); ++fIt, ++l ) - os << " - " << l+1 << " " << *fIt << endl; + os << " ... skip " << maillage->size() - l << " mailles" << endl; + } + os << std::endl << "Vector des " << mi.groupes.size() << " groupes : " << std::endl; + for (unsigned int k=0; k!=mi.groupes.size(); k++) + os << std::setw(3) << k << " " << mi.groupes[k] << std::endl; + + os << std::endl << "map des " << mi.points.size() << " noeuds : " << std::endl; + std::map::const_iterator j=mi.points.begin(); + for( l = 0; l < DUMP_LINES_LIMIT && j!=mi.points.end(); ++j, ++l) + os << j->second << std::endl; + if ( l == DUMP_LINES_LIMIT ) + os << " ... skip " << mi.points.size() - l << " noeuds" << endl; + + os << endl << mi.fields.size() << " fields:" << endl; + std::list<_fieldBase* >::const_iterator fIt = mi.fields.begin(); + for ( l = 0; fIt != mi.fields.end(); ++fIt, ++l ) + os << " - " << l+1 << " " << *fIt << endl; - return os; + return os; } @@ -211,7 +279,7 @@ std::ostream& operator << (std::ostream& os, const _intermediateMED& mi) void _intermediateMED::treatGroupes() { const char * LOC = "_intermediateMED::treatGroupes() : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if ( myGroupsTreated ) return; @@ -226,7 +294,7 @@ void _intermediateMED::treatGroupes() for (unsigned int i=0; i!=this->groupes.size(); ++i) { _groupe& grp = groupes[i]; - //INFOS( i << " " << grp.nom ); + //INFOS_MED( i << " " << grp.nom ); j = grp.groupes.begin(); while( j!=grp.groupes.end() ) { int grpInd = *j-1; @@ -236,7 +304,7 @@ void _intermediateMED::treatGroupes() } _groupe & sub_grp = groupes[ grpInd ]; if ( !sub_grp.groupes.empty() ) { - MESSAGE("High hierarchical depth of subgroups in group " << i ); + MESSAGE_MED("High hierarchical depth of subgroups in group " << i ); *j = sub_grp.groupes[0]; // replace j with its 1st subgroup // push back the rest subs for ( int k = 1; k < (int)sub_grp.groupes.size(); ++k ) @@ -282,7 +350,7 @@ void _intermediateMED::treatGroupes() _groupe& grp = groupes[i]; grp.mailles.clear(); grp.groupes.clear(); - MESSAGE( "Erase " << i << "-th group " << grp.nom ); + MESSAGE_MED( "Erase " << i << "-th group " << grp.nom ); } } @@ -300,156 +368,162 @@ void _intermediateMED::treatGroupes() // check if sub-groups have different dimension j = grp.groupes.begin(); int dim = groupes[*j-1].mailles[0]->dimension(); - for( j++; /*!hasMixedCells &&*/ j!=grp.groupes.end(); ++j) { + for( j++; j!=grp.groupes.end(); ++j) { int dim2 = groupes[*j-1].mailles[0]->dimension(); if ( dim != dim2 ) { - if ( dim == 0 || dim2 == 0 ) { - // cant create a group of nodes plus anything else + if ( dim == 0 || dim2 == 0 || dim + dim2 == 9 ) { + // cant create a group of nodes plus anything else, + // neither a group of polygones + polyhedrons grp.mailles.clear(); grp.groupes.clear(); - MESSAGE( "Erase mixed dim group with nodes:" << i << "-th group " << grp.nom ); + MESSAGE_MED( "Erase mixed dim group with nodes:" << i << "-th group " << grp.nom ); + break; } - else { + int d1 = dim < 4 ? dim : dim - 2; // care of poly + int d2 = dim2 < 4 ? dim2 : dim2 - 2; + if ( d1 != d2 ) { hasMixedCells = true; - MESSAGE( "Mixed dim group: " << i << "-th " << grp.nom << + MESSAGE_MED( "Mixed dim group: " << i << "-th " << grp.nom << " dim1 = " << dim << " dim2 = " << dim2 ); } - break; } } } // if ( hasMixedCells ) -// INFOS( "There will be groups of mixed dimention" ); - END_OF(LOC); +// INFOS_MED( "There will be groups of mixed dimention" ); + END_OF_MED(LOC); } void _intermediateMED::numerotationMaillage() { - const char * LOC = "_intermediateMED::numerotationMaillage() : "; - BEGIN_OF(LOC); + const char* LOC = "_intermediateMED::numerotationMaillage() : "; + BEGIN_OF_MED(LOC); + if ( myMaillesNumerated ) + return; + myMaillesNumerated = true; treatGroupes(); + set<_maille>::const_iterator i, iEnd; + // numerotation mailles of type MED_POINT1 by node number - std::set<_maille>::iterator i=maillage.begin(); - if ( i->geometricType == MED_POINT1 ) { + bool hasPointMailles = false; + if ( const set<_maille> * points = _maillageByDimIterator( *this, 0 ).nextType() ) { + hasPointMailles = true; numerotationPoints(); - while ( i!=maillage.end() && i->geometricType == MED_POINT1 ) { - i->ordre = i->sommets[0]->second.number; - i++; - } + for ( i = points->begin(), iEnd = points->end(); i != iEnd; ++i ) + i->setOrdre( i->sommets[0]->second.number ); // is merged if point is merged } - // check if numeration is needed - if ( i->ordre > 0 && maillage.rbegin()->ordre > 0 ) + // loop on entities + for ( int dim = 1; dim <= 3; ++dim ) { - // already numerated, check numeration - bool ok = true; - const int maxNbTypes = 20; - pair< unsigned, unsigned > minMaxOrder[ maxNbTypes ]; - int nbElems[ maxNbTypes ]; - std::set<_maille>::iterator j=i; - - do { // loop on elements of one entity - int iType = 0; - minMaxOrder[ iType ] = make_pair( maillage.size(), 0 ); - int i_maille = 0, dimension = j->dimension(), type = j->geometricType; - - std::set<_maille>::iterator k=j; - for ( ; j!=maillage.end() && (hasMixedCells || dimension==j->dimension()); ++j) - { - if (type != j->geometricType) // si changement de type geometrique - { - nbElems[ iType ] = i_maille; - i_maille=0; - type = j->geometricType; - iType++; - minMaxOrder[ iType ] = make_pair( maillage.size(), 0 ); - } - ++i_maille; - if ( j->ordre < minMaxOrder[ iType ].first ) - minMaxOrder[ iType ].first = j->ordre; - if ( j->ordre > minMaxOrder[ iType ].second ) - minMaxOrder[ iType ].second = j->ordre; + int iterDim = hasMixedCells ? -1 : dim; + const bool skipFirstType = ( hasPointMailles && hasMixedCells ); + + // check if any numeration is present + bool hasNumeration = true; + _maillageByDimIterator entityMailles( *this, iterDim, true ); + if ( skipFirstType ) entityMailles.nextType(); + while ( const set<_maille> * typeMailles = entityMailles.nextType() ) { + if ( typeMailles->begin()->ordre() == 0 || typeMailles->rbegin()->ordre() == 0 ) { + hasNumeration = false; + break; } - nbElems[ iType ] = i_maille; + } + // check if re-numeration is needed + bool ok = false, renumEntity = false; + if ( hasNumeration ) + { + ok = true; + _maillageByDimIterator entityMailles( *this, iterDim, true ); + if ( skipFirstType ) entityMailles.nextType(); - bool renumEntity = false; - for ( int t = 0; t <= iType; ++t ) { - int orderRange = minMaxOrder[ t ].second - minMaxOrder[ t ].first; - if ( nbElems[ t ] != orderRange + 1 ) + int prevNbElems = 0; + while ( const set<_maille> * typeMailles = entityMailles.nextType() ) + { + unsigned minOrdre = INT_MAX, maxOrdre = 0; + for ( i = typeMailles->begin(), iEnd = typeMailles->end(); i!=iEnd; ++i) { + if ( i->ordre() < minOrdre ) minOrdre = i->ordre(); + if ( i->ordre() > maxOrdre ) maxOrdre = i->ordre(); + } + unsigned typeSize = entityMailles.sizeWithoutMerged(); + if ( typeSize != maxOrdre - minOrdre + 1 ) ok = false; - if ( t > 0 ) { - if ( minMaxOrder[ t ].first == 1 ) + if ( prevNbElems != 0 ) { + if ( minOrdre == 1 ) renumEntity = true; - else if ( minMaxOrder[ t-1 ].second+1 != minMaxOrder[ t ].first ) + else if ( prevNbElems+1 != minOrdre ) ok = false; } + prevNbElems += typeSize; } - if ( ok && renumEntity ) { // each type of entity is numerated separately - int iType = 0, i_shift = 0; - type = k->geometricType; - for ( ; k != j; ++k ) { - if (type != k->geometricType) { // si changement de type geometrique - i_shift = minMaxOrder[ iType++ ].second; - type = k->geometricType; - } - k->ordre += i_shift; + + if ( ok && renumEntity ) // each geom type was numerated separately + { + entityMailles.init( iterDim, true ); + if ( skipFirstType ) entityMailles.nextType(); + prevNbElems = entityMailles.nextType()->size(); // no need to renumber the first type + while ( const set<_maille> * typeMailles = entityMailles.nextType() ) { + for ( i = typeMailles->begin(), iEnd = typeMailles->end(); i!=iEnd; ++i) + i->setOrdre( i->ordre() + prevNbElems ); + prevNbElems += typeMailles->size(); } } - - } while ( ok && j != maillage.end() ); - - if ( ok ) return; // renumeration not needed - } - - // numerotation des mailles par entité - int i_maille=0; - int dimension=i->dimension(); - for( ; i!=maillage.end(); ++i) - { - if ( !hasMixedCells && dimension != i->dimension() ) // on change d'entite + } + if ( !ok ) { - MESSAGE( "NB dim " << dimension << " entities: " << i_maille); - dimension=i->dimension(); - i_maille=0; + int i_maille=0; + entityMailles.init( iterDim, true ); + if ( skipFirstType ) entityMailles.nextType(); + while ( const set<_maille> * typeMailles = entityMailles.nextType() ) + for ( i = typeMailles->begin(), iEnd = typeMailles->end(); i!=iEnd; ++i) + i->setOrdre( ++i_maille ); } - i->ordre=++i_maille; } - END_OF(LOC); + END_OF_MED(LOC); } -void _intermediateMED::numerotationPoints() +bool _intermediateMED::numerotationPoints() { -// if ( myPointsNumerated ) -// return; -// myPointsNumerated = true; - // Fonction de renumerotation des noeuds (necessaire quand il y a des trous dans la numerotation. + if ( !myNodesNumerated ) // is negative if numerated by merge + { int i_noeud=0; - for( std::map::const_iterator i=points.begin(); i!=points.end(); ++i) - i->second.number = ++i_noeud ; + for( map::iterator i=points.begin(); i!=points.end(); ++i) + i->second.number = ++i_noeud ; + myNodesNumerated = true; + return true; + } + return false; } +int _intermediateMED::nbMerged(int type) const //!< nb nodes removed by merge +{ + TNbByType::const_iterator typeNb = nbRemovedByType.find( type ); + return ( typeNb == nbRemovedByType.end() ? 0 : typeNb->second ); +} + /*! * \if developper * create a MED COORDINATE from the intermediate structure. * \endif */ -COORDINATE * -_intermediateMED::getCoordinate(const string & coordinateSystem) +COORDINATE * _intermediateMED::getCoordinate(const string & coordinateSystem) { const medModeSwitch mode=MED_FULL_INTERLACE; int spaceDimension=points.begin()->second.coord.size(); - int numberOfNodes=points.size(); - + int numberOfNodes=points.size() - nbMerged( MED_POINT1 ); // creation du tableau des coordonnees en mode MED_FULL_INTERLACE double * coord = new double[spaceDimension*numberOfNodes]; - int k=0; - for( std::map::const_iterator i=points.begin(); i!=points.end(); ++i, ++k) - std::copy(i->second.coord.begin(), i->second.coord.end(), coord+k*spaceDimension); + double * xyz = coord; + for( std::map::const_iterator i=points.begin(); i!=points.end(); ++i ) + if ( i->second.number > 0 ) { + std::copy(i->second.coord.begin(), i->second.coord.end(), xyz ); + xyz += spaceDimension; + } // creation de l'objet COORDINATE COORDINATE * coordinate = new COORDINATE(spaceDimension, numberOfNodes, mode); @@ -460,199 +534,269 @@ _intermediateMED::getCoordinate(const string & coordinateSystem) } - /*! - * \if developper - * create a MED CONNECTIVITY from the intermediate structure. - * for memory optimisation, clear the intermediate structure (the "maillage" set ) - * \endif - */ +/*! + * \if developper + * create a MED CONNECTIVITY from the intermediate structure. + * \endif + */ CONNECTIVITY * _intermediateMED::getConnectivity() { - const char * LOC = "_intermediateMED::getConnectivity() : "; - BEGIN_OF(LOC); - int numberOfNodes=points.size(); // number of nodes in the mesh - int numberOfTypes=0; - medEntityMesh entity; - medGeometryElement * types=NULL; // pointeurs pour allouer les structures MED - int * count=NULL; - int * connectivity=NULL; - CONNECTIVITY *Connectivity, *Constituent; - //int dimension_maillage_moin_2=maillage.rbegin()->dimension() - 2; + const char * LOC = "_intermediateMED::getConnectivity() : "; + BEGIN_OF_MED(LOC); - medGeometryElement type=0; // variables de travail - int nbtype=0; - int dimension=0; - bool first = true; + int numberOfNodes=points.size() - nbMerged( MED_POINT1 ); // number of nodes in the mesh + medEntityMesh entity; + CONNECTIVITY *Connectivity = NULL, *Constituent = NULL; - std::vector vtype; // tableau de travail : stockage des types geometriques pour UNE entite - std::vector vcount; // tableau de travail : nombre d'elements pour chaque type geometrique de vtype + set<_maille>::const_iterator i, iEnd; // iterateurs sur les mailles - std::set<_maille>::const_iterator i, j; // iterateurs sur les mailles + // find out mesh dimension + medGeometryElement meshDim; + _maillageByDimIterator allMailles( *this, -1, true ); + while ( allMailles.nextType() ) + meshDim = allMailles.dim(); - // min and max element nb for each geom type - const int maxNbTypes = 20; - vector< pair< unsigned, unsigned > > minMaxOrder( maxNbTypes ); + // renumerote les points de 1 a n (pour le cas ou certains points ne sont pas presents dans le maillage d'origine) + numerotationPoints(); + // STANDARD types connectivity + + // loop on entities + for ( int dim = 0; dim <= 3; ++dim ) + { // skip nodes and elements of or less dimension // Unfortunately, it is impossible because of MESH::createFamilies() that requires // presence of connectivity even for nodes! - for ( i = maillage.begin(); i != maillage.end(); ++i ) - //if ( i->geometricType != MED_POINT1 && i->dimension() > dimension_maillage_moin_2 ) - break; - j = i; + //int dimension_maillage_moin_2=maillage.rbegin()->dimension() - 2; + + // tableau de travail : nombre d'elements pour chaque type geometrique + vector count; + count.reserve( maillageByType.size() ); + count.push_back( 1 ); + + // tableau de travail : stockage des types geometriques pour UNE entite + vector types; + types.reserve( maillageByType.size() ); + + // iterator returning mailles of each type of an entity, + // but if hasMixedCells, we iterate on all types at every dim, since + // in this case we store POINT1 elems as MED_NODE and + // elems of all the rest types as MED_CELL + int iterDim = hasMixedCells ? -1 : dim; + _maillageByDimIterator entityMailles( *this, iterDim ); + + // count nb of types and nb mailles of each type + int dimension=0; + if ( dim == 0 ) { + if ( entityMailles.nextType() && entityMailles.dim() == 0 ) + { + count.push_back( count.back() + numberOfNodes ); + types.push_back( MED_POINT1 ); + } + } + else { + while ( entityMailles.nextType() ) + { + if ( entityMailles.dim() > 3 ) break; // ignore poly + + dimension = entityMailles.dim(); + if ( dimension == 0 ) continue; // if hasMixedCells, iterator returns all types + + count.push_back( count.back() + entityMailles.sizeWithoutMerged() ); + types.push_back( entityMailles.type() ); + } + } + int numberOfTypes = types.size(); // nombre de types de l'entite + if ( numberOfTypes == 0 ) + continue; + + if ( dimension == meshDim ) entity=MED_CELL; + else if (dimension==2 ) entity=MED_FACE; + else if (dimension==1 ) entity=MED_EDGE; + else if (dimension==0 ) entity=MED_NODE; - // renumerote les points de 1 a n (pour le cas ou certains points ne sont pas presents dans le maillage d'origine) - numerotationPoints(); + Connectivity = new CONNECTIVITY ( numberOfTypes, entity ); + Connectivity->setEntityDimension( dimension ); + Connectivity->setNumberOfNodes ( numberOfNodes ); + Connectivity->setGeometricTypes ( &types[0], entity); + Connectivity->setCount ( &count[0], entity ); - do + int prevNbElems = 1; // in previous type + for (int k=0; k!=numberOfTypes; ++k ) { - // boucle sur les entites de la structure maillage : - // - on parcourt une premiere fois avec i les mailles d'une entite pour récupérer - // des infos sur les types geometriques, leur nombre et le nombre d'elements. - // - on alloue la connectivite - // - on parcourt une deuxieme fois avec j pour lire les noeuds. - - type=i->geometricType; // init boucle for - dimension=i->dimension(); - nbtype=0; - vtype.push_back(type); - // Boucle sur i de parcours des mailles d'une entite - // Une entite se termine lorsqu'on atteint la fin de maillage ou lorsque la dimension des mailles change - - int iType=0; - minMaxOrder[ iType ] = make_pair( maillage.size(), 0 ); - - // if hasMixedCells, store POINT1 elems as MED_NODE and - // elems of all the rest types as MED_CELL, i.e. do not break the loop - // when dimension changes - bool ignoreDimChange = hasMixedCells && dimension > 0; - for( ; i!=maillage.end() && ( ignoreDimChange || dimension==i->dimension()) ; ++i) - { - if (type != i->geometricType) // si changement de type geometrique - { - vcount.push_back(nbtype); // stocke le nombre d'elements de type nbtype - nbtype=0; - type=i->geometricType; - vtype.push_back(type); // stocke le nouveau type geometrique rencontre - dimension=i->dimension(); - iType++; - minMaxOrder[ iType ] = make_pair( maillage.size(), 0 ); - } - if ( i->ordre < minMaxOrder[ iType ].first ) - minMaxOrder[ iType ].first = i->ordre; - if ( i->ordre > minMaxOrder[ iType ].second ) - minMaxOrder[ iType ].second = i->ordre; - ++nbtype; - } - vcount.push_back(dimension ? nbtype : numberOfNodes); // n'a pas été stocké dans la boucle - - // Pour l'entite qu'on vient de parcourir, allocation des tableau et creation de la connectivite -// cout << "Dimension = " << dimension << endl; -// cout << "Nombre de type geometriques : " << vtype.size() << endl; -// for (unsigned k=0; k!=vtype.size(); ++k ) -// cout << " -> " << vtype[k] << " : " << vcount[k] << endl; - - numberOfTypes=vtype.size(); // nombre de types de l'entite - - if ( i==maillage.end() ) // cas de l'entite de plus haut niveau - entity=MED_CELL; - else if (dimension==2 ) - entity=MED_FACE; - else if (dimension==1 ) - entity=MED_EDGE; - else if (dimension==0 ) - entity=MED_NODE; - - Connectivity = new CONNECTIVITY(numberOfTypes,entity); - Connectivity->setEntityDimension(dimension); - Connectivity->setNumberOfNodes(numberOfNodes); - - types = new medGeometryElement[numberOfTypes]; - std::copy(vtype.begin(),vtype.end(),types); - Connectivity->setGeometricTypes(types,entity); - delete [] types; - - count = new int[numberOfTypes+1]; - count[0]=1; - for (unsigned int k=0; k!=vcount.size(); ++k ) - count[k+1]=count[k]+vcount[k]; - Connectivity->setCount (count, entity); - SCRUTE( entity ); - SCRUTE(numberOfTypes); - SCRUTE(count[numberOfTypes]-1); - delete [] count; - - for (int k=0; k!=numberOfTypes; ++k ) - { - int orderShift = 1; - if ( minMaxOrder[ k ].first > 1 ) // min elem number != 1 - orderShift += minMaxOrder[ k-1 ].second; // max elem number in previous type - // pour chaque type géometrique k, copie des sommets dans connectivity et set dans Connectivity - int nbSommetsParMaille = j->sommets.size(); - int n, nbSommets = vcount[k] * nbSommetsParMaille; - connectivity = new int[ nbSommets ]; - for (int l=0; l!=vcount[k]; ++l) // loop on elements of geom type - { - if ( entity==MED_NODE ) - connectivity[l] = l+1; - else - { - int index0 = nbSommetsParMaille * ( j->ordre - orderShift ); - for ( n=0; n != nbSommetsParMaille; ++n) { - //connectivity[nbSommetsParMaille*l+n] = - connectivity[ index0 + n ] = - j->sommets[ j->reverse ? nbSommetsParMaille-n-1 : n ]->second.number; - } - // DO NOT ERASE, maillage will be used while fields construction - //maillage.erase(j); ; // dangereux, mais optimise la mémoire consommée! - j++; - } - } - - Connectivity->setNodal (connectivity, entity, vtype[k]); - delete [] connectivity; - } - - if ( entity==MED_NODE ) - j = i; - else if (i!=j) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Erreur de lecture des mailles .")); - - if ( ! first) - Connectivity->setConstituent (Constituent); - else - first = false; - Constituent = Connectivity; // stocke Connectivity pour utilisation dans setConstituent lors de la boucle suivante - - vtype.clear(); - vcount.clear(); + set<_maille> & typeMailles = maillageByType[ types[k] ]; + i = typeMailles.begin(), iEnd = typeMailles.end(); + // copie des sommets dans connectivity et set dans Connectivity + int nbSommetsParMaille = i->sommets.size(); + int nbMailles = count[k+1]-count[k]; + int nbSommets = nbMailles * nbSommetsParMaille; + int* connectivity = new int[ nbSommets ]; + if ( entity==MED_NODE ) { + for (int l=0; l!=nbSommets; ++l) { + connectivity[l] = l+1; + } + } + else { + for ( ; i != iEnd; ++i ) { // loop on elements of geom type + if ( i->isMerged() ) + continue; + int* mailleConn = connectivity + nbSommetsParMaille * ( i->ordre() - prevNbElems ); + if ( i->reverse ) + for ( int n=nbSommetsParMaille-1; n!=-1; --n) + *mailleConn++ = i->nodeNum( n ); + else + for ( int n=0; n != nbSommetsParMaille; ++n) + *mailleConn++ = i->nodeNum( n ); + } + // DO NOT ERASE, maillage will be used while fields construction + //maillage.erase(j); ; // dangereux, mais optimise la mémoire consommée! + } + Connectivity->setNodal (connectivity, entity, types[k]); + delete [] connectivity; + prevNbElems += nbMailles; + } + if ( Constituent ) + Connectivity->setConstituent (Constituent); + // stocke Connectivity pour utilisation dans setConstituent lors de la boucle suivante + Constituent = Connectivity; + + if ( entity == MED_CELL ) + break; // necessary if hasMixedCells + } + + // POLYGONAL connectivity + + set<_maille > & polygones = maillageByType[ MED_POLYGON ]; + if ( !polygones.empty() ) + { + // create connectivity if necessary + entity = ( meshDim == 2 ) ? MED_CELL : MED_FACE; + if ( !Connectivity || Connectivity->getEntity() > entity ) { + Connectivity = new CONNECTIVITY ( 0, entity ); + Connectivity->setEntityDimension( 2 ); + Connectivity->setNumberOfNodes ( numberOfNodes ); + if ( Constituent ) + Connectivity->setConstituent (Constituent); + Constituent = Connectivity; } - while ( i != maillage.end() ); + + // put polygones in order of increasing number + int numShift = 1 + Connectivity->getNumberOf( entity, MED_ALL_ELEMENTS ); + int nbPoly = polygones.size() - nbMerged( MED_POLYGON ); + vector orderedPoly( nbPoly ); + for ( i = polygones.begin(), iEnd = polygones.end(); i != iEnd; ++i ) + if ( !i->isMerged() ) + orderedPoly[ i->ordre() - numShift ] = &(*i); + + // make index + vector polyIndex; + polyIndex.reserve( nbPoly + 1 ); + vector::iterator poly = orderedPoly.begin(), polyEnd = orderedPoly.end(); + for ( polyIndex.push_back( 1 ); poly != polyEnd; ++poly) + polyIndex.push_back( polyIndex.back() + (*poly)->sommets.size() ); + + // make connectivity + int nbNodes = polyIndex.back() - 1; + vector polyConn( nbNodes ); + vector::iterator conn = polyConn.begin(); + for ( poly = orderedPoly.begin(); poly != polyEnd; ++poly) { + for ( int j = 0, nbNodes = (*poly)->sommets.size(); j < nbNodes; ++j ) + *conn++ = (*poly)->nodeNum( j ); + } + Connectivity->setPolygonsConnectivity(MED_NODAL, entity, + &polyConn[0], &polyIndex[0], + polyConn.size(), nbPoly ); + } + + // POLYHEDRAL connectivity - END_OF(LOC); - return Connectivity; + set<_maille > & pHedra = maillageByType[ MED_POLYHEDRA ]; + if ( !pHedra.empty() ) + { + if ( pHedra.size() != polyherdalNbFaceNodes.size() ) + throw MEDEXCEPTION (LOCALIZED(STRING(LOC) << "Missing info on polyhedron faces")); + + // create connectivity if necessary + entity = MED_CELL; + if ( !Connectivity || Connectivity->getEntity() != entity ) { + Connectivity = new CONNECTIVITY ( 0, entity ); + Connectivity->setEntityDimension( 3 ); + Connectivity->setNumberOfNodes ( numberOfNodes ); + if ( Constituent ) + Connectivity->setConstituent (Constituent); + } + typedef TPolyherdalNbFaceNodes::iterator TPolyFaNoIter; + TPolyFaNoIter polyFaNo, polyFaNoEnd = polyherdalNbFaceNodes.end(); + + // put poly's in order of increasing number + int numShift = 1 + Connectivity->getNumberOf( entity, MED_ALL_ELEMENTS ); + int nbPoly = pHedra.size() - nbMerged( MED_POLYHEDRA ); + vector orderedPolyFaNo( nbPoly ); + for ( polyFaNo = polyherdalNbFaceNodes.begin(); polyFaNo != polyFaNoEnd; ++polyFaNo ) + if ( !polyFaNo->first->isMerged() ) + orderedPolyFaNo[ polyFaNo->first->ordre() - numShift ] = polyFaNo; + + vector::iterator pfnIter, pfnEnd = orderedPolyFaNo.end(); + + // make index pointing to faces of a polyhedron + vector polyIndex; + polyIndex.reserve( nbPoly + 1 ); + polyIndex.push_back( 1 ); + for ( pfnIter = orderedPolyFaNo.begin(); pfnIter != pfnEnd; ++pfnIter) { + int nbFaces = (*pfnIter)->second.size(); + polyIndex.push_back( polyIndex.back() + nbFaces ); + } + + // make face index pointing to nodes of a face + int nbFaces = polyIndex.back() - 1; + vector faceIndex; + faceIndex.reserve( polyIndex.back() ); + faceIndex.push_back( 1 ); + for ( pfnIter = orderedPolyFaNo.begin(); pfnIter != pfnEnd; ++pfnIter) { + vector & faceNodes = (*pfnIter)->second; + vector::iterator nbNodes = faceNodes.begin(), nbEnd = faceNodes.end(); + for ( ; nbNodes != nbEnd; ++nbNodes ) + faceIndex.push_back( faceIndex.back() + *nbNodes ); + } + + // make connectivity + int nbNodes = faceIndex.back() - 1; + vector polyConn( nbNodes ); + vector::iterator conn = polyConn.begin(); + for ( pfnIter = orderedPolyFaNo.begin(); pfnIter != pfnEnd; ++pfnIter) { + const _maille * poly = (*pfnIter)->first; + for ( int j = 0, nbNodes = poly->sommets.size(); j < nbNodes; ++j ) + *conn++ = poly->nodeNum( j ); + } + Connectivity->setPolyhedronConnectivity(MED_NODAL, + &polyConn[0], &polyIndex[0], + polyConn.size(), nbPoly, + &faceIndex[0], nbFaces ); + } + + END_OF_MED(LOC); + return Connectivity; } - /*! - * \if developper - * fill the arguments vector of groups from the intermediate structure. - * This function must be called before getConnectivity() - * \endif - */ -void -_intermediateMED::getGroups(vector & _groupCell, - vector & _groupFace, - vector & _groupEdge, - vector & _groupNode, MESH * _ptrMesh) +/*! + * \if developper + * fill the arguments vector of groups from the intermediate structure. + * This function must be called before getConnectivity() + * \endif + */ +void _intermediateMED::getGroups(vector & _groupCell, + vector & _groupFace, + vector & _groupEdge, + vector & _groupNode, MESH * _ptrMesh) { - const char * LOC = "_intermediateMED::getGroups() : "; - BEGIN_OF(LOC); + const char* LOC = "_intermediateMED::getGroups() : "; + BEGIN_OF_MED(LOC); - medGroupes.resize( groupes.size(), 0 ); - if (maillage.size() == 0) { - INFOS( "Erreur : il n'y a plus de mailles"); + //medGroupes.resize( groupes.size(), 0 ); + if (maillageByType.size() == 0) { + INFOS_MED( "Erreur : il n'y a plus de mailles"); return; } @@ -664,26 +808,27 @@ _intermediateMED::getGroups(vector & _groupCell, numerotationMaillage(); // Renumerotation des mailles par entite - int dimension_maillage=maillage.rbegin()->dimension(); + int dimension_maillage=getMeshDimension(); - for (unsigned int i=0; i!=this->groupes.size(); ++i) + for (size_t i=0; i!=this->groupes.size(); ++i) { _groupe& grp = groupes[i]; - if ( medGroupes[ i ] ) + if ( grp.medGroup /*medGroupes[ i ]*/ ) continue; // grp already converted into a MED group bool isFieldSupport = ( support_groups.find( i ) != support_groups.end() ); // si le groupe est vide, ou si le groupe n'est pas nommé : on passe au suivant if ( grp.empty() || ( grp.nom.empty() && !isFieldSupport )) { if ( !grp.nom.empty() ) { - INFOS("Skip group " << i << grp.nom); + INFOS_MED("Skip group " << i << " " << grp.nom); // } else { -// MESSAGE("Skip group " << i << " <" << grp.nom << "> " << ( grp.empty() ? ": empty" : "")); +// MESSAGE_MED("Skip group " << i << " <" << grp.nom << "> " << ( grp.empty() ? ": empty" : "")); } continue; } // Build a set of mailles: sort mailles by type and exclude maille doubling + bool isSelfIntersect = false; typedef set< set<_maille>::iterator, _mailleIteratorCompare > TMailleSet; TMailleSet mailleSet; if( grp.groupes.size() ) {// le groupe i contient des sous-maillages @@ -691,21 +836,22 @@ _intermediateMED::getGroups(vector & _groupCell, for( vector::iterator j=grp.groupes.begin(); j!=grp.groupes.end(); ++j) { nb_elem += groupes[*j-1].mailles.size(); - _groupe::mailleIter maIt=groupes[*j-1].mailles.begin(); + _groupe::TMailleIter maIt=groupes[*j-1].mailles.begin(); for( ; maIt!=groupes[*j-1].mailles.end(); ++maIt) { // TMailleSet::const_iterator ma_it = mailleSet.find( *maIt ); // if ( ma_it != mailleSet.end() ) { -// MESSAGE("EQUAL ELEMS: " << *ma_it << " AND " << *maIt); +// MESSAGE_MED("EQUAL ELEMS: " << *ma_it << " AND " << *maIt); // } // else mailleSet.insert( *maIt ); } } if ( nb_elem != mailleSet.size() ) { // Self intersecting compound group - INFOS("Self intersecting group: " << i << " <" << grp.nom << ">" + isSelfIntersect = true; + INFOS_MED("Self intersecting group: " << i << " <" << grp.nom << ">" << ", mailleSet.size = " << mailleSet.size() << ", sum nb elems = " << nb_elem); for( vector::iterator j=grp.groupes.begin(); j!=grp.groupes.end(); ++j) - INFOS(" in sub-group "<< *j << " <" << groupes[*j-1].nom << "> " + INFOS_MED(" in sub-group "<< *j << " <" << groupes[*j-1].nom << "> " << groupes[*j-1].mailles.size() << " mailles of type " << groupes[*j-1].mailles[0]->geometricType); // if a group serve as a support to a field, then the _field is to be converted @@ -732,44 +878,53 @@ _intermediateMED::getGroups(vector & _groupCell, } } else { - _groupe::mailleIter maIt=grp.mailles.begin(); + _groupe::TMailleIter maIt=grp.mailles.begin(); for(; maIt!=grp.mailles.end(); ++maIt) mailleSet.insert( *maIt ); if ( grp.mailles.size() != mailleSet.size() ) - INFOS( "Self intersecting group: " << i << " <" << grp.nom << ">" + INFOS_MED( "Self intersecting group: " << i << " <" << grp.nom << ">" << ", mailleSet.size = " << mailleSet.size() << ", nb elems = " << grp.mailles.size()); } // MEDMEM does not allow constituents of -2 and less dimension // but do not skip node group - int group_min_dim = (**mailleSet.begin()).dimension(); - int group_max_dim = (**(--mailleSet.end())).dimension(); + int group_min_dim = (**mailleSet.begin()).dimensionWithPoly(); + int group_max_dim = (**(--mailleSet.end())).dimensionWithPoly(); if ( group_max_dim != 0 && group_min_dim <= dimension_maillage - 2 ) { - MESSAGE("Skip group: " << i << " <" << grp.nom << "> - too small dimension: " + MESSAGE_MED("Skip group: " << i << " <" << grp.nom << "> - too small dimension: " << group_min_dim); continue; } - // 1. Build a map _maille* -> index in MEDMEM::GROUP.getNumber(MED_ALL_ELEMENTS). - // It is used while fields building. - // 2. make mailles know the groups they belong to, that is used in getFamilies() - TMailleSet::iterator maIt = mailleSet.begin(); - int iMa; - for ( iMa = 0; maIt != mailleSet.end(); maIt++ ) { - grp.relocMap.insert( make_pair( &(**maIt), ++iMa )); - (*maIt)->groupes.push_back( i ); - } - ASSERT( iMa == grp.relocMap.size() ); - - int nb_geometric_types=1; - TMailleSet::iterator j=mailleSet.begin(); // initialise groupe_entity a l'entite de la premiere maille du groupe medEntityMesh groupe_entity = (**mailleSet.rbegin()).getEntity(dimension_maillage); if ( hasMixedCells && group_min_dim > 0 ) groupe_entity = MED_CELL; - medGeometryElement geometrictype=(**j).geometricType; + // total nb of elements in mesh of groupe_entity + int totalNbElements = 0; + if ( groupe_entity == MED_NODE ) + totalNbElements = points.size() - nbMerged( MED_POINT1 ); + else { + int entityDim = hasMixedCells ? -1 : group_min_dim; + _maillageByDimIterator allMailles( *this, entityDim, true ); + while ( allMailles.nextType() ) + if ( allMailles.dim() > 0 ) + totalNbElements += allMailles.sizeWithoutMerged(); + } + const bool isOnAll = ( mailleSet.size() == totalNbElements ); + + // if !isOnAll, build a map _maille::ordre() -> index in GROUP.getNumber(MED_ALL_ELEMENTS). + // It is used while fields building. + if ( !isOnAll || isSelfIntersect ) { + TMailleSet::iterator maIt = mailleSet.begin(); + for ( int iMa = 0; maIt != mailleSet.end(); maIt++ ) + grp.relocMap.insert( make_pair( (*maIt)->ordre(), ++iMa )); + } //Parcours des mailles (a partir de la deuxieme) pour compter les types geometriques + int nb_geometric_types=1; + TMailleSet::iterator j=mailleSet.begin(); + medGeometryElement geometrictype=(**j).geometricType; for ( ++j ; j!=mailleSet.end(); ++j ) { //Compte nombre de types geometriques @@ -796,7 +951,7 @@ _intermediateMED::getGroups(vector & _groupCell, for ( ; j!=mailleSet.end(); ++j , ++indice_mailles) { const _maille& ma = **j; - tab_numeros_elements[indice_mailles]= ma.ordre; + tab_numeros_elements[indice_mailles]= ma.ordre(); // if ( maxOrdre < tab_numeros_elements[indice_mailles] ) // maxOrdre = tab_numeros_elements[indice_mailles]; if (ma.geometricType != geometrictype) @@ -812,7 +967,7 @@ _intermediateMED::getGroups(vector & _groupCell, { tab_nombres_elements[k] = tab_index_types_geometriques[k+1]-tab_index_types_geometriques[k]; } - //INFOS( "MAX ORDRE in grp " << grp.nom << " entity " << groupe_entity << " : " << maxOrdre); + //INFOS_MED( "MAX ORDRE in grp " << grp.nom << " entity " << groupe_entity << " : " << maxOrdre); //Determination type entite du groupe vector * vect_group; @@ -831,11 +986,12 @@ _intermediateMED::getGroups(vector & _groupCell, vect_group= & _groupNode; break; } + //Creation nouveau groupe MED GROUP * new_group = new GROUP(); - medGroupes[ i ] = new_group; + grp.medGroup = new_group; //Appel methodes set - new_group->setTotalNumberOfElements(mailleSet.size()); + //new_group->setTotalNumberOfElements(mailleSet.size()); new_group->setName(grp.nom); new_group->setMesh(_ptrMesh); new_group->setNumberOfGeometricType(nb_geometric_types); @@ -843,7 +999,7 @@ _intermediateMED::getGroups(vector & _groupCell, new_group->setNumberOfElements(tab_nombres_elements); new_group->setNumber(tab_index_types_geometriques,tab_numeros_elements); new_group->setEntity(groupe_entity); - new_group->setAll(mailleSet.size() == maillage.size()); + new_group->setAll( isOnAll ); vect_group->push_back(new_group); @@ -853,7 +1009,7 @@ _intermediateMED::getGroups(vector & _groupCell, delete [] tab_nombres_elements; } - END_OF(LOC); + END_OF_MED(LOC); } //======================================================================= @@ -863,133 +1019,133 @@ _intermediateMED::getGroups(vector & _groupCell, // order. Call it after getGroups() //======================================================================= -void _intermediateMED::getFamilies(std::vector & _famCell, - std::vector & _famFace, - std::vector & _famEdge, - std::vector & _famNode, MESH * _ptrMesh) -{ - const char * LOC = "_intermediateMED::getFamilies() : "; - BEGIN_OF(LOC); +// void _intermediateMED::getFamilies(std::vector & _famCell, +// std::vector & _famFace, +// std::vector & _famEdge, +// std::vector & _famNode, MESH * _ptrMesh) +// { +// const char * LOC = "_intermediateMED::getFamilies() : "; +// BEGIN_OF_MED(LOC); - int nbElemFam = 0, nbNodeFam = 0; - std::map< GROUP*, vector< FAMILY * > > grpFamsMap; - int dimension_maillage=maillage.rbegin()->dimension(); - - std::set<_maille>::const_iterator i=maillage.begin(); // iterateurs sur les mailles - std::set<_maille>::const_iterator j=maillage.begin(); - - do - { - // make a family containing mailles shared by the same set of groups - std::list& grList = i->groupes; // to define the family end - int dimension = i->dimension(); // to define the entity end - medGeometryElement type = i->geometricType; - medEntityMesh entity = i->getEntity( dimension_maillage ); - - std::vector tab_types_geometriques; - std::vector tab_index_types_geometriques; - std::vector tab_nombres_elements; - std::vector tab_numeros_elements; - - int iMa = 1, nbtype = 0; - tab_types_geometriques.push_back( type ); - tab_index_types_geometriques.push_back( iMa ); - - // scan family cells and fill the tab that are needed by the create a MED FAMILY - while (i != maillage.end() && - i->groupes == grList && - i->dimension() == dimension) - { - if (type != i->geometricType) // si changement de type geometrique - { - tab_index_types_geometriques.push_back(iMa); - tab_nombres_elements.push_back(nbtype); - nbtype=0; - type=i->geometricType; - tab_types_geometriques.push_back(type); // stocke le nouveau type geometrique rencontre - } - ++nbtype; - ++iMa; - ++i; - } - tab_index_types_geometriques.push_back(iMa); - tab_nombres_elements.push_back(nbtype); // n'a pas été stocké dans la boucle - - tab_numeros_elements.resize( iMa - 1 ); - for ( iMa = 0; j != i; j++, iMa++ ) - tab_numeros_elements[ iMa ] = j->ordre; - - int id = ( entity == MED_NODE ? ++nbNodeFam : -(++nbElemFam) ); - - ostringstream name; - name << "FAM_" << id; - - // create a empty MED FAMILY and fill it with the tabs we constructed - FAMILY* newFam = new FAMILY(); - newFam->setTotalNumberOfElements( iMa ); - newFam->setName( name.str() ); - newFam->setMesh( _ptrMesh ); - newFam->setNumberOfGeometricType( tab_types_geometriques.size() ); - newFam->setGeometricType( &tab_types_geometriques[0] ); // we know the tab is not empy - newFam->setNumberOfElements( &tab_nombres_elements[0] ); - newFam->setNumber( &tab_index_types_geometriques[0], &tab_numeros_elements[0] ); - newFam->setEntity( entity ); - newFam->setAll( false ); - newFam->setIdentifier( id ); - newFam->setNumberOfGroups( grList.size() ); - - // Update links between families and groups - if ( ! grList.empty() ) - { - std::string * groupNames = new string[ grList.size() ]; - std::list::iterator g = grList.begin(); - for ( int i = 0; g != grList.end(); ++g, ++i ) { - GROUP * medGROUP = getGroup( *g ); - groupNames[ i ] = medGROUP->getName(); - grpFamsMap[ medGROUP ].push_back( newFam ); - } - newFam->setGroupsNames(groupNames); - } - // store newFam - std::vector* families = 0; - switch ( entity ) - { - case MED_CELL : - families = & _famCell; break; - case MED_FACE : - families = & _famFace; break; - case MED_EDGE : - families = & _famEdge; break; - case MED_NODE : - families = & _famNode; break; - } - if ( families ) - families->push_back( newFam ); - - } while ( i != maillage.end() ); - - // update references in groups - std::map< GROUP*, vector< FAMILY * > >::iterator gf = grpFamsMap.begin(); - for ( ; gf != grpFamsMap.end(); ++gf ) - { - gf->first->setNumberOfFamilies( gf->second.size() ); - gf->first->setFamilies( gf->second ); - } -} +// int nbElemFam = 0, nbNodeFam = 0; +// std::map< GROUP*, vector< FAMILY * > > grpFamsMap; +// int dimension_maillage=maillage.rbegin()->dimension(); + +// std::set<_maille>::const_iterator i=maillage.begin(); // iterateurs sur les mailles +// std::set<_maille>::const_iterator j=maillage.begin(); + +// do +// { +// // make a family containing mailles shared by the same set of groups +// std::list& grList = i->groupes; // to define the family end +// int dimension = i->dimension(); // to define the entity end +// medGeometryElement type = i->geometricType; +// medEntityMesh entity = i->getEntity( dimension_maillage ); + +// std::vector tab_types_geometriques; +// std::vector tab_index_types_geometriques; +// std::vector tab_nombres_elements; +// std::vector tab_numeros_elements; + +// int iMa = 1, nbtype = 0; +// tab_types_geometriques.push_back( type ); +// tab_index_types_geometriques.push_back( iMa ); + +// // scan family cells and fill the tab that are needed by the create a MED FAMILY +// while (i != maillage.end() && +// i->groupes == grList && +// i->dimension() == dimension) +// { +// if (type != i->geometricType) // si changement de type geometrique +// { +// tab_index_types_geometriques.push_back(iMa); +// tab_nombres_elements.push_back(nbtype); +// nbtype=0; +// type=i->geometricType; +// tab_types_geometriques.push_back(type); // stocke le nouveau type geometrique rencontre +// } +// ++nbtype; +// ++iMa; +// ++i; +// } +// tab_index_types_geometriques.push_back(iMa); +// tab_nombres_elements.push_back(nbtype); // n'a pas été stocké dans la boucle + +// tab_numeros_elements.resize( iMa - 1 ); +// for ( iMa = 0; j != i; j++, iMa++ ) +// tab_numeros_elements[ iMa ] = j->ordre; + +// int id = ( entity == MED_NODE ? ++nbNodeFam : -(++nbElemFam) ); + +// ostringstream name; +// name << "FAM_" << id; + +// // create a empty MED FAMILY and fill it with the tabs we constructed +// FAMILY* newFam = new FAMILY(); +// newFam->setTotalNumberOfElements( iMa ); +// newFam->setName( name.str() ); +// newFam->setMesh( _ptrMesh ); +// newFam->setNumberOfGeometricType( tab_types_geometriques.size() ); +// newFam->setGeometricType( &tab_types_geometriques[0] ); // we know the tab is not empy +// newFam->setNumberOfElements( &tab_nombres_elements[0] ); +// newFam->setNumber( &tab_index_types_geometriques[0], &tab_numeros_elements[0] ); +// newFam->setEntity( entity ); +// newFam->setAll( false ); +// newFam->setIdentifier( id ); +// newFam->setNumberOfGroups( grList.size() ); + +// // Update links between families and groups +// if ( ! grList.empty() ) +// { +// std::string * groupNames = new string[ grList.size() ]; +// std::list::iterator g = grList.begin(); +// for ( int i = 0; g != grList.end(); ++g, ++i ) { +// GROUP * medGROUP = getGroup( *g ); +// groupNames[ i ] = medGROUP->getName(); +// grpFamsMap[ medGROUP ].push_back( newFam ); +// } +// newFam->setGroupsNames(groupNames); +// } +// // store newFam +// std::vector* families = 0; +// switch ( entity ) +// { +// case MED_CELL : +// families = & _famCell; break; +// case MED_FACE : +// families = & _famFace; break; +// case MED_EDGE : +// families = & _famEdge; break; +// case MED_NODE : +// families = & _famNode; break; +// } +// if ( families ) +// families->push_back( newFam ); + +// } while ( i != maillage.end() ); + +// // update references in groups +// std::map< GROUP*, vector< FAMILY * > >::iterator gf = grpFamsMap.begin(); +// for ( ; gf != grpFamsMap.end(); ++gf ) +// { +// gf->first->setNumberOfFamilies( gf->second.size() ); +// gf->first->setFamilies( gf->second ); +// } +//} //======================================================================= //function : getGroup //purpose : //======================================================================= -GROUP * _intermediateMED::getGroup( int i ) -{ - if ( i <(int) medGroupes.size() ) - return medGroupes[ i ]; - throw MEDEXCEPTION - (LOCALIZED(STRING("_intermediateMED::getGroup(): WRONG GROUP INDEX: ") - << medGroupes.size() << " <= " << i )); -} +// GROUP * _intermediateMED::getGroup( int i ) +// { +// if ( i <(int) medGroupes.size() ) +// return medGroupes[ i ]; +// throw MEDEXCEPTION +// (LOCALIZED(STRING("_intermediateMED::getGroup(): WRONG GROUP INDEX: ") +// << medGroupes.size() << " <= " << i )); +// } //======================================================================= //function : getFields @@ -999,18 +1155,18 @@ GROUP * _intermediateMED::getGroup( int i ) void _intermediateMED::getFields(std::list< FIELD_* >& theFields) { const char * LOC = "_intermediateMED::getFields() : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); std::list< _fieldBase* >::const_iterator fIt = fields.begin(); for ( ; fIt != fields.end(); fIt++ ) { const _fieldBase* fb = *fIt; - list > ff = fb->getField(groupes, medGroupes); + list > ff = fb->getField(groupes); list >::iterator f_sup = ff.begin(); for (int j = 1 ; f_sup != ff.end(); f_sup++, ++j ) { FIELD_ * f = f_sup->first; - SUPPORT * sup = getGroup( f_sup->second ); + SUPPORT * sup = groupes[ f_sup->second ].medGroup; if ( !sup ) throw MEDEXCEPTION (LOCALIZED(STRING(LOC) <<"_intermediateMED::getFields(), NULL field support: " @@ -1031,12 +1187,17 @@ void _intermediateMED::getFields(std::list< FIELD_* >& theFields) f->setOrderNumber( j ); } } - END_OF(LOC); + END_OF_MED(LOC); } +//======================================================================= +//function : ~_intermediateMED +//purpose : destructor +//======================================================================= + _intermediateMED::~_intermediateMED() { - MESSAGE( "~_intermediateMED()"); + MESSAGE_MED( "~_intermediateMED()"); std::list< _fieldBase* >::const_iterator fIt = fields.begin(); for ( ; fIt != fields.end(); fIt++ ) delete *fIt; @@ -1078,6 +1239,251 @@ bool _fieldBase::hasSameComponentsBySupport() const return true; } +//======================================================================= +// +//function : mergeNodes +// +//======================================================================= +namespace { + +struct __NOEUD +{ + typedef map::iterator Inoeud; + Inoeud i_noeud; + + __NOEUD() {} + __NOEUD(Inoeud n): i_noeud(n) {} + const double & operator[] (int i) const { return i_noeud->second.coord[i]; } + double operator[] (int i) { return i_noeud->second.coord[i]; } + int dim() const { return i_noeud->second.coord.size(); } + int& num() { return i_noeud->second.number; } + int id() const { return i_noeud->first; } + bool isMerged() const { return i_noeud->second.number < 1; } +}; +//----------------------------------------------------------------------- +double DistanceL2(const __NOEUD &A,const __NOEUD &B) +{ + if ( B.isMerged() ) return DBL_MAX; + const double* cooA = &A[0], *cooB = &B[0], *cooEnd = cooA + A.dim(); + double dist, somme=0; + while ( cooA < cooEnd ) { + dist=((*cooA++) - (*cooB++)); + somme+=dist*dist; + } + return sqrt(somme); +} +//----------------------------------------------------------------------- +struct __NUAGENOEUD +{ + vector< __NOEUD > nodes; + __NUAGENOEUD(_intermediateMED& imed); + __NOEUD & operator [] (int i) { return nodes[i]; } + int size() const { return nodes.size(); } +}; +//----------------------------------------------------------------------- +__NUAGENOEUD::__NUAGENOEUD(_intermediateMED& imed) +{ + nodes.resize( imed.points.size() ); + map::iterator i_noeud = imed.points.begin(); + for( int i = 0; i_noeud!=imed.points.end(); ++i_noeud, ++i ) { + i_noeud->second.number = i+1; + nodes[ i ] = i_noeud; + } +} +//----------------------------------------------------------------------- +// mergeNodes +template int mergeNodes(double tolerance, + _intermediateMED& imed, + vector< int > & /*newNodeIDs*/) +{ + typedef dTree<__NOEUD,__NUAGENOEUD,DIM > DTree; + __NUAGENOEUD aNUAGENOEUD( imed ); + DTree tree( &aNUAGENOEUD ); + +// int maxID = imed.points.rbegin()->first; +// newNodeIDs.resize( maxID + 1, 0 ); + + int num = 0, nbRemoved = 0; + int nbNodes = aNUAGENOEUD.size(); + for ( int i = 0; i < nbNodes; ++i ) + { + __NOEUD & node = aNUAGENOEUD[i]; + int & number = node.num(); + if ( number < 0 ) + continue; // already merged + number = ++num; + + list closeNumbers; + int nbCoinsident = tree.get_all_close( node, tolerance, closeNumbers ); + if ( nbCoinsident > 1 ) // not only node it-self found + { + nbRemoved += nbCoinsident-1; // one of coincident nodes remains + int id = node.id(); + list::iterator n = closeNumbers.begin(), nEnd = closeNumbers.end(); + while ( n != nEnd ) { + __NOEUD & coincNode = aNUAGENOEUD[ *n++ ]; + int coincID = coincNode.id(); + if ( coincID != id ) { + coincNode.num() = -number; + //newNodeIDs[ coincID ] = id; + } + } + } + } + return nbRemoved; +} +//----------------------------------------------------------------------- +// wrapper of _maille used after merging nodes to find equal mailles +struct _mailleWrap +{ + const _maille* _ma; + + _mailleWrap(const _maille* ma=0): _ma(ma) { if (_ma) _ma->init(); } + ~_mailleWrap() { if (_ma) _ma->init(); } + + bool operator < (const _mailleWrap& mw) const + { + size_t l=_ma->sommets.size(); + const int* v1 = getSortedNodeNums(_ma); + const int* v2 = getSortedNodeNums(mw._ma); + for ( const int* vEnd = v1 + l; v1 < vEnd; ++v1, ++v2 ) + if(*v1 != *v2) + return *v1 < *v2; + return false; // cas d'égalité + } + static const int* getSortedNodeNums(const _maille* ma) + { + if ( !ma->sortedNodeIDs ) { + size_t l=ma->sommets.size(); + ma->sortedNodeIDs = new int[ l ]; + for (size_t i=0; i!=l; ++i) + ma->sortedNodeIDs[i]=ma->nodeNum(i); + std::sort( ma->sortedNodeIDs, ma->sortedNodeIDs + l ); + } + return ma->sortedNodeIDs; + } +}; + +} // namespace + +//======================================================================= +//function : mergeNodesAndElements +//purpose : optionally merge nodes and elements +//======================================================================= + +void _intermediateMED::mergeNodesAndElements(double tolerance) +{ + //const char * LOC = "_intermediateMED::mergeNodesAndElements(): "; + vector< int > newNodeIDs; // for i-th node id, id to replace with + + int nbRemovedNodes = 0; + const int spaceDimension=points.begin()->second.coord.size(); + if ( spaceDimension == 3 ) + nbRemovedNodes = mergeNodes<3>( tolerance, *this, newNodeIDs ); + else if ( spaceDimension == 2 ) + nbRemovedNodes = mergeNodes<2>( tolerance, *this, newNodeIDs ); + + myNodesNumerated = true; + + if ( nbRemovedNodes == 0 ) + return; + + // all commented code here was used to keep initial numeration but it was too slow + //numerotationMaillage(); + treatGroupes(); + + nbRemovedByType[ MED_NONE ] = nbRemovedNodes; + nbRemovedByType[ MED_POINT1 ] = nbRemovedNodes; + + bool hasPointMailles = false; + _maillageByDimIterator entityMailles( *this, 0 ); + if ( const set<_maille> * points = entityMailles.nextType() ) { + hasPointMailles = true; + set<_maille>::const_iterator i, iEnd = points->end(); + for ( i = points->begin(); i != iEnd; ++i ) + i->setOrdre( i->sommets[0]->second.number ); // is merged if point is merged + } + const bool skipFirstType = ( hasPointMailles && hasMixedCells ); + // loop on entities + for ( int dim = 1; dim <= 3; ++dim ) + { + int iterDim = hasMixedCells ? -1 : dim; + //int nbRemovedInEntity = 0; + + // count total nb of mailles in entity +// int nbMailles = 0; +// entityMailles.init( iterDim, true ); +// if ( skipFirstType ) entityMailles.nextType(); // merged POINT1's are same as nodes +// while ( const set<_maille> * typeMailles = entityMailles.nextType() ) +// nbMailles += typeMailles->size(); + + // for each maille number, count shift due to removed mailles with lower numbers + //vector shift( nbMailles+1, 0 ); + + // merge and numerate mailles + int num = 0; + entityMailles.init( iterDim, true ); + if ( skipFirstType ) entityMailles.nextType(); // merged POINT1's are same as nodes + while ( const set<_maille> * typeMailles = entityMailles.nextType() ) + { + int nbRemoved = 0; + set<_mailleWrap> maNodeNumSorted; + pair< set<_mailleWrap>::const_iterator, bool > mw_isunique; + + set<_maille>::const_iterator ma = typeMailles->begin(), maEnd = typeMailles->end(); + while ( ma != maEnd ) + { + const _maille & m = *ma++; + mw_isunique = maNodeNumSorted.insert( &m ); + if ( mw_isunique.second ) { + m.setOrdre( ++num ); + } + else { + const _maille* equalMa = mw_isunique.first->_ma; + //unsigned ordreToRemove = m.ordre(); + m.setMergedOrdre( equalMa->ordre() ); + nbRemoved++; +// while ( ordreToRemove <= nbMailles ) +// shift[ ordreToRemove++ ]++; + } + } + + if ( nbRemoved ) { + nbRemovedByType[ entityMailles.type() ] = nbRemoved; + //nbRemovedInEntity += nbRemoved; + } + + // update maille ordre +// if ( nbRemovedInEntity ) { +// for ( ma = typeMailles->begin(); ma != maEnd; ++ma ) { +// unsigned newOrdre = ma->ordre() - shift[ ma->ordre() ]; +// if ( ma->isMerged() ) +// ma->setMergedOrdre( newOrdre ); +// else +// ma->setOrdre( newOrdre ); +// } +// } + } + } + + myMaillesNumerated = true; + +} + +//======================================================================= +//function : getMeshDimension +//purpose : count mesh dimension +//======================================================================= + +int _intermediateMED::getMeshDimension() const +{ + int dim = 0; + _maillageByDimIterator allMailles( *this, -1, true ); + while ( allMailles.nextType() ) + dim = allMailles.dim(); + return dim; +} + } ///// diff --git a/src/MEDMEM/MEDMEM_DriverTools.hxx b/src/MEDMEM/MEDMEM_DriverTools.hxx index 267e02639..67fa5dfa2 100644 --- a/src/MEDMEM/MEDMEM_DriverTools.hxx +++ b/src/MEDMEM/MEDMEM_DriverTools.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef DRIVERTOOLS_HXX #define DRIVERTOOLS_HXX @@ -36,6 +38,7 @@ #include #include #include +#include // Way of storing values with gauss points by CASTEM: full/no interlace. // Remove code switched by this symbol as soon as the way is found out, @@ -50,62 +53,101 @@ class COORDINATE; class GROUP; class FAMILY; class FIELD_; +class _intermediateMED; +// ============================================================================== struct MEDMEM_EXPORT _noeud { - mutable int number; - std::vector coord; + mutable int number; // negative if node is merged + std::vector coord; }; +// ============================================================================== typedef pair _link; // a pair of node numbers +// ============================================================================== struct MEDMEM_EXPORT _maille { - typedef std::map::iterator iter; - MED_EN::medGeometryElement geometricType; - std::vector< iter > sommets; - mutable unsigned ordre; // l'ordre est fixé après insertion dans le set, et ne change ni l'état, ni l'ordre -> mutable - mutable bool reverse; // to reverse sommets of a face - mutable list groupes; // the GROUPs maille belongs to, used to create families - - _maille() : geometricType(MED_EN::MED_NONE),ordre(0),reverse(false) - { - }; - _maille(MED_EN::medGeometryElement _geometricType, size_t nelem) : geometricType(_geometricType),ordre(0),reverse(false) - { - sommets.reserve(nelem); - }; - int dimension() const // retourne la dimension de la maille - { - return geometricType/100; - }; - bool operator < (const _maille& ma) const; - MED_EN::medEntityMesh getEntity(const int meshDimension) const throw (MEDEXCEPTION); - _link link(int i) const; + typedef std::map::iterator TNoeud; //iter; + std::vector< TNoeud > sommets; + MED_EN::medGeometryElement geometricType; + mutable bool reverse; // to reverse sommets of a face + mutable int* sortedNodeIDs; // for comparison and merge + //mutable list groupes; // the GROUPs maille belongs to, used to create families + + _maille(MED_EN::medGeometryElement type=MED_EN::MED_NONE, size_t nelem=0) + : geometricType(type),reverse(false),sortedNodeIDs(0),_ordre(0) { sommets.reserve(nelem); } + + _maille(const _maille& ma); + void init() const { if ( sortedNodeIDs ) delete [] sortedNodeIDs; sortedNodeIDs = 0; } + ~_maille() { init(); } + + int dimension() const // retourne la dimension de la maille + { return geometricType/100; } + + int dimensionWithPoly() const // retourne la dimension de la maille + { return geometricType >= MED_EN::MED_POLYGON ? dimension()-2 : dimension(); } + + const int* getSortedNodes() const; // creates if needed and return sortedNodeIDs + bool operator < (const _maille& ma) const; + MED_EN::medEntityMesh getEntity(const int meshDimension) const throw (MEDEXCEPTION); + _link link(int i) const; + + //bool isMerged(int i) const { return sommets[i]->second.number < 0; } + int nodeNum(int i) const { return abs( sommets[i]->second.number ); } + int nodeID (int i) const { return sommets[i]->first; } // key in points map + + unsigned ordre() const { return abs( _ordre ); } + bool isMerged() const { return _ordre < 0; } + void setMergedOrdre(unsigned o) const { _ordre = -o; } + void setOrdre(int o) const { _ordre = o; } + +private: + mutable int _ordre; // l'ordre est fixé après insertion dans le set, et ne change ni l'état, ni l'ordre -> mutable + _maille& operator=(const _maille& ma); }; +// ============================================================================== struct MEDMEM_EXPORT _mailleIteratorCompare // pour ordonner le set d'iterateurs sur mailles { - bool operator () (std::set<_maille>::iterator i1, std::set<_maille>::iterator i2) - { - return *i1<*i2; - } + // this operator is used for ordering mailles thinin a group, which happens when + // right numbers are already given to _maille's, so we can use _maille::ordre + // for comparison instead of a heavy _maille::operator < + bool operator () (std::set<_maille>::iterator i1, std::set<_maille>::iterator i2) + { + //return *i1<*i2; + return i1->ordre() < i2->ordre(); + } }; +// ============================================================================== struct MEDMEM_EXPORT _groupe { - typedef std::vector< std::set<_maille>::iterator>::const_iterator mailleIter; - std::string nom; - std::vector< std::set<_maille>::iterator > mailles; // iterateurs sur les mailles composant le groupe - std::vector groupes; // indices des sous-groupes composant le groupe - std::map relocMap; // map _maille* -> index in MEDMEM::GROUP.getNumber(MED_ALL_ELEMENTS). It is built by _intermediateMED::getGroups() - bool empty() const { return mailles.empty() && groupes.empty(); } + typedef std::set<_maille>::iterator TMaille; + typedef std::vector< TMaille >::const_iterator TMailleIter; + std::string nom; + std::vector< TMaille > mailles; // iterateurs sur les mailles composant le groupe + std::vector groupes; // indices des sous-groupes composant le groupe + std::map relocMap; // map _maille::ordre() -> index in GROUP, built by getGroups() + GROUP* medGroup; + + const _maille& maille(int index) { return *mailles[index]; } + bool empty() const { return mailles.empty() && groupes.empty(); } +#ifdef WNT + int size() const { return (mailles.size()>relocMap.size())?mailles.size():relocMap.size(); } +#else + int size() const { return std::max( mailles.size(), relocMap.size() ); } +#endif + _groupe():medGroup(0) {} }; +// ============================================================================== struct MEDMEM_EXPORT _fieldBase { // a field contains several subcomponents each referring to its own support and // having several named components + // ---------------------------------------------------------------------------- struct _sub_data // a subcomponent + // -------------------------------- { int _supp_id; // group index within _intermediateMED::groupes std::vector _comp_names; // component names @@ -117,9 +159,14 @@ struct MEDMEM_EXPORT _fieldBase { std::string & compName( int i_comp ) { return _comp_names[ i_comp ]; } bool isValidNbGauss() const { return *std::max_element( _nb_gauss.begin(), _nb_gauss.end() ) == *std::min_element( _nb_gauss.begin(), _nb_gauss.end() ); } +#ifdef WNT + int nbGauss() const { return (1>_nb_gauss[0])?1:_nb_gauss[0]; } +#else int nbGauss() const { return std::max( 1, _nb_gauss[0] ); } +#endif bool hasGauss() const { return nbGauss() > 1; } }; + // ---------------------------------------------------------------------------- std::vector< _sub_data > _sub; int _group_id; // group index within _intermediateMED::groupes // if _group_id == -1 then each subcomponent makes a separate MEDMEM::FIELD, else all subcomponents @@ -131,8 +178,7 @@ struct MEDMEM_EXPORT _fieldBase { _fieldBase( MED_EN::med_type_champ theType, int nb_sub ) : _group_id(-1),_type(theType) { _sub.resize( nb_sub ); } - virtual std::list > getField(std::vector<_groupe>& groupes, - std::vector& medGroups) const = 0; + virtual std::list > getField(std::vector<_groupe>& groupes) const = 0; void getGroupIds( std::set & ids, bool all ) const; // return ids of main and/or sub-groups bool hasCommonSupport() const { return _group_id >= 0; } // true if there is one support for all subs bool hasSameComponentsBySupport() const; @@ -140,6 +186,7 @@ struct MEDMEM_EXPORT _fieldBase { virtual ~_fieldBase() {} }; +// ============================================================================== template< class T > class _field: public _fieldBase { std::vector< std::vector< T > > comp_values; @@ -147,11 +194,67 @@ template< class T > class _field: public _fieldBase _field< T > ( MED_EN::med_type_champ theType, int nb_sub, int total_nb_comp ) : _fieldBase( theType, nb_sub ) { comp_values.reserve( total_nb_comp ); } std::vector< T >& addComponent( int nb_values ); // return a vector ready to fill in - std::list > getField(std::vector<_groupe>& groupes, - std::vector& medGroups) const; + std::list > getField(std::vector<_groupe>& groupes) const; virtual void dump(std::ostream&) const; }; +// ============================================================================== +/*! + * \if developper + * Iterator on set of _maille's of given dimension + * \endif + */ +class MEDMEM_EXPORT _maillageByDimIterator +{ +public: + // if (convertPoly) then treat poly as 2d and 3d, else as 4d and 5d (=medGeometryElement/100) + _maillageByDimIterator( const _intermediateMED & medi, + const int dim=-1, // dim=-1 - for all dimensions + const bool convertPoly = false ) + { myImed = & medi; init( dim, convertPoly ); } + + // if (convertPoly) then treat poly as 2d and 3d, else as 4d and 5d (=medGeometryElement/100) + void init(const int dim=-1, // dim=-1 - for all dimensions + const bool convertPoly = false ); + + //!< return next set of _maille's of required dimension + const std::set<_maille > * nextType() { + while ( myIt != myEnd ) + if ( !myIt->second.empty() && ( myDim < 0 || dim(false) == myDim )) + return & (myIt++)->second; + else + ++myIt; + return 0; + } + //!< return dimension of mailles returned by the last or further next() + int dim(const bool last=true) const { + iterator it = myIt; + if ( last ) --it; + return myConvertPoly ? + it->second.begin()->dimensionWithPoly() : + it->second.begin()->dimension(); + } + //!< return type of mailles returned by the last next() + MED_EN::medGeometryElement type() const { iterator it = myIt; return (--it)->first; } + + //!< return number of mailles taking into account merged ones + int sizeWithoutMerged() const { + iterator it = myIt; + removed::const_iterator tNb = nbRemovedByType->find( (--it)->first ); + return it->second.size() - ( tNb == nbRemovedByType->end() ? 0 : tNb->second ); + } +private: + typedef std::map removed; + typedef std::map > TMaillageByType; + typedef TMaillageByType::const_iterator iterator; + + const _intermediateMED* myImed; + iterator myIt, myEnd; + int myDim, myConvertPoly; + const removed * nbRemovedByType; +}; + +// ============================================================================== /*! * \if developper * Intermediate structure used by drivers to store data read from the other format file. @@ -164,34 +267,71 @@ template< class T > class _field: public _fieldBase */ struct MEDMEM_EXPORT _intermediateMED { - std::set<_maille> maillage; + typedef std::map > TMaillageByType; + typedef std::map TNbByType; + typedef std::map< const _maille*, std::vector > TPolyherdalNbFaceNodes; + + TNbByType nbRemovedByType; // nb mailles removed by merge std::vector<_groupe> groupes; - std::vector medGroupes; + //std::vector medGroupes; std::map< int, _noeud > points; std::list< _fieldBase* > fields; - bool hasMixedCells; // true if there are groups with mixed entity types - - CONNECTIVITY * getConnectivity(); // set MED connectivity from the intermediate structure - COORDINATE * getCoordinate(const string & coordinateSystem="CARTESIAN"); // set MED coordinate from the - // intermediate structure - void getFamilies(std::vector & _famCell, std::vector & _famFace, - std::vector & _famEdge, std::vector & _famNode, MESH * _ptrMesh); + bool hasMixedCells; // true if there are groups with mixed entity types + TPolyherdalNbFaceNodes polyherdalNbFaceNodes; // nb of nodes in faces for each polyhedron + + inline _groupe::TMaille insert(const _maille& ma); + + int getMeshDimension() const; + void mergeNodesAndElements(double tolerance); // optionally merge nodes and elements + CONNECTIVITY * getConnectivity(); // creates MED connectivity from the intermediate structure + COORDINATE * getCoordinate(const string & coordinateSystem="CARTESIAN"); // makes MED coordinate +// void getFamilies(std::vector & _famCell, std::vector & _famFace, +// std::vector & _famEdge, std::vector & _famNode, +// MESH * _ptrMesh); void getGroups(std::vector & _groupCell, std::vector & _groupFace, - std::vector & _groupEdge, std::vector & _groupNode, MESH * _ptrMesh); - GROUP * getGroup( int i ); + std::vector & _groupEdge, std::vector & _groupNode, + MESH * _ptrMesh); + //GROUP * getGroup( int i ); void getFields(std::list< FIELD_* >& fields); // used by previous functions to renumber points & mesh. - void treatGroupes(); // detect groupes of mixed dimention - void numerotationMaillage(); - void numerotationPoints(); bool myGroupsTreated; - bool myPointsNumerated; - - _intermediateMED() { myGroupsTreated = myPointsNumerated = false; } - ~_intermediateMED(); + void treatGroupes(); // detect groupes of mixed dimension + void numerotationMaillage(); + bool numerotationPoints(); // return true if renumeration done + int nbMerged(int geoType) const; //!< nb nodes removed by merge + + _intermediateMED() + { myNodesNumerated = myMaillesNumerated = myGroupsTreated = false; currentTypeMailles = 0; } + ~_intermediateMED(); + +private: + + bool myNodesNumerated, myMaillesNumerated; + // mailles groupped by geom type; use insert() for filling in and + // _maillageByDimIterator for exploring it + //std::set<_maille> maillage; + TMaillageByType maillageByType; + TMaillageByType::value_type* currentTypeMailles; // for fast insertion + friend class _maillageByDimIterator; }; +//----------------------------------------------------------------------- +_groupe::TMaille _intermediateMED::insert(const _maille& ma) +{ + if ( !currentTypeMailles || currentTypeMailles->first != ma.geometricType ) + currentTypeMailles = & *maillageByType.insert + ( make_pair( ma.geometricType, std::set<_maille >())).first; + + _groupe::TMaille res = currentTypeMailles->second.insert( ma ).first; + + ((_maille&)ma).init(); // this method was added for the sake of this call which is needed to + // remove comparison key (sortedNodeIDs) from a temporary _maille ma + + return res; +} + +// ============================================================================== std::ostream& operator << (std::ostream& , const _maille& ); std::ostream& operator << (std::ostream& , const _groupe& ); @@ -218,8 +358,7 @@ template //======================================================================= template -std::list > _field< T >::getField(std::vector<_groupe> & groupes, - std::vector & medGroups) const +std::list > _field< T >::getField(std::vector<_groupe> & groupes) const { const char* LOC = "_field< T >::getField()"; @@ -238,7 +377,7 @@ std::list > _field< T >::getField(std::vector<_groupe> if ( hasCommonSupport() ) // several subs are combined into one field { grp = & groupes[ _group_id ]; - medGrp = medGroups[ _group_id ]; + medGrp = grp->medGroup; if ( !grp || grp->empty() || !medGrp || !medGrp->getNumberOfTypes()) return res; @@ -246,16 +385,19 @@ std::list > _field< T >::getField(std::vector<_groupe> nbtypegeo = medGrp->getNumberOfTypes(); nbelgeoc .resize( nbtypegeo + 1, 0 ); nbgaussgeo.resize( nbtypegeo + 1, 0 ); - const int * nbElemByType = medGrp->getNumberOfElements(); - sub_data = _sub.begin(); + const int * nbElemByType = medGrp->getNumberOfElements(); + const MED_EN::medGeometryElement* types = medGrp->getTypes(); for (int iType = 0; iType < nbtypegeo; ++iType) { + // nb elem by type nbelgeoc [ iType+1 ] = nbelgeoc[ iType ] + nbElemByType[ iType ]; - nbgaussgeo[ iType+1 ] = sub_data->nbGauss(); - int nbElemInSubs = 0; - while ( nbElemInSubs < nbElemByType[ iType ] && sub_data != sub_end ) { - nbElemInSubs += groupes[ sub_data->_supp_id ].relocMap.size(); - ++sub_data; + // nb gauss by type; find a sub for a geo type + for ( sub_data = _sub.begin(); sub_data != sub_end; ++sub_data ) { + _groupe & sub_grp = groupes[ sub_data->_supp_id ]; + if ( !sub_grp.empty() && sub_grp.mailles[0]->geometricType == types[ iType ]) + break; } + ASSERT_MED( sub_data != sub_end ); + nbgaussgeo[ iType+1 ] = sub_data->nbGauss(); } } typedef typename MEDMEM_ArrayInterface::Array TArrayNoGauss; @@ -271,20 +413,20 @@ std::list > _field< T >::getField(std::vector<_groupe> // nb values in a field if ( !hasCommonSupport() ) { grp = & groupes[ sub_data->_supp_id ]; - medGrp = medGroups[ sub_data->_supp_id ]; + medGrp = grp->medGroup; } - int nb_val = grp->relocMap.size(); + int nb_val = grp->size(); // check validity of a sub_data bool validSub = true; if ( !nb_val ) { - INFOS("Skip field <" << _name << ">: invalid supporting group " + INFOS_MED("Skip field <" << _name << ">: invalid supporting group " << (hasCommonSupport() ? _group_id : sub_data->_supp_id ) << " of " << i_sub << "-th subcomponent" ); validSub = false; } if ( !sub_data->isValidNbGauss() ) { - INFOS("Skip field <" << _name << ">: different nb of gauss points in components "); + INFOS_MED("Skip field <" << _name << ">: different nb of gauss points in components "); validSub = false; } if ( !validSub ) { @@ -320,7 +462,7 @@ std::list > _field< T >::getField(std::vector<_groupe> f->setMEDComponentsUnits( &str[0] ); res.push_back( make_pair( f , hasCommonSupport() ? _group_id : sub_data->_supp_id )); - MESSAGE(" MAKE " << nb_fields << "-th field <" << _name << "> on group_id " << _group_id ); + MESSAGE_MED(" MAKE " << nb_fields << "-th field <" << _name << "> on group_id " << _group_id ); // make an array if ( !sub_data->hasGauss() ) { @@ -355,7 +497,7 @@ std::list > _field< T >::getField(std::vector<_groupe> _groupe & sub_grp = groupes[ sub_data->_supp_id ]; int nb_supp_elems = sub_grp.mailles.size(); int nb_gauss = sub_data->nbGauss(); - MESSAGE("insert sub data, group_id: " << sub_data->_supp_id << + MESSAGE_MED("insert sub data, group_id: " << sub_data->_supp_id << ", nb values: " << comp_values[ i_comp_tot ].size() << ", relocMap size: " << sub_grp.relocMap.size() << ", nb mailles: " << nb_supp_elems); @@ -374,24 +516,20 @@ std::list > _field< T >::getField(std::vector<_groupe> // store values const std::vector< T > & values = comp_values[ i_comp_tot++ ]; bool oneValue = ( values.size() == 1 ); - ASSERT( oneValue || values.size() == nb_supp_elems * nb_gauss ); + ASSERT_MED( oneValue || values.size() == nb_supp_elems * nb_gauss ); for ( int k = 0; k < nb_supp_elems; ++k ) { const T& val = oneValue ? values[ 0 ] : values[ k * elem_step ]; - const _maille* ma = &(*sub_grp.mailles[ k ]); + const _maille& ma = sub_grp.maille( k ); if ( medGrp->isOnAllElements() ) { - i = ma->ordre; - if ( i > nb_val ) - throw MEDEXCEPTION (LOCALIZED(STRING(LOC) << ", wrong elem position. " - << k << "-th elem: " << ma - << ", pos (" << i << ") must be <= " << nb_val)); + i = ma.ordre(); } else { - std::map::const_iterator ma_i = grp->relocMap.find( ma ); - if ( ma_i == grp->relocMap.end() ) + std::map::const_iterator ordre_i = grp->relocMap.find( ma.ordre() ); + if ( ordre_i == grp->relocMap.end() ) throw MEDEXCEPTION (LOCALIZED(STRING(LOC) << ", cant find elem index. " << k << "-th elem: " << ma)); - i = ma_i->second; + i = ordre_i->second; } if ( arrayNoGauss ) { arrayNoGauss->setIJ( i, i_comp, val ); @@ -409,7 +547,9 @@ std::list > _field< T >::getField(std::vector<_groupe> } +// ============================================================================== template void _field< T >::dump(std::ostream& os) const +// ============================================================================== { _fieldBase::dump(os); os << endl; @@ -419,6 +559,6 @@ template void _field< T >::dump(std::ostream& os) const } } -}; // namespace MEDMEM +} // namespace MEDMEM #endif /* DRIVERTOOLS_HXX */ diff --git a/src/MEDMEM/MEDMEM_DriversDef.cxx b/src/MEDMEM/MEDMEM_DriversDef.cxx index dc65ac489..f4b4827f2 100644 --- a/src/MEDMEM/MEDMEM_DriversDef.cxx +++ b/src/MEDMEM/MEDMEM_DriversDef.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_DriversDef.hxx" @@ -51,9 +53,9 @@ GEO_NAME::GEO_NAME() : map() GEO_NAME::~GEO_NAME() { -// MESSAGE(" destructor GEO_NAME::~GEO_NAME() "<< size() ); +// MESSAGE_MED(" destructor GEO_NAME::~GEO_NAME() "<< size() ); // clear(); -// MESSAGE(" end of destructor GEO_NAME::~GEO_NAME() "<< size() ); +// MESSAGE_MED(" end of destructor GEO_NAME::~GEO_NAME() "<< size() ); } string & GEO_NAME::operator[]( const MED_EN::medGeometryElement &c ) const @@ -78,9 +80,9 @@ ENT_NAME::ENT_NAME() : map() ENT_NAME::~ENT_NAME() { -// MESSAGE(" destructor ENT_NAME::~ENT_NAME() "<< size() ); +// MESSAGE_MED(" destructor ENT_NAME::~ENT_NAME() "<< size() ); // clear(); -// MESSAGE(" end of destructor ENT_NAME::~ENT_NAME() "<< size() ); +// MESSAGE_MED(" end of destructor ENT_NAME::~ENT_NAME() "<< size() ); } string & ENT_NAME::operator[]( const MED_EN::medEntityMesh &c ) const @@ -152,9 +154,9 @@ MESH_ENTITIES::MESH_ENTITIES () : map & MESH_ENTITIES::operator[]( const MED_EN::medEntityMesh &c ) const diff --git a/src/MEDMEM/MEDMEM_DriversDef.hxx b/src/MEDMEM/MEDMEM_DriversDef.hxx index 2c54c6c35..a0e5c151d 100644 --- a/src/MEDMEM/MEDMEM_DriversDef.hxx +++ b/src/MEDMEM/MEDMEM_DriversDef.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // # ifndef DRIVERS_DEF_HXX # define DRIVERS_DEF_HXX diff --git a/src/MEDMEM/MEDMEM_EnsightFieldDriver.cxx b/src/MEDMEM/MEDMEM_EnsightFieldDriver.cxx new file mode 100644 index 000000000..e395c1120 --- /dev/null +++ b/src/MEDMEM/MEDMEM_EnsightFieldDriver.cxx @@ -0,0 +1,1658 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include +#include +#include + +#include "MEDMEM_Utilities.hxx" + +#include "MEDMEM_Field.hxx" +#include "MEDMEM_EnsightUtils.hxx" + +#define TStrTool _ASCIIFileReader + +using namespace MED_EN; +using namespace MEDMEM_ENSIGHT; + +namespace { + + // ============================================================================== + /*! + * \brief Iterator on specified values of a field component + */ + template class _SelectedValueIterator + { + int myDelta; + const T* myPtr; + int myIndexDelta; + const int* myIndex; + public: + _SelectedValueIterator() // by default next() returns zero + : myDelta( 0 ), myPtr (_ValueIterator::zeroPtr()), + myIndexDelta( 0 ), myIndex(_ValueIterator::zeroPtr()) {} + + _SelectedValueIterator(const T* values, int delta, const int* index) + : myDelta( delta ), myPtr(values), myIndexDelta(1), myIndex(index-1) {} + + const T & next() { myIndex += myIndexDelta; return myPtr[ (*myIndex) * myDelta ]; } + }; + + // ============================================================================== + /*! + * \brief Container of values of any type to read/write from/to EnSight variable. + * It stores values relating to one element type within a part + */ + struct _SubPartValues + { + _SubPart mySubPart; + const char * myValues; + medModeSwitch myInterlace; + bool myOwnValues; // to delete or not myValues + string myConstValue; // if myConstValue is set, other members are meaningless + + // for writing values of a field-on-all-entities for a group + const int * myNumbers; + + string myUndefValue; + set myUndefIndices; + vector myPartialIndices; + + _SubPartValues(const _SubPart& sub=_SubPart()) + : mySubPart(sub), myValues(0), myInterlace(MED_NO_INTERLACE), myOwnValues(true) {}; + + ~_SubPartValues() { clear(); } + void clear() { if ( myOwnValues ) delete [] myValues; myValues = 0; } + + // ------------------------------------------------------------------- + //!< copying removes data from the source object + _SubPartValues(const _SubPartValues& other) + :mySubPart(other.mySubPart), myValues(other.myValues), + myInterlace(other.myInterlace), myOwnValues(true) + { ((_SubPartValues&)other).myValues=0; } + + // ------------------------------------------------------------------- + //!< Return iterator on values of a component counted from 1 + // nbElements is a number of values of a component located one by one in + // not full interlace + template _ValueIterator + getValues( int component, int nbElements, int nbComponents ) const + { + const T* values = (T*) myValues; + if ( myInterlace == MED_FULL_INTERLACE ) { + values += (component - 1); + return _ValueIterator( values, nbComponents ); + } + else { + values += (component - 1) * nbElements; + return _ValueIterator( values, 1 ); + } + } + // ------------------------------------------------------------------- + //!< Return iterator on specified values of a component counted from 1. + // nbElements is a number of values of a component located one by one in + // not full interlace + template _SelectedValueIterator + getSelectedValues( int component, int nbElements, int nbComponents ) const + { + // Values are specified by myNumbers. myValues points to the value + // relating to myNumbers[0] element. + const T* values = (T*) myValues; + if ( myInterlace == MED_FULL_INTERLACE ) { + values -= myNumbers[0] * nbComponents; + values += (component - 1); + return _SelectedValueIterator( values, nbComponents, myNumbers ); + } + else { + values -= myNumbers[0]; + values += (component - 1) * nbElements; + return _SelectedValueIterator( values, 1, myNumbers ); + } + } + // ------------------------------------------------------------------- + //!< Return iterators on all values of all components + template vector< _ValueIterator > + getAllValues( int nbElements, int nbComponents, bool add3dComp ) const + { + // add the 3-d component to a vector in 2D space + int addComp = ( add3dComp && nbComponents == 2 ) ? 1 : 0; + vector< _ValueIterator > compValIt( nbComponents + addComp); + for ( int j = 1; j <= nbComponents; ++j ) + compValIt[ j-1 ] = getValues( j, nbElements, nbComponents ); + return compValIt; + } + // ------------------------------------------------------------------- + //!< Return iterators on specified values for all components + template vector< _SelectedValueIterator > + getAllSelectedValues( int nbElements, int nbComponents, bool add3dComp ) const + { + // add the 3-d component to a vector in 2D space + int addComp = ( add3dComp && nbComponents == 2 ) ? 1 : 0; + vector< _SelectedValueIterator > compValIt( nbComponents + addComp); + for ( int j = 1; j <= nbComponents; ++j ) + compValIt[ j-1 ] = getSelectedValues( j, nbElements, nbComponents ); + return compValIt; + } + }; + + //======================================================================= + /*! + use file reader to get values of a _SubPart + */ + template + void readSubPartValues( FileReader& reader, + const FIELD_* field, + _SubPartValues & subValues) + { + medEntityMesh entity = field->getSupport()->getEntity(); + int nbComponents = field->getNumberOfComponents(); + + int nbElements = 0; + if ( entity == MED_NODE ) + nbElements = subValues.mySubPart.myNbNodes; + else + nbElements = subValues.mySubPart.myNbCells; + + int nbValues = nbElements * nbComponents; + if ( nbValues < 1 ) + return; + + const char* undefValue = 0; + set* undefIndices = &subValues.myUndefIndices; + vector* partial = 0; + if ( !subValues.myUndefValue.empty() ) + undefValue = subValues.myUndefValue.c_str(); + if ( !subValues.myPartialIndices.empty() ) + partial = &subValues.myPartialIndices; + + if ( field->getValueType() == MED_REEL64 ) + subValues.myValues = reader.template convertReals( nbValues, + undefValue, undefIndices, + partial, nbComponents ); + else if ( field->getValueType() == MED_INT32 ) + subValues.myValues = reader.template convertReals ( nbValues, + undefValue, undefIndices, + partial, nbComponents ); + else + subValues.myValues = reader.template convertReals ( nbValues, + undefValue, undefIndices, + partial, nbComponents ); + // convert partial indices into undef indices + if ( !subValues.myPartialIndices.empty() ) + { + // sort partial + set sortedPartial; + vector::iterator p = partial->begin(), pEnd = partial->end(); + while ( p != pEnd ) + sortedPartial.insert( sortedPartial.end(), *p++ ); + partial->clear(); + + // fill undef indices + set & undef = subValues.myUndefIndices; + set::iterator sp = sortedPartial.begin(); + int i = 1; + for ( ; sp != sortedPartial.end() && i <= nbElements; ++i, ++sp ) { + while ( i < *sp ) + undef.insert( undef.end(), i++ ); + } + while ( i <= nbElements ) + undef.insert( undef.end(), i++ ); + } + } + //======================================================================= + /*! + set values to an array + */ + template + void _setValuesToArray( vector< _ValueIterator > & compValIt, + const int nbValues, + TArray* array, + TMailIter& cellIt, + _Support* interSupport, + const set& localUndefIndices, + set & globalUndefIndices) + { + int nbComponents = array->getDim(); + if ( localUndefIndices.empty() ) + { + for ( int c = 0; c < nbValues; ++c, ++cellIt ) + { + int i = interSupport->getIndex( *cellIt ); + for ( int j = 1; j <= nbComponents; ++j ) + array->setIJ( i, j, compValIt[ j ].next() ); + } + } + else + { + // set values from the first till undefined end + set::const_iterator undef = localUndefIndices.begin(); + int c = 1, last = min( nbValues, *localUndefIndices.rbegin() ); + for ( ; c <= last; ++c, ++cellIt ) + { + int i = interSupport->getIndex( *cellIt ); + if ( c == *undef ) { + globalUndefIndices.insert( i ); + ++undef; + } + for ( int j = 1; j <= nbComponents; ++j ) + array->setIJ( i, j, compValIt[ j ].next() ); + } + // set all the rest values + for ( ; c <= nbValues; ++c, ++cellIt ) + { + int i = interSupport->getIndex( *cellIt ); + for ( int j = 1; j <= nbComponents; ++j ) + array->setIJ( i, j, compValIt[ j ].next() ); + } + } + } + + //================================================================================ + /*! + * \brief creates a new support excluding undef indices + */ + //================================================================================ + + SUPPORT* makeShiftedSupport(const SUPPORT* support, + const set undefIndices) + { + int nbElements = support->getNumberOfElements(MED_ALL_ELEMENTS); + int nbTypes = support->getNumberOfTypes(); + + int i, shitf = 1; + set::const_iterator undef; + + // shift support numbers + int * index = new int[ nbTypes + 1 ]; + int * number = new int[ nbElements - undefIndices.size() ]; + if ( support->isOnAllElements() ) { + // make shifted number + int * numberPtr = number; + for ( i = 0, undef = undefIndices.begin(); undef != undefIndices.end(); ++undef ) + while ( ++i < *undef ) + *numberPtr++ = i; + while ( ++i <= nbElements ) + *numberPtr++ = i; + // fill index but without shift + const int * oldNbElemByType = support->getNumberOfElements(); + index[0] = 1; + for ( int t = 0; t < nbTypes; ++t ) + index[ t+1 ] = index[ t ] + oldNbElemByType[ t ]; + } + else { + // shift existing number + shitf = 1; + const int * oldNumber = support->getNumber( MED_ALL_ELEMENTS ); + std::copy( oldNumber, oldNumber + *undefIndices.begin()-1, number ); // copy [0:firstUndef] + for ( undef = undefIndices.begin(); undef != undefIndices.end(); ) { + i = *undef++; + int nextUndef = ( undef != undefIndices.end() ) ? *undef : nbElements + 1; + while ( ++i < nextUndef ) + number[ i-1 - shitf ] = oldNumber[ i-1 ]; // shift number + ++shitf; + } + // copy index + const int * oldIndex = support->getNumberIndex(); + std::copy( oldIndex, oldIndex + nbTypes + 1, index ); + } + // update index + { + set::const_reverse_iterator undef = undefIndices.rbegin(); + for ( ; undef != undefIndices.rend(); ++undef ) { + for ( int t = nbTypes; t ; --t ) + if ( *undef < index[ t ] ) + --index[ t ]; + else + break; + } + } + // count number of elements by type + vector nbElem( nbTypes ); + for ( int t = 0; t < nbTypes; ++t ) + nbElem[ t ] = index[ t+1 ] - index[ t ]; + + SUPPORT* newSup = new SUPPORT(); + newSup->setMesh ( support->getMesh() ); + newSup->setNumberOfGeometricType( nbTypes ); + newSup->setGeometricType ( support->getTypes() ); + newSup->setNumberOfElements ( &nbElem[0] ); + newSup->setNumber ( index, number, /*shallowCopy =*/ true ); + newSup->setEntity ( support->getEntity() ); + newSup->setAll ( false ); + + return newSup; + } + + //======================================================================= + /*! + set values to a field + */ + template + void _setValuesToField( FIELD* field, + _Support* interSupport, + list<_SubPartValues> & subPartValues ) + { + medEntityMesh entity = field->getSupport()->getEntity(); + SUPPORT* support = interSupport->medSupport( entity ); + field->setSupport( support ); + + int j, nbComponents = field->getNumberOfComponents(); + int nbElements = field->getSupport()->getNumberOfElements(MED_ALL_ELEMENTS); + + typedef typename MEDMEM_ArrayInterface::Array TArray; + + const string& constValue = subPartValues.front().myConstValue; + if ( !constValue.empty() ) + { + vector values(nbComponents * nbElements, (T)atof(constValue.c_str())); + field->setArray( new TArray( &values[0], nbComponents, nbElements )); + field->setNumberOfValues( nbElements ); + return; + } + + field->allocValue( nbComponents, nbElements ); + TArray * array = field->getArrayNoGauss(); + + set undefIndices; // indices of undefined values + + // loop on subParts conatining ensight field values + list<_SubPartValues>::iterator subValue = subPartValues.begin(); + for ( ; subValue != subPartValues.end(); ++subValue ) + { + _SubPart & subPart = subValue->mySubPart; + int nbValues = entity==MED_NODE ? subPart.myNbNodes : subPart.myNbCells; + if ( nbValues == 0 ) + continue; + // value iterator for each component + vector< _ValueIterator > compValIt( nbComponents+1 ); + for ( j = 1; j <= nbComponents; ++j ) + compValIt[ j ] = subValue->template getValues( j, nbValues, nbComponents ); + + // Set values + + if ( entity == MED_NODE ) { + map< int, _noeud >::iterator inode = subPart.myFirstNode; + _setValuesToArray( compValIt, nbValues, array, inode, interSupport, + subValue->myUndefIndices, undefIndices ); + } + else { + _groupe::TMailleIter cell = subPart.myFirstCell; + _setValuesToArray( compValIt, nbValues, array, cell, interSupport, + subValue->myUndefIndices, undefIndices ); + } + } + + if ( !undefIndices.empty() ) + { + // Some values are undefined; it's necessary to compact values in the array + // and create a new support of defined numbers only. + + // shift values + int i, shitf = 1; + set::iterator undef = undefIndices.begin(); + while ( undef != undefIndices.end() ) { + i = *undef++; + int nextUndef = ( undef != undefIndices.end() ) ? *undef : nbElements + 1; + while ( ++i < nextUndef ) { + for ( int j = 1; j <= nbComponents; ++j ) + array->setIJ( i - shitf, j, array->getIJ( i, j )); // shift value + //number[ i-1 - shitf ] = oldNumber[ i-1 ]; // shift number + } + ++shitf; + } + array->_nbelem -= undefIndices.size(); + array->_arraySize = array->_nbelem * nbComponents; + + support = makeShiftedSupport( support, undefIndices ); + support->setName( STRING("Partial for ") << field->getName() ); + field->setSupport( support ); + field->setNumberOfValues( array->_nbelem ); + } + if ( support->getName().empty() ) + support->setName( STRING("Support for ") << field->getName() ); + } + + //======================================================================= + /*! + set values to a field + */ + void setValuesToField( FIELD_* field, + _Support* interSupport, + list<_SubPartValues> & subPartValues ) + { + switch ( field->getInterlacingType() ) { + case MED_FULL_INTERLACE: + if ( field->getValueType() == MED_REEL64 ) + _setValuesToField( static_cast< FIELD* >( field ), + interSupport, subPartValues ); + else + _setValuesToField( static_cast< FIELD* >( field ), + interSupport, subPartValues ); + break; + case MED_NO_INTERLACE: + if ( field->getValueType() == MED_REEL64 ) + _setValuesToField( static_cast< FIELD* >( field ), + interSupport, subPartValues ); + else + _setValuesToField( static_cast< FIELD* >( field ), + interSupport, subPartValues ); + break; + case MED_NO_INTERLACE_BY_TYPE: + if ( field->getValueType() == MED_REEL64 ) + _setValuesToField( static_cast< FIELD* >( field ), + interSupport, subPartValues ); + else + _setValuesToField( static_cast< FIELD* >( field ), + interSupport, subPartValues ); + break; + default:; + } + } + + + //================================================================================ + /*! + * \brief Return node numbers of a non-nodal support + */ + //================================================================================ + + int* getNodeNumbers( const SUPPORT* support, int & nbNodes ) + { + map nodeNumbers; + _CaseFileDriver_User::getSupportNodes( support, nodeNumbers ); + nbNodes = nodeNumbers.size(); + int* nNumbers = new int[ nbNodes ]; + int* nPtr = nNumbers; + map::iterator n = nodeNumbers.begin(), nEnd = nodeNumbers.end(); + while ( n != nEnd ) + *nPtr++ = n->first, n++; + + return nNumbers; + } + +} // namespace + +//======================================================================= +/*! + Constructor. +*/ +ENSIGHT_FIELD_DRIVER::ENSIGHT_FIELD_DRIVER(): + _CaseFileDriver_User(), + _ptrField((FIELD_ *) 0) +{} +//======================================================================= +/*! + Constructor. +*/ +ENSIGHT_FIELD_DRIVER::ENSIGHT_FIELD_DRIVER(const string & fileName, + FIELD_ * ptrField, + med_mode_acces accessMode): + _CaseFileDriver_User(fileName,accessMode), + _ptrField((FIELD_ *) ptrField) +{ +} +//======================================================================= +/*! + Copy constructor. +*/ +ENSIGHT_FIELD_DRIVER::ENSIGHT_FIELD_DRIVER(const ENSIGHT_FIELD_DRIVER & fieldDriver): + _CaseFileDriver_User(fieldDriver), + _ptrField(fieldDriver._ptrField), + _fieldName(fieldDriver._fieldName) +{ +} +//======================================================================= +/*! + Take missing data from other driver. +*/ +void ENSIGHT_FIELD_DRIVER::merge ( const GENDRIVER& driver ) +{ + _CaseFileDriver_User::merge( driver ); + + const ENSIGHT_FIELD_DRIVER* other = dynamic_cast< const ENSIGHT_FIELD_DRIVER* >( &driver ); + if ( other ) { + if ( !_ptrField ) + _ptrField = other->_ptrField; + if ( _constantValue.empty() ) + _constantValue = other->_constantValue; + // _fieldName is copied by GENDRIVER + } +} +//======================================================================= +/*! + Destructor. +*/ +ENSIGHT_FIELD_DRIVER::~ENSIGHT_FIELD_DRIVER() +{ +} +//======================================================================= +/*! + Set the name of the FIELD in EnSight file +*/ +void ENSIGHT_FIELD_DRIVER::setFieldName(const string & fieldName) throw (MEDEXCEPTION) +{ + const char* LOC = "ENSIGHT_FIELD_DRIVER::setFieldName(): "; + if ( fieldName.size() > MAX_FIELD_NAME_LENGTH ) + throw MEDEXCEPTION( compatibilityPb(LOC) << "too long name (> " << + MAX_FIELD_NAME_LENGTH << "): " << fieldName); + + // look for illegal characters + string::size_type pos = fieldName.find_first_of( ILLEGAL_FIELD_NAME_CHARACTERS ); + if ( pos != fieldName.npos ) + throw MEDEXCEPTION( compatibilityPb(LOC) << "Character " << pos << " (" << fieldName[pos] << + ") "<< " in " << fieldName << " is not allowed in field name in EnSight\n" + "The illegal characters are: '" << ILLEGAL_FIELD_NAME_CHARACTERS << "'"); + _fieldName = fieldName; +} +//======================================================================= +/*! + Check possibility to open a case file or a data file +*/ +void ENSIGHT_FIELD_DRIVER::openConst(bool checkDataFile) const throw (MEDEXCEPTION) +{ + const char * LOC ="ENSIGHT_FIELD_DRIVER::open() : "; + BEGIN_OF_MED(LOC); + + if ( checkDataFile ) + { + if ( !getConstantValue().empty() ) + return; // constant value is either stored in case file or is read by _CaseFileDriver + + if ( getDataFileName().empty() ) + throw MED_EXCEPTION + ( LOCALIZED( STRING(LOC) << "Internal error, variable file name is empty")); + + if (!canOpenFile( getDataFileName(), getAccessMode() )) + throw MED_EXCEPTION + ( LOCALIZED( STRING(LOC) << "Can not open Ensight Variable file " << getDataFileName() + << " in access mode " << getAccessMode())); + } + else + { + if ( getCaseFileName().empty() ) + throw MED_EXCEPTION + ( LOCALIZED( STRING(LOC) << "Case file name is empty, " + "please set a correct fileName before calling open()")); + + if ( !canOpenFile( getCaseFileName(), getAccessMode() )) + throw MED_EXCEPTION + ( LOCALIZED( STRING(LOC) << "Can not open Ensight Case file " << getCaseFileName() + << " in access mode " << getAccessMode())); + } + + END_OF_MED(LOC); +} +// ========================================================================================== +//function : ENSIGHT_FIELD_RDONLY_DRIVER + +ENSIGHT_FIELD_RDONLY_DRIVER::ENSIGHT_FIELD_RDONLY_DRIVER() + :ENSIGHT_FIELD_DRIVER(), _fieldStep(1) +{ +} + +//======================================================================= +/*! + Constructor to read a field of index-th time step +*/ +//======================================================================= + +ENSIGHT_FIELD_RDONLY_DRIVER::ENSIGHT_FIELD_RDONLY_DRIVER(const string & fileName, + FIELD_ * ptrField, + int step) + :ENSIGHT_FIELD_DRIVER(fileName,ptrField,MED_EN::RDONLY),_fieldStep(step) +{ +} + +//======================================================================= +//function : ENSIGHT_FIELD_RDONLY_DRIVER +//======================================================================= + +ENSIGHT_FIELD_RDONLY_DRIVER::ENSIGHT_FIELD_RDONLY_DRIVER(const ENSIGHT_FIELD_RDONLY_DRIVER & drv) + :ENSIGHT_FIELD_DRIVER(drv),_fieldStep(drv._fieldStep) +{ +} + +//======================================================================= +//function : ~ENSIGHT_FIELD_RDONLY_DRIVER +//======================================================================= + +ENSIGHT_FIELD_RDONLY_DRIVER::~ENSIGHT_FIELD_RDONLY_DRIVER() +{ + close(); +} + +//======================================================================= +//function : copy +//======================================================================= + +GENDRIVER * ENSIGHT_FIELD_RDONLY_DRIVER::copy(void) const +{ + ENSIGHT_FIELD_RDONLY_DRIVER * myDriver = new ENSIGHT_FIELD_RDONLY_DRIVER(*this); + + return myDriver ; +} +//======================================================================= +// Take missing data from other driver. +//======================================================================= + +void ENSIGHT_FIELD_RDONLY_DRIVER::merge ( const GENDRIVER& driver ) +{ + ENSIGHT_FIELD_DRIVER::merge( driver ); + + const ENSIGHT_FIELD_RDONLY_DRIVER* other = + dynamic_cast< const ENSIGHT_FIELD_RDONLY_DRIVER* >( &driver ); + if ( other ) { + if ( _fieldStep < other->_fieldStep ) + _fieldStep = other->_fieldStep; + } +} + +//======================================================================= +//function : read +//======================================================================= + +void ENSIGHT_FIELD_RDONLY_DRIVER::read (void) + throw (MEDEXCEPTION) +{ + const char * LOC = "ENSIGHT_FIELD_RDONLY_DRIVER::read() : " ; + BEGIN_OF_MED(LOC); + + openConst(false); // check if can read case file + + _CaseFileDriver caseFile( getCaseFileName(), this); + caseFile.read(); + + // find out index of variable to read + int variableIndex = caseFile.getVariableIndex( _fieldName ); + if ( !variableIndex ) + variableIndex = caseFile.getVariableIndex( _ptrField->getName() ); + if ( !variableIndex ) { + if ( !_fieldName.empty() ) + throw MEDEXCEPTION + (LOCALIZED(STRING(LOC) << "no field found by name |" << _fieldName << "|")); + else + throw MEDEXCEPTION + (LOCALIZED(STRING(LOC) << "no field found by name |" << _ptrField->getName() << "|")); + } + + // here data from Case File is passed: + // * field name + // * number of components + // * etc. + caseFile.setDataFileName( variableIndex, _fieldStep, this ); + + openConst(true); // check if can read data file + + getInterData(); // get data on nb of entities by type and on their relocation + + cout << "-> Entering into the field file " << getDataFileName() << endl ; + + if ( !getConstantValue().empty() ) + { + // Create a constant value field + + medEntityMesh entity = MED_CELL; + GROUP* support = new GROUP; + support->setName( string("SupportOnAll_")+entNames[entity]); + support->setMesh( getInterData()->_medMesh ); + support->setAll( true ); + support->setEntity( entity ); + support->update(); + + _groupe interGroup; + interGroup.medGroup = support; + _Support interSupport; + interSupport.setGroup( &interGroup ); + + list<_SubPartValues> subPartValues( 1 ); + subPartValues.back().myConstValue = getConstantValue(); + + setValuesToField( _ptrField, &interSupport, subPartValues ); + } + else + { + // Read values + + if ( isBinaryDataFile( getDataFileName() ) ) // binary + { + if ( isGoldFormat() ) // Gold + { + readGoldBinary(); + } + else // EnSight6 + { + read6Binary(); + } + } + else // ASCII + { + if ( isGoldFormat() ) // Gold + { + readGoldASCII(); + } + else // EnSight6 + { + read6ASCII(); + } + } + } +} + +//======================================================================= +/*! + Read Ensight Gold ASCII +*/ +//======================================================================= + +void ENSIGHT_FIELD_RDONLY_DRIVER::readGoldASCII () +{ + + // data that was set by CaseFile Driver + medEntityMesh entity = _ptrField->getSupport()->getEntity(); + + _SupportDesc supportDescriptor; + list<_SubPartValues> subPartValues; + + _ASCIIFileReader varFile( getDataFileName() ); + + if ( isSingleFileMode() ) { + int curTimeStep = 1; + while ( curTimeStep < getIndexInDataFile() ) { + while ( !varFile.isTimeStepEnd() ) + varFile.getLine(); + curTimeStep++; + } + while ( !varFile.isTimeStepBeginning() ) + varFile.getLine(); + } + string description = varFile.getLine(); // description line + _ptrField->setDescription( description ); + + int partNumber = 0; + _SubPartValues subValuesSample; // to keep interlace + subValuesSample.myInterlace = MED_NO_INTERLACE; + while ( !varFile.isTimeStepEnd() ) + { + string word, restLine, line = varFile.getLine(); + TStrTool::split( line, word, restLine ); + if ( word == "part" ) { + partNumber = varFile.getInt(); // part # + continue; + } + subPartValues.push_back( subValuesSample ); + _SubPartValues & subValues = subPartValues.back(); + + if ( restLine == "undef" ) + subValues.myUndefValue = varFile.getWord(); // undef + + if ( restLine == "partial" ) { + int nbPartial = varFile.getInt(); // ne + subValues.myPartialIndices.reserve( nbPartial ); + while ( nbPartial-- ) + subValues.myPartialIndices.push_back( varFile.getInt() ); // i_ne + } + _SubPartDesc desc( partNumber, word ); + subValues.mySubPart = *getSubPart( desc ); + readSubPartValues( varFile, _ptrField, subValues ); + supportDescriptor.insert( desc ); + } + + _Support* interSupport = getSupport( supportDescriptor, entity ); + setValuesToField( _ptrField, interSupport, subPartValues ); + +} + +//======================================================================= +/*! + Read Ensight GOLD binary +*/ +//======================================================================= + +void ENSIGHT_FIELD_RDONLY_DRIVER::readGoldBinary() +{ + + // data that was set by CaseFile Driver + medEntityMesh entity = _ptrField->getSupport()->getEntity(); + + _SupportDesc supportDescriptor; + list<_SubPartValues> subPartValues; + + _BinaryFileReader varFile( getDataFileName() ); + + // check if swapping bytes needed + try { + skipTimeStamp( varFile ); + } + catch (...) { + varFile.swapBytes(); + varFile.rewind(); + } + if ( getIndexInDataFile() <= 1 ) + varFile.rewind(); + + if ( isSingleFileMode() ) { + // one time step may be skipped by skipTimeStamp() + int curTimeStep = varFile.getPosition() ? 2 : 1 ; + while ( curTimeStep < getIndexInDataFile() ) { + skipTimeStamp( varFile ); + curTimeStep++; + } + varFile.skipTimeStepBeginning(); + } + TStrOwner description( varFile.getLine() ); // description line + _ptrField->setDescription( description.myValues ); + + int partNumber = 0; + _SubPartValues subValuesSample; // to keep interlace + subValuesSample.myInterlace = MED_NO_INTERLACE; + while ( !varFile.eof() ) + { + TStrOwner line( varFile.getLine() ); + if ( isTimeStepEnd( line.myValues )) + break; + string word, restLine; + TStrTool::split( line.myValues, word, restLine ); + if ( word == "part" ) { + partNumber = *TIntOwner( varFile.getInt(1)); // part # + continue; + } + subPartValues.push_back( subValuesSample ); + _SubPartValues & subValues = subPartValues.back(); + + if ( restLine == "undef" ) + subValues.myUndefValue = (STRING( *TFltOwner( varFile.getFlt(1) ))); // undef + + if ( restLine == "partial" ) { + int nbPartial = *TIntOwner( varFile.getInt(1) ); // ne + TIntOwner partial( varFile.getInt( nbPartial )); + subValues.myPartialIndices.assign( partial.myValues, + partial.myValues+nbPartial ); // i_ne + } + _SubPartDesc desc( partNumber, word ); + subValues.mySubPart = *getSubPart( desc ); + readSubPartValues( varFile, _ptrField, subValues ); + supportDescriptor.insert( desc ); + } + + _Support* interSupport = getSupport( supportDescriptor, entity ); + setValuesToField( _ptrField, interSupport, subPartValues ); + +} + +//======================================================================= +/*! + Read Ensight6 ASCII +*/ +//======================================================================= + +void ENSIGHT_FIELD_RDONLY_DRIVER::read6ASCII() +{ + + // data that was set by CaseFile Driver + medEntityMesh entity = _ptrField->getSupport()->getEntity(); + + _SupportDesc supportDescriptor; + list<_SubPartValues> subPartValues; + + _ASCIIFileReader varFile( getDataFileName() ); + + if ( isSingleFileMode() ) { + int curTimeStep = 1; + while ( curTimeStep < getIndexInDataFile() ) { + while ( !varFile.isTimeStepEnd() ) + varFile.getLine(); + curTimeStep++; + } + while ( !varFile.isTimeStepBeginning() ) + varFile.getLine(); + } + string description = varFile.getLine(); // description line + _ptrField->setDescription( description ); + + const _SubPart* subPart = 0; + if ( entity == MED_NODE ) // variable per node + { + _SubPartDesc desc = _SubPartDesc::globalCoordDesc(); + subPart = getSubPart( desc ); + if ( subPart ) { + supportDescriptor.insert( desc ); + _SubPartValues subValues( *subPart ); + subValues.myInterlace = MED_FULL_INTERLACE; + readSubPartValues( varFile, _ptrField, subValues ); + subPartValues.push_back( subValues ); + } + } + int partNumber = 0; + while ( !varFile.isTimeStepEnd() ) + { + string word = varFile.getWord(); + if ( word == "part" ) { + partNumber = varFile.getInt(); + continue; + } + _SubPartDesc desc( partNumber, word ); + supportDescriptor.insert( desc ); + subPart = getSubPart( desc ); + _SubPartValues subValues( *subPart ); + if ( desc.typeName() == "block" ) + subValues.myInterlace = MED_NO_INTERLACE; + else + subValues.myInterlace = MED_FULL_INTERLACE; + readSubPartValues( varFile, _ptrField, subValues ); + subPartValues.push_back( subValues ); + } + + _Support* interSupport = getSupport( supportDescriptor, entity ); + setValuesToField( _ptrField, interSupport, subPartValues ); + +} + +//======================================================================= +/*! + Read Ensight6 binary +*/ +//======================================================================= + +void ENSIGHT_FIELD_RDONLY_DRIVER::read6Binary() +{ + + // data that was set by CaseFile Driver + medEntityMesh entity = _ptrField->getSupport()->getEntity(); + + _SupportDesc supportDescriptor; + list<_SubPartValues> subPartValues; + const _SubPart* subPart = 0; + int partNumber = 0; + + _BinaryFileReader varFile( getDataFileName() ); + + // check if swapping bytes needed + try { + skipTimeStamp( varFile ); + } + catch (...) { + varFile.swapBytes(); + varFile.rewind(); + } + if ( getIndexInDataFile() <= 1 ) + varFile.rewind(); + + if ( isSingleFileMode() ) { + // one time step may be skipped by skipTimeStamp() + int curTimeStep = varFile.getPosition() ? 2 : 1 ; + while ( curTimeStep < getIndexInDataFile() ) { + skipTimeStamp( varFile ); + curTimeStep++; + } + varFile.skipTimeStepBeginning(); + } + + TStrOwner description( varFile.getLine() ); // description line + _ptrField->setDescription( description.myValues ); + + if ( entity == MED_NODE ) // global unstructured node values + { + _SubPartDesc desc = _SubPartDesc::globalCoordDesc(); + subPart = getSubPart( desc ); + if ( subPart ) { + supportDescriptor.insert( desc ); + _SubPartValues subValues( *subPart ); + subValues.myInterlace = MED_FULL_INTERLACE; + readSubPartValues( varFile, _ptrField, subValues ); + subPartValues.push_back( subValues ); + } + } + while ( !varFile.eof() ) + { + TStrOwner line( varFile.getLine() ); + if ( isTimeStepEnd( line )) + break; + string word, restLine; + TStrTool::split( line.myValues, word, restLine ); + if ( word == "part" ) { + partNumber = atoi( restLine.c_str() ); + continue; + } + _SubPartDesc desc( partNumber, word ); + supportDescriptor.insert( desc ); + subPart = getSubPart( desc ); + _SubPartValues subValues( *subPart ); + if ( desc.typeName() == "block" ) + subValues.myInterlace = MED_NO_INTERLACE; + else + subValues.myInterlace = MED_FULL_INTERLACE; + readSubPartValues( varFile, _ptrField, subValues ); + subPartValues.push_back( subValues ); + } + + _Support* interSupport = getSupport( supportDescriptor, entity ); + setValuesToField( _ptrField, interSupport, subPartValues ); + +} + +//================================================================================ +/*! + * \brief Looks for beginning of the next time stamp + */ +//================================================================================ + +void ENSIGHT_FIELD_RDONLY_DRIVER::skipTimeStamp(_BinaryFileReader& varFile) +{ + medEntityMesh entity = _ptrField->getSupport()->getEntity(); + int nbComponents = _ptrField->getNumberOfComponents(); + + if ( isSingleFileMode() ) + varFile.skipTimeStepBeginning(); + + varFile.skip( 80 ); // description + + _SubPart* subPart; + if ( entity == MED_NODE && !isGoldFormat() ) { // skip values on global nodes + subPart = getSubPart( _SubPartDesc::globalCoordDesc() ); + if ( subPart ) + varFile.skip( subPart->myNbNodes * nbComponents * sizeof(float) ); + } + int partNumber; + while ( !varFile.eof() ) + { + TStrOwner line( varFile.getLine() ); + if ( isTimeStepEnd( line )) + break; + + string word, restLine; + TStrTool::split( line.myValues, word, restLine ); + + if ( word == "part" ) { + if ( isGoldFormat() ) + partNumber = *TIntOwner( varFile.getInt(1)); + else + partNumber = atoi( restLine.c_str() ); + continue; + } + if ( restLine == "undef" ) { + varFile.skip( sizeof(int) ); + } + if ( restLine == "partial" ) { + int nbPartial = *TIntOwner( varFile.getInt(1)); // ne + varFile.skip( nbPartial * sizeof(int)); + } + + _SubPartDesc desc( partNumber, word ); + subPart = getSubPart( desc ); + int nbElems = ( entity == MED_NODE ) ? subPart->myNbNodes : subPart->myNbCells; + varFile.skip( nbElems * nbComponents * sizeof(float) ); + } +} + +//======================================================================= +//function : write +//======================================================================= + +void ENSIGHT_FIELD_RDONLY_DRIVER::write(void) const + throw (MEDEXCEPTION) +{ + throw MEDEXCEPTION("ENSIGHT_FIELD_RDONLY_DRIVER::write : Can't write with a RDONLY driver !"); +} + +//======================================================================= +//function : ENSIGHT_FIELD_WRONLY_DRIVER +//======================================================================= + +ENSIGHT_FIELD_WRONLY_DRIVER::ENSIGHT_FIELD_WRONLY_DRIVER() + :ENSIGHT_FIELD_DRIVER() +{ +} + +//======================================================================= +//function : ENSIGHT_FIELD_WRONLY_DRIVER +//======================================================================= + +ENSIGHT_FIELD_WRONLY_DRIVER::ENSIGHT_FIELD_WRONLY_DRIVER(const string & fileName, + FIELD_ * ptrField) + :ENSIGHT_FIELD_DRIVER(fileName,ptrField,MED_EN::WRONLY) +{ +} + +//======================================================================= +//function : ENSIGHT_FIELD_WRONLY_DRIVER +//======================================================================= + + +ENSIGHT_FIELD_WRONLY_DRIVER::ENSIGHT_FIELD_WRONLY_DRIVER(const ENSIGHT_FIELD_WRONLY_DRIVER & drv) + :ENSIGHT_FIELD_DRIVER(drv) +{ +} + +//======================================================================= +//function : ~ENSIGHT_FIELD_WRONLY_DRIVER +//======================================================================= + +ENSIGHT_FIELD_WRONLY_DRIVER::~ENSIGHT_FIELD_WRONLY_DRIVER() +{ + close(); +} + + +//======================================================================= +//function : copy +//======================================================================= + +GENDRIVER * ENSIGHT_FIELD_WRONLY_DRIVER::copy(void) const +{ + ENSIGHT_FIELD_WRONLY_DRIVER * myDriver = new ENSIGHT_FIELD_WRONLY_DRIVER(*this); + + return myDriver ; +} + +//======================================================================= +//function : read +//======================================================================= + +void ENSIGHT_FIELD_WRONLY_DRIVER::read (void) + throw (MEDEXCEPTION) +{ + throw MEDEXCEPTION("ENSIGHT_FIELD_WRONLY_DRIVER::read : Can't read with a write only!"); +} + +//================================================================================ +/*! + * \brief Return pointer to the value of the i-th element + */ +//================================================================================ + +const char* getValuePointer( int i, const FIELD_* field ) +{ + switch ( field->getInterlacingType() ) { + case MED_FULL_INTERLACE: + if ( field->getValueType() == MED_REEL64 ) + return (const char*) & static_cast* > + ( field )->getArrayNoGauss()->getIJ( i, 1 ); + else + return (const char*) & static_cast* > + ( field )->getArrayNoGauss()->getIJ( i, 1 ); + case MED_NO_INTERLACE: + if ( field->getValueType() == MED_REEL64 ) + return (const char*) & static_cast* > + ( field )->getArrayNoGauss()->getIJ( i, 1 ); + else + return (const char*) & static_cast* > + ( field )->getArrayNoGauss()->getIJ( i, 1 ); + case MED_NO_INTERLACE_BY_TYPE: + if ( field->getValueType() == MED_REEL64 ) + return (const char*) & static_cast* > + ( field )->getArrayNoGauss()->getIJ( i, 1 ); + else + return (const char*) & static_cast* > + ( field )->getArrayNoGauss()->getIJ( i, 1 ); + default:; + } + return 0; +} + +//======================================================================= +/*! + * \brief Write field values in EnSight6 ASCII format +*/ +//======================================================================= + +template< typename T > +void write6ASCIIValues( const _SubPartValues& subPartValues, + int nbValues, + int nbComponents, + int componentShift, + ofstream & ensightDataFile ) +{ + // add the 3-d component to a vector in 2D space + const bool add3dComp = true; + int mypoint=0; + if ( subPartValues.myNumbers ) + { + vector< _SelectedValueIterator > compValIt = + subPartValues.template getAllSelectedValues( componentShift, nbComponents, add3dComp ); + nbComponents = compValIt.size(); + // in full interlace + for (int i=0; i > compValIt = + subPartValues.template getAllValues( componentShift, nbComponents, add3dComp ); + nbComponents = compValIt.size(); + // in full interlace + for (int i=0; i +void writeGoldASCIIValues( const _SubPartValues& subPartValues, + int nbValues, + int nbComponents, + int componentShift, + ofstream & ensightDataFile ) +{ + // in no-interlace + for(int j=1; j<=nbComponents; j++) { + if ( subPartValues.myNumbers ) + { + _SelectedValueIterator values + = subPartValues.template getSelectedValues( j, componentShift, nbComponents ); + for (int i=0; i values + = subPartValues.template getValues( j, componentShift, nbComponents ); + for (int i=0; i +void write6BinaryValues( const _SubPartValues& subPartValues, + int nbValues, + int nbComponents, + int componentShift, + _BinaryFileWriter & ensightDataFile ) +{ + const bool add3dComp = true; + if ( subPartValues.myNumbers ) + { + vector< _SelectedValueIterator > compValIt = + subPartValues.template getAllSelectedValues( componentShift, nbComponents, add3dComp ); + ensightDataFile.addReal( compValIt, nbValues, MED_FULL_INTERLACE ); + } + else + { + vector< _ValueIterator > compValIt = + subPartValues.template getAllValues( componentShift, nbComponents, add3dComp ); + ensightDataFile.addReal( compValIt, nbValues, MED_FULL_INTERLACE ); + } +} + +//======================================================================= +/*! + * \brief Write field values in EnSight GOLD Binary format +*/ +//======================================================================= + +template< typename T > +void writeGoldBinaryValues( const _SubPartValues& subPartValues, + int nbValues, + int nbComponents, + int componentShift, + _BinaryFileWriter & ensightDataFile ) +{ + const bool add3dComp = false; + if ( subPartValues.myNumbers ) + { + vector< _SelectedValueIterator > compValIt = + subPartValues.template getAllSelectedValues( componentShift, nbComponents, add3dComp ); + ensightDataFile.addReal( compValIt, nbValues, MED_NO_INTERLACE ); + } + else + { + vector< _ValueIterator > compValIt = + subPartValues.template getAllValues( componentShift, nbComponents, add3dComp ); + ensightDataFile.addReal( compValIt, nbValues, MED_NO_INTERLACE ); + } + // add the 3-d component to a vector in 2D space + if ( nbComponents == 2 ) { + vector values( nbValues, 0. ); + ensightDataFile.addReal( & values[0], nbValues ); + } +} + +//======================================================================= +//function : write +//======================================================================= + +void ENSIGHT_FIELD_WRONLY_DRIVER::write(void) const + throw (MEDEXCEPTION) +{ + const char * LOC = "ENSIGHT_FIELD_WRONLY_DRIVER::write(void) const " ; + BEGIN_OF_MED(LOC); + + openConst(false) ; // check if can write to case file + + // Ensight case organization requires a main file (filename.case) which defines organization + + _CaseFileDriver caseFile( getCaseFileName(), this); + caseFile.read(); + caseFile.addField( this ); + caseFile.write(); // all fields of _CaseFileDriver_User are set by this method + + openConst(true) ; // check if can write to data file + + const FIELD_* field = _ptrField; + const SUPPORT * support = field->getSupport(); + const MESH * mesh = support->getMesh(); + + int dt = field->getIterationNumber(); + int it = field->getOrderNumber(); + int nbComponents = field->getNumberOfComponents(); + med_type_champ type = field->getValueType() ; + + medEntityMesh entity = support->getEntity(); + int totalNbValues = support->getNumberOfElements(MED_ALL_ELEMENTS); + //const int* mainNbValsByType = support->getNumberOfElements(); + + int nbValuesByType = 0; + int& componentShift = (type == MED_NO_INTERLACE_BY_TYPE) ? nbValuesByType : totalNbValues; + + bool isOnAll = support->isOnAllElements(); + if (!isOnAll && !mesh) + throw MED_EXCEPTION(STRING("Can't write field ") << field->getName() << + ", which is not on all elements while mesh is not set to its support"); + if (!isOnAll) + isOnAll = ( mesh->getNumberOfElements(entity,MED_ALL_ELEMENTS) == componentShift ); + if (!isOnAll && entity == MED_NODE && !isGoldFormat() ) { + throw MED_EXCEPTION(compatibilityPb("Can't write field ") << field->getName() << + " which is not on all nodes of the mesh in EnSight6 format," + " use EnSight Gold format instead"); + } + if ( entity == MED_EDGE && mesh && !isToWriteEntity( MED_EDGE, mesh )) + throw MED_EXCEPTION(STRING(LOC) << "Can't write field " << field->getName() + << ", fields on MED_EDGE in volumic mesh are not supported"); + + // part number + int partNum = getPartNumber( support ); + string isPartial = ""; + if ( !partNum ) { + if ( !isGoldFormat() ) + throw MED_EXCEPTION(STRING("Can't write field ") << field->getName() + << " in EnSight6 format, it's support " << support->getName() + << " is not stored in geo file, use EnSight Gold format instead"); + isPartial = " partial"; + SUPPORT tmpSupport; + tmpSupport.setAll(true); + tmpSupport.setEntity( entity ); + partNum = getPartNumber( &tmpSupport ); + } + + // supports to write the field for + map< int, const SUPPORT* > parts; + map< int, const SUPPORT* >::iterator partNumIt; + parts[ partNum ] = support; + + // In Ensight 6, nodal field is visible on all parts as nodes are global, for + // the rest cases we write field for all groups in order to see values on them + if ( isOnAll && ( isGoldFormat() || entity != MED_NODE ) && mesh ) + { + // In Ensight Gold, to see nodal field on all groups we write them all + int ent = entity, toEntity = entity + 1; + if ( isGoldFormat() && entity == MED_NODE ) + ent = MED_CELL, toEntity = MED_ALL_ENTITIES; + + for ( ; ent < toEntity; ++ent ) { + int nbGroups = mesh->getNumberOfGroups(ent); + for ( int i=1; i<=nbGroups; i++) { + const GROUP* group = mesh->getGroup( ent, i ); + if ( group != support && !group->isOnAllElements() ) { + partNum = getPartNumber( group ); + if ( partNum ) + parts.insert( make_pair( partNum, group )); + } + } + } + } + + // description + string description = field->getDescription(); + if ( description.empty() ) + description = STRING(field->getName()) << " dt=" << dt << " it=" << it; + + cout << "-> Creating the Ensight data file " << getDataFileName() << endl ; + + + _SubPartValues geoTypeValues; + geoTypeValues.myOwnValues = false; + geoTypeValues.myInterlace = field->getInterlacingType(); + int nbWrittenValues = 0; + + if ( isBinaryEnSightFormatForWriting() ) + { + // ====================================================== + // Binary + // ====================================================== + + // function to write values + typedef void (* TWriteValues) (const _SubPartValues& , int, int, int, _BinaryFileWriter &); + TWriteValues writeValues; + if ( isGoldFormat() ) { + if ( type == MED_REEL64 ) writeValues = writeGoldBinaryValues; + else if ( type == MED_INT32 ) writeValues = writeGoldBinaryValues; + else writeValues = writeGoldBinaryValues; + } + else { + if ( type == MED_REEL64 ) writeValues = write6BinaryValues; + else if ( type == MED_INT32 ) writeValues = write6BinaryValues; + else writeValues = write6BinaryValues; + } + _BinaryFileWriter ensightDataFile( getDataFileName() ); + + // description + ensightDataFile.addString( description ); + + for ( partNumIt = parts.begin(); partNumIt != parts.end(); ++partNumIt) + { + const SUPPORT* partSup = partNumIt->second; + partNum = partNumIt->first; + const bool otherEntity = ( entity != partSup->getEntity() ); // Gold, nodal field + nbWrittenValues = 0; + + // part number + if ( isGoldFormat() ) { + ensightDataFile.addString("part"); + ensightDataFile.addInt( partNum ); + } + else if ( entity != MED_NODE ) { + ensightDataFile.addString( STRING("part ") << partNum ); + } + // loop on types + int nbTypes = partSup->getNumberOfTypes(); + const medGeometryElement* geoType = partSup->getTypes(); + for (int i=0; igetNumberOfElements(medType); + + // type name + if ( entity != MED_NODE ) { + const TEnSightElemType& ensightType = getEnSightType(medType); + ensightDataFile.addString( ensightType._name + isPartial ); + } + else if ( isGoldFormat() ) { + ensightDataFile.addString( "coordinates" + isPartial ); + } + + // supporting numbers (Gold only) + if ( !isPartial.empty() ) { + const int *number = partSup->getNumber(medType); + ensightDataFile.addInt( nbValuesByType ); + ensightDataFile.addInt( number, nbValuesByType ); + } + + // get field values + if ( otherEntity ) { // Gold, nodal field, non-nodal group (partSup) + if ( isOnAll && partSup->isOnAllElements() ) { + geoTypeValues.myNumbers = 0; + geoTypeValues.myValues = getValuePointer( 1, field ); + nbValuesByType = totalNbValues; + } + else { + geoTypeValues.myNumbers = getNodeNumbers( partSup, nbValuesByType ); + geoTypeValues.myValues = getValuePointer( geoTypeValues.myNumbers[0], field ); + } + } + else if ( partSup->getNumberOfElements(MED_ALL_ELEMENTS) != totalNbValues ) { + geoTypeValues.myNumbers = partSup->getNumber(medType); + geoTypeValues.myValues = getValuePointer( geoTypeValues.myNumbers[0], field ); + } + else { + geoTypeValues.myNumbers = 0; + geoTypeValues.myValues = getValuePointer( nbWrittenValues + 1, field ); + } + // write values + writeValues(geoTypeValues, nbValuesByType, nbComponents, componentShift, ensightDataFile); + nbWrittenValues += nbValuesByType; + + if ( otherEntity ) { + if ( geoTypeValues.myNumbers ) delete [] geoTypeValues.myNumbers; + break; // all nodal values are written at once + } + } + } + } + else + { + // ====================================================== + // ASCII + // ====================================================== + + // function to write values + typedef void (* TWriteValues) (const _SubPartValues& , int, int, int, ofstream &); + TWriteValues writeValues; + if ( isGoldFormat() ) { + if ( type == MED_REEL64 ) writeValues = writeGoldASCIIValues; + else if ( type == MED_INT32 ) writeValues = writeGoldASCIIValues; + else writeValues = writeGoldASCIIValues; + } + else { + if ( type == MED_REEL64 ) writeValues = write6ASCIIValues; + else if ( type == MED_INT32 ) writeValues = write6ASCIIValues; + else writeValues = write6ASCIIValues; + } + const int iw = isGoldFormat() ? 10 : 8; // width of integer + + ofstream ensightDataFile( getDataFileName().c_str(), ios::out); + ensightDataFile.setf(ios::scientific); + ensightDataFile.precision(5); + + // description + ensightDataFile << description << endl; + + for ( partNumIt = parts.begin(); partNumIt != parts.end(); ++partNumIt) + { + const SUPPORT* partSup = partNumIt->second; + partNum = partNumIt->first; + const bool otherEntity = ( entity != partSup->getEntity() ); // Gold, nodal field + nbWrittenValues = 0; + + // part number + if ( isGoldFormat() ) + ensightDataFile << "part" << endl << setw(iw) << partNum << endl; + else if ( entity != MED_NODE ) { + ensightDataFile << "part " << partNum << endl; + } + // loop on types + int nbTypes = partSup->getNumberOfTypes(); + const medGeometryElement* geoType = partSup->getTypes(); + for (int i=0; igetNumberOfElements(medType); + + // type name + if ( entity != MED_NODE ) { + const TEnSightElemType& ensightType = getEnSightType(medType); + ensightDataFile << ensightType._name << isPartial << endl; + } + else if ( isGoldFormat() ) { + ensightDataFile << "coordinates" << isPartial << endl; + } + + // supporting numbers (Gold only) + if ( !isPartial.empty() ) { + const int *number = partSup->getNumber(medType); + const int *nEnd = number + nbValuesByType; + ensightDataFile << setw(iw) << nbValuesByType << endl; + while ( number < nEnd ) + ensightDataFile << setw(iw) << *number++ << endl; + } + + // get field values + if ( otherEntity ) { // Gold, nodal field, non-nodal group (partSup) + if ( isOnAll && partSup->isOnAllElements() ) { + geoTypeValues.myNumbers = 0; + geoTypeValues.myValues = getValuePointer( 1, field ); + nbValuesByType = totalNbValues; + } + else { + geoTypeValues.myNumbers = getNodeNumbers( partSup, nbValuesByType ); + geoTypeValues.myValues = getValuePointer( geoTypeValues.myNumbers[0], field ); + } + } + else if ( partSup->getNumberOfElements(MED_ALL_ELEMENTS) != totalNbValues ) { + geoTypeValues.myNumbers = partSup->getNumber(medType); + geoTypeValues.myValues = getValuePointer( geoTypeValues.myNumbers[0], field ); + } + else { + geoTypeValues.myNumbers = 0; + geoTypeValues.myValues = getValuePointer( nbWrittenValues + 1, field ); + } + + // write values + writeValues(geoTypeValues, nbValuesByType, nbComponents, componentShift, ensightDataFile); + nbWrittenValues += nbValuesByType; + + if ( otherEntity ) { + if ( geoTypeValues.myNumbers ) delete [] geoTypeValues.myNumbers; + break; // all nodal values are written at once + } + } + } // loop on supports + + ensightDataFile.close(); + } +} diff --git a/src/MEDMEM/MEDMEM_EnsightFieldDriver.hxx b/src/MEDMEM/MEDMEM_EnsightFieldDriver.hxx index e23c6aac3..8bfe16de4 100644 --- a/src/MEDMEM/MEDMEM_EnsightFieldDriver.hxx +++ b/src/MEDMEM/MEDMEM_EnsightFieldDriver.hxx @@ -1,907 +1,160 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef ENSIGHT_FIELD_DRIVER_HXX #define ENSIGHT_FIELD_DRIVER_HXX #include -#include -#include -#include - -#include "MEDMEM_define.hxx" - -#include "MEDMEM_GenDriver.hxx" -#include "MEDMEM_Utilities.hxx" - -#include "MEDMEM_ArrayInterface.hxx" - -#include "MEDMEM_STRING.hxx" -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_Unit.hxx" -#include "MEDMEM_nArray.hxx" -#include "MEDMEM_ArrayConvert.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_CellModel.hxx" +#include "MEDMEM_EnsightUtils.hxx" +// ========================================================================================== /*! - Driver Ensight for FIELD. - - Generic part : implement open and close methods. - */ +// ========================================================================================== namespace MEDMEM { -template class ENSIGHT_FIELD_DRIVER : public GENDRIVER +class MEDMEM_EXPORT ENSIGHT_FIELD_DRIVER : public MEDMEM_ENSIGHT::_CaseFileDriver_User { protected: - FIELD * _ptrField; - string _fieldName; - int _fieldNum; - -public : - - /*! - Constructor. - */ - ENSIGHT_FIELD_DRIVER():GENDRIVER(), - _ptrField((FIELD *) 0), _fieldName(""), - _fieldNum(MED_INVALID) - {} - /*! - Constructor. - */ - template - ENSIGHT_FIELD_DRIVER(const string & fileName, - FIELD * ptrField, - MED_EN::med_mode_acces accessMode): - GENDRIVER(fileName,accessMode), - _ptrField((FIELD *) ptrField), - _fieldNum(MED_INVALID) - { - _fieldName = ptrField->getName(); - } - - /*! - Copy constructor. - */ - ENSIGHT_FIELD_DRIVER(const ENSIGHT_FIELD_DRIVER & fieldDriver): - GENDRIVER(fieldDriver), - _ptrField(fieldDriver._ptrField), - _fieldName(fieldDriver._fieldName), - _fieldNum(fieldDriver._fieldNum) - { - } - - /*! - Destructor. - */ - virtual ~ENSIGHT_FIELD_DRIVER() - { - } - virtual void open() throw (MEDEXCEPTION) = 0; - virtual void close() =0; - virtual void write( void ) const = 0 ; - virtual void read ( void ) = 0 ; - - /*! - Set the name of the FIELD asked in file. - - It could be different than the name of the FIELD object. - */ - virtual void setFieldName(const string & fieldName) { _fieldName = fieldName; } - /*! - Get the name of the FIELD asked in file. - */ - virtual string getFieldName() const { return _fieldName; } -protected: - virtual GENDRIVER * copy ( void ) const = 0 ; - -}; - + FIELD_ * _ptrField; + std::string _fieldName; + std::string _constantValue; - -template class ENSIGHT_FIELD_RDONLY_DRIVER : public ENSIGHT_FIELD_DRIVER -{ + void openConst(bool checkDataFile=false) const throw (MEDEXCEPTION); public : - - /*! - Constructor. - */ - ENSIGHT_FIELD_RDONLY_DRIVER():ENSIGHT_FIELD_DRIVER() - { - const char * LOC = "ENSIGHT_FIELD_RDONLY_DRIVER::ENSIGHT_FIELD_RDONLY_DRIVER() "; - BEGIN_OF(LOC); - _ensightFile = new ifstream(); - - END_OF(LOC); - } /*! Constructor. */ - template - ENSIGHT_FIELD_RDONLY_DRIVER(const string & fileName, - FIELD * ptrField):ENSIGHT_FIELD_DRIVER(fileName,ptrField,MED_EN::MED_RDONLY) - { - const char * LOC = "ENSIGHT_FIELD_RDONLY_DRIVER::ENSIGHT_FIELD_RDONLY_DRIVER(const string & fileName, FIELD * ptrField) "; - BEGIN_OF(LOC); - _ensightFile = new ifstream(); - - END_OF(LOC); - } - + ENSIGHT_FIELD_DRIVER(); + ENSIGHT_FIELD_DRIVER(const std::string & fileName, + FIELD_ * ptrField, + MED_EN::med_mode_acces accessMode); /*! Copy constructor. */ - ENSIGHT_FIELD_RDONLY_DRIVER(const ENSIGHT_FIELD_RDONLY_DRIVER & fieldDriver):ENSIGHT_FIELD_DRIVER(fieldDriver) - { - _ensightFile = new ifstream(); - } - + ENSIGHT_FIELD_DRIVER(const ENSIGHT_FIELD_DRIVER & fieldDriver); + virtual void merge ( const GENDRIVER& driver ); /*! Destructor. */ - ~ENSIGHT_FIELD_RDONLY_DRIVER() - { - const char * LOC ="ENSIGHT_FIELD_RDONLY_DRIVER::~ENSIGHT_FIELD_RDONLY_DRIVER()"; - BEGIN_OF(LOC); - - close(); - - SCRUTE(_ensightFile); - - delete _ensightFile ; - - SCRUTE(_ensightFile); - - END_OF(LOC); - } - - void openConst() const throw (MEDEXCEPTION) - { - const char * LOC = "ENSIGHT_FIELD_RDONLY_DRIVER::openConst()" ; - BEGIN_OF(LOC); - - MESSAGE(LOC<<" : _fileName.c_str : "<< ENSIGHT_FIELD_DRIVER::_fileName.c_str()<<",mode : "<< ENSIGHT_FIELD_DRIVER::_accessMode); - - if ( ENSIGHT_FIELD_DRIVER::_fileName == "" ) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) - << "_fileName is |\"\"|, please set a correct fileName before calling open()" - ) - ); - - if (!(*_ensightFile).is_open()) - (*_ensightFile).open(ENSIGHT_FIELD_DRIVER::_fileName.c_str()) ; - - SCRUTE((*_ensightFile).is_open()); - SCRUTE(_ensightFile); - - if (!(*_ensightFile)) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file " - << ENSIGHT_FIELD_DRIVER::_fileName) - ); -// _ensightFile.setf(ios::scientific); -// _ensightFile.precision(5); - END_OF(LOC); - } - - void openConstAppend() const throw (MEDEXCEPTION) - { - const char * LOC = "ENSIGHT_FIELD_DRIVER::openConstAppend()" ; - BEGIN_OF(LOC); - - MESSAGE(LOC<<" : _fileName.c_str : "<< ENSIGHT_FIELD_DRIVER::_fileName.c_str()<<",mode : "<< ENSIGHT_FIELD_DRIVER::_accessMode); - - if ( ENSIGHT_FIELD_DRIVER::_fileName == "" ) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) - << "_fileName is |\"\"|, please set a correct fileName before calling open()" - ) - ); - - SCRUTE((*_ensightFile).is_open()); - - if (!(*_ensightFile).is_open()) - { - MESSAGE(LOC<<"The file is already close and it is opened with the right option"); - (*_ensightFile).open(ENSIGHT_FIELD_DRIVER::_fileName.c_str(), ofstream::out | ofstream::app) ; - } - else - { - MESSAGE(LOC<<"The file is still open, it is closed to make sure that it will be opened with the right option"); - - (*_ensightFile).close() ; - - _ensightFile->open(ENSIGHT_FIELD_DRIVER::_fileName.c_str(), ofstream::out | ofstream::app) ; - } - - SCRUTE((*_ensightFile).is_open()); - SCRUTE(_ensightFile); - - if (!(*_ensightFile)) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file " - << ENSIGHT_FIELD_DRIVER::_fileName) - ); -// _ensightFile.setf(ios::scientific); -// _ensightFile.precision(5); - END_OF(LOC); - } - - void open() throw (MEDEXCEPTION) - { - openConst() ; - } - - void openAppend() throw (MEDEXCEPTION) - { - openConstAppend() ; - } - - void closeConst() const throw (MEDEXCEPTION) - { - const char * LOC = "ENSIGHT_FIELD_DRIVER::closeConst() " ; - BEGIN_OF(LOC); - - SCRUTE(_ensightFile); - SCRUTE(*_ensightFile); - - - if ((*_ensightFile).is_open()) - (*_ensightFile).close(); - - SCRUTE(_ensightFile); - SCRUTE(*_ensightFile); - - if (!(*_ensightFile)) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not close file " - << ENSIGHT_FIELD_DRIVER::_fileName) - ); - - END_OF(LOC); - } - - void close() { - closeConst() ; - } + virtual ~ENSIGHT_FIELD_DRIVER(); /*! - Set the name of the FIELD asked in file. + Set the name of the FIELD in EnSight file. It could be different than the name of the FIELD object. */ - void setFieldName(const string & fieldName) ; + virtual void setFieldName(const std::string & fieldName) throw (MEDEXCEPTION); /*! - Get the name of the FIELD asked in file. + Get the name of the FIELD in EnSight file. */ - string getFieldName() const ; + virtual std::string getFieldName() const { return _fieldName; } - /*! - Return a MEDEXCEPTION : it is the write-only driver. - */ - void read ( void ) throw (MEDEXCEPTION) ; + virtual void open() throw (MEDEXCEPTION) { openConst(); } - /*! - Write FIELD in the specified file, with its mesh through its support - which has to be on all entities (excluding the faces in 3d and edges - in 2d). - */ - void write( void ) const throw (MEDEXCEPTION) ; + virtual void close() {} - /*! - Write FIELD in the specified file, the mesh is supposed to be - written in this file. The field support has to be on all entities - (excluding the faces in 3d and edges in 2d). - */ - void writeAppend( void ) const throw (MEDEXCEPTION); + FIELD_* getField() { return _ptrField; } -private: - ifstream * _ensightFile; // The main _ensightFile used to read - GENDRIVER * copy ( void ) const ; + void setConstantValue(const std::string& value) { _constantValue = value; } + + const std::string& getConstantValue() const { return _constantValue; } }; -template class ENSIGHT_FIELD_WRONLY_DRIVER : public ENSIGHT_FIELD_DRIVER -{ +// ========================================================================================== +class MEDMEM_EXPORT ENSIGHT_FIELD_RDONLY_DRIVER : public ENSIGHT_FIELD_DRIVER +{ public : /*! - Constructor. + Constructor to read the field of a specified name and index-th time step. + Append "_Im" to field name to select an imaginary part of a complex field */ - ENSIGHT_FIELD_WRONLY_DRIVER():ENSIGHT_FIELD_DRIVER() - { - const char * LOC = "ENSIGHT_FIELD_WRONLY_DRIVER::ENSIGHT_FIELD_WRONLY_DRIVER() "; - BEGIN_OF(LOC); - - _ensightFile = new ifstream(); + ENSIGHT_FIELD_RDONLY_DRIVER(const string & fileName, FIELD_ * ptrField, int step=1); - END_OF(LOC); - } - /*! - Constructor. - */ - template - ENSIGHT_FIELD_WRONLY_DRIVER(const string & fileName, - FIELD * ptrField): - ENSIGHT_FIELD_DRIVER(fileName,ptrField,MED_EN::MED_WRONLY) - { - const char * LOC = "ENSIGHT_FIELD_WRONLY_DRIVER::ENSIGHT_FIELD_WRONLY_DRIVER(const string & fileName, FIELD * ptrField) "; - BEGIN_OF(LOC); - _ensightFile = new ifstream(); - - END_OF(LOC); - } + ENSIGHT_FIELD_RDONLY_DRIVER(); + ENSIGHT_FIELD_RDONLY_DRIVER(const ENSIGHT_FIELD_RDONLY_DRIVER & fieldDriver); + ~ENSIGHT_FIELD_RDONLY_DRIVER(); + virtual GENDRIVER * copy ( void ) const ; + virtual void merge ( const GENDRIVER& driver ); /*! - Copy constructor. + Read a field */ - ENSIGHT_FIELD_WRONLY_DRIVER(const ENSIGHT_FIELD_WRONLY_DRIVER & fieldDriver):ENSIGHT_FIELD_DRIVER(fieldDriver) - { - _ensightFile = new ifstream(); - } + void read ( void ) throw (MEDEXCEPTION); /*! - Destructor. + Return a MEDEXCEPTION : it is a read-only driver. */ - ~ENSIGHT_FIELD_WRONLY_DRIVER() - { - const char * LOC ="ENSIGHT_FIELD_WRONLY_DRIVER::~ENSIGHT_FIELD_WRONLY_DRIVER()"; - BEGIN_OF(LOC); - - close(); - - SCRUTE(_ensightFile); - - delete _ensightFile ; - - SCRUTE(_ensightFile); - - END_OF(LOC); - } - - void openConst() const throw (MEDEXCEPTION) - { - const char * LOC = "ENSIGHT_FIELD_WRONLY_DRIVER::openConst()" ; - BEGIN_OF(LOC); - - MESSAGE(LOC<<" : _fileName.c_str : "<< ENSIGHT_FIELD_DRIVER::_fileName.c_str()<<",mode : "<< ENSIGHT_FIELD_DRIVER::_accessMode); - - if ( ENSIGHT_FIELD_DRIVER::_fileName == "" ) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) - << "_fileName is |\"\"|, please set a correct fileName before calling open()" - ) - ); - - if (!(*_ensightFile).is_open()) - (*_ensightFile).open(ENSIGHT_FIELD_DRIVER::_fileName.c_str()) ; - - SCRUTE((*_ensightFile).is_open()); - SCRUTE(_ensightFile); - - if (!(*_ensightFile)) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file " - << ENSIGHT_FIELD_DRIVER::_fileName) - ); -// _ensightFile.setf(ios::scientific); -// _ensightFile.precision(5); - END_OF(LOC); - } - - void openConstAppend() const throw (MEDEXCEPTION) - { - const char * LOC = "ENSIGHT_FIELD_WRONLY_DRIVER::openConstAppend()" ; - BEGIN_OF(LOC); - - MESSAGE(LOC<<" : _fileName.c_str : "<< ENSIGHT_FIELD_DRIVER::_fileName.c_str()<<",mode : "<< ENSIGHT_FIELD_DRIVER::_accessMode); - - if ( ENSIGHT_FIELD_DRIVER::_fileName == "" ) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) - << "_fileName is |\"\"|, please set a correct fileName before calling open()" - ) - ); - - SCRUTE((*_ensightFile).is_open()); - - if (!(*_ensightFile).is_open()) - { - MESSAGE(LOC<<"The file is already close and it is opened with the right option"); - (*_ensightFile).open(ENSIGHT_FIELD_DRIVER::_fileName.c_str(), ofstream::out | ofstream::app) ; - } - else - { - MESSAGE(LOC<<"The file is still open, it is closed to make sure that it will be opened with the right option"); - - (*_ensightFile).close() ; - - _ensightFile->open(ENSIGHT_FIELD_DRIVER::_fileName.c_str(), ofstream::out | ofstream::app) ; - } - - SCRUTE((*_ensightFile).is_open()); - SCRUTE(_ensightFile); - - if (!(*_ensightFile)) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file " - << ENSIGHT_FIELD_DRIVER::_fileName) - ); -// _ensightFile.setf(ios::scientific); -// _ensightFile.precision(5); - END_OF(LOC); - } + void write( void ) const throw (MEDEXCEPTION) ; - void open() throw (MEDEXCEPTION) - { - openConst() ; - } +private: - void openAppend() throw (MEDEXCEPTION) - { - openConstAppend() ; - } + void readGoldASCII (); + void readGoldBinary(); + void read6ASCII (); + void read6Binary (); - void closeConst() const throw (MEDEXCEPTION) - { - const char * LOC = "ENSIGHT_FIELD_WRONLY_DRIVER::closeConst() " ; - BEGIN_OF(LOC); + void skipTimeStamp(MEDMEM_ENSIGHT::_BinaryFileReader& fileReader); - SCRUTE(_ensightFile); - SCRUTE(*_ensightFile); + int _fieldStep; +}; +// ========================================================================================== - if ((*_ensightFile).is_open()) - (*_ensightFile).close(); +class MEDMEM_EXPORT ENSIGHT_FIELD_WRONLY_DRIVER : public ENSIGHT_FIELD_DRIVER +{ +public : - SCRUTE(_ensightFile); - SCRUTE(*_ensightFile); - - if (!(*_ensightFile)) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not close file " - << ENSIGHT_FIELD_DRIVER::_fileName) - ); - - END_OF(LOC); - } - - void close() { - closeConst() ; - } - /*! - Set the name of the FIELD asked in file. - - It could be different than the name of the FIELD object. + Constructor to append a field to the file */ - void setFieldName(const string & fieldName) ; + ENSIGHT_FIELD_WRONLY_DRIVER(const string & fileName, FIELD_ * ptrField); - /*! - Get the name of the FIELD asked in file. - */ - string getFieldName() const ; + ENSIGHT_FIELD_WRONLY_DRIVER(); + ENSIGHT_FIELD_WRONLY_DRIVER(const ENSIGHT_FIELD_WRONLY_DRIVER & fieldDriver); + ~ENSIGHT_FIELD_WRONLY_DRIVER(); + GENDRIVER * copy ( void ) const ; /*! Return a MEDEXCEPTION : it is the write-only driver. */ void read ( void ) throw (MEDEXCEPTION) ; - /*! - Write FIELD in the specified file, with its mesh through its support - which has to be on all entities (excluding the faces in 3d and edges - in 2d). - */ - void write( void ) const throw (MEDEXCEPTION) ; - /*! Write FIELD in the specified file, the mesh is supposed to be - written in this file. The field support has to be on all entities - (excluding the faces in 3d and edges in 2d). + written in this file */ - void writeAppend( void ) const throw (MEDEXCEPTION); - -private: - ifstream * _ensightFile; // The main _ensightFile used to read - GENDRIVER * copy ( void ) const ; + void write( void ) const throw (MEDEXCEPTION) ; }; -/*-------------------------*/ -/* template implementation */ -/*-------------------------*/ - -/*--------------------- DRIVER PART -------------------------------*/ - -template void ENSIGHT_FIELD_RDONLY_DRIVER::setFieldName(const string & fieldName) -{ - GENDRIVER::setFieldName(fieldName); -} - -template string ENSIGHT_FIELD_RDONLY_DRIVER::getFieldName() const -{ - return ENSIGHT_FIELD_DRIVER::_fieldName; -} - -template GENDRIVER * ENSIGHT_FIELD_RDONLY_DRIVER::copy(void) const -{ - ENSIGHT_FIELD_RDONLY_DRIVER * myDriver = new ENSIGHT_FIELD_RDONLY_DRIVER(*this); - - return myDriver ; -} - -template void ENSIGHT_FIELD_RDONLY_DRIVER::read (void) - throw (MEDEXCEPTION) -{ - - vector var ; - double myVar ; - char ligne[80]; - string mot_lu ; - - string field_namefile ; - string field_read_name ; - - int is_scalar=0 ; - int is_vector=0; - int is_node=0; - int is_element=0; - - // recuperation des valeurs du champ - - ifstream ensightCaseFile(ENSIGHT_FIELD_DRIVER::_fileName.c_str(),ios::in); - cout << "-> Ensight case file name to read " << ENSIGHT_FIELD_DRIVER::_fileName << endl ; - - field_read_name = "EnsightField"; // defaut name for the field - - if (ensightCaseFile.is_open() ) - { - while ( ensightCaseFile >> mot_lu ) - { - if ( mot_lu == "VARIABLE" ) { - cout << "field detected" << endl ; - while ( ensightCaseFile >> mot_lu ){ - if ( mot_lu == "scalar" || mot_lu == "vector" ) { - if ( mot_lu == "scalar" ) is_scalar = 1 ; - if ( mot_lu == "vector" ) is_vector = 1 ; - ensightCaseFile >> mot_lu ; //per - ensightCaseFile >> mot_lu ; //node - if ( mot_lu == "node:" ) is_node = 1 ; - if ( mot_lu == "element:" ) is_element = 1 ; - else { - ensightCaseFile >> mot_lu ; //description - ensightCaseFile >> mot_lu ; - field_namefile = mot_lu ; - cout << "name of field : " << field_namefile << endl ; - break ; // couple la boucle sur les champs - } - } - } - // cout << " scalar " << is_scalar << " vector " << is_vector << " node " << is_node << " element " << is_element << endl ; - if ( !(is_scalar+is_vector) ) { - cout << " the field ist not a scalar and is not a vector " << endl ; - break ; - } - else if ( !(is_node+is_element) ) { - cout << " the field ist not on nodes and is not on elements " << endl ; - break ; - } - } - } - } - else - { - cout << "Error : requested file " << ensightCaseFile << " not found " << endl; - exit( EXIT_FAILURE ); - } - - ifstream ensightFieldFile(field_namefile.c_str(),ios::in); - cout << "-> Entering into the field file " << field_namefile << endl ; - - if ( ensightFieldFile.is_open() ) - { - ensightFieldFile.getline(ligne, 80, '\n') ; // read the first line of comment - -// while ( ensightFieldFile.eof() == 0 ) - - while ( ensightFieldFile >> setw(12) >> myVar ) - { - var.push_back(myVar) ; - } - } - int NumberOfValues = var.size() ; - - // construction med - - ENSIGHT_FIELD_DRIVER::_ptrField->setName(field_read_name) ; - - int NumberOfComponents = 1 ; - if ( is_vector ) NumberOfComponents = 3 ; - ENSIGHT_FIELD_DRIVER::_ptrField->setNumberOfComponents(NumberOfComponents) ; - string * componentsNames = new string[NumberOfComponents] ; - if ( NumberOfComponents == 1 ) componentsNames[0] = "scalar comp" ; - else if ( NumberOfComponents == 3 ) { - componentsNames[0] = "X comp" ; - componentsNames[1] = "Y comp" ; - componentsNames[2] = "Z comp" ; - } - ENSIGHT_FIELD_DRIVER::_ptrField->setComponentsNames(componentsNames); - delete[] componentsNames ; - - ENSIGHT_FIELD_DRIVER::_ptrField->setNumberOfValues(NumberOfValues); - - int NumberOf = NumberOfValues / NumberOfComponents; - cout << "-> Loading " << NumberOf << " NumberOf values " << endl ; - ENSIGHT_FIELD_DRIVER::_ptrField->allocValue(NumberOfComponents); - for ( int i = 1 ; i <= NumberOf ; i++) { - for ( int j = 1 ; j <= NumberOfComponents ; j++) { -// cout << "-> EnsightFieldDriver : write v = " << var[NumberOfComponents*(i-1)+j-1] << endl ; - ENSIGHT_FIELD_DRIVER::_ptrField->setValueIJ(i,j,(T)var[NumberOfComponents*(i-1)+j-1]); - } - } - cout << "NOM DU MAILLAGE : " << ENSIGHT_FIELD_DRIVER::_ptrField->getSupport()->getMesh()->getName() << endl; - -} - -template void ENSIGHT_FIELD_RDONLY_DRIVER::write(void) const - throw (MEDEXCEPTION) -{ - throw MEDEXCEPTION("ENSIGHT_FIELD_RDONLY_DRIVER::write : Can't write with a RDONLY driver !"); -} - -template void ENSIGHT_FIELD_RDONLY_DRIVER::writeAppend(void) const - throw (MEDEXCEPTION) -{ - throw MEDEXCEPTION("ENSIGHT_FIELD_RDONLY_DRIVER::write : Can't write with a RDONLY driver !"); -} - -template void ENSIGHT_FIELD_WRONLY_DRIVER::setFieldName(const string & fieldName) -{ - ENSIGHT_FIELD_DRIVER::_fieldName = fieldName; -} - -template string ENSIGHT_FIELD_WRONLY_DRIVER::getFieldName() const -{ - return ENSIGHT_FIELD_DRIVER::_fieldName; -} - -template GENDRIVER * ENSIGHT_FIELD_WRONLY_DRIVER::copy(void) const -{ - ENSIGHT_FIELD_WRONLY_DRIVER * myDriver = new ENSIGHT_FIELD_WRONLY_DRIVER(*this); - - return myDriver ; -} - -template void ENSIGHT_FIELD_WRONLY_DRIVER::read (void) - throw (MEDEXCEPTION) -{ - throw MEDEXCEPTION("ENSIGHT_FIELD_WRONLY_DRIVER::read : Can't read with a ENSIGHT driver because it is write only driver !"); -} - -template void ENSIGHT_FIELD_WRONLY_DRIVER::write(void) const - throw (MEDEXCEPTION) -{ - - const char * LOC = "ENSIGHT_FIELD_WRONLY_DRIVER::write(void) const " ; - BEGIN_OF(LOC); - - string mot_lu ; - int is_node = 0 ; - int is_element = 0 ; - int is_variable = 0 ; - -// FIELD_ * myField = ENSIGHT_FIELD_DRIVER::_ptrField ; -// MESH * meshField = supportField->getMesh(); - - const SUPPORT * supportField = ENSIGHT_FIELD_DRIVER::_ptrField->getSupport(); - - int dt = ENSIGHT_FIELD_DRIVER::_ptrField->getIterationNumber(); - int it = ENSIGHT_FIELD_DRIVER::_ptrField->getOrderNumber(); - - ostringstream name ; - string nameField = ENSIGHT_FIELD_DRIVER::_ptrField->getName(); - MED_EN::medEntityMesh entitySupport = supportField->getEntity(); - name << nameField << "_" << dt << "_" << it << ".sol" ; - - if ( ENSIGHT_FIELD_DRIVER::_ptrField->getGaussPresence() ) - throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<::_ptrField->getName()<<" which use Gauss Points !" << entitySupport)); - - if (!(supportField->isOnAllElements())) - throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<::_ptrField->getName()<<" which is not on all entities of the mesh !" << entitySupport)); - -// if (entitySupport == MED_EN::MED_NODE) int NumberOfNodes = ENSIGHT_FIELD_DRIVER::_ptrField->getNumberOfElements(MED_EN::MED_NODE,MED_EN::MED_ALL_ELEMENTS) ; -// else if (entitySupport == MED_EN::MED_CELL) int NumberOfElements = ENSIGHT_FIELD_DRIVER::_ptrField->getNumberOfElements(MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS) ; -// else -// throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << "Could not write field "<::_ptrField->getName()<<" which is not on all nodes or cells but it's on !" << entitySupport)); - - int NumberOfValue = ENSIGHT_FIELD_DRIVER::_ptrField->getSupport()->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS) ; - int NumberOfComponents = ENSIGHT_FIELD_DRIVER::_ptrField->getNumberOfComponents() ; - -// MED_EN::med_type_champ fieldType = ENSIGHT_FIELD_DRIVER::_ptrField->getValueType() ; - -// Case file part -//--------------- - - ifstream ensightCaseFile(ENSIGHT_FIELD_DRIVER::_fileName.c_str(),ios::in); - cout << "-> Creating the Ensight case file " << ENSIGHT_FIELD_DRIVER::_fileName << endl ; - - if (ensightCaseFile.is_open() ) // test si le mot clé VARIABLE est déjà dans le case file - { - while ( ensightCaseFile.eof() == 0 ) - { - ensightCaseFile >> mot_lu ; - if ( mot_lu == "VARIABLE" ) is_variable = 1 ; - } - } -// else -// cout << "-> Cannot access to the Ensight case file : " << ENSIGHT_FIELD_DRIVER::_fileName << endl ; - ensightCaseFile.close(); - - MED_EN::med_type_champ type = ENSIGHT_FIELD_DRIVER::_ptrField->getValueType() ; - SCRUTE(name); - SCRUTE(type); - - if ( ENSIGHT_FIELD_DRIVER::_ptrField->getSupport()->getEntity() == 0 ) is_element = 1 ; - else if ( ENSIGHT_FIELD_DRIVER::_ptrField->getSupport()->getEntity() == 3 ) is_node = 1 ; - - ofstream NensightCaseFile(ENSIGHT_FIELD_DRIVER::_fileName.c_str(),ios::out|ios::app); - NensightCaseFile << endl ; - if (!is_variable) NensightCaseFile << "VARIABLE" << endl ; // mot clé VARIABLE non présent dans le case file, on l'ajoute - - int len = ENSIGHT_FIELD_DRIVER::_fileName.size() ; - string prefix = ENSIGHT_FIELD_DRIVER::_fileName.substr(0,len-5); // extraction de .case - string dataname = prefix + ".sol" ; - - std::string aBaseName = getBaseName( (char*)dataname.c_str() ); - NensightCaseFile << "# --Field detected for " << aBaseName << endl ; - if ( NumberOfComponents > 1 ) { - if (is_node) NensightCaseFile << "vector per node: " << nameField << " " << aBaseName << endl ; - if (is_element) NensightCaseFile << "vector per element: " << nameField << " " << aBaseName << endl ; - } else { - if (is_node) NensightCaseFile << "scalar per node: " << nameField << " " << aBaseName << endl ; - if (is_element) NensightCaseFile << "scalar per element: " << nameField << " " << aBaseName << endl ; - } - NensightCaseFile.close(); - -// Field file part -//---------------- - - ofstream ensightDataFile(dataname.c_str(),ios::out) ; - cout << "-> Creating the Ensight data file " << dataname << endl ; - ensightDataFile.setf(ios::scientific); - ensightDataFile.precision(5); - - switch (type) - - { - case MED_EN::MED_INT32 : { - MESSAGE("MED_INT32"); - if (NumberOfComponents==3) { - if (is_node) ensightDataFile << "vector per node integer 32 mode for " << nameField << " following " << endl ; - if (is_element) ensightDataFile << "vector per element integer 32 mode for " << nameField << "following " << endl ; - } else if (NumberOfComponents<=4) { - if (is_node) ensightDataFile << "scalar per node integer 32 mode for " << nameField << " following " << endl ; - if (is_element) ensightDataFile << "scalar per element integer 32 mode for " << nameField << " following " << endl ; - } else { - MESSAGE(LOC << "Could not write field "<< nameField << " there are more than 4 components !"); - return ; - } - - const T * value; - if ( ENSIGHT_FIELD_DRIVER::_ptrField->getInterlacingType() == MED_EN::MED_NO_INTERLACE ) { - value = ENSIGHT_FIELD_DRIVER::_ptrField->getValue(); - } - else if ( ENSIGHT_FIELD_DRIVER::_ptrField->getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) { - MEDMEM_Array_ * ptrArray = ENSIGHT_FIELD_DRIVER::_ptrField->getArray(); - MEDMEM_Array * temp = dynamic_cast * > ( ptrArray ); - MEDMEM_Array * array = ArrayConvert2No( *temp ); - value = array->getPtr(); - } - else { - MEDMEM_Array_ * ptrArray = ENSIGHT_FIELD_DRIVER::_ptrField->getArray(); - MEDMEM_Array * temp = dynamic_cast * > ( ptrArray ); - MEDMEM_Array * array = ArrayConvert( *temp ); - value = array->getPtr(); - } - - int mypoint=0; - for (int i=0; i::_ptrField->getInterlacingType() != MED_EN::MED_NO_INTERLACE ) delete value; - break ; - } - - case MED_EN::MED_REEL64 : { - MESSAGE("MED_REEL64"); - if (NumberOfComponents==3) { - if (is_node) ensightDataFile << "vector per node real 64 mode for " << nameField << " following " << endl ; - if (is_element) ensightDataFile << "vector per element real 64 mode for " << nameField << " following " << endl ; - } else if (NumberOfComponents<=4) { - if (is_node) ensightDataFile << "scalar per node real 64 mode for " << nameField << " following " << endl ; - if (is_element) ensightDataFile << "scalar per element real 64 mode for " << nameField << " following " << endl ; - } else { - MESSAGE(LOC << "Could not write field "<::_ptrField->getName()<<" there are more than 4 components !"); - return ; - } - - const T * value; - if ( ENSIGHT_FIELD_DRIVER::_ptrField->getInterlacingType() == MED_EN::MED_NO_INTERLACE ) - value = ENSIGHT_FIELD_DRIVER::_ptrField->getValue(); - else if ( ENSIGHT_FIELD_DRIVER::_ptrField->getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) { - MEDMEM_Array_ * ptrArray = ENSIGHT_FIELD_DRIVER::_ptrField->getArray(); - MEDMEM_Array * temp = dynamic_cast * > ( ptrArray ); - MEDMEM_Array * array = ArrayConvert2No( *temp ); // ici ca pond un p'tain de core // - value = array->getPtr(); - } - else { - MEDMEM_Array_ * ptrArray = ENSIGHT_FIELD_DRIVER::_ptrField->getArray(); - MEDMEM_Array * temp = dynamic_cast * > ( ptrArray ); - MEDMEM_Array * array = ArrayConvert( *temp ); // ici ca pond un p'tain de core // - value = array->getPtr(); - } - - int mypoint=0; - for (int i=0; i::_ptrField->getInterlacingType() != MED_EN::MED_NO_INTERLACE ) delete value; - ensightDataFile << endl ; - break ; - } - default : { - MESSAGE(LOC << "Could not write field "< void ENSIGHT_FIELD_WRONLY_DRIVER::writeAppend(void) const - throw (MEDEXCEPTION) -{ - const char * LOC = "ENSIGHT_FIELD_DRIVER::writeAppend(void) const " ; - BEGIN_OF(LOC); - -// redondant avec write() - - END_OF(LOC); -} - }//End namespace MEDMEM #endif /* ENSIGHT_FIELD_DRIVER_HXX */ diff --git a/src/MEDMEM/MEDMEM_EnsightMedDriver.cxx b/src/MEDMEM/MEDMEM_EnsightMedDriver.cxx index c1fad8c8c..2e518a7c2 100644 --- a/src/MEDMEM/MEDMEM_EnsightMedDriver.cxx +++ b/src/MEDMEM/MEDMEM_EnsightMedDriver.cxx @@ -1,96 +1,112 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // -#include "MEDMEM_EnsightMedDriver.hxx" - -#include -#include - #include "MEDMEM_define.hxx" #include "MEDMEM_Med.hxx" -#include "MEDMEM_Field.hxx" #include "MEDMEM_Support.hxx" #include "MEDMEM_Mesh.hxx" -#include "MEDMEM_CellModel.hxx" -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_MedFieldDriver.hxx" -#include "MEDMEM_Meshing.hxx" -#include "MEDMEM_Group.hxx" +#include "MEDMEM_EnsightMedDriver.hxx" +#include "MEDMEM_EnsightFieldDriver.hxx" +#include "MEDMEM_EnsightMeshDriver.hxx" using namespace std; -using namespace MEDMEM; +//using namespace MEDMEM; using namespace MED_EN; +using namespace MEDMEM_ENSIGHT; -ENSIGHT_MED_DRIVER::ENSIGHT_MED_DRIVER(): GENDRIVER(), - _ptrMed((MED * const)MED_NULL) +// ================================================================================ +// ENSIGHT_MED_DRIVER +// ================================================================================ +namespace MEDMEM { + +ENSIGHT_MED_DRIVER::ENSIGHT_MED_DRIVER(): + _CaseFileDriver_User(),_ptrMed((MED *)MED_NULL) {} -ENSIGHT_MED_DRIVER::ENSIGHT_MED_DRIVER(const string & fileName, MED * const ptrMed): - GENDRIVER(fileName,MED_EN::MED_RDWR), _ptrMed(ptrMed) +ENSIGHT_MED_DRIVER::ENSIGHT_MED_DRIVER(const string & fileName, MED * ptrMed): + _CaseFileDriver_User(fileName,RDONLY), _ptrMed(ptrMed) { } ENSIGHT_MED_DRIVER::ENSIGHT_MED_DRIVER(const string & fileName, - MED * const ptrMed, - MED_EN::med_mode_acces accessMode): - GENDRIVER(fileName,accessMode), _ptrMed(ptrMed) + MED * ptrMed, + med_mode_acces accessMode): + _CaseFileDriver_User(fileName,accessMode), _ptrMed(ptrMed) { } ENSIGHT_MED_DRIVER::ENSIGHT_MED_DRIVER(const ENSIGHT_MED_DRIVER & driver): - GENDRIVER(driver), - _ptrMed(driver._ptrMed) + _CaseFileDriver_User(driver), _ptrMed(driver._ptrMed) { } -ENSIGHT_MED_DRIVER::~ENSIGHT_MED_DRIVER() +void ENSIGHT_MED_DRIVER::openConst() const { - MESSAGE("ENSIGHT_MED_DRIVER::~ENSIGHT_MED_DRIVER() has been destroyed"); + const char * LOC ="ENSIGHT_MED_DRIVER::open() : "; + BEGIN_OF_MED(LOC); + + if ( _fileName.empty() ) + throw MED_EXCEPTION + ( LOCALIZED( STRING(LOC) << "_fileName is empty, " + "please set a correct fileName before calling open()")); + + if (!canOpenFile( _fileName, getAccessMode() )) + throw MED_EXCEPTION + ( LOCALIZED( STRING(LOC) << "Can not open main Ensight file " << _fileName)); + + END_OF_MED(LOC); } void ENSIGHT_MED_DRIVER::open() { - openConst() ; + openConst(); } - void ENSIGHT_MED_DRIVER::close() { - closeConst() ; } +ENSIGHT_MED_DRIVER::~ENSIGHT_MED_DRIVER() +{ + MESSAGE_MED("ENSIGHT_MED_DRIVER::~ENSIGHT_MED_DRIVER() has been destroyed"); +} + +// ================================================================================ +// WRONLY +// ================================================================================ + ENSIGHT_MED_WRONLY_DRIVER::ENSIGHT_MED_WRONLY_DRIVER() : ENSIGHT_MED_DRIVER() { - _ensightFile = new ofstream(); } -ENSIGHT_MED_WRONLY_DRIVER::ENSIGHT_MED_WRONLY_DRIVER(const string & fileName, MED * const ptrMed) : ENSIGHT_MED_DRIVER(fileName,ptrMed) +ENSIGHT_MED_WRONLY_DRIVER::ENSIGHT_MED_WRONLY_DRIVER(const string & fileName, MED * ptrMed) + : ENSIGHT_MED_DRIVER(fileName, ptrMed, MED_EN::WRONLY ) { - _ensightFile = new ofstream(); } -ENSIGHT_MED_WRONLY_DRIVER::ENSIGHT_MED_WRONLY_DRIVER(const ENSIGHT_MED_WRONLY_DRIVER & driver) : ENSIGHT_MED_DRIVER(driver) +ENSIGHT_MED_WRONLY_DRIVER::ENSIGHT_MED_WRONLY_DRIVER(const ENSIGHT_MED_WRONLY_DRIVER & driver) + : ENSIGHT_MED_DRIVER(driver) { - _ensightFile = new ofstream(); } ENSIGHT_MED_WRONLY_DRIVER::~ENSIGHT_MED_WRONLY_DRIVER() { - delete _ensightFile ; } GENDRIVER * ENSIGHT_MED_WRONLY_DRIVER::copy() const @@ -98,526 +114,94 @@ GENDRIVER * ENSIGHT_MED_WRONLY_DRIVER::copy() const return new ENSIGHT_MED_WRONLY_DRIVER(*this) ; } -void ENSIGHT_MED_WRONLY_DRIVER::openConst() const { - - const char * LOC ="ENSIGHT_MED_WRONLY_DRIVER::open() : "; - - BEGIN_OF(LOC); - - if ( _fileName == "" ) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) - << "_fileName is |\"\"|, please set a correct fileName before calling open()" - ) - ); - - if (!(*_ensightFile).is_open()) - (*_ensightFile).open(_fileName.c_str()) ; - - if (!(*_ensightFile)) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open main Ensight file " - << _fileName) - ); - END_OF(LOC); -} - -void ENSIGHT_MED_WRONLY_DRIVER::closeConst() const { - - const char * LOC = "ENSIGHT_MED_WRONLY_DRIVER::close() : "; - BEGIN_OF(LOC); - - (*_ensightFile).close(); - - if (!(*_ensightFile)) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not close main Ensight file " - << _fileName) - ); - END_OF(LOC); -} - void ENSIGHT_MED_WRONLY_DRIVER::read() throw (MEDEXCEPTION) { throw MEDEXCEPTION("ENSIGHT_MED_WRONLY_DRIVER::read : Can't read with a WRONLY driver !"); } -void ENSIGHT_MED_WRONLY_DRIVER::write() const throw (MEDEXCEPTION) { - +void ENSIGHT_MED_WRONLY_DRIVER::write() const throw (MEDEXCEPTION) +{ const char * LOC = "ENSIGHT_MED_WRONLY_DRIVER::write() : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); - // Well we must open ensight file first, because there are - // no other driver than MED for ENSIGHT that do it ! - openConst() ; + openConst(); // check if can open the case file + + _CaseFileDriver caseFile( getCaseFileName(), this ); - // Ensight case organization requires a main file (filename.case) which defines organization - // We also need a geom file (filemane.geo) to store the meshs - // We also need a data file (filemane.data) to store the fields - int NumberOfMeshes = _ptrMed->getNumberOfMeshes() ; deque MeshNames = _ptrMed->getMeshNames() ; - // In fact, we must take care of all supports - // We restrict Field on all nodes or cells int NumberOfFields = _ptrMed->getNumberOfFields() ; deque FieldNames = _ptrMed->getFieldNames() ; - - cout << "-> creating the Ensight case file " << _fileName << endl ; - (*_ensightFile) << "FORMAT" << endl ; - (*_ensightFile) << "type: ensight" << endl ; - (*_ensightFile) << endl ; - if (NumberOfMeshes){ - (*_ensightFile) << "GEOMETRY" << endl ; - for (int i=0; igetMesh(MeshNames[i]) ; - writeMesh(myMesh, i) ; - // get all field which values are on this mesh => revoir api de Med !!! - // first : field on node - // fields is on all node ! - for (int j=0; j timeStep = _ptrMed->getFieldIteration(FieldNames[j]) ; - deque::const_iterator currentTimeStep ; - for ( currentTimeStep=timeStep.begin(); currentTimeStep!=timeStep.end(); currentTimeStep++) { - int dt = (*currentTimeStep).dt ; - int it = (*currentTimeStep).it ; - FIELD_ * myField = _ptrMed->getField(FieldNames[j],dt,it) ; - ostringstream name ; - name << myField->getName() << "_" << dt << "_" << it ; - (*_ensightFile) << "# -Field "<< j+1 << " detected with name = " << name.str() << endl ; - if( MeshNames[i] == myField->getSupport()->getMesh()->getName() ) { - // rigth in all case : better compare pointeur ? - if (MED_NODE == myField->getSupport()->getEntity()) - if (myField->getSupport()->isOnAllElements()) { - int NumberOfComponents = myField->getNumberOfComponents() ; - ostringstream name ; - name << myField->getName() << "_" << dt << "_" << it ; - if (NumberOfComponents==3) (*_ensightFile) << "vector per node: " << name.str() << " " << name.str() << ".sol" << endl ; - else if (NumberOfComponents<=4) (*_ensightFile) << "scalar per node: " << name.str() << " " << name.str() << ".sol" << endl ; - writeField(myField,name.str()) ; - } else - MESSAGE(LOC << "Could not write field "<getName()<<" which is not on all nodes !"); - } - } - } - for (int j=0; j timeStep = _ptrMed->getFieldIteration(FieldNames[j]) ; - deque::const_iterator currentTimeStep ; - for ( currentTimeStep=timeStep.begin(); currentTimeStep!=timeStep.end(); currentTimeStep++) { - int dt = (*currentTimeStep).dt; - int it = (*currentTimeStep).it; - FIELD_ * myField = _ptrMed->getField(FieldNames[j],dt,it) ; - ostringstream name ; - name << myField->getName() << "_" << dt << "_" << it ; - (*_ensightFile) << "# --Field "<< j+1 << " detected for " << name.str() << endl ; - if( MeshNames[i] == myField->getSupport()->getMesh()->getName() ) { - // rigth in all case : better compare pointeur ? - if (MED_CELL == myField->getSupport()->getEntity()) - if (myField->getSupport()->isOnAllElements()) { - int NumberOfComponents = myField->getNumberOfComponents() ; - ostringstream name ; - name << myField->getName() << "_" << dt << "_" << it ; - if (NumberOfComponents==3) (*_ensightFile) << "vector per element: " << name.str() << " " << name.str() << ".sol" << endl ; - else if (NumberOfComponents<=4) (*_ensightFile) << "scalar per element: " << name.str() << " " << name.str() << ".sol" << endl ; - writeField(myField,name.str()) ; - } else - MESSAGE(LOC << "Could not write field "<getName()<<" which is not on all cells !"); - } - } - } - - } - - // Well we must close ensight file first, because there are - // no other driver than MED for ENSIGHT that do it ! - // closeConst() ; - - END_OF(LOC); -} - -void ENSIGHT_MED_WRONLY_DRIVER::writeMesh(MESH * myMesh , int imesh) const { - - const char * LOC = "ENSIGHT_MED_DRIVER::writeMesh() : "; - BEGIN_OF(LOC); - - int len = _fileName.size() ; - string prefix = _fileName.substr(0,len-5); // extraction de .case - strstream w_mesh ; - w_mesh << prefix << "-" << imesh+1 << ".geom" << ends ; - string ensight_geomf = w_mesh.str() ; - - ofstream ensightGeomFile(ensight_geomf.c_str(),ios::out); - cout << "-> creating the Ensight geometry file " << ensight_geomf << endl ; + // Create drivers for all meshes and fields + // and add them to be written to Case file - // ------------ create the Ensight file associated to this meshe - ensightGeomFile << "Ensight Geometry File : " << endl - << "Meshing from MedMemory" << endl ; -// ensightGeomFile << "node id given " << endl ; -// ensightGeomFile << "element id given " << endl ; - ensightGeomFile << "node id assign " << endl ; - ensightGeomFile << "element id assign " << endl ; - ensightGeomFile << "coordinates" << endl ; - // put points (all point are in 3D, so if we are in 1D or 2D, we complete by zero ! - int SpaceDimension = myMesh->getSpaceDimension() ; - int NumberOfNodes = myMesh->getNumberOfNodes() ; - ensightGeomFile << NumberOfNodes << endl ; - const double *coordinate = myMesh->getCoordinates(MED_FULL_INTERLACE) ; - ensightGeomFile.setf(ios::scientific); - ensightGeomFile.precision(5); - for (int i=0;i drivers; + ENSIGHT_MESH_WRONLY_DRIVER * meshDriver; + ENSIGHT_FIELD_WRONLY_DRIVER * fieldDriver; - // we put connectivity - // how many cells and how many value in connectivity : - int cells_types_count = myMesh->getNumberOfTypes(MED_CELL) ; -// int cells_sum = myMesh->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) ; - const CELLMODEL * cells_type = myMesh->getCellsTypes(MED_CELL) ; - ensightGeomFile << "part 1 " << endl ; - ensightGeomFile << "elements are following " << endl ; + for (int i=0; igetMesh(MeshNames[i]) ; + meshDriver = new ENSIGHT_MESH_WRONLY_DRIVER( _fileName, mesh ); + caseFile.addMesh( meshDriver ); + drivers.push_back( meshDriver ); - // we put connectivity - for (int i=0;igetNumberOfElements(MED_CELL,cells_type[i].getType()) ; - int *filter = (int*) NULL ; - switch (cells_type[i].getType()) + // get all fields on this mesh + for (int j=0; j timeSteps = _ptrMed->getFieldIteration(FieldNames[j]) ; + deque::const_iterator dtit = timeSteps.begin(); + for ( ; dtit!=timeSteps.end(); dtit++) { - case MED_POINT1 : { - ensightGeomFile << "point" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[1] ; - filter[0] = 0 ; - break ; - } - case MED_SEG2 : { - ensightGeomFile << "bar2" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[2] ; - filter[0] = 0 ; - filter[1] = 1 ; - break ; - } - case MED_SEG3 : { - filter = new int[3] ; - filter[0] = 0 ; - filter[1] = 2 ; - filter[2] = 1 ; - break ; - } - case MED_TRIA3 : { - ensightGeomFile << "tria3" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[3] ; - filter[0] = 0 ; - filter[1] = 2 ; - filter[2] = 1 ; - break ; - } - case MED_QUAD4 : { - ensightGeomFile << "quad4" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[4] ; - filter[0] = 0 ; - filter[1] = 3 ; - filter[2] = 2 ; - filter[3] = 1 ; - break ; - } - case MED_TRIA6 : { - ensightGeomFile << "tria6" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[6] ; - filter[0] = 0 ; - filter[1] = 2 ; - filter[2] = 1 ; - filter[3] = 5 ; - filter[4] = 4 ; - filter[5] = 3 ; - break ; - } - case MED_QUAD8 : { - ensightGeomFile << "quad8" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[8] ; - filter[0] = 0 ; - filter[1] = 3 ; - filter[2] = 2 ; - filter[3] = 1 ; - filter[4] = 7 ; - filter[5] = 6 ; - filter[6] = 5 ; - filter[7] = 4 ; - break ; - } - case MED_TETRA4 : { - ensightGeomFile << "tetra4" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[4] ; - filter[0] = 0 ; - filter[1] = 1 ; - filter[2] = 3 ; // 3td element in med are 4th in vtk (array begin at 0 !) - filter[3] = 2 ; // 4th element in med are 3rd in vtk (array begin at 0 !) - break ; + FIELD_ * field = _ptrMed->getField( FieldNames[j], dtit->dt, dtit->it ); + MESH* supMesh = field->getSupport()->getMesh(); + if ( supMesh == mesh || mesh->getName() == field->getSupport()->getMeshName() ) { + fieldDriver = new ENSIGHT_FIELD_WRONLY_DRIVER( _fileName, field ); + caseFile.addField( fieldDriver ); + drivers.push_back( fieldDriver ); + } } - case MED_PYRA5 : { - ensightGeomFile << "pyramid5" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[5] ; - filter[0] = 0 ; - filter[1] = 3 ; // 2nd element in med are 4th in vtk (array begin at 0 !) - filter[2] = 2 ; - filter[3] = 1 ; // 4th element in med are 2nd in vtk (array begin at 0 !) - filter[4] = 4 ; - break ; - } - case MED_PENTA6 : { - ensightGeomFile << "penta6" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[6] ; - filter[0] = 0 ; - filter[1] = 2 ; - filter[2] = 1 ; - filter[3] = 3 ; - filter[4] = 4 ; - filter[5] = 5 ; - break ; - } - case MED_HEXA8 : { - ensightGeomFile << "hexa8" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[8] ; - filter[0] = 0 ; - filter[1] = 3 ; - filter[2] = 2 ; - filter[3] = 1 ; - filter[4] = 4 ; - filter[5] = 7 ; - filter[6] = 6 ; - filter[7] = 5 ; - break ; - } - case MED_TETRA10 : { - ensightGeomFile << "tetra10" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[10] ; - filter[0] = 0 ; - filter[1] = 2 ; - filter[2] = 1 ; - filter[3] = 3 ; - filter[4] = 6 ; - filter[5] = 5 ; - filter[6] = 4 ; - filter[7] = 7 ; - filter[8] = 9 ; - filter[9] = 8 ; - break ; - } - case MED_PYRA13 : { - ensightGeomFile << "pyramid13" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - break ; - } - case MED_PENTA15 : { - ensightGeomFile << "penta15" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - break ; - } - case MED_HEXA20 : { - ensightGeomFile << "hexa20" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - break ; - } - default : { - break ; - } - } - if (filter==NULL) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": MED element type not supported yet : " << cells_type[i].getName() ) ) ; - int nodes_cell = cells_type[i].getNumberOfNodes(); - const int * connectivityArray = myMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,cells_type[i].getType()); - for (int j=0;j::Array ArrayIntNo; - typedef MEDMEM_ArrayInterface::Array ArrayDoubleNo; - - int NumberOfValue = myField->getSupport()->getNumberOfElements(MED_ALL_ELEMENTS) ; - int NumberOfComponents = myField->getNumberOfComponents() ; - - int is_node = 0 ; - int is_element = 0 ; - - string dataname = name += ".sol" ; - ofstream ensightDataFile(name.c_str(),ios::out) ; - cout << "-> creating the Ensight data file " << name << endl ; - ensightDataFile.setf(ios::scientific); - ensightDataFile.precision(5); + // case file + caseFile.write();// necessary data is passed to the drivers by this method - med_type_champ type = myField->getValueType() ; - SCRUTE(name); - SCRUTE(type); - - if ( myField->getSupport()->getEntity() == 0 ) is_element = 1 ; - else if ( myField->getSupport()->getEntity() == 3 ) is_node = 1 ; - - switch (type) - - { - case MED_INT32 : { - MESSAGE("MED_INT32"); - if (NumberOfComponents==3) { - if (is_node) ensightDataFile << "vector per node integer 32 mode for " << name << " following " << endl ; - if (is_element) ensightDataFile << "vector per element integer 32 mode for " << name << " following " << endl ; - } else if (NumberOfComponents<=4) { - if (is_node) ensightDataFile << "scalar per node integer 32 mode for " << name << " following " << endl ; - if (is_element) ensightDataFile << "scalar per element integer 32 mode for " << name << " following " << endl ; - } else { - MESSAGE(LOC << "Could not write field "<getName()<<" there are more than 4 components !"); - return ; - } - - const int * value; - ArrayIntNo * myArray = 0; - if ( myField->getInterlacingType() == MED_FULL_INTERLACE ) { - myArray = ArrayConvert( *( dynamic_cast< FIELD* > - (myField)->getArrayNoGauss() - ) - ); - value = myArray->getPtr(); - } else if ( myField->getInterlacingType() == MED_NO_INTERLACE_BY_TYPE ) { - myArray = ArrayConvert2No( *( dynamic_cast< FIELD* > - (myField)->getArrayNoGauss() - ) - ); - value = myArray->getPtr(); - } else { - value = ((FIELD*)myField)->getValue() ; - } - - for (int i=0; igetInterlacingType() != MED_NO_INTERLACE ) - delete myArray; - break ; - } - case MED_REEL64 : { - MESSAGE("MED_REEL64"); - if (NumberOfComponents==3) { - if (is_node) ensightDataFile << "vector per node real 64 mode for " << name << " following " << endl ; - if (is_element) ensightDataFile << "vector per element real 64 mode for " << name << " following " << endl ; - } else if (NumberOfComponents<=4) { - if (is_node) ensightDataFile << "scalar per node real 64 mode for " << name << " following " << endl ; - if (is_element) ensightDataFile << "scalar per element real 64 mode for " << name << " following " << endl ; - } else { - MESSAGE(LOC << "Could not write field "<getName()<<" there are more than 4 components !"); - return ; - } - - const double * value; - ArrayDoubleNo * myArray = 0; - if ( myField->getInterlacingType() == MED_FULL_INTERLACE ) { - myArray = ArrayConvert( *( dynamic_cast< FIELD* > - (myField)->getArrayNoGauss() - ) - ); - value = myArray->getPtr(); - } else if ( myField->getInterlacingType() == MED_NO_INTERLACE_BY_TYPE ) { - myArray = ArrayConvert2No( *( dynamic_cast< FIELD* > - (myField)->getArrayNoGauss() - ) - ); - value = myArray->getPtr(); - } else { - value = ((FIELD*)myField)->getValue() ; - } - - int mypoint=0; - //cout << "-> number of values " << NumberOfValue << " number of components " << NumberOfComponents << endl ; - for (int i=0; igetInterlacingType() != MED_NO_INTERLACE ) - delete myArray; - - break ; - } - default : { - MESSAGE(LOC << "Could not write field "<::iterator drv = drivers.begin(); + for ( ; drv != drivers.end(); ++drv ) { + GENDRIVER* driver = *drv; + driver->write(); + delete driver; + } - ensightDataFile.close(); - - END_OF(LOC); + END_OF_MED(LOC); } -void ENSIGHT_MED_WRONLY_DRIVER::writeSupport(SUPPORT * mySupport) const { - const char * LOC = "ENSIGHT_MED_WRONLY_DRIVER::writeSupport(SUPPORT *) : " ; - BEGIN_OF(LOC) ; - MESSAGE(LOC << "Not yet implemented, acting on the object " << *mySupport); - END_OF(LOC) ; -} +// ================================================================================ +// RDONLY +// ================================================================================ -ENSIGHT_MED_RDONLY_DRIVER::ENSIGHT_MED_RDONLY_DRIVER() : ENSIGHT_MED_DRIVER() +ENSIGHT_MED_RDONLY_DRIVER::ENSIGHT_MED_RDONLY_DRIVER() : + ENSIGHT_MED_DRIVER(), _isFileStructRead(false) { - _ensightFile = new ifstream(); } -ENSIGHT_MED_RDONLY_DRIVER::ENSIGHT_MED_RDONLY_DRIVER(const string & fileName, MED * const ptrMed) : ENSIGHT_MED_DRIVER(fileName,ptrMed) +ENSIGHT_MED_RDONLY_DRIVER::ENSIGHT_MED_RDONLY_DRIVER(const string & fileName, MED * ptrMed) + : ENSIGHT_MED_DRIVER( fileName, ptrMed, MED_EN::RDONLY), _isFileStructRead(false) { - _ensightFile = new ifstream(); } -ENSIGHT_MED_RDONLY_DRIVER::ENSIGHT_MED_RDONLY_DRIVER(const ENSIGHT_MED_RDONLY_DRIVER & driver) : ENSIGHT_MED_DRIVER(driver) +ENSIGHT_MED_RDONLY_DRIVER::ENSIGHT_MED_RDONLY_DRIVER(const ENSIGHT_MED_RDONLY_DRIVER & driver) + : ENSIGHT_MED_DRIVER(driver), _isFileStructRead(false) { - _ensightFile = new ifstream(); } ENSIGHT_MED_RDONLY_DRIVER::~ENSIGHT_MED_RDONLY_DRIVER() { - delete _ensightFile ; } GENDRIVER * ENSIGHT_MED_RDONLY_DRIVER::copy() const @@ -625,418 +209,121 @@ GENDRIVER * ENSIGHT_MED_RDONLY_DRIVER::copy() const return new ENSIGHT_MED_RDONLY_DRIVER(*this) ; } -void ENSIGHT_MED_RDONLY_DRIVER::openConst() const { - - const char * LOC ="ENSIGHT_MED_RDONLY_DRIVER::open() : "; - - BEGIN_OF(LOC); - - if ( _fileName == "" ) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) - << "_fileName is |\"\"|, please set a correct fileName before calling open()" - ) - ); - - if (!(*_ensightFile).is_open()) - (*_ensightFile).open(_fileName.c_str()) ; - - if (!(*_ensightFile)) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open main Ensight file " - << _fileName) - ); - END_OF(LOC); -} - -void ENSIGHT_MED_RDONLY_DRIVER::closeConst() const { - - const char * LOC = "ENSIGHT_MED_RDONLY_DRIVER::close() : "; - BEGIN_OF(LOC); - - (*_ensightFile).close(); - - if (!(*_ensightFile)) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not close main Ensight file " - << _fileName) - ); - END_OF(LOC); -} - void ENSIGHT_MED_RDONLY_DRIVER::write() const throw (MEDEXCEPTION) { throw MEDEXCEPTION("ENSIGHT_MED_RDONLY_DRIVER::write : Can't write with a RDONLY driver !"); } -void ENSIGHT_MED_RDONLY_DRIVER::read() { - +void ENSIGHT_MED_RDONLY_DRIVER::read() +{ const char * LOC = "ENSIGHT_MED_RDONLY_DRIVER::read() : " ; - BEGIN_OF(LOC); - - openConst() ; - - string type_Ensight[15] = { - "point" , "bar2", "bar3" , "tria3" , "tria6" , "quad4" , "quad8" , "tetra4" , "tetra10" , "pyramid5" , - "pyramid13" , "hexa8" , "hexa20" , "penta6" , "penta15" }; - int nb_edge[15] = { 1,2,3,3,6,4,8,4,10,5,13,8,20,6,15 }; - - vector type_read ; - vector nbcell_read ; - vector< vector > total_conn ; - vector var ; - - char ligne[80]; - //int number_of_geom ; - string geom_namefile ; -// vector field_namefile ; - string field_namefile ; - string mot_lu ; - int geom_given = 0 ; - int num_coordinate ; - string type_cell ; - int number_of_cell ; - int conn ; - //----- ? - int SpaceDimension = 3 ; - //----- ? - int NumberOfTypes = 0 ; - int NumberOfNodes ; - int iType ; - - int is_scalar=0 ; - int is_vector=0; - int is_node=0; - int is_element=0; - int my_field=0 ; - int is_doublon=0 ; - int type_doublon=0 ; -// strstream w_field ; - - MESHING* MyMeshing = new MESHING(); - - MyMeshing->setName( "MeshFromEnsight" ); + BEGIN_OF_MED(LOC); - // recuperation des arguments du fichier ensight case - // -------------------------------------------------- + if ( _isFileStructRead ) { - // In this release, the following options are available : - // For GEOMETRY -> model: - // For VARIABLE -> scalar per node: - // -> vector per node: - // -> scalar per element: - // -> vector per element: + int NumberOfMeshes = _ptrMed->getNumberOfMeshes() ; + deque MeshNames = _ptrMed->getMeshNames() ; - cout << "****************** READ **************** starting " << endl ; + int NumberOfFields = _ptrMed->getNumberOfFields() ; + deque FieldNames = _ptrMed->getFieldNames() ; - ifstream ensightCaseFile(_fileName.c_str(),ios::in); - cout << "Ensight case file name to read " << _fileName << endl ; - string diren = getDirName((char*)_fileName.c_str()); - - if (ensightCaseFile.is_open() ) - { - while ( ensightCaseFile >> mot_lu ) - { - if ( mot_lu == "GEOMETRY" ) { - cout << "geometry detected" << endl ; - while ( ensightCaseFile >> mot_lu ){ - if ( mot_lu == "model:" ) { -// ensightCaseFile >> number_of_geom ; -// cout << "number of geometries " << number_of_geom << endl ; - ensightCaseFile >> mot_lu ; - geom_namefile = mot_lu; - cout << "name of geometrie : " << geom_namefile << endl ; - break ; - } - } - } - else if ( mot_lu == "VARIABLE" ) { - cout << "field detected" << endl ; - while ( ensightCaseFile >> mot_lu ){ - if ( mot_lu == "scalar" || mot_lu == "vector" ) { - if ( mot_lu == "scalar" ) is_scalar = 1 ; - if ( mot_lu == "vector" ) is_vector = 1 ; - ensightCaseFile >> mot_lu ; //per - ensightCaseFile >> mot_lu ; //node - if ( mot_lu == "node:" ) is_node = 1 ; - if ( mot_lu == "element:" ) is_element = 1 ; - else { - ensightCaseFile >> mot_lu ; //description - ensightCaseFile >> mot_lu ; - field_namefile = mot_lu ; - my_field +=1 ; - cout << "name of field : " << my_field << " = " << field_namefile << endl ; - break ; // couple la boucle sur les champs - } - } - } - // cout << " scalar " << is_scalar << " vector " << is_vector << " node " << is_node << " element " << is_element << endl ; - if ( !(is_scalar+is_vector) ) { - cout << " the field ist not a scalar and is not a vector " << endl ; - break ; - } - else if ( !(is_node+is_element) ) { - cout << " the field ist not on nodes and is not on elements " << endl ; - break ; - } - } - } - } - else + for (int i=0; igetMesh(MeshNames[i]) ; + mesh->read( getId() ); } - - // chargement des noeuds et connectivites necessaires depuis le fichier ensight geom - // --------------------------------------------------------------------------------- - - string cgeom_namefile; - if( diren.length() > 0 ) - cgeom_namefile = diren + '/' + geom_namefile; - else - cgeom_namefile = geom_namefile; - cout << "-> Entering into the geometry file " << cgeom_namefile << endl; - - ifstream ensightGeomFile(cgeom_namefile.c_str(),ios::in); - if (ensightGeomFile.is_open() ) + // read fields + for (int j=0; j> mot_lu ){ - if ( mot_lu == "given" ) geom_given=1 ; - if ( mot_lu == "coordinates" ) { -//---------------- Nodes part -------------------------------------------------- - ensightGeomFile >> NumberOfNodes ; - cout << "-> loading " << NumberOfNodes << " coordinates " << endl ; - int NumberOfCoordinates = NumberOfNodes*SpaceDimension ; - double* Coordinates = new double[NumberOfCoordinates]; - int iCoord = 0 ; - cout << "-> geom given " << geom_given << endl ; - for ( int i=0 ; i < NumberOfNodes ; i++) { - if( geom_given) ensightGeomFile >> setw(8) >> num_coordinate ; - ensightGeomFile >> setw(12) >> Coordinates[iCoord] ; - ensightGeomFile >> setw(12) >> Coordinates[iCoord+1] ; - ensightGeomFile >> setw(12) >> Coordinates[iCoord+2] ; -// cout << "coordinate " << i+1 << " read : x = " << Coordinates[iCoord] << " y = " << Coordinates[iCoord+1] << " z = " << Coordinates[iCoord+2] << endl ; -// cout << "coordinate read " << num_coordinate << " : x = " << Coordinates[iCoord] << " y = " << Coordinates[iCoord+1] << " z = " << Coordinates[iCoord+2] << endl ; - iCoord+=3 ; - } - - MyMeshing->setSpaceDimension(SpaceDimension); - MyMeshing->setNumberOfNodes(NumberOfNodes); - MyMeshing->setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,"CARTESIAN",MED_EN::MED_FULL_INTERLACE); - string coordname[3] = { "x", "y", "z" } ; - MyMeshing->setCoordinatesNames(coordname) ; - delete [] Coordinates; - } - else if ( mot_lu == "part" ) { -//---------------- Connectivities part -------------------------------------------- - - while ( ensightGeomFile >> mot_lu ){ - for ( int j = 0 ; j < 15 ; j++){ - if( mot_lu == type_Ensight[j] ) { - is_doublon=0 ; - for ( int ltype = 0 ; ltype < NumberOfTypes ; ltype++ ){ - if ( mot_lu == type_read[ltype] ) { - is_doublon=1 ; - type_doublon=ltype ; - } - } - if ( is_doublon ) { - // type_read already stored - ensightGeomFile >> number_of_cell ; - int last_number_of_cell = nbcell_read[type_doublon] ; - int total_number_of_cell = number_of_cell + last_number_of_cell ; - nbcell_read[type_doublon] = total_number_of_cell ; - total_conn[type_doublon].resize(nb_edge[j]*total_number_of_cell); - cout << "-> loading again by adding " << number_of_cell << " to " << last_number_of_cell << " cells connectivities of type " << type_Ensight[j] << " existing" << endl << "-> new results for " << type_Ensight[j] << " are : number of cells connectivities = " << total_number_of_cell << " and total number of values = " << nb_edge[j]*total_number_of_cell << endl ; - for ( int k=0 ; k < nb_edge[j]*number_of_cell ; k++ ) { - ensightGeomFile >> setw(8) >> conn ; - int last_dim = last_number_of_cell*nb_edge[j] ; - total_conn[type_doublon][last_dim+k]=conn ; -// cout << " connectivitie " << last_number_of_cell+k+1 << " read = " << total_conn[type_doublon][last_dim+k] << endl ; - } - } - else { - NumberOfTypes+=1; - iType=NumberOfTypes-1 ; - total_conn.resize(NumberOfTypes) ; - type_read.push_back(mot_lu) ; - ensightGeomFile >> number_of_cell ; - nbcell_read.push_back(number_of_cell) ; - total_conn[iType].resize(nb_edge[j]*number_of_cell); - cout << "-> loading " << number_of_cell << " cell connectivities of type " << type_Ensight[j] << " (total number of values = " << nb_edge[j]*number_of_cell << ") " << endl ; - for ( int k=0 ; k < nb_edge[j]*number_of_cell ; k++ ) { - ensightGeomFile >> setw(8) >> conn ; - total_conn[iType][k]=conn ; -// cout << " connectivitie " << k+1 << " read = " << total_conn[iType][k] << endl ; - } - } - } - } - } - - - - } + deque timeSteps = _ptrMed->getFieldIteration(FieldNames[j]) ; + deque::const_iterator dtit = timeSteps.begin(); + for ( ; dtit!=timeSteps.end(); dtit++) + { + FIELD_ * field = _ptrMed->getField( FieldNames[j], dtit->dt, dtit->it ); + field->read( getId() ); } } - // for compilation on WNT -#ifndef WNT - medGeometryElement classicalTypesCell[NumberOfTypes]; - int nbOfClassicalTypesCell[NumberOfTypes]; -#else // massive with zero size can't exist on Win32 - medGeometryElement* classicalTypesCell = new medGeometryElement(NumberOfTypes); - int* nbOfClassicalTypesCell = new int(NumberOfTypes); -#endif - - int ind=0 ; - for (int k=0 ; ksetNumberOfTypes(NumberOfTypes, MED_EN::MED_CELL) ; - MyMeshing->setTypes(classicalTypesCell, MED_EN::MED_CELL) ; - MyMeshing->setNumberOfElements(nbOfClassicalTypesCell, MED_EN::MED_CELL); - int MeshDimension ; - MeshDimension = 2 ; - for (int k=0 ; k6 ) MeshDimension = 3 ; - } - MyMeshing->setMeshDimension(MeshDimension); + } + else { - for (int k = 0 ; k < NumberOfTypes ; k++) { - int nb_connectivities = total_conn[k].size(); - cout << "-> type = " << k+1 << " has for total number of values of connectivities : " << nb_connectivities << endl ; - int *connectivities = new int[nb_connectivities]; - for (int itab=0 ; itab < nb_connectivities ; itab++) connectivities[itab]=total_conn[k][itab] ; - for (int j=0 ; j<15 ; j++) { - if( type_read[k] == type_Ensight[j] ) { - cout << "-> type read = " << type_read[k] << endl ; - switch ( j+1 ) - { - case 1 : {MyMeshing->setConnectivity(connectivities,MED_EN::MED_CELL,MED_EN::MED_POINT1) ; break ;} - case 2 : {MyMeshing->setConnectivity(connectivities,MED_EN::MED_CELL,MED_EN::MED_SEG2) ; break ;} - case 3 : {MyMeshing->setConnectivity(connectivities,MED_EN::MED_CELL,MED_EN::MED_SEG3) ; break ;} - case 4 : {MyMeshing->setConnectivity(connectivities,MED_EN::MED_CELL,MED_EN::MED_TRIA3) ; break ;} - case 5 : {MyMeshing->setConnectivity(connectivities,MED_EN::MED_CELL,MED_EN::MED_TRIA6) ; break ;} - case 6 : {MyMeshing->setConnectivity(connectivities,MED_EN::MED_CELL,MED_EN::MED_QUAD4) ; break ;} - case 7 : {MyMeshing->setConnectivity(connectivities,MED_EN::MED_CELL,MED_EN::MED_QUAD8) ; break ;} - case 8 : {MyMeshing->setConnectivity(connectivities,MED_EN::MED_CELL,MED_EN::MED_TETRA4) ; break ;} - case 9 : {MyMeshing->setConnectivity(connectivities,MED_EN::MED_CELL,MED_EN::MED_TETRA10) ; break ;} - case 10 : {MyMeshing->setConnectivity(connectivities,MED_EN::MED_CELL,MED_EN::MED_PYRA5) ; break ;} - case 11 : {MyMeshing->setConnectivity(connectivities,MED_EN::MED_CELL,MED_EN::MED_PYRA13) ; break ;} - case 12 : {MyMeshing->setConnectivity(connectivities,MED_EN::MED_CELL,MED_EN::MED_HEXA8) ; break ;} - case 13 : {MyMeshing->setConnectivity(connectivities,MED_EN::MED_CELL,MED_EN::MED_HEXA20) ; break ;} - case 14 : {MyMeshing->setConnectivity(connectivities,MED_EN::MED_CELL,MED_EN::MED_PENTA6) ; break ;} - case 15 : {MyMeshing->setConnectivity(connectivities,MED_EN::MED_CELL,MED_EN::MED_PENTA15) ; break ;} - default : break ; - } - } - } - delete [] connectivities; - } - cout << "-> connectivities OK " << endl ; + open(); // check if can open the case file -// cout << "-> Writing the mesh into med file" << endl ; -// int id = MyMeshing->addDriver(MED_DRIVER,med_filename,MyMeshing->getName()); -// MyMeshing->write(id) ; - cout << "-> Writing the mesh into the med object" << endl ; - _ptrMed->addMesh(MyMeshing); + _CaseFileDriver caseFile( getCaseFileName(), this ); - // chargement des variables depuis le fichier ensight data - // ------------------------------------------------------- - // ! faire le distinguo champs aux noeuds et aux mailles OK - // ! faire le cas des champs multiples + caseFile.read(); -// for (int ifield=0 ; ifield < my_field ; ifield++) { - string cfield_namefile; - if( diren.length() > 0 ) - cfield_namefile = diren + '/' + field_namefile; - else - cfield_namefile = field_namefile; - cout << "-> Entering into the field file " << cfield_namefile << endl ; + int nbOfMeshes = caseFile.getNbMeshes(); + for ( int i = 1; i <= nbOfMeshes; ++i ) + { + MESH* mesh = new MESH; + ENSIGHT_MESH_RDONLY_DRIVER meshDriver(_fileName, mesh); + caseFile.setDataFileName( i, &meshDriver ); + meshDriver.open(); + meshDriver.read(); + _ptrMed->addMesh( mesh ); + } - ifstream ensightFieldFile(cfield_namefile.c_str(),ios::in); - if (ensightFieldFile.is_open() ) + int nbOfFields = caseFile.getNbVariables(); + for ( int i = 1; i <= nbOfFields; i++ ) + { + int nbSteps = caseFile.getNbVarSteps( i ); + for ( int step = 1; step <= nbSteps; ++step ) { - ensightFieldFile.getline(ligne, 80, '\n') ; // read the first line of comment - - medEntityMesh Entity ; - if ( is_node ) { - cout << "-> loading " << NumberOfNodes << " variables on nodes " << endl ; - var.resize(NumberOfNodes); - for (int k = 0 ; k < NumberOfNodes ; k++) ensightFieldFile >> setw(12) >> var[k] ; - Entity = MED_EN::MED_NODE ; - } - else if ( is_element ) { - int NumberOfElements = 0 ; - for ( int i = 0 ; i < NumberOfTypes ; i++ ) { - NumberOfElements = NumberOfElements + nbcell_read[i] ; - } - cout << "-> loading " << NumberOfElements << " variables on elements " << endl ; - var.resize(NumberOfElements); - for (int k = 0 ; k < NumberOfElements ; k++) ensightFieldFile >> setw(12) >> var[k] ; - Entity = MED_EN::MED_CELL ; - } + FIELD_* field = new FIELD; + ENSIGHT_FIELD_RDONLY_DRIVER fieldDriver( _fileName, field ); + caseFile.setDataFileName( i, step, &fieldDriver ); + fieldDriver.open(); + fieldDriver.read(); + _ptrMed->addField( field ); + } + } + } +} +//================================================================================ +/*! + * \brief Create all meshes and fields but not read them + */ +//================================================================================ - SUPPORT * MySupport = new SUPPORT(MyMeshing,"Support",Entity); +void ENSIGHT_MED_RDONLY_DRIVER::readFileStruct() +{ + const char * LOC = "ENSIGHT_MED_RDONLY_DRIVER::read() : " ; + BEGIN_OF_MED(LOC); - int NumberOfComponents = 1 ; - if ( is_vector ) NumberOfComponents = 3 ; - FIELD *MyField = new FIELD(MySupport,NumberOfComponents); + open(); // check if can open the case file -// w_field << "FieldFromEnsight" << ifield << ends ; -// const string FieldName = "FieldFromEnsight" ; -// const string FieldName = w_field.str() ; + _CaseFileDriver caseFile( getCaseFileName(), this ); - const string FieldName = "FieldFromEnsight" ; - MyField->setName(FieldName) ; - string * ComponentsNames = new string[NumberOfComponents] ; - if ( NumberOfComponents == 1 ) ComponentsNames[0] = "scalar comp" ; - else if ( NumberOfComponents == 3 ) { - ComponentsNames[0] = "X comp" ; - ComponentsNames[1] = "Y comp" ; - ComponentsNames[2] = "Z comp" ; - } - - MyField->setComponentsNames(ComponentsNames) ; - const int NumberOfValues = MySupport->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS) ; - MyField->setNumberOfValues(NumberOfValues) ; + caseFile.read(); - int NumberOf = NumberOfValues / NumberOfComponents; - for ( int i = 1 ; i <= NumberOf ; i++) { - for ( int j = 1 ; j <= NumberOfComponents ; j++) { - MyField->setValueIJ(i,j,var[NumberOfComponents*(i-1)+j-1]) ; - } - } - cout << "-> Writing the field into the med object" << endl ; - _ptrMed->addField(MyField); + int nbOfMeshes = caseFile.getNbMeshes(); + vector meshes( nbOfMeshes+1, (MESH*)0 ); + for ( int i = 1; i <= nbOfMeshes; ++i ) + { + MESH* mesh = meshes[ i ] = new MESH; + ENSIGHT_MESH_RDONLY_DRIVER meshDriver(_fileName, mesh, i); + caseFile.setDataFileName( i, &meshDriver ); // retrieve mesh name + setId( mesh->addDriver( meshDriver )); + _ptrMed->addMesh( mesh ); + } + _isFileStructRead = true; -// cout << "-> Writing the field into the med file" << endl ; -// int id = MyField.addDriver(MED_DRIVER,med_filename,MyField.getName()); -// MyField.write(id) ; + int nbOfFields = caseFile.getNbVariables(); + for ( int i = 1; i <= nbOfFields; i++ ) + { + int nbSteps = caseFile.getNbVarSteps( i ); + for ( int step = 1; step <= nbSteps; ++step ) + { + FIELD* field = new FIELD; + ENSIGHT_FIELD_RDONLY_DRIVER fieldDriver( _fileName, field, step ); + int meshIndex = caseFile.setDataFileName( i, step, &fieldDriver ); // retrieve field name + field->addDriver( fieldDriver ); + if ( const SUPPORT* sup = field->getSupport() ) { + if ( meshIndex > nbOfMeshes || !meshes[ meshIndex ]) + meshIndex = 1; + ((SUPPORT*) sup)->setMesh( meshes[ meshIndex ]); } -// } - - - cout << "****************** READ **************** ending " << endl ; - + _ptrMed->addField( field ); + } + } +} } diff --git a/src/MEDMEM/MEDMEM_EnsightMedDriver.hxx b/src/MEDMEM/MEDMEM_EnsightMedDriver.hxx index 93808b3f6..2125c9168 100644 --- a/src/MEDMEM/MEDMEM_EnsightMedDriver.hxx +++ b/src/MEDMEM/MEDMEM_EnsightMedDriver.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef ENSIGHT_MED_DRIVER_HXX #define ENSIGHT_MED_DRIVER_HXX @@ -25,7 +27,7 @@ #include "MEDMEM_Utilities.hxx" #include "MEDMEM_Exception.hxx" -#include "MEDMEM_GenDriver.hxx" +#include "MEDMEM_EnsightUtils.hxx" #include @@ -37,73 +39,78 @@ class MESH; class SUPPORT; class FIELD_; class MED; -// This driver pilots within a ENSIGHT class read/write accesses of fields/meshes -class ENSIGHT_MED_DRIVER : public GENDRIVER + +// ============================================================================== +/*! + * \brief Base of EnSight drivers + */ +// ============================================================================== + +class MEDMEM_EXPORT ENSIGHT_MED_DRIVER : public MEDMEM_ENSIGHT::_CaseFileDriver_User { protected: - MED * const _ptrMed ; // Store 'ENSIGHT_DRIVER (0..n)----(1) ENSIGHT' associations + MED * _ptrMed; // Store 'ENSIGHT_DRIVER (0..n)----(1) ENSIGHT' associations - virtual void openConst() const =0; - virtual void closeConst() const =0; + virtual void openConst() const; public : ENSIGHT_MED_DRIVER(); - ENSIGHT_MED_DRIVER(const string & fileName, MED * const ptrMed); - ENSIGHT_MED_DRIVER(const string & fileName, MED * const ptrMed, - MED_EN::med_mode_acces accessMode); + ENSIGHT_MED_DRIVER(const string & fileName, MED * ptrMed); + ENSIGHT_MED_DRIVER(const string & fileName, MED * ptrMed, + MED_EN::med_mode_acces accessMode); ENSIGHT_MED_DRIVER(const ENSIGHT_MED_DRIVER & driver); virtual ~ENSIGHT_MED_DRIVER(); - // OPERATEUR DE RECOPIE AVEC _ensightFile ?? - - void open(); - void close(); - virtual void write( void ) const = 0 ; - virtual void read( void ) = 0 ; - virtual GENDRIVER * copy (void ) const = 0; + virtual void open(); + virtual void close(); }; -class ENSIGHT_MED_RDONLY_DRIVER : public virtual ENSIGHT_MED_DRIVER +// ============================================================================== +/*! + * \brief Reading EnSight driver + */ +// ============================================================================== + +class MEDMEM_EXPORT ENSIGHT_MED_RDONLY_DRIVER : public virtual ENSIGHT_MED_DRIVER { public : ENSIGHT_MED_RDONLY_DRIVER(); - ENSIGHT_MED_RDONLY_DRIVER(const string & fileName, MED * const ptrMed); + ENSIGHT_MED_RDONLY_DRIVER(const string & fileName, MED * ptrMed); ENSIGHT_MED_RDONLY_DRIVER(const ENSIGHT_MED_RDONLY_DRIVER & driver); virtual ~ENSIGHT_MED_RDONLY_DRIVER(); - void openConst() const; - void closeConst() const; - void write ( void ) const throw (MEDEXCEPTION) ; + virtual void write ( void ) const throw (MEDEXCEPTION) ; virtual void read ( void ) ; -// virtual void readFileStruct ( void ) ; -private: - ifstream * _ensightFile; // The main _ensightFile used to read geom and data _filename + virtual void readFileStruct ( void ) ; GENDRIVER * copy ( void ) const; +private: + + bool _isFileStructRead; }; -class ENSIGHT_MED_WRONLY_DRIVER : public virtual ENSIGHT_MED_DRIVER -{ +// ============================================================================== +/*! + * \brief Writing EnSight driver. + * To set writing format use + * setEnSightFormatForWriting(EnSightFormat) and + * setEnSightBinaryFormatForWriting(bool) + */ +// ============================================================================== +class MEDMEM_EXPORT ENSIGHT_MED_WRONLY_DRIVER : public virtual ENSIGHT_MED_DRIVER +{ public : ENSIGHT_MED_WRONLY_DRIVER(); - ENSIGHT_MED_WRONLY_DRIVER(const string & fileName, MED * const ptrMed); + ENSIGHT_MED_WRONLY_DRIVER(const string & fileName, MED * ptrMed); ENSIGHT_MED_WRONLY_DRIVER(const ENSIGHT_MED_WRONLY_DRIVER & driver); virtual ~ENSIGHT_MED_WRONLY_DRIVER(); - void openConst() const; - void closeConst() const; - void write ( void ) const throw (MEDEXCEPTION) ; -// void writeFrom ( void ) const throw (MEDEXCEPTION) ; + virtual void write ( void ) const throw (MEDEXCEPTION) ; virtual void read ( void ) throw (MEDEXCEPTION) ; -// virtual void readFileStruct ( void ) throw (MEDEXCEPTION) ; -private: - ofstream * _ensightFile; // The main _ensightFile used to write geom and data _filename + //virtual void readFileStruct ( void ) throw (MEDEXCEPTION) ; GENDRIVER * copy ( void ) const; - void writeMesh(MESH * myMesh,int imesh) const ; - void writeSupport(SUPPORT * mySupport) const ; - void writeField(FIELD_ * myField,string name) const ; }; -}; +} #endif /* ENSIGTH_MED_DRIVER_HXX */ diff --git a/src/MEDMEM/MEDMEM_EnsightMeshDriver.cxx b/src/MEDMEM/MEDMEM_EnsightMeshDriver.cxx index 8939639d7..5a78dff48 100644 --- a/src/MEDMEM/MEDMEM_EnsightMeshDriver.cxx +++ b/src/MEDMEM/MEDMEM_EnsightMeshDriver.cxx @@ -1,27 +1,29 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_EnsightMeshDriver.hxx" #include -#include #include +#include #include "MEDMEM_define.hxx" #include "MEDMEM_Family.hxx" @@ -32,75 +34,162 @@ #include "MEDMEM_CellModel.hxx" #include "MEDMEM_Grid.hxx" -#include "MEDMEM_Meshing.hxx" #include "MEDMEM_MedMeshDriver.hxx" using namespace std; using namespace MEDMEM; using namespace MED_EN; +using namespace MEDMEM_ENSIGHT; + +#define TStrTool _ASCIIFileReader +#define TOLERANCE 1e-15 + +//#define ELEMENT_ID_GIVEN + +namespace { + + // --------------------------------------------------------------------- + /*! + * \brief The beginning of mesh description used to distinguish files + * generated by ENSIGHT_MESH_WRONLY_DRIVER from others + */ + const char* theDescriptionPrefix = "Meshing from MedMemory. "; + + // --------------------------------------------------------------------- + /*! + * \brief Default name of a mesh read from EnSight + */ + const char* theDefaultMeshName = "EnsightMesh"; + + // --------------------------------------------------------------------- + /*! + * \brief Max number of types in EnSight part + */ + const int theMaxNbTypes = 20; + + // --------------------------------------------------------------------- + /*! + * \brief Make array with elements == index[i+1]-index[i] + * \param size - result array size + */ + int* getNumbersByIndex( const int* index, int size, const int* elemNumbers=0) + { + int* numbers = new int[size]; + int* n = numbers; + if ( elemNumbers ) { + const int *elem = elemNumbers-1, *elemEnd = elemNumbers + size; + while ( ++elem < elemEnd ) + *n++ = index[*elem] - index[*elem-1]; + } + else { + const int *ind = index, *indEnd = index + size + 1; + while ( ++ind < indEnd ) + *n++ = ind[0] - ind[-1]; + } + return numbers; + } + // --------------------------------------------------------------------- + /*! + * \brief Type used to delete numbers returned by getNumbersByIndex() + */ + typedef _ValueOwner TNumbers; -#define MED_NULL NULL +} // namespace -ENSIGHT_MESH_DRIVER::ENSIGHT_MESH_DRIVER(): GENDRIVER(), - _ptrMesh((MESH *)MED_NULL) + +ENSIGHT_MESH_DRIVER::ENSIGHT_MESH_DRIVER(): _CaseFileDriver_User(), _ptrMesh((MESH *)NULL) { } ENSIGHT_MESH_DRIVER::ENSIGHT_MESH_DRIVER(const string & fileName, - MESH * ptrMesh) : - GENDRIVER(fileName,MED_EN::MED_RDWR), _ptrMesh(ptrMesh) + MESH * ptrMesh) + :_CaseFileDriver_User(fileName,MED_EN::RDWR), _ptrMesh(ptrMesh), + _meshName(ptrMesh->getName()) { } ENSIGHT_MESH_DRIVER::ENSIGHT_MESH_DRIVER(const string & fileName, - MESH * ptrMesh, - MED_EN::med_mode_acces accessMode): - GENDRIVER(fileName,accessMode), _ptrMesh(ptrMesh) + MESH * ptrMesh, + med_mode_acces accessMode) + :_CaseFileDriver_User(fileName,accessMode), _ptrMesh(ptrMesh), _meshName(ptrMesh->getName()) { } -ENSIGHT_MESH_DRIVER::ENSIGHT_MESH_DRIVER(const ENSIGHT_MESH_DRIVER & driver): - GENDRIVER(driver), - _ptrMesh(driver._ptrMesh), - _meshName(driver._meshName) +ENSIGHT_MESH_DRIVER::ENSIGHT_MESH_DRIVER(const ENSIGHT_MESH_DRIVER & driver) + :_CaseFileDriver_User(driver), _ptrMesh(driver._ptrMesh), _meshName(driver._meshName) { } ENSIGHT_MESH_DRIVER::~ENSIGHT_MESH_DRIVER() { - MESSAGE("ENSIGHT_MESH_DRIVER::~ENSIGHT_MESH_DRIVER() has been destroyed"); + MESSAGE_MED("ENSIGHT_MESH_DRIVER::~ENSIGHT_MESH_DRIVER() has been destroyed"); } void ENSIGHT_MESH_DRIVER::setMeshName(const string & meshName) { _meshName = meshName; }; string ENSIGHT_MESH_DRIVER::getMeshName() const { return _meshName; }; +void ENSIGHT_MESH_DRIVER::openConst(bool checkDataFile) const +{ + const char * LOC ="ENSIGHT_MESH_DRIVER::open() : "; + BEGIN_OF_MED(LOC); + + if ( checkDataFile ) + { + if ( getDataFileName().empty() ) + throw MED_EXCEPTION + ( LOCALIZED( STRING(LOC) << "Internal error, geometry file name is empty")); + + if (!canOpenFile( getDataFileName(), getAccessMode() )) + throw MED_EXCEPTION + ( LOCALIZED( STRING(LOC) << "Can not open Ensight Geometry file " << getDataFileName() + << " in access mode " << getAccessMode())); + } + else + { + if ( getCaseFileName().empty() ) + throw MED_EXCEPTION + ( LOCALIZED( STRING(LOC) << "Case file name is empty, " + "please set a correct fileName before calling open()")); + + if ( !canOpenFile( getCaseFileName(), getAccessMode() )) + throw MED_EXCEPTION + ( LOCALIZED( STRING(LOC) << "Can not open Ensight Case file " << getCaseFileName() + << " in access mode " << getAccessMode())); + } + + END_OF_MED(LOC); +} + void ENSIGHT_MESH_DRIVER::open() { openConst() ; } void ENSIGHT_MESH_DRIVER::close() { - closeConst() ; } +// ================================================================================ +// WRONLY +// ================================================================================ + ENSIGHT_MESH_WRONLY_DRIVER::ENSIGHT_MESH_WRONLY_DRIVER() : ENSIGHT_MESH_DRIVER() { - _ensightFile = new ofstream(); } -ENSIGHT_MESH_WRONLY_DRIVER::ENSIGHT_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) : ENSIGHT_MESH_DRIVER(fileName,ptrMesh) +ENSIGHT_MESH_WRONLY_DRIVER::ENSIGHT_MESH_WRONLY_DRIVER(const string & fileName, + MESH * ptrMesh, + bool append) + : ENSIGHT_MESH_DRIVER( fileName, ptrMesh, WRONLY ), _append(append) { - _ensightFile = new ofstream(); } -ENSIGHT_MESH_WRONLY_DRIVER::ENSIGHT_MESH_WRONLY_DRIVER(const ENSIGHT_MESH_WRONLY_DRIVER & driver) : ENSIGHT_MESH_DRIVER(driver),_support(driver._support) +ENSIGHT_MESH_WRONLY_DRIVER::ENSIGHT_MESH_WRONLY_DRIVER(const ENSIGHT_MESH_WRONLY_DRIVER & driver) + : ENSIGHT_MESH_DRIVER(driver),_append(driver._append) { - _ensightFile = new ofstream(); } ENSIGHT_MESH_WRONLY_DRIVER::~ENSIGHT_MESH_WRONLY_DRIVER() { - delete _ensightFile ; } GENDRIVER * ENSIGHT_MESH_WRONLY_DRIVER::copy() const @@ -108,519 +197,985 @@ GENDRIVER * ENSIGHT_MESH_WRONLY_DRIVER::copy() const return new ENSIGHT_MESH_WRONLY_DRIVER(*this) ; } -void ENSIGHT_MESH_WRONLY_DRIVER::openConst() const +void ENSIGHT_MESH_WRONLY_DRIVER::read() throw (MEDEXCEPTION) { + throw MEDEXCEPTION("ENSIGHT_MESH_WRONLY_DRIVER::read : Can't read with a WRONLY driver !"); +} + +//================================================================================ +/*! + * \brief writing + */ +//================================================================================ + +void ENSIGHT_MESH_WRONLY_DRIVER::write() const throw (MEDEXCEPTION) { - const char * LOC = "ENSIGHT_MESH_WRONLY_DRIVER::open()" ; + const char * LOC = "ENSIGHT_MESH_WRONLY_DRIVER::write() : "; + BEGIN_OF_MED(LOC); - BEGIN_OF(LOC); + openConst(false) ; // check if can write to case file - if ( _fileName == "" ) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) - << "_fileName is |\"\"|, please set a correct fileName before calling open()" - ) - ); + // Ensight case organization requires a main file (filename.case) which defines organization - if (!(*_ensightFile).is_open()) - (*_ensightFile).open(_fileName.c_str()) ; + _CaseFileDriver caseFile( getCaseFileName(), this); + if ( _append ) + caseFile.read(); + caseFile.addMesh( this ); + caseFile.write(); // all fields of _CaseFileDriver_User are set by this method - if (!(*_ensightFile)) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open main Ensight file " - << _fileName) - ); + openConst(true) ; // check if can write to data file - END_OF(LOC); -} + cout << "-> creating the Ensight geometry file " << getDataFileName() << endl ; -void ENSIGHT_MESH_WRONLY_DRIVER::closeConst() const { - - const char * LOC = "ENSIGHT_MESH_WRONLY_DRIVER::close() : "; - BEGIN_OF(LOC); - - (*_ensightFile).close(); - - if (!(*_ensightFile)) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not close main Ensight file " - << _fileName) - ); - END_OF(LOC); -} + // Store mesh description and a special mark in the first two description lines each + // of 79 chars length maximum, while MED mesh description is up to 200 chars + const char* line1 = theDescriptionPrefix; + string line2 = _ptrMesh->getDescription(); + for ( int i = 0; i < line2.size(); ++i ) { // protect from gabage + if ( !isascii( line2[ i ])) { + line2.resize( i ); + break; + } + } + if ( line2.size() >= MAX_LINE_LENGTH ) + line2.resize( MAX_LINE_LENGTH ); + + // EnSight will assign node/element visible numbers it-self + const char* line3 = "node id assign"; +#ifdef ELEMENT_ID_GIVEN + const char* line4 = "element id given"; +#else + const char* line4 = "element id assign"; +#endif -void ENSIGHT_MESH_WRONLY_DRIVER::read() throw (MEDEXCEPTION) { - throw MEDEXCEPTION("ENSIGHT_MESH_WRONLY_DRIVER::read : Can't read with a WRONLY driver !"); -} + if ( isBinaryEnSightFormatForWriting() ) + { + // ====================================================== + // Binary + // ====================================================== -void ENSIGHT_MESH_WRONLY_DRIVER::write() const throw (MEDEXCEPTION) -{ + _BinaryFileWriter ensightGeomFile( getDataFileName() ); - const char * LOC = "ENSIGHT_MESH_WRONLY_DRIVER::write() : "; - BEGIN_OF(LOC); + ensightGeomFile.addString("C Binary"); + ensightGeomFile.addString(line1); + ensightGeomFile.addString(line2); + ensightGeomFile.addString(line3); + ensightGeomFile.addString(line4); - // Well we must open ensight file first, because there are - // no other driver than MESH for ENSIGHT that do it ! - openConst() ; + // function to write a support as a part + typedef void (ENSIGHT_MESH_WRONLY_DRIVER::* TWritePart) (_BinaryFileWriter&, const SUPPORT*) const; + TWritePart writePart; + if ( isGoldFormat() ) + { + // GOLD + writePart = & ENSIGHT_MESH_WRONLY_DRIVER::writePartGoldBinary; + } + else + { + // ENSIGHT 6. Write addionally global nodes + writePart = & ENSIGHT_MESH_WRONLY_DRIVER::writePart6Binary; + + // All point are in 3D, so if we are in 1D or 2D, we complete by zero ! + int SpaceDimension = _ptrMesh->getSpaceDimension() ; + int NumberOfNodes = _ptrMesh->getNumberOfNodes() ; + ensightGeomFile.addString("coordinates"); + ensightGeomFile.addInt( NumberOfNodes ); + const double *coordinate = _ptrMesh->getCoordinates(MED_FULL_INTERLACE) ; + if ( SpaceDimension == 3 ) { + ensightGeomFile.addReal(coordinate, NumberOfNodes * SpaceDimension ); + } + else { + typedef _ValueIterator< double > TComponentIt; + vector< TComponentIt > coordCompIt( 3 ); + for (int j=0; j<3; j++, coordinate++) + if ( j < SpaceDimension ) + coordCompIt[ j ] = TComponentIt( coordinate, SpaceDimension ); + else + coordCompIt[ j ] = TComponentIt(); // to iterate on zeros + ensightGeomFile.addReal( coordCompIt, NumberOfNodes, MED_FULL_INTERLACE ); + } + } - // Ensight case organization requires a main file (filename.case) which defines organization - // We also need a geom file (filemane.geo) to store the meshs - // We also need a data file (filemane.data) to store the fields - - string MeshName = _ptrMesh->getName() ; - // In fact, we must take care of all supports - // We restrict Field on all nodes or cells - - cout << "-> creating the Ensight case file " << _fileName << endl ; - (*_ensightFile) << "FORMAT" << endl ; - (*_ensightFile) << "type: ensight" << endl ; - (*_ensightFile) << endl ; - (*_ensightFile) << "GEOMETRY" << endl ; - int len = _fileName.size() ; - string prefix = _fileName.substr(0,len-5); // extraction de .case - string ensight_geomf = prefix + ".geom" ; - string basen = getBaseName((char*)ensight_geomf.c_str()); - (*_ensightFile) << "# Mesh detected with name = " << MeshName << endl ; - (*_ensightFile) << "model: " << basen << endl ; - (*_ensightFile) << endl ; - - ofstream ensightGeomFile(ensight_geomf.c_str(),ios::out); - cout << "-> creating the Ensight geometry file " << ensight_geomf << endl ; - - // ------------ create the Ensight file associated to this meshe - ensightGeomFile << "Ensight Geometry File : " << endl - << "Meshing from MedMemory" << endl ; -// ensightGeomFile << "node id given " << endl ; -// ensightGeomFile << "element id given " << endl ; - ensightGeomFile << "node id assign " << endl ; - ensightGeomFile << "element id assign " << endl ; - ensightGeomFile << "coordinates" << endl ; - // put points (all point are in 3D, so if we are in 1D or 2D, we complete by zero ! + // We put connectivity + + if ( isToWriteEntity( MED_CELL, _ptrMesh )) + { + SUPPORT allCells(_ptrMesh, getMeshName(), MED_CELL ); + (this->*writePart)( ensightGeomFile, &allCells ); + } + // And meshdim-1 connectivity + if ( isToWriteEntity( MED_FACE, _ptrMesh )) + { + SUPPORT allFaces(_ptrMesh, string("SupportOnAll_")+entNames[MED_FACE], MED_FACE ); + (this->*writePart)( ensightGeomFile, & allFaces); + } + else if ( isToWriteEntity(MED_EDGE, _ptrMesh)) + { + SUPPORT allEdges(_ptrMesh, string("SupportOnAll_")+entNames[MED_EDGE], MED_EDGE ); + (this->*writePart)( ensightGeomFile, & allEdges); + } + + // Write all groups as parts + + for ( int ent = MED_CELL; ent < MED_ALL_ENTITIES; ++ent ) + { + medEntityMesh entity = (medEntityMesh) ent; + int nbGroups = _ptrMesh->getNumberOfGroups(entity); + for ( int i=1; i<=nbGroups; i++) + { + const GROUP* group = _ptrMesh->getGroup( entity, i ); + (this->*writePart)( ensightGeomFile, group ); + } + } + + } + else + { + // ====================================================== + // ASCII + // ====================================================== + ofstream ensightGeomFile( getDataFileName().c_str(), ios::out); + ensightGeomFile.setf(ios::scientific); + ensightGeomFile.precision(5); + + ensightGeomFile << line1 << endl + << line2 << endl + << line3 << endl + << line4 << endl; + + // function to write a support as a part + typedef void (ENSIGHT_MESH_WRONLY_DRIVER::* TWritePart) (ofstream&, const SUPPORT*) const; + TWritePart writePart; + if ( isGoldFormat() ) + { + // GOLD + writePart = & ENSIGHT_MESH_WRONLY_DRIVER::writePartGoldASCII; + } + else + { + // ENSIGHT 6. Write addionally global nodes + writePart = & ENSIGHT_MESH_WRONLY_DRIVER::writePart6ASCII; + + // Put points (all point are in 3D, so if we are in 1D or 2D, we complete by zero ! + int SpaceDimension = _ptrMesh->getSpaceDimension() ; + int NumberOfNodes = _ptrMesh->getNumberOfNodes() ; + string zeros; + if (SpaceDimension==2) zeros = " 0.00000e+00"; + if (SpaceDimension==1) zeros = " 0.00000e+00 0.00000e+00"; + ensightGeomFile << "coordinates" << endl + << setw(8) << NumberOfNodes << endl ; + const double *coordinate = _ptrMesh->getCoordinates(MED_FULL_INTERLACE) ; + for (int i=0; i*writePart)( ensightGeomFile, &allCells ); + } + // And meshdim-1 connectivity + if ( isToWriteEntity( MED_FACE, _ptrMesh )) + { + SUPPORT allFaces(_ptrMesh, string("SupportOnAll_")+entNames[MED_FACE], MED_FACE ); + (this->*writePart)( ensightGeomFile, & allFaces); + } + else if ( isToWriteEntity(MED_EDGE, _ptrMesh)) + { + SUPPORT allEdges(_ptrMesh, string("SupportOnAll_")+entNames[MED_EDGE], MED_EDGE ); + (this->*writePart)( ensightGeomFile, & allEdges); + } + + // Write all groups as parts + + for ( int ent = MED_CELL; ent < MED_ALL_ENTITIES; ++ent ) + { + medEntityMesh entity = (medEntityMesh) ent; + int nbGroups = _ptrMesh->getNumberOfGroups(entity); + for ( int i=1; i<=nbGroups; i++) + { + const GROUP* group = _ptrMesh->getGroup( entity, i ); + (this->*writePart)( ensightGeomFile, group ); + } + } + + ensightGeomFile.close(); + + } // end ASCII format + +} // ENSIGHT_MESH_WRONLY_DRIVER::write() + +//================================================================================ +/*! + * \brief Write support as an EnSight Gold part + */ +//================================================================================ + +void ENSIGHT_MESH_WRONLY_DRIVER::writePartGoldBinary(_BinaryFileWriter& ensightGeomFile, + const SUPPORT* support) const +{ + // part number + int partNum = getPartNumber( support ); + if ( !partNum ) + throw MED_EXCEPTION ( LOCALIZED( STRING("Internal error: invalid part number"))); + ensightGeomFile.addString( "part" ); + ensightGeomFile.addInt( partNum ); + + // group/mesh name + ensightGeomFile.addString( support->getName() ); + + // get geom types + medEntityMesh entity = support->getEntity(); + int nbTypes = support->getNumberOfTypes(); + const medGeometryElement* geoType = support->getTypes(); + + const int * connectivity = 0; + const int * elemConnectivity = 0; + const int * index = 0; + int j; + + // COORDINATES Gold binary + // =================================================================================== + // In Ensight, coordinates of nodes of support elements are in MED_NO_INTERLACE mode. + // We are to write only nodes belonging to elements of the support and + // nodal connectivity should refer to these nodes. + map med2ensIds; + map::iterator medEnsIt; int SpaceDimension = _ptrMesh->getSpaceDimension() ; int NumberOfNodes = _ptrMesh->getNumberOfNodes() ; - ensightGeomFile << NumberOfNodes << endl ; - const double *coordinate = _ptrMesh->getCoordinates(MED_FULL_INTERLACE) ; - ensightGeomFile.setf(ios::scientific); - ensightGeomFile.precision(5); - for (int i=0;igetNumberOfTypes(MED_CELL) ; - const CELLMODEL * cells_type =_ptrMesh->getCellsTypes(MED_CELL) ; - ensightGeomFile << "part 1 " << endl ; - ensightGeomFile << "elements are following " << endl ; - - // we put connectivity - for (int i=0;igetNumberOfElements(MED_CELL,cells_type[i].getType()) ; - int *filter = (int*) NULL ; - switch (cells_type[i].getType()) - { - case MED_POINT1 : { - ensightGeomFile << "point" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[1] ; - filter[0] = 0 ; - break ; - } - case MED_SEG2 : { - ensightGeomFile << "bar2" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[2] ; - filter[0] = 0 ; - filter[1] = 1 ; - break ; - } - case MED_SEG3 : { - filter = new int[3] ; - filter[0] = 0 ; - filter[1] = 2 ; - filter[2] = 1 ; - break ; - } - case MED_TRIA3 : { - ensightGeomFile << "tria3" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[3] ; - filter[0] = 0 ; - filter[1] = 2 ; - filter[2] = 1 ; - break ; - } - case MED_QUAD4 : { - ensightGeomFile << "quad4" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[4] ; - filter[0] = 0 ; - filter[1] = 3 ; - filter[2] = 2 ; - filter[3] = 1 ; - break ; - } - case MED_TRIA6 : { - ensightGeomFile << "tria6" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[6] ; - filter[0] = 0 ; - filter[1] = 2 ; - filter[2] = 1 ; - filter[3] = 5 ; - filter[4] = 4 ; - filter[5] = 3 ; - break ; - } - case MED_QUAD8 : { - ensightGeomFile << "quad8" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[8] ; - filter[0] = 0 ; - filter[1] = 3 ; - filter[2] = 2 ; - filter[3] = 1 ; - filter[4] = 7 ; - filter[5] = 6 ; - filter[6] = 5 ; - filter[7] = 4 ; - break ; - } - case MED_TETRA4 : { - ensightGeomFile << "tetra4" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[4] ; - filter[0] = 0 ; - filter[1] = 1 ; - filter[2] = 3 ; // 3td element in med are 4th in vtk (array begin at 0 !) - filter[3] = 2 ; // 4th element in med are 3rd in vtk (array begin at 0 !) - break ; - } - case MED_PYRA5 : { - ensightGeomFile << "pyramid5" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[5] ; - filter[0] = 0 ; - filter[1] = 3 ; // 2nd element in med are 4th in vtk (array begin at 0 !) - filter[2] = 2 ; - filter[3] = 1 ; // 4th element in med are 2nd in vtk (array begin at 0 !) - filter[4] = 4 ; - break ; - } - case MED_PENTA6 : { - ensightGeomFile << "penta6" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[6] ; - filter[0] = 0 ; - filter[1] = 2 ; - filter[2] = 1 ; - filter[3] = 3 ; - filter[4] = 4 ; - filter[5] = 5 ; - break ; - } - case MED_HEXA8 : { - ensightGeomFile << "hexa8" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[8] ; - filter[0] = 0 ; - filter[1] = 3 ; - filter[2] = 2 ; - filter[3] = 1 ; - filter[4] = 4 ; - filter[5] = 7 ; - filter[6] = 6 ; - filter[7] = 5 ; - break ; - } - case MED_TETRA10 : { - ensightGeomFile << "tetra10" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[10] ; - filter[0] = 0 ; - filter[1] = 2 ; - filter[2] = 1 ; - filter[3] = 3 ; - filter[4] = 6 ; - filter[5] = 5 ; - filter[6] = 4 ; - filter[7] = 7 ; - filter[8] = 9 ; - filter[9] = 8 ; - break ; - } - case MED_PYRA13 : { - ensightGeomFile << "pyramid13" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - break ; - } - case MED_PENTA15 : { - ensightGeomFile << "penta15" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - break ; - } - case MED_HEXA20 : { - ensightGeomFile << "hexa20" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - break ; - } - default : { - break ; - } - } - if (filter==NULL) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": MED element type not supported yet : " << cells_type[i].getName() ) ) ; - int nodes_cell = cells_type[i].getNumberOfNodes(); - const int * connectivityArray = _ptrMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,cells_type[i].getType()); - for (int j=0;jgetNumberOfTypes() ; - const medGeometryElement * geo_type = _support[i]->getTypes() ; - - ensightGeomFile << "part " << i+2 << endl; - ensightGeomFile << "connectivities description" << endl; - - int nodes_cell; - // we put connectivity - for (int i=0;igetNumberOfElements(geo_type[i]) ; - int *filter = (int*) NULL ; // index in ensight connectivity - switch (geo_type[i]){ - case MED_POINT1 : { - nodes_cell=1; - ensightGeomFile << "point" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[1] ; - filter[0] = 0 ; - break ; - } - case MED_SEG2 : { - nodes_cell=2; - ensightGeomFile << "bar2" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[2] ; - filter[0] = 0 ; - filter[1] = 1 ; - break ; - } - case MED_SEG3 : { - nodes_cell=3; - ensightGeomFile << "bar3" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[3] ; - filter[0] = 0 ; - filter[1] = 2 ; - filter[2] = 1 ; - break ; - } - case MED_TRIA3 : { - nodes_cell=3; - ensightGeomFile << "tria3" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[3] ; - filter[0] = 0 ; - filter[1] = 2 ; - filter[2] = 1 ; - break ; - } - case MED_QUAD4 : { - nodes_cell=4; - ensightGeomFile << "quad4" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[4] ; - filter[0] = 0 ; - filter[1] = 3 ; - filter[2] = 2 ; - filter[3] = 1 ; - break ; - } - case MED_TRIA6 : { - nodes_cell=6; - ensightGeomFile << "tria6" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[6] ; - filter[0] = 0 ; - filter[1] = 2 ; - filter[2] = 1 ; - filter[3] = 5 ; - filter[4] = 4 ; - filter[5] = 3 ; - break ; - } - case MED_QUAD8 : { - nodes_cell=8; - ensightGeomFile << "quad8" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[8] ; - filter[0] = 0 ; - filter[1] = 3 ; - filter[2] = 2 ; - filter[3] = 1 ; - filter[4] = 7 ; - filter[5] = 6 ; - filter[6] = 5 ; - filter[7] = 4 ; - break ; - } - case MED_TETRA4 : { - nodes_cell=4; - ensightGeomFile << "tetra4" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[4] ; - filter[0] = 0 ; - filter[1] = 1 ; - filter[2] = 3 ; // 3td element in med are 4th in ensight (array begin at 0 !) - filter[3] = 2 ; // 4th element in med are 3rd in ensight (array begin at 0 !) - break ; - } - case MED_PYRA5 : { - nodes_cell=5; - ensightGeomFile << "pyramid5" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[5] ; - filter[0] = 0 ; - filter[1] = 3 ; // 2nd element in med are 4th in ensight (array begin at 0 !) - filter[2] = 2 ; - filter[3] = 1 ; // 4th element in med are 2nd in ensight (array begin at 0 !) - filter[4] = 4 ; - break ; - } - case MED_PENTA6 : { - nodes_cell=6; - ensightGeomFile << "penta6" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[6] ; - filter[0] = 0 ; - filter[1] = 2 ; - filter[2] = 1 ; - filter[3] = 3 ; - filter[4] = 5 ; - filter[5] = 4 ; - break ; - } - case MED_HEXA8 : { - nodes_cell=8; - ensightGeomFile << "hexa8" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[8] ; - filter[0] = 0 ; - filter[1] = 3 ; - filter[2] = 2 ; - filter[3] = 1 ; - filter[4] = 4 ; - filter[5] = 7 ; - filter[6] = 6 ; - filter[7] = 5 ; - break ; - } - case MED_TETRA10 : { - nodes_cell=10; - ensightGeomFile << "tetra10" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - filter = new int[10] ; - filter[0] = 0 ; - filter[1] = 2 ; - filter[2] = 1 ; - filter[3] = 3 ; - filter[4] = 6 ; - filter[5] = 5 ; - filter[6] = 4 ; - filter[7] = 7 ; - filter[8] = 9 ; - filter[9] = 8 ; - break ; - } - case MED_PYRA13 : { - nodes_cell=13; - ensightGeomFile << "pyramid13" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - break ; - } - case MED_PENTA15 : { - nodes_cell=15; - ensightGeomFile << "penta15" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - break ; - } - case MED_HEXA20 : { - nodes_cell=20; - ensightGeomFile << "hexa20" << endl ; - ensightGeomFile << setw(8) << numberOfCell << endl ; - break ; - } - default : { - break ; - } - } - if (filter==NULL) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": MED element type not supported yet : " << cells_type[i].getName() ) ) ; - - const int * connectivityArray = _ptrMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,_support[i]->getEntity(),geo_type[i]); - const int *type = _support[i]->getNumber(geo_type[i]); - - for (int j=0;jisOnAllElements() ) + { + // nb of nodes + ensightGeomFile.addString( "coordinates" ); + ensightGeomFile.addInt( NumberOfNodes ); + + // coordinates + const double *coordinate = _ptrMesh->getCoordinates(MED_FULL_INTERLACE); + typedef _ValueIterator< double > TComponentIt; + vector< TComponentIt > coordCompIt( 1 ); + for (int j=0; j floatCoords( NumberOfNodes ); + for ( j=0; j < SPACE_DIM; j++) { // loop on dimensions + medEnsIt = med2ensIds.begin(); + if ( j < SpaceDimension ) { + const double *coordinate = _ptrMesh->getCoordinates(MED_FULL_INTERLACE) + j; + for (int i=0; ifirst-1) * SpaceDimension]; + } + else if ( j-1 < SpaceDimension ) { + for (int i=0; isecond = j; + } + + // CONNECTIVITY Gold binary + // =================================================================================== + // loop on types + for (int i=0; igetNumberOfElements(medType); + int nbCellNodes = ensightType._medIndex.size(); + + // type name and nb cells + ensightGeomFile.addString( ensightType._name ); + ensightGeomFile.addInt( numberOfCell ); + + vector nodeIds; + + // ------------------------------------------------- + if ( support->isOnAllElements() ) + { +#ifdef ELEMENT_ID_GIVEN + // elem numbers + nodeIds.resize( numberOfCell ); + for ( j = 1; j <= numberOfCell; j++) + nodeIds[ j-1 ] = j; + ensightGeomFile.addInt( nodeIds ); + + if ( entity != MED_NODE ) nodeIds.clear(); +#endif + + if ( nbCellNodes > 1 ) // STANDARD ELEMENTS connectivity + { + connectivity = _ptrMesh->getConnectivity(MED_FULL_INTERLACE, MED_NODAL, + entity, medType); + nodeIds.reserve( numberOfCell * nbCellNodes); + for (j = 0 ; j < numberOfCell; j++, connectivity += nbCellNodes) + for (int k=0; kgetPolygonsConnectivity(MED_NODAL, entity); + index = _ptrMesh->getPolygonsConnectivityIndex(MED_NODAL, entity); + int connLength = _ptrMesh->getPolygonsConnectivityLength(MED_NODAL, entity); + // number of nodes in each element + { + TIntOwner nbNodesInPoly( getNumbersByIndex( index, numberOfCell )); + ensightGeomFile.addInt( nbNodesInPoly.myValues, numberOfCell ); + } // nbNodesInPoly is deleted here + + // connectivity + ensightGeomFile.addInt( connectivity, connLength ); + } + else // POLYHEDRA connectivity + { + connectivity = _ptrMesh->getPolyhedronConnectivity(MED_NODAL); + index = _ptrMesh->getPolyhedronIndex(MED_NODAL); + const int * fIndex = _ptrMesh->getPolyhedronFacesIndex(); + int connLength = _ptrMesh->getPolyhedronConnectivityLength(MED_NODAL); + int nbFaces = _ptrMesh->getNumberOfPolyhedronFaces(); + // nb of faces in each polyhedron + { + TIntOwner nbFacesInPoly( getNumbersByIndex( index, numberOfCell )); + ensightGeomFile.addInt( nbFacesInPoly.myValues, numberOfCell ); + } + // number of nodes in each face + { + TIntOwner nbNodesInFace( getNumbersByIndex( fIndex, nbFaces )); + ensightGeomFile.addInt( nbNodesInFace.myValues, nbFaces ); + } + // connectivity + ensightGeomFile.addInt( connectivity, connLength ); + } + } + // ------------------------------------------------- + else // support is not on all elements + { + const int *number = support->getNumber(medType); + +#ifdef ELEMENT_ID_GIVEN + ensightGeomFile.addInt( number, numberOfCell ); +#endif + if ( nbCellNodes > 1 ) // STANDARD ELEMENTS connectivity + { + connectivity = _ptrMesh->getConnectivity(MED_FULL_INTERLACE, MED_NODAL, + entity, MED_ALL_ELEMENTS); + index = _ptrMesh->getConnectivityIndex(MED_FULL_INTERLACE, entity); + + nodeIds.reserve( numberOfCell * nbCellNodes); + for (j=0; jgetPolygonsConnectivity(MED_NODAL, entity); + index = _ptrMesh->getPolygonsConnectivityIndex(MED_NODAL, entity); + int connLength = _ptrMesh->getPolygonsConnectivityLength(MED_NODAL, entity); + int nbStdElems = _ptrMesh->getNumberOfElements(entity,MED_ALL_ELEMENTS); + // number of nodes in each element + { + TIntOwner nbNodesInPoly( getNumbersByIndex( index-nbStdElems, numberOfCell, number )); + ensightGeomFile.addInt( nbNodesInPoly.myValues, numberOfCell ); + } // nbNodesInPoly is deleted here + + // connectivity + nodeIds.reserve( connLength ); + for ( j = 0; j < numberOfCell; ++j ) + { + int elem = number[ j ] - nbStdElems; + elemConnectivity = connectivity + index[ elem-1 ]-1; + const int* connEnd = connectivity + index[ elem ]-1; + while ( elemConnectivity < connEnd ) + nodeIds.push_back( med2ensIds[ *elemConnectivity++ ]); + } + ensightGeomFile.addInt( nodeIds ); + } + else // POLYHEDRA connectivity + { + connectivity = _ptrMesh->getPolyhedronConnectivity(MED_NODAL); + index = _ptrMesh->getPolyhedronIndex(MED_NODAL); + const int * fIndex = _ptrMesh->getPolyhedronFacesIndex(); + int connLength = _ptrMesh->getPolyhedronConnectivityLength(MED_NODAL); + int nbStdElems = _ptrMesh->getNumberOfElements(entity,MED_ALL_ELEMENTS); + // nb of faces in each polyhedron + { + TIntOwner nbFacesInPoly( getNumbersByIndex( index-nbStdElems, numberOfCell, number )); + ensightGeomFile.addInt( nbFacesInPoly.myValues, numberOfCell ); + } + // number of nodes in each face + nodeIds.reserve( connLength ); + for ( j = 0; j < numberOfCell; ++j ) + { + int elem = number[ j ] - nbStdElems; + int f1 = index[ elem-1 ] - 1, f2 = index[ elem ] - 1; + int nbFaces = f2 - f1; + { + TIntOwner nbNodesInFace( getNumbersByIndex( &fIndex[ f1 ], nbFaces )); + ensightGeomFile.addInt( nbNodesInFace.myValues, nbFaces ); + } + elemConnectivity = connectivity + fIndex[ f1 ] - 1; + const int* connEnd = connectivity + fIndex[ f2 ] - 1; + while ( elemConnectivity < connEnd ) + nodeIds.push_back( med2ensIds[ *elemConnectivity++ ]); + } + // connectivity + ensightGeomFile.addInt( nodeIds ); + } + } + } +} // writePartGoldBinary() + +//================================================================================ +/*! + * \brief Write support as an EnSight Gold part + */ +//================================================================================ + +void ENSIGHT_MESH_WRONLY_DRIVER::writePartGoldASCII(ofstream& ensightGeomFile, + const SUPPORT* support) const +{ + const int iw = 10; + + // part number + int partNum = getPartNumber( support ); + ensightGeomFile << "part" << endl + << setw(iw) << partNum << endl; + if ( !partNum ) + throw MED_EXCEPTION ( LOCALIZED( STRING("Internal error: invalid part number"))); + + // group/mesh name + ensightGeomFile << support->getName() << endl; + + // get geom types + medEntityMesh entity = support->getEntity(); + int nbTypes = support->getNumberOfTypes(); + const medGeometryElement* geoType = support->getTypes(); + + const int * connectivity = 0; + const int * elemConnectivity = 0; + const int * index = 0; + int j; + + // COORDINATES Gold ASCII + // =================================================================================== + // In Ensight, coordinates of nodes of support elements are in MED_NO_INTERLACE mode. + // We are to write only nodes belonging to elements of the support and + // nodal connectivity should refer to these nodes. + map med2ensIds; + map::iterator medEnsIt; + int SpaceDimension = _ptrMesh->getSpaceDimension() ; + int NumberOfNodes = _ptrMesh->getNumberOfNodes() ; + string zeroStr = " 0.00000e+00"; + // ----------------------------------- + if ( support->isOnAllElements() ) + { + // nb of nodes + ensightGeomFile << "coordinates" << endl + << setw(iw) << NumberOfNodes << endl ; + + // coordinates + for (j=0; jgetCoordinates(MED_FULL_INTERLACE) + j; + for (int i=0; igetCoordinates(MED_FULL_INTERLACE) + j; + for (int i=0; ifirst-1) * SpaceDimension] << endl; + } + else { + for (int i=0; isecond = j; + } + + // CONNECTIVITY Gold ASCII + // =================================================================================== + // loop on types + for (int i=0; igetNumberOfElements(medType); + int nbCellNodes = ensightType._medIndex.size(); + + // type name and nb cells + ensightGeomFile << ensightType._name << endl + << setw(iw) << numberOfCell << endl; + + // ----------------------------------- + if ( support->isOnAllElements() ) + { +#ifdef ELEMENT_ID_GIVEN + for ( j = 1; j <= numberOfCell; j++) + ensightGeomFile << setw(iw) << j << endl; +#endif + + if ( nbCellNodes > 1 ) // STANDARD ELEMENTS connectivity + { + connectivity = _ptrMesh->getConnectivity(MED_FULL_INTERLACE, MED_NODAL, + entity, medType); + for (j = 0 ; j < numberOfCell; j++, connectivity += nbCellNodes) { + for (int k=0; kgetPolygonsConnectivity(MED_NODAL, entity); + index = _ptrMesh->getPolygonsConnectivityIndex(MED_NODAL, entity); + // number of nodes in each element + const int* ind = index; + for (j = 0 ; j < numberOfCell; j++, ++ind) + ensightGeomFile << setw(iw) << ( ind[1] - ind[0] ) << endl; + + // connectivity + for (j = 0; j < numberOfCell; j++, ++index) { + nbCellNodes = index[1] - index[0]; + for (int k=0; kgetPolyhedronConnectivity(MED_NODAL); + index = _ptrMesh->getPolyhedronIndex(MED_NODAL); + const int * fIndex = _ptrMesh->getPolyhedronFacesIndex(); + int nbFaces = _ptrMesh->getNumberOfPolyhedronFaces(); + // nb of faces in each polyhedron + const int* ind = index; + for (j = 0 ; j < numberOfCell; j++, ++ind) + ensightGeomFile << setw(iw) << ( ind[1] - ind[0] ) << endl ; + // number of nodes in each face + ind = fIndex; + for (j = 0 ; j < nbFaces; j++, ++ind) + ensightGeomFile << setw(iw) << ( ind[1] - ind[0] ) << endl ; + // connectivity of each face + for (j = 0 ; j < nbFaces; j++, ++fIndex) { + int nbFaceNodes = fIndex[1] - fIndex[0]; + for (int k=0; kgetNumber(medType); + +#ifdef ELEMENT_ID_GIVEN + for ( j = 0; j < numberOfCell; j++) + ensightGeomFile << setw(iw) << number[j] << endl; +#endif + if ( nbCellNodes > 1 ) // STANDARD ELEMENTS connectivity + { + connectivity = _ptrMesh->getConnectivity(MED_FULL_INTERLACE, MED_NODAL, + entity, MED_ALL_ELEMENTS); + index = _ptrMesh->getConnectivityIndex(MED_FULL_INTERLACE, entity); + + for (j=0; jgetPolygonsConnectivity(MED_NODAL, entity); + index = _ptrMesh->getPolygonsConnectivityIndex(MED_NODAL, entity); + int nbStdElems = _ptrMesh->getNumberOfElements(entity,MED_ALL_ELEMENTS); + // number of nodes in each element + for (j = 0 ; j < numberOfCell; j++) { + int elem = number[j] - nbStdElems; + ensightGeomFile << setw(iw) << ( index[elem] - index[elem-1] ) << endl; + } + // connectivity + for ( j = 0; j < numberOfCell; ++j ) { + int elem = number[ j ] - nbStdElems; + elemConnectivity = connectivity + index[ elem-1 ]-1; + const int* connEnd = connectivity + index[ elem ]-1; + while ( elemConnectivity < connEnd ) + ensightGeomFile << setw(iw) << med2ensIds[ *elemConnectivity++ ]; + ensightGeomFile << endl; + } + } + else // POLYHEDRA connectivity + { + connectivity = _ptrMesh->getPolyhedronConnectivity(MED_NODAL); + index = _ptrMesh->getPolyhedronIndex(MED_NODAL); + const int * fIndex = _ptrMesh->getPolyhedronFacesIndex(); + int nbStdElems = _ptrMesh->getNumberOfElements(entity,MED_ALL_ELEMENTS); + // nb of faces in each polyhedron + for (j = 0 ; j < numberOfCell; j++) { + int elem = number[j] - nbStdElems; + ensightGeomFile << setw(iw) << ( index[elem] - index[elem-1] ) << endl; + } + // number of nodes in each face + for ( j = 0; j < numberOfCell; ++j ) { + int elem = number[ j ] - nbStdElems; + int f1 = index[ elem-1 ], f2 = index[ elem ]; + while ( f1 < f2 ) { + ensightGeomFile << setw(iw) << ( fIndex[f1] - fIndex[f1-1] ) << endl; + ++f1; + } + } + // connectivity of each face + for ( j = 0; j < numberOfCell; ++j ) { + int elem = number[ j ] - nbStdElems; + int f1 = index[ elem-1 ] - 1, f2 = index[ elem ] - 1; + while ( f1 < f2 ) { + int n1 = fIndex[f1]-1, n2 = fIndex[f1+1]-1; + ++f1; + while ( n1 < n2 ) + ensightGeomFile << setw(iw) << connectivity[ n1++ ]; + ensightGeomFile << endl ; + } + } + } + } + } +} // writePartGoldASCII() + +//================================================================================ +/*! + * \brief Write support as an Ensight6 part + */ +//================================================================================ + +void ENSIGHT_MESH_WRONLY_DRIVER::writePart6Binary(_BinaryFileWriter& ensightGeomFile, + const SUPPORT* support) const +{ + // part number + int partNum = getPartNumber( support ); + ensightGeomFile.addString( STRING("part ") << partNum ); + if ( !partNum ) + throw MED_EXCEPTION ( LOCALIZED( STRING("Internal error: invalid part number"))); + + // group/mesh name + ensightGeomFile.addString( support->getName() ); + + // get geom types + medEntityMesh entity = support->getEntity(); + int nbTypes = support->getNumberOfTypes(); + const medGeometryElement* geoType = support->getTypes(); + + int j = 1; + const int * connectivity = 0; + if ( entity != MED_NODE ) + connectivity = _ptrMesh->getConnectivity(MED_FULL_INTERLACE, MED_NODAL, + entity, MED_ALL_ELEMENTS); + const int * elemConnectivity = connectivity; + + // CONNECTIVITY Ensight 6 binary + // =================================================================================== + // loop on types + for (int i=0; igetNumberOfElements(medType); + ensightGeomFile.addString( ensightType._name ); + ensightGeomFile.addInt( numberOfCell ); + + vector nodeIds; + // ------------------------------------------------- + if ( support->isOnAllElements() ) + { +#ifdef ELEMENT_ID_GIVEN + nodeIds.resize( numberOfCell ); + for ( j = 1; j <= numberOfCell; j++) + nodeIds[ j-1 ] = j; + ensightGeomFile.addInt( nodeIds ); +#endif + if ( entity == MED_NODE ) { +#if !defined(ELEMENT_ID_GIVEN) + nodeIds.resize( numberOfCell * nbCellNodes); + for ( j = 1; j <= numberOfCell; j++) + nodeIds[ j-1 ] = j; +#endif + } + else { + nodeIds.clear(); + nodeIds.reserve( numberOfCell * nbCellNodes ); + for (j = 0 ; j < numberOfCell; j++, elemConnectivity += nbCellNodes) + for (int k=0; kgetNumber(medType); + +#ifdef ELEMENT_ID_GIVEN + ensightGeomFile.addInt( number, numberOfCell ); +#endif + if ( entity == MED_NODE ) { + ensightGeomFile.addInt( number, numberOfCell ); + } + else { + const int* index = _ptrMesh->getConnectivityIndex(MED_FULL_INTERLACE, entity); + + nodeIds.reserve( numberOfCell * nbCellNodes); + for (j=0; jgetName() << endl; + + // get geom types + medEntityMesh entity = support->getEntity(); + int nbTypes = support->getNumberOfTypes(); + const medGeometryElement* geoType = support->getTypes(); + + int j = 1; + const int * connectivity = 0; + if ( entity != MED_NODE ) + connectivity = _ptrMesh->getConnectivity(MED_FULL_INTERLACE, MED_NODAL, + entity, MED_ALL_ELEMENTS); + const int * elemConnectivity = connectivity; + + // CONNECTIVITY Ensight 6 ASCII + // =================================================================================== + // loop on types + for (int i=0; igetNumberOfElements(medType); + ensightGeomFile << ensightType._name << endl + << setw(iw) << numberOfCell << endl; + + // ------------------------------------------------- + if ( support->isOnAllElements() ) + { + if ( entity == MED_NODE ) { + for ( j = 1; j <= numberOfCell; j++) { +#ifdef ELEMENT_ID_GIVEN + ensightGeomFile << setw(iw) << j; +#endif + ensightGeomFile << setw(iw) << j << endl; + } + } + else { + for (j = 1 ; j <= numberOfCell; j++, elemConnectivity += nbCellNodes) { +#ifdef ELEMENT_ID_GIVEN + ensightGeomFile << setw(iw) << elem++; +#endif + for (int k=0; kgetNumber(medType); + if ( entity == MED_NODE ) { + for (j=0; jgetConnectivityIndex(MED_FULL_INTERLACE, entity); + + for (j=0; jgetNumberOfGroups(medEntityMesh(ent)); + nbParts += nbGroups; + } + return nbParts; } -// void ENSIGHT_MESH_WRONLY_DRIVER::writeSupport(SUPPORT * mySupport) const { -// const char * LOC = "ENSIGHT_MESH_WRONLY_DRIVER::writeSupport(SUPPORT *) : " ; -// BEGIN_OF(LOC) ; -// MESSAGE(LOC << "Not yet implemented, acting on the object " << *mySupport); -// END_OF(LOC) ; -// } +// ================================================================================ +// RDONLY +// ================================================================================ -ENSIGHT_MESH_RDONLY_DRIVER::ENSIGHT_MESH_RDONLY_DRIVER() : ENSIGHT_MESH_DRIVER() +ENSIGHT_MESH_RDONLY_DRIVER::ENSIGHT_MESH_RDONLY_DRIVER() + : ENSIGHT_MESH_DRIVER(), _indexInCaseFile(1) { - _ensightFile = new ifstream(); } -ENSIGHT_MESH_RDONLY_DRIVER::ENSIGHT_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh) : ENSIGHT_MESH_DRIVER(fileName,ptrMesh) +ENSIGHT_MESH_RDONLY_DRIVER::ENSIGHT_MESH_RDONLY_DRIVER(const string & fileName, + MESH * ptrMesh, + int index) + : ENSIGHT_MESH_DRIVER(fileName,ptrMesh,RDONLY), _indexInCaseFile( index ) { - _ensightFile = new ifstream(); } -ENSIGHT_MESH_RDONLY_DRIVER::ENSIGHT_MESH_RDONLY_DRIVER(const ENSIGHT_MESH_RDONLY_DRIVER & driver) : ENSIGHT_MESH_DRIVER(driver) +ENSIGHT_MESH_RDONLY_DRIVER::ENSIGHT_MESH_RDONLY_DRIVER(const ENSIGHT_MESH_RDONLY_DRIVER & driver) : ENSIGHT_MESH_DRIVER(driver), _indexInCaseFile( driver._indexInCaseFile ) { - _ensightFile = new ifstream(); } ENSIGHT_MESH_RDONLY_DRIVER::~ENSIGHT_MESH_RDONLY_DRIVER() { - delete _ensightFile ; } GENDRIVER * ENSIGHT_MESH_RDONLY_DRIVER::copy() const @@ -628,266 +1183,2069 @@ GENDRIVER * ENSIGHT_MESH_RDONLY_DRIVER::copy() const return new ENSIGHT_MESH_RDONLY_DRIVER(*this) ; } -void ENSIGHT_MESH_RDONLY_DRIVER::openConst() const { +void ENSIGHT_MESH_RDONLY_DRIVER::write() const throw (MEDEXCEPTION) +{ + throw MEDEXCEPTION("ENSIGHT_MESH_RDONLY_DRIVER::write : Can't write with a RDONLY driver !"); +} - const char * LOC ="ENSIGHT_MESH_RDONLY_DRIVER::open() : "; +void ENSIGHT_MESH_RDONLY_DRIVER::merge ( const GENDRIVER& driver ) +{ + _CaseFileDriver_User::merge( driver ); - BEGIN_OF(LOC); + const ENSIGHT_MESH_RDONLY_DRIVER* other = + dynamic_cast< const ENSIGHT_MESH_RDONLY_DRIVER* >( &driver ); + if ( other ) { + if ( _indexInCaseFile < other->_indexInCaseFile ) + _indexInCaseFile = other->_indexInCaseFile; + } +} - if ( _fileName == "" ) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) - << "_fileName is |\"\"|, please set a correct fileName before calling open()" - ) - ); +//================================================================================ +/*! + * \brief Read mesh in all supported formats + */ +//================================================================================ - if (!(*_ensightFile).is_open()) - (*_ensightFile).open(_fileName.c_str()) ; +void ENSIGHT_MESH_RDONLY_DRIVER::read() throw (MEDEXCEPTION) +{ + const char * LOC = "ENSIGHT_MESH_RDONLY_DRIVER::read() : " ; + BEGIN_OF_MED(LOC); - if (!(*_ensightFile)) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open main Ensight file " - << _fileName) - ); - END_OF(LOC); -} + openConst(false); // check if can read case file -void ENSIGHT_MESH_RDONLY_DRIVER::closeConst() const { - - const char * LOC = "ENSIGHT_MESH_RDONLY_DRIVER::close() : "; - BEGIN_OF(LOC); - - (*_ensightFile).close(); - - if (!(*_ensightFile)) - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not close main Ensight file " - << _fileName) - ); - END_OF(LOC); -} + _CaseFileDriver caseFile( getCaseFileName(), this); + caseFile.read(); + caseFile.setDataFileName( _indexInCaseFile, this ); // data from Case File is passed here -void ENSIGHT_MESH_RDONLY_DRIVER::write() const throw (MEDEXCEPTION) { - throw MEDEXCEPTION("ENSIGHT_MESH_RDONLY_DRIVER::write : Can't write with a RDONLY driver !"); -} + openConst(true); // check if can read data file -void ENSIGHT_MESH_RDONLY_DRIVER::read() { + cout << "-> Entering into the geometry file " << getDataFileName() << endl ; - const char * LOC = "ENSIGHT_MESH_RDONLY_DRIVER::read() : " ; - BEGIN_OF(LOC); + _InterMed* imed = new _InterMed(); + imed->_medMesh = getMesh(); + imed->_isOwnMedMesh = false; + imed->_needSubParts = ( caseFile.getNbVariables() > 0 ); + imed->groupes.reserve(1000); - openConst() ; + // to let field drivers know eventual indices of values + if ( imed->_needSubParts ) + setInterData( imed ); - string type_Ensight[15] = { - "point" , "bar2", "bar3" , "tria3" , "tria6" , "quad4" , "quad8" , "tetra4" , "tetra10" , "pyramid5" , - "pyramid13" , "hexa8" , "hexa20" , "penta6" , "penta15" }; - int nb_edge[15] = { 1,2,3,3,6,4,8,4,10,5,13,8,20,6,15 }; - - vector type_read ; - vector nbcell_read ; - vector< vector > total_conn ; - vector var ; - - //int number_of_geom ; - string geom_namefile ; - string field_namefile ; - string mot_lu ; - int geom_given = 0 ; - int num_coordinate ; - string type_cell ; - int number_of_cell ; - int conn ; - //----- ? - int SpaceDimension = 3 ; - //----- ? - - int NumberOfTypes = 0 ; - int NumberOfNodes ; - int iType ; - - string mesh_read_name = "EnsightMesh"; // defaut name for the mesh - - // recuperation des arguments du fichier ensight case - // -------------------------------------------------- - - // In this release, the following options are available : - // For GEOMETRY -> model: - - cout << "****************** READ **************** starting " << endl ; - - ifstream ensightCaseFile(_fileName.c_str(),ios::in); - cout << "Ensight case file name to read " << _fileName << endl ; - string diren = getDirName((char*)_fileName.c_str()); - - if (ensightCaseFile.is_open() ) - { - while ( ensightCaseFile >> mot_lu ) - { - if ( mot_lu == "GEOMETRY" ) { - cout << "geometry detected" << endl ; - while ( ensightCaseFile >> mot_lu ){ - if ( mot_lu == "model:" ) { -// ensightCaseFile >> number_of_geom ; -// cout << "number of geometries " << number_of_geom << endl ; - ensightCaseFile >> mot_lu ; - geom_namefile = mot_lu; - cout << "name of geometry file : " << geom_namefile << endl ; - break ; - } - } - } - } + if ( isBinaryDataFile( getDataFileName() )) // binary + { + if ( isGoldFormat() ) // Gold + { + readGoldBinary( *imed ); } - else + else // EnSight6 + { + read6Binary( *imed ); + } + } + else // ASCII + { + if ( isGoldFormat() ) // Gold + { + readGoldASCII( *imed ); + } + else // EnSight6 { - cout << "Error : requested file " << ensightCaseFile << " not found " << endl; - exit( EXIT_FAILURE ); + read6ASCII( *imed ); } - - // chargement des noeuds et connectivites necessaires depuis le fichier ensight geom - // --------------------------------------------------------------------------------- + } - _ptrMesh->_name = mesh_read_name ; + if ( _isMadeByMed && !imed->groupes.empty() ) { + _ptrMesh->_name = imed->groupes[0].nom; + imed->groupes[0].nom = "SupportOnAll_"; + imed->groupes[0].nom += entNames[MED_CELL]; + } + else { + _ptrMesh->_name = theDefaultMeshName; + } + _ptrMesh->_spaceDimension = SPACE_DIM; + _ptrMesh->_meshDimension = _ptrMesh->_spaceDimension; + _ptrMesh->_numberOfNodes = imed->points.size() - imed->nbMerged( MED_POINT1 ); + _ptrMesh->_isAGrid = 0; + _ptrMesh->_coordinate = imed->getCoordinate(); + + //Construction des groupes + imed->getGroups(_ptrMesh->_groupCell, + _ptrMesh->_groupFace, + _ptrMesh->_groupEdge, + _ptrMesh->_groupNode, _ptrMesh); + + _ptrMesh->_connectivity = imed->getConnectivity(); + + _ptrMesh->createFamilies(); + + // add attributes to families + set famNames; + for (medEntityMesh entity=MED_CELL; entitygetNumberOfFamilies(entity); + for ( i = 1; i <= nb; ++i ) { + FAMILY* f = const_cast( _ptrMesh->getFamily( entity, i )); + f->setNumberOfAttributes( 1 ); + int* attIDs = new int[1]; + attIDs[0] = 1; + f->setAttributesIdentifiers( attIDs ); + int* attVals = new int[1]; + attVals[0] = 1; + f->setAttributesValues( attVals ); + string* attDescr = new string[1]; + attDescr[0] = "med_family"; + f->setAttributesDescriptions( attDescr ); + if ( f->getName().length() > 31 ) // limit a name length + f->setName( STRING("FAM_") << f->getIdentifier()); + // check if family is on the whole mesh entity + if (_ptrMesh->getNumberOfElements( entity, MED_ALL_ELEMENTS ) == + f->getNumberOfElements( MED_ALL_ELEMENTS )) + { + f->setAll( true ); + *(f->getnumber()) = MEDSKYLINEARRAY(); + } + // setAll() for groups + nb = _ptrMesh->getNumberOfGroups(entity); + for ( i = 1; i <= nb; ++i ) { + GROUP * g = const_cast( _ptrMesh->getGroup( entity, i )); + if (_ptrMesh->getNumberOfElements( entity, MED_ALL_ELEMENTS ) == + g->getNumberOfElements( MED_ALL_ELEMENTS )) + { + g->setAll( true ); + *(g->getnumber()) = MEDSKYLINEARRAY(); + } + } + } + } - string cgeom_namefile; - if( diren.length() > 0 ) - cgeom_namefile = diren + '/' + geom_namefile; - else - cgeom_namefile = geom_namefile; - cout << "-> Entering into the geometry file " << geom_namefile << endl ; - ifstream ensightGeomFile(cgeom_namefile.c_str(),ios::in); - if (ensightGeomFile.is_open() ) - { - while ( ensightGeomFile >> mot_lu ){ - if ( mot_lu == "given" ) geom_given=1 ; - if ( mot_lu == "coordinates" ) { -//---------------- Nodes part -------------------------------------------------- - ensightGeomFile >> NumberOfNodes ; - cout << "-> loading " << NumberOfNodes << " coordinates " << endl ; - int NumberOfCoordinates = NumberOfNodes*SpaceDimension ; - double* Coordinates = new double[NumberOfCoordinates]; - int iCoord = 0 ; - //cout << "-> geom given " << geom_given << endl ; - for ( int i=0 ; i < NumberOfNodes ; i++) { - if( geom_given) ensightGeomFile >> setw(8) >> num_coordinate ; - ensightGeomFile >> setw(12) >> Coordinates[iCoord] ; - ensightGeomFile >> setw(12) >> Coordinates[iCoord+1] ; - ensightGeomFile >> setw(12) >> Coordinates[iCoord+2] ; -// cout << "coordinate read " << num_coordinate << " : x = " << Coordinates[iCoord] << " y = " << Coordinates[iCoord+1] << " z = " << Coordinates[iCoord+2] << endl ; - iCoord+=3 ; - } - _ptrMesh->_spaceDimension = SpaceDimension; - _ptrMesh->_numberOfNodes = NumberOfNodes; - _ptrMesh->_coordinate = new COORDINATE(SpaceDimension,NumberOfNodes,MED_EN::MED_FULL_INTERLACE); - _ptrMesh->_coordinate->setCoordinates(MED_EN::MED_FULL_INTERLACE,Coordinates); - _ptrMesh->_coordinate->setCoordinatesSystem("CARTESIAN"); - delete [] Coordinates; - } - else if ( mot_lu == "part" ) { -//---------------- Connectivities part -------------------------------------------- - while ( ensightGeomFile >> mot_lu ){ - for ( int j = 0 ; j < 15 ; j++){ - if( mot_lu == type_Ensight[j] ) { - NumberOfTypes+=1; - iType=NumberOfTypes-1 ; - total_conn.resize(NumberOfTypes) ; - type_read.push_back(mot_lu) ; - ensightGeomFile >> number_of_cell ; - nbcell_read.push_back(number_of_cell) ; - total_conn[iType].resize(nb_edge[j]*number_of_cell); - cout << "-> loading " << number_of_cell << " cells connectivities of type " << type_Ensight[j] << " (" << nb_edge[j]*number_of_cell << ") values " << endl ; - for ( int k=0 ; k < nb_edge[j]*number_of_cell ; k++ ) { - ensightGeomFile >> setw(8) >> conn ; - total_conn[iType][k]=conn ; - // cout << " connectivitie " << k << " read = " << total_conn[iType][k] << endl ; - } - } - } - } - } - } - } - // for compilation on WNT -#ifndef WNT - medGeometryElement classicalTypesCell[NumberOfTypes]; - int nbOfClassicalTypesCell[NumberOfTypes]; -#else // massive with zero size can't exist on Win32 - medGeometryElement* classicalTypesCell = new medGeometryElement(NumberOfTypes); - int* nbOfClassicalTypesCell = new int(NumberOfTypes); -#endif - int ind=0 ; - for (int k=0 ; k_connectivity = new CONNECTIVITY(NumberOfTypes,MED_EN::MED_CELL); - _ptrMesh->_connectivity->setGeometricTypes(classicalTypesCell,MED_EN::MED_CELL); - int * Count = new int[NumberOfTypes+1] ; - Count[0]=1 ; - for (int i=0; i_connectivity->setCount(Count,MED_EN::MED_CELL) ; - delete[] Count ; - int MeshDimension ; - MeshDimension = 2 ; - for (int k=0 ; k6 ) MeshDimension = 3 ; - } - _ptrMesh->_meshDimension = MeshDimension; - _ptrMesh->_connectivity->setEntityDimension(MeshDimension); - - for (int k = 0 ; k < NumberOfTypes ; k++) { - int nb_connectivities = total_conn[k].size(); - int *connectivities = new int[nb_connectivities]; - for (int itab=0 ; itab < nb_connectivities ; itab++) connectivities[itab]=total_conn[k][itab] ; - for (int j=0 ; j<15 ; j++) { - if( type_read[k] == type_Ensight[j] ) { - switch ( j+1 ) - { - case 1 : {_ptrMesh->_connectivity->setNodal(connectivities,MED_EN::MED_CELL,MED_EN::MED_POINT1) ; break ;} - case 2 : {_ptrMesh->_connectivity->setNodal(connectivities,MED_EN::MED_CELL,MED_EN::MED_SEG2) ; break ;} - case 3 : {_ptrMesh->_connectivity->setNodal(connectivities,MED_EN::MED_CELL,MED_EN::MED_SEG3) ; break ;} - case 4 : {_ptrMesh->_connectivity->setNodal(connectivities,MED_EN::MED_CELL,MED_EN::MED_TRIA3) ; break ;} - case 5 : {_ptrMesh->_connectivity->setNodal(connectivities,MED_EN::MED_CELL,MED_EN::MED_TRIA6) ; break ;} - case 6 : {_ptrMesh->_connectivity->setNodal(connectivities,MED_EN::MED_CELL,MED_EN::MED_QUAD4) ; break ;} - case 7 : {_ptrMesh->_connectivity->setNodal(connectivities,MED_EN::MED_CELL,MED_EN::MED_QUAD8) ; break ;} - case 8 : {_ptrMesh->_connectivity->setNodal(connectivities,MED_EN::MED_CELL,MED_EN::MED_TETRA4) ; break ;} - case 9 : {_ptrMesh->_connectivity->setNodal(connectivities,MED_EN::MED_CELL,MED_EN::MED_TETRA10) ; break ;} - case 10 : {_ptrMesh->_connectivity->setNodal(connectivities,MED_EN::MED_CELL,MED_EN::MED_PYRA5) ; break ;} - case 11 : {_ptrMesh->_connectivity->setNodal(connectivities,MED_EN::MED_CELL,MED_EN::MED_PYRA13) ; break ;} - case 12 : {_ptrMesh->_connectivity->setNodal(connectivities,MED_EN::MED_CELL,MED_EN::MED_HEXA8) ; break ;} - case 13 : {_ptrMesh->_connectivity->setNodal(connectivities,MED_EN::MED_CELL,MED_EN::MED_HEXA20) ; break ;} - case 14 : {_ptrMesh->_connectivity->setNodal(connectivities,MED_EN::MED_CELL,MED_EN::MED_PENTA6) ; break ;} - case 15 : {_ptrMesh->_connectivity->setNodal(connectivities,MED_EN::MED_CELL,MED_EN::MED_PENTA15) ; break ;} - default : break ; - } - } - } - delete [] connectivities; - } - -// cout << "Impression de _ptrmesh dans EnsightMeshDriver: " << endl; -// cout << *_ptrMesh ; - - END_OF(LOC); + END_OF_MED(LOC); } +//================================================================================ +/*! + * \brief Read mesh in Gold ASCII format + */ +//================================================================================ + +void ENSIGHT_MESH_RDONLY_DRIVER::readGoldASCII(_InterMed & imed) +{ + const char * LOC ="ENSIGHT_MESH_RDONLY_DRIVER::readGoldASCII() : "; + BEGIN_OF_MED(LOC); + + _ASCIIFileReader geoFile( getDataFileName() ); + + if ( isSingleFileMode() ) { + int curTimeStep = 1; + while ( curTimeStep++ < getIndexInDataFile() ) { + while ( !geoFile.isTimeStepEnd()) + geoFile.getLine(); + } + while ( !geoFile.isTimeStepBeginning() ) + geoFile.getLine(); + } + // ---------------------- + // Read mesh description + // ---------------------- + { + string descriptionLine1 = geoFile.getLine(); + string descriptionLine2 = geoFile.getLine(); + + // find out if the file was created by MED driver + int prefixSize = strlen( theDescriptionPrefix ); + _isMadeByMed = ( descriptionLine1.substr(0, prefixSize ) == theDescriptionPrefix ); + + if ( _isMadeByMed ) + descriptionLine1 = descriptionLine1.substr( prefixSize ); + _ptrMesh->setDescription( descriptionLine1 + descriptionLine2 ); + } + + // ---------------------------------------- + // Find out presence of node/elem numbers + // ---------------------------------------- + + // EnSight User Manual (for v8) says: +// You do not have to assign node IDs. If you do, the element connectivities are +// based on the node numbers. If you let EnSight assign the node IDs, the nodes +// are considered to be sequential starting at node 1, and element connectivity is +// done accordingly. If node IDs are set to off, they are numbered internally; +// however, you will not be able to display or query on them. If you have node +// IDs in your data, you can have EnSight ignore them by specifying "node id +// ignore." Using this option may reduce some of the memory taken up by the +// Client and Server, but display and query on the nodes will not be available. + + // read "node|element id " + geoFile.getWord(); geoFile.getWord(); + string nodeIds = geoFile.getWord(); + geoFile.getWord(); geoFile.getWord(); + string elemIds = geoFile.getWord(); + + bool haveNodeIds = ( nodeIds == "given" || nodeIds == "ignore" ); + bool haveElemIds = ( elemIds == "given" || elemIds == "ignore" ); + + // extents: xmin xmax ymin ymax zmin zmax + vector extents; + geoFile.toNextLine(); + if ( strncmp( "extents", geoFile.getCurrentPtr(), 7 ) == 0 ) { + geoFile.skip( /*width =*/ 7, /*nbLines =*/ 1 ); + extents.reserve( 6 ); + while ( extents.size() < extents.capacity() ) + extents.push_back( geoFile.getReal() ); + } + + typedef map::iterator INoeud; + map & points = imed.points; + INoeud firstNode; + + _groupe * partGroupe = 0; + int partNum = 0, nbParts = 0; + + while ( !geoFile.isTimeStepEnd() ) + { + string word, restLine, line = geoFile.getLine(); + TStrTool::split( line, word, restLine ); + + const TEnSightElemType & partType = getEnSightType( word ); + if ( partType._medType != MED_ALL_ELEMENTS ) + { + // Unstructured element type encounters + // -------------------------------------- + int nbElemNodes = partType._medType % 100; + int nbElems = geoFile.getInt(); // ne + bool isGhost = isGhostType( word ); + int nodeShift = points.empty() ? 0 : points.rbegin()->first; + + // read element ids + vector elemIds; + if ( haveElemIds ) { + elemIds.reserve( nbElems ); + while ( elemIds.size() < nbElems ) + elemIds.push_back( geoFile.getInt() ); // id_e + } + if ( isGhost ) { // do not store ghost elements (?) + int nbNodes = nbElems * nbElemNodes; + if ( partType._name == "nsided" ) // polygons + { + for ( int i = 0; i < nbElems; ++i ) + nbNodes += geoFile.getInt(); + geoFile.skip( nbNodes * INT_WIDTH_GOLD, /*nbLines = */nbElems ); + } + else if ( partType._name == "nfaced" ) // polyhedrons + { + int nbFaces = 0; + for ( int i = 0; i < nbElems; ++i ) + nbFaces += geoFile.getInt(); + for ( int f = 0; f < nbFaces; ++f ) + nbNodes += geoFile.getInt(); + geoFile.skip( nbNodes * INT_WIDTH_GOLD, /*nbLines = */nbFaces ); + } + else // standard types + { + geoFile.skip( nbNodes, nbElemNodes, INT_WIDTH_GOLD ); + } + continue; + } + + // add a group corresponding to subPart (geoType) + imed.groupes.push_back(_groupe()); + _groupe & groupe = imed.groupes.back(); + groupe.mailles.resize( nbElems ); + + // find out if "coordinates" has already been encountered + _SubPartDesc coordDesc( partNum , "coordinates"); + map< _SubPartDesc, _SubPart >::iterator descPart = + imed._subPartDescribed.find( coordDesc ); + bool haveCoords = ( descPart != imed._subPartDescribed.end() ); + if ( haveCoords ) { + firstNode = descPart->second.myFirstNode; + nodeShift -= descPart->second.myNbNodes; + } + + // read poly element data + bool isPoly = ( !nbElemNodes ); + vector nbElemNodesVec( 1, nbElemNodes); + vector nbElemFaces, nbFaceNodes; + if ( partType._name == "nsided" ) // polygons + { + nbElemNodesVec.resize( nbElems ); + for ( int i = 0; i < nbElems; ++i ) + nbElemNodesVec[ i ] = geoFile.getInt(); // npi + } + else if ( partType._name == "nfaced" ) // polyhedrons + { + nbElemFaces.resize( nbElems ); + nbElemNodesVec.resize( nbElems ); + int totalNbFaces = 0; + for ( int i = 0; i < nbElems; ++i ) + totalNbFaces += ( nbElemFaces[ i ] = geoFile.getInt() ); // nf_ei + + nbFaceNodes.resize( totalNbFaces ); + vector::iterator nbFN = nbFaceNodes.begin(); + for ( int i = 0; i < nbElems; ++i ) { + nbElemNodesVec[ i ] = 0; + for ( int nbFaces = nbElemFaces[ i ]; nbFaces; --nbFaces, ++nbFN ) + nbElemNodesVec[ i ] += ( *nbFN = geoFile.getInt() ); // np(f_ei) + } + } + // iterator returning nbElemNodes for standard elems and + // next value from nbElemNodesVec for poly elements + _ValueIterator nbElemNodesIt( & nbElemNodesVec[0], isPoly ? 1 : 0); + + // iterator returning values form partType._medIndex for standard elems + // and node index (n) for poly elements + int n; + _ValueIterator medIndexIt( isPoly ? &n : &partType._medIndex[0], + isPoly ? 0 : 1); + // read connectivity + _maille ma( partType._medType, nbElemNodes ); + ma.sommets.resize( nbElemNodes ); + INoeud node; + for ( int i = 0; i < nbElems; ++i ) { + _ValueIterator medIndex = medIndexIt; + nbElemNodes = nbElemNodesIt.next(); + if ( ma.sommets.size() != nbElemNodes ) + ma.sommets.resize( nbElemNodes ); + for ( n = 0; n < nbElemNodes; ++n ) { + int nodeID = geoFile.getInt(); // nn_ei + if ( haveCoords ) + node = points.find( nodeID + nodeShift ); + else + node = points.insert( make_pair( nodeID + nodeShift, _noeud())).first; + ma.sommets[ medIndex.next() ] = node; + } + if ( haveElemIds ) + ma.setOrdre( elemIds[ i ] ); + groupe.mailles[i] = imed.insert(ma); + } + // store nb nodes in polyhedron faces + if ( !nbFaceNodes.empty() ) { + const int* nbFaceNodesPtr = & nbFaceNodes[0]; + for ( int i = 0; i < nbElems; ++i ) { + vector & nbNodesByFace = imed.polyherdalNbFaceNodes[ &groupe.maille( i ) ]; + nbNodesByFace.assign( nbFaceNodesPtr, nbFaceNodesPtr + nbElemFaces[ i ] ); + nbFaceNodesPtr += nbElemFaces[ i ]; + } + } + // create subPart for "coordinates" + if ( !haveCoords ) { + _SubPart & coordSubPart = imed._subPartDescribed[ coordDesc ]; + coordSubPart.myFirstNode = points.insert( make_pair( 1 + nodeShift, _noeud())).first; + } + // add subPart group to part group + int groupeIndex = imed.groupes.size(); + partGroupe->groupes.push_back( groupeIndex ); + + // create subPart + _SubPart subPart( partNum, partType._name ); + subPart.myNbCells = nbElems; + subPart.myCellGroupIndex = groupeIndex; + imed.addSubPart( subPart ); + } + else if ( word == "coordinates" ) + { + // Local node coordinates of a part + // ------------------------------------ + int nbNodes = geoFile.getInt(); // nn + + // read node ids + vector nodeIds; + if ( haveNodeIds ) { + nodeIds.reserve( nbNodes ); + while ( nodeIds.size() < nbNodes ) + nodeIds.push_back( geoFile.getInt() ); // id_n + } + + // find out if "coordinates" has already been add at reading connectivity + _SubPartDesc coordDesc( partNum , "coordinates"); + map< _SubPartDesc, _SubPart >::iterator descPart = + imed._subPartDescribed.find( coordDesc ); + bool haveCoords = ( descPart != imed._subPartDescribed.end() ); + + if ( haveCoords ) { + // check that all nodes have been added + firstNode = descPart->second.myFirstNode; + descPart->second.myNbNodes = nbNodes; + INoeud inoeud = firstNode, inoEnd = points.end(); + int id = inoeud->first, idEnd = id + nbNodes; + for ( ; id < idEnd; ++id ) { + if ( inoeud == inoEnd || inoeud->first > id ) { + INoeud in = points.insert( inoeud, make_pair( id, _noeud() )); + in->second.number = id; + in->second.coord.resize( SPACE_DIM ); + } else { + ++inoeud; + } + } + } + else { + // add nodes + int nodeShift = points.empty() ? 0 : points.rbegin()->first; + for ( int iNode = 1; iNode <= nbNodes; ++iNode ) { + INoeud inoeud = points.insert( points.end(), make_pair( iNode + nodeShift, _noeud())); + inoeud->second.number = inoeud->first; + inoeud->second.coord.resize( SPACE_DIM ); + } + firstNode = points.find( 1 + nodeShift ); + // create "coordinates" subPart + _SubPart & subPart = imed._subPartDescribed[ coordDesc ]; + subPart.myNbNodes = nbNodes; + subPart.myFirstNode = firstNode; + } + + // read coordinates in no interlace mode + INoeud endNode = points.end(); + for ( int j = 0; j < SPACE_DIM; ++j ) { + for ( INoeud in = firstNode; in != endNode; ++in ) { + _noeud & node = in->second; + node.coord[ j ] = geoFile.getReal(); + } + } + } + else if ( word == "part" ) + { + // Another part encounters + // ----------------------- + partNum = geoFile.getInt(); + nbParts++; + geoFile.toNextLine(); + + string partName = geoFile.getLine(); + if ( partName.empty() ) + partName = "Part_" + restLine; + + if ( imed.groupes.capacity() - imed.groupes.size() < theMaxNbTypes ) + imed.groupes.reserve( size_t( 1.5 * imed.groupes.size() )); + imed.groupes.push_back(_groupe()); + partGroupe = & imed.groupes.back(); + partGroupe->nom = partName; + partGroupe->groupes.reserve( theMaxNbTypes ); + } + else if ( word == "block" ) + { + // Structured type + // ------------------ + bool rectilinear = ( restLine.find( "rectilinear" ) != restLine.npos ); + bool uniform = ( restLine.find( "uniform" ) != restLine.npos ); + bool curvilinear = ( !rectilinear && !uniform ); + bool iblanked = ( restLine.find( "iblanked" ) != restLine.npos ); + bool with_ghost = ( restLine.find( "with_ghost" ) != restLine.npos ); + bool range = ( restLine.find( "range" ) != restLine.npos ); + + // dimension + int I = geoFile.getInt(); + int J = geoFile.getInt(); + int K = geoFile.getInt(); + int NumberOfNodes = I*J*K; + if ( !NumberOfNodes ) continue; + + // range + if ( range ) { + vector ijkRange; // imin imax jmin jmax kmin kmax + ijkRange.reserve(6); + while ( ijkRange.size() < 6 ) + ijkRange.push_back( geoFile.getInt() ); + I = ijkRange[1]-ijkRange[0]+1; + J = ijkRange[3]-ijkRange[2]+1; + K = ijkRange[5]-ijkRange[4]+1; + NumberOfNodes = I*J*K; + } + // add nodes + int nodeShift = points.empty() ? 0 : points.rbegin()->first; + for ( int iNode = 1; iNode <= NumberOfNodes; ++iNode ) { + INoeud inoeud = points.insert( points.end(), make_pair( iNode + nodeShift, _noeud())); + _noeud & node = inoeud->second; + node.number = inoeud->first; + node.coord.resize( SPACE_DIM ); + } + INoeud firstNode = points.find( nodeShift + 1 ); + INoeud endNode = points.end(); + + GRID grid; // calculator of unstructured data + grid._iArrayLength = I; + grid._jArrayLength = J; + grid._kArrayLength = K; + grid._numberOfNodes = NumberOfNodes ; + grid._spaceDimension = SPACE_DIM; + if ( J < 2 ) { grid._spaceDimension--; grid._jArrayLength = 0; } + if ( K < 2 ) { grid._spaceDimension--; grid._kArrayLength = 0; } + int nbElems = grid.getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS); + + if ( curvilinear ) // read coordinates for all nodes + { + for ( int j = 0; j < SPACE_DIM; ++j ) { + for ( INoeud in = firstNode; in != endNode; ++in ) + in->second.coord[ j ] = geoFile.getReal(); + } + grid._gridType = MED_BODY_FITTED; + } + else if ( rectilinear ) // read delta vectors with non-regular spacing + { + grid._iArray = (double*)geoFile.convertReals( I ); + grid._jArray = (double*)geoFile.convertReals( J ); + grid._kArray = (double*)geoFile.convertReals( K ); + grid._gridType = MED_CARTESIAN; + } + else // uniform: read grid origine and delta vectors for regular spacing grid + { + TDblOwner xyzOrigin( (double*)geoFile.convertReals( 3 )); + TDblOwner xyzDelta ( (double*)geoFile.convertReals( 3 )); + // compute full delta vectors + grid._iArray = new double[ I ]; + grid._jArray = new double[ J ]; + grid._kArray = new double[ K ]; + double* coors[SPACE_DIM] = { grid._iArray, grid._jArray, grid._kArray }; + int size [SPACE_DIM] = { I, J, K }; + for ( int j = 0; j < SPACE_DIM; ++j ) { + double* coo = coors[ j ]; + double* cooEnd = coo + size[ j ]; + coo[0] = xyzOrigin[ j ]; + while ( ++coo < cooEnd ) + *coo = coo[-1] + xyzDelta[ j ]; + } + grid._gridType = MED_CARTESIAN; + } + + // iblanks + if ( iblanked ) + geoFile.skip( NumberOfNodes, /*nbPerLine =*/ 1, INT_WIDTH_GOLD); + // ghosts + if ( with_ghost ) { + geoFile.getWord(); // "ghost_flags" + geoFile.skip( nbElems, /*nbPerLine =*/ 1, INT_WIDTH_GOLD); + } + // node ids + if ( haveNodeIds && geoFile.lookAt( "node_ids" )) { + geoFile.getWord(); // "node_ids" + geoFile.skip( NumberOfNodes, /*nbPerLine =*/ 1, INT_WIDTH_GOLD); + } + // element ids + if ( haveElemIds && geoFile.lookAt( "element_ids" ) ) { + geoFile.getWord(); // "element_ids" + geoFile.skip( nbElems, /*nbPerLine =*/ 1, INT_WIDTH_GOLD); + } + + if ( !curvilinear ) // let GRID compute all coordinates + { + grid._coordinate = new COORDINATE; + const double * coo = grid.getCoordinates(MED_FULL_INTERLACE); + typedef _ValueIterator< double > TCoordIt; + TCoordIt xCoo( coo+0, grid._spaceDimension); + TCoordIt yCoo( coo+1, grid._spaceDimension); + TCoordIt zCoo( coo+2, grid._spaceDimension); + if ( grid._spaceDimension < 3 ) zCoo = TCoordIt( grid._kArray, 0 ); + if ( grid._spaceDimension < 2 ) yCoo = TCoordIt( grid._jArray, 0 ); + for ( INoeud in = firstNode; in != endNode; ++in ) { + _noeud& node = in->second; + node.coord[ 0 ] = xCoo.next(); + node.coord[ 1 ] = yCoo.next(); + node.coord[ 2 ] = zCoo.next(); + } + } + + // let GRID calculate connectivity + + const int * conn = grid.getConnectivity( MED_FULL_INTERLACE, MED_NODAL, + MED_CELL, MED_ALL_ELEMENTS ); + medGeometryElement elemType = grid.getElementType( MED_CELL, 1 ); + int nbElemNodes = elemType % 100; + + partGroupe->mailles.resize( nbElems ); + _maille ma( elemType, nbElemNodes ); + ma.sommets.resize( nbElemNodes ); + + for ( int i = 0, nIndex = 0; i < nbElems; ++i ) { + for ( int n = 0; n < nbElemNodes; ++n ) { + int nodeID = conn[ nIndex++ ]; + ma.sommets[n] = points.find( nodeID + nodeShift ); + } + //ma.ordre = ++order; + partGroupe->mailles[i] = imed.insert(ma); + } + + _SubPart subPart( partNum, "block" ); + subPart.myNbCells = nbElems; + subPart.myNbNodes = NumberOfNodes; + subPart.myFirstNode = firstNode; + subPart.myCellGroupIndex = imed.groupes.size(); + imed.addSubPart( subPart ); + } + else + { + throw MEDEXCEPTION + ( LOCALIZED( STRING(LOC) << "Unexpected word: " << word << + " in " << getDataFileName())); + } + } // while ( !geoFile.eof() ) + + if ( nbParts > 1 ) + imed.mergeNodesAndElements(TOLERANCE); + + END_OF_MED(LOC); +} + +//================================================================================ +/*! + * \brief Read mesh in Gold Binary format + */ +//================================================================================ + +void ENSIGHT_MESH_RDONLY_DRIVER::readGoldBinary(_InterMed & imed) +{ + const char * LOC ="ENSIGHT_MESH_RDONLY_DRIVER::readGoldBinary() : "; + BEGIN_OF_MED(LOC); + + _BinaryFileReader geoFile( getDataFileName() ); + + // check if swapping bytes needed + try { + countPartsBinary( geoFile, isSingleFileMode()); + } + catch (...) { + geoFile.swapBytes(); + geoFile.rewind(); + } + if ( getIndexInDataFile() <= 1 ) + geoFile.rewind(); + if ( geoFile.getPosition() == 0 ) { + TStrOwner format( geoFile.getLine() ); // "C|Fortran Binary" + if ( !contains( "C Binary", format )) { + if ( contains( "Fortran Binary", format )) + throw(MEDEXCEPTION(STRING(LOC) << "Fortran Binary format not supported")); + else + throw(MEDEXCEPTION(STRING(LOC) << "unexpected line in " << getDataFileName() + << "\n" << format.myValues)); + } + } + if ( isSingleFileMode() ) { + // one time step may be skipped by countPartsBinary + int curTimeStep = geoFile.getPosition() ? 2 : 1 ; + while ( curTimeStep < getIndexInDataFile() ) { + countPartsBinary( geoFile, true ); // skip time step + curTimeStep++; + } + while (1) { + TStrOwner line( geoFile.getLine() ); + if ( isTimeStepBeginning( line.myValues )) + break; + } + } + // ---------------------- + // Read mesh description + // ---------------------- + { + TStrOwner descriptionLine1 ( geoFile.getLine() ); + TStrOwner descriptionLine2 ( geoFile.getLine() ); + + // find out if the file was created by MED driver + _isMadeByMed = contains( theDescriptionPrefix, descriptionLine1 ); + + if ( _isMadeByMed ) + _ptrMesh->setDescription( descriptionLine2.myValues ); + else + _ptrMesh->setDescription( string(descriptionLine1) + descriptionLine2.myValues ); + } + + // ---------------------------------------- + // Find out presence of node/elem numbers + // ---------------------------------------- + + // EnSight User Manual (for v8) says: +// You do not have to assign node IDs. If you do, the element connectivities are +// based on the node numbers. If you let EnSight assign the node IDs, the nodes +// are considered to be sequential starting at node 1, and element connectivity is +// done accordingly. If node IDs are set to off, they are numbered internally; +// however, you will not be able to display or query on them. If you have node +// IDs in your data, you can have EnSight ignore them by specifying "node id +// ignore." Using this option may reduce some of the memory taken up by the +// Client and Server, but display and query on the nodes will not be available. + + // read "node|element id " + bool haveNodeIds, haveElemIds; + { + TStrOwner nodeIds( geoFile.getLine() ); + TStrOwner elemIds( geoFile.getLine() ); + + haveNodeIds = ( contains( "given", nodeIds ) || contains( "ignore", nodeIds ) ); + haveElemIds = ( contains( "given", elemIds ) || contains( "ignore", elemIds ) ); + } + + typedef map::iterator INoeud; + map & points = imed.points; + INoeud firstNode; + + _groupe * partGroupe = 0; + int partNum = 0, nbParts = 0; + + TFltOwner extents(0); // extents: xmin xmax ymin ymax zmin zmax + + while ( !geoFile.eof() ) + { + TStrOwner line( geoFile.getLine() ); + if ( isSingleFileMode() && isTimeStepEnd( line.myValues )) + break; + string word, restLine; + TStrTool::split( line.myValues, word, restLine ); + + const TEnSightElemType & partType = getEnSightType( word ); + if ( partType._medType != MED_ALL_ELEMENTS ) + { + // Unstructured element type encounters + // -------------------------------------- + int nbElems = *TIntOwner( geoFile.getInt(1) ); // ne + int nbElemNodes = partType._medType % 100; + bool isGhost = isGhostType( word ); + int nodeShift = points.empty() ? 0 : points.rbegin()->first; + + // read element ids + TIntOwner elemIds( haveElemIds ? geoFile.getInt( nbElems ): 0 ); // id_e + + if ( isGhost ) { // do not store ghost elements (?) + int nbNodes = nbElems * nbElemNodes; + if ( partType._name == "nsided" ) // polygons + { + TIntOwner nbNodesInFace( geoFile.getInt( nbElems )); + nbNodes = std::accumulate( nbNodesInFace.myValues, nbNodesInFace.myValues + nbElems, 0 ); + } + else if ( partType._name == "nfaced" ) // polyhedrons + { + TIntOwner nbElemFaces( geoFile.getInt( nbElems )); + int nbFaces = accumulate( nbElemFaces.myValues, nbElemFaces.myValues + nbElems, 0 ); + TIntOwner nbNodesInFace( geoFile.getInt( nbFaces )); + nbNodes = std::accumulate( nbNodesInFace.myValues, nbNodesInFace.myValues + nbElems, 0 ); + } + geoFile.skip( nbNodes * sizeof(int) ); + continue; + } + + // add a group corresponding to subPart (geoType) + imed.groupes.push_back(_groupe()); + _groupe & groupe = imed.groupes.back(); + groupe.mailles.resize( nbElems ); + + // find out if "coordinates" has already been encountered + _SubPartDesc coordDesc( partNum , "coordinates"); + map< _SubPartDesc, _SubPart >::iterator descPart = + imed._subPartDescribed.find( coordDesc ); + bool haveCoords = ( descPart != imed._subPartDescribed.end() ); + if ( haveCoords ) { + firstNode = descPart->second.myFirstNode; + nodeShift -= descPart->second.myNbNodes; + } + + // read poly element data + bool isPoly = ( !nbElemNodes ); + int nbNodes = 0; + TIntOwner nbElemNodesVec(0), nbElemFaces(0), nbFaceNodes(0); + if ( partType._name == "nsided" ) // polygons + { + nbElemNodesVec.myValues = geoFile.getInt( nbElems ); // npi + nbNodes = accumulate( nbElemNodesVec.myValues, nbElemNodesVec.myValues + nbElems, 0 ); + } + else if ( partType._name == "nfaced" ) // polyhedrons + { + nbElemFaces.myValues = geoFile.getInt( nbElems ); // nf_ei + int totalNbFaces = accumulate( nbElemFaces.myValues, nbElemFaces.myValues + nbElems, 0 ); + + nbFaceNodes.myValues = geoFile.getInt( totalNbFaces ); // np(f_ei) + // calculate nb of nodes in each polyhedron + int* nbEN = nbElemNodesVec.myValues = new int[ nbElems ]; + const int *nbFN = nbFaceNodes, *nbEF = nbElemFaces, *nbEND = nbEN + nbElems; + for ( ; nbEN < nbEND; ++nbEN, ++nbEF ) { + nbNodes += *nbEN = accumulate( nbFN, nbFN + *nbEF, 0 ); + nbFN += *nbEF; + } + } + else // standard types + { + nbElemNodesVec.myValues = new int[ 1 ]; + nbElemNodesVec[ 0 ] = nbElemNodes; + nbNodes = nbElems * nbElemNodes; + } + // iterator returning nbElemNodes for standard elems and + // next value from nbElemNodesVec for poly elements + _ValueIterator nbElemNodesIt( nbElemNodesVec, isPoly ? 1 : 0); + + // iterator returning values form partType._medIndex for standard elems + // and node index (n) for poly elements + int n; + _ValueIterator medIndexIt( isPoly ? &n : &partType._medIndex[0], + isPoly ? 0 : 1); + // read connectivity + _maille ma( partType._medType, nbElemNodes ); + ma.sommets.resize( nbElemNodes ); + TIntOwner connectivity( geoFile.getInt( nbNodes )); // nn_ei + int* nodeID = connectivity; + INoeud node; + for ( int i = 0; i < nbElems; ++i ) { + _ValueIterator medIndex = medIndexIt; + nbElemNodes = nbElemNodesIt.next(); + if ( ma.sommets.size() != nbElemNodes ) + ma.sommets.resize( nbElemNodes ); + for ( n = 0; n < nbElemNodes; ++n, ++nodeID ) { + if ( haveCoords ) + node = points.find( *nodeID + nodeShift ); + else + node = points.insert( make_pair( *nodeID + nodeShift, _noeud())).first; + ma.sommets[ medIndex.next() ] = node; + } + if ( haveElemIds ) + ma.setOrdre( elemIds[ i ] ); + groupe.mailles[i] = imed.insert(ma); + } + // store nb nodes in polyhedron faces + if ( nbFaceNodes.myValues ) { + const int* nbFaceNodesPtr = nbFaceNodes.myValues; + for ( int i = 0; i < nbElems; ++i ) { + vector & nbNodesByFace = imed.polyherdalNbFaceNodes[ &groupe.maille( i ) ]; + nbNodesByFace.assign( nbFaceNodesPtr, nbFaceNodesPtr + nbElemFaces[ i ] ); + nbFaceNodesPtr += nbElemFaces[ i ]; + } + } + // create subPart for "coordinates" + if ( !haveCoords ) { + _SubPart & coordSubPart = imed._subPartDescribed[ coordDesc ]; + coordSubPart.myFirstNode = points.insert( make_pair( 1 + nodeShift, _noeud())).first; + } + // add subPart group to part group + int groupeIndex = imed.groupes.size(); + partGroupe->groupes.push_back( groupeIndex ); + + // create subPart + _SubPart subPart( partNum, partType._name ); + subPart.myNbCells = nbElems; + subPart.myCellGroupIndex = groupeIndex; + imed.addSubPart( subPart ); + } + else if ( word == "coordinates" ) + { + // Local node coordinates of a part + // ------------------------------------ + int nbNodes = *TIntOwner( geoFile.getInt(1) ); // nn + + // read node ids + TIntOwner nodeIds(0); + if ( haveNodeIds ) + nodeIds.myValues = geoFile.getInt( nbNodes ); // id_n + + // find out if "coordinates" has already been add at reading connectivity + _SubPartDesc coordDesc( partNum , "coordinates"); + map< _SubPartDesc, _SubPart >::iterator descPart = + imed._subPartDescribed.find( coordDesc ); + bool haveCoords = ( descPart != imed._subPartDescribed.end() ); + + if ( haveCoords ) { + // check that all nodes have been added + firstNode = descPart->second.myFirstNode; + descPart->second.myNbNodes = nbNodes; + INoeud inoeud = firstNode, inoEnd = points.end(); + int id = inoeud->first, idEnd = id + nbNodes; + for ( ; id < idEnd; ++id ) { + if ( inoeud == inoEnd || inoeud->first > id ) { + INoeud in = points.insert( inoeud, make_pair( id, _noeud() )); + in->second.number = id; + } else { + ++inoeud; + } + } + } + else { + // add nodes + int nodeShift = points.empty() ? 0 : points.rbegin()->first; + for ( int iNode = 1; iNode <= nbNodes; ++iNode ) { + INoeud inoeud = points.insert( points.end(), make_pair( iNode + nodeShift, _noeud())); + inoeud->second.number = inoeud->first; + } + firstNode = points.find( 1 + nodeShift ); + // create "coordinates" subPart + _SubPart & subPart = imed._subPartDescribed[ coordDesc ]; + subPart.myNbNodes = nbNodes; + subPart.myFirstNode = firstNode; + } + + // read coordinates in no interlace mode + TFltOwner noInterlaceCoords( geoFile.getFlt( nbNodes * SPACE_DIM )); + float* x = noInterlaceCoords; + float* y = x + nbNodes; + float* z = y + nbNodes; + INoeud endNode = points.end(); + for ( INoeud in = firstNode; in != endNode; ++in ) { + _noeud & node = in->second; + node.coord.resize( SPACE_DIM ); + node.coord[ 0 ] = *x++; + node.coord[ 1 ] = *y++; + node.coord[ 2 ] = *z++; + } + } + else if ( word == "part" ) + { + // Another part encounters + // ----------------------- + partNum = *TIntOwner( geoFile.getInt(1) ); + nbParts++; + + string partName( TStrOwner( geoFile.getLine() )); + if ( partName.empty() ) + partName = "Part_" + restLine; + + if ( imed.groupes.capacity() - imed.groupes.size() < theMaxNbTypes ) + imed.groupes.reserve( size_t( 1.5 * imed.groupes.size() )); + imed.groupes.push_back(_groupe()); + partGroupe = & imed.groupes.back(); + partGroupe->nom = partName; + partGroupe->groupes.reserve( theMaxNbTypes ); + } + else if ( word == "block" ) + { + // Structured type + // ------------------ + bool rectilinear = ( restLine.find( "rectilinear" ) != restLine.npos ); + bool uniform = ( restLine.find( "uniform" ) != restLine.npos ); + bool curvilinear = ( !rectilinear && !uniform ); + bool iblanked = ( restLine.find( "iblanked" ) != restLine.npos ); + bool with_ghost = ( restLine.find( "with_ghost" ) != restLine.npos ); + bool range = ( restLine.find( "range" ) != restLine.npos ); + + // dimension + TIntOwner ijk( geoFile.getInt(3) ); + int I = ijk[0]; + int J = ijk[1]; + int K = ijk[2]; + int NumberOfNodes = I*J*K; + if ( !NumberOfNodes ) continue; + + // range + if ( range ) { + TIntOwner ijkRange( geoFile.getInt( 6 ));// imin imax jmin jmax kmin kmax + I = ijkRange[1]-ijkRange[0]+1; + J = ijkRange[3]-ijkRange[2]+1; + K = ijkRange[5]-ijkRange[4]+1; + NumberOfNodes = I*J*K; + } + // add nodes + int nodeShift = points.empty() ? 0 : points.rbegin()->first; + for ( int iNode = 1; iNode <= NumberOfNodes; ++iNode ) { + INoeud inoeud = points.insert( points.end(), make_pair( iNode + nodeShift, _noeud())); + _noeud & node = inoeud->second; + node.number = inoeud->first; + node.coord.resize( SPACE_DIM ); + } + INoeud firstNode = points.find( nodeShift + 1 ); + INoeud endNode = points.end(); + + GRID grid; // calculator of unstructured data + grid._iArrayLength = I; + grid._jArrayLength = J; + grid._kArrayLength = K; + grid._numberOfNodes = NumberOfNodes ; + grid._spaceDimension = SPACE_DIM; + if ( J < 2 ) { grid._spaceDimension--; grid._jArrayLength = 0; } + if ( K < 2 ) { grid._spaceDimension--; grid._kArrayLength = 0; } + int nbElems = grid.getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS); + + if ( curvilinear ) // read coordinates for all nodes + { + TFltOwner noInterlaceCoords( geoFile.getFlt( NumberOfNodes * SPACE_DIM )); + float* x = noInterlaceCoords; + float* y = x + NumberOfNodes; + float* z = y + NumberOfNodes; + for ( INoeud in = firstNode; in != endNode; ++in ) { + _noeud & node = in->second; + node.coord.resize( SPACE_DIM ); + node.coord[ 0 ] = *x++; + node.coord[ 1 ] = *y++; + node.coord[ 2 ] = *z++; + } + grid._gridType = MED_BODY_FITTED; + } + else if ( rectilinear ) // read delta vectors with non-regular spacing + { + grid._iArray = (double*)geoFile.convertReals( I ); + grid._jArray = (double*)geoFile.convertReals( J ); + grid._kArray = (double*)geoFile.convertReals( K ); + grid._gridType = MED_CARTESIAN; + } + else // uniform: read grid origine and delta vectors for regular spacing grid + { + TFltOwner xyzOrigin( geoFile.getFlt( 3 )); + TFltOwner xyzDelta ( geoFile.getFlt( 3 )); + // compute full delta vectors + grid._iArray = new double[ I ]; + grid._jArray = new double[ J ]; + grid._kArray = new double[ K ]; + double* coors[SPACE_DIM] = { grid._iArray, grid._jArray, grid._kArray }; + int size [SPACE_DIM] = { I, J, K }; + for ( int j = 0; j < SPACE_DIM; ++j ) { + double* coo = coors[ j ]; + double* cooEnd = coo + size[ j ]; + coo[0] = xyzOrigin[ j ]; + while ( ++coo < cooEnd ) + *coo = coo[-1] + xyzDelta[ j ]; + } + grid._gridType = MED_CARTESIAN; + } + + // iblanks + if ( iblanked ) + geoFile.skip( NumberOfNodes * sizeof(int) ); + // ghosts + if ( with_ghost ) { + TStrOwner( geoFile.getLine() ); // "ghost_flags" + geoFile.skip( nbElems * sizeof(int) ); + } + // node ids + if ( haveNodeIds && !geoFile.eof() ) { + TStrOwner nextLine( geoFile.getLine() ); // "node_ids" + if ( contains( "node_ids", nextLine ) ) + geoFile.skip( NumberOfNodes * sizeof(int) ); + else + geoFile.skip( -MAX_LINE_LENGTH ); + } + // element ids + TIntOwner elemIdOwner(0); + _ValueIterator elemIds; + if ( haveElemIds && !geoFile.eof() ) { + TStrOwner nextLine( geoFile.getLine() ); // "element_ids" + if ( contains( "element_ids", nextLine ) ) { + elemIdOwner.myValues = geoFile.getInt( nbElems ); + elemIds = _ValueIterator( elemIdOwner, 1); + } else { + geoFile.skip( -MAX_LINE_LENGTH ); + } + } + + if ( !curvilinear ) // let GRID compute all coordinates + { + grid._coordinate = new COORDINATE; + const double * coo = grid.getCoordinates(MED_FULL_INTERLACE); + typedef _ValueIterator< double > TCoordIt; + TCoordIt xCoo( coo+0, grid._spaceDimension); + TCoordIt yCoo( coo+1, grid._spaceDimension); + TCoordIt zCoo( coo+2, grid._spaceDimension); + if ( grid._spaceDimension < 3 ) zCoo = TCoordIt( grid._kArray, 0 ); + if ( grid._spaceDimension < 2 ) yCoo = TCoordIt( grid._jArray, 0 ); + for ( INoeud in = firstNode; in != endNode; ++in ) { + _noeud& node = in->second; + node.coord[ 0 ] = xCoo.next(); + node.coord[ 1 ] = yCoo.next(); + node.coord[ 2 ] = zCoo.next(); + } + } + + // let GRID calculate connectivity + + const int * conn = grid.getConnectivity( MED_FULL_INTERLACE, MED_NODAL, + MED_CELL, MED_ALL_ELEMENTS ); + medGeometryElement elemType = grid.getElementType( MED_CELL, 1 ); + int nbElemNodes = elemType % 100; + + partGroupe->mailles.resize( nbElems ); + _maille ma( elemType, nbElemNodes ); + ma.sommets.resize( nbElemNodes ); + + for ( int i = 0, nIndex = 0; i < nbElems; ++i ) { + for ( int n = 0; n < nbElemNodes; ++n ) { + int nodeID = conn[ nIndex++ ]; + ma.sommets[n] = points.find( nodeID + nodeShift ); + } + ma.setOrdre( elemIds.next() ); + partGroupe->mailles[i] = imed.insert(ma); + } + + _SubPart subPart( partNum, "block" ); + subPart.myNbCells = nbElems; + subPart.myNbNodes = NumberOfNodes; + subPart.myFirstNode = firstNode; + subPart.myCellGroupIndex = imed.groupes.size(); + imed.addSubPart( subPart ); + } + else if ( word == "extents" ) + { + extents.myValues = geoFile.getFlt( 6 ); + } + else + { + throw MED_EXCEPTION + ( LOCALIZED( STRING(LOC) << "Unexpected word: " << word << + " in " << getDataFileName())); + } + } // while ( !geoFile.eof() ) + + if ( nbParts > 1 ) + imed.mergeNodesAndElements(TOLERANCE); + + END_OF_MED(LOC); +} + +//================================================================================ +/*! + * \brief Read mesh in Ensight6 ASCII format + */ +//================================================================================ + +void ENSIGHT_MESH_RDONLY_DRIVER::read6ASCII(_InterMed & imed) +{ + const char * LOC ="ENSIGHT_MESH_RDONLY_DRIVER::read6ASCII() : "; + BEGIN_OF_MED(LOC); + + _ASCIIFileReader geoFile( getDataFileName() ); + + if ( isSingleFileMode() ) { + int curTimeStep = 1; + while ( curTimeStep < getIndexInDataFile() ) { + while ( !geoFile.isTimeStepEnd()) + geoFile.getLine(); + curTimeStep++; + } + while ( !geoFile.isTimeStepBeginning() ) + geoFile.getLine(); + } + // ---------------------- + // Read mesh description + // ---------------------- + { + string descriptionLine1 = geoFile.getLine(); + string descriptionLine2 = geoFile.getLine(); + + // find out if the file was created by MED driver + int prefixSize = strlen( theDescriptionPrefix ); + _isMadeByMed = ( descriptionLine1.substr(0, prefixSize ) == theDescriptionPrefix ); + + if ( _isMadeByMed ) + descriptionLine1 = descriptionLine1.substr( prefixSize ); + _ptrMesh->setDescription( descriptionLine1 + descriptionLine2 ); + } + + // ---------------------------------------- + // Find out presence of node/elem numbers + // ---------------------------------------- + + // EnSight User Manual (for v8) says: +// You do not have to assign node IDs. If you do, the element connectivities are +// based on the node numbers. If you let EnSight assign the node IDs, the nodes +// are considered to be sequential starting at node 1, and element connectivity is +// done accordingly. If node IDs are set to off, they are numbered internally; +// however, you will not be able to display or query on them. If you have node +// IDs in your data, you can have EnSight ignore them by specifying "node id +// ignore." Using this option may reduce some of the memory taken up by the +// Client and Server, but display and query on the nodes will not be available. + + // read "node|element id " + geoFile.getWord(); geoFile.getWord(); + string nodeIds = geoFile.getWord(); + geoFile.getWord(); geoFile.getWord(); + string elemIds = geoFile.getWord(); + + bool haveNodeIds = ( nodeIds == "given" || nodeIds == "ignore" ); + bool haveElemIds = ( elemIds == "given" || elemIds == "ignore" ); + + map & points = imed.points; + typedef map::iterator INoeud; + + int haveStructuredParts = 0, haveUnstructuredParts = 0; + + _groupe * partGroupe = 0; + int partNum = 0; + + while ( !geoFile.isTimeStepEnd() ) + { + string word, restLine, line = geoFile.getLine(); + TStrTool::split( line, word, restLine ); + + const TEnSightElemType & partType = getEnSightType( word ); + if ( !partType._medIndex.empty() ) + { + // Unstructured element type encounters + // -------------------------------------- + int nbElemNodes = partType._medType % 100; + int nbElems = geoFile.getInt(); + if ( nbElems > 0 ) + haveUnstructuredParts++; + + imed.groupes.push_back(_groupe()); + _groupe & groupe = imed.groupes.back(); + groupe.mailles.resize( nbElems ); + + // read connectivity + _maille ma( partType._medType, nbElemNodes ); + ma.sommets.resize( nbElemNodes ); + INoeud node; + for ( int i = 0; i < nbElems; ++i ) { + if ( haveElemIds ) + geoFile.getInt(); + for ( int n = 0; n < nbElemNodes; ++n ) { + int nodeID = geoFile.getInt(); + ma.sommets[ partType._medIndex[n] ] = points.find( nodeID ); + } + //ma.ordre = ++order; + groupe.mailles[i] = imed.insert(ma); + } + + int groupeIndex = imed.groupes.size(); + partGroupe->groupes.push_back( groupeIndex ); + + _SubPart subPart( partNum, partType._name ); + subPart.myNbCells = nbElems; + subPart.myCellGroupIndex = groupeIndex; + imed.addSubPart( subPart ); + } + else if ( word == "part" ) + { + // Another part encounters + // ----------------------- + partNum = atoi( restLine.c_str() ); + + string partName = geoFile.getLine(); + if ( partName.empty() ) + partName = "Part_" + restLine; + + if ( imed.groupes.capacity() - imed.groupes.size() < theMaxNbTypes ) + imed.groupes.reserve( size_t( 1.5 * imed.groupes.size() )); + imed.groupes.push_back(_groupe()); + partGroupe = & imed.groupes.back(); + partGroupe->nom = partName; + partGroupe->groupes.reserve( theMaxNbTypes ); + } + else if ( word == "block" ) + { + // Structured type + // ------------------ + bool iblanked = ( restLine == "iblanked" ); + + // dimension + int I = geoFile.getInt(); + int J = geoFile.getInt(); + int K = geoFile.getInt(); + int NumberOfNodes = I*J*K; + if ( !NumberOfNodes ) continue; + haveStructuredParts++; + + // add nodes + int nodeShift = points.empty() ? 0 : points.rbegin()->first; + for ( int iNode = 1; iNode <= NumberOfNodes; ++iNode ) { + INoeud inoeud = points.insert( points.end(), make_pair( iNode + nodeShift, _noeud())); + _noeud & node = inoeud->second; + node.number = inoeud->first; + node.coord.resize( SPACE_DIM ); + } + // read coordinates + INoeud firstNode = points.find( nodeShift + 1 ); + INoeud endNode = points.end(); + for ( int j = 0; j < SPACE_DIM; ++j ) { + for ( INoeud in = firstNode; in != endNode; ++in ) { + _noeud & node = in->second; + node.coord[ j ] = geoFile.getReal(); + } + } + // iblanks + if ( iblanked ) + geoFile.skip(NumberOfNodes, /*nbPerLine =*/ 10, INT_WIDTH_6); + + // let GRID calculate connectivity + GRID grid; + grid._numberOfNodes = NumberOfNodes ; + grid._iArrayLength = I; + grid._jArrayLength = J; + grid._kArrayLength = K; + grid._gridType = MED_BODY_FITTED; + grid._spaceDimension= SPACE_DIM; + if ( J < 2 ) { grid._spaceDimension--; grid._jArrayLength = 0; } + if ( K < 2 ) { grid._spaceDimension--; grid._kArrayLength = 0; } + + const int * conn = grid.getConnectivity( MED_FULL_INTERLACE, MED_NODAL, + MED_CELL, MED_ALL_ELEMENTS ); + medGeometryElement elemType = grid.getElementType( MED_CELL, 1 ); + int nbElemNodes = elemType % 100; + int nbElems = grid.getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS); + + partGroupe->mailles.resize( nbElems ); + _maille ma( elemType, nbElemNodes ); + ma.sommets.resize( nbElemNodes ); + + for ( int i = 0, nIndex = 0; i < nbElems; ++i ) { + for ( int n = 0; n < nbElemNodes; ++n ) { + int nodeID = conn[ nIndex++ ]; + ma.sommets[n] = points.find( nodeID + nodeShift ); + } + //ma.ordre = ++order; + partGroupe->mailles[i] = imed.insert(ma); + } + + _SubPart subPart( partNum, "block" ); + subPart.myNbCells = nbElems; + subPart.myNbNodes = NumberOfNodes; + subPart.myFirstNode = firstNode; + subPart.myCellGroupIndex = imed.groupes.size(); + imed.addSubPart( subPart ); + } + else if ( word == "coordinates" ) + { + // ------------------------------------ + // Unstructured global node coordinates + // ------------------------------------ + int nbNodes = geoFile.getInt(); + + cout << "-> loading coordinates of " << nbNodes << " nodes " << endl ; + + INoeud inoeud; + for ( int i=0 ; i < nbNodes ; i++ ) + { + if ( haveNodeIds ) { + int nodeID = geoFile.getInt(); + inoeud = points.insert( make_pair( nodeID, _noeud() )).first; + inoeud->second.number = nodeID; + } + else { + int nodeID = i + 1; + inoeud = points.insert( points.end(), make_pair( nodeID, _noeud())); + inoeud->second.number = nodeID; + } + _noeud & node = inoeud->second; + node.coord.resize( SPACE_DIM ); + node.coord[ 0 ] = geoFile.getReal(); + node.coord[ 1 ] = geoFile.getReal(); + node.coord[ 2 ] = geoFile.getReal(); + } + + _SubPartDesc cooDesc = _SubPartDesc::globalCoordDesc(); + _SubPart subPart( cooDesc.partNumber(), cooDesc.typeName() ); + subPart.myNbNodes = nbNodes; + subPart.myFirstNode = points.begin(); + imed.addSubPart( subPart ); + } + else + { + throw MED_EXCEPTION + ( LOCALIZED( STRING(LOC) << "Unexpected word: " << word << + " in " << getDataFileName())); + } + } // while ( !geoFile.eof() ) + + if ( haveStructuredParts && haveUnstructuredParts || haveStructuredParts > 1 ) + imed.mergeNodesAndElements(TOLERANCE); + + END_OF_MED(LOC); +} + +//================================================================================ +/*! + * \brief Read mesh in Ensight6 ASCII format + */ +//================================================================================ + +void ENSIGHT_MESH_RDONLY_DRIVER::read6Binary(_InterMed & imed) +{ + const char * LOC ="ENSIGHT_MESH_RDONLY_DRIVER::read6Binary() : "; + BEGIN_OF_MED(LOC); + + _BinaryFileReader geoFile( getDataFileName() ); + + // check if swapping bytes needed + try { + countPartsBinary( geoFile, isSingleFileMode()); + } + catch (...) { + geoFile.swapBytes(); + geoFile.rewind(); + } + if ( getIndexInDataFile() <= 1 ) + geoFile.rewind(); + if ( geoFile.getPosition() == 0 ) { + TStrOwner format( geoFile.getLine() ); // "C|Fortran Binary" + if ( !contains( "C Binary", format )) { + if ( contains( "Fortran Binary", format )) + throw(MEDEXCEPTION(STRING(LOC) << "Fortran Binary format not supported")); + else + throw(MEDEXCEPTION(STRING(LOC) << "unexpected line in " << getDataFileName() + << "\n" << format.myValues)); + } + } + + if ( isSingleFileMode() ) { + // one time step may be skipped by countPartsBinary + int curTimeStep = geoFile.getPosition() ? 2 : 1 ; + while ( curTimeStep < getIndexInDataFile() ) { + countPartsBinary( geoFile, true ); // skip time step + curTimeStep++; + } + while (1) { + TStrOwner line( geoFile.getLine() ); + if ( isTimeStepBeginning( line.myValues )) + break; + } + } + // ---------------------- + // Read mesh description + // ---------------------- + { + TStrOwner descriptionLine1( geoFile.getLine() ); + TStrOwner descriptionLine2( geoFile.getLine() ); + + // find out if the file was created by MED driver + _isMadeByMed = contains( theDescriptionPrefix, descriptionLine1 ); + + if ( _isMadeByMed ) + _ptrMesh->setDescription( descriptionLine2.myValues ); + else + _ptrMesh->setDescription( string(descriptionLine1) + descriptionLine2.myValues ); + } + + // ---------------------------------------- + // Find out presence of node/elem numbers + // ---------------------------------------- + + // EnSight User Manual (for v8) says: +// You do not have to assign node IDs. If you do, the element connectivities are +// based on the node numbers. If you let EnSight assign the node IDs, the nodes +// are considered to be sequential starting at node 1, and element connectivity is +// done accordingly. If node IDs are set to off, they are numbered internally; +// however, you will not be able to display or query on them. If you have node +// IDs in your data, you can have EnSight ignore them by specifying "node id +// ignore." Using this option may reduce some of the memory taken up by the +// Client and Server, but display and query on the nodes will not be available. + + // read "node|element id " + bool haveNodeIds, haveElemIds; + { + TStrOwner nodeIds( geoFile.getLine() ); + TStrOwner elemIds( geoFile.getLine() ); + + haveNodeIds = ( contains( "given", nodeIds ) || contains( "ignore", nodeIds ) ); + haveElemIds = ( contains( "given", elemIds ) || contains( "ignore", elemIds ) ); + } + map & points = imed.points; + typedef map::iterator INoeud; + + int haveStructuredParts = 0, haveUnstructuredParts = 0; + + _groupe * partGroupe = 0; + int partNum = 0; + + while ( !geoFile.eof() ) + { + TStrOwner line( geoFile.getLine() ); + if ( isSingleFileMode() && isTimeStepEnd( line.myValues )) + break; + string word, restLine; + TStrTool::split( line.myValues, word, restLine ); + + const TEnSightElemType & partType = getEnSightType( word ); + if ( !partType._medIndex.empty() ) + { + // Unstructured element type encounters + // -------------------------------------- + int nbElemNodes = partType._medType % 100; + int nbElems = *TIntOwner( geoFile.getInt(1) ); // ne + if ( nbElems > 0 ) + haveUnstructuredParts++; + + TIntOwner numbers(0); + if ( haveElemIds ) + numbers.myValues = geoFile.getInt( nbElems ); // id_e + + imed.groupes.push_back(_groupe()); + _groupe & groupe = imed.groupes.back(); + groupe.mailles.resize( nbElems ); + + // read connectivity + _maille ma( partType._medType, nbElemNodes ); + ma.sommets.resize( nbElemNodes ); + TIntOwner connectivity( geoFile.getInt( nbElems * nbElemNodes )); + int* nodeID = connectivity; + INoeud node; + for ( int i = 0; i < nbElems; ++i ) { + for ( int n = 0; n < nbElemNodes; ++n, ++nodeID ) + ma.sommets[ partType._medIndex[n] ] = points.find( *nodeID ); + //ma.ordre = ++order; + groupe.mailles[i] = imed.insert(ma); + } + + int groupeIndex = imed.groupes.size(); + partGroupe->groupes.push_back( groupeIndex ); + + _SubPart subPart( partNum, partType._name ); + subPart.myNbCells = nbElems; + subPart.myCellGroupIndex = groupeIndex; + imed.addSubPart( subPart ); + } + else if ( word == "part" ) + { + // Another part encounters + // ----------------------- + partNum = atoi( restLine.c_str() ); + + string partName( TStrOwner( geoFile.getLine() )); + if ( partName.empty() ) + partName = "Part_" + restLine; + + if ( imed.groupes.capacity() - imed.groupes.size() < theMaxNbTypes ) + imed.groupes.reserve( size_t( 1.5 * imed.groupes.size() )); + imed.groupes.push_back(_groupe()); + partGroupe = & imed.groupes.back(); + partGroupe->nom = partName; + partGroupe->groupes.reserve( theMaxNbTypes ); + } + else if ( word == "block" ) + { + // Structured type + // ------------------ + bool iblanked = ( restLine == "iblanked" ); + + // dimension + TIntOwner ijk( geoFile.getInt(3) ); + int I = ijk[0]; + int J = ijk[1]; + int K = ijk[2]; + int NumberOfNodes = I*J*K; + if ( !NumberOfNodes ) continue; + haveStructuredParts++; + + // read coordinates + int nodeShift = points.empty() ? 0 : points.rbegin()->first; + { + TFltOwner noInterlaceCoords( geoFile.getFlt( NumberOfNodes * SPACE_DIM )); + float* x = noInterlaceCoords; + float* y = x + NumberOfNodes; + float* z = y + NumberOfNodes; + for ( int iNode = 1; iNode <= NumberOfNodes; ++iNode ) { + INoeud inoeud = points.insert( points.end(), make_pair( iNode + nodeShift, _noeud())); + _noeud & node = inoeud->second; + node.number = inoeud->first; + node.coord.resize( SPACE_DIM ); + node.coord[0] = *x++; + node.coord[1] = *y++; + node.coord[2] = *z++; + } + } + // iblanks + if ( iblanked ) + geoFile.skip(NumberOfNodes * sizeof(int)); + + // let GRID calculate connectivity + GRID grid; + grid._numberOfNodes = NumberOfNodes ; + grid._iArrayLength = I; + grid._jArrayLength = J; + grid._kArrayLength = K; + grid._gridType = MED_BODY_FITTED; + grid._spaceDimension= SPACE_DIM; + if ( J < 2 ) { grid._spaceDimension--; grid._jArrayLength = 0; } + if ( K < 2 ) { grid._spaceDimension--; grid._kArrayLength = 0; } + + const int * conn = grid.getConnectivity( MED_FULL_INTERLACE, MED_NODAL, + MED_CELL, MED_ALL_ELEMENTS ); + medGeometryElement elemType = grid.getElementType( MED_CELL, 1 ); + int nbElemNodes = elemType % 100; + int nbElems = grid.getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS); + + partGroupe->mailles.resize( nbElems ); + _maille ma( elemType, nbElemNodes ); + ma.sommets.resize( nbElemNodes ); + + for ( int i = 0, nIndex = 0; i < nbElems; ++i ) { + for ( int n = 0; n < nbElemNodes; ++n ) { + int nodeID = conn[ nIndex++ ]; + ma.sommets[n] = points.find( nodeID + nodeShift ); + } + //ma.ordre = ++order; + partGroupe->mailles[i] = imed.insert(ma); + } + + _SubPart subPart( partNum, "block" ); + subPart.myNbCells = nbElems; + subPart.myNbNodes = NumberOfNodes; + subPart.myFirstNode = points.find( nodeShift + 1 ); + subPart.myCellGroupIndex = imed.groupes.size(); + imed.addSubPart( subPart ); + } + else if ( word == "coordinates" ) + { + // ------------------------------ + // Unstructured node coordinates + // ------------------------------ + int nbNodes = *TIntOwner( geoFile.getInt(1) ); + + TIntOwner numbers(0); + if ( haveNodeIds ) + numbers.myValues = geoFile.getInt( nbNodes ); + + TFltOwner fullInterlaceCoords( geoFile.getFlt( nbNodes * SPACE_DIM )); + float* coord = fullInterlaceCoords; + + cout << "-> loading coordinates of " << nbNodes << " nodes " << endl ; + + INoeud inoeud; + for ( int i=0 ; i < nbNodes ; i++ ) + { + if ( haveNodeIds ) { + int nodeID = numbers[ i ]; + inoeud = points.insert( make_pair( nodeID, _noeud() )).first; + inoeud->second.number = nodeID; + } + else { + int nodeID = i + 1; + inoeud = points.insert( points.end(), make_pair( nodeID, _noeud())); + inoeud->second.number = nodeID; + } + _noeud & node = inoeud->second; + node.coord.resize( SPACE_DIM ); + node.coord[ 0 ] = *coord++; + node.coord[ 1 ] = *coord++; + node.coord[ 2 ] = *coord++; + } + + _SubPartDesc cooDesc = _SubPartDesc::globalCoordDesc(); + _SubPart subPart( cooDesc.partNumber(), cooDesc.typeName() ); + subPart.myNbNodes = nbNodes; + subPart.myFirstNode = points.begin(); + imed.addSubPart( subPart ); + } + else + { + throw MED_EXCEPTION + ( LOCALIZED( STRING(LOC) << "Unexpected word: " << word << + " in " << getDataFileName())); + } + } // while ( !geoFile.eof() ) + + if ( haveStructuredParts && haveUnstructuredParts || haveStructuredParts > 1 ) + imed.mergeNodesAndElements(TOLERANCE); + + END_OF_MED(LOC); +} + +//================================================================================ +/*! + * \brief count number of parts in EnSight geometry file + */ +//================================================================================ + +int ENSIGHT_MESH_RDONLY_DRIVER::countParts(const string& geomFileName, + const bool isSingleFileMode) +{ + const char * LOC ="ENSIGHT_MESH_RDONLY_DRIVER::countParts() : "; + + int nbParts = 0; + if ( isBinaryDataFile( geomFileName )) + { + _BinaryFileReader geoFile(geomFileName); + // check if swapping bytes needed + try { + return countPartsBinary( geoFile, isSingleFileMode ); + } + catch (...) { + } + geoFile.swapBytes(); + geoFile.rewind(); + nbParts = countPartsBinary( geoFile, isSingleFileMode ); + } + else + { + _ASCIIFileReader geoFile(geomFileName); + + if ( isSingleFileMode ) + while ( !isTimeStepBeginning( geoFile.getLine() )); + + geoFile.getLine(); // description line 1 + geoFile.getLine(); // description line 2 + + // read "node|element id " + geoFile.getWord(); geoFile.getWord(); + string nodeIds = geoFile.getWord(); + geoFile.getWord(); geoFile.getWord(); + string elemIds = geoFile.getWord(); + bool haveNodeIds = ( nodeIds == "given" || nodeIds == "ignore" ); + bool haveElemIds = ( elemIds == "given" || elemIds == "ignore" ); + + bool isGold = true; + while ( !geoFile.isTimeStepEnd() ) + { + string word, restLine, line = geoFile.getLine(); + TStrTool::split( line, word, restLine ); + + const TEnSightElemType & partType = getEnSightType( word ); + if ( partType._medType != MED_ALL_ELEMENTS ) + { + // Unstructured element type encounters + // -------------------------------------- + int nbElemNodes = partType._medType % 100; + int nbElems = geoFile.getInt(); // ne + + // element ids + if ( haveElemIds && isGold ) + geoFile.skip( nbElems, /*nbPerLine =*/ 1, INT_WIDTH_GOLD ); // id_e + + // skip connectivity + int nbNodes = nbElems * nbElemNodes; + if ( partType._name == "nsided" ) // polygons + { + for ( int i = 0; i < nbElems; ++i ) + nbNodes += geoFile.getInt(); + geoFile.skip( nbNodes * INT_WIDTH_GOLD, /*nbLines = */nbElems ); + } + else if ( partType._name == "nfaced" ) // polyhedrons + { + int nbFaces = 0; + for ( int i = 0; i < nbElems; ++i ) + nbFaces += geoFile.getInt(); + for ( int f = 0; f < nbFaces; ++f ) + nbNodes += geoFile.getInt(); + geoFile.skip( nbNodes * INT_WIDTH_GOLD, /*nbLines = */nbFaces ); + } + else // standard types + { + if ( isGold ) + geoFile.skip( nbNodes, nbElemNodes, INT_WIDTH_GOLD ); + else if ( haveElemIds ) + geoFile.skip( nbNodes + nbElems, nbElemNodes+1, INT_WIDTH_6 ); + else + geoFile.skip( nbNodes, nbElemNodes, INT_WIDTH_6 ); + } + } + else if ( word == "coordinates" ) + { + isGold = ( nbParts > 0 ); + int nbNodes = geoFile.getInt(); // nn + + if ( isGold ) + { + if ( haveNodeIds ) + geoFile.skip( nbNodes, /*nbPerLine =*/ 1, INT_WIDTH_GOLD ); // node ids + geoFile.skip( nbNodes * SPACE_DIM, /*nbPerLine =*/ 1, FLT_WIDTH ); // coordinates + } + else { + int coordWidth = 3 * FLT_WIDTH; + if ( haveNodeIds ) + coordWidth += INT_WIDTH_6; + geoFile.skip(nbNodes, /*nbPerLine =*/ 1, coordWidth); + } + } + else if ( word == "part" ) + { + nbParts++; + if ( isGold ) + geoFile.skip( 1, /*nbPerLine =*/ 1, INT_WIDTH_GOLD ); //part number + else + geoFile.getWord(); // part number + geoFile.toNextLine(); + geoFile.getLine(); // description line + } + else if ( word == "block" ) + { + // Structured type + // ------------------ + bool rectilinear = ( restLine.find( "rectilinear" ) != restLine.npos ); + bool uniform = ( restLine.find( "uniform" ) != restLine.npos ); + bool curvilinear = ( !rectilinear && !uniform ); + bool iblanked = ( restLine.find( "iblanked" ) != restLine.npos ); + bool with_ghost = ( restLine.find( "with_ghost" ) != restLine.npos ); + bool range = ( restLine.find( "range" ) != restLine.npos ); + + // dimension + int I = geoFile.getInt(); + int J = geoFile.getInt(); + int K = geoFile.getInt(); + int nbNodes = I*J*K; + if ( !nbNodes ) continue; + + // range + if ( range ) { + vector ijkRange; // imin imax jmin jmax kmin kmax + ijkRange.reserve(6); + while ( ijkRange.size() < 6 ) + ijkRange.push_back( geoFile.getInt() ); + I = ijkRange[1]-ijkRange[0]+1; + J = ijkRange[3]-ijkRange[2]+1; + K = ijkRange[5]-ijkRange[4]+1; + nbNodes = I*J*K; + } + int nbElems = (I-1)*(J-1)*(K-1); + + if ( curvilinear ) // read coordinates for all nodes + { + if ( isGold ) + geoFile.skip( nbNodes, /*nbPerLine =*/ 1, FLT_WIDTH ); + else + geoFile.skip( nbNodes * SPACE_DIM, /*nbPerLine =*/ 6, FLT_WIDTH ); + } + else if ( rectilinear ) // read delta vectors with non-regular spacing + { + geoFile.skip( I + J + K, /*nbPerLine =*/ 1, FLT_WIDTH ); + } + else // uniform: read grid origine and delta vectors for regular spacing grid + { + geoFile.skip( 6, /*nbPerLine =*/ 1, FLT_WIDTH ); + } + + // iblanks + if ( iblanked ) { + if ( isGold ) + geoFile.skip( nbNodes, /*nbPerLine =*/ 1, INT_WIDTH_GOLD); + else + geoFile.skip( nbNodes, /*nbPerLine =*/ 10, INT_WIDTH_6 ); + } + // ghosts + if ( with_ghost ) { + geoFile.getWord(); // "ghost_flags" + geoFile.skip( nbElems, /*nbPerLine =*/ 1, INT_WIDTH_GOLD); + } + // node ids + if ( haveNodeIds && geoFile.lookAt( "node_ids" )) { + geoFile.getWord(); // "node_ids" + geoFile.skip( nbNodes, /*nbPerLine =*/ 1, INT_WIDTH_GOLD); + } + // element ids + if ( haveElemIds && geoFile.lookAt( "element_ids" ) ) { + geoFile.getWord(); // "element_ids" + geoFile.skip( nbElems, /*nbPerLine =*/ 1, INT_WIDTH_GOLD); + } + } + else if ( word == "extents" ) { + geoFile.getLine(); geoFile.getLine(); geoFile.getLine();// 3 x 2E12.5 + } + else + { + throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Unexpected word: " << word)); + } + } + } + return nbParts; +} + +//================================================================================ +/*! + * \brief count number of parts in EnSight geometry file + */ +//================================================================================ + +int ENSIGHT_MESH_RDONLY_DRIVER::countPartsBinary(_BinaryFileReader& geoFile, + const bool isSingleFileMode) +{ + const char * LOC ="ENSIGHT_MESH_RDONLY_DRIVER::countPartsBinary() : "; + + if ( geoFile.getPosition() == 0 ) { + TStrOwner format( geoFile.getLine() ); // "C|Fortran Binary" + if ( !contains( "C Binary", format )) { + if ( contains( "Fortran Binary", format )) + throw(MEDEXCEPTION(STRING(LOC) << "Fortran Binary format not supported")); + else + throw(MEDEXCEPTION(STRING(LOC) << "unexpected line: \n" << format.myValues)); + } + } + + if ( isSingleFileMode ) { + while (1) { + TStrOwner line( geoFile.getLine() ); + if ( isTimeStepBeginning( line.myValues )) + break; + } + } + + // 2 description lines + // ---------------------- + geoFile.skip( 2 * MAX_LINE_LENGTH ); + + // read "node|element id " + bool haveNodeIds, haveElemIds; + { + TStrOwner nodeIds( geoFile.getLine() ); + TStrOwner elemIds( geoFile.getLine() ); + + haveNodeIds = ( contains( "given", nodeIds ) || contains( "ignore", nodeIds ) ); + haveElemIds = ( contains( "given", elemIds ) || contains( "ignore", elemIds ) ); + } + + int nbParts = 0; // the result + bool isGold = true; + + while ( !geoFile.eof() ) + { + TStrOwner line( geoFile.getLine() ); + if ( isSingleFileMode && isTimeStepEnd( line.myValues )) + break; + string word, restLine; + TStrTool::split( line.myValues, word, restLine ); + + const TEnSightElemType & partType = getEnSightType( word ); + if ( partType._medType != MED_ALL_ELEMENTS ) + { + // Unstructured element type encounters + // -------------------------------------- + int nbElems = *TIntOwner( geoFile.getInt(1) ); // ne + int nbElemNodes = partType._medType % 100; + + // read element ids + if ( haveElemIds ) + geoFile.skip( nbElems * sizeof(int) ); // id_e + + int nbNodes = nbElems * nbElemNodes; + if ( partType._name == "nsided" ) // polygons + { + TIntOwner nbNodesInFace( geoFile.getInt( nbElems )); + nbNodes = std::accumulate( nbNodesInFace.myValues, nbNodesInFace.myValues + nbElems, 0 ); + } + else if ( partType._name == "nfaced" ) // polyhedrons + { + TIntOwner nbElemFaces( geoFile.getInt( nbElems )); + int nbFaces = accumulate( nbElemFaces.myValues, nbElemFaces.myValues + nbElems, 0 ); + TIntOwner nbNodesInFace( geoFile.getInt( nbFaces )); + nbNodes = std::accumulate( nbNodesInFace.myValues, nbNodesInFace.myValues + nbFaces, 0 ); + } + geoFile.skip( nbNodes * sizeof(int) ); + } + else if ( word == "coordinates" ) + { + if ( nbParts == 0 ) + isGold = false; + int nbNodes = *TIntOwner( geoFile.getInt(1) ); // nn + + // node ids + if ( haveNodeIds ) + geoFile.skip( nbNodes * sizeof(int) ); // id_n + + // coordinates + geoFile.skip( nbNodes * SPACE_DIM * sizeof(int) ); + } + else if ( word == "part" ) + { + ++nbParts; + if ( isGold ) geoFile.skip(sizeof(int)); // part # + + geoFile.skip(MAX_LINE_LENGTH); // description line + } + else if ( word == "block" ) + { + // Structured type + // ------------------ + bool rectilinear = ( restLine.find( "rectilinear" ) != restLine.npos ); + bool uniform = ( restLine.find( "uniform" ) != restLine.npos ); + bool curvilinear = ( !rectilinear && !uniform ); + bool iblanked = ( restLine.find( "iblanked" ) != restLine.npos ); + bool with_ghost = ( restLine.find( "with_ghost" ) != restLine.npos ); + bool range = ( restLine.find( "range" ) != restLine.npos ); + + // dimension + TIntOwner ijk( geoFile.getInt(3) ); + int I = ijk[0]; + int J = ijk[1]; + int K = ijk[2]; + int NumberOfNodes = I*J*K; + if ( !NumberOfNodes ) { + if ( I != 0 && J != 0 && K != 0 ) + throw MEDEXCEPTION( "Need to swap bytes" ); + continue; + } + + // range + if ( range ) { + TIntOwner ijkRange( geoFile.getInt( 6 ));// imin imax jmin jmax kmin kmax + I = ijkRange[1]-ijkRange[0]+1; + J = ijkRange[3]-ijkRange[2]+1; + K = ijkRange[5]-ijkRange[4]+1; + NumberOfNodes = I*J*K; + } + int nbElems = (I-1)*(J-1)*(K-1); + + if ( curvilinear ) // read coordinates for all nodes + { + geoFile.skip( NumberOfNodes * SPACE_DIM * sizeof(float) ); + } + else if ( rectilinear ) // read delta vectors with non-regular spacing + { + geoFile.skip( (I+J+K) * sizeof(float) ); + } + else // uniform: read grid origine and delta vectors for regular spacing grid + { + geoFile.skip( 6 * sizeof(float) ); + } + + // iblanks + if ( iblanked ) + geoFile.skip( NumberOfNodes * sizeof(int) ); + // ghosts + if ( with_ghost ) { + geoFile.skip( MAX_LINE_LENGTH ); // "ghost_flags" + geoFile.skip( nbElems * sizeof(int) ); + } + // node ids + if ( haveNodeIds && isGold && !geoFile.eof() ) { + TStrOwner nextLine( geoFile.getLine() ); // "node_ids" + if ( contains( "node_ids", nextLine ) ) + geoFile.skip( NumberOfNodes * sizeof(int) ); + else + geoFile.skip( -MAX_LINE_LENGTH ); + } + // element ids + if ( haveElemIds && isGold && !geoFile.eof() ) { + TStrOwner nextLine( geoFile.getLine() ); // "element_ids" + if ( contains( "element_ids", nextLine ) ) + geoFile.skip( nbElems * sizeof(int) ); + else + geoFile.skip( -MAX_LINE_LENGTH ); + } + } + else if ( word == "extents" ) + { + geoFile.skip( 6 * sizeof(float) ); + } + else + { + throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Unexpected word: " << word )); + } + } // while ( !geoFile.eof() ) + + return nbParts; +} + +GROUP* ENSIGHT_MESH_RDONLY_DRIVER::makeGroup( _groupe& grp, + _InterMed & imed) +{ + //const char* LOC = "ENSIGHT_MESH_RDONLY_DRIVER::makeGroup(): error"; + + // prevent creation of other groups but only this one + for (size_t i=0; i < imed.groupes.size(); ++i) + imed.groupes[i].nom.clear(); + + // let _intermediateMED create a GROUP from grp + grp.medGroup = 0; // the new GROUP should appear in grp.medGroup + grp.nom = "TMP"; + vector tmp; + imed.getGroups( tmp, tmp, tmp, tmp, imed._medMesh ); + if ( !grp.medGroup ) + throw MEDEXCEPTION(LOCALIZED("Can't create a GROUP from _groupe")); + + grp.medGroup->setName(""); // to let a caller set a proper name + grp.nom = ""; + + // find pre-existing equal _groupe + _groupe * equalGroupe = 0; + for (unsigned int i=0; i < imed.groupes.size() && !equalGroupe; ++i) { + _groupe& g = imed.groupes[i]; + if ( &g != &grp && g.medGroup && g.medGroup->deepCompare( *grp.medGroup )) + equalGroupe = & g; + } + if ( equalGroupe ) { + delete grp.medGroup; + grp.medGroup = equalGroupe->medGroup; + } + else { // new unique group + + if ( grp.medGroup->isOnAllElements() ) // on all elems + grp.medGroup->setName( string("SupportOnAll_")+entNames[ grp.medGroup->getEntity() ] ); + + // add a new group to mesh + if ( !imed._isOwnMedMesh ) { + vector * groups = 0; + switch ( grp.medGroup->getEntity() ) { + case MED_CELL: groups = & imed._medMesh->_groupCell; break; + case MED_FACE: groups = & imed._medMesh->_groupFace; break; + case MED_EDGE: groups = & imed._medMesh->_groupEdge; break; + case MED_NODE: groups = & imed._medMesh->_groupNode; break; + default:; + } + if ( groups ) { + groups->resize( groups->size() + 1 ); + groups->at( groups->size() - 1) = grp.medGroup; + } + } + } + return grp.medGroup; +} diff --git a/src/MEDMEM/MEDMEM_EnsightMeshDriver.hxx b/src/MEDMEM/MEDMEM_EnsightMeshDriver.hxx index 34a427ac2..066c83f16 100644 --- a/src/MEDMEM/MEDMEM_EnsightMeshDriver.hxx +++ b/src/MEDMEM/MEDMEM_EnsightMeshDriver.hxx @@ -1,122 +1,149 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef ENSIGHT_MESH_DRIVER_HXX #define ENSIGHT_MESH_DRIVER_HXX -#include -#include #include "MEDMEM_define.hxx" -#include "MEDMEM_GenDriver.hxx" -#include "MEDMEM_Support.hxx" - -#include "MEDMEM_STRING.hxx" #include "MEDMEM_Exception.hxx" -#include "MEDMEM_Utilities.hxx" +#include "MEDMEM_EnsightUtils.hxx" #include -using namespace std ; +namespace MEDMEM { -/*! + class MESH; + class SUPPORT; +// ============================================================================== +/*! Driver Ensight for MESH ( writing and reading ). Generic part : implement open and close methods. - */ -namespace MEDMEM { -class MESH; -class FAMILY; -class GROUP; -class CONNECTIVITY; -class ENSIGHT_MESH_DRIVER : public GENDRIVER +// ============================================================================== + +class MEDMEM_EXPORT ENSIGHT_MESH_DRIVER : public MEDMEM_ENSIGHT::_CaseFileDriver_User { protected: - MESH * _ptrMesh; - string _meshName; + MESH * _ptrMesh; + std::string _meshName; - virtual void openConst() const =0; - virtual void closeConst() const =0; + virtual void openConst(bool checkDataFile=false) const; public : ENSIGHT_MESH_DRIVER() ; - ENSIGHT_MESH_DRIVER(const string & fileName, MESH * ptrMesh) ; - ENSIGHT_MESH_DRIVER(const string & fileName, MESH * ptrMesh, - MED_EN::med_mode_acces accessMode); + ENSIGHT_MESH_DRIVER(const std::string & fileName, MESH * ptrMesh) ; + ENSIGHT_MESH_DRIVER(const std::string & fileName, MESH * ptrMesh, + MED_EN::med_mode_acces accessMode); ENSIGHT_MESH_DRIVER(const ENSIGHT_MESH_DRIVER & driver) ; virtual ~ENSIGHT_MESH_DRIVER() ; void open(); void close(); - virtual void write( void ) const = 0 ; - virtual void read( void ) = 0 ; - virtual GENDRIVER * copy (void ) const = 0; - void setMeshName(const string & meshName) ; - string getMeshName() const ; + virtual void setMeshName(const string & meshName); + virtual std::string getMeshName() const; + MESH* getMesh() { return _ptrMesh; } }; -class ENSIGHT_MESH_RDONLY_DRIVER : public virtual ENSIGHT_MESH_DRIVER +// ============================================================================== +/*! + * \brief Reading EnSight driver. + */ +// ============================================================================== + +class MEDMEM_EXPORT ENSIGHT_MESH_RDONLY_DRIVER : public virtual ENSIGHT_MESH_DRIVER { public : + //!< to read mesh of index-th time step + ENSIGHT_MESH_RDONLY_DRIVER(const std::string & fileName, MESH * ptrMesh, int index=1); + ENSIGHT_MESH_RDONLY_DRIVER(); - ENSIGHT_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh); ENSIGHT_MESH_RDONLY_DRIVER(const ENSIGHT_MESH_RDONLY_DRIVER & driver); virtual ~ENSIGHT_MESH_RDONLY_DRIVER(); - void openConst() const; - void closeConst() const; - void write ( void ) const throw (MEDEXCEPTION) ; - void read ( void ) ; + virtual GENDRIVER * copy ( void ) const; + virtual void merge ( const GENDRIVER& driver ); + virtual void write ( void ) const throw (MEDEXCEPTION) ; + virtual void read ( void ) throw (MEDEXCEPTION); + + //!< count number of parts in EnSight geometry file + static int countParts(const std::string& geomFileName, + const bool isSingleFileMode); + + static GROUP* makeGroup( MEDMEM::_groupe & interGroup, + MEDMEM_ENSIGHT::_InterMed & imed); + private: - ifstream * _ensightFile; // The main _ensightFile used to read geom and data _filename - GENDRIVER * copy ( void ) const; + + void readGoldASCII (MEDMEM_ENSIGHT::_InterMed & imed); + void readGoldBinary(MEDMEM_ENSIGHT::_InterMed & imed); + void read6ASCII (MEDMEM_ENSIGHT::_InterMed & imed); + void read6Binary (MEDMEM_ENSIGHT::_InterMed & imed); + + static int countPartsBinary(MEDMEM_ENSIGHT::_BinaryFileReader& fileReader, + const bool isSingleFileMode); + + bool _isMadeByMed; + int _indexInCaseFile; }; -class ENSIGHT_MESH_WRONLY_DRIVER : public virtual ENSIGHT_MESH_DRIVER +// ============================================================================== +/*! + * \brief Writing EnSight mesh driver. + * To set writing format use + * setEnSightFormatForWriting(EnSightFormat) and + * setEnSightBinaryFormatForWriting(bool) + */ +// ============================================================================== + +class MEDMEM_EXPORT ENSIGHT_MESH_WRONLY_DRIVER : public virtual ENSIGHT_MESH_DRIVER { public : + //!< write a mesh; + // to be appended, a mesh mush have same nb of groups and dimension as already present ones + ENSIGHT_MESH_WRONLY_DRIVER(const std::string & fileName, MESH * ptrMesh, bool append=false); + ENSIGHT_MESH_WRONLY_DRIVER(); - ENSIGHT_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh); ENSIGHT_MESH_WRONLY_DRIVER(const ENSIGHT_MESH_WRONLY_DRIVER & driver); virtual ~ENSIGHT_MESH_WRONLY_DRIVER(); - void openConst() const; - void closeConst() const; - void write ( void ) const throw (MEDEXCEPTION) ; -// void writeFrom ( void ) const throw (MEDEXCEPTION) ; - void read ( void ) throw (MEDEXCEPTION) ; -// virtual void readFileStruct ( void ) throw (MEDEXCEPTION) ; - // add one support - void addSupport(SUPPORT *sup); + GENDRIVER * copy ( void ) const; + void write ( void ) const throw (MEDEXCEPTION) ; + void read ( void ) throw (MEDEXCEPTION) ; + + int nbPartsToWrite() const; private: - ofstream * _ensightFile; // The main _ensightFile used to write geom and data _filename - GENDRIVER * copy ( void ) const; - vector _support; -// void writeMesh(MESH * myMesh,int imesh) const ; -// void writeSupport(SUPPORT * mySupport) const ; -}; + void writePart6Binary (MEDMEM_ENSIGHT::_BinaryFileWriter& file, const SUPPORT* support) const; + void writePartGoldBinary(MEDMEM_ENSIGHT::_BinaryFileWriter& file, const SUPPORT* support) const; + void writePart6ASCII (std::ofstream& fileStream, const SUPPORT* support) const; + void writePartGoldASCII (std::ofstream& fileStream, const SUPPORT* support) const; + bool _append; }; +} + #endif /* ENSIGHT_MESH_DRIVER_HXX */ diff --git a/src/MEDMEM/MEDMEM_EnsightUtils.cxx b/src/MEDMEM/MEDMEM_EnsightUtils.cxx new file mode 100644 index 000000000..290a2e81c --- /dev/null +++ b/src/MEDMEM/MEDMEM_EnsightUtils.cxx @@ -0,0 +1,2914 @@ +// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// File : MEDMEM_EnsightUtils.cxx +// Created : Fri Jun 6 16:08:32 2008 +// Author : Edward AGAPOV (eap) + + +#include "MEDMEM_Field.hxx" // important to include it before MEDMEM_EnsightUtils.hxx, +// in order not to redefine DBL_MIN + +#include "MEDMEM_EnsightUtils.hxx" + +#include "MEDMEM_EnsightMeshDriver.hxx" +#include "MEDMEM_EnsightFieldDriver.hxx" +#include "MEDMEM_DriverTools.hxx" + +#ifdef WNT +#include +#else +#include +#endif +#include +//#include + +using namespace std; +using namespace MEDMEM; + + // TODO: +// -2) in transient model, get time values for meshes form fields on them +// -1) why after reading /data/eap/ENSIGHT/SAMPLES_SRC/EnSight/crash.case only +// geo EnSIght files are written +// -0) test selecting imaginary part to read +// 0) appending fields to write with same names in Case file +// 1) write grid +// 2) if mesh description is longer that maxLen, distribute it among two lines +// 3) care of mesh description at reading +// 4) at writing, cut off " t=..." from mesh name and set to meshDriver->_meshName +// 5) MEDMEM_EXPORT +// 4.5) do something with zzzz121b.med pb +// 6) stripe in getLine() +// 7) care of elem numbers that were read +// 8) read real and imaginary of complex field by MED driver +// 9) read "mesured" and care of variable on it +// 10) clear theInterMedMap and delete _InterMed's there +// 11) not to fill MESH made in getMeshData() +// 12) care of changing nb of '*' in names +// 14) analize _TimeSet to write in shortest form +// 15) add LOCALIZED where no method name specified +// 17) add checks of input mesh and field like in gibi +// 18) check writing interlace in all modes +// 19) define creation by MEDMEM by case file and not by geo +// 21) there maybe '\n' in binary file after string end +// 22) optimize _ASCIIFileReader::eof() at file end +// 23) What if to create CELL entity with 1-3 dim and a CELL group? +// 24) not to write CELL connectivity if a group on all cells is present +// 25) compact imed (sortedNodeIDs etc.) +// 26) no need in converting EnSight variables to eventual types in convertReals +// since a result array is not used directly but occupies more memory +// 27) try to exclude merged nodes in DTree and compare time on ChampsDarcy.med + + +namespace MEDMEM +{ + // ============================================================================== + /*! + Writing format. + */ + // ============================================================================== + + EnSightFormat theEnSightFormatForWriting = ENSIGHT_6; + bool theBinaryFormatForWriting = false; + bool theIgnoreIncompatibility = false; + + void setEnSightFormatForWriting (EnSightFormat format, bool isBinary) + { + theEnSightFormatForWriting = format; + theBinaryFormatForWriting = isBinary; + } + EnSightFormat getEnSightFormatForWriting() + { + return theEnSightFormatForWriting; + } + bool isBinaryEnSightFormatForWriting() + { + return theBinaryFormatForWriting; + } + // ============================================================================== + /*! + To raise or not if MEDMEM-EnSight incompatibility encounters or suspected + */ + // ============================================================================== + + void setIgnoreIncompatibility(bool toIgnore) + { + theIgnoreIncompatibility = toIgnore; + } +} + +#ifdef WNT +#define FILE_SEPARATOR '\\' +#else +#define FILE_SEPARATOR '/' +#endif + +#define _ATOI( str ) atoi((str).c_str()) +#define _ATOF( str ) atof((str).c_str()) + +#define BUFFER_SIZE 16184 // for non-stream input + +namespace MEDMEM_ENSIGHT +{ + //-------------------------------------------------------------------------------- + /*! + * \brief Registry of drivers creating _CaseFileDriver + * + * The problem is that if the mesh/field driver is created by the user, it is + * to write Case file, but if it is created by MED driver, it should not, in + * order not to overwrite the Case file written by MED driver. + * To assure this feature, we register all mesh/field drivers added to a case + * file by a MED driver and then ignore thier calls to _CaseFileDriver. + */ + set< const _CaseFileDriver_User* > theCaseUsers; + + //-------------------------------------------------------------------------------- + /*! + * \brief Storage of data read by mesh driver to be used by field drivers + * + * The field driver needs info read by the mesh driver (nb of elements by type in + * each part and what place the element gets in MEDMED support). + * So we store needed data unless it is no more needed (i.e. no driver is alive). + * The map key is ":". + */ + map< string, _InterMed* > theInterMedMap; + + //-------------------------------------------------------------------------------- + /*! + * \brief Add a driver to the registry and return true if was already in + */ + bool isToIgnore(const _CaseFileDriver_User* driver) + { + return ! theCaseUsers.insert( driver ).second; + } + + //-------------------------------------------------------------------------------- + /*! + * \brief Remove a driver from the registry + */ + void unregister(const _CaseFileDriver_User* driver) + { + theCaseUsers.erase( driver ); + } + + //-------------------------------------------------------------------------------- + /*! + * \brief Return mesh data needed by field driver + */ + _InterMed* getMeshData( const string& key ) + { + // find existing data + map< string, _InterMed* >::iterator kimed = theInterMedMap.find( key ); + if ( kimed != theInterMedMap.end() ) + return kimed->second; + + // create a new data + MESH * mesh = new MESH; + string caseFile, meshIndex; + _ASCIIFileReader::split( key, caseFile, meshIndex, ':' ); + ENSIGHT_MESH_RDONLY_DRIVER meshDrv(caseFile, mesh, _ATOI( meshIndex )); + meshDrv.read(); + kimed = theInterMedMap.find( key ); + if ( kimed == theInterMedMap.end() ) + return 0; + _InterMed* imed = kimed->second; + imed->_medMesh = mesh; + imed->_isOwnMedMesh = true; + return imed; + } + // --------------------------------------------------------------- + /*! + * \brief Prepend "EnSight-MEDMEM compatibility problem" to the text + * of an exception + */ + STRING compatibilityPb(const string& exceptionText) + { + return STRING("EnSight-MEDMEM compatibility problem:\n") << exceptionText; + } + // --------------------------------------------------------------- + /*! + * \brief To ignore incompatibility or not + */ + bool toIgnoreIncompatibility() + { + return theIgnoreIncompatibility; + } + + //-------------------------------------------------------------------------------- + /*! + * \brief Return true if set index is empty or corresponds to an existing set + */ + template bool isValidIndex(const string& index, const map& aMap) + { + if ( index.empty() ) return true; + return ( aMap.find( _ATOI( index ) ) != aMap.end() ); + } + + //-------------------------------------------------------------------------------- + /*! + * \brief Return EnSight type corresponding to med one + */ + const TEnSightElemType& getEnSightType(medGeometryElement medType) + { + static TEnSightElemType theEnSightType; + + int nbNodes = medType % 100; + theEnSightType._medType = medType; + + switch ( medType ) { + case MED_NONE : + case MED_POINT1 : { + theEnSightType._name = "point"; + theEnSightType._medIndex.resize(1,0); + break ; + } + case MED_SEG2 : { + theEnSightType._name = "bar2"; + int conn [2] = {0,1}; + theEnSightType._medIndex.assign( conn, conn+nbNodes ); + break ; + } + case MED_SEG3 : { + theEnSightType._name = "bar3"; + int conn [3] = {0,2,1}; + theEnSightType._medIndex.assign( conn, conn+nbNodes ); + break ; + } + case MED_TRIA3 : { + theEnSightType._name = "tria3"; + int conn [3] = {0,2,1}; + theEnSightType._medIndex.assign( conn, conn+nbNodes ); + break ; + } + case MED_QUAD4 : { + theEnSightType._name = "quad4"; + int conn [4] = {0,3,2,1}; + theEnSightType._medIndex.assign( conn, conn+nbNodes ); + break ; + } + case MED_TRIA6 : { + theEnSightType._name = "tria6"; + int conn [6] = {0,2,1,5,4,3}; + theEnSightType._medIndex.assign( conn, conn+nbNodes ); + break ; + } + case MED_QUAD8 : { + theEnSightType._name = "quad8"; + int conn [8] = {0,3,2,1,7,6,5,4}; + theEnSightType._medIndex.assign( conn, conn+nbNodes ); + break ; + } + case MED_TETRA4 : { + theEnSightType._name = "tetra4"; + int conn [4] = {0,1,3,2}; + theEnSightType._medIndex.assign( conn, conn+nbNodes ); + break ; + } + case MED_PYRA5 : { + theEnSightType._name = "pyramid5"; + int conn [5] = {0,3,2,1,4}; + theEnSightType._medIndex.assign( conn, conn+nbNodes ); + break ; + } + case MED_PENTA6 : { + theEnSightType._name = "penta6"; + int conn [6] = {0,2,1,3,5,4}; + theEnSightType._medIndex.assign( conn, conn+nbNodes ); + break ; + } + case MED_HEXA8 : { + theEnSightType._name = "hexa8"; + int conn [8] = {0,3,2,1,4,7,6,5}; + theEnSightType._medIndex.assign( conn, conn+nbNodes ); + break ; + } + case MED_TETRA10 : { + theEnSightType._name = "tetra10"; + int conn [10] = {0,2,1,3,6,5,4,7,9,8}; + theEnSightType._medIndex.assign( conn, conn+nbNodes ); + break ; + } + case MED_PYRA13 : { + theEnSightType._name = "pyramid13"; + int conn [13] = {0,3,2,1,4,8,7,6,5,9,12,11,10}; + theEnSightType._medIndex.assign( conn, conn+nbNodes ); + break ; + } + case MED_PENTA15 : { + theEnSightType._name = "penta15"; + int conn [15] = {0,2,1,3,5,4,8,7,6,11,10,12,14,13}; + theEnSightType._medIndex.assign( conn, conn+nbNodes ); + break ; + } + case MED_HEXA20 : { + theEnSightType._name = "hexa20"; + int conn [20] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17}; + theEnSightType._medIndex.assign( conn, conn+nbNodes ); + break ; + } + case MED_POLYGON : { + theEnSightType._name = "nsided"; + theEnSightType._medIndex.clear(); + break ; + } + case MED_POLYHEDRA : { + theEnSightType._name = "nfaced"; + theEnSightType._medIndex.clear(); + break ; + } + default: { + theEnSightType._name = ""; + theEnSightType._medIndex.clear(); + } + } + return theEnSightType; + } + + //-------------------------------------------------------------------------------- + /*! + * \brief Return EnSight type having a given name + */ + const TEnSightElemType& getEnSightType(const string& theTypeName) + { + string typeName = theTypeName; + if ( isGhostType( typeName )) + typeName = string( &typeName[2] ); // ghost type + + static map name2Type; + + map::iterator nameType = name2Type.find( typeName ); + if ( nameType != name2Type.end() ) + return nameType->second; + + const list & allMedTypes = MED_EN::meshEntities[MED_CELL]; + list< medGeometryElement >::const_iterator medType = allMedTypes.begin(); + for ( ; medType != allMedTypes.end(); ++medType ) + { + const TEnSightElemType& enSightType = getEnSightType( *medType ); + if ( enSightType._name == typeName ) + return name2Type[ typeName ] = enSightType; + } + return getEnSightType(MED_ALL_ELEMENTS); + } + +// =============================================================== _CaseFileDriver +/*! + * \brief Case file driver constructor + */ +//================================================================================ + +_CaseFileDriver::_CaseFileDriver(const string & fileName, + const _CaseFileDriver_User* creator) + : _user( creator ), _fileName( fileName ), _directory(".") +{ + // Find out if the driver is blocked + _blocked = isToIgnore( creator ); + if ( !_blocked ) { + // set directory + string::size_type sepPos = _fileName.rfind( FILE_SEPARATOR ); + if ( sepPos != _fileName.npos ) { + _directory = _fileName.substr( 0, sepPos ); + } + _format = getEnSightFormatForWriting(); + } +} + +// =============================================================== _CaseFileDriver +/*! + * \brief Case file driver destructor + */ +//================================================================================ + +_CaseFileDriver::~_CaseFileDriver() +{ + if ( !_blocked ) + // to write case file again by same DRIVER + unregister( _user ); +} + +#define READ_NEXT_LINE continue +#define RAISE_EXCEPTION break + +//================================================================================ +/*! + * \brief Read Case file + */ +//================================================================================ + +void _CaseFileDriver::read() throw (MEDEXCEPTION) +{ + if ( _blocked ) + return; + + _ASCIIFileReader reader( _fileName ); + + STRING badFile("Invalid Case file "); + badFile << _fileName << "\n"; + + list<_FileSet> fileSets; + list<_TimeSet> timeSets; + + set varNames; // to detect equal variable names + + string section = "_"; + int lineNb = 0; + while ( !reader.eof() ) + { + string line = reader.getLine(); + ++lineNb; + + // cut off comments + string comment; + reader.split( line, line, comment, '#'); + if ( line.empty() ) + READ_NEXT_LINE; + + string key, value; // parts of a line splited by column + reader.split( line, key, value, ':'); + + STRING errorMsg; + + // analyse not empty lines + switch ( section[0] ) { + case 'V': { + // -------------------------------------------------------------------------------- + // VARIABLE + + string type, s, ts, fs; + reader.split(key,type,s); + int newVarIndex = _variables.empty() ? 1 : _variables.rbegin()->first + 1; + + if ( type == "scalar" || type == "vector" || type == "tensor" ) + { + // scalar per node: [ts] [fs] description filename + // vector per node: [ts] [fs] description filename + // tensor symm per node: [ts] [fs] description filename + // tensor asym per node: [ts] [fs] description filename + // scalar per element: [ts] [fs] description filename + // vector per element: [ts] [fs] description filename + // tensor symm per element: [ts] [fs] description filename + // tensor asym per element: [ts] [fs] description filename + // scalar per measured node: [ts] [fs] description filename + // vector per measured node: [ts] [fs] description filename + list parts; + int nbParts = reader.split( value, parts ); + if ( nbParts < 2 ) { + errorMsg << "invalid variable format:\n" << line; + RAISE_EXCEPTION; + } + if ( contains( "per measured node", s.c_str() )) { + //cout << "Skip not supported data type: " << key << endl; + READ_NEXT_LINE; + } + list::reverse_iterator p = parts.rbegin(); + _Variable& var = _variables[newVarIndex]; + var._type = key; + var._fileNameOrData = *p++; + var._name = *p++; + if ( nbParts == 3 ) { + var._timeSetNumber = *p; + } + else if ( nbParts == 4 ) { + var._fileSetNumber = *p++; + var._timeSetNumber = *p; + } + varNames.insert( var._name ); + READ_NEXT_LINE; + } + else if ( type == "constant" ) + { + // constant per case: [ts] description const_value(s) + // constant per case file: [ts] description cvfilename + reader.split(value,s,value); + if ( reader.isDigit( s )) { + ts = s; + reader.split(value,s,value); + } + _Variable& var = _variables[newVarIndex]; + var._type = key; + var._name = s; + var._fileNameOrData = value; + var._timeSetNumber = ts; + if ( var._name.empty() || var._fileNameOrData.empty() ) { + errorMsg << "invalid variable format:\n" << line; + RAISE_EXCEPTION; + } + varNames.insert( var._name ); + READ_NEXT_LINE; + } + else if ( type == "complex" ) + { + // complex scalar per node: [ts] [fs] description Re_fn Im_fn freq + // complex vector per node: [ts] [fs] description Re_fn Im_fn freq + // complex scalar per element: [ts] [fs] description Re_fn Im_fn freq + // complex vector per element: [ts] [fs] description Re_fn Im_fn freq + reader.split(value,s,value); + if ( reader.isDigit( s )) { + ts = s; + reader.split(value,s,value); + if ( reader.isDigit( s )) { + fs = s; + reader.split(value,s,value); + } + } + list parts; + int nbParts = reader.split( value, parts ); + if ( nbParts < 3 ) { + errorMsg << "invalid variable format:\n" << line; + RAISE_EXCEPTION; + } + // a variable contains two fields. We leave one slot in _variables empty + // in order to have last key in _variables equal to number of fields. + // Variable index equal to missing slot key corresponds to real part (Re_fn) + _Variable& var = _variables[++newVarIndex]; + var._type = key; + var._name = s; + var._timeSetNumber = ts; + var._fileSetNumber = fs; + var._fileNameOrData = value; + varNames.insert( var._name ); + READ_NEXT_LINE; + } + break; + } + case 'T': { + // -------------------------------------------------------------------------------- + // TIME + // time set: ts [description] + // number of steps: ns + // filename start number: fs + // filename increment: fi + // time values: time_1 time_2 .... time_ns + // or + // time set: ts [description] + // number of steps: ns + // filename numbers: fn + // time values: time_1 time_2 .... time_ns + // or + // time set: ts [description] + // number of steps: ns + // filename numbers file: fnfilename + // time values file: tvfilename + _TimeSet* timeSet = timeSets.empty() ? 0 : & timeSets.back(); + // --------------------------------------------------------- + if ( key == "time set" ) + { + int nb = _ATOI( value ); + if ( nb < 1 ) { + errorMsg << "Invalid time set number: " << value; + RAISE_EXCEPTION; + } + timeSets.push_back( _TimeSet() ); + timeSets.back()._number = nb; + READ_NEXT_LINE; + } + // --------------------------------------------------------- + if ( key == "number of steps" ) + { + if ( !timeSet || !timeSet->_times.empty() ) { + errorMsg << "Unexpected command: " << key; + RAISE_EXCEPTION; + } + int nbSteps = _ATOI( value ); + if ( nbSteps < 1 ) { + errorMsg << "invalid number of steps: " << value; + RAISE_EXCEPTION; + } + timeSet->_times.resize( nbSteps ); + timeSet->_fileIndex.resize( nbSteps ); + READ_NEXT_LINE; + } + // --------------------------------------------------------- + if ( key == "filename start number" ) + { + if ( !timeSet || timeSet->_fileIndex.empty() ) { + errorMsg << "Unexpected command: " << key; + RAISE_EXCEPTION; + } + if ( !reader.isDigit( value )) { + errorMsg << "invalid " << line; + RAISE_EXCEPTION; + } + timeSet->_fileIndex[0] = value; + READ_NEXT_LINE; + } + // --------------------------------------------------------- + if ( key == "filename increment" ) { + int incr = _ATOI( value ); + if ( incr == 0 ) { + errorMsg << "invalid " << line; + RAISE_EXCEPTION; + } + if ( !timeSet || + timeSet->_fileIndex.empty() || + timeSet->_fileIndex[0].empty() ) { + errorMsg << "Unexpected command: " << key; + RAISE_EXCEPTION; + } + int index = incr + _ATOI( timeSet->_fileIndex[0] ); + int nbSteps = timeSet->_fileIndex.size(); + for ( int i = 1; i < nbSteps; ++i, index += incr ) + timeSet->_fileIndex[i] = STRING( index ); + READ_NEXT_LINE; + } + // --------------------------------------------------------- + if ( key == "time values" ) + { + if ( !timeSet || timeSet->_times.empty() ) { + errorMsg << "Unexpected command: " << key; + RAISE_EXCEPTION; + } + list times; + int i, nbTimes = reader.split( value, times ); + list::iterator t = times.begin(); + for ( i = 0; i < nbTimes; ++i, ++t ) + timeSet->_times[i] = *t; + while ( nbTimes != timeSet->_times.size() ) { + value = reader.getLine(); + ++lineNb; + nbTimes += reader.split( value, times ); + for (t = times.begin(); i < nbTimes; ++i, ++t ) { + if ( ! reader.isDigit( *t, /*real=*/true )) + break; + timeSet->_times[i] = *t; + } + } + if ( nbTimes != timeSet->_times.size() ) { + errorMsg << "incorrect number of times in time set " << timeSet->_number; + RAISE_EXCEPTION; + } + for ( i = 1; i < nbTimes; ++i ) + if ( _ATOF( timeSet->_times[ i ]) <= _ATOF(timeSet->_times[ i-1 ] )) + break; + if ( i < nbTimes ) { // break from the previous loop occured + errorMsg << "time values are not in ascending order in time set " << timeSet->_number; + RAISE_EXCEPTION; + } + READ_NEXT_LINE; + } + // --------------------------------------------------------- + if ( key == "filename numbers" ) + { + if ( !timeSet || timeSet->_fileIndex.empty()) { + errorMsg << "Unexpected command: " << key; + RAISE_EXCEPTION; + } + list numbers; + int i, nb = reader.split( value, numbers ); + int nbFiles = timeSet->_fileIndex.size(); + timeSet->_fileIndex.insert(timeSet->_fileIndex.begin(), numbers.begin(), numbers.end() ); + while ( nb != nbFiles ) { + value = reader.getLine(); + ++lineNb; + i = nb; + nb += reader.split( value, numbers ); + list::iterator n = numbers.begin(); + for ( ; i < nb; ++i, ++n ) { + if ( ! reader.isDigit( *n )) + break; + timeSet->_fileIndex[i] = *n; + } + } + if ( nb != nbFiles ) { + errorMsg << "incorrect number of " << key << " in time set " << timeSet->_number; + RAISE_EXCEPTION; + } + READ_NEXT_LINE; + } + // --------------------------------------------------------- + if ( key == "filename numbers file" || + key == "time values file" ) + { + if ( !timeSet || timeSet->_fileIndex.empty()) { + errorMsg << "Unexpected command: " << key; + RAISE_EXCEPTION; + } + string fileName = _directory + FILE_SEPARATOR + value; + if ( !_user->canOpenFile( fileName, RDONLY )) { + errorMsg << "Can not open file " << fileName; + RAISE_EXCEPTION; + } + _ASCIIFileReader file( fileName ); + list numbers; + while ( !file.eof() ) + numbers.push_back( file.getWord() ); + int nb = numbers.size(); + if ( nb != timeSet->_times.size() ) { + errorMsg << "incorrect number of values in file " << value; + RAISE_EXCEPTION; + } + if ( key[0] == 'f' ) + timeSet->_fileIndex.assign( numbers.begin(), numbers.end() ); + else + timeSet->_times.assign( numbers.begin(), numbers.end() ); + READ_NEXT_LINE; + } + break; + } + case 'F': { + if ( section[1] == 'I' ) { + // -------------------------------------------------------------------------------- + // FILE + // file set: fs + // filename index: fi # Note: only used when data continues in other files + // number of steps: ns + if ( key == "file set" ) { + int nb = _ATOI( value ); + if ( nb < 1 ) { + errorMsg << "Invalid file set number: " << value; + } + else { + fileSets.push_back( _FileSet() ); + fileSets.back()._number = nb; + READ_NEXT_LINE; + } + } + else if ( key == "filename index" ) { + if ( fileSets.empty() ) { + errorMsg << "'filename index' before 'file set'"; + } + else if ( !value.empty() ) { + fileSets.back()._fileIndex.push_back( value ); + READ_NEXT_LINE; + } + } + else if ( key == "number of steps" ) { + if ( fileSets.empty() ) { + errorMsg << "'number of steps' before 'file set'"; + } + else if ( value.empty() ) { + errorMsg << "number of steps omitted: " << line; + } + else if ( !reader.isDigit( value )) { + errorMsg << "invalid number of steps: " << value; + } + else { + int n = _ATOI( value ); + if ( n < 1 ) { + errorMsg << "invalid number of steps: " << value; + RAISE_EXCEPTION; + } + fileSets.back()._nbStepsInFile.push_back( n ); + READ_NEXT_LINE; + } + } + } + else { + // -------------------------------------------------------------------------------- + // FORMAT + // type: ensight + if ( key != "type" ) { + errorMsg << "unexpected info in section " << section << ":\n" << line; + RAISE_EXCEPTION; + } + else { + if ( value == "ensight gold" ) { + _format = ENSIGHT_GOLD; + } + else if ( value == "ensight" ) { + _format = ENSIGHT_6; + } + else { + errorMsg << "Unsupported EnSight format: " << value; + RAISE_EXCEPTION; + } + section = "_"; + READ_NEXT_LINE; + } + } + break; + } + case 'G': { + // -------------------------------------------------------------------------------- + // GEOMETRY + // model: [ts] [fs] filename [change_coords_only] + // measured: [ts] [fs] filename [change_coords_only] + // match: filename + // boundary: filename + // rigid_body: filename + if ( key == "measured" || key == "match" || key == "boundary" || key == "rigid_body") { + //errorMsg << key << " geometry not supported"; + cout << "Warning: " << key << " geomerty not supported" << endl; + READ_NEXT_LINE; + } + else if ( key == "model" ) { + list parts; + reader.split( value, parts ); + list::reverse_iterator s = parts.rbegin(); + for ( ; s != parts.rend(); ++s ) + { + if ( *s == "change_coords_only" ) + _model._change_coords_only = *s; + else if ( _model._fileName.empty() ) + _model._fileName = *s; + else if ( _model._fileSetNumber.empty() ) + _model._fileSetNumber = *s; + else + _model._timeSetNumber = *s; + } + if ( _model._timeSetNumber.empty() && !_model._fileSetNumber.empty() ) + swap( _model._timeSetNumber, _model._fileSetNumber ); + if ( _model._fileName.empty() ) { + errorMsg << "invalid model: " << value; + RAISE_EXCEPTION; + } + READ_NEXT_LINE; + } + break; + } + case 'M': { // MATERIAL + string keyWord1; + reader.split(key,keyWord1,key); + if ( keyWord1 == "material" || keyWord1 == "species" ) + READ_NEXT_LINE; + break; + } + } // end switch (section[0]) + + if ( !errorMsg.empty() ) { + throw MEDEXCEPTION(STRING("Invalid Case file ") << _fileName + << ":" << lineNb << "\n" << errorMsg ); + } + + // we are here if a line was not recognized to belong to a current section + if ( line == "FORMAT" || + line == "GEOMETRY" || + line == "VARIABLE" || + line == "TIME" || + line == "FILE" || + line == "MATERIAL") + section = line; + else + throw MEDEXCEPTION(STRING() << "Invalid format of Case file " << _fileName + << "\nwrong line: " << line ); + } + + if ( _model._fileName.empty() ) + throw MEDEXCEPTION(badFile << "no supported geometry information found" ); + + // store time sets and file sets + list<_FileSet>::iterator fs = fileSets.begin(); + for ( ; fs != fileSets.end(); ++fs ) { + if ( fs->_nbStepsInFile.size() > 1 && fs->_fileIndex.empty() ) + throw MEDEXCEPTION(badFile << "missing file indices in a file set " << fs->_number ); + _fileSets[ fs->_number ] = *fs; + } + list<_TimeSet>::iterator ts = timeSets.begin(); + for ( ; ts != timeSets.end(); ++ts ) + _timeSets[ ts->_number ] = *ts; + + // check validity of ts and fs + + if ( !isValidIndex( _model._timeSetNumber, _timeSets )) + throw MEDEXCEPTION(badFile << "bad time set index:" << _model._timeSetNumber ); + if ( !isValidIndex( _model._fileSetNumber, _fileSets )) + throw MEDEXCEPTION(badFile << "bad file set index:" << _model._timeSetNumber ); + + map< int, _Variable>::iterator ivars = _variables.begin(); + for ( ; ivars != _variables.end(); ++ivars ) { + if ( !isValidIndex( ivars->second._timeSetNumber, _timeSets )) + throw MEDEXCEPTION(badFile << "bad time set index:" << ivars->second._timeSetNumber ); + if ( !isValidIndex( ivars->second._fileSetNumber, _fileSets )) + throw MEDEXCEPTION(badFile << "bad file set index:" << ivars->second._fileSetNumber ); + } + + // check uniqueness of variable names + if ( varNames.size() != _variables.size() ) + cout << badFile << + "Warning: there are different fields with equal names, you may have problems!" << endl; +// throw MEDEXCEPTION(badFile ); + + // As variable does not refer to time set if there is one step (issue 0020113), + // we try to restore the reference + + for ( ivars = _variables.begin(); ivars != _variables.end(); ++ivars ) { + _Variable & var = ivars->second; + if ( var._timeSetNumber.empty() ) + { + // try to find time set with id equal to variable order number + map< int, _TimeSet >::iterator iTs = _timeSets.find( ivars->first ); + if ( iTs != _timeSets.end() && iTs->second._times.size() == 1 ) + var._timeSetNumber = STRING( iTs->second._number ); + else { + // find any time set with 1 time value + for ( iTs = _timeSets.begin(); iTs != _timeSets.end(); ++iTs ) + if ( iTs->second._times.size() == 1 ) + var._timeSetNumber = STRING( iTs->second._number ); + } + } + } +} + +//================================================================================ +/*! + * \brief return number of time steps of a model + */ +//================================================================================ + +int _CaseFileDriver::getNbMeshes() const +{ + if ( _blocked || checkWasRead()) + return 0 ; + if ( _model._timeSetNumber.empty() ) + return 1; + int ts = _ATOI( _model._timeSetNumber ); + map< int, _TimeSet >::const_iterator its = _timeSets.find( ts ); + if ( its == _timeSets.end() ) + throw MEDEXCEPTION(STRING() << "Invalid format of Case file " << _fileName + << "\n Inexistent time set number of a model" ); + return its->second._times.size(); +} + +//================================================================================ +/*! + * \brief Sets all data necessary for meshDriver::read() + * \param meshIndex - time step index + * \param meshDriver - driver + */ +//================================================================================ + +void _CaseFileDriver::setDataFileName(const int meshIndex, + ENSIGHT_MESH_RDONLY_DRIVER* meshDriver) +{ + if ( _blocked || checkWasRead()) + return; + isToIgnore( meshDriver ); // remeber + + meshDriver->_dataFileName = _directory + FILE_SEPARATOR + _model._fileName; + meshDriver->_indexInDataFile = fixWildCardName( meshIndex, + _model._timeSetNumber, + _model._fileSetNumber, + meshDriver->_dataFileName, + meshDriver->_time); + meshDriver->_isGoldFormat = ( _format == ENSIGHT_GOLD ); + meshDriver->_transientMode = ( !_model._timeSetNumber.empty() ); + meshDriver->_singleFileMode = ( !_fileSets.empty() ); + meshDriver->_imedMapKey = STRING(_fileName)<<":"<getMesh(); + ptrMesh->setName(STRING("EnSight mesh ") << meshIndex); +} + +//================================================================================ +/*! + * \brief Return nb of ensight variables + */ +//================================================================================ + +int _CaseFileDriver::getNbVariables() const +{ + return _variables.empty() ? 0 : _variables.rbegin()->first; +} + +//================================================================================ +/*! + * \brief return number of time steps of a variable + */ +//================================================================================ + +int _CaseFileDriver::getNbVarSteps(const int variableIndex) +{ + if ( _blocked || checkWasRead() ) + return 0; + + map< int, _Variable>::const_iterator ivar = _variables.find( variableIndex ); + if ( ivar == _variables.end() ) { + // it can be index of real part of complex variable + ivar = _variables.find( variableIndex+1 ); + if ( ivar == _variables.end() || !contains( "complex", ivar->second._type.c_str() )) { + throw MEDEXCEPTION(STRING( "_CaseFileDriver::getNbVarSteps(): invalid variable index: ") + << variableIndex); + } + } + const _Variable & var = ivar->second; + if ( var._timeSetNumber.empty() ) + return 1; + + const _TimeSet & ts = _timeSets[ _ATOI( var._timeSetNumber)]; + return ts._times.size(); +} + +//================================================================================ +/*! + * \brief return variable index by variable name, return 0 if none found + */ +//================================================================================ + +int _CaseFileDriver::getVariableIndex(const string & varName) const +{ + if ( _blocked || checkWasRead() ) + return 0; + + map< int, _Variable>::const_iterator ivar = _variables.begin(); + for ( ; ivar != _variables.end(); ++ivar ) + { + if ( ivar->second._name == varName ) { + if ( contains( "complex", ivar->second._type.c_str() )) + return ivar->first - 1; // real part of complex variable + return ivar->first; + } + } + // maybe varName is "_Im" + size_t _ImBeg = varName.size() - 3; + if ( varName[ _ImBeg + 0 ] == '_' && + varName[ _ImBeg + 1 ] == 'I' && + varName[ _ImBeg + 2 ] == 'm' ) + { + int i = getVariableIndex( varName.substr( 0, _ImBeg )); + return ( i ? i + 1 : i ); // getVariableIndex() returns index for a real part + } + return 0; +} + +//================================================================================ +/*! + * \brief sets all data necessary for fieldDriver::read() + */ +//================================================================================ + +int _CaseFileDriver::setDataFileName(const int varIndex, + const int stepIndex, + ENSIGHT_FIELD_RDONLY_DRIVER* fieldDriver) +{ + const char* LOC = "_CaseFileDriver::setDataFileName(): "; + if ( _blocked || checkWasRead() ) + return 0; + isToIgnore( fieldDriver ); // remeber + + map< int, _Variable>::iterator ivar = _variables.find( varIndex ); + if ( ivar == _variables.end() ) { + // it can be index of real part of complex variable + ivar = _variables.find( varIndex+1 ); + if ( ivar == _variables.end() || !contains( "complex", ivar->second._type.c_str() )) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "invalid variable index: " << varIndex)); + } + _Variable & var = ivar->second; + + const bool isComplex = contains( "complex", var._type.c_str() ); + const bool isImaginary = ( isComplex && varIndex == ivar->first ); + + // complex scalar per element: [ts] [fs] description Re_fn Im_fn freq + // complex scalar per node: [ts] [fs] description Re_fn Im_fn freq + // complex vector per element: [ts] [fs] description Re_fn Im_fn freq + // complex vector per node: [ts] [fs] description Re_fn Im_fn freq + // constant per case file: [ts] description cvfilename + // constant per case: [ts] description const_value(s) + // scalar per element: [ts] [fs] description filename + // scalar per measured node: [ts] [fs] description filename + // scalar per node: [ts] [fs] description filename + // tensor asym per element: [ts] [fs] description filename + // tensor asym per node: [ts] [fs] description filename + // tensor symm per element: [ts] [fs] description filename + // tensor symm per node: [ts] [fs] description filename + // vector per element: [ts] [fs] description filename + // vector per measured node: [ts] [fs] description filename + // vector per node: [ts] [fs] description filename + + FIELD_* field = fieldDriver->getField(); + + // field name + if ( field->getName().empty() ) { + if ( isImaginary ) + field->setName( var._name + "_Im" ); + else + field->setName( var._name ); + } + // nb of components + list type_parts; + _ASCIIFileReader::split( var._type, type_parts ); + string type1 = type_parts.front(); type_parts.pop_front(); + string type2 = type_parts.front(); type_parts.pop_front(); + int nbComponents = 1; + if ( type1 == "vector" || type2 == "vector" ) + nbComponents = 3; + else if ( type1 == "tensor" ) + nbComponents = ( type2 == "symm" ) ? 6 : 9; + field->setNumberOfComponents( nbComponents ); + + // component names + vector compNames( nbComponents ); + switch ( nbComponents ) { + case 1: + compNames[0] = type1; + break; + case 3: { + const char* xyz[3] = { "X comp","Y comp","Z comp" }; + compNames.assign(xyz, xyz+3); + break; + } + case 6: { + const char* xyz[6] = { "11 comp", "22 comp", "33 comp","12 comp", "13 comp", "23 comp" }; + compNames.assign(xyz, xyz+6); + break; + } + case 9: { + const char* xyz[9] = { "11 comp", "12 comp", "13 comp", "21 comp", "22 comp", "23 comp", + "31 comp", "32 comp", "33 comp" }; + compNames.assign(xyz, xyz+9); + break; + }} + field->setComponentsNames( & compNames[0] ); + + // componet units + vector units( nbComponents ); + vector unitS( nbComponents ), descriptions( nbComponents ); + field->setComponentsUnits(&units[0]); + field->setMEDComponentsUnits(&unitS[0]); + field->setComponentsDescriptions(&descriptions[0]); + + // support type + SUPPORT* sup = const_cast( field->getSupport()); + if ( !sup ) + field->setSupport( sup = new SUPPORT ); + medEntityMesh entity = ( type_parts.back() == "node" ) ? MED_NODE : MED_CELL; + sup->setEntity( entity ); + + // data file name etc. + list fileData_parts; + _ASCIIFileReader::split( var._fileNameOrData, fileData_parts ); + if ( isImaginary ) + fieldDriver->_dataFileName = _directory + FILE_SEPARATOR + *(++fileData_parts.begin()); + else + fieldDriver->_dataFileName = _directory + FILE_SEPARATOR + fileData_parts.front(); + fieldDriver->_indexInDataFile = fixWildCardName( stepIndex, + var._timeSetNumber, + var._fileSetNumber, + fieldDriver->_dataFileName, + fieldDriver->_time); + fieldDriver->_isGoldFormat = ( _format == ENSIGHT_GOLD ); + fieldDriver->_transientMode = ( !var._timeSetNumber.empty() ); + fieldDriver->_singleFileMode = ( !_fileSets.empty() ); + + if ( type1 == "constant" ) { + if ( type_parts.back() == "file" ) { + // append constant values from cvfilename to fileData_parts + string cvfilename = _directory + FILE_SEPARATOR + fileData_parts.back(); + _ASCIIFileReader cvfile( cvfilename ); + fileData_parts.pop_back(); + while ( !cvfile.eof() ) + fileData_parts.push_back( cvfile.getWord() ); + } + if ( fileData_parts.size() < stepIndex ) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "can't find value for step " << stepIndex + << " of " << var._type << " " << var._name)); + list::iterator value = fileData_parts.begin(); + advance( value, stepIndex-1 ); + fieldDriver->setConstantValue( *value ); + } + + // mesh data + int meshIndex = 1; + if ( _model._fileName.find('*') != _model._fileName.npos ) { + _TimeSet& ts = _timeSets[ _ATOI( _model._timeSetNumber )]; + vector::iterator t = find( ts._times.begin(), ts._times.end(), fieldDriver->_time ); + if ( t != ts._times.end() ) + meshIndex += distance( ts._times.begin(), t ); + } + fieldDriver->_imedMapKey = STRING(_fileName) << ":" << meshIndex; + + // time + if ( fieldDriver->_transientMode ) { + field->setTime( _ATOF( fieldDriver->_time )); + //field->setOrderNumber( stepIndex ); + field->setIterationNumber( stepIndex ); + } + return meshIndex; +} + +//================================================================================ +/*! + * \brief Throws if case file has not been read else return false + */ +//================================================================================ + +bool _CaseFileDriver::checkWasRead() const throw (MEDEXCEPTION) +{ + if ( _model._fileName.empty() ) + throw MEDEXCEPTION(STRING("Case file ") << _fileName << " has not been successfully read"); + return false; +} + +//================================================================================ +/*! + * \brief replace '*' in file name if any and return index in file + */ +//================================================================================ + +int _CaseFileDriver::fixWildCardName(const int timeStep, + const string & ts, + const string & fs, + string & fileName, + string & time) +{ + int indexInFile = 0; + string fileIndex; + + STRING badFile("Invalid Case file "); + badFile << _fileName << "\n"; + + if ( !fs.empty() ) { // single file mode + const _FileSet & fileSet = _fileSets[ _ATOI( fs ) ]; + if ( fileSet._fileIndex.empty() ) { // no file continuation + indexInFile = timeStep; + } + else { + list::const_iterator nbStepsIt = fileSet._nbStepsInFile.begin(); + list::const_iterator fIndexIt = fileSet._fileIndex.begin(); + int nbSteps = 0; + for ( ; nbStepsIt != fileSet._nbStepsInFile.end(); ++nbStepsIt ) { + if ( nbSteps + *nbStepsIt <= timeStep ) + break; + nbSteps += *nbStepsIt; + } + if ( nbStepsIt == fileSet._nbStepsInFile.end() ) + throw MEDEXCEPTION(LOCALIZED(badFile << "Cant'f find file index for time step " << + timeStep << " in file set " << fs )); + indexInFile = timeStep - nbSteps; + fileIndex = *fIndexIt; + } + } + + string head, queue; + _ASCIIFileReader::split( fileName, head, queue, '*' ); + int indexWidth = fileName.size() - head.size() - queue.size(); + + if ( indexWidth > 0 || !ts.empty() ) { + int tsId = ts.empty() ? 1 : _ATOI( ts ); + const _TimeSet& timeSet = _timeSets[ tsId ]; + if ( timeStep > timeSet._times.size() ) + throw MEDEXCEPTION(LOCALIZED(badFile << "Cant'f find time for time step " << + timeStep << " in time set " << ts )); + time = timeSet._times[ timeStep-1 ]; + if ( timeStep-1 < timeSet._fileIndex.size() ) + fileIndex = timeSet._fileIndex[ timeStep-1 ]; + if ( !indexInFile ) + indexInFile = 1; + } + + if ( indexWidth > 0 ) + { + if ( fileIndex.empty() ) { + throw MEDEXCEPTION(LOCALIZED(badFile << "Can't find file index for time step " << + timeStep << " in time set <" << ts << + "> and file set <" << fs << ">")); + } + if ( indexWidth == fileIndex.size() ) { + fileName = head + fileIndex + queue; + } + else { + fileName = (STRING(head) << setw(indexWidth) << setfill('0') << fileIndex << queue); + } + } + return indexInFile; +} + +//================================================================================ +/*! + * \brief add a mesh to the Case file + */ +//================================================================================ + +void _CaseFileDriver::addMesh(const ENSIGHT_MESH_WRONLY_DRIVER* meshDriver) +{ + if ( _blocked ) + return; + + _meshDrivers.push_back( const_cast( meshDriver )); + + if ( _format == ENSIGHT_6 ) + { + const MESH* mesh = _meshDrivers.back()->getMesh(); + if ( mesh->getNumberOfPolygons() > 0 || mesh->getNumberOfPolyhedron() > 0 ) + throw MEDEXCEPTION + ( compatibilityPb(STRING("Can't write mesh <") << mesh->getName() << + "> since Ensight6 format does not support poly elements," + " use Ensight Gold format instead: call " + "setEnSightFormatForWriting( ENSIGHT_GOLD )")); + } + + isToIgnore( meshDriver ); // remeber +} + +//================================================================================ +/*! + * \brief add a field to the Case file + */ +//================================================================================ + +void _CaseFileDriver::addField(const ENSIGHT_FIELD_WRONLY_DRIVER * theFieldDriver) +{ + if ( _blocked ) + return; + + ENSIGHT_FIELD_WRONLY_DRIVER * fieldDriver = + const_cast( theFieldDriver ); + + FIELD_* field = fieldDriver->getField(); + + STRING problem; + if ( field->getNumberOfValues() == 0 ) + problem << "getNumberOfValues() == 0"; + else if ( field->getGaussPresence() ) + problem << compatibilityPb("Gauss points are not supported by EnSight v8"); + else if ( !field->getSupport() ) + problem << "it has NULL support"; + + switch ( field->getNumberOfComponents() ) { + case 1: + case 3: + case 6: + case 9: break; // ok, supported + case 2: + if ( MESH* mesh = field->getSupport()->getMesh() ) + if ( mesh->getSpaceDimension() == 2 ) + break; // we add one component to both mesh and field + default: + problem << + compatibilityPb(STRING("it has ") << field->getNumberOfComponents() + << " components but only 1,3,6 and 9 components are supported by EnSight"); + } + if ( !problem.empty() ) + throw MEDEXCEPTION(STRING("Can't write field <") << field->getName() << + "> to EnSight: " << problem); + + string fieldName = fieldDriver->getFieldName(); + if ( fieldName.empty() ) + fieldName = field->getName(); + if ( fieldName.empty() ) + fieldName = STRING("med_field_")<<_fieldDrivers.size(); + else { // replace illegal characters + string::size_type pos = fieldName.find_first_of( ILLEGAL_FIELD_NAME_CHARACTERS ); + while ( pos != fieldName.npos ) { + fieldName[ pos ] = '_'; + pos = fieldName.find_first_of( ILLEGAL_FIELD_NAME_CHARACTERS ); + } + } + + _fieldDrivers[ fieldName ].push_back( fieldDriver ); + + isToIgnore( fieldDriver ); // remeber +} + +//================================================================================ +/*! + * \brief writing Case file + */ +//================================================================================ + +void _CaseFileDriver::write() throw (MEDEXCEPTION) +{ + if ( _blocked ) + return; + + // Make case file data from added drivers + + bool dataIsRead = !_model._fileName.empty(); + if ( !dataIsRead && _meshDrivers.empty() ) + throw MEDEXCEPTION("no mesh to write into Case file"); + + const int defaultNbDigits = 3; // in file index + + string path, name, ext; + _ASCIIFileReader::split( _fileName, path, name, FILE_SEPARATOR, /*fromBack=*/true); + _ASCIIFileReader::split( name, name, ext, '.', /*fromBack=*/true); + if ( name.empty()) + name = ext; // _fileName: "path/.name" + + list::iterator mDrv = _meshDrivers.begin(); + TFieldDriversByName::iterator fDrv = _fieldDrivers.begin(); + + map< string, string > fileToRenameTo; + + int i, nbOldMeshes = 0, nbNewMeshes = _meshDrivers.size(); + + if ( nbNewMeshes > 0 ) + { + if ( dataIsRead ) + { + // A mesh is going to be added into an existing case file. + // Check that number of parts is same in the existing model + // and in the added ones + string geoFileName = _directory + FILE_SEPARATOR + _model._fileName; + string realGeoFileName = geoFileName, time; + fixWildCardName( 1, + _model._timeSetNumber, + _model._fileSetNumber, + realGeoFileName, + time); + int nbParts = ENSIGHT_MESH_RDONLY_DRIVER::countParts(realGeoFileName, + !_model._fileSetNumber.empty()); + for ( ; mDrv != _meshDrivers.end(); ++mDrv ) + { + int nbNewParts = (*mDrv)->nbPartsToWrite(); + if ( nbParts != nbNewParts ) + throw MEDEXCEPTION(compatibilityPb("Can't add a mesh ") << (*mDrv)->getMesh()->getName() + << "to " << _fileName << " as number of parts in the file " + "differs from number of parts going to be written"); + } + if ( !_model._timeSetNumber.empty() && !_variables.empty() ) { + // Make time set of the model independent of that of variables as + // the number of time steps is apparently becoming different + map< int, _Variable>::iterator ivar = _variables.begin(); + for ( ; ivar != _variables.end(); ++ivar ) { + if ( ivar->second._timeSetNumber == _model._timeSetNumber ) { + int tsNum = _timeSets.rbegin()->first + 1; + _TimeSet& ts = _timeSets[ tsNum ]; + ts._number = tsNum; + ts = _timeSets[ _ATOI( _model._timeSetNumber )]; + _model._timeSetNumber = STRING(tsNum); + break; + } + } + } + int digitPos = (int) _model._fileName.find('*'); + bool isSeveralFiles = ( digitPos != _model._fileName.npos ); + int nbDigits = defaultNbDigits; + if ( isSeveralFiles ) { + nbDigits = 1; + while ( _model._fileName[ ++digitPos ] == '*' ) + nbDigits++; + } + // Update time set and file set of the model + int nbMeshes; + if ( _model._timeSetNumber.empty() ) { + // old model is static, create a time set + nbMeshes = nbNewMeshes + 1; + int tsNum = _timeSets.empty() ? 1 : _timeSets.rbegin()->first + 1; + _TimeSet& ts = _timeSets[ tsNum ]; + ts._number = tsNum; + _model._timeSetNumber = STRING(tsNum); + // fill the new time set + ts._fileIndex.resize( nbMeshes ); + ts._times.resize ( nbMeshes ); + for ( i = 0; i < nbMeshes; ++i ) { + ts._fileIndex[ i ] = (STRING() << setw(nbDigits) << setfill('0') << i); + ts._times [ i ] = STRING(i); + } + // not to create equal time sets + map< int, _TimeSet >::iterator its, tsEnd = _timeSets.end(); + for ( --tsEnd, its = _timeSets.begin(); its != tsEnd; ++its ) { + if ( ts == its->second ) { + _model._timeSetNumber = STRING( its->first ); + _timeSets.erase( tsEnd ); + break; + } + } + } + else { + // old model is transient, add times and file indices for new meshes + _TimeSet& ts = _timeSets[ _ATOI( _model._timeSetNumber )]; + nbOldMeshes = ts._times.size(); + nbMeshes = nbNewMeshes + nbOldMeshes; + ts._times.resize( nbMeshes ); + double time = 1. + _ATOF( ts._times[ nbOldMeshes-1 ] ); + for ( i = nbOldMeshes; i < nbMeshes; ++i, time+=1. ) + ts._times[ i ] = STRING( time ); + if ( _model._fileSetNumber.empty() ) { // multi-file mode + ts._fileIndex.resize( nbMeshes, string(nbDigits,'0')); + i = nbOldMeshes; + int index = 1 + _ATOI( ts._fileIndex[ i-1 ] ); + for ( ; i < nbMeshes; ++i, ++index ) + ts._fileIndex[ i ] = (STRING() << setw(nbDigits) << setfill('0') << index); + } + else { // single-file mode + _FileSet & fs = _fileSets[ _ATOI( _model._fileSetNumber )]; + for ( i = 0; i < nbNewMeshes; ++i ) + fs._nbStepsInFile.push_back( 1 ); + int index = 1; + if ( fs._fileIndex.empty() ) + fs._fileIndex.push_back(string(nbDigits,'0')); + else + index += _ATOI( fs._fileIndex.back() ); + for ( i = fs._fileIndex.size(); i < nbMeshes; ++i, ++index ) + ts._fileIndex[ i ] = (STRING() << setw(3) << setfill('0') << index); + } + } + // file of the old model is to be renamed + if ( !isSeveralFiles ) { + _model._fileName += string(nbDigits,'*'); + fileToRenameTo[ geoFileName ] = geoFileName + string(nbDigits,'0'); + } + } + else if ( nbNewMeshes > 1 ) + { + // Store meshes into a new case file: create a time set + int tsNum = _timeSets.empty() ? 1 : _timeSets.rbegin()->first + 1; + _TimeSet& ts = _timeSets[ tsNum ]; + ts._number = tsNum; + _model._timeSetNumber = STRING(tsNum); + _model._fileName = name + ".geo" + string(defaultNbDigits, '*'); + // fill the new time set + ts._fileIndex.resize( nbNewMeshes ); + ts._times.resize ( nbNewMeshes ); + for ( i = 0; i < nbNewMeshes; ++i ) { + ts._fileIndex[ i ] = (STRING() << setw(defaultNbDigits) << setfill('0') << i); + ts._times [ i ] = STRING(i); + } + } + else { + // One mesh in a new file + _model._fileName = name + ".geo"; + } + + // Set data to mesh drivers + i = nbOldMeshes + 1; + for ( mDrv = _meshDrivers.begin(); mDrv != _meshDrivers.end(); ++mDrv, ++i ) + { + _CaseFileDriver_User* meshDriver = (*mDrv); + meshDriver->_dataFileName = _directory + FILE_SEPARATOR + _model._fileName; + meshDriver->_indexInDataFile = fixWildCardName( i, + _model._timeSetNumber, + _model._fileSetNumber, + meshDriver->_dataFileName, + meshDriver->_time); + meshDriver->_isGoldFormat = ( _format == ENSIGHT_GOLD ); + meshDriver->_transientMode = ( meshDriver->_indexInDataFile > 0 ); + meshDriver->_singleFileMode = ( !_fileSets.empty() ); + meshDriver->_imedMapKey = STRING(_fileName)<<":"< FDriverByDouble; + + //bool isVarsRead = ( !_variables.empty() ); + for ( ; fDrv != _fieldDrivers.end(); ++fDrv ) + { + const string & fieldName = fDrv->first; + list< ENSIGHT_FIELD_WRONLY_DRIVER* > & drivers = fDrv->second; + + int nbNewSteps = drivers.size(); + + // find out by which parameter fields differ and sort them by the parameter + FDriverByDouble timeMap, iterMap, orderMap; + list< ENSIGHT_FIELD_WRONLY_DRIVER* >::iterator drv; + for ( drv = drivers.begin(); drv != drivers.end(); ++drv ) { + FIELD_* field = (*drv)->getField(); + double time = field->getTime(); + int iter = field->getIterationNumber(); + int ordr = field->getOrderNumber(); + timeMap.insert ( make_pair( time, *drv )); + iterMap.insert ( make_pair( iter, *drv )); + orderMap.insert ( make_pair( ordr, *drv )); + } + FDriverByDouble * sortedDrivers; + FDriverByDouble::iterator tDrv; + if ( timeMap.size() == nbNewSteps ) + sortedDrivers = & timeMap; + else if ( iterMap.size() == nbNewSteps ) + sortedDrivers = & iterMap; + else if ( orderMap.size() == nbNewSteps ) + sortedDrivers = & orderMap; + else { + timeMap.clear(); + sortedDrivers = & timeMap; + for ( drv = drivers.begin(); drv != drivers.end(); ++drv ) { + double time = (*drv)->getField()->getTime(); + if ( ! timeMap.insert( make_pair( time, *drv )).second ) + timeMap.insert( make_pair( timeMap.rbegin()->first + 1., *drv )); + } + } + +// if ( isVarsRead ) { +// int iVar = getVariableIndex( fieldName ); +// if ( iVar > 0 ) { +// // A variable with fieldName already exists, +// // add more time steps to it +// _Variable& var = _variables[ iVar ]; +// _TimeSet& ts = _timeSets[ _ATOI( var._timeSetNumber )]; +// int nbOldSteps = ts._times.size(); +// } +// } + FIELD_* field = drivers.front()->getField(); + int varNum = _variables.size() + 1; + _Variable& var = _variables[ varNum ]; + var._name = fieldName; + switch ( field->getNumberOfComponents() ) { + case 1: var._type = "scalar "; break; + case 2: var._type = "vector "; break;// we add one component to a vector in 2d space + case 3: var._type = "vector "; break; + case 6: var._type = "tensor symm "; break; + case 9: var._type = "tensor asym "; break; + } + if ( field->getSupport()->getEntity() == MED_NODE ) + var._type += "per node"; + else + var._type += "per element"; + var._fileNameOrData = name + "." + fieldName; + + // always create Time set to store time + int nbDigits = defaultNbDigits; + int tsNum = _timeSets.empty() ? 1 : _timeSets.rbegin()->first + 1; + var._timeSetNumber = STRING( tsNum ); + _TimeSet & ts = _timeSets[ tsNum ]; + ts._number = tsNum; + ts._fileIndex.resize( nbNewSteps ); + ts._times.resize ( nbNewSteps ); + tDrv = sortedDrivers->begin(); + for ( i = 0; tDrv != sortedDrivers->end(); ++tDrv, ++i ) { + ts._times [ i ] = (STRING( tDrv->first )); + ts._fileIndex[ i ] = (STRING() << setw(nbDigits) << setfill('0') << i); + } + if ( nbNewSteps > 1 ) + var._fileNameOrData += string( nbDigits, '*' ); + else + ts._fileIndex.clear(); + // not to create equal time sets + map< int, _TimeSet >::iterator its, tsEnd = _timeSets.end(); + for ( --tsEnd, its = _timeSets.begin(); its != tsEnd; ++its ) { + if ( ts == its->second ) { + tsNum = its->first; + var._timeSetNumber = STRING( tsNum ); + _timeSets.erase( tsEnd ); + break; + } + } + tDrv = sortedDrivers->begin(); + for ( i = 1; tDrv != sortedDrivers->end(); ++tDrv, ++i ) { + _CaseFileDriver_User* fieldDriver = tDrv->second; + fieldDriver->_dataFileName = _directory + FILE_SEPARATOR + var._fileNameOrData; + fieldDriver->_indexInDataFile = fixWildCardName( i, + var._timeSetNumber, + var._fileSetNumber, + fieldDriver->_dataFileName, + fieldDriver->_time); + fieldDriver->_isGoldFormat = ( _format == ENSIGHT_GOLD ); + fieldDriver->_transientMode = ( fieldDriver->_indexInDataFile > 0 ); + fieldDriver->_singleFileMode = ( !_fileSets.empty() ); + } + + // do not refer to time set if there is one step (issue 0020113) + if ( nbNewSteps == 1 ) + var._timeSetNumber = ""; + + } // loop on _fieldDrivers + + if ( nbOldMeshes + nbNewMeshes > 1 && !_variables.empty() ) + { + // if there are variables on a transient model, model should not change much, + // nb of entities in all parts with values must be same + if ( nbOldMeshes == 0 ) { + // TODO: check consistency + } + if ( toIgnoreIncompatibility() ) + cout << "Warning: EnSight file will be probably invalid " << _fileName << endl; + else + throw MEDEXCEPTION + (compatibilityPb(STRING("EnSight file will be invalid if fields refer to " + "the second mesh, which differ from the first one too much.\n" + "If you are sure in data correctness, you can suppress " + "this exception by calling setIgnoreIncompatibility(1)\n") + << _fileName)); + } + + // Write a file + + ofstream caseFile( _fileName.c_str(), ios::out ); + if ( !caseFile ) + throw MEDEXCEPTION(STRING("Can't open file for writing ") << _fileName); + + caseFile << "# generated by MEDMEM-to-EnSight driver" << endl << endl + << "FORMAT" << endl + << "type: " << (_format==ENSIGHT_GOLD ? "ensight gold" : "ensight") << endl + << endl + << "GEOMETRY" + << endl + << "model:\t" + << _model._timeSetNumber << " " + << _model._fileSetNumber << " " + << _model._fileName << " \t" + << _model._change_coords_only + << endl << endl; + + // write VARIABLE section + if ( !_variables.empty() ) + { + caseFile << "VARIABLE" << endl; + + map< int, _Variable>::iterator ivar = _variables.begin(); + for ( ; ivar != _variables.end(); ++ivar ) + { + _Variable& var = ivar->second; + caseFile << var._type << ": \t" + << var._timeSetNumber << " " + << var._fileSetNumber << " \t" + << var._name << " \t" + << var._fileNameOrData << endl; + } + caseFile << endl; + } + // write TIME section + if ( !_timeSets.empty() ) + { + caseFile << "TIME" << endl; + + map< int, _TimeSet>::iterator its = _timeSets.begin(); + for ( ; its != _timeSets.end(); ++its ) + { + _TimeSet & ts = its->second; + caseFile << "time set:\t" << ts._number << endl + << "number of steps:\t" << ts._times.size() << endl; + if ( !ts._fileIndex.empty() ) { + STRING numbers( "filename numbers:" ); + for ( int i = 0; i < ts._fileIndex.size(); ++i ) { + if ( numbers.size() + ts._fileIndex[i].size() + 2 > MAX_LINE_LENGTH ) { + caseFile << numbers << endl; + numbers = STRING(); + } + numbers << " " << ts._fileIndex[i]; + } + caseFile << numbers << endl; + } + STRING times( "time values:" ); + for ( int i = 0; i < ts._times.size(); ++i ) { + if ( times.size() + ts._times[i].size() + 2 > MAX_LINE_LENGTH ) { + caseFile << times << endl; + times = STRING(); + } + times << " " << ts._times[i]; + } + caseFile << times << endl; + } + } + // write FILE section + if ( !_fileSets.empty() ) + { + caseFile << "FILE" << endl; + + map< int, _FileSet >::iterator ifs = _fileSets.begin(); + for ( ; ifs != _fileSets.end(); ++ifs ) + { + _FileSet & fs = ifs->second; + caseFile << "file set: " << fs._number << endl; + + list::iterator nbSteps = fs._nbStepsInFile.begin(); + list::iterator fileIndex = fs._fileIndex.begin(); + for ( ; nbSteps != fs._nbStepsInFile.end(); ++nbSteps ) + { + if ( fileIndex != fs._fileIndex.end() ) + caseFile << "filename index: " << *fileIndex++; + caseFile << "number of steps: " << *nbSteps << endl; + } + } + } + + caseFile.close(); + +} // _CaseFileDriver::write() + + +//================================================================================ +/*! + * \brief _CaseFileDriver_User constructor + */ +//================================================================================ + +_CaseFileDriver_User::_CaseFileDriver_User(const string & caseFileName, + med_mode_acces mode) + : GENDRIVER( caseFileName, mode, ENSIGHT_DRIVER ), _imed(0) +{ +} + +//================================================================================ +/*! + * \brief analyse if data file is binary + */ +//================================================================================ + +bool _CaseFileDriver_User::isBinaryDataFile(const string& dataFileName) +{ +#ifdef WNT + int _file = ::_open (dataFileName.c_str(), _O_RDONLY|_O_BINARY); +#else + int _file = ::open (dataFileName.c_str(), O_RDONLY); +#endif + char buf[81]; + int nBytesRead = ::read (_file, buf, 80); + + bool isBinary = true; + + const char cBin[] = "C Binary"; + const char fBin[] = "Fortran Binary"; + if ( strncmp( buf, cBin, sizeof(cBin)-1) != 0 && + strncmp( buf, fBin, sizeof(fBin)-1) != 0 ) + { + for ( int i = nBytesRead-1; i >= 0 && isBinary; --i ) + isBinary = ( buf[ i ] != '\n' ); + } + + ::close (_file); + + return isBinary; +} + +//================================================================================ +/*! + * \brief return part number to write support with, zero in failure case + */ +//================================================================================ + +int _CaseFileDriver_User::getPartNumber(const SUPPORT* support) const +{ + bool isGroup = ( dynamic_cast( support )); + bool isForField = ( dynamic_cast( this )); + medEntityMesh entity = support->getEntity(); + const MESH* mesh = support->getMesh(); + + // for supports on all entities, reserve numbers corresponding to entity + bool isOnAll = support->isOnAllElements(); + if (!isOnAll && mesh ) { + int nbMeshElem = mesh->getNumberOfElements(entity, MED_ALL_ELEMENTS); + int nbSuppElem = support->getNumberOfElements(MED_ALL_ELEMENTS); + isOnAll = ( nbSuppElem == nbMeshElem ); + } + if ( !isGroup ) { + if ( !isOnAll ) + return 0; + else if ( entity == MED_NODE ) + return 1 + MED_CELL; // all nodes are described with all CELLs + else + return 1 + entity; + } + if ( isForField && isOnAll ) { + if ( entity == MED_NODE ) + return 1 + MED_CELL; // all nodes are described with all CELLs + else + return 1 + entity; + } + if ( !mesh ) + return 0; + + int partNum = MED_ALL_ENTITIES + 1; + for ( int ent = MED_CELL; ent < MED_ALL_ENTITIES; ++ent ) { + entity = (medEntityMesh) ent; + int nbGroups = mesh->getNumberOfGroups(entity); + if ( entity != support->getEntity() ) { + partNum += nbGroups; + } + else { + for ( int i=1; i<=nbGroups; ++i, ++partNum) + if ( support == mesh->getGroup( entity, i )) + return partNum; + } + } + throw MED_EXCEPTION + ( LOCALIZED( STRING("Can't find GROUP ") << support->getName() << " in its MESH")); + + return 0; +} + +//================================================================================ +/*! + * \brief Return true if we strore an enetuty to EnSight + */ +//================================================================================ + +bool _CaseFileDriver_User::isToWriteEntity(const medEntityMesh entity, + const MESH* mesh) +{ + if ( entity == MED_NODE ) + return mesh->getNumberOfNodes() > 0; + + if ( mesh->getNumberOfTypesWithPoly( entity ) < 1 ) + return false; + if ( entity == MED_CELL ) + return true; + int meshDim = mesh->getTypes(MED_CELL)[0] / 100; + if ( entity == MED_FACE ) + return ( meshDim == 3 || meshDim == 5 ); + if ( entity == MED_EDGE ) + return ( meshDim == 2 || meshDim == 4 ); + + return false; +} + +//================================================================================ +/*! + * \brief Return nodes of non-nodal support, which is not on all entities + */ +//================================================================================ + +void _CaseFileDriver_User::getSupportNodes(const SUPPORT* support, map & nodeIds) +{ + MESH* mesh = support->getMesh(); + medEntityMesh entity = support->getEntity(); + + const medModeSwitch conMode = MED_FULL_INTERLACE; + const medConnectivity conType = MED_NODAL; + const medGeometryElement allGeoms = MED_ALL_ELEMENTS; + const int * connectivity = 0; + const int * elemConnectivity = 0; + const int * index = 0; + const int * number = 0; + int j; + + if ( support->isOnAllElements() ) + { + if ( entity == MED_NODE ) { // all NODES + int numberOfCell = support->getNumberOfElements(allGeoms); + while ( numberOfCell ) { + nodeIds.insert( nodeIds.begin(), make_pair( numberOfCell, numberOfCell )); + --numberOfCell; + } + } + else { + int nbTypes = support->getNumberOfTypes(); + const medGeometryElement* geoType = support->getTypes(); + const medGeometryElement* geoTypeEnd = geoType + nbTypes; + int hasPolygons = ( find( geoType, geoTypeEnd, MED_POLYGON ) != geoTypeEnd ); + int hasPolyhedra = ( find( geoType, geoTypeEnd, MED_POLYHEDRA ) != geoTypeEnd ); + int hasStdTypes = ( nbTypes - hasPolygons - hasPolyhedra > 0 ); + int conLength = 0; + if ( hasStdTypes ) { + connectivity = mesh->getConnectivity (conMode, conType, entity, allGeoms); + conLength = mesh->getConnectivityLength(conMode, conType, entity, allGeoms); + while ( conLength-- ) nodeIds[ *connectivity++ ]; + } + if ( hasPolygons ) { + connectivity = mesh->getPolygonsConnectivity (conType, entity); + conLength = mesh->getPolygonsConnectivityLength(conType, entity); + while ( conLength-- ) nodeIds[ *connectivity++ ]; + } + if ( hasPolyhedra ) { + connectivity = mesh->getPolyhedronConnectivity (conType); + conLength = mesh->getPolyhedronConnectivityLength(conType); + while ( conLength-- ) nodeIds[ *connectivity++ ]; + } + } + return; + } + + if ( entity == MED_NODE ) + { + number = support->getNumber(MED_ALL_ELEMENTS); + int numberOfCell = support->getNumberOfElements(MED_ALL_ELEMENTS); + for (j=0; j < numberOfCell; j++) + nodeIds.insert(nodeIds.end(), make_pair( number[j], j )); + return; + } + + // loop on types + int nbTypes = support->getNumberOfTypes(); + const medGeometryElement* geoType = support->getTypes(); + for (int i=0; igetNumber(medType); + int numberOfCell = support->getNumberOfElements(medType); + + if ( medType < MED_POLYGON ) // STANDARD ELEMENTS + { + index = mesh->getConnectivityIndex(MED_FULL_INTERLACE, entity); + connectivity = mesh->getConnectivity(MED_FULL_INTERLACE, MED_NODAL, + entity, MED_ALL_ELEMENTS); + for ( j = 0; j < numberOfCell; ++j ) { + int elem = number[j]; + elemConnectivity = connectivity + index[elem-1]-1; + const int* connEnd = connectivity + index[elem]-1; + while ( elemConnectivity < connEnd ) + nodeIds[ *elemConnectivity++ ]; + } + } + else if ( medType == MED_POLYGON ) // POLYGONs connectivity + { + connectivity = mesh->getPolygonsConnectivity(MED_NODAL, entity); + index = mesh->getPolygonsConnectivityIndex(MED_NODAL, entity); + int nbStdElems = mesh->getNumberOfElements(entity,MED_ALL_ELEMENTS); + for ( j = 0; j < numberOfCell; ++j ) { + int elem = number[ j ] - nbStdElems; + elemConnectivity = connectivity + index[elem-1]-1; + const int* connEnd = connectivity + index[elem]-1; + while ( elemConnectivity < connEnd ) + nodeIds[ *elemConnectivity++ ]; + } + } + else // POLYHEDRA connectivity + { + connectivity = mesh->getPolyhedronConnectivity(MED_NODAL); + index = mesh->getPolyhedronIndex(MED_NODAL); + const int * fIndex = mesh->getPolyhedronFacesIndex(); + int nbStdElems = mesh->getNumberOfElements(entity,MED_ALL_ELEMENTS); + for ( j = 0; j < numberOfCell; ++j ) { + int elem = number[ j ] - nbStdElems; + int f1 = index[ elem-1 ] - 1, f2 = index[ elem ] - 1; + elemConnectivity = connectivity + fIndex[ f1 ] - 1; + const int* connEnd = connectivity + fIndex[ f2 ] - 1; + while ( elemConnectivity < connEnd ) + nodeIds[ *elemConnectivity++ ]; + } + } + } +} + +//================================================================================ +/*! + * \brief method called by mesh driver at reading to store data to be used by + * field driver + */ +//================================================================================ + +void _CaseFileDriver_User::setInterData(_InterMed* imed ) +{ + theInterMedMap[ _imedMapKey ] = imed; + if ( ENSIGHT_MESH_DRIVER* mDrv = dynamic_cast( this )) { + imed->_medMesh = mDrv->getMesh(); + imed->_isOwnMedMesh = false; + } + else + imed->_medMesh = 0; +} + +//================================================================================ +/*! + * \brief for field driver to get mesh data + */ +//================================================================================ + +_InterMed* _CaseFileDriver_User::getInterData() +{ + return _imed = getMeshData( _imedMapKey ); +} + +//================================================================================ +/*! + * \brief return _SubPart by its description + */ +//================================================================================ + +_SubPart* _CaseFileDriver_User::getSubPart(const _SubPartDesc & descriptor) + throw (MEDEXCEPTION) +{ + if ( !_imed ) + _imed = getMeshData( _imedMapKey ); + + map< _SubPartDesc, _SubPart >::iterator descPart = + _imed->_subPartDescribed.find( descriptor ); + + if ( descPart != _imed->_subPartDescribed.end() ) + return & descPart->second; + + if ( descriptor == _SubPartDesc::globalCoordDesc() ) + return 0; // if the mesh is structured, there are no global coordinates (EnSight 6) + + throw MEDEXCEPTION(LOCALIZED(STRING("No mesh info for part ") << descriptor.partNumber() + << " " << descriptor.typeName())); +} + +//================================================================================ +/*! + * \brief return _Support by its description + */ +//================================================================================ + +_Support* _CaseFileDriver_User::getSupport(const _SupportDesc & descriptor, + const medEntityMesh entity) + throw (MEDEXCEPTION) +{ + const char* LOC = "_CaseFileDriver_User::getSupport(): "; + if ( !_imed ) + _imed = getMeshData( _imedMapKey ); + + _imed->treatGroupes(); + + if ( _imed->_supportDescribed.empty() && !_imed->_subPartDescribed.empty() ) + { + // fill _supportDescribed with _Support's corresponding to EnSight parts + for (unsigned int i=0; i < _imed->groupes.size(); ++i) + { + _groupe& grp = _imed->groupes[i]; + if ( !grp.medGroup ) continue; + + vector grpIndices(1,i); + if ( !grp.groupes.empty() ) + grpIndices.assign( grp.groupes.begin(), grp.groupes.end()); + + _SupportDesc supDescriptor; + // look for a subpart for each _groupe + vector::iterator grIndex = grpIndices.begin(), grIndexEnd = grpIndices.end(); + for ( ; grIndex != grIndexEnd; ++grIndex ) + { + map< _SubPartDesc, _SubPart >::iterator descSub; + for ( descSub = _imed->_subPartDescribed.begin(); + descSub != _imed->_subPartDescribed.end(); + ++descSub) + { + if ( descSub->second.myCellGroupIndex == *grIndex ) { + supDescriptor.insert( descSub->first ); + break; + } + } + } + if ( supDescriptor.size() == grpIndices.size() ) { + _Support & sup = _imed->_supportDescribed[ supDescriptor ]; + sup.setGroup( & grp ); + } + } + } + + // find the support by its description + map< _SupportDesc, _Support >::iterator descSup = + _imed->_supportDescribed.find( descriptor ); + + // Create a new support + if ( descSup == _imed->_supportDescribed.end() || !descSup->second.medSupport( entity )) + { + // create a _groupe composed of groups corresponding to subparts + _imed->groupes.push_back(_groupe()); + _groupe& grp = _imed->groupes.back(); + grp.groupes.reserve( descriptor.size() ); + + // to detect dimension change within a support group + set dimensions; + + // fill grp with sub-group indices + _SupportDesc::const_iterator subPartDesc = descriptor.begin(); + for ( ; subPartDesc != descriptor.end(); ++subPartDesc ) + { + const _SubPart* subPart = getSubPart(*subPartDesc); + if ( !subPart ) + throw MEDEXCEPTION(LOCALIZED(STRING("No mesh info for ") << *subPartDesc)); + + int groupIndex = + (entity == MED_NODE) ? subPart->myNodeGroupIndex : subPart->myCellGroupIndex; + if ( groupIndex < 1 ) { + if ( entity == MED_NODE ) + { + // make a _groupe of nodes + _imed->groupes.push_back(_groupe()); + groupIndex = subPart->myNodeGroupIndex = _imed->groupes.size(); + _groupe & groupe = _imed->groupes.back(); + groupe.mailles.resize( subPart->myNbNodes ); + + _maille ma( MED_POINT1, 1 ); + ma.sommets.resize( 1 ); + map< int, _noeud >::iterator n = subPart->myFirstNode; + for (int i = 0; i < subPart->myNbNodes; ++i, ++n ) { + ma.sommets[0] = n; + ma.setOrdre( n->second.number ); + groupe.mailles[i] = _imed->insert(ma); + } + } + else + { + throw MEDEXCEPTION(LOCALIZED(STRING("No cell info for ") << *subPartDesc)); + } + } + grp.groupes.push_back( groupIndex ); + + // find out subpart dimension + if ( entity != MED_NODE ) + dimensions.insert( _imed->groupes[ groupIndex-1 ].maille(0).dimensionWithPoly() ); + } + // check if MEDMEM allows creating such a support + if ( dimensions.size() > 1 ) + throw MEDEXCEPTION + (compatibilityPb(LOC) << "can't create a SUPPORT for the field from " + << _dataFileName << ", since it is on different mesh entities"); + + ENSIGHT_MESH_RDONLY_DRIVER::makeGroup( grp, *_imed ); + + // add _Support + descSup = _imed->_supportDescribed.insert( make_pair( descriptor, _Support() )).first; + _Support & sup = descSup->second; + sup.setGroup( & grp ); + + } // new SUPPORT creation + + _Support* sup = & descSup->second; + + // remove temporary mesh from med SUPPORT + if ( _imed->_isOwnMedMesh ) + sup->medSupport( entity )->setMesh( 0 ); + + return sup; +} + +//================================================================================ +/*! + * \brief check possibility to open a file with a given mode + */ +//================================================================================ + +bool _CaseFileDriver_User::canOpenFile(const string& fileName, + med_mode_acces mode) +{ + bool ok = false; + if ( mode == WRONLY ) { + fstream file( fileName.c_str(), + ios::app | ios_base::out ); // not to overwrite it, just to check + ok = bool(file); + } + else { + fstream file( fileName.c_str(), ios::in ); + ok = bool(file); + } + return ok; +} + +//================================================================================ +/*! + * \brief _CaseFileDriver_User destructor + */ +//================================================================================ + +_CaseFileDriver_User::~_CaseFileDriver_User() +{ + if ( _imed ) + _imed->_nbUsers--; + unregister( this ); +} + +//================================================================================ +/*! + * \brief Search substring in a string + */ +//================================================================================ + +bool contains( const char* what, const char* inString ) +{ + size_t whatLen = strlen( what ); + size_t inLen = strlen( inString ); + return + ( search( inString, inString+inLen, what, what + whatLen) != inString+inLen ); +} + +//================================================================================ +/*! + * \brief store subPart data + */ +//================================================================================ + +void _InterMed::addSubPart(const _SubPart& theSubPart) +{ + if ( _needSubParts ) { + _SubPart & subPart = _subPartDescribed[ theSubPart.getDescriptor() ]; + subPart = theSubPart; + if ( subPart.myCellGroupIndex > 0 ) { + _groupe & groupe = this->groupes[ subPart.myCellGroupIndex-1 ]; + subPart.myFirstCell = groupe.mailles.begin(); + } + } +} + +//================================================================================ +/*! + * \brief For a node, find its index in the supporting GROUP + */ +//================================================================================ + +int _Support::getIndex( const pair& inode) +{ + if ( myNodeGroup->relocMap.empty() ) // on all and not self intersecting support + return abs( inode.second.number ); + + map::iterator ordreIndex = myNodeGroup->relocMap.find( abs( inode.second.number )); + if ( ordreIndex == myNodeGroup->relocMap.end() ) + throw MEDEXCEPTION(LOCALIZED(STRING("No index found for ") << inode.second)); +// map < int, int >::iterator numIndex = myNodeRelocMap.find( node->number ); +// if ( numIndex == myNodeRelocMap.end() ) +// throw MEDEXCEPTION(STRING("No index found for node ") << node->number); + + return ordreIndex->second; +} + +//================================================================================ +/*! + * \brief For a cell, return its index in the supporting GROUP + */ +//================================================================================ + +int _Support::getIndex( const _groupe::TMaille& cell) +{ + if ( myCellGroup->relocMap.empty() ) // on all and not self intersecting support + return cell->ordre(); + + map::iterator ordreIndex = myCellGroup->relocMap.find( cell->ordre() ); + if ( ordreIndex == myCellGroup->relocMap.end() ) + throw MEDEXCEPTION(LOCALIZED(STRING("No index found for ") << *cell)); + + return ordreIndex->second; +} + +//================================================================================ +/*! + * \brief Return med geom type for a subPart element + */ +//================================================================================ + +// medGeometryElement _Support::getType( const pair& node) +// { +// return myNodeGroup->medGroup.getTypes[0]; +// } + +// //================================================================================ +// /*! +// * \brief Return med geom type for a subPart element +// */ +// //================================================================================ + +// medGeometryElement _Support::getType( const _groupe::TMaille& cell) +// { +// return cell->geometricType; +// } + +//================================================================================ +/*! + * \brief Set med support + */ +//================================================================================ + +void _Support::setGroup( _groupe* group ) +{ + if ( group->medGroup ) { + if ( group->medGroup->getEntity() == MED_NODE ) + myNodeGroup = group; + else + myCellGroup = group; + } + else { + throw MEDEXCEPTION(LOCALIZED("_Support::setGroup(): med GROUP is NULL")); + } +} + +//================================================================================ +/*! + * \brief Return med group correspoding to entity + */ +//================================================================================ + +SUPPORT* _Support::medSupport( medEntityMesh entity ) +{ + if ( entity == MED_NODE ) + return myNodeGroup ? myNodeGroup->medGroup : 0; + else + return myCellGroup ? myCellGroup->medGroup : 0; +} + +//================================================================================ +/*! + * \brief print _SubPartDesc + */ +//================================================================================ + +std::ostream& operator << (std::ostream& os, const _SubPartDesc& desc) +{ + if ( desc == _SubPartDesc::globalCoordDesc() ) + os << "'global coordinates'"; + else + os << "<'part " << desc.partNumber() << "', '" << desc.typeName() << "'>"; + return os; +} + +//================================================================================ +/*! + * \brief Constructor of ASCIIFileReader + */ +//================================================================================ + +_ASCIIFileReader::_ASCIIFileReader(const string& fileName) throw (MEDEXCEPTION) +{ +#ifdef WNT + _file = ::_open (fileName.c_str(), _O_RDONLY|_O_BINARY); +#else + _file = ::open (fileName.c_str(), O_RDONLY); +#endif + if (_file >= 0) + { + _start = new char [BUFFER_SIZE]; + _ptr = _start; + _eptr = _start; + } + else + { + throw MEDEXCEPTION(STRING("Can't read from ")<= _start ) + isASCII = (*ptr-- == '\n'); + _isWin = ( *ptr == '\r'); + if ( !isASCII ) + throw MEDEXCEPTION(STRING("Not ASCII file ")< 0) { + char* tmpBuf = new char [nBytesRest]; + memcpy (tmpBuf, _ptr, nBytesRest); + memcpy (_start, tmpBuf, nBytesRest); + delete [] tmpBuf; + } else { + nBytesRest = 0; + } + _ptr = _start; + const int nBytesRead = ::read (_file, + &_start [nBytesRest], + BUFFER_SIZE - nBytesRest); + nBytesRest += nBytesRead; + _eptr = &_start [nBytesRest]; + + // skip spaces at file end + if ( nBytesRest < MAX_LINE_LENGTH ) { + while ( isspace( *_ptr )) _ptr++; + nBytesRest = _eptr - _ptr; + } + } + return nBytesRest < 1; +} + +//================================================================================ +/*! + * \brief read out given data + */ +//================================================================================ + +void _ASCIIFileReader::skip(int nbVals, int nbPerLine, int valWidth) +{ + int nbLines = (nbVals + nbPerLine - 1) / nbPerLine; + int width = nbVals * valWidth; + skip( width, nbLines ); +} + +//================================================================================ +/*! + * \brief read out width chars and nbLines line-ends + */ +//================================================================================ + +void _ASCIIFileReader::skip(int width, int nbLines) +{ + width += nbLines; // to skip '\n' + if ( _isWin ) + width += nbLines; // to skip '\r' + + _ptr += width; + int nBytesRest = _eptr - _ptr; + while ( nBytesRest < 0 ) { + width = -nBytesRest; + if ( eof() ) return; + _ptr += width; + nBytesRest = _eptr - _ptr; + } +} + +//================================================================================ +/*! + * \brief Read a next line from the file + */ +//================================================================================ + +char* _ASCIIFileReader::getLine() throw (MEDEXCEPTION) +{ + if ( eof() ) + throw MEDEXCEPTION("Unexpected EOF"); + + // Check the buffer for the end-of-line + char * ptr = _ptr; + while (true) + { + // Check for end-of-the-buffer, the ultimate criterion for termination + if (ptr >= _eptr) + { + //_eptr[-1] = '\0'; + _eptr[0] = '\0'; + break; + } + // seek the line-feed character + if (ptr[0] == '\n') + { + if ( ptr > _start && // avoid "Invalid read" error by valgrind + ptr[-1] == '\r') + ptr[-1] = '\0'; + ptr[0] = '\0'; + ++ptr; + break; + } + ++ptr; + } + // Output the result + char * line = _ptr; + _ptr = ptr; + + return line; +} + +//================================================================================ +/*! + * \brief + */ +//================================================================================ + +bool _ASCIIFileReader::lookAt( const char* text ) +{ + while ( isspace(*_ptr)) ++_ptr; + return ( strncmp( _ptr, text, strlen( text )) == 0 ); +} + +//================================================================================ +/*! + * \brief Read a next word from the file + */ +//================================================================================ + +string _ASCIIFileReader::getWord() +{ + if ( eof() ) + return ""; + + // skip spaces + while ( isspace(*_ptr)) ++_ptr; + if ( _ptr >= _eptr ) + return ""; + + // skip not spaces + char* word = _ptr++; + while ( !isspace(*_ptr)) ++_ptr; + + return string( word, _ptr - word ); +} + +//================================================================================ +/*! + * \brief Return true if TIME_STEP_BEG follows and skips TIME_STEP_BEG line + */ +//================================================================================ + +bool _ASCIIFileReader::isTimeStepBeginning() +{ + if ( eof() ) throw MEDEXCEPTION(LOCALIZED("Unexpected EOF")); + + while ( isspace(*_ptr)) ++_ptr; + + if ( strncmp( _ptr, TIME_STEP_BEG, TIME_STEP_BEG_LEN ) != 0 ) + return false; + + _ptr += TIME_STEP_BEG_LEN; + while ( isspace(*_ptr)) ++_ptr; + return true; +} + +//================================================================================ +/*! + * \brief Return true if TIME_STEP_END follows and skips TIME_STEP_END line + */ +//================================================================================ + +bool _ASCIIFileReader::isTimeStepEnd() +{ + if ( eof() ) return true; + + while ( isspace(*_ptr)) ++_ptr; + + if ( strncmp( _ptr, TIME_STEP_END, TIME_STEP_END_LEN ) != 0 ) + return false; + + _ptr += TIME_STEP_END_LEN; + while ( isspace(*_ptr)) ++_ptr; + return true; +} + + +//================================================================================ +/*! + * \brief divide a string into two parts + */ +//================================================================================ + +int _ASCIIFileReader::split(const string& str, + string & part1, + string & part2, + const char separator, + const bool fromBack) +{ + int nbParts = 0; + string parts[2]; + const char* ptr1 = str.c_str(); + const char* back = ptr1 + str.size(); + for (nbParts = 0; nbParts < 2; ++nbParts ) { + // skip spaces before the current part + while ( isspace(*ptr1)) ++ptr1; + if ( !*ptr1) break; + // find end of the part and beginning of the next part + const char* ptr2 = ptr1; + const char* nextBeg = back; + if ( nbParts > 0 ) { + ptr2 = back; + } + else if ( fromBack ) { + ptr2 = back; + string::size_type pos = str.rfind( separator ); + if ( pos != str.npos ) { + ptr2 = & str[ pos ]; + nextBeg = ptr2 + 1; + if ( separator != ' ') + while ( *nextBeg && *nextBeg == separator ) ++nextBeg; + } + } + else if ( separator == ' ' ) { + while ( *ptr2 && !isspace(*ptr2)) ++ptr2; + if ( *ptr2 ) nextBeg = ptr2 + 1; + } + else { + while ( *ptr2 && *ptr2 != separator ) ++ptr2; + if ( *ptr2 ) { + nextBeg = ptr2 + 1; + while ( *nextBeg && *nextBeg == separator ) ++nextBeg; + } + } + //if ( !*ptr2) --ptr2; + // skip spaces after the current part + while ( isspace(ptr2[-1])) --ptr2; + parts[ nbParts ] = string( ptr1, ptr2-ptr1 ); + ptr1 = nextBeg; + } + part1 = parts[0]; + part2 = parts[1]; + return nbParts; +} + +//================================================================================ +/*! + * \brief divide a string into parts, return nb of parts + */ +//================================================================================ + +int _ASCIIFileReader::split(const string& str, + list & parts, + const char separator, + const bool fromBack) +{ + parts.clear(); + if ( str.empty() ) + return 0; + int nbParts = 0; + const char* ptr1 = str.c_str(); + const char* back = ptr1 + str.size(); + if ( fromBack ) { + swap( ptr1, back ); + while (1) { + // skip spaces after the current part + while ( isspace(ptr1[-1])) --ptr1; + if ( ptr1 <= back ) break; + // find beginning of the part + const char* ptr2 = ptr1 - 1; + if ( separator == ' ' ) + while ( ptr2 > back && !isspace(ptr2[-1])) --ptr2; + else + while ( ptr2 > back && ptr2[-1] != separator ) --ptr2; + //if ( !*ptr2) --ptr2; + const char* sepPtr = ptr2; + // skip spaces before the current part + while ( isspace(*ptr2)) ++ptr2; + parts.push_back( string( ptr2, ptr1-ptr2 )); + ++nbParts; + ptr1 = sepPtr - 1; + } + } + else { + while (1) { + // skip spaces before the current part + while ( isspace(*ptr1)) ++ptr1; + if ( ptr1 >= back) break; + // find end of the part + const char* ptr2 = ptr1 + 1; + if ( separator == ' ' ) + while ( *ptr2 && !isspace(*ptr2)) ++ptr2; + else + while ( *ptr2 && *ptr2 != separator ) ++ptr2; + //if ( !*ptr2) --ptr2; + const char* sepPtr = ptr2; + // skip spaces after the current part + while ( isspace(ptr2[-1])) --ptr2; + parts.push_back( string( ptr1, ptr2-ptr1 )); + ++nbParts; + ptr1 = sepPtr + int( sepPtr < back ); + } + } + return nbParts; +} + +//================================================================================ +/*! + * \brief check if a string contains only digits + */ +//================================================================================ + +bool _ASCIIFileReader::isDigit(const string& str, const bool real) +{ + const char* s = str.c_str(); + if ( real ) { + while ( *s ) { + char c = *s++; + if ( !isdigit(c) && c!='-' && c!='+' && c!='.' && c!=',' && c!='E' && c!='e') + return false; + } + } + else { + while ( *s ) { + if ( !isdigit( *s++ )) + return false; + } + } + return true; +} + +//================================================================================ +/*! + * \brief Destructor of ASCIIFileReader closes its file + */ +//================================================================================ + +_ASCIIFileReader::~_ASCIIFileReader() +{ + if (_file >= 0) + { + ::close (_file); + delete [] _start; + } +} + +//================================================================================ +/*! + * \brief Constructor of _BinaryFileReader opens its file + */ +//================================================================================ + +_BinaryFileReader::_BinaryFileReader(const string& fileName) throw (MEDEXCEPTION) + : _exception(STRING("Unexpected EOF ") << fileName), _mySwapBytes(false) +{ +#ifdef WNT + _file = ::_open (fileName.c_str(), _O_RDONLY|_O_BINARY); +#else + _file = ::open (fileName.c_str(), O_RDONLY); +#endif + + if (_file < 0) + throw MEDEXCEPTION(STRING("Can't read from ") << fileName); + + _maxPos = ::lseek( _file, 0, SEEK_END); + _pos = ::lseek( _file, 0, SEEK_SET); +} + +//================================================================================ +/*! + * \brief Destructor of _BinaryFileWriter closes its file + */ +//================================================================================ + +_BinaryFileReader::~_BinaryFileReader() +{ + if (_file >= 0) + ::close (_file); +} + +//================================================================================ +/*! + * \brief rewind the file backward + */ +//================================================================================ + +void _BinaryFileReader::rewind() +{ + _pos = ::lseek( _file, 0, SEEK_SET); +} + +//================================================================================ +/*! + * \brief size of not read file portion in sizeof(int) + */ +//================================================================================ + +int _BinaryFileReader::moreValuesAvailable() const +{ + return (_maxPos - _pos) / sizeof(int); // believe that sizeof(int) == sizeof(float) +} + +//================================================================================ +/*! + * \brief Return true if the whole file has been read + */ +//================================================================================ + +bool _BinaryFileReader::eof() +{ + return _pos >= _maxPos; +} + +//================================================================================ +/*! + * \brief Skips given nb of bytes + */ +//================================================================================ + +void _BinaryFileReader::skip(int size) throw (MEDEXCEPTION) +{ + if ( _pos + size > _maxPos ) + throw _exception; + off_t newPos = ::lseek( _file, size, SEEK_CUR); + if ( newPos < _pos + size ) + throw _exception; + _pos = newPos; +} + +//================================================================================ +/*! + * \brief Read lines until TIME_STEP_BEG encounters + */ +//================================================================================ + +void _BinaryFileReader::skipTimeStepBeginning() throw (MEDEXCEPTION) +{ + bool tsbReached = false; + while ( !tsbReached ) { + TStrOwner line( getLine() ); + tsbReached = ( strncmp( line, TIME_STEP_BEG, TIME_STEP_BEG_LEN ) == 0 ); + } +} + +//================================================================================ +/*! + * \brief Constructor of _BinaryFileWriter opens its file + */ +//================================================================================ + +_BinaryFileWriter::_BinaryFileWriter(const string& fileName) throw (MEDEXCEPTION) + : _exception(STRING("Can't write into ") << fileName) +{ +#ifdef WNT + _file = ::_open (fileName.c_str(), _O_WRONLY|_O_BINARY|_O_TRUNC); +#else + _file = ::open (fileName.c_str(), O_WRONLY|O_TRUNC); //length shall be truncated to 0 +#endif + + if (_file < 0) + throw _exception; +} + +//================================================================================ +/*! + * \brief Destructor of _BinaryFileWriter closes its file + */ +//================================================================================ + +_BinaryFileWriter::~_BinaryFileWriter() +{ + if (_file >= 0) + ::close (_file); +} + +//================================================================================ +/*! + * \brief Write string + */ +//================================================================================ + +void _BinaryFileWriter::addString(const char* str) throw (MEDEXCEPTION) +{ + size_t len = strlen( str ); + if ( len > MAX_LINE_LENGTH ) + throw MEDEXCEPTION + (LOCALIZED(STRING("_BinaryFileWriter::addString(), too long string (>80):\n") << str)); + + string buffer( str, len ); + // avoid "Syscall param write(buf) points to uninitialised byte(s)" error by valgrind + buffer += string(MAX_LINE_LENGTH, ' '); + buffer[ len ] = '\0'; + buffer[ MAX_LINE_LENGTH-1 ] = '\0'; // to have line-end within + + add( buffer.c_str(), MAX_LINE_LENGTH ); +} + + + +} // end namespace MEDMEM_ENSIGHT diff --git a/src/MEDMEM/MEDMEM_EnsightUtils.hxx b/src/MEDMEM/MEDMEM_EnsightUtils.hxx new file mode 100644 index 000000000..7c3502221 --- /dev/null +++ b/src/MEDMEM/MEDMEM_EnsightUtils.hxx @@ -0,0 +1,945 @@ +// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// File : MEDMEM_EnsightUtils.hxx +// Created : Tue May 27 12:24:11 2008 +// Author : Edward AGAPOV (eap) + + +#ifndef MEDMEM_EnsightUtils_HeaderFile +#define MEDMEM_EnsightUtils_HeaderFile + +#include "MEDMEM_GenDriver.hxx" +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_DriverTools.hxx" +#include "MEDMEM_Mesh.hxx" +//#include "MEDMEM_Field.hxx" + +#include +#include +#include + +namespace MEDMEM { + + // ============================================================================== + /*! + * \brief Functions to set writing format. + * Default format is EnSight6 ASCII + */ + // ============================================================================== + + enum EnSightFormat { ENSIGHT_6, ENSIGHT_GOLD }; + + void MEDMEM_EXPORT setEnSightFormatForWriting (EnSightFormat format, bool isBinary); + + EnSightFormat getEnSightFormatForWriting(); + bool isBinaryEnSightFormatForWriting(); + + // ============================================================================== + /*! + * \brief To raise or not if MEDMEM-EnSight incompatibility encounters or suspected + * + * Default is to raise. + * To ignore incompatibility is useful for debug of EnSigt reading and + * for suppressing exceptions in some suspicious cases, for example writing + * several meshes and fields. + * Incompatibility exception includes "EnSight-MEDMEM compatibility problem" string. + * Not all incompatibility exceptions can be suppressed. + */ + // ============================================================================== + + void MEDMEM_EXPORT setIgnoreIncompatibility(bool toIgnore=true); +} + +namespace MEDMEM { + class ENSIGHT_MESH_RDONLY_DRIVER; + class ENSIGHT_FIELD_RDONLY_DRIVER; + class ENSIGHT_MESH_WRONLY_DRIVER; + class ENSIGHT_FIELD_WRONLY_DRIVER; +} + +// ============================================================================== +namespace MEDMEM_ENSIGHT { // INTERNAL MATTERS +// ============================================================================== + + class _CaseFileDriver; + class _CaseFileDriver_User; + struct _InterMed; + struct _SubPart; + struct _SubPartDesc; + struct _Support; + typedef std::set< _SubPartDesc > _SupportDesc; + + using namespace MED_EN; + using namespace MEDMEM; + using namespace std; + + // --------------------------------------------------------------- + /*! + * \brief Prepend "EnSight-MEDMEM compatibility problem" to the text + * of an exception + */ + STRING compatibilityPb(const string& exceptionText); + + // --------------------------------------------------------------- + /*! + * \brief To ignore incompatibility or not + */ + bool toIgnoreIncompatibility(); + + // --------------------------------------------------------------- + //!< search substring in a string + bool contains( const char* what, const char* inString ); + + // --------------------------------------------------------------- + /*! + * \brief EnSight element type name and an array to convert + * med connectivity to EnSight one + */ + struct TEnSightElemType + { + string _name; + vector _medIndex; + medGeometryElement _medType; + }; + // --------------------------------------------------------------- + /*! + * \brief Return EnSight type corresponding to med one + */ + const TEnSightElemType& getEnSightType(medGeometryElement medType); + + // --------------------------------------------------------------- + /*! + * \brief Return EnSight type having a given name + */ + const TEnSightElemType& getEnSightType(const string& typeName); + + // --------------------------------------------------------------- + /*! + * \brief Return true if typeName begins with "g_" + */ + inline bool isGhostType(const string& typeName) + { return ( typeName[0] == 'g' && typeName[1] == '_'); } + + // --------------------------------------------------------------- + /*! + * \brief Maximal EnSight line length + */ + const int MAX_LINE_LENGTH = 80; + + // --------------------------------------------------------------- + /*! + * \brief Maximal length of field name in EnSight + */ + const int MAX_FIELD_NAME_LENGTH = 19; + + // --------------------------------------------------------------- + /*! + * \brief Maximal length of field name in EnSight + */ + const string ILLEGAL_FIELD_NAME_CHARACTERS = " !@#$^()[]*/+-"; // '.,' ???? + + // --------------------------------------------------------------- + /*! + * \brief Width of fields in ASCII file + */ + const int INT_WIDTH_6 = 8; + const int INT_WIDTH_GOLD = 10; + const int FLT_WIDTH = 12; + + // --------------------------------------------------------------- + /*! + * \brief EnSight space dimension + */ + const int SPACE_DIM = 3; + + // --------------------------------------------------------------- + /*! + * \brief Time step data boundaries in single-file mode + */ + static const char* TIME_STEP_BEG = "BEGIN TIME STEP"; + static const char* TIME_STEP_END = "END TIME STEP"; + const size_t TIME_STEP_BEG_LEN = 15; + const size_t TIME_STEP_END_LEN = 13; + + + // --------------------------------------------------------------- + /*! + * \brief Cast value to float and protect from overflow + */ + static inline float _toFloat (const double & value) { + if ( value > FLT_MAX ) return FLT_MAX; + if ( value < -FLT_MAX ) return -FLT_MAX; +#ifdef WNT +#else + if ( isnan( value )) throw MEDEXCEPTION(compatibilityPb("NaN value not allowed")); +#endif + return float( value ); + } + static inline float _toFloat (const int & value) { return float( value ); } + static inline float _toFloat (const long & value) { return float( value ); } + +// ============================================================================== +/*! + * \brief Reader/writer of EnSight Case file + * + * Apart from it's major job, it + * o assures cooperation of MED and Mesh/Field drivers so that the Case file created + * by MED driver is not overwritten by Mesh driver called by MED driver. + */ +// ============================================================================== + +class _CaseFileDriver +{ +public: + _CaseFileDriver(const string& fileName, const _CaseFileDriver_User* creator); + ~_CaseFileDriver(); + + void read() throw (MEDEXCEPTION); + + // --------------- + // reading meshes + // --------------- + + int getNbMeshes() const; + + //!< sets all data necessary for meshDriver::read() + void setDataFileName(const int meshIndex, ENSIGHT_MESH_RDONLY_DRIVER* meshDriver); + + // --------------- + // reading fields + // --------------- + + int getNbVariables() const; + + int getNbVarSteps(const int variableIndex); + + //!< return variable index by variable name, return 0 if none found + int getVariableIndex(const string & varName) const; + + //!< sets all data necessary for fieldDriver::read(), returns meshIndex + int setDataFileName(const int varIndex, + const int stepIndex, + ENSIGHT_FIELD_RDONLY_DRIVER* fieldDriver); + + // -------- + // writing + // -------- + + //!< add a mesh to the Case file + void addMesh(const ENSIGHT_MESH_WRONLY_DRIVER* meshDriver); + + //!< add a field to the Case file + void addField(const ENSIGHT_FIELD_WRONLY_DRIVER * fieldDriver); + + //!< write and set necessary data to added drivers + void write() throw (MEDEXCEPTION); + +private: + + //!< throw if Case file has not been read else return false + bool checkWasRead() const throw (MEDEXCEPTION); + + //!< replace '*' in file name if any and return index in a file and time + int fixWildCardName(const int timeStep, + const std::string & ts, + const std::string & fs, + std::string & fileName, + std::string & time); + + // -------------------------------------------------------------------------------- + // GEOMETRY section + // model: [ts] [fs] filename [change_coords_only] + // ts = time set number as specified in TIME section. This is optional. + // fs = corresponding file set number as specified in FILE section below. + // (Note, if you specify fs, then ts is no longer optional and must also be + // specified.) + // filename = The filename of the appropriate file. + // -> Model or measured filenames for a static geometry case, as well as match, + // boundary, and rigid_body filenames will not contain "*" wildcards. + // -> Model or measured filenames for a changing geometry case will + // contain "*" wildcards. + // change_coords_only = The option to indicate that the changing geometry (as + // indicated by wildcards in the filename) is coords only. + // Otherwise, changing geometry connectivity will be + // assumed. + struct _Model { + string _timeSetNumber, _fileSetNumber; //!< ts, fs + string _fileName; //!< filename + string _change_coords_only; + }; + // -------------------------------------------------------------------------------- + // VARIABLE section + // ts = The corresponding time set number (or index) as specified in TIME + // section below. This is only required for transient constants and + // variables. + // fs = The corresponding file set number (or index) as specified in FILE + // section below. + // (Note, if you specify fs, then ts is no longer optional and must + // also be specified.) + // description = The variable (GUI) name (ex. Pressure, Velocity, etc.) + // const_value(s) = The constant value. If constants change over time, then ns (see + // TIME section below) constant values of ts. + // cvfilename = The filename containing the constant values, one value per time step. + // filename = The filename of the variable file. Note: only transient filenames + // contain "*" wildcards. + // Re_fn = The filename for the file containing the real values of the complex + // variable. + // Im_fn = The filename for the file containing the imaginary values of the + // complex variable. + // freq = The corresponding harmonic frequency of the complex variable. + // For complex variables where harmonic frequency is undefined, + // simply use the text string: UNDEFINED. + struct _Variable { + string _type; //!< constant|scalar|etc. + string _name; //!< description + string _timeSetNumber, _fileSetNumber; //!< [ts], [fs] + string _fileNameOrData; //!< [cv]filename|Re_fn Im_fn freq|const_value(s) + }; + // -------------------------------------------------------------------------------- + // FILE section + // fs = file set number. This is the number referenced in the GEOMETRY + // and VARIABLE sections above. + // ns = number of transient steps + // fi = file index number in the file name (replaces "*" in the filenames) + struct _FileSet { + int _number; //!< fs + std::list _nbStepsInFile; //!< ns + std::list _fileIndex; //!< fi + }; + // -------------------------------------------------------------------------------- + // TIME section + struct _TimeSet { + int _number; //!< ts + std::vector _fileIndex; //!< fn + std::vector _times; //!< times + + bool operator==(const _TimeSet& ts) const + { return ( _fileIndex == ts._fileIndex && _times == ts._times ); } + }; + +private: + + std::string _fileName; + std::string _directory; + EnSightFormat _format; + _Model _model; + std::map< int, _Variable> _variables; //!< map order number to variable data + std::map< int, _TimeSet > _timeSets; //!< map ts to time set data + std::map< int, _FileSet > _fileSets; //!< map fs to file set data + + const _CaseFileDriver_User* _user; //!< mesh/field driver + + std::list _meshDrivers; //!< added meshes + + typedef std::map > TFieldDriversByName; + TFieldDriversByName _fieldDrivers; //!< added field drivers groupped by name + + //!< to block all calls from a mesh/field driver governed by med driver + bool _blocked; +}; + + // ============================================================================== +/*! + * \brief Base of all Ensight drivers. + * It stores data passed from case file + */ +// ============================================================================== + +class _CaseFileDriver_User: public GENDRIVER +{ +protected: + + _CaseFileDriver_User(const std::string& caseFileName="", + MED_EN::med_mode_acces mode=MED_EN::RDWR); + + const std::string& getCaseFileName() const { return GENDRIVER::_fileName; } + + const std::string& getDataFileName() const { return _dataFileName; } + + bool isGoldFormat() const { return _isGoldFormat; } + + //!< returns true if there are several meshes/fields in a data file + bool isSingleFileMode() const { return _singleFileMode; } + + //!< index of meshes/fields in a data file, zero for static mesh/feild + int getIndexInDataFile() const { return _indexInDataFile; } + + //!< true if there are time steps, i.e. getTime() has sense + bool isTransientMode() const { return _transientMode; } + + //!< time of a step + double getTime() const { return atof(_time.c_str()); } + + // ------------------------------- + // pass mesh data to field driver + // ------------------------------- + + //!< for mesh driver to store data + void setInterData(_InterMed* imed); + + //!< for field driver to get mesh data + _InterMed* getInterData(); + + _SubPart* getSubPart(const _SubPartDesc & descriptor) throw (MEDEXCEPTION); + + _Support* getSupport(const _SupportDesc & descriptor, + const medEntityMesh entity) throw (MEDEXCEPTION); + + +public: + //!< return part number to write support with, zero in failure case + int getPartNumber(const SUPPORT* support) const; + + static bool canOpenFile(const string& fileName, med_mode_acces mode); + + static void getSupportNodes(const SUPPORT* sup, map & nodeIds); + + //!< analyse if data file is binary + static bool isBinaryDataFile(const string& dataFileName); + + static bool isTimeStepBeginning(const string& line) + { return ( line == TIME_STEP_BEG ); } + + static bool isTimeStepEnd(const char* line) + { return ( strncmp( line, TIME_STEP_END, TIME_STEP_END_LEN ) == 0 ); } + + static bool isToWriteEntity(const medEntityMesh entity, const MESH* mesh); + + ~_CaseFileDriver_User(); + +private: + + friend class _CaseFileDriver; + + // members set by _CaseFileDriver::setDataFileName(...) and _CaseFileDriver::write() + std::string _dataFileName; + bool _isGoldFormat; + bool _transientMode; //!< true if there are time steps + bool _singleFileMode; //!< only one or several meshes/fields in a data file + int _indexInDataFile; //!< which meshes/fields in a data file + std::string _time; //!< time of a step + + _InterMed* _imed; //!< to be used by field driver + string _imedMapKey; //!< key in the map storing mesh data for usage by field drv + +}; + +// ============================================================================== +/*! + * \brief Descriptor of the sub-part: part number and elem type or "block" etc. + */ +// ============================================================================== + +struct _SubPartDesc: public std::pair +{ + _SubPartDesc(int partNumber=-1, + const std::string& typeName="") + : std::pair ( partNumber, typeName ) {} + + const int& partNumber() const { return this->first; } + const string& typeName() const { return this->second; } + + static _SubPartDesc globalCoordDesc() { return _SubPartDesc(-1,"coordinates"); } +}; + +std::ostream& operator << (std::ostream& os, const _SubPartDesc& desc); + +// ============================================================================== +/*! + * \brief A type within EnSight part. It stores data needed by field driver to + * know nb of values of a geometric type and what place they get in MED group + */ +// ============================================================================== + +struct _SubPart: public _SubPartDesc +{ + // _SubPart describes both nodes and elements since "block" describes the both. + // Mesh driver sets + // for cells: myNbCells and myCellGroupIndex + // for nodes: myNbNodes and myFirstNode + // GROUP of cells is created always, + // GROUP of nodes, only if nodal field support is required (see getSupport()) + + int myNbCells; //!< nb of cells + int myCellGroupIndex; //!< cell group id in _InterMed + _groupe::TMailleIter myFirstCell; //!< pointer to the first cell + + int myNbNodes; //!< nb of nodes + mutable int myNodeGroupIndex; //!< node group id in _InterMed + _maille::TNoeud myFirstNode; //!< pointer to the first node + + _SubPart(int partNumber=-1, + const std::string& typeName="") + : _SubPartDesc(partNumber,typeName), + myNbCells(0), myCellGroupIndex(-1), + myNbNodes(0), myNodeGroupIndex(-1) + {} + + _SubPartDesc getDescriptor() const { return _SubPartDesc( partNumber(), typeName() ); } +}; + +// ============================================================================== +/*! + * \brief EnSight variable support composed of _SubPart's + */ +// ============================================================================== + +struct _Support +{ + _groupe * myCellGroup; //!< cell group in _InterMed + _groupe * myNodeGroup; //!< node group in _InterMed + + _Support(): myCellGroup(0), myNodeGroup(0) {} + + void setGroup( _groupe* g ); + SUPPORT* medSupport( medEntityMesh entity ); + + int getIndex( const pair& node); + int getIndex( const _groupe::TMaille& cell); + +// medGeometryElement getType( const pair& node); +// medGeometryElement getType( const _groupe::TMaille& cell); +}; + +// ============================================================================== +/*! + * \brief Structure to temporarily store data read from EnSight geom file + */ +// ============================================================================== + +struct _InterMed : public _intermediateMED +{ + MESH * _medMesh; + bool _isOwnMedMesh; //!< whether to delete _medMesh + int _nbUsers; //!< to know when to delete _medMesh + + bool _needSubParts; //!< true if there are fields needing _SubPart data + + map< _SubPartDesc, _SubPart > _subPartDescribed; + + map< _SupportDesc, _Support > _supportDescribed; + + void addSubPart(const _SubPart& subPart); + + ~_InterMed() { if ( _isOwnMedMesh ) { delete _medMesh; _medMesh=0; }} +}; + +// ============================================================================== +/*! + * \brief Simple owner of C array + */ +// ============================================================================== + +template struct _ValueOwner { + T * myValues; + _ValueOwner(T* values):myValues(values) {} + ~_ValueOwner() { if ( myValues ) delete [] myValues; } + operator T*() { return myValues; } +private: + _ValueOwner(const _ValueOwner& other) {} // forbidden +}; +// instantiations +typedef _ValueOwner TStrOwner; +typedef _ValueOwner TIntOwner; +typedef _ValueOwner TDblOwner; +typedef _ValueOwner TFltOwner; + +// ============================================================================== +/*! + * \brief Iterator on values of a component + */ +// ============================================================================== + +template class _ValueIterator +{ +protected: + const T* myPtr; + int myDelta; +public: + _ValueIterator() // by default next() returns zero + : myPtr(zeroPtr()), myDelta( 0 ) {} + + _ValueIterator(const T* values, int delta): myPtr(values-delta), myDelta(delta) {} + + const T & next() { myPtr += myDelta; return *myPtr; } + + static const T* zeroPtr() { static T a0 = 0; return &a0; } +}; + +// ============================================================================== +/*! + * \brief Reader of ASCII files + */ +// ============================================================================== + +class _ASCIIFileReader +{ +public: + _ASCIIFileReader(const string& fileName) throw (MEDEXCEPTION); + + ~_ASCIIFileReader(); + + bool eof(); + + string getWord(); //!< never throws + + int getInt() throw (MEDEXCEPTION) { + if ( eof() ) throw MEDEXCEPTION("Unexpected EOF"); + return strtol(_ptr, &_ptr, 10); + } + float getReal() throw (MEDEXCEPTION) { + if ( eof() ) throw MEDEXCEPTION("Unexpected EOF"); +#ifdef WNT +#else + return strtof(_ptr, &_ptr); +#endif + } + //!< needed after getWord(), getInt() or getReal() to get a next line + void toNextLine() { + while (isspace(*_ptr)) if ((++_ptr)[-1]=='\n') break; + } + char* getLine() throw (MEDEXCEPTION); + + const char* getCurrentPtr() const { return _ptr; } + + bool lookAt( const char* text ); + + bool isTimeStepBeginning(); + + bool isTimeStepEnd(); + + //!< read out given data + void skip(int nbVals, int nbPerLine, int valWidth); + + //!< read out width chars and nbLines line-ends + void skip(int width, int nbLines); + + template + char* convertReals( const int nbValues, + const char* undefValue = 0, + set* undefIndices = 0, + const vector* partialIndices = 0, + const int nbPartialComponents = 0) + throw (MEDEXCEPTION) + { + T* result = new T[ nbValues ]; + T* ptrT = result; + if ( undefValue ) // fill undefIndices + { + undefIndices->clear(); + float undef = atof( undefValue ); + for ( int i = 0; i < nbValues; ++i, ++ptrT ) { + float value = getReal(); + (*ptrT) = (T) value; + if ( value == undef ) + undefIndices->insert( undefIndices->end(), i+1 ); + } + } + else if ( partialIndices ) + { + // partial variables are available in GOLD format only where + // values are in no-interlace + int shift = 1; + for ( int j = 1; j <= nbPartialComponents; ++j ) { + vector::const_iterator i = partialIndices->begin(), iEnd = partialIndices->end(); + while ( i != iEnd ) + result[ *i++ - shift ] = (T) getReal(); + shift += nbValues; + } + } + else + { + for ( int i = 0; i < nbValues; ++i, ++ptrT ) + (*ptrT) = (T) getReal(); + } + return (char*) result; + } + + //static string strip(char* & str); + + //!< divide a string into two parts + static int split(const string& str, + string & part1, + string & part2, + const char separator=' ', + const bool fromBack=false); + + //!< divide a string into parts, return nb of parts + static int split(const string& str, + std::list & parts, + const char separator=' ', + const bool fromBack=false); + + //!< check if string contains only digits + static bool isDigit(const string& str, const bool real=false); + +private: + + int _file; + char* _start; // buffer start + char* _ptr; // beginning of not read portion + char* _eptr; // end of buffer contents + + bool _isWin; + +};// class _ASCIIFileReader + + +// ============================================================================== +/*! + * \brief Reader of binary files + */ +// ============================================================================== + +class _BinaryFileReader +{ +public: + _BinaryFileReader(const string& fileName) throw (MEDEXCEPTION); + + ~_BinaryFileReader(); + + void rewind(); //!< rewind the file backward + + void swapBytes() //!< turn on swapping bytes + { _mySwapBytes = true; } + + int moreValuesAvailable() const; //!< size of not read file portion in sizeof(int) + + bool eof(); + + void skip(int size) throw (MEDEXCEPTION); + + void skipTimeStepBeginning() throw (MEDEXCEPTION); + + char* getLine() throw (MEDEXCEPTION) + { return get(80); } + + int* getInt(int nb) throw (MEDEXCEPTION) + { return get(nb,_mySwapBytes); } + + float* getFlt(int nb) throw (MEDEXCEPTION) + { return get(nb,_mySwapBytes); } + + ssize_t getPosition() const { return _pos; } + + template + char* convertReals( const int nbValues, + const char* undefValue = 0, + set* undefIndices = 0, + const vector* partialIndices = 0, + const int nbPartialComponents = 0 ) + throw (MEDEXCEPTION) + { + T* result = new T[ nbValues ]; + T* ptrT = result, *endT = result + nbValues; + int nb = partialIndices ? partialIndices->size() * nbPartialComponents : nbValues; + TFltOwner fltData( getFlt( nb )); + float* ptrFlt = fltData; + if ( undefValue ) // fill undefIndices + { + undefIndices->clear(); + float undef = atof( undefValue ); + while ( ptrT < endT ) { + float value = *ptrFlt++; + *ptrT++ = (T) value; + if ( std::abs( value - undef ) <= FLT_MIN ) + undefIndices->insert( undefIndices->end(), ptrT - result ); + } + } + else if ( partialIndices ) + { + // partial variables are available in GOLD format only where + // values are in no-interlace + int shift = 1; + for ( int j = 1; j <= nbPartialComponents; ++j ) { + vector::const_iterator i = partialIndices->begin(), iEnd = partialIndices->end(); + while ( i != iEnd ) + result[ *i++ - shift ] = (T) *ptrFlt++; + shift += nbValues; + } + } + else + { + while ( ptrT < endT ) + *ptrT++ = (T) *ptrFlt++; + } + return (char*) result; + } +private: + + int _file; //!< descriptor + MEDEXCEPTION _exception; //!< ready to raise exception + ssize_t _pos, _maxPos; //!< current position and end position + bool _mySwapBytes; //!< to swap bytes + + //!< read any data from file + template T* get(int nb, bool inverseBytes=false) + { + size_t bufSize = nb * sizeof( T ); + if ( bufSize > _maxPos - _pos ) + throw _exception; + T* buf = new T[ nb ]; +#ifdef WNT +#else + ssize_t nBytesRead = ::read (_file, buf, bufSize ); + _pos += nBytesRead; + if ( nBytesRead < bufSize ) { + delete buf; + throw _exception; + } + if ( inverseBytes ) { // swap bytes + int* intBuf = ((int*) buf) - 1; + int* bufEnd = (int*)((char*) buf + nBytesRead); + while ( ++intBuf < bufEnd ) + *intBuf = InverseInt( *intBuf ); + } +#endif + return buf; + } + //!< swap bytes of int + int InverseInt (const int theValue) + { + return (0 | (( theValue & 0x000000ff ) << 24 ) + | (( theValue & 0x0000ff00 ) << 8 ) + | (( theValue & 0x00ff0000 ) >> 8 ) + | (( theValue >> 24 ) & 0x000000ff ) ); + } +}; + +// ============================================================================== +/*! + * \brief Writer of binary files + */ +// ============================================================================== + +class _BinaryFileWriter +{ +public: + _BinaryFileWriter(const string& fileName) throw (MEDEXCEPTION); + + ~_BinaryFileWriter(); + + //!< write a string + void addString(const char* str) throw (MEDEXCEPTION); + + //!< write a string + void addString(const string& str) throw (MEDEXCEPTION) + { addString( str.c_str() ); } + + //!< write an integer value + void addInt(const int value) throw (MEDEXCEPTION) + { add( &value, 1 ); } + + //!< write integer values + void addInt(const int* data, int nbValues) throw (MEDEXCEPTION) + { add( data, nbValues ); } + + //!< write integer values + void addInt(const vector< int >& data) throw (MEDEXCEPTION) + { add( &data[0], data.size() ); } + + //!< write any data as floats + template + void addReal(const T* data, int nbValues) throw (MEDEXCEPTION) + { + _RealData realData( data, nbValues ); + add( realData.values(), nbValues ); + } + + //!< write any data as floats + template + void addReal(vector< TValueIterator >& componentIt, + const int nbValues, + const medModeSwitch interlace) throw (MEDEXCEPTION) + { + _RealData realData( componentIt, nbValues, interlace ); + add( realData.values(), nbValues * componentIt.size() ); + } + +private: + + int _file; //!< descriptor + MEDEXCEPTION _exception; //!< ready to raise exception + + //!< write any data to file + template + void add(const T* data, int nbValues) throw (MEDEXCEPTION) + { +#ifdef WNT +#else + ssize_t nbWritten = ::write( _file, (const void *) data, nbValues * sizeof(T)); + if ( nbWritten < 0 ) throw _exception; +#endif + } + // ------------------------------------------------------------------------ + /*! + * \brief Container of temporary data converting any data to floats + */ + // ------------------------------------------------------------------------ + class _RealData { + PointerOf _floatData; + public: + //!< return pointer to float array + const float* values() { return _floatData; } + + //!< convert nbValues to floats + template + _RealData(const T* data, int nbValues) + { + if ( sizeof( T ) == sizeof( float )) + _floatData.set((const float*) data); + else { + _floatData.set(nbValues); + float* floatPtr = _floatData; + const T *tPtr = data, *tEnd = data + nbValues; + while ( tPtr < tEnd ) + *floatPtr++ = _toFloat( *tPtr++ ); + } + } + + //!< convert nbValues to floats in given interlace + template + _RealData(vector< TValueIterator >& componentIt, + const int nbValues, + const medModeSwitch interlace) + { + int nbComponents = componentIt.size(); + _floatData.set(nbValues * nbComponents); + float* floatPtr = _floatData; + if ( interlace == MED_FULL_INTERLACE && nbComponents > 1 ) { + for ( int i = 0; i < nbValues; ++i ) + for ( int j = 0; j < nbComponents; ++j ) + *floatPtr++ = _toFloat( componentIt[ j ].next() ); + } + else { + for ( int j = 0; j < nbComponents; ++j ) { + TValueIterator & values = componentIt[ j ]; + for ( int i = 0; i < nbValues; ++i ) + *floatPtr++ = _toFloat( values.next() ); + } + } + } + }; // class _RealData + +}; // class _BinaryFileWriter + +}// namespace MEDMEM_ENSIGHT + +#endif diff --git a/src/MEDMEM/MEDMEM_Exception.cxx b/src/MEDMEM/MEDMEM_Exception.cxx index 473aba560..89613a343 100644 --- a/src/MEDMEM/MEDMEM_Exception.cxx +++ b/src/MEDMEM/MEDMEM_Exception.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // /* File MedException.cxx @@ -42,11 +44,11 @@ extern "C" char* duplicate( const char *const str ) ; char* duplicate( const char *const str ) { - ASSERT(str!=NULL) ; + ASSERT_MED(str!=NULL) ; const size_t length = strlen( str ) ; - ASSERT(length>0) ; + ASSERT_MED(length>0) ; char *new_str = new char[ 1+length ] ; - ASSERT(new_str) ; + ASSERT_MED(new_str) ; strcpy( new_str , str ) ; return new_str ; } @@ -58,8 +60,8 @@ char* duplicate( const char *const str ) MEDEXCEPTION::MEDEXCEPTION( void ): exception() , _text(0) // ------------------------------------------------------ // { - MESSAGE( "You must user the standard builder : MEDEXCEPTION::MEDEXCEPTION( const char *text )" ) ; - INTERRUPTION(1) ; + MESSAGE_MED( "You must user the standard builder : MEDEXCEPTION::MEDEXCEPTION( const char *text )" ) ; + INTERRUPTION_MED(1) ; } @@ -73,7 +75,7 @@ char *makeText( const char *text, const char *fileName, const unsigned int lineN { char *newText = 0 ; - ASSERT(text) ; + ASSERT_MED(text) ; const size_t l1 = strlen(text) ; const char* prefix = "MED Exception" ; @@ -83,13 +85,13 @@ char *makeText( const char *text, const char *fileName, const unsigned int lineN { const size_t l2 = strlen(fileName) ; - ASSERT(lineNumber>=1) ; + ASSERT_MED(lineNumber>=1) ; const size_t l3 = 1+int(log10(float(lineNumber))) ; const size_t l4 = l0+l1+l2+l3+10+1 ; newText = new char [ l4 ] ; sprintf( newText , "%s in %s [%u] : %s" , prefix, fileName, lineNumber, text ) ; - ASSERT(newText[l4-1] == '\0' ); + ASSERT_MED(newText[l4-1] == '\0' ); } else @@ -97,7 +99,7 @@ char *makeText( const char *text, const char *fileName, const unsigned int lineN newText = new char [ l0+l1+3+1 ] ; sprintf( newText , "%s : %s" , prefix, text ) ; } - ASSERT(newText) ; + ASSERT_MED(newText) ; return newText ; } @@ -112,7 +114,7 @@ MEDEXCEPTION::MEDEXCEPTION( const char *text, const char *fileName, const unsign exception(), _text( makeText( text , fileName , lineNumber ) ) // ------------------------------------------------------------------------------------------------ // { - MESSAGE(_text); + MESSAGE_MED(_text); } /*! @@ -129,7 +131,7 @@ MEDEXCEPTION::~MEDEXCEPTION() throw () delete [] _text ; _text = 0 ; } - ASSERT(_text==NULL) ; + ASSERT_MED(_text==NULL) ; } diff --git a/src/MEDMEM/MEDMEM_Exception.hxx b/src/MEDMEM/MEDMEM_Exception.hxx index 8e243f7ef..62aa1e342 100644 --- a/src/MEDMEM/MEDMEM_Exception.hxx +++ b/src/MEDMEM/MEDMEM_Exception.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // /* File MedException.hxx @@ -44,7 +46,7 @@ using namespace std; */ namespace MEDMEM { class MEDEXCEPTION; - ostream & operator<< (ostream &os, const MEDEXCEPTION &ex ); + MEDMEM_EXPORT ostream & operator<< (ostream &os, const MEDEXCEPTION &ex ); //--------------------------------------// class MEDMEM_EXPORT MEDEXCEPTION : public std::exception //--------------------------------------// @@ -79,6 +81,6 @@ public : ~MED_DRIVER_NOT_FOUND_EXCEPTION() throw(); }; -}; +} #endif /* MEDEXCEPTION_HXX */ diff --git a/src/MEDMEM/MEDMEM_Extractor.cxx b/src/MEDMEM/MEDMEM_Extractor.cxx new file mode 100644 index 000000000..e2d1ee5df --- /dev/null +++ b/src/MEDMEM/MEDMEM_Extractor.cxx @@ -0,0 +1,1573 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +// File : MEDMEM_Extractor.cxx +// Created : Thu Dec 18 11:10:11 2008 +// Author : Edward AGAPOV (eap) + +#include "MEDMEM_Extractor.hxx" + +#include +#include +#include +#include + +#include + +#include + +using namespace MED_EN; +using namespace std; +using namespace MEDMEM; + +namespace { // local tools + + const int _POLYGON = -1; //!< map key to store connectivity of polygons + + const double _TOLER = 1e-12; + + //================================================================================ + /*! + * \brief calculate cross product of two vectors + */ + void crossProduct(const double* v1, const double* v2, double* res) + { + res[0] = v1[1] * v2[2] - v1[2] * v2[1]; + res[1] = v1[2] * v2[0] - v1[0] * v2[2]; + res[2] = v1[0] * v2[1] - v1[1] * v2[0]; + } + //================================================================================ + /*! + * \brief calculate dot product of two vectors + */ + double dotProduct(const double* v1, const double* v2) + { + return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; + } + //================================================================================ + /*! + * \brief SUPPORT owning the mesh + */ + struct TSupport : public SUPPORT + { + TSupport(MESH* mesh): SUPPORT(mesh) {} + ~TSupport() { delete getMesh(); setMeshDirectly((MESH*)0); } + }; + //================================================================================ + /*! + * \brief Field owning the support + */ + struct TField: public FIELD + { + TField( const SUPPORT * Support, int nbComp ): FIELD( Support, nbComp ) {} + ~TField() { if ( _support ) delete _support; _support = (SUPPORT*)0; } + }; + //================================================================================ + /*! + * \brief Accessor to some ids. Provides operator[] and more-next access methods + */ + class TIter + { + const int *_cur, *_end; + public: + TIter(const int* start, const int* end):_cur(start), _end(end) {} + TIter(const int* start, int nb):_cur(start), _end(start+nb) {} + int size() const { return _end - _cur; } + int operator[] (int i) const { return _cur[i]; } + bool more() const { return _cur < _end; } + int next() { return *_cur++; } + const int* begin() const { return _cur; } + const int* end() const { return _end; } + }; + //================================================================================ + /*! + * \brief Edge linking two nodes, used to find equal edges and store edges in std containers + */ + struct TEdge: public pair + { + TEdge(const int n1=0, const int n2=0): pair(n1,n2) + { if ( n2 < n1 ) first = n2, second = n1; } + TEdge(const TIter& nodes, int i ) + { *this = TEdge( nodes[i], nodes[ (i+1)%nodes.size() ]); } + int node1() const { return first; } + int node2() const { return second; } + }; + //================================================================================ + /*! + * \brief Tool providing iteration on edges of the cell of given classical type + */ + struct TEdgeIterator + { + vector* _edges; + TEdgeIterator(const medGeometryElement type); + int getNbEdges() const { return _edges->size(); } + TEdge getEdge(int i, const int* cellConn ) const + { return TEdge( cellConn[(*_edges)[i].node1()], cellConn[(*_edges)[i].node2()]); } + TEdge getEdge(int i, const TIter& cellNodes ) const + { return TEdge( cellNodes[(*_edges)[i].node1()], cellNodes[(*_edges)[i].node2()]); } + }; + //================================================================================ + /*! + * \brief Comparator used to sort nodes of polygon + */ + struct TNodeCompare + { + const double* _coords; //!< coordinates of mesh nodes in full interlace + const double* _bc; //!< polygon barycentre + int _i1, _i2; //!< indices of two ordinates used to compare points + + TNodeCompare(const double* nodeCoords, int i1, int i2): + _coords(nodeCoords),_i1(i1),_i2(i2) {} + + void setBaryCenter(const double* bc) { _bc = bc; } + + bool operator()(const int pt1, const int pt2) { + const double* p1 = _coords + 3*(pt1-1); + const double* p2 = _coords + 3*(pt2-1); + // calculate angles of Op1 and Op2 with the i1 axis on plane (i1,i2) + double ang1 = atan2(p1[_i1] - _bc[0], p1[_i2] - _bc[1]); + double ang2 = atan2(p2[_i1] - _bc[0], p2[_i2] - _bc[1]); + return ang1 > ang2; + } + }; + //================================================================================ + /*! + * \brief Return tolerance to consider nodes coincident + */ + double getTolerance(const MESH* mesh ) + { + vector< vector > bb = mesh->getBoundingBox(); + double diagonal = 0; + for ( int j = 0; j < mesh->getSpaceDimension(); ++j ) { + double dist = bb[0][j] - bb[1][j]; + diagonal += dist*dist; + } + return sqrt( diagonal ) * 1e-7; + } + //================================================================================ + /*! + * \brief Line data and some methods + */ + struct TLine + { + const double* _dir; + const double* _coord; + int _maxDir; //!< index of maximal coordinate of _dir + TLine( const double* dir, const double* coord): _dir(dir), _coord(coord) { + _maxDir = 0; + if ( fabs( _dir[_maxDir] ) < fabs( _dir[1] )) _maxDir = 1; + if ( fabs( _dir[_maxDir] ) < fabs( _dir[2] )) _maxDir = 2; + } + //!< Check if intersection points coincide in _maxDir direction + bool isSame( const double* p1, const double* p2 ) const { + return fabs(p1[_maxDir] - p2[_maxDir]) < _TOLER; + } + }; + //================================================================================ + /*! + * \brief Result of transfixing a face + * + * TIntersection's make up a chain via _prevSection field. Depending on whether + * _prevSection is NULL or not, there are two types of TIntersection: + * . _prevSection == NULL: TIntersection ending the chain. It is TIntersection from + * which chain building starts. + * . _prevSection != NULL: intermediate TIntersection, stores cells cut by a result segment. + */ + struct TIntersection + { + double _point[3]; //!< coordinates of itersection + set _cells; //!< intersected cells + int _face; //!< intersected face of a cell + set _startNodes; //!< nodes around which to look for next intersection + TIntersection* _prevSection; //!< neighbor intersection + + TIntersection(): _face(-1), _prevSection(NULL) + {} + ~TIntersection() { + if ( _prevSection ) delete _prevSection; _prevSection=0; + } + void getRange( double& min, double& max, const int j ) const { + if ( _point[j] < min ) min = _point[j]; + if ( _point[j] > max ) max = _point[j]; + if ( _prevSection ) _prevSection->getRange( min, max, j ); + } + void reverse() { + if ( _prevSection ) { + _prevSection->reverse(); + _prevSection->_cells = _cells; + _prevSection->_prevSection = this; + _prevSection = NULL; + } + } + int size() const { return 1 + ( _prevSection ? _prevSection->size() : 0 ); } + }; + //================================================================================ + /*! + * \brief Provider of comfortable access to connectivity data of MESH + */ + struct TMeshData + { + int _dim; + double _tolerance; + const double* _coord; + const int* _cellConn; + const int* _cellConnIndex; + const int* _faceConn; + const int* _faceConnIndex; + const int* _face2Cell; + const int* _face2CellIndex; + const int* _cell2Face; + const int* _cell2FaceIndex; + const int* _node2Cell; + const int* _node2CellIndex; + TMeshData(const MESH &mesh) + { + _tolerance = getTolerance(&mesh); + _dim = mesh.getSpaceDimension(); + _coord = mesh.getCoordinates(MED_FULL_INTERLACE); + _cellConn = mesh.getConnectivity(MED_FULL_INTERLACE, MED_NODAL, + MED_CELL, MED_ALL_ELEMENTS); + _cellConnIndex = mesh.getConnectivityIndex(MED_NODAL, MED_CELL); + _cell2Face = mesh.getConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, + MED_CELL, MED_ALL_ELEMENTS); + _cell2FaceIndex = mesh.getConnectivityIndex( MED_DESCENDING, MED_CELL ); + _face2Cell = mesh.getReverseConnectivity( MED_DESCENDING ); + _face2CellIndex = mesh.getReverseConnectivityIndex( MED_DESCENDING ); + _faceConn = mesh.getConnectivity(MED_FULL_INTERLACE, MED_NODAL, + MED_FACE, MED_ALL_ELEMENTS); + _faceConnIndex = mesh.getConnectivityIndex(MED_NODAL, MED_FACE); + _node2Cell = mesh.getReverseConnectivity( MED_NODAL ); + _node2CellIndex = mesh.getReverseConnectivityIndex( MED_NODAL ); + } + double tolerance() const { + return _tolerance; } + const double* getNodeCoord( int node ) const { + return _coord + _dim*(node-1); } + TIter getFaces( int cell ) const { + return TIter( _cell2Face+_cell2FaceIndex[cell-1]-1, _cell2Face+_cell2FaceIndex[cell]-1 ); } + TIter getCellNodes( int cell ) const { + return TIter( _cellConn+_cellConnIndex[cell-1]-1, _cellConn+_cellConnIndex[cell]-1 ); } + TIter getFaceNodes( int face ) const { + face = abs(face); + return TIter( _faceConn+_faceConnIndex[face-1]-1, _faceConn+_faceConnIndex[face]-1 ); } + TIter getCellsByNode( int node ) const { + return TIter( _node2Cell+_node2CellIndex[node-1]-1, _node2Cell+_node2CellIndex[node]-1 ); } + TIter getCellsByFace( int face ) const { + face = abs(face); + return TIter( _face2Cell+_face2CellIndex[face-1]-1, _face2Cell+_face2CellIndex[face]-1 ); } + int isFreeFace( int face ) const { + TIter cells = getCellsByFace( face ); + return ( cells[1] == 0 ) ? cells[0] : 0; } + }; + //================================================================================ + /*! + * \brief Calculates face normal + * \retval bool - false if face has zero area + */ + bool calcFaceNormal( const int face, + const TMeshData& meshData, + double* norm) + { + TIter nodes = meshData.getFaceNodes( face ); + bool zeroArea = false; + int i = 0; + do { + const double* p1 = meshData.getNodeCoord( nodes[i] ); + const double* p2 = meshData.getNodeCoord( nodes[i+1] ); + const double* p3 = meshData.getNodeCoord( nodes[i+2] ); + double p2p1[3] = { p1[0]-p2[0], p1[1]-p2[1], p1[2]-p2[2] }; + double p2p3[3] = { p3[0]-p2[0], p3[1]-p2[1], p3[2]-p2[2] }; + crossProduct( p2p3, p2p1, norm ); + double normSize2 = dotProduct( norm, norm ); + zeroArea = (normSize2 < DBL_MIN); + } + while ( zeroArea && i < 2 ); + return zeroArea; + } + //================================================================================ + /*! + * \brief Fill set of cells sharing edge + */ + void getCellsSharingEdge( const TEdge& edge, const TMeshData& meshData, set & theCells ) + { + TIter cells = meshData.getCellsByNode( edge.node1() ); + while ( cells.more() ) { + int cell = cells.next(); + TIter nodes = meshData.getCellNodes( cell ); + TEdgeIterator edgeIter( medGeometryElement( 300 + nodes.size() )); + for ( int i = 0, nb = edgeIter.getNbEdges(); i < nb; ++i ) { + TEdge e = edgeIter.getEdge( i , nodes ); + if ( edge == e ) { + theCells.insert( cell ); + break; + } + } + } + } + bool canIntersect(const int cell, + const TMeshData& meshData, + const TLine& line); + + TIntersection* intersect(const int cell, + const TMeshData& meshData, + const TLine& line, + set& checkedCells, + TIntersection* prevInter=0); + +} // noname namespace + +namespace MEDMEM +{ + + //================================================================================ + /*! + * \brief Creates a tool + * \param inputField - input field + * + * The input field is supposed to comply with following conditions
    + *
  • it is constant by element (i.e. has 1 gauss point),
  • + *
  • it's support mesh does not contain poly elements,
  • + *
  • volumic elements have planar faces,
  • + *
  • surfasic elements have linear edges.
+ */ + //================================================================================ + +Extractor::Extractor(const FIELD& inputField) throw (MEDEXCEPTION) +: _myInputField( & inputField ) +{ + const char* LOC = "Extractor::Extractor(inputField) :"; + + // Check if the input field complies with the conditions + + if ( !inputField.getSupport() ) + throw MEDEXCEPTION(STRING(LOC) << "InputField has NULL support"); + + medEntityMesh entity = inputField.getSupport()->getEntity(); + if ( entity == MED_NODE || entity == MED_EDGE ) + throw MEDEXCEPTION(STRING(LOC) << "InputField has invalid supporting entity"); + + if ( inputField.getSupport()->getNumberOfElements(MED_ALL_ELEMENTS) == 0 ) + throw MEDEXCEPTION(STRING(LOC) << "InputField has support of zero size"); + + if ( inputField.getGaussPresence() && inputField.getNumberOfGaussPoints()[0] > 1 ) + throw MEDEXCEPTION(STRING(LOC) << "InputField is not constant be element"); + + MESH* mesh = inputField.getSupport()->getMesh(); + if ( !mesh ) + throw MEDEXCEPTION(STRING(LOC) << "InputField has support with NULL mesh"); + + if ( mesh->getSpaceDimension() < 2 ) + throw MEDEXCEPTION(STRING(LOC) << "InputField with 1D support not acceptable"); + + if ( mesh->getNumberOfPolygons() > 0 || + mesh->getNumberOfPolyhedron() > 0 ) + throw MEDEXCEPTION(STRING(LOC) << "InputField has supporting mesh with poly elements"); + + if ( mesh->getConnectivityptr()->getEntityDimension() < 2 ) + throw MEDEXCEPTION(STRING(LOC) << "Invalid entity dimension of connectivity"); +} + +//================================================================================ + /*! + * \brief Creates a field by cutting inputField by a plane + * \param coords - give a point to pass through by the plane + * \param normal - gives the plane normal + * \retval FIELD* - resulting field holding ownership of its support, + * which in its turn holds ownership of its mesh + * + * If the plane does not intersect the field, NULL is returned. + */ +//================================================================================ + +FIELD* Extractor::extractPlane(const double* coords, const double* normal) + throw (MEDEXCEPTION) +{ + const char* LOC = "Extractor::extractPlane(const double* coords, const double* normal) :"; + + // check agrument validity + if ( !coords || !normal ) + throw MEDEXCEPTION(STRING(LOC) << "NULL argument"); + + double normalSize = sqrt(normal[0]*normal[0] + normal[1]*normal[1] + normal[2]*normal[2]); + if ( normalSize <= DBL_MIN ) + throw MEDEXCEPTION(STRING(LOC) << "normal has zero size"); + + if ( _myInputField->getSupport()->getMesh()->getSpaceDimension() < 3 ) + throw MEDEXCEPTION(STRING(LOC) << "Extraction by plane is possible in 3D space only "); + + double norm[3] = { normal[0] / normalSize, normal[1] / normalSize, normal[2] / normalSize }; + + // cut mesh + map > new2oldCells; + MESH* mesh = divideEdges( coords, norm, new2oldCells ); + if ( !mesh ) return 0; + + return makeField( new2oldCells, mesh ); +} + +//================================================================================ + /*! + * \brief Creates a field by cutting inputField by a line + * \param coords - give a point to pass through by the line + * \param direction - gives a vector collinear to the line + * \retval FIELD* - resulting field holding ownership of its support, + * which in its turn holds ownership of its mesh + * + * If the line does not intersect the field, NULL is returned. + */ +//================================================================================ + +FIELD* Extractor::extractLine(const double* coords, const double* direction) + throw (MEDEXCEPTION) +{ + const char* LOC = "Extractor::extractLine(const double* coords, const double* direction) :"; + + // check agrument validity + if ( !coords || !direction ) + throw MEDEXCEPTION(STRING(LOC) << "NULL argument"); + + double directionSize = + sqrt(direction[0]*direction[0] + direction[1]*direction[1] + direction[2]*direction[2]); + if ( directionSize <= DBL_MIN ) + throw MEDEXCEPTION(STRING(LOC) << "direction has zero size"); + + const SUPPORT* support = _myInputField->getSupport(); + const medGeometryElement* inTypes = support->getTypes(); + const int meshDim = inTypes[ support->getNumberOfTypes()-1 ] / 100; + + if ( meshDim == 2 && support->getMesh()->getSpaceDimension() == 3 ) + throw MEDEXCEPTION(STRING(LOC) << "Extraction from 2D mesh not supported"); + + map > new2oldCells; + MESH* mesh = 0; + if ( meshDim == 2 ) + { + double norm[2] = { direction[1] / directionSize, + direction[0] / directionSize, }; + // cut mesh + mesh = divideEdges( coords, norm, new2oldCells ); + } + else + { + double dir[3] = { direction[0] / directionSize, + direction[1] / directionSize, + direction[2] / directionSize }; + mesh = transfixFaces( coords, dir, new2oldCells ); + } + + if ( !mesh ) return 0; + + return makeField( new2oldCells, mesh ); +} + +//================================================================================ +/*! + * \brief Creates a new field and fill it from the input one + * \param new2oldCells - mapping of new to old cells + * \retval FIELD* - resulting field + */ +//================================================================================ + +FIELD* Extractor::makeField( const map >& new2oldCells, + MESH* mesh ) const +{ + // make new field + int nbComp = _myInputField->getNumberOfComponents(); + FIELD * outField = new TField( new TSupport( mesh ), nbComp ); + double* outValues = const_cast( outField->getValue() ); + + outField->setComponentsNames ( _myInputField->getComponentsNames() ); + outField->setName ( STRING("Extracted from ")<< _myInputField->getName() ); + outField->setDescription ( STRING("Created by MEDMEM::Extractor")); + outField->setComponentsDescriptions( _myInputField->getComponentsDescriptions() ); + outField->setMEDComponentsUnits ( _myInputField->getMEDComponentsUnits() ); + + + // put values to the new field + map >::const_iterator new_olds, noEnd = new2oldCells.end(); + for ( new_olds = new2oldCells.begin(); new_olds != noEnd; ++new_olds ) + { + for ( int j = 0; j < nbComp; ++j ) + { + int ind = ( new_olds->first - 1 ) * nbComp + j; + outValues[ ind ] = 0.0; + set::const_iterator inCells = new_olds->second.begin(); + set::const_iterator inEnd = new_olds->second.end(); + for ( ; inCells != inEnd; ++inCells ) + outValues[ ind ] += _myInputField->getValueIJ( *inCells, j+1 ); + + outValues[ ind ] /= new_olds->second.size(); + } + } + return outField; +} + +//================================================================================ +/*! + * \brief Makes a mesh by dividing edges of cells of the input mesh by plane + * in 3D or by line in 2D. + * \param coords - give a point to pass through by the plane or the line + * \param normal - gives the normal to plane or line + * \param new2oldCells - output map of new cells to cut input cell + */ +//================================================================================ + +MESH* Extractor::divideEdges(const double* coords, + const double* normal, + map >& new2oldCells) +{ + const char* LOC = "Extractor::divideEdges()"; + + const SUPPORT* support = _myInputField->getSupport(); + medEntityMesh entity = support->getEntity(); + MESH* inMesh = support->getMesh(); + const medGeometryElement* inTypes = support->getTypes(); + + const int* inConn = inMesh->getConnectivity(MED_FULL_INTERLACE, MED_NODAL, + entity, MED_ALL_ELEMENTS); + const int* inConnIndex = inMesh->getConnectivityIndex(MED_NODAL, entity); + const int spaceDim = inMesh->getSpaceDimension(); + const int meshDim = inTypes[ support->getNumberOfTypes()-1 ] / 100; + + + // connectivity of new cells by nb of nodes per cell + map< int, vector< int > > newConnByNbNodes; + int nbInputCells = support->getNumberOfElements( MED_ALL_ELEMENTS ); + int minNbNodesPerCell = 2, maxNbNodesPerCell = 2; + if ( meshDim == 3 ) { + newConnByNbNodes[ 3 ].reserve( nbInputCells/2 ); + newConnByNbNodes[ 4 ].reserve( nbInputCells/2 ); + minNbNodesPerCell = 3; + maxNbNodesPerCell = int (MED_POLYGON); // polygones allowed + } + else { + newConnByNbNodes[ 2 ].reserve( nbInputCells/2 ); + } + list nbNodesPerPolygon; // to make connectivity index of polygons + + // new cells + map< set, int> oldNodes2newCell; //!< map connectivity of all old nodes to new cell id + + // new nodes + map< TEdge, int > cutEdge2newNodeId; // ids of nodes located between extremities of old edge + map< int, int > oldNode2newNodeId; // ids of nodes coincident with old node + + // tolerance + double tol = getTolerance( inMesh ); + + + // ---------------------------------------------- + // compute distances of nodes from plane or line + // ---------------------------------------------- + + computeDistanceOfNodes(coords, normal); + + + // ---------- + // Cut edges + // ---------- + + int inCell = 0; + for ( int iType = 0; iType < support->getNumberOfTypes(); ++iType) // loop on geom types + { + medGeometryElement type = inTypes[ iType ]; + TEdgeIterator edges( type ); + + const int* inCells = 0; + if ( !support->isOnAllElements() ) + inCells = support->getNumber( type ); + + int nbInputCells = support->getNumberOfElements( type ); // loop on cells + for ( int i = 0; i < nbInputCells; ++i ) + { + int oldCell = inCells ? inCells[i] : ++inCell; + const int* cellConn = inConn + (inConnIndex[ oldCell-1 ] - 1); + + // Nodes of new mesh are either coincide with input nodes or lay on + // edges cut by plane. If at least one edge of a cell is cut in the middle + // then there will be the new cell, if the plane pass only through nodes of + // input cell then the new cell is not necessarily created. + + set oldNodes, newNodes; //!< cut old nodes, new nodes on edges + int nbEdgesOnPlane = 0; + for ( int iEdge = 0; iEdge < edges.getNbEdges(); ++iEdge ) // loop on cell edges + { + // Analyse edge position in relation to the cutting plane or line + const TEdge& edge = edges.getEdge( iEdge, cellConn ); + double dist1 = _myNodeDistance[ edge.node1()-1 ]; + double dist2 = _myNodeDistance[ edge.node2()-1 ]; + bool n1OnPlane = fabs( dist1 ) < tol; + bool n2OnPlane = fabs( dist2 ) < tol; + if ( n1OnPlane ) + oldNodes.insert( edge.node1() ); + if ( n2OnPlane ) + oldNodes.insert( edge.node2() ); + else if ( !n1OnPlane && dist1 * dist2 < 0 ) { + // edge intersected + int newNode = cutEdge2newNodeId.size() + oldNode2newNodeId.size() + 1; + int node = cutEdge2newNodeId.insert( make_pair( edge, newNode )).first->second; + newNodes.insert( node ); + } + nbEdgesOnPlane += int( n1OnPlane && n2OnPlane ); + } + int nbNodesInNewCell = oldNodes.size() + newNodes.size(); + if ( nbNodesInNewCell > maxNbNodesPerCell ) + throw MEDEXCEPTION(STRING(LOC) << "invalid input mesh"); + + if ( nbNodesInNewCell >= minNbNodesPerCell ) + { + // Associate new and old cells + int newCell = new2oldCells.size() + 1; + // detect equal new cells on boundaries of old cells + if ( newNodes.empty() && oldNodes.size() == nbEdgesOnPlane + int(meshDim==2)) { + pair < map< set, int>::iterator, bool > it_unique = + oldNodes2newCell.insert( make_pair( oldNodes, newCell )); + if ( !it_unique.second ) { // equal new faces + int equalNewCell = it_unique.first->second; + new2oldCells[ equalNewCell ].insert( oldCell ); + continue; + } + } + set& oldCells = // add a set of old cells to the end of new2oldCells + new2oldCells.insert( new2oldCells.end(), make_pair(newCell, set()))->second; + oldCells.insert( oldCell ); + + // Store nodes + vector< int >& connectivity = + nbNodesInNewCell>4 ? newConnByNbNodes[_POLYGON] : newConnByNbNodes[nbNodesInNewCell]; + // nodes at edge intersection + set::iterator n, nEnd; + for ( n = newNodes.begin(), nEnd = newNodes.end(); n != nEnd; ++n ) + { + connectivity.push_back( *n ); + } + // nodes coincident with input nodes + for ( n = oldNodes.begin(), nEnd = oldNodes.end(); n != nEnd; ++n ) + { + int newNode = cutEdge2newNodeId.size() + oldNode2newNodeId.size() + 1; + int node = oldNode2newNodeId.insert( make_pair( *n, newNode )).first->second; + connectivity.push_back( node ); + } + if ( nbNodesInNewCell>4 ) + nbNodesPerPolygon.push_back( nbNodesInNewCell ); + } + } // loop on cells, cutting thier edges + + } // loop on geom types of input mesh + + + // ----------------- + // Make coordinates + // ----------------- + + int nbNodes = cutEdge2newNodeId.size() + oldNode2newNodeId.size(); + vector< double > resCoords( nbNodes * spaceDim ); + + const double* inCoords = inMesh->getCoordinates(MED_FULL_INTERLACE); + + // nodes in the middle of edges + map< TEdge, int >::iterator edge_node, enEnd = cutEdge2newNodeId.end(); + for ( edge_node = cutEdge2newNodeId.begin(); edge_node != enEnd; ++edge_node ) + { + int newNode = edge_node->second; + const TEdge& edge = edge_node->first; + + double* nodeCoords = & resCoords[ spaceDim * ( newNode-1 )]; + const double* n1Coords = inCoords + spaceDim * ( edge.node1()-1 ); + const double* n2Coords = inCoords + spaceDim * ( edge.node2()-1 ); + + double dist1 = _myNodeDistance[ edge.node1()-1 ]; + double dist2 = _myNodeDistance[ edge.node2()-1 ]; + double r1 = dist1 / ( dist1 - dist2 ); + + for ( int j = 0 ; j < spaceDim; ++j ) + nodeCoords[ j ] = ( 1.-r1 ) * n1Coords[ j ] + r1 * n2Coords[ j ]; + } + + // nodes coincident with input nodes + map< int, int >::iterator old_newNode, onEnd = oldNode2newNodeId.end(); + const size_t size = size_t( sizeof(double)*spaceDim ); + for ( old_newNode = oldNode2newNodeId.begin(); old_newNode != onEnd; ++old_newNode ) + { + double* newCoords = & resCoords[ spaceDim * ( old_newNode->second - 1 )]; + const double* oldCoords = inCoords + spaceDim * ( old_newNode->first - 1 ); + memcpy( newCoords, oldCoords, size ); + } + + // -------------------- + // Sort nodes of cells + // -------------------- + + sortNodes( newConnByNbNodes, &resCoords[0], coords, normal, nbNodesPerPolygon ); + + // ---------- + // Make mesh + // ---------- + + // count classical types + vector< medGeometryElement > types; + vector< int > nbCellByType; + map< int, vector< int > >::iterator nbNoConn, ncEnd =newConnByNbNodes.end(); + for ( nbNoConn = newConnByNbNodes.begin(); nbNoConn != ncEnd; ++nbNoConn ) + { + int nbNodesPerCell = nbNoConn->first; + int connSize = nbNoConn->second.size(); + if ( nbNodesPerCell >= 2 && nbNodesPerCell <= 4 && connSize > 0 ) { + nbCellByType.push_back( connSize / nbNodesPerCell ); + types.push_back( medGeometryElement( (meshDim-1)*100 + nbNodesPerCell )); + } + } + if ( types.empty() && newConnByNbNodes[_POLYGON].empty() ) + return 0; + + MESHING* meshing = new MESHING(); + + meshing->setName(STRING("Cut of ") << inMesh->getName()); + meshing->setNumberOfTypes( types.size(), MED_CELL ); + meshing->setCoordinates( spaceDim, nbNodes, & resCoords[0], + inMesh->getCoordinatesSystem(), MED_FULL_INTERLACE ); + meshing->setTypes( &types[0], MED_CELL ); + meshing->setNumberOfElements( &nbCellByType[0], MED_CELL); + for ( int i = 0; i < types.size(); ++i ) + meshing->setConnectivity( & newConnByNbNodes[ types[i]%100 ].front(), MED_CELL, types[i]); + meshing->setMeshDimension( spaceDim /*meshDim-1*/ ); + + // polygons + if ( !newConnByNbNodes[_POLYGON].empty() ) + { + // make index + vector index; + index.reserve( newConnByNbNodes[_POLYGON].size() / 5 ); + index.push_back( 1 ); + list::iterator nbNodes = nbNodesPerPolygon.begin(), nnEnd = nbNodesPerPolygon.end(); + for ( ; nbNodes != nnEnd; ++nbNodes ) + index.push_back( index.back() + *nbNodes ); + + meshing->setPolygonsConnectivity( & index[0], + & newConnByNbNodes[_POLYGON][0], + index.size()-1, + MED_CELL ); + } + return meshing; +} + +//================================================================================ +/*! + * \brief computes distance of each node from the plane or the line given by point and normal + */ +//================================================================================ + +void Extractor::computeDistanceOfNodes(const double* point, + const double* normal) +{ + const MESH* mesh = _myInputField->getSupport()->getMesh(); + const double * coord = mesh->getCoordinates(MED_FULL_INTERLACE); + const int spaceDim = mesh->getSpaceDimension(); + + _myNodeDistance.resize(mesh->getNumberOfNodes()); + + // compute dot product: normal * Vec(point,node) + for ( int i = 0; i < mesh->getNumberOfNodes(); ++i ) + { + _myNodeDistance[i] = 0.0; + for ( int j = 0; j < spaceDim; ++j, ++coord ) + { + _myNodeDistance[i] += normal[j] * (*coord - point[j]); + } + } +} + +//================================================================================ +/*! + * \brief Orient elements correctly and sort nodes of polygons + * \param connByNbNodes - map of nb of nodes per cell to cell connectivity to rearrange + * \param nodeCoords - coordinates of nodes of a new mesh in full interlace + * \param point - point on plane or line + * \param normal - normal to plane or line + * \param nbNodesPerPolygon - index of connByNbNodes[_POLYGON] connectivity + */ +//================================================================================ + +void Extractor::sortNodes( map< int, vector< int > >& connByNbNodes, + const double* nodeCoords, + const double* point, + const double* normal, + const list & nbNodesPerPolygon) +{ + const int spaceDim = _myInputField->getSupport()->getMesh()->getSpaceDimension(); + + if ( !connByNbNodes[2].empty() ) // 1D mesh + { + vector< int > & conn = connByNbNodes[2]; + if ( spaceDim == 2 ) + { + // Orient edges along an coordinate axis, + // select ordinate to check + int ind = (fabs(normal[0]) < fabs(normal[1])) ? 1 : 0; + // sorting + for ( int i = 0; i < conn.size(); i += 2) { + const double* p1 = nodeCoords + spaceDim*(conn[i]-1); + const double* p2 = nodeCoords + spaceDim*(conn[i+1]-1); + if ( p1[ind] > p2[ind] ) + std::swap( conn[i], conn[i+1] ); + } + } + else + { + // Reverse if necessary adjacent edges if they have equal nodes + if ( conn.size() > 2 ) { + if ( conn[0] == conn[2] || conn[0] == conn[3] ) + std::swap( conn[0], conn[1] ); + int i; + for ( i = 2; i < conn.size()-2; i += 2) { + if ( conn[i-1] == conn[i+1] ) + std::swap( conn[i], conn[i+1] ); + else if ( conn[i] == conn[i+2] || conn[i] == conn[i+3] ) + std::swap( conn[i], conn[i+1] ); + } + if ( conn[i+1] == conn[i-1] ) + std::swap( conn[i], conn[i+1] ); + } + } + return; + } + + // Fix order of nodes + + // select two ordinates for sorting + int i1 = 0, i2 = 1, i3 = 2; + if ( fabs( normal[i1] ) > fabs( normal[i3] )) swap( i1, i3 ); + if ( fabs( normal[i2] ) > fabs( normal[i3] )) swap( i2, i3 ); + + // comparator of nodes + TNodeCompare nodeCompare( nodeCoords, i1, i2 ); + + map< int, vector< int > >::iterator nbN_conn = connByNbNodes.begin(); + for ( ; nbN_conn != connByNbNodes.end(); ++nbN_conn ) + { + if ( nbN_conn->second.empty() ) continue; + + int * conn = & nbN_conn->second[0]; + int * connEnd = conn + nbN_conn->second.size(); + + int nbNodesPerFace = nbN_conn->first; + list::const_iterator nbPolyNodes, npEnd = nbNodesPerPolygon.end(); + + for ( nbPolyNodes = nbNodesPerPolygon.begin(); conn != connEnd; conn += nbNodesPerFace ) + { + if ( nbPolyNodes != npEnd ) + nbNodesPerFace = *nbPolyNodes++; + + // Sort nodes of polygons and quadrangles + + if ( nbNodesPerFace > 3 ) + { + // get barycenter + double bary[2] = { 0., 0. }; + for ( int i = 0; i < nbNodesPerFace; ++i ) { + const double* coord = nodeCoords + spaceDim*(conn[i]-1); + bary[0] += coord[i1]; bary[1] += coord[i2]; + } + bary[0] /= nbNodesPerFace; bary[1] /= nbNodesPerFace; + nodeCompare.setBaryCenter( bary ); + + // sorting + std::sort( conn, conn + nbNodesPerFace, nodeCompare); + } + + // Fix orientation of faces, orient them to have thier normal collinear with plane normal + + // calculate cross product of two adjacent segments + double dot = 0.; + int i = 0; + do { + const double* p1 = nodeCoords + spaceDim*(conn[i+0]-1); + const double* p2 = nodeCoords + spaceDim*(conn[i+1]-1); + const double* p3 = nodeCoords + spaceDim*(conn[i+2]-1); + double p2p1[2] = { p1[i1]-p2[i1] , p1[i2]-p2[i2] }; + double p2p3[2] = { p3[i1]-p2[i1] , p3[i2]-p2[i2] }; + dot = p2p3[1] * p2p1[0] - p2p3[0] * p2p1[1]; + ++i; + } + while ( dot == 0. && i+2 < nbNodesPerFace ); + + if ( dot * normal[i3] < 0. ) + std::reverse( conn, conn + nbNodesPerFace ); + } + } +} +//================================================================================ +/*! + * \brief Makes a 1D mesh by transfixing faces of 3D cells of input mesh by the line + * \param coords - give a point to pass through by the line + * \param direction - direction of the line + * \param new2oldCells - output map of new cells to cut input cell + */ +//================================================================================ + +MESH* Extractor::transfixFaces( const double* coords, + const double* direction, + map >& new2oldCells) +{ + MESH* inMesh = _myInputField->getSupport()->getMesh(); + TMeshData inMeshData( *inMesh ); + TLine line( direction, coords ); + + const int nbFaces = inMesh->getNumberOfElements( MED_FACE, MED_ALL_ELEMENTS ); + const int dim = 3; + + // Intersect 1st domain + + vector< TIntersection*> chains; + vector< pair< double, double > > ranges; + int nbSegments = 0; // in the future mesh + + set checkedCells; + checkedCells.insert(0); // 0 is returned by getCellsByFace() for boundary faces + + int face = 1; + for ( ; face <= nbFaces; ++face ) { + if ( int soleCell = inMeshData.isFreeFace( face )) + if ( checkedCells.insert(soleCell).second && + canIntersect( soleCell, inMeshData, line )) + if ( TIntersection* chain = intersect( soleCell, inMeshData, line, checkedCells )) { + chains.push_back( chain ); + double min = DBL_MAX, max = -DBL_MAX; + chain->getRange( min, max, line._maxDir ); + ranges.push_back( make_pair( min, max )); + nbSegments += chain->size() - 1; + break; + } + } + if ( chains.empty() ) + return 0; + + // Intersect the rest domains + + for ( ; face <= nbFaces; ++face ) { + if ( int soleCell = inMeshData.isFreeFace( face )) + if ( checkedCells.insert(soleCell).second) + { + // check if at least one node of face is out of ranges of found chains + TIter nodes = inMeshData.getFaceNodes( face ); + bool isOut = false; + while ( nodes.more() && !isOut ) { + double coord = inMeshData.getNodeCoord( nodes.next() )[ line._maxDir ]; + bool isIn = false; + for ( int i = 0; i < ranges.size() && !isIn; ++i ) { + const pair< double, double > & minMax = ranges[i]; + isIn = ( minMax.first < coord && coord < minMax.second ); + } + isOut = !isIn; + } + // try to intersect + if ( isOut && canIntersect( soleCell, inMeshData, line )) + if ( TIntersection* chain = intersect( soleCell, inMeshData, line, checkedCells )) { + chains.push_back( chain ); + double min = DBL_MAX, max = -DBL_MAX; + chain->getRange( min, max, line._maxDir ); + ranges.push_back( make_pair( min, max )); + nbSegments += chain->size() - 1; + } + } + } + + // Fill mesh data + + int nbNodes = nbSegments + chains.size(); + vector< double > resCoords( nbNodes * dim ); + vector< int > resConn; resConn.reserve( nbSegments * 2 ); + + int iNode = 1, iSeg = 1; + double* coord = & resCoords[0]; + const size_t cooSize = size_t( sizeof(double)*dim ); + + for ( int i = 0; i < chains.size(); ++i ) { + TIntersection* section = chains[i]; + while ( section ) { + memcpy( coord, section->_point, cooSize ); + coord += dim; + if ( section->_prevSection ) { + resConn.push_back( iNode++ ); + resConn.push_back( iNode ); + new2oldCells[ iSeg++ ] = section->_cells; + } + section = section->_prevSection; + } + iNode++; + delete chains[i]; + } + + // Create mesh + + MESHING* meshing = new MESHING(); + + meshing->setName(STRING("Cut of ") << inMesh->getName()); + meshing->setNumberOfTypes( 1, MED_CELL ); + //meshing->setMeshDimension( dim ); + meshing->setCoordinates( dim, nbNodes, &resCoords[0], + inMesh->getCoordinatesSystem(), MED_FULL_INTERLACE ); + meshing->setTypes( &MED_SEG2, MED_CELL ); + meshing->setNumberOfElements( &nbSegments, MED_CELL); + meshing->setConnectivity( & resConn[0], MED_CELL, MED_SEG2); + meshing->setMeshDimension( dim ); + + return meshing; +} + +} // namespace MEDMEM + + +//================================================================================ +/*! + * \brief Constructs TEdgeIterator on given classical cell type + */ +//================================================================================ + +TEdgeIterator::TEdgeIterator(const medGeometryElement type) +{ + static map< medGeometryElement, vector* > _edgesByType; + if ( _edgesByType.empty() ) { + _edges = _edgesByType[ MED_TRIA3 ] = _edgesByType[ MED_TRIA6 ] = new vector(); + _edges->reserve( 3 ); + _edges->push_back( TEdge( 0, 1 )); + _edges->push_back( TEdge( 1, 2 )); + _edges->push_back( TEdge( 2, 0 )); + _edges = _edgesByType[ MED_QUAD4 ] = _edgesByType[ MED_QUAD8 ] = new vector(); + _edges->reserve( 4 ); + _edges->push_back( TEdge( 0, 1 )); + _edges->push_back( TEdge( 1, 2 )); + _edges->push_back( TEdge( 2, 3 )); + _edges->push_back( TEdge( 3, 0 )); + _edges = _edgesByType[ MED_TETRA4 ] = _edgesByType[ MED_TETRA10 ] = new vector(); + _edges->reserve( 6 ); + _edges->push_back( TEdge( 0, 1 )); + _edges->push_back( TEdge( 1, 2 )); + _edges->push_back( TEdge( 2, 0 )); + _edges->push_back( TEdge( 0, 3 )); + _edges->push_back( TEdge( 1, 3 )); + _edges->push_back( TEdge( 2, 3 )); + _edges = _edgesByType[ MED_HEXA8 ] = _edgesByType[ MED_HEXA20 ] = new vector(); + _edges->reserve( 12 ); + _edges->push_back( TEdge( 0, 1 )); + _edges->push_back( TEdge( 1, 2 )); + _edges->push_back( TEdge( 2, 3 )); + _edges->push_back( TEdge( 3, 0 )); + _edges->push_back( TEdge( 4, 5 )); + _edges->push_back( TEdge( 5, 6 )); + _edges->push_back( TEdge( 6, 7 )); + _edges->push_back( TEdge( 7, 4 )); + _edges->push_back( TEdge( 0, 4 )); + _edges->push_back( TEdge( 1, 5 )); + _edges->push_back( TEdge( 2, 6 )); + _edges->push_back( TEdge( 3, 7 )); + _edges = _edgesByType[ MED_PYRA5 ] = _edgesByType[ MED_PYRA13 ] = new vector(); + _edges->reserve( 8 ); + _edges->push_back( TEdge( 0, 1 )); + _edges->push_back( TEdge( 1, 2 )); + _edges->push_back( TEdge( 2, 3 )); + _edges->push_back( TEdge( 3, 0 )); + _edges->push_back( TEdge( 0, 4 )); + _edges->push_back( TEdge( 1, 4 )); + _edges->push_back( TEdge( 2, 4 )); + _edges->push_back( TEdge( 3, 4 )); + _edges = _edgesByType[ MED_PENTA6 ] = _edgesByType[ MED_PENTA15 ] = new vector(); + _edges->reserve( 9 ); + _edges->push_back( TEdge( 0, 1 )); + _edges->push_back( TEdge( 1, 2 )); + _edges->push_back( TEdge( 2, 0 )); + _edges->push_back( TEdge( 3, 4 )); + _edges->push_back( TEdge( 4, 5 )); + _edges->push_back( TEdge( 5, 3 )); + _edges->push_back( TEdge( 0, 4 )); + _edges->push_back( TEdge( 1, 5 )); + _edges->push_back( TEdge( 2, 3 )); + _edgesByType[ MED_NONE ] = 0; + _edgesByType[ MED_POINT1 ] = 0; + _edgesByType[ MED_SEG2 ] = 0; + _edgesByType[ MED_SEG3 ] = 0; + _edgesByType[ MED_POLYGON ] = 0; + _edgesByType[ MED_POLYHEDRA ] = 0; + _edgesByType[ MED_ALL_ELEMENTS ] = 0; + } + _edges = _edgesByType[type]; +} + +namespace { + +//================================================================================ +/*! + * \brief Transfixes a cell with a line. Returns a head of chain of intersections + * \param cell - cell id to transfixe + * \param meshData - input 3D mesh + * \param line - cutting line + * \param checkedCells - set of cell already tried + * \param prevInter - previosly found intersection. Used to build a chain of + * intersection via recursive call + */ +//================================================================================ + +TIntersection* intersect(const int cell, + const TMeshData& meshData, + const TLine& line, + set& checkedCells, + TIntersection* prevInter) +{ + TIntersection* newSection = 0; // section to find + TIntersection* auxSection = 0; // second section used when !prevInter + list< TIntersection > bndSections;// list of intersection on edges + + int avoidFace = prevInter ? prevInter->_face : -1; + + TIter faces = meshData.getFaces( cell ); + while ( faces.more() ) ///////// loop on faces of the cell + { + int face = abs( faces.next() ); + if ( face == avoidFace ) + continue; + TIter nodes = meshData.getFaceNodes( face ); + + // Get face normal + // ---------------- + + double faceNormal[3]; + bool zeroArea = calcFaceNormal( face, meshData, faceNormal ); + if ( zeroArea ) + continue; // next face + + // Is face parallel to line + // ------------------------- + + double dirDotNorm = dotProduct( line._dir, faceNormal ); + const double* pFace0 = meshData.getNodeCoord( nodes[0] ); + if ( fabs( dirDotNorm ) < _TOLER ) + { + // line || face, check if the line lays on the face + + double lf[3] = { line._coord[0] - pFace0[0], + line._coord[1] - pFace0[1], + line._coord[2] - pFace0[2] }; + double lfDotNorm = dotProduct( lf, faceNormal ); + if ( fabs( lfDotNorm ) < _TOLER ) + { + // ========================================================= + // Line lays on face. Intersect line with edges of the face + // ========================================================= + + // Calculate distance of nodes from the line + // ------------------------------------------ + double lineNormal[3]; + crossProduct( faceNormal, line._dir, lineNormal ); + vector dist( nodes.size(), 0.0 ); + for ( int n = 0; n < nodes.size(); ++n ) + { + const double* p = meshData.getNodeCoord( nodes[n] ); + for ( int j = 0; j < 3; ++j ) + dist[n] += lineNormal[j] * ( p[j] - line._coord[j] ); + } + // Find intersections + // ------------------- + vector pCoords; // intersection coordinates + set pAtNodes; // intersected nodes of the face + list cutEdges; // intersected edges + int nbPoints = 0; // nb intersections + pCoords.reserve(6); + for ( int n = 0; n < nodes.size() && nbPoints < 2; ++n ) + { + int n2 = (n+1) % nodes.size(); + double dist1 = dist[ n ]; + double dist2 = dist[ n2 ]; + bool n1OnLine = fabs( dist1 ) < meshData.tolerance(); + bool n2OnLine = fabs( dist2 ) < meshData.tolerance(); + if ( n1OnLine ) + pAtNodes.insert( nodes[n] ); + if ( n2OnLine ) + pAtNodes.insert( nodes[n2] ); + else if ( !n1OnLine && dist1 * dist2 < 0 ) { + const double* p1 = meshData.getNodeCoord( nodes[n] ); + const double* p2 = meshData.getNodeCoord( nodes[n2] ); + double r1 = dist1 / ( dist1 - dist2 ); + for ( int j = 0 ; j < 3; ++j ) + pCoords.push_back(( 1.-r1 ) * p1[ j ] + r1 * p2[ j ]); + cutEdges.push_back( TEdge( nodes[n], nodes[n2] )); + } + nbPoints = cutEdges.size() + pAtNodes.size(); + } + // coords of intersection are stored in pCoords in order: + // first go points on edges, then, points on nodes + if ( nbPoints == 2 && !pAtNodes.empty() ) { + set::iterator n = pAtNodes.begin(); + while ( pCoords.size() != 6 ) { // there must be coords of two points + const double* p = meshData.getNodeCoord( *n++ ); + for ( int j = 0 ; j < 3; ++j ) + pCoords.push_back( p[j] ); + } + } + // Store intersections + // -------------------- + if ( nbPoints == 2 ) + { + vector< TIntersection* > sections(nbPoints); + const double* intCoord = & pCoords[0]; + + for ( int i = 0; i < nbPoints; ++i, intCoord += 3 ) + { + // Set coords of intersection point + sections[i] = new TIntersection; + sections[i]->_point[0] = intCoord[0]; + sections[i]->_point[1] = intCoord[1]; + sections[i]->_point[2] = intCoord[2]; + + // Set intersected cells + if ( cutEdges.empty() ) { + // line can pass by edge shared by several cells + TEdge cutEdge( *pAtNodes.begin(), *pAtNodes.rbegin() ); + getCellsSharingEdge( cutEdge, meshData, sections[i]->_cells ); + } + if ( !cutEdges.empty() || sections[i]->_cells.empty() ) { + // line pass by face between two cells + TIter cells = meshData.getCellsByFace( face ); + while ( cells.more() ) + if ( int elem = cells.next() ) + sections[i]->_cells.insert( elem ); + } + // Not to check the face at next search + sections[i]->_face = face; + + // Set nodes to start search of next intersection from + if ( !cutEdges.empty() ) { + sections[i]->_startNodes.insert( cutEdges.front().node1() ); + sections[i]->_startNodes.insert( cutEdges.front().node2() ); + cutEdges.pop_front(); + } + else if ( pAtNodes.size() > 1 ) { + set::iterator p = pAtNodes.begin(); + if ( !line.isSame( intCoord, meshData.getNodeCoord( *p ))) + ++p; + sections[i]->_startNodes.insert( *p ); + pAtNodes.erase( p ); + } + else { + sections[i]->_startNodes.insert( *pAtNodes.begin() ); + } + } + if ( prevInter ) { + // Only one point is needed, exclude already found intersection + if ( line.isSame( prevInter->_point, sections[0]->_point )) + std::swap( sections[0], sections[1] ); + delete sections[1]; + sections[1] = 0; + } + newSection = sections[0]; + auxSection = sections[1]; + if ( auxSection ) + auxSection->_cells = newSection->_cells; + + bndSections.clear(); // remove already found intersections + + } // if ( nbPoints == 2 ) + + break; // from loop on faces of cell + + } // line lays on face + } + else + { + // ================================== + // Line intersects the plane of face + // ================================== + + // Find distance of intersection point from line origin + // t = faceNormal * ( pFace0 - line._coord ) / ( faceNormal * line._dir ) + + double pf0Coord[] = { pFace0[0] - line._coord[0], + pFace0[1] - line._coord[1], + pFace0[2] - line._coord[2] }; + double t = dotProduct( faceNormal, pf0Coord ) / dotProduct( faceNormal, line._dir ); + + // facePlane-line intersection point + double ip[] = { line._coord[0] + line._dir[0] * t, + line._coord[1] + line._dir[1] * t, + line._coord[2] + line._dir[2] * t}; + + if ( prevInter && line.isSame( ip, prevInter->_point )) + continue; + if ( !bndSections.empty() && line.isSame( ip, bndSections.back()._point )) + continue; + + // Check if intersection point (ip) is inside the face. + // ---------------------------------------------------- + + // do it in 2d, on the cartesian plane most normal to the face; + // find indices on that plane: i1, i2 + int i1 = 0, i2 = 1, i3 = 2; + if ( fabs( faceNormal[i1] ) > fabs( faceNormal[i3] )) swap( i1, i3 ); + if ( fabs( faceNormal[i2] ) > fabs( faceNormal[i3] )) swap( i2, i3 ); + if ( i2-i1 != 1 && i2 != 0 ) swap ( i1, i2 ); + + int inside = true, nbOnBoundary = 0; + TEdge cutEdge; + for ( int n = 0; n < nodes.size() && inside; ++n ) + { + const double* p0 = meshData.getNodeCoord( nodes[n] ); + const double* p1 = meshData.getNodeCoord( nodes[ (n+1) % nodes.size() ] ); + double sign = + faceNormal[i3]*((ip[i2] - p0[i2])*(p1[i1] - p0[i1]) - (ip[i1] - p0[i1])*(p1[i2] - p0[i2])); + if ( sign < -DBL_MIN ) + inside = false; + else if ( sign < DBL_MIN ) { + nbOnBoundary++; + cutEdge = TEdge( nodes, n ); + } + } + + // Store intersection point + // ------------------------- + if ( inside ) + { + TIntersection* section; + if ( !nbOnBoundary ) + section = new TIntersection; + else { + if ( bndSections.size() >= 2 ) + continue; // go to next face + bndSections.push_back( TIntersection() ); + section = & bndSections.back(); + // set nodes to start next searching from + if ( nbOnBoundary == 1 ) { + // edge is cut + section->_startNodes.insert( cutEdge.node1() ); + section->_startNodes.insert( cutEdge.node2() ); + } + else { // node is cut + const double* p1 = meshData.getNodeCoord( cutEdge.node1() ); + if ( fabs( ip[i1]-p1[i1] ) < _TOLER && fabs( ip[i2]-p1[i2] ) < _TOLER ) + section->_startNodes.insert( cutEdge.node1() ); + else + section->_startNodes.insert( cutEdge.node2() ); + } + } + section->_point[0] = ip[0]; + section->_point[1] = ip[1]; + section->_point[2] = ip[2]; + section->_face = face; + section->_cells.insert( cell ); + + if ( !nbOnBoundary ) + { + if ( !newSection ) + newSection = section; + else + auxSection = section; + if ( prevInter || auxSection ) { + bndSections.clear(); + break; // from loop on faces + } + } + } + } + } // loop on faces of cell + + // Care of intersections passing through edges + // -------------------------------------------- + + if ( !bndSections.empty() ) + { + if ( prevInter ) { // boundary section not equal to previous section + if ( !newSection ) + newSection = new TIntersection( bndSections.front() ); + } + else { + if ( !newSection ) { + newSection = new TIntersection( bndSections.front() ); + bndSections.pop_front(); + } + if ( !auxSection && !bndSections.empty() ) { + auxSection = new TIntersection( bndSections.front() ); + } + } + } + + // Find the rest of chain starting from the found sections + // -------------------------------------------------------- + + if ( newSection && ( prevInter || auxSection )) + { + TIntersection* chain[] = { newSection, auxSection }; + int chainLength[] = {0,0}; + for ( int i = 0; i < 2; ++i ) + { + TIntersection* section = chain[i]; + if ( !section ) continue; + // get cells to try to intersect next + set cellsToCheck; + if ( !section->_startNodes.empty() ) { + if ( section->_startNodes.size() == 1 ) { + TIter cells = meshData.getCellsByNode( *section->_startNodes.begin() ); + cellsToCheck.insert( cells.begin(), cells.end() ); + } + else { + TEdge cutEdge( *section->_startNodes.begin(), *section->_startNodes.rbegin() ); + getCellsSharingEdge( cutEdge, meshData, cellsToCheck ); + } + } + else { + TIter cells = meshData.getCellsByFace( section->_face ); + cellsToCheck.insert( cells.begin(), cells.end() ); + } + // find the rest intersections + chain[i] = 0; + set::iterator elem = cellsToCheck.begin(), elemEnd = cellsToCheck.end(); + for ( ; elem != elemEnd && !chain[i]; ++elem ) { + if ( checkedCells.insert( *elem ).second && + section->_cells.find( *elem ) == section->_cells.end() ) + { + chain[i] = intersect( *elem, meshData, line, checkedCells, section ); + } + } + if ( chain[i] ) + chainLength[i] = chain[i]->size(); + } + + // Connect just found sections into a chain + if ( prevInter ) { + newSection->_prevSection = prevInter; + } + else { + if ( chainLength[0] < chainLength[1] ) { + std::swap( chain[0], chain[1] ); + std::swap( newSection, auxSection ); + } + if ( chain[1] ) + chain[1]->reverse(); + newSection->_prevSection = auxSection; + } + + if ( chain[0] ) + return chain[0]; + return newSection; + } + else { + delete newSection; + } + + return 0; +} + +//================================================================================ +/*! + * \brief Evaluate if the line can intersect a cell + */ +//================================================================================ + +bool canIntersect(const int cell, + const TMeshData& meshData, + const TLine& line) +{ + // calculate bnd box of the cell + double min[] = { DBL_MAX,DBL_MAX,DBL_MAX }, max[] = { -DBL_MAX,-DBL_MAX,-DBL_MAX }; + + TIter cellNodes = meshData.getCellNodes( cell ); + for ( int n = 0; n < cellNodes.size(); ++n ) { + const double* node = meshData.getNodeCoord( cellNodes[n] ); + for ( int j = 0; j < 3; ++j ) { + if ( node[j] < min[j] ) min[j] = node[j]; + if ( node[j] > max[j] ) max[j] = node[j]; + } + } + double xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin, zmax; + double parmin, parmax, par1, par2; + bool xToSet, yToSet; + const double infinite = 1e100; + + if (fabs(line._dir[0])>0.) { + par1=(min[0]-line._coord[0])/line._dir[0]; + par2=(max[0]-line._coord[0])/line._dir[0]; + parmin=std::min(par1, par2); + parmax=std::max(par1, par2); + xToSet=true; + } + else { + if (line._coord[0]0.) { + par1=(min[1]-line._coord[1])/line._dir[1]; + par2=(max[1]-line._coord[1])/line._dir[1]; + if(parmax < std::min(par1,par2) || parmin > std::max(par1,par2)) + return false; + parmin=std::max(parmin, std::min(par1,par2)); + parmax=std::min(parmax, std::max(par1,par2)); + yToSet=true; + } + else { + if (line._coord[1]0.) { + par1=(min[2]-line._coord[2])/line._dir[2]; + par2=(max[2]-line._coord[2])/line._dir[2]; + if(parmax < std::min(par1,par2) || parmin > std::max(par1,par2)) + return false; + parmin=std::max(parmin, std::min(par1,par2)); + parmax=std::min(parmax, std::max(par1,par2)); + par1=line._coord[2]+parmin*line._dir[2]; + par2=line._coord[2]+parmax*line._dir[2]; + zmin=std::min(par1, par2); + zmax=std::max(par1, par2); + } + else { + if (line._coord[2] +#include +#include + +namespace MEDMEM +{ + /*! + * \brief Tool taking an input field and making a field of lower dimension + * by cutting the given field by a plane or a line. + * + * The following extractions are possible:
    + *
  • 3D -> 2D (3D mesh cut by plane)
  • + *
  • 3D -> 1D (3D mesh cut by line)
  • + *
  • 2D -> 1D (2D mesh cut by line in 2D space or by plane in 3D space)
+ */ + class Extractor + { + /*! + * \brief Creates a tool + * \param inputField - input field + * + * The input field is supposed to comply with following conditions
    + *
  • it is constant by element (i.e. has 1 gauss point),
  • + *
  • it's support mesh does not contain poly elements,
  • + *
  • volumic elements have planar faces,
  • + *
  • surfasic elements have linear edges.
+ */ + public: + Extractor(const FIELD& inputField) throw (MEDEXCEPTION); + + /*! + * \brief Creates a field by cutting inputField by a plane + * \param coords - give a point to pass through by the plane + * \param normal - gives the plane normal + * \retval FIELD* - resulting field holding ownership of its support, + * which in its turn holds ownership of its mesh + */ + FIELD* extractPlane(const double* coords, const double* normal) throw (MEDEXCEPTION); + + /*! + * \brief Creates a field by cutting inputField by a line + * \param coords - give a point to pass through by the line + * \param direction - gives a vector collinear to the line + * \retval FIELD* - resulting field holding ownership of its support, + * which in its turn holds ownership of its mesh + */ + FIELD* extractLine(const double* coords, const double* direction) throw (MEDEXCEPTION); + + private: + + MESH* divideEdges(const double* coords, + const double* normal, + std::map >& new2oldCells); + + MESH* transfixFaces( const double* coords, + const double* direction, + std::map >& new2oldCells); + + FIELD* makeField( const std::map >& new2oldCells, + MESH* mesh) const; + + void computeDistanceOfNodes(const double* point, const double* normal); + + void sortNodes( std::map< int, std::vector< int > >& connByNbNodes, + const double* nodeCoords, + const double* point, + const double* normal, + const std::list & nbNodesPerPolygon); + + + const FIELD* _myInputField; //!< input field + std::vector _myNodeDistance; //!< distance of input nodes to cutting tool + }; +} + +#endif diff --git a/src/MEDMEM/MEDMEM_Family.cxx b/src/MEDMEM/MEDMEM_Family.cxx index 45dd81714..cf0073c5e 100644 --- a/src/MEDMEM/MEDMEM_Family.cxx +++ b/src/MEDMEM/MEDMEM_Family.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // /* File MEDMEM_Family.cxx @@ -38,8 +40,8 @@ using namespace MED_EN; FAMILY::FAMILY():_identifier(0), _numberOfAttribute(0), _numberOfGroup(0) { - MESSAGE("FAMILY::FAMILY()"); -}; + MESSAGE_MED("FAMILY::FAMILY()"); +} FAMILY::FAMILY(MESH* Mesh, int Identifier, string Name, int NumberOfAttribute, int *AttributeIdentifier, int *AttributeValue, string AttributeDescription, @@ -53,34 +55,37 @@ FAMILY::FAMILY(MESH* Mesh, int Identifier, string Name, int NumberOfAttribute, _numberOfAttribute(NumberOfAttribute), _numberOfGroup(NumberOfGroup) { - MESSAGE("FAMILY(int Identifier, string Name, int NumberOfAttribute,int *AttributeIdentifier,int *AttributeValue,string AttributeDescription,int NumberOfGroup,string GroupName, int ** Number) : "< 0) { _attributeIdentifier.set(_numberOfAttribute,AttributeIdentifier); _attributeValue.set(_numberOfAttribute,AttributeValue); - _attributeDescription.set(_numberOfAttribute); + //_attributeDescription.set(_numberOfAttribute); + _attributeDescription.resize(_numberOfAttribute); for (int i=0;i0) { @@ -180,38 +185,37 @@ FAMILY::FAMILY(MESH* Mesh, int Identifier, string Name, int NumberOfAttribute, if (!Find) { _numberOfGeometricType = 0 ; _isOnAllElts = false ; - MESSAGE ("FAMILY() : No entity found !") ; + MESSAGE_MED ("FAMILY() : No entity found !") ; } - MESSAGE("Well now ??? :::"); + MESSAGE_MED("Well now ??? :::"); - MESSAGE("Name : "<< getName()); - MESSAGE("Description : "<< getDescription()); - MESSAGE("Mesh name : " << getMesh()->getName()); - MESSAGE("Entity : "<< getEntity()); - MESSAGE("Entity list :"); + MESSAGE_MED("Name : "<< getName()); + MESSAGE_MED("Description : "<< getDescription()); + MESSAGE_MED("Mesh name : " << getMesh()->getName()); + MESSAGE_MED("Entity : "<< getEntity()); + MESSAGE_MED("Entity list :"); if (!(isOnAllElements())) { - int numberoftypes = getNumberOfTypes() ; - MESSAGE("NumberOfTypes : "< int numberOfTypes = _mesh->getNumberOfTypesWithPoly(Entity) ; @@ -321,7 +330,7 @@ bool FAMILY::build(medEntityMesh Entity,int **FamilyNumber /* from MED file */) const int * GlobalNumberingIndex = _mesh->getGlobalNumberingIndex(Entity); - SCRUTE(numberOfTypes); + SCRUTE_MED(numberOfTypes); // we search for all elements in this family for (int TypeNumber=0; TypeNumber < numberOfTypes; TypeNumber++) { @@ -333,7 +342,7 @@ bool FAMILY::build(medEntityMesh Entity,int **FamilyNumber /* from MED file */) for (int i=0; igetNumberOfElementsWithPoly(Entity,MED_ALL_ELEMENTS) && Entity==MED_EN::MED_CELL) { + if (_totalNumberOfElements == + _mesh->getNumberOfElementsWithPoly(Entity,MED_ALL_ELEMENTS)/* && Entity==MED_EN::MED_CELL*/) { _isOnAllElts = true ; // all others attributs are rights ! for (int i=0; i<_numberOfGeometricType; i++) diff --git a/src/MEDMEM/MEDMEM_Family.hxx b/src/MEDMEM/MEDMEM_Family.hxx index 0c8a590b6..d464074ca 100644 --- a/src/MEDMEM/MEDMEM_Family.hxx +++ b/src/MEDMEM/MEDMEM_Family.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef FAMILY_HXX #define FAMILY_HXX @@ -35,8 +37,8 @@ */ namespace MEDMEM { class FAMILY; - ostream & operator<<(ostream &os, FAMILY &my); - ostream & operator<<(ostream &os, const FAMILY &my) ; + MEDMEM_EXPORT ostream & operator<<(ostream &os, FAMILY &my); + MEDMEM_EXPORT ostream & operator<<(ostream &os, const FAMILY &my) ; class MEDMEM_EXPORT FAMILY : virtual public SUPPORT { @@ -75,7 +77,8 @@ protected : There is one for each attribute. \endif */ - PointerOf _attributeDescription ; + //PointerOf _attributeDescription ; + vector _attributeDescription ; /*! \if developper Number of the group the family belongs to. @@ -87,7 +90,8 @@ protected : Name of the group the family belongs to. \endif */ - PointerOf _groupName ; + //PointerOf _groupName ; + vector _groupName ; public: /*! Constructor. */ @@ -116,9 +120,9 @@ public: /*! Destructor. */ virtual ~FAMILY(); FAMILY & operator=(const FAMILY &fam); - friend MEDMEM_EXPORT ostream & operator<<(ostream &os, FAMILY &my) ; + friend ostream & operator<<(ostream &os, FAMILY &my) ; - friend MEDMEM_EXPORT ostream & operator<<(ostream &os, const FAMILY &my) ; + friend ostream & operator<<(ostream &os, const FAMILY &my) ; bool build(MED_EN::medEntityMesh Entity,int **FamilyNumber); @@ -137,9 +141,9 @@ public: inline int getNumberOfAttributes() const; inline const int * getAttributesIdentifiers() const; inline const int * getAttributesValues() const; - inline const string * getAttributesDescriptions() const; + inline const string* getAttributesDescriptions() const; inline int getNumberOfGroups() const; - inline const string * getGroupsNames() const; + inline const string* getGroupsNames() const; // A FAIRE : VERIFIER LA VALIDITE DES PARAMETRES ! inline int getAttributeIdentifier(int i) const; @@ -188,8 +192,18 @@ inline void FAMILY::setAttributesValues(int * AttributeValue) inline void FAMILY::setAttributesDescriptions(string * AttributeDescription) //-------------------------------------------------------------------------- { - //_attributeDescription = AttributeDescription ; - _attributeDescription.setShallowAndOwnership(AttributeDescription) ; + //_attributeDescription = AttributeDescription ; + //_attributeDescription.setShallowAndOwnership(AttributeDescription) ; + int nbAttr = getNumberOfAttributes(); +// if(nbAttr<1) { +// std::string diagnosis; +// diagnosis="Can not set attributes descriptions - number of attributes is not set"; +// throw MEDMEM::MEDEXCEPTION(diagnosis.c_str()); +// } + _attributeDescription.resize(nbAttr); + for(int i=0; i +// if (giveOwnership) +// _groupName.setShallowAndOwnership(GroupName); +// else +// //_groupName = GroupName ; +// _groupName.set(_numberOfGroup, GroupName) ; + + int nbGr = getNumberOfGroups(); +// if(nbGr<1) { +// std::string diagnosis; +// diagnosis="Can not set groups names - number of groups is not set"; +// throw MEDMEM::MEDEXCEPTION(diagnosis.c_str()); +// } + if (giveOwnership) { + //_groupName.setShallowAndOwnership(GroupName); + _groupName.resize(nbGr); + for(int i=0; igetNumberOfElements(MED_ALL_ELEMENTS); - _componentsTypes = new int[NumberOfComponents] ; - _componentsNames = new string[NumberOfComponents]; - _componentsDescriptions = new string[NumberOfComponents]; - _componentsUnits = new UNIT[NumberOfComponents]; - _MEDComponentsUnits = new string[NumberOfComponents]; + //_componentsTypes = new int[NumberOfComponents] ; + //_componentsNames = new string[NumberOfComponents]; + //_componentsDescriptions = new string[NumberOfComponents]; + //_componentsUnits = new UNIT[NumberOfComponents]; + //_MEDComponentsUnits = new string[NumberOfComponents]; + _componentsTypes.resize(NumberOfComponents); + _componentsNames.resize(NumberOfComponents); + _componentsDescriptions.resize(NumberOfComponents); + _componentsUnits.resize(NumberOfComponents); + _MEDComponentsUnits.resize(NumberOfComponents); for(int i=0;i" ); } + /*!\if MEDMEM_ug @} \endif*/ + } //End namespace MEDMEM ///////////////////////// @@ -631,6 +855,7 @@ inline MED_EN::med_type_champ FIELD_::getValueType () const */ + namespace MEDMEM { template class MED_FIELD_RDONLY_DRIVER21; @@ -639,6 +864,7 @@ namespace MEDMEM { template class MED_FIELD_WRONLY_DRIVER22; template class VTK_FIELD_DRIVER; + template class FIELD : public FIELD_ @@ -659,6 +885,10 @@ protected: // array of value of type T Array *_value ; + // MESH, to be used for field reading from a file (if desired to link + // to existing support instead of new support creation for the field) + MESH* _mesh; + // extrema values T _vmin; T _vmax; @@ -669,8 +899,8 @@ protected: static T pow(T x); private: - void _operation(const FIELD& m,const FIELD& n, char* Op); - void _operationInitialize(const FIELD& m,const FIELD& n, char* Op); + void _operation(const FIELD& m,const FIELD& n, const char* Op); + void _operationInitialize(const FIELD& m,const FIELD& n, const char* Op); void _add_in_place(const FIELD& m,const FIELD& n); void _sub_in_place(const FIELD& m,const FIELD& n); void _mul_in_place(const FIELD& m,const FIELD& n); @@ -680,10 +910,11 @@ private: public: FIELD(); FIELD(const FIELD &m); - FIELD(const SUPPORT * Support, const int NumberOfComponents) throw (MEDEXCEPTION) ; - FIELD( driverTypes driverType, - const string & fileName, const string & fieldDriverName, - const int iterationNumber=-1, const int orderNumber=-1) + FIELD(const SUPPORT * Support, const int NumberOfComponents) throw (MEDEXCEPTION); + FIELD(driverTypes driverType, + const string & fileName, const string & fieldDriverName, + const int iterationNumber=-1, const int orderNumber=-1, + MESH* mesh = 0) throw (MEDEXCEPTION); FIELD(const SUPPORT * Support, driverTypes driverType, const string & fileName="", const string & fieldName="", @@ -692,7 +923,7 @@ public: ~FIELD(); FIELD & operator=(const FIELD &m); - + FIELD & operator=(T value); const FIELD operator+(const FIELD& m) const; const FIELD operator-(const FIELD& m) const; const FIELD operator*(const FIELD& m) const; @@ -702,6 +933,8 @@ public: FIELD& operator-=(const FIELD& m); FIELD& operator*=(const FIELD& m); FIELD& operator/=(const FIELD& m); + + void applyLin(T a, T b, int icomp); static FIELD* add(const FIELD& m, const FIELD& n); static FIELD* addDeep(const FIELD& m, const FIELD& n); static FIELD* sub(const FIELD& m, const FIELD& n); @@ -744,7 +977,7 @@ public: int addDriver(driverTypes driverType, const string & fileName="Default File Name.med", const string & driverFieldName="Default Field Name", - MED_EN::med_mode_acces access=MED_EN::MED_REMP) ; + MED_EN::med_mode_acces access=MED_EN::RDWR) ; int addDriver(GENDRIVER & driver); @@ -767,10 +1000,33 @@ public: inline bool getGaussPresence() const throw (MEDEXCEPTION); inline int getValueLength() const throw (MEDEXCEPTION); + + /*! \if MEDMEM_ug +\addtogroup FIELD_value +@{ +\endif */ + /*! Returns a pointer to the value array.*/ inline const T* getValue() const throw (MEDEXCEPTION); inline const T* getRow(int i) const throw (MEDEXCEPTION); inline const T* getColumn(int j) const throw (MEDEXCEPTION); +/*! + Returns the value of \f$ i^{th} \f$ element and \f$ j^{th}\f$ component. + This method only works with fields having no particular Gauss point +definition (i.e., fields having one value per element). + This method makes the retrieval of the value independent from the + interlacing pattern, but it is slower than the complete retrieval + obtained by the \b getValue() method. +*/ + inline T getValueIJ(int i,int j) const throw (MEDEXCEPTION); + +/*! + Returns the \f$ j^{th}\f$ component of \f$ k^{th}\f$ Gauss points of \f$ i^{th}\f$ value. + This method is compatible with elements having more than one Gauss point. + This method makes the retrieval of the value independent from the + interlacing pattern, but it is slower than the complete retrieval + obtained by the \b getValue() method. +*/ inline T getValueIJK(int i,int j,int k) const throw (MEDEXCEPTION); inline int getValueByTypeLength(int t) const throw (MEDEXCEPTION); @@ -778,6 +1034,13 @@ public: inline T getValueIJByType(int i,int j,int t) const throw (MEDEXCEPTION); inline T getValueIJKByType(int i,int j,int k,int t) const throw (MEDEXCEPTION); + /*! + The following example describes the creation of a FIELD. + + \example FIELDcreate.cxx + + \if MEDMEM_ug @} \endif */ + bool getValueOnElement(int eltIdInSup,T* retValues) const throw (MEDEXCEPTION); const int getNumberOfGeometricTypes() const throw (MEDEXCEPTION); @@ -794,10 +1057,27 @@ public: bool isOnAllElements() const throw (MEDEXCEPTION); inline void setArray(MEDMEM_Array_ *value) throw (MEDEXCEPTION); + + /*! \if MEDMEM_ug + \addtogroup FIELD_value +@{ +\endif + */ +/*! +This method makes it possible to have the field pointing to +an existing value array. The ordering of the elements in the value array must +conform to the MEDMEM ordering (I,K,J) : the outer loop is on the elements, +the intermediate loop is on the Gauss points, the inner loop is on +the components. +*/ inline void setValue( T* value) throw (MEDEXCEPTION); inline void setRow( int i, T* value) throw (MEDEXCEPTION); inline void setColumn( int i, T* value) throw (MEDEXCEPTION); +/*! + Sets the value of \f$ i^{th} \f$ element and \f$ j^{th}\f$ component with \a value. +*/ inline void setValueIJ(int i, int j, T value) throw (MEDEXCEPTION); + /*! \if MEDMEM_ug @} \endif */ inline void setValueIJK(int i, int j, int k, T value) throw (MEDEXCEPTION); inline void setValueIJByType(int i, int j, int t, T value) throw (MEDEXCEPTION); inline void setValueIJKByType(int i, int j, int k, int t, T value) throw (MEDEXCEPTION); @@ -810,7 +1090,7 @@ public: has be a SUPPORT on 3D cells. This initialisation could be done by the empty constructor followed by a setSupport and setNumberOfComponents call. */ - void getVolume() const throw (MEDEXCEPTION) ; + //void getVolume() const throw (MEDEXCEPTION) ; /*! This fonction feeds the FIELD private attributs _value with the area of each cells (or faces) belonging to the attribut _support. The field @@ -819,7 +1099,7 @@ public: SUPPORT on 2D cells or 3D faces. This initialisation could be done by the empty constructor followed by a setSupport and setNumberOfComponents call. */ - void getArea() const throw (MEDEXCEPTION) ; + //void getArea() const throw (MEDEXCEPTION) ; /*! This fonction feeds the FIELD private attributs _value with the length of each segments belonging to the attribut _support. The field has @@ -828,7 +1108,7 @@ public: SUPPORT on 3D edges or 2D faces. This initialisation could be done by the empty constructor followed by a setSupport and setNumberOfComponents call. */ - void getLength() const throw (MEDEXCEPTION) ; + //void getLength() const throw (MEDEXCEPTION) ; /*! This fonction feeds the FIELD private attributs _value with the normal vector of each faces belonging to the attribut _support. The field @@ -838,7 +1118,7 @@ public: by the empty constructor followed by a setSupport and setNumberOfComponents call. */ - void getNormal() const throw (MEDEXCEPTION) ; + //void getNormal() const throw (MEDEXCEPTION) ; /*! This fonction feeds the FIELD private attributs _value with the barycenter of each faces or cells or edges belonging to the attribut _support. @@ -848,7 +1128,7 @@ public: This initialisation could be done by the empty constructor followed by a setSupport and setNumberOfComponents call. */ - void getBarycenter() const throw (MEDEXCEPTION) ; + //void getBarycenter() const throw (MEDEXCEPTION) ; typedef void (*myFuncType)(const double *,T*); void fillFromAnalytic(myFuncType f) throw (MEDEXCEPTION); @@ -873,37 +1153,56 @@ template T FIELD::_scalarFor template FIELD::FIELD():FIELD_() { - MESSAGE("Constructeur FIELD sans parametre"); + MESSAGE_MED("Constructeur FIELD sans parametre"); //INITIALISATION DE _valueType DS LE CONSTRUCTEUR DE FIELD_ - ASSERT(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE); + ASSERT_MED(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE); FIELD_::_valueType=SET_VALUE_TYPE::_valueType; //INITIALISATION DE _interlacingType DS LE CONSTRUCTEUR DE FIELD_ - ASSERT(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE); + ASSERT_MED(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE); FIELD_::_interlacingType=SET_INTERLACING_TYPE::_interlacingType; _value = ( ArrayNoGauss * ) NULL; } + /*! +\addtogroup FIELD_constructors FIELD constructors +@{ + */ + /*! - Constructor with parameters such that all attrribut are set but the _value - attribut is allocated but not set. + Constructor that allocates the value array with the dimensions provided by +\a NumberOfComponents and the dimension of \a Support. The value array is + allocated but not initialized. +This constructor does not allow the creation of fields with Gauss points. +\param Support support on which the field lies +\param NumberOfComponents number of components of the variable stored. For instance, +it will be 3 for a (vx,vy,vz) vector. + +\code +FIELD field (support, 3); +int nbelem = support->getNumberOfElements(MED_ALL_ELEMENTS); +for (int i=1; i<=nbelem; i++) + for (j=1; j<=3;j++) + field->setValueIJ(i,j,0.0); +\endcode */ template FIELD::FIELD(const SUPPORT * Support, - const int NumberOfComponents) throw (MEDEXCEPTION) : + const int NumberOfComponents) throw (MEDEXCEPTION) : FIELD_(Support, NumberOfComponents),_value(NULL) { - BEGIN_OF("FIELD::FIELD(const SUPPORT * Support, const int NumberOfComponents)"); - SCRUTE(this); + const char* LOC = "FIELD::FIELD(const SUPPORT * Support, const int NumberOfComponents)"; + BEGIN_OF_MED(LOC); + SCRUTE_MED(this); //INITIALISATION DE _valueType DS LE CONSTRUCTEUR DE FIELD_ - ASSERT(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE) + ASSERT_MED(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE) FIELD_::_valueType=SET_VALUE_TYPE::_valueType; //INITIALISATION DE _interlacingType DS LE CONSTRUCTEUR DE FIELD_ - ASSERT(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE) + ASSERT_MED(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE) FIELD_::_interlacingType=SET_INTERLACING_TYPE::_interlacingType; try { @@ -915,17 +1214,19 @@ FIELD::FIELD(const SUPPORT * Support, #else catch (MEDEXCEPTION ) { #endif - MESSAGE("No value defined ! ("<::FIELD(const SUPPORT * Support, const int NumberOfComponents)"); + END_OF_MED(LOC); } - + /*! +@} + */ /*! \if developper \endif @@ -940,7 +1241,7 @@ template void FIELD::init ( template FIELD::FIELD(const FIELD & m): FIELD_((FIELD_) m) { - MESSAGE("Constructeur FIELD de recopie"); + MESSAGE_MED("Constructeur FIELD de recopie"); // RECOPIE PROFONDE <> de l'operateur= Rmq from EF if (m._value != NULL) @@ -972,7 +1273,7 @@ template FIELD::FIELD(const template FIELD & FIELD::operator=(const FIELD &m) { - MESSAGE("Appel de FIELD::operator=") ; + MESSAGE_MED("Appel de FIELD::operator=") ; if ( this == &m) return *this; // copy values array @@ -994,6 +1295,25 @@ FIELD & FIELD::operator=(const FIELD &m) return *this; } +/*! + Initializes all the field values to \a value +*/ +template +FIELD & FIELD::operator=(T value) +{ + MESSAGE_MED("Appel de FIELD::operator= T") ; + int size=getNumberOfComponents()*getNumberOfValues(); + T* ptr= const_cast( getValue()); + for (int i=0; i< size; i++) + {*ptr++=value;} + + return *this; +} + +/*!\addtogroup FIELD_algo +@{ +*/ + /*! Overload addition operator. This operation is authorized only for compatible fields that have the same support. @@ -1017,7 +1337,8 @@ FIELD & FIELD::operator=(const FIELD &m) template const FIELD FIELD::operator+(const FIELD & m) const { - BEGIN_OF("FIELD::operator+(const FIELD & m)"); + const char* LOC = "FIELD::operator+(const FIELD & m)"; + BEGIN_OF_MED(LOC); FIELD_::_checkFieldCompatibility(*this, m); // may throw exception // Creation of the result - memory is allocated by FIELD constructor @@ -1026,7 +1347,7 @@ const FIELD FIELD::operator+(const FIELD result._operationInitialize(*this,m,"+"); // perform Atribute's initialization result._add_in_place(*this,m); // perform addition - END_OF("FIELD::operator+(const FIELD & m)"); + END_OF_MED(LOC); return result; } @@ -1037,7 +1358,8 @@ const FIELD FIELD::operator+(const FIELD template FIELD& FIELD::operator+=(const FIELD & m) { - BEGIN_OF("FIELD::operator+=(const FIELD & m)"); + const char* LOC = "FIELD::operator+=(const FIELD & m)"; + BEGIN_OF_MED(LOC); FIELD_::_checkFieldCompatibility(*this, m); // may throw exception const T* value1=m.getValue(); // get pointers to the values we are adding @@ -1048,7 +1370,7 @@ FIELD& FIELD::operator+=(const FIELD & m const T* endV=value+size; // pointer to the end of value for(;value!=endV; value1++,value++) *value += *value1; - END_OF("FIELD::operator+=(const FIELD & m)"); + END_OF_MED(LOC); return *this; } @@ -1061,7 +1383,8 @@ FIELD& FIELD::operator+=(const FIELD & m template FIELD* FIELD::add(const FIELD& m, const FIELD& n) { - BEGIN_OF("FIELD::add(const FIELD & m, const FIELD& n)"); + const char* LOC = "FIELD::add(const FIELD & m, const FIELD& n)"; + BEGIN_OF_MED(LOC); FIELD_::_checkFieldCompatibility(m, n); // may throw exception // Creation of a new field @@ -1070,7 +1393,7 @@ FIELD* FIELD::add(const FIELD& m, const result->_operationInitialize(m,n,"+"); // perform Atribute's initialization result->_add_in_place(m,n); // perform addition - END_OF("FIELD::add(const FIELD & m, const FIELD& n)"); + END_OF_MED(LOC); return result; } @@ -1079,7 +1402,8 @@ FIELD* FIELD::add(const FIELD& m, const template FIELD* FIELD::addDeep(const FIELD& m, const FIELD& n) { - BEGIN_OF("FIELD::addDeep(const FIELD & m, const FIELD& n)"); + const char* LOC = "FIELD::addDeep(const FIELD & m, const FIELD& n)"; + BEGIN_OF_MED(LOC); FIELD_::_deepCheckFieldCompatibility(m, n); // may throw exception // Creation of a new field @@ -1088,7 +1412,7 @@ FIELD* FIELD::addDeep(const FIELD& m, co result->_operationInitialize(m,n,"+"); // perform Atribute's initialization result->_add_in_place(m,n); // perform addition - END_OF("FIELD::addDeep(const FIELD & m, const FIELD& n)"); + END_OF_MED(LOC); return result; } @@ -1115,7 +1439,8 @@ FIELD* FIELD::addDeep(const FIELD& m, co template const FIELD FIELD::operator-(const FIELD & m) const { - BEGIN_OF("FIELD::operator-(const FIELD & m)"); + const char* LOC = "FIELD::operator-(const FIELD & m)"; + BEGIN_OF_MED(LOC); FIELD_::_checkFieldCompatibility(*this, m); // may throw exception // Creation of the result - memory is allocated by FIELD constructor @@ -1124,14 +1449,15 @@ const FIELD FIELD::operator-(const FIELD result._operationInitialize(*this,m,"-"); // perform Atribute's initialization result._sub_in_place(*this,m); // perform substracion - END_OF("FIELD::operator-(const FIELD & m)"); + END_OF_MED(LOC); return result; } template const FIELD FIELD::operator-() const { - BEGIN_OF("FIELD::operator-()"); + const char* LOC = "FIELD::operator-()"; + BEGIN_OF_MED(LOC); // Creation of the result - memory is allocated by FIELD constructor FIELD result(this->getSupport(),this->getNumberOfComponents()); @@ -1154,7 +1480,7 @@ const FIELD FIELD::operator-() const for(;value!=endV; value1++,value++) *value = -(*value1); - END_OF("FIELD::operator-=(const FIELD & m)"); + END_OF_MED(LOC); return result; } @@ -1165,7 +1491,8 @@ const FIELD FIELD::operator-() const template FIELD& FIELD::operator-=(const FIELD & m) { - BEGIN_OF("FIELD::operator-=(const FIELD & m)"); + const char* LOC = "FIELD::operator-=(const FIELD & m)"; + BEGIN_OF_MED(LOC); FIELD_::_checkFieldCompatibility(*this, m); // may throw exception const T* value1=m.getValue(); @@ -1178,11 +1505,32 @@ FIELD& FIELD::operator-=(const FIELD & m for(;value!=endV; value1++,value++) *value -= *value1; - END_OF("FIELD::operator-=(const FIELD & m)"); + END_OF_MED(LOC); return *this; } + +/*! Apply to a given field component the linear function x -> ax+b. + * calculation is done "in place". + */ +template void FIELD::applyLin(T a, T b, int icomp) +{ + // get a non const pointer to the inside array of values and perform operation in place + T * value=const_cast (getValue()); + + const int size=getNumberOfValues()*getNumberOfComponents(); // size of array + + if (size>0) // for a negative size, there is nothing to do + { + value+=icomp-1; + const T* lastvalue=value+size; // pointer to the end of value + + for(;value!=lastvalue; value+=getNumberOfComponents()) // apply linear transformation + *value = a*(*value)+b; + } +} + /*! Substraction of fields. Static member function. * The function return a pointer to a new created field that holds the substraction. * Data members are checked for compatibility and initialized. @@ -1191,7 +1539,8 @@ FIELD& FIELD::operator-=(const FIELD & m template FIELD* FIELD::sub(const FIELD& m, const FIELD& n) { - BEGIN_OF("FIELD::sub(const FIELD & m, const FIELD& n)"); + const char* LOC = "FIELD::sub(const FIELD & m, const FIELD& n)"; + BEGIN_OF_MED(LOC); FIELD_::_checkFieldCompatibility(m, n); // may throw exception // Creation of a new field @@ -1200,7 +1549,7 @@ FIELD* FIELD::sub(const FIELD& m, const result->_operationInitialize(m,n,"-"); // perform Atribute's initialization result->_sub_in_place(m,n); // perform substraction - END_OF("FIELD::sub(const FIELD & m, const FIELD& n)"); + END_OF_MED(LOC); return result; } @@ -1209,7 +1558,8 @@ FIELD* FIELD::sub(const FIELD& m, const template FIELD* FIELD::subDeep(const FIELD& m, const FIELD& n) { - BEGIN_OF("FIELD::subDeep(const FIELD & m, const FIELD& n)"); + const char* LOC = "FIELD::subDeep(const FIELD & m, const FIELD& n)"; + BEGIN_OF_MED(LOC); FIELD_::_deepCheckFieldCompatibility(m, n); // may throw exception // Creation of a new field @@ -1218,7 +1568,7 @@ FIELD* FIELD::subDeep(const FIELD& m, co result->_operationInitialize(m,n,"-"); // perform Atribute's initialization result->_sub_in_place(m,n); // perform substraction - END_OF("FIELD::subDeep(const FIELD & m, const FIELD& n)"); + END_OF_MED(LOC); return result; } @@ -1245,7 +1595,8 @@ FIELD* FIELD::subDeep(const FIELD& m, co template const FIELD FIELD::operator*(const FIELD & m) const { - BEGIN_OF("FIELD::operator*(const FIELD & m)"); + const char* LOC = "FIELD::operator*(const FIELD & m)"; + BEGIN_OF_MED(LOC); FIELD_::_checkFieldCompatibility(*this, m, false); // may throw exception // Creation of the result - memory is allocated by FIELD constructor @@ -1254,7 +1605,7 @@ const FIELD FIELD::operator*(const FIELD result._operationInitialize(*this,m,"*"); // perform Atribute's initialization result._mul_in_place(*this,m); // perform multiplication - END_OF("FIELD::operator*(const FIELD & m)"); + END_OF_MED(LOC); return result; } @@ -1265,7 +1616,8 @@ const FIELD FIELD::operator*(const FIELD template FIELD& FIELD::operator*=(const FIELD & m) { - BEGIN_OF("FIELD::operator*=(const FIELD & m)"); + const char* LOC = "FIELD::operator*=(const FIELD & m)"; + BEGIN_OF_MED(LOC); FIELD_::_checkFieldCompatibility(*this, m, false); // may throw exception const T* value1=m.getValue(); @@ -1278,7 +1630,7 @@ FIELD& FIELD::operator*=(const FIELD & m for(;value!=endV; value1++,value++) *value *= *value1; - END_OF("FIELD::operator*=(const FIELD & m)"); + END_OF_MED(LOC); return *this; } @@ -1291,7 +1643,8 @@ FIELD& FIELD::operator*=(const FIELD & m template FIELD* FIELD::mul(const FIELD& m, const FIELD& n) { - BEGIN_OF("FIELD::mul(const FIELD & m, const FIELD& n)"); + const char* LOC = "FIELD::mul(const FIELD & m, const FIELD& n)"; + BEGIN_OF_MED(LOC); FIELD_::_checkFieldCompatibility(m, n, false); // may throw exception // Creation of a new field @@ -1300,7 +1653,7 @@ FIELD* FIELD::mul(const FIELD& m, const result->_operationInitialize(m,n,"*"); // perform Atribute's initialization result->_mul_in_place(m,n); // perform multiplication - END_OF("FIELD::mul(const FIELD & m, const FIELD& n)"); + END_OF_MED(LOC); return result; } @@ -1309,7 +1662,8 @@ FIELD* FIELD::mul(const FIELD& m, const template FIELD* FIELD::mulDeep(const FIELD& m, const FIELD& n) { - BEGIN_OF("FIELD::mulDeep(const FIELD & m, const FIELD& n)"); + const char* LOC = "FIELD::mulDeep(const FIELD & m, const FIELD& n)"; + BEGIN_OF_MED(LOC); FIELD_::_deepCheckFieldCompatibility(m, n, false); // may throw exception // Creation of a new field @@ -1318,7 +1672,7 @@ FIELD* FIELD::mulDeep(const FIELD& m, co result->_operationInitialize(m,n,"*"); // perform Atribute's initialization result->_mul_in_place(m,n); // perform multiplication - END_OF("FIELD::mulDeep(const FIELD & m, const FIELD& n)"); + END_OF_MED(LOC); return result; } @@ -1345,7 +1699,8 @@ FIELD* FIELD::mulDeep(const FIELD& m, co template const FIELD FIELD::operator/(const FIELD & m) const { - BEGIN_OF("FIELD::operator/(const FIELD & m)"); + const char* LOC = "FIELD::operator/(const FIELD & m)"; + BEGIN_OF_MED(LOC); FIELD_::_checkFieldCompatibility(*this, m, false); // may throw exception // Creation of the result - memory is allocated by FIELD constructor @@ -1354,7 +1709,7 @@ const FIELD FIELD::operator/(const FIELD result._operationInitialize(*this,m,"/"); // perform Atribute's initialization result._div_in_place(*this,m); // perform division - END_OF("FIELD::operator/(const FIELD & m)"); + END_OF_MED(LOC); return result; } @@ -1366,7 +1721,8 @@ const FIELD FIELD::operator/(const FIELD template FIELD& FIELD::operator/=(const FIELD & m) { - BEGIN_OF("FIELD::operator/=(const FIELD & m)"); + const char* LOC = "FIELD::operator/=(const FIELD & m)"; + BEGIN_OF_MED(LOC); FIELD_::_checkFieldCompatibility(*this, m, false); // may throw exception const T* value1=m.getValue(); // get pointers to the values we are adding @@ -1379,7 +1735,7 @@ FIELD& FIELD::operator/=(const FIELD & m for(;value!=endV; value1++,value++) *value /= *value1; - END_OF("FIELD::operator/=(const FIELD & m)"); + END_OF_MED(LOC); return *this; } @@ -1392,7 +1748,8 @@ FIELD& FIELD::operator/=(const FIELD & m template FIELD* FIELD::div(const FIELD& m, const FIELD& n) { - BEGIN_OF("FIELD::div(const FIELD & m, const FIELD& n)"); + const char* LOC = "FIELD::div(const FIELD & m, const FIELD& n)"; + BEGIN_OF_MED(LOC); FIELD_::_checkFieldCompatibility(m, n, false); // may throw exception // Creation of a new field @@ -1401,7 +1758,7 @@ FIELD* FIELD::div(const FIELD& m, const result->_operationInitialize(m,n,"/"); // perform Atribute's initialization result->_div_in_place(m,n); // perform division - END_OF("FIELD::div(const FIELD & m, const FIELD& n)"); + END_OF_MED(LOC); return result; } @@ -1410,7 +1767,8 @@ FIELD* FIELD::div(const FIELD& m, const template FIELD* FIELD::divDeep(const FIELD& m, const FIELD& n) { - BEGIN_OF("FIELD::divDeep(const FIELD & m, const FIELD& n)"); + const char* LOC = "FIELD::divDeep(const FIELD & m, const FIELD& n)"; + BEGIN_OF_MED(LOC); FIELD_::_deepCheckFieldCompatibility(m, n, false); // may throw exception // Creation of a new field @@ -1419,10 +1777,15 @@ FIELD* FIELD::divDeep(const FIELD& m, co result->_operationInitialize(m,n,"/"); // perform Atribute's initialization result->_div_in_place(m,n); // perform division - END_OF("FIELD::divDeep(const FIELD & m, const FIELD& n)"); + END_OF_MED(LOC); return result; } + +/*! +@} +*/ + /*! \if developper This internal method initialize the members of a new field created to hold the result of the operation Op . @@ -1431,9 +1794,9 @@ FIELD* FIELD::divDeep(const FIELD& m, co \endif */ template -void FIELD::_operationInitialize(const FIELD& m,const FIELD& n, char* Op) +void FIELD::_operationInitialize(const FIELD& m,const FIELD& n, const char* Op) { - MESSAGE("Appel methode interne " << Op); + MESSAGE_MED("Appel methode interne " << Op); // Atribute's initialization (copy of the first field's attributes) // Other data members (_support, _numberOfValues) are initialized in the field's constr. @@ -1446,10 +1809,10 @@ void FIELD::_operationInitialize(const FIELD& m,const FIELD& // The following data member may differ from field m to n. // The initialization is done based on the first field. - if(m.getComponentsUnits() != NULL) - setComponentsUnits(m.getComponentsUnits()); - else - _componentsUnits = (UNIT *) NULL; + //if(m.getComponentsUnits() != NULL) + setComponentsUnits(m.getComponentsUnits()); + //else + // _componentsUnits = (UNIT *) NULL; setIterationNumber(m.getIterationNumber()); setTime(m.getTime()); @@ -1475,7 +1838,7 @@ void FIELD::_add_in_place(const FIELD& m,const FIELD& n) T * value=const_cast (getValue()); const int size=getNumberOfValues()*getNumberOfComponents(); - SCRUTE(size); + SCRUTE_MED(size); const T* endV1=value1+size; for(;value1!=endV1; value1++,value2++,value++) *value=(*value1)+(*value2); @@ -1499,7 +1862,7 @@ void FIELD::_sub_in_place(const FIELD& m,const FIELD& n) T * value=const_cast (getValue()); const int size=getNumberOfValues()*getNumberOfComponents(); - SCRUTE(size); + SCRUTE_MED(size); const T* endV1=value1+size; for(;value1!=endV1; value1++,value2++,value++) *value=(*value1)-(*value2); @@ -1523,7 +1886,7 @@ void FIELD::_mul_in_place(const FIELD& m,const FIELD& n) T * value=const_cast (getValue()); const int size=getNumberOfValues()*getNumberOfComponents(); - SCRUTE(size); + SCRUTE_MED(size); const T* endV1=value1+size; for(;value1!=endV1; value1++,value2++,value++) *value=(*value1)*(*value2); @@ -1547,7 +1910,7 @@ void FIELD::_div_in_place(const FIELD& m,const FIELD& n) thr T * value=const_cast (getValue()); const int size=getNumberOfValues()*getNumberOfComponents(); - SCRUTE(size); + SCRUTE_MED(size); const T* endV1=value1+size; for(;value1!=endV1; value1++,value2++,value++){ if ( *value2 == 0 ) { // FAIRE PLUTOT UN TRY CATCH Rmq from EF @@ -1559,7 +1922,12 @@ void FIELD::_div_in_place(const FIELD& m,const FIELD& n) thr } } -/*! Return Max Norm +/*! +\addtogroup FIELD_algo +@{ +*/ + +/*! Return maximum of all absolute values contained in the array (all elements and all components are browsed). */ template double FIELD::normMax() const throw (MEDEXCEPTION) { @@ -1591,7 +1959,7 @@ template double FIELD::normMa return Max>Min ? static_cast(Max) : static_cast(Min); } -/*! Return Euclidien norm +/*! Return Euclidian norm for all elements of the array. */ template double FIELD::norm2() const throw (MEDEXCEPTION) { @@ -1616,7 +1984,7 @@ template double FIELD::norm2( //------------- TDG and BS addings -/*! Return Extremums of field +/*! Return Extrema of field */ template void FIELD::getMinMax(T &vmin, T &vmax) throw (MEDEXCEPTION) { @@ -1693,7 +2061,7 @@ template FIELD* FIELD::buildGradient() const throw (MEDEXCEPTION) { const char * LOC = "FIELD::buildGradient() : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // space dimension of input mesh int spaceDim = getSupport()->getMesh()->getSpaceDimension(); @@ -1858,7 +2226,7 @@ FIELD* FIELD::buildGradient() const th delete [] x; - END_OF(LOC); + END_OF_MED(LOC); return Gradient; } @@ -1868,7 +2236,7 @@ template FIELD* FIELD::buildNorm2Field() const throw (MEDEXCEPTION) { const char * LOC = "FIELD::buildNorm2Field() : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); FIELD* Norm2Field = new FIELD(getSupport(),1); @@ -1900,7 +2268,7 @@ FIELD* FIELD::buildNorm2Field() const Norm2Field->setValueIJ(i,1,sqrt(norm2)); } - END_OF(LOC); + END_OF_MED(LOC); return Norm2Field; } @@ -1931,7 +2299,7 @@ void FIELD::applyFunc() template T FIELD::pow(T x) { - return (T)::pow(x,FIELD::_scalarForPow); + return (T)::pow((double)x,FIELD::_scalarForPow); } /*! Apply to each (scalar) field component the math function pow. @@ -2034,40 +2402,84 @@ double FIELD::normL2(int component, const FIELD * p_field_size=p_field_volume; if(!p_field_volume) // if the user don't supply the volume - p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh] + p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh] // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size const double* vol=p_field_size->getValue(); // Il n'est vraiment pas optimal de mixer des champs dans des modes d'entrelacement // different juste pour le calcul - const T * value = NULL; - ArrayNo * myArray = NULL; - if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE ) - value = getValue(); - else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) { - myArray = ArrayConvert2No( *( dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() ) )); - value = myArray->getPtr(); - } - else { - myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) )); - value = myArray->getPtr(); - } - - value = value + (component-1) * getNumberOfValues(); - const T* lastvalue=value+getNumberOfValues(); // pointing just after the end of column double integrale=0.0; double totVol=0.0; - for (; value!=lastvalue ; ++value ,++vol) - { + + if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE ) { + const T* value = getValue(); + value = value + (component-1) * getNumberOfValues(); + const T* lastvalue = value + getNumberOfValues(); // pointing just after the end of column + for (; value!=lastvalue ; ++value ,++vol) { integrale += static_cast((*value) * (*value)) * (*vol); totVol+=*vol; + } + } + else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) { + ArrayNoByType* anArray = dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() ); + //for (int i=1; i <= anArray->getNbElem() ; i++ ) { + // for (int j=1; j<= anArray->getDim(); j++, ++vol ) { + // integrale += static_cast( anArray->getIJ(i,j) * anArray->getIJ(i,j) * (*vol) ); + // totVol+=*vol; + // } + //} + for (int i=1; i <= anArray->getNbElem() ; i++, ++vol ) { + integrale += static_cast( anArray->getIJ(i,component) * anArray->getIJ(i,component) * (*vol) ); + totVol+=*vol; + } + //delete anArray; + } + else { // FULL_INTERLACE + ArrayFull* anArray = dynamic_cast< ArrayFull * > ( getArrayNoGauss() ); + //for (int i=1; i <= anArray->getNbElem() ; i++ ) { + // for (int j=1; j<= anArray->getDim(); j++, ++vol ) { + //for (int j=1; j<= anArray->getDim(); j++ ) { + // for (int i=1; i <= anArray->getNbElem() ; i++, ++vol ) { + // integrale += static_cast( anArray->getIJ(i,j) * anArray->getIJ(i,j) * (*vol) ); + // totVol+=*vol; + // } + //} + for (int i=1; i <= anArray->getNbElem() ; i++, ++vol ) { + integrale += static_cast( anArray->getIJ(i,component) * anArray->getIJ(i,component) * (*vol) ); + totVol+=*vol; + } + //delete anArray; } + //const T * value = NULL; + //ArrayNo * myArray = NULL; + //if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE ) + // value = getValue(); + //else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) { + // myArray = ArrayConvert2No( *( dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() ) )); + // value = myArray->getPtr(); + //} + //else { + // myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) )); + // value = myArray->getPtr(); + //} + + //value = value + (component-1) * getNumberOfValues(); + //const T* lastvalue=value+getNumberOfValues(); // pointing just after the end of column + + //double integrale=0.0; + //double totVol=0.0; + //for (; value!=lastvalue ; ++value ,++vol) + //{ + //integrale += static_cast((*value) * (*value)) * (*vol); + //totVol+=*vol; + //} + if(!p_field_volume) // if the user didn't supply the volume delete p_field_size; // delete temporary volume field - if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE ) delete myArray; + //if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE ) delete myArray; if( totVol <= 0) throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!")); @@ -2084,38 +2496,75 @@ double FIELD::normL2(const FIELD * p_ _checkNormCompatibility(p_field_volume); // may throw exception const FIELD * p_field_size=p_field_volume; if(!p_field_volume) // if the user don't supply the volume - p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh] + p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh] // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size const double* vol=p_field_size->getValue(); const double* lastvol=vol+getNumberOfValues(); // pointing just after the end of vol - const T * value = NULL; - ArrayNo * myArray = NULL; - if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE ) - value = getValue(); - else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ){ - myArray = ArrayConvert2No( *( dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() ) )); - value = myArray->getPtr(); - } - else { - myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) )); - value = myArray->getPtr(); - } + double integrale=0.0; double totVol=0.0; const double* p_vol=vol; for (p_vol=vol; p_vol!=lastvol ; ++p_vol) // calculate total volume totVol+=*p_vol; - double integrale=0.0; - for (int i=1; i<=getNumberOfComponents(); ++i) // compute integral on all components - for (p_vol=vol; p_vol!=lastvol ; ++value ,++p_vol) - integrale += static_cast((*value) * (*value)) * (*p_vol); + if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE ) { + const T* value = getValue(); + for (int i=1; i<=getNumberOfComponents(); ++i) { // compute integral on all components + for (p_vol=vol; p_vol!=lastvol ; ++value ,++p_vol) { + integrale += static_cast((*value) * (*value)) * (*p_vol); + } + } + } + else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) { + ArrayNoByType* anArray = dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() ); + for (int j=1; j<=anArray->getDim(); j++) { + int i = 1; + for (p_vol=vol; i<=anArray->getNbElem() || p_vol!=lastvol; i++, ++p_vol ) { + integrale += static_cast( anArray->getIJ(i,j) * anArray->getIJ(i,j) * (*p_vol) ); + } + } + //delete anArray; + } + else { // FULL_INTERLACE + ArrayFull* anArray = dynamic_cast< ArrayFull * > ( getArrayNoGauss() ); + for (int j=1; j<=anArray->getDim(); j++) { + int i = 1; + for (p_vol=vol; i<=anArray->getNbElem() || p_vol!=lastvol; i++, ++p_vol ) { + integrale += static_cast( anArray->getIJ(i,j) * anArray->getIJ(i,j) * (*p_vol) ); + } + } + //delete anArray; + } + + + //const T * value = NULL; + //ArrayNo * myArray = NULL; + //if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE ) + // value = getValue(); + //else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ){ + // myArray = ArrayConvert2No( *( dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() ) )); + // value = myArray->getPtr(); + //} + //else { + // myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) )); + // value = myArray->getPtr(); + //} + + //double totVol=0.0; + //const double* p_vol=vol; + //for (p_vol=vol; p_vol!=lastvol ; ++p_vol) // calculate total volume + //totVol+=*p_vol; + + //double integrale=0.0; + //for (int i=1; i<=getNumberOfComponents(); ++i) // compute integral on all components + //for (p_vol=vol; p_vol!=lastvol ; ++value ,++p_vol) + // integrale += static_cast((*value) * (*value)) * (*p_vol); if(!p_field_volume) // if the user didn't supply the volume delete p_field_size; // delete temporary volume field - if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE ) delete myArray; + //if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE ) delete myArray; if( totVol <= 0) throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!")); @@ -2136,36 +2585,77 @@ double FIELD::normL1(int component, const FIELD * p_field_size=p_field_volume; if(!p_field_volume) // if the user don't supply the volume - p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh] + p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh] // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size - const double* vol=p_field_size->getValue(); - const T * value = NULL; - ArrayNo * myArray = NULL; - if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE ) - value = getColumn(component); - else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) { - myArray = ArrayConvert2No( *( dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() ) )); - value = myArray->getColumn(component); - } - else { - myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) )); - value = myArray->getColumn(component); - } - - const T* lastvalue=value+getNumberOfValues(); // pointing just after the end of column + const double* vol = p_field_size->getValue(); double integrale=0.0; double totVol=0.0; - for (; value!=lastvalue ; ++value ,++vol) - { - integrale += std::abs( static_cast(*value) ) * (*vol); + + if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE ) { + const T* value = getValue(); + const T* lastvalue = value + getNumberOfValues(); // pointing just after the end of column + for (; value!=lastvalue ; ++value ,++vol) { + integrale += std::fabs( static_cast(*value) ) * (*vol); totVol+=*vol; + } + } + else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) { + ArrayNoByType* anArray = dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() ); + //for (int i=1; i <= anArray->getNbElem() ; i++ ) { + // for (int j=1; j<= anArray->getDim(); j++, ++vol ) { + // integrale += std::abs(static_cast( anArray->getIJ(i,j)) ) * (*vol); + // totVol+=*vol; + // } + //} + for (int i=1; i <= anArray->getNbElem() ; i++, ++vol ) { + integrale += std::abs(static_cast( anArray->getIJ(i,component)) ) * (*vol); + totVol+=*vol; + } + //delete anArray; + } + else { // FULL_INTERLACE + ArrayFull* anArray = dynamic_cast< ArrayFull * > ( getArrayNoGauss() ); + //for (int i=1; i <= anArray->getNbElem() ; i++ ) { + // for (int j=1; j<= anArray->getDim(); j++, ++vol ) { + // integrale += std::abs(static_cast( anArray->getIJ(i,j)) ) * (*vol); + // totVol+=*vol; + // } + //} + for (int i=1; i <= anArray->getNbElem() ; i++, ++vol ) { + integrale += std::abs(static_cast( anArray->getIJ(i,component)) ) * (*vol); + totVol+=*vol; + } + //delete anArray; } + + //const T * value = NULL; + //ArrayNo * myArray = NULL; + //if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE ) + // value = getColumn(component); + //else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) { + // myArray = ArrayConvert2No( *( dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() ) )); + // value = myArray->getColumn(component); + //} + //else { + // myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) )); + // value = myArray->getColumn(component); + //} + + //const T* lastvalue=value+getNumberOfValues(); // pointing just after the end of column + + //double integrale=0.0; + //double totVol=0.0; + //for (; value!=lastvalue ; ++value ,++vol) + //{ + //integrale += std::abs( static_cast(*value) ) * (*vol); + //totVol+=*vol; + //} if(!p_field_volume) // if the user didn't supply the volume delete p_field_size; // delete temporary volume field - if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE ) delete myArray; + //if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE ) delete myArray; if( totVol <= 0) throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!")); @@ -2179,45 +2669,81 @@ double FIELD::normL1(int component, template double FIELD::normL1(const FIELD * p_field_volume) const { - _checkNormCompatibility(p_field_volume); // may throw exception - const FIELD * p_field_size=p_field_volume; - if(!p_field_volume) // if the user don't supply the volume - p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh] - - // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size - const double* vol=p_field_size->getValue(); - const double* lastvol=vol+getNumberOfValues(); // pointing just after the end of vol - - const T * value = NULL; - ArrayNo * myArray = NULL; - if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE ) - value = getValue(); - else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) { - myArray = ArrayConvert2No( *( dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() ) )); - value = myArray->getPtr(); + _checkNormCompatibility(p_field_volume); // may throw exception + const FIELD * p_field_size=p_field_volume; + if(!p_field_volume) // if the user don't supply the volume + p_field_size=_getFieldSize(); // we calculate the volume [PROVISOIRE, en attendant l'implémentation dans mesh] + + // get pointer to the element's volumes. MED_FULL_INTERLACE is the default mode for p_field_size + const double* vol = p_field_size->getValue(); + const double* lastvol = vol+getNumberOfValues(); // pointing just after the end of vol + + double integrale=0.0; + double totVol=0.0; + const double* p_vol=vol; + for (p_vol=vol; p_vol!=lastvol ; ++p_vol) // calculate total volume + totVol+=*p_vol; + + if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE ) { + const T* value = getValue(); + for (int i=1; i<=getNumberOfComponents(); ++i) { // compute integral on all components + for (p_vol=vol; p_vol!=lastvol ; ++value ,++p_vol) { + integrale += std::abs( static_cast(*value) ) * (*p_vol); + } } - else { - myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) )); - value = myArray->getPtr(); + } + else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) { + ArrayNoByType* anArray = dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() ); + for (int j=1; j<=anArray->getDim(); j++) { + int i = 1; + for (p_vol=vol; i<=anArray->getNbElem() || p_vol!=lastvol; i++, ++p_vol ) { + integrale += std::abs(static_cast(anArray->getIJ(i,j))) * (*p_vol); + } } - - double totVol=0.0; - const double* p_vol=vol; - for (p_vol=vol; p_vol!=lastvol ; ++p_vol) // calculate total volume - totVol+=*p_vol; - - double integrale=0.0; - for (int i=1; i<=getNumberOfComponents(); ++i) // compute integral on all components - for (p_vol=vol; p_vol!=lastvol ; ++value ,++p_vol) - integrale += std::abs( static_cast(*value) ) * (*p_vol); - - if(!p_field_volume) // if the user didn't supply the volume - delete p_field_size; // delete temporary volume field - if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE ) delete myArray; - if( totVol <= 0) - throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!")); - - return integrale/totVol; + //delete anArray; + } + else { // FULL_INTERLACE + ArrayFull* anArray = dynamic_cast< ArrayFull * > ( getArrayNoGauss() ); + for (int j=1; j<=anArray->getDim(); j++) { + int i = 1; + for (p_vol=vol; i<=anArray->getNbElem() || p_vol!=lastvol; i++, ++p_vol ) { + integrale += std::abs(static_cast(anArray->getIJ(i,j))) * (*p_vol); + } + } + //delete anArray; + } + + + //const T * value = NULL; + //ArrayNo * myArray = NULL; + //if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE ) + // value = getValue(); + //else if ( getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) { + // myArray = ArrayConvert2No( *( dynamic_cast< ArrayNoByType * > ( getArrayNoGauss() ) )); + // value = myArray->getPtr(); + //} + //else { + // myArray = ArrayConvert( *( dynamic_cast< ArrayFull * > ( getArrayNoGauss() ) )); + // value = myArray->getPtr(); + //} + + //double totVol=0.0; + //const double* p_vol=vol; + //for (p_vol=vol; p_vol!=lastvol ; ++p_vol) // calculate total volume + // totVol+=*p_vol; + + //double integrale=0.0; + //for (int i=1; i<=getNumberOfComponents(); ++i) // compute integral on all components + // for (p_vol=vol; p_vol!=lastvol ; ++value ,++p_vol) + // integrale += std::abs( static_cast(*value) ) * (*p_vol); + + if(!p_field_volume) // if the user didn't supply the volume + delete p_field_size; // delete temporary volume field + //if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE ) delete myArray; + if( totVol <= 0) + throw MEDEXCEPTION(STRING("cannot compute sobolev norm : volume is not positive!")); + + return integrale/totVol; } /*! Return a new field (to deallocate with delete) lying on subSupport that is included by @@ -2254,7 +2780,14 @@ FIELD* FIELD::extract(const SUPPORT *sub ret->copyGlobalInfo(*this); return ret; } +/*! +@} +*/ +/*! + \addtogroup FIELD_io + @{ +*/ /*! Constructor with parameters; the object is set via a file and its associated driver. For the moment only the MED_DRIVER is considered and if the last two @@ -2271,20 +2804,19 @@ FIELD::FIELD(const SUPPORT * Support, const int iterationNumber, const int orderNumber) throw (MEDEXCEPTION) { - const char * LOC = "template FIELD::FIELD(const SUPPORT * Support, driverTypes driverType, const string & fileName=\"\", const string & fieldName=\"\", const int iterationNumber=-1, const int orderNumber=-1) : "; + const char* LOC = "template FIELD::FIELD(const SUPPORT * Support, driverTypes driverType, const string & fileName=\"\", const string & fieldName=\"\", const int iterationNumber=-1, const int orderNumber=-1) : "; + BEGIN_OF_MED(LOC); int current; - BEGIN_OF(LOC); - init(); //INITIALISATION DE _valueType DS LE CONSTRUCTEUR DE FIELD_ - ASSERT(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE) + ASSERT_MED(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE) FIELD_::_valueType=SET_VALUE_TYPE::_valueType; //INITIALISATION DE _interlacingType DS LE CONSTRUCTEUR DE FIELD_ - ASSERT(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE) + ASSERT_MED(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE) FIELD_::_interlacingType=SET_INTERLACING_TYPE::_interlacingType; _support = Support; @@ -2302,42 +2834,50 @@ FIELD::FIELD(const SUPPORT * Support, _time = 0.0; _orderNumber = orderNumber; - current = addDriver(driverType,fileName,fieldDriverName,MED_EN::MED_LECT); + current = addDriver(driverType,fileName,fieldDriverName,MED_EN::RDONLY); _drivers[current]->open(); _drivers[current]->read(); _drivers[current]->close(); - END_OF(LOC); + END_OF_MED(LOC); } /*! - This constructor, at least, allows to create a FIELD without creating any + If the mesh argument is not initialized or passed NULL, + this constructor, at least, allows to create a FIELD without creating any SUPPORT then without having to load a MESH object, a support is created. It provides the meshName related mesh but doesn't not set a mesh in the created support. + If the passed mesh contains corresponding support, this support will be used + for the field. This support will be found in mesh by name of one of profiles, + on which the FIELD lays in MED-file. This has sense for the case, then MED-file + was created by MEDMEM, and so name of profile contains name of corresponding support. */ template FIELD::FIELD(driverTypes driverType, const string & fileName, const string & fieldDriverName, const int iterationNumber, - const int orderNumber) + const int orderNumber, + MESH* mesh) throw (MEDEXCEPTION) :FIELD_() { int current; - const char * LOC ="FIELD::FIELD( driverTypes driverType, const string & fileName, string & fieldDriverName, int iterationNumber, int orderNumber) : "; - BEGIN_OF(LOC); + const char* LOC = "FIELD::FIELD( driverTypes driverType, const string & fileName, string & fieldDriverName, int iterationNumber, int orderNumber) : "; + BEGIN_OF_MED(LOC); init(); + _mesh = mesh; + //INITIALISATION DE _valueType DS LE CONSTRUCTEUR DE FIELD_ - ASSERT(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE) - FIELD_::_valueType=SET_VALUE_TYPE::_valueType; + ASSERT_MED(FIELD_::_valueType == MED_EN::MED_UNDEFINED_TYPE) + FIELD_::_valueType = SET_VALUE_TYPE::_valueType; //INITIALISATION DE _interlacingType DS LE CONSTRUCTEUR DE FIELD_ - ASSERT(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE) - FIELD_::_interlacingType=SET_INTERLACING_TYPE::_interlacingType; + ASSERT_MED(FIELD_::_interlacingType == MED_EN::MED_UNDEFINED_INTERLACE) + FIELD_::_interlacingType = SET_INTERLACING_TYPE::_interlacingType; _support = (SUPPORT *) NULL; // OCC 10/03/2006 -- According to the rules defined with help of @@ -2351,28 +2891,32 @@ FIELD::FIELD(driverTypes driverType, _time = 0.0; _orderNumber = orderNumber; - current = addDriver(driverType,fileName,fieldDriverName,MED_EN::MED_LECT); + current = addDriver(driverType,fileName,fieldDriverName,MED_EN::RDONLY); _drivers[current]->open(); _drivers[current]->read(); _drivers[current]->close(); - END_OF(LOC); + END_OF_MED(LOC); } +/*! +@} +*/ /*! Destructor. */ template FIELD::~FIELD() { - BEGIN_OF(" Destructeur FIELD::~FIELD()"); - SCRUTE(this); + const char* LOC = " Destructeur FIELD::~FIELD()"; + BEGIN_OF_MED(LOC); + SCRUTE_MED(this); if (_value) delete _value; locMap::const_iterator it; for ( it = _gaussModel.begin();it != _gaussModel.end(); it++ ) delete (*it).second; - END_OF(" Destructeur FIELD::~FIELD()"); + END_OF_MED(LOC); } /*! @@ -2381,20 +2925,25 @@ template FIELD::~FIELD() template void FIELD::allocValue(const int NumberOfComponents) { - const char* LOC = "FIELD::allocValue(const int NumberOfComponents)" ; - BEGIN_OF(LOC); + const char* LOC = "FIELD::allocValue(const int NumberOfComponents)"; + BEGIN_OF_MED(LOC); _numberOfComponents = NumberOfComponents ; - if (_componentsTypes == NULL) - _componentsTypes = new int[NumberOfComponents] ; - if (_componentsNames == NULL) - _componentsNames = new string[NumberOfComponents]; - if (_componentsDescriptions == NULL) - _componentsDescriptions = new string[NumberOfComponents]; - if (_componentsUnits == NULL) - _componentsUnits = new UNIT[NumberOfComponents]; - if (_MEDComponentsUnits == NULL) - _MEDComponentsUnits = new string[NumberOfComponents]; + //if (_componentsTypes == NULL) + // _componentsTypes = new int[NumberOfComponents] ; + _componentsTypes.resize(NumberOfComponents); + //if (_componentsNames == NULL) + // _componentsNames = new string[NumberOfComponents]; + _componentsNames.resize(NumberOfComponents); + //if (_componentsDescriptions == NULL) + // _componentsDescriptions = new string[NumberOfComponents]; + _componentsDescriptions.resize(NumberOfComponents); + //if (_componentsUnits == NULL) + // _componentsUnits = new UNIT[NumberOfComponents]; + _componentsUnits.resize(NumberOfComponents); + //if (_MEDComponentsUnits == NULL) + // _MEDComponentsUnits = new string[NumberOfComponents]; + _MEDComponentsUnits.resize(NumberOfComponents); for (int i=0;i::allocValue(const int NumberOfComponents) try { // becarefull about the number of gauss point _numberOfValues = _support->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS); - MESSAGE(LOC <<" : "<<_numberOfValues <<" et "<< NumberOfComponents); + MESSAGE_MED(PREFIX_MED <<" : "<<_numberOfValues <<" et "<< NumberOfComponents); - //EF : A modifier lors de l'intégration de la classe de localisation des points de gauss + //EF : A modifier lors de l'intégration de la classe de localisation des points de gauss _value = new ArrayNoGauss(_numberOfComponents,_numberOfValues); _isRead = true ; } catch (MEDEXCEPTION &ex) { - MESSAGE("No value defined, problem with NumberOfComponents (and may be _support) size of MEDARRAY::_value !"); + MESSAGE_MED("No value defined, problem with NumberOfComponents (and may be _support) size of MEDARRAY::_value !"); // OCC 10/03/2006 -- According to the rules defined with help of // MEDMEM_IntrelacingTraits class, it is not allowed to instantiate // MEDMEM_Array<> template using INTERLACING_TAG parameter of @@ -2419,8 +2968,8 @@ void FIELD::allocValue(const int NumberOfComponents) _value = NULL; } - SCRUTE(_value); - END_OF("void FIELD::allocValue(const int NumberOfComponents)"); + SCRUTE_MED(_value); + END_OF_MED(LOC); } /*! @@ -2430,33 +2979,39 @@ template void FIELD::allocValue(const int NumberOfComponents, const int LengthValue) { - BEGIN_OF("void FIELD::allocValue(const int NumberOfComponents,const int LengthValue)"); + const char* LOC = "void FIELD::allocValue(const int NumberOfComponents,const int LengthValue)"; + BEGIN_OF_MED(LOC); _numberOfComponents = NumberOfComponents ; - if (_componentsTypes == NULL) - _componentsTypes = new int[NumberOfComponents] ; - if (_componentsNames == NULL) - _componentsNames = new string[NumberOfComponents]; - if (_componentsDescriptions == NULL) - _componentsDescriptions = new string[NumberOfComponents]; - if (_componentsUnits == NULL) - _componentsUnits = new UNIT[NumberOfComponents]; - if (_MEDComponentsUnits == NULL) - _MEDComponentsUnits = new string[NumberOfComponents]; + //if (_componentsTypes == NULL) + // _componentsTypes = new int[NumberOfComponents] ; + //if (_componentsNames == NULL) + // _componentsNames = new string[NumberOfComponents]; + //if (_componentsDescriptions == NULL) + // _componentsDescriptions = new string[NumberOfComponents]; + //if (_componentsUnits == NULL) + // _componentsUnits = new UNIT[NumberOfComponents]; + //if (_MEDComponentsUnits == NULL) + // _MEDComponentsUnits = new string[NumberOfComponents]; + _componentsTypes.resize(NumberOfComponents); + _componentsNames.resize(NumberOfComponents); + _componentsDescriptions.resize(NumberOfComponents); + _componentsUnits.resize(NumberOfComponents); + _MEDComponentsUnits.resize(NumberOfComponents); for (int i=0;i::allocValue(const int NumberOfComponents,const int LengthValue)"); + SCRUTE_MED(_value); + END_OF_MED(LOC); } /*! @@ -2465,22 +3020,38 @@ void FIELD::allocValue(const int NumberOfComponents, template void FIELD::deallocValue() { - BEGIN_OF("void FIELD::deallocValue()"); + const char* LOC = "void FIELD::deallocValue()"; + BEGIN_OF_MED(LOC); _numberOfValues = 0 ; _numberOfComponents = 0 ; - if (_value != NULL) + if (_value != NULL) { delete _value; + _value = NULL; + } - END_OF("void FIELD::deallocValue()"); + END_OF_MED(LOC); } + + +/*!\if MEDMEM_ug + +\addtogroup FIELD_io +@{ +\endif */ // ----------------- // Methodes Inline // ----------------- /*! - Create the specified driver and return its index reference to path to + Creates the specified driver and return its index reference to path to read or write methods. + +\param driverType specifies the file type (MED_DRIVER or VTK_DRIVER) +\param fileName name of the output file +\param driverName name of the field +\param access access type (read, write or both) + */ template @@ -2490,13 +3061,13 @@ int FIELD::addDriver(driverTypes driverType, MED_EN::med_mode_acces access) { //jfa tmp (as last argument has no default value):const char * LOC = "FIELD::addDriver(driverTypes driverType, const string & fileName=\"Default File Name.med\",const string & driverName=\"Default Field Name\",MED_EN::med_mode_acces access) : "; - const char * LOC = "FIELD::addDriver(driverTypes driverType, const string & fileName,const string & driverName,MED_EN::med_mode_acces access) :";//jfa tmp GENDRIVER * driver; - BEGIN_OF(LOC); + const char* LOC = "FIELD::addDriver(driverTypes driverType, const string & fileName,const string & driverName,MED_EN::med_mode_acces access) :"; + BEGIN_OF_MED(LOC); - SCRUTE(driverType); + SCRUTE_MED(driverType); driver = DRIVERFACTORY::buildDriverForField(driverType,fileName,this,access); @@ -2506,39 +3077,43 @@ int FIELD::addDriver(driverTypes driverType, _drivers[current]->setFieldName(driverName); - END_OF(LOC); + END_OF_MED(LOC); return current; } - +/*! \if MEDMEM_ug @} \endif */ /*! - Duplicate the given driver and return its index reference to path to + Duplicates the given driver and return its index reference to path to read or write methods. */ template inline int FIELD::addDriver (GENDRIVER & driver ) { - const char * LOC = "FIELD::addDriver(GENDRIVER &) : "; int current; - BEGIN_OF(LOC); + const char* LOC = "FIELD::addDriver(GENDRIVER &) : "; + BEGIN_OF_MED(LOC); // duplicate driver to delete it with destructor ! - GENDRIVER * newDriver = driver.copy() ; + //GENDRIVER * newDriver = driver.copy() ; + // for FIELD->read( genDriver ) if FIELD was not passed to genDriver + GENDRIVER * newDriver = + DRIVERFACTORY::buildDriverForField(driver.getDriverType(), + driver.getFileName(), this, + driver.getAccessMode()); _drivers.push_back(newDriver); current = _drivers.size()-1; - SCRUTE(current); + SCRUTE_MED(current); driver.setId(current); - MESSAGE(LOC << " je suis la 1"); - END_OF(LOC); - MESSAGE(LOC << " je suis la 2"); + newDriver->merge( driver ); + newDriver->setId(current); return current ; -}; +} /*! Remove the driver referenced by its index. @@ -2547,12 +3122,12 @@ template void FIELD::rmDriver (int index/*=0*/) { const char * LOC = "FIELD::rmDriver (int index=0): "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); - if ( _drivers[index] ) { + if ( index>=0 && index<_drivers.size() && _drivers[index] ) { //_drivers.erase(&_drivers[index]); // why not ???? - MESSAGE ("detruire"); + MESSAGE_MED ("detruire"); } else throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) @@ -2561,7 +3136,7 @@ void FIELD::rmDriver (int index/*=0*/) ) ); - END_OF(LOC); + END_OF_MED(LOC); } /*! @@ -2570,9 +3145,9 @@ void FIELD::rmDriver (int index/*=0*/) template inline void FIELD::read(int index/*=0*/) { const char * LOC = "FIELD::read(int index=0) : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); - if ( _drivers[index] ) { + if ( index>=0 && index<_drivers.size() && _drivers[index] ) { _drivers[index]->open(); _drivers[index]->read(); _drivers[index]->close(); @@ -2583,18 +3158,32 @@ template inline void FIELD: << _drivers.size() ) ); - END_OF(LOC); + END_OF_MED(LOC); } +/*! \if MEDMEM_ug +\addtogroup FIELD_io +@{ +\endif */ + /*! - Write FIELD in the file specified in the driver given by its index. + Writes FIELD in the file specified by the driver handle \a index. + +Example : +\verbatim +//... +// Attaching the friver to file "output.med", meshname "Mesh" +int driver_handle = mesh.addDriver(MED_DRIVER, "output.med", "Mesh"); +// Writing the content of mesh to the file +mesh.write(driver_handle); +\endverbatim */ template inline void FIELD::write(int index/*=0*/, const string & driverName /*= ""*/) { const char * LOC = "FIELD::write(int index=0, const string & driverName = \"\") : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); - if( _drivers[index] ) { + if( index>=0 && index<_drivers.size() && _drivers[index] ) { _drivers[index]->open(); if (driverName != "") _drivers[index]->setFieldName(driverName); _drivers[index]->write(); @@ -2606,9 +3195,9 @@ template inline void FIELD: << _drivers.size() ) ); - END_OF(LOC); + END_OF_MED(LOC); } - +/*! \if MEDMEM_ug @} \endif */ /*! Write FIELD in the file specified in the driver given by its index. Use this method for ASCII drivers (e.g. VTK_DRIVER) @@ -2616,9 +3205,9 @@ template inline void FIELD: template inline void FIELD::writeAppend(int index/*=0*/, const string & driverName /*= ""*/) { const char * LOC = "FIELD::write(int index=0, const string & driverName = \"\") : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); - if( _drivers[index] ) { + if( index>=0 && index<_drivers.size() && _drivers[index] ) { _drivers[index]->openAppend(); if (driverName != "") _drivers[index]->setFieldName(driverName); _drivers[index]->writeAppend(); @@ -2630,7 +3219,7 @@ template inline void FIELD: << _drivers.size() ) ); - END_OF(LOC); + END_OF_MED(LOC); } /*! @@ -2641,8 +3230,8 @@ template inline void FIELD: */ template inline void FIELD::write(const GENDRIVER & genDriver) { - const char * LOC = " FIELD::write(const GENDRIVER &) : "; - BEGIN_OF(LOC); + const char* LOC = " FIELD::write(const GENDRIVER &) : "; + BEGIN_OF_MED(LOC); for (unsigned int index=0; index < _drivers.size(); index++ ) if ( *_drivers[index] == genDriver ) { @@ -2651,7 +3240,7 @@ template inline void FIELD: _drivers[index]->close(); } - END_OF(LOC); + END_OF_MED(LOC); } @@ -2663,8 +3252,8 @@ template inline void FIELD: */ template inline void FIELD::writeAppend(const GENDRIVER & genDriver) { - const char * LOC = " FIELD::write(const GENDRIVER &) : "; - BEGIN_OF(LOC); + const char* LOC = " FIELD::write(const GENDRIVER &) : "; + BEGIN_OF_MED(LOC); for (unsigned int index=0; index < _drivers.size(); index++ ) if ( *_drivers[index] == genDriver ) { @@ -2673,7 +3262,7 @@ template inline void FIELD: _drivers[index]->close(); } - END_OF(LOC); + END_OF_MED(LOC); } @@ -2685,8 +3274,8 @@ template inline void FIELD: */ template inline void FIELD::read(const GENDRIVER & genDriver) { - const char * LOC = " FIELD::read(const GENDRIVER &) : "; - BEGIN_OF(LOC); + const char* LOC = " FIELD::read(const GENDRIVER &) : "; + BEGIN_OF_MED(LOC); for (unsigned int index=0; index < _drivers.size(); index++ ) if ( *_drivers[index] == genDriver ) { @@ -2695,7 +3284,7 @@ template inline void FIELD: _drivers[index]->close(); } - END_OF(LOC); + END_OF_MED(LOC); } @@ -2761,9 +3350,9 @@ inline void FIELD::setArray(MEDMEM_Array_ * Value) template inline MEDMEM_Array_ * FIELD::getArray() const throw (MEDEXCEPTION) { - const char * LOC = "MEDMEM_Array_ * FIELD::getArray() : "; - BEGIN_OF(LOC); - END_OF(LOC); + const char* LOC = "MEDMEM_Array_ * FIELD::getArray() : "; + BEGIN_OF_MED(LOC); + END_OF_MED(LOC); return _value ; } template inline @@ -2771,7 +3360,7 @@ typename MEDMEM_ArrayInterface::Array * FIELD::getArrayGauss() const throw (MEDEXCEPTION) { const char * LOC = "FIELD::getArrayGauss() : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if ( getGaussPresence() ) return static_cast (_value); @@ -2779,7 +3368,7 @@ FIELD::getArrayGauss() const throw (MEDEXCEPTION) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<< "The field has no Gauss Point")); - END_OF(LOC); + END_OF_MED(LOC); } @@ -2788,7 +3377,7 @@ typename MEDMEM_ArrayInterface::Array * FIELD::getArrayNoGauss() const throw (MEDEXCEPTION) { const char * LOC = "FIELD::getArrayNoGauss() : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if ( ! getGaussPresence() ) return static_cast < ArrayNoGauss * > (_value); @@ -2796,7 +3385,7 @@ FIELD::getArrayNoGauss() const throw (MEDEXCEPTION) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<< "The field has Gauss Point")); - END_OF(LOC); + END_OF_MED(LOC); } @@ -2804,14 +3393,14 @@ template inline bool FIELD::getGaussPresence() const throw (MEDEXCEPTION) { const char * LOC = "FIELD::getGaussPresence() const :"; - //BEGIN_OF(LOC); + //BEGIN_OF_MED(LOC); if (_value != NULL) return _value->getGaussPresence(); else throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Can't call getGaussPresence on a null _value")); - //END_OF(LOC); + //END_OF_MED(); } /*! @@ -2828,21 +3417,46 @@ inline int FIELD::getValueLength() const return static_cast(_value)->getArraySize() ; } + +/*! \if MEDMEM_ug +\defgroup FIELD_value Field values + +These methods are provided for accessing the values of a field. +There are two ways to do so : one consists in using accessors +that retrieve elements or group of elements from the entire field. Typical use is +\verbatim +FIELD field(MED_DRIVER, "result.med","Pressure"); +double P0=field.getValueIJ(1,1); +\endverbatim + +Another way is to retrieve the pointer to the array that contains the +variable values. In this case, the user should be aware of the interlacing mode +so that no mistakes are made when retrieving the values. + +\verbatim +FIELD field(MED_DRIVER, "result.med","Pressure"); +double* ptrP=field.getValue(); +double P0=ptrP[0]; +\endverbatim + +@{ +\endif +*/ /*! - Return a reference to values array to read them. + Returns a reference to values array to read them. */ template inline const T* FIELD::getValue() const throw (MEDEXCEPTION) { - const char * LOC ="FIELD::getValue() : "; - BEGIN_OF(LOC); + const char* LOC = "FIELD::getValue() : "; + BEGIN_OF_MED(LOC); if ( getGaussPresence() ) return static_cast(_value)->getPtr() ; else return static_cast(_value)->getPtr() ; } /*! - Return a reference to i^{th} row + Returns a reference to \f$ i^{th} \f$ row of FIELD values array. If a faster accessor is intended you may use getArray() once, then MEDMEM_Array accessors. @@ -2854,7 +3468,7 @@ const T* FIELD::getRow(int i) const throw (MEDEXCEPTION) { const char * LOC = "FIELD::getRow(int i) : "; - //BEGIN_OF(LOC); + //BEGIN_OF_MED(LOC); int valIndex=-1; if (_support) @@ -2867,18 +3481,17 @@ FIELD::getRow(int i) const throw (MEDEXCEPTION) return static_cast(_value)->getRow(valIndex) ; else return static_cast(_value)->getRow(valIndex) ; - //END_OF(LOC); + //END_OF_MED(); } /*! - Return a reference to j^{th} column + Returns a reference to $j^{th}$ column of FIELD values array. */ template inline const T* FIELD::getColumn(int j) const throw (MEDEXCEPTION) { - //const char * LOC ="FIELD::getColumn(int j) : "; - //BEGIN_OF(LOC); + //BEGIN_OF_MED(LOC); if ( getGaussPresence() ) return static_cast(_value)->getColumn(j) ; else @@ -2886,12 +3499,17 @@ FIELD::getColumn(int j) const throw (MEDEXCEPTION) } /*! - Return the value of i^{th} element and j^{th} component. + Returns the value of $i^{th}$ element and $j^{th}$ component. + This method only works with fields having no particular Gauss point +definition (i.e., fields having one value per element). + This method makes the retrieval of the value independent from the + interlacing pattern, but it is slower than the complete retrieval + obtained by the \b getValue() method. */ template inline T FIELD::getValueIJ(int i,int j) const throw (MEDEXCEPTION) { const char * LOC = "getValueIJ(..)"; - //BEGIN_OF(LOC); + //BEGIN_OF_MED(LOC); int valIndex=-1; if (_support) valIndex = _support->getValIndFromGlobalNumber(i); @@ -2905,12 +3523,16 @@ template inline T FIELD::getV } /*! - Return the j^{th} component of k^{th} gauss points of i^{th} value. + Returns the $j^{th}$ component of $k^{th}$ Gauss points of $i^{th}$ value. + This method is compatible with elements having more than one Gauss point. + This method makes the retrieval of the value independent from the + interlacing pattern, but it is slower than the complete retrieval + obtained by the \b getValue() method. */ template inline T FIELD::getValueIJK(int i,int j,int k) const throw (MEDEXCEPTION) { const char * LOC = "getValueIJK(..)"; - //BEGIN_OF(LOC); + //BEGIN_OF_MED(LOC); int valIndex=-1; if (_support) valIndex = _support->getValIndFromGlobalNumber(i); @@ -2922,6 +3544,7 @@ template inline T FIELD::getV else return static_cast(_value)->getIJK(valIndex,j,k) ; } +/*! \if MEDMEM_ug @} \endif */ /*! Return number of values of a geomertic type in NoInterlaceByType mode @@ -2930,7 +3553,7 @@ template inline int FIELD::getValueByTypeLength(int t) const throw (MEDEXCEPTION) { const char * LOC ="getValueByTypeLength() : "; - //BEGIN_OF(LOC); + //BEGIN_OF_MED(LOC); if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"not MED_NO_INTERLACE_BY_TYPE field" )); @@ -2955,7 +3578,7 @@ template inline const T* FIELD::getValueByType(int t) const throw (MEDEXCEPTION) { const char * LOC ="getValueByType() : "; - //BEGIN_OF(LOC); + //BEGIN_OF_MED(LOC); if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"not MED_NO_INTERLACE_BY_TYPE field" )); @@ -2975,7 +3598,7 @@ inline const T* FIELD::getValueByType(int t) const throw (MED template inline T FIELD::getValueIJByType(int i,int j, int t) const throw (MEDEXCEPTION) { const char * LOC = "getValueIJByType(..)"; - //BEGIN_OF(LOC); + //BEGIN_OF_MED(LOC); if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"not MED_NO_INTERLACE_BY_TYPE field" )); @@ -2991,7 +3614,7 @@ template inline T FIELD::getV template inline T FIELD::getValueIJKByType(int i,int j,int k,int t) const throw (MEDEXCEPTION) { const char * LOC = "getValueIJKByType(..)"; - //BEGIN_OF(LOC); + //BEGIN_OF_MED(LOC); if ( getInterlacingType() != MED_EN::MED_NO_INTERLACE_BY_TYPE ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"not MED_NO_INTERLACE_BY_TYPE field" )); @@ -3005,14 +3628,19 @@ template inline T FIELD::getV template const int FIELD::getNumberOfGeometricTypes() const throw (MEDEXCEPTION) { const char * LOC = "getNumberOfGeometricTypes(..)"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_support) return _support->getNumberOfTypes(); else throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" )); - END_OF(LOC); -}; + END_OF_MED(LOC); +} +/*! \if MEDMEM_ug +\addtogroup FIELD_gauss +@{ +\endif + */ template const GAUSS_LOCALIZATION & FIELD::getGaussLocalization(MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION) @@ -3028,7 +3656,7 @@ FIELD::getGaussLocalization(MED_EN::medGeometryElement geomEl else throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Can't find any GaussLocalization on this geometric type" )); -}; +} template const GAUSS_LOCALIZATION * FIELD::getGaussLocalizationPtr(MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION) @@ -3044,7 +3672,7 @@ FIELD::getGaussLocalizationPtr(MED_EN::medGeometryElement geo else throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Can't find any GaussLocalization on this geometric type" )); -}; +} /*! * \brief Return GAUSS_LOCALIZATION_* whose interlacing type may differ from one of the field @@ -3061,7 +3689,7 @@ FIELD::getGaussLocalizationRoot(MED_EN::medGeometryElement ge else throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Can't find any GaussLocalization on this geometric type: "<< geomElement )); -}; +} /*! * \brief Take onership of GAUSS_LOCALIZATION_* whose interlacing type may differ from one of the field @@ -3077,7 +3705,7 @@ FIELD::setGaussLocalization(MED_EN::medGeometryElement geomEl else { _gaussModel[ geomElement ] = gaussloc; } -}; +} template void @@ -3091,7 +3719,7 @@ FIELD::setGaussLocalization(MED_EN::medGeometryElement geomEl else { _gaussModel[ geomElement ] = new GAUSS_LOCALIZATION (gaussloc); } -}; +} /*! Returns number of Gauss points for this medGeometryElement. @@ -3149,14 +3777,14 @@ template const int * FIELD::g } /*! - Returns number of Gauss points for element n°i. + Returns number of Gauss points for element n°i. The i index is a global index (take care of previous element on different geometric type). */ template const int FIELD::getNbGaussI(int i) const throw (MEDEXCEPTION) { const char * LOC = "getNbGaussI(..)"; -// BEGIN_OF(LOC); +// BEGIN_OF_MED(LOC); int valIndex=-1; if (_support) @@ -3171,46 +3799,57 @@ template const int FIELD::get return static_cast(_value)->getNbGauss(valIndex) ; else throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"_value not defined" )); -// END_OF(LOC); -}; +// END_OF_MED(); +} +/*! +@} + */ + template const int * FIELD::getNumberOfElements() const throw (MEDEXCEPTION) { const char * LOC = "getNumberOfElements(..)"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_support) return _support->getNumberOfElements(); else throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" )); - END_OF(LOC); -}; + END_OF_MED(LOC); +} template const MED_EN::medGeometryElement * FIELD::getGeometricTypes() const throw (MEDEXCEPTION) { const char * LOC = "getGeometricTypes(..)"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_support) return _support->getTypes(); else throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" )); - END_OF(LOC); -}; + END_OF_MED(LOC); +} template bool FIELD::isOnAllElements() const throw (MEDEXCEPTION) { const char * LOC = "isOnAllElements(..)"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_support) return _support->isOnAllElements(); else throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined" )); - END_OF(LOC); -}; + END_OF_MED(LOC); +} + +/*! \if MEDMEM_ug +\addtogroup FIELD_value +@{ +\endif */ /*! Copy new values array in FIELD according to the given mode. Array must have right size. If not results are unpredicable. + In MED_FULL_INTERLACE mode, values are stored elementwise in X1,Y1,Z1,X2,Y2,Z2.. order. +In MED_NO_INTERLACE mode, values are stored componentwise in X1,X2,X3,...,Y1,Y2,Y3,... order. */ template inline void FIELD::setValue( T* value) throw (MEDEXCEPTION) { @@ -3241,7 +3880,7 @@ inline void FIELD::setRow( int i, T* value) throw (MEDEXCEPTI } /*! - Update values array in the j^{th} column of FIELD values array with the given ones and + Update values array in the $j^{th}$ column of FIELD values array with the given ones and according to specified mode. */ template @@ -3254,7 +3893,7 @@ inline void FIELD::setColumn( int j, T* value) throw (MEDEXCE } /*! - Set the value of i^{th} element and j^{th} component with the given one. + Sets the value of i^{th} element and j^{th} component with the given one. */ template inline void FIELD::setValueIJ(int i, int j, T value) throw (MEDEXCEPTION) { @@ -3318,6 +3957,7 @@ template inline void FIELD::s else return static_cast(_value)->setIJKByType(i,j,k,t,value) ; } +/*! \if MEDMEM_ug @} \endif */ /* METHODS @@ -3326,107 +3966,107 @@ template inline void FIELD::s /*! Fill values array with volume values. */ -template -void FIELD::getVolume() const throw (MEDEXCEPTION) -{ - const char * LOC = "FIELD::getVolume() const : "; - BEGIN_OF(LOC); - - // The field has to be initilised by a non empty support and a - // number of components = 1 and its value type has to be set to MED_REEL64 - // (ie a FIELD) - - if ((_support == (SUPPORT *) NULL) || (_numberOfComponents != 1) || (_valueType != MED_EN::MED_REEL64)) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to 1 and a value type set to MED_REEL64")); - - END_OF(LOC); -} - -/*! - Fill values array with area values. -*/ -template -void FIELD::getArea() const throw (MEDEXCEPTION) -{ - const char * LOC = "FIELD::getArea() const : "; - BEGIN_OF(LOC); - - // The field has to be initilised by a non empty support and a - // number of components = 1 and its value type has to be set to MED_REEL64 - // (ie a FIELD) - - if ((_support == (SUPPORT *) NULL) || (_numberOfComponents != 1) || (_valueType != MED_EN::MED_REEL64)) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to 1 and a value type set to MED_REEL64")); - - END_OF(LOC); -} - -/*! - Fill values array with length values. -*/ -template -void FIELD::getLength() const throw (MEDEXCEPTION) -{ - const char * LOC = "FIELD::getLength() const : "; - BEGIN_OF(LOC); - - // The field has to be initilised by a non empty support and a - // number of components = 1 and its value type has to be set to MED_REEL64 - // (ie a FIELD) - - if ((_support == (SUPPORT *) NULL) || (_numberOfComponents != 1) || (_valueType != MED_EN::MED_REEL64)) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to 1 and a value type set to MED_REEL64")); - - END_OF(LOC); -} - -/*! - Fill values array with normal values. -*/ -template -void FIELD::getNormal() const throw (MEDEXCEPTION) -{ - const char * LOC = "FIELD::getNormal() const : "; - BEGIN_OF(LOC); - - // The field has to be initilised by a non empty support and a - // number of components = 1 and its value type has to be set to MED_REEL64 - // (ie a FIELD) - - if (_support == (SUPPORT *) NULL) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to the space dimension and a value type set to MED_REEL64")); - - int dim_space = _support->getMesh()->getSpaceDimension(); - - if ((_numberOfComponents != dim_space) || (_valueType != MED_EN::MED_REEL64)) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to the space dimension and a value type set to MED_REEL64")); - - END_OF(LOC); -} - -/*! - Fill values array with barycenter values. -*/ -template -void FIELD::getBarycenter() const throw (MEDEXCEPTION) -{ - const char * LOC = "FIELD::getBarycenter() const : "; - BEGIN_OF(LOC); - - // The field has to be initilised by a non empty support and a number of - //components = space dimension and its value type has to be set to MED_REEL64 - // (ie a FIELD) - - if (_support == (SUPPORT *) NULL) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to the space dimension and a value type set to MED_REEL64")); - - int dim_space = _support->getMesh()->getSpaceDimension(); - - if ((_numberOfComponents != dim_space) || (_valueType != MED_EN::MED_REEL64)) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to the space dimension and a value type set to MED_REEL64")); - - END_OF(LOC); -} +// template +// void FIELD::getVolume() const throw (MEDEXCEPTION) +// { +// const char * LOC = "FIELD::getVolume() const : "; +// BEGIN_OF_MED(LOC); + +// // The field has to be initilised by a non empty support and a +// // number of components = 1 and its value type has to be set to MED_REEL64 +// // (ie a FIELD) + +// if ((_support == (SUPPORT *) NULL) || (_numberOfComponents != 1) || (_valueType != MED_EN::MED_REEL64)) +// throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to 1 and a value type set to MED_REEL64")); + +// END_OF_MED(LOC); +// } + +// /*! +// Fill values array with area values. +// */ +// template +// void FIELD::getArea() const throw (MEDEXCEPTION) +// { +// const char * LOC = "FIELD::getArea() const : "; +// BEGIN_OF_MED(LOC); + +// // The field has to be initilised by a non empty support and a +// // number of components = 1 and its value type has to be set to MED_REEL64 +// // (ie a FIELD) + +// if ((_support == (SUPPORT *) NULL) || (_numberOfComponents != 1) || (_valueType != MED_EN::MED_REEL64)) +// throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to 1 and a value type set to MED_REEL64")); + +// END_OF_MED(LOC); +// } + +// /*! +// Fill values array with length values. +// */ +// template +// void FIELD::getLength() const throw (MEDEXCEPTION) +// { +// const char * LOC = "FIELD::getLength() const : "; +// BEGIN_OF_MED(LOC); + +// // The field has to be initilised by a non empty support and a +// // number of components = 1 and its value type has to be set to MED_REEL64 +// // (ie a FIELD) + +// if ((_support == (SUPPORT *) NULL) || (_numberOfComponents != 1) || (_valueType != MED_EN::MED_REEL64)) +// throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to 1 and a value type set to MED_REEL64")); + +// END_OF_MED(LOC); +// } + +// /*! +// Fill values array with normal values. +// */ +// template +// void FIELD::getNormal() const throw (MEDEXCEPTION) +// { +// const char * LOC = "FIELD::getNormal() const : "; +// BEGIN_OF_MED(LOC); + +// // The field has to be initilised by a non empty support and a +// // number of components = 1 and its value type has to be set to MED_REEL64 +// // (ie a FIELD) + +// if (_support == (SUPPORT *) NULL) +// throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to the space dimension and a value type set to MED_REEL64")); + +// int dim_space = _support->getMesh()->getSpaceDimension(); + +// if ((_numberOfComponents != dim_space) || (_valueType != MED_EN::MED_REEL64)) +// throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to the space dimension and a value type set to MED_REEL64")); + +// END_OF_MED(LOC); +// } + +// /*! +// Fill values array with barycenter values. +// */ +// template +// void FIELD::getBarycenter() const throw (MEDEXCEPTION) +// { +// const char * LOC = "FIELD::getBarycenter() const : "; +// BEGIN_OF_MED(LOC); + +// // The field has to be initilised by a non empty support and a number of +// //components = space dimension and its value type has to be set to MED_REEL64 +// // (ie a FIELD) + +// if (_support == (SUPPORT *) NULL) +// throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to the space dimension and a value type set to MED_REEL64")); + +// int dim_space = _support->getMesh()->getSpaceDimension(); + +// if ((_numberOfComponents != dim_space) || (_valueType != MED_EN::MED_REEL64)) +// throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The field has to be initialised with a non empty support, a number of components set to the space dimension and a value type set to MED_REEL64")); + +// END_OF_MED(LOC); +// } /*! Fill array by using T_Analytic. @@ -3475,9 +4115,16 @@ void FIELD::fillFromAnalytic(myFuncType f) throw (MEDEXCEPTI else { barycenterField = mesh->getBarycenter(_support); - bary=barycenterField->getValue(); + bary = barycenterField->getValue(); + //for(i=0; i::fillFromAnalytic(myFuncType f) throw (MEDEXCEPTI delete [] xyz[j]; delete [] xyz; } + /*! Execute a function on _values on 'this' and put the result on a newly created field that has to be deallocated. WARNING : "this" must have allocated its array by setting this->_support and this->_numberOfComponents properly. Typically you should use it on a field built with constructor FIELD::FIELD(SUPPORT *,int nbOfComponents) */ - template - FIELD *FIELD::execFunc(int nbOfComponents, myFuncType2 f) throw (MEDEXCEPTION) +template +FIELD *FIELD::execFunc(int nbOfComponents, + myFuncType2 f) throw (MEDEXCEPTION) { FIELD *ret=new FIELD(_support,nbOfComponents); const T* valsInput=getValue(); diff --git a/src/MEDMEM/MEDMEM_FieldConvert.hxx b/src/MEDMEM/MEDMEM_FieldConvert.hxx index 996df2ebb..8ceeeb33e 100644 --- a/src/MEDMEM/MEDMEM_FieldConvert.hxx +++ b/src/MEDMEM/MEDMEM_FieldConvert.hxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #ifndef FIELD_CONVERT_HXX #define FIELD_CONVERT_HXX diff --git a/src/MEDMEM/MEDMEM_FieldForward.hxx b/src/MEDMEM/MEDMEM_FieldForward.hxx index 016ef2f42..713e71548 100644 --- a/src/MEDMEM/MEDMEM_FieldForward.hxx +++ b/src/MEDMEM/MEDMEM_FieldForward.hxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #ifndef FIELD_FORWARD #define FIELD_FORWARD diff --git a/src/MEDMEM/MEDMEM_Formulae.hxx b/src/MEDMEM/MEDMEM_Formulae.hxx deleted file mode 100644 index 61bf75b7c..000000000 --- a/src/MEDMEM/MEDMEM_Formulae.hxx +++ /dev/null @@ -1,367 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#ifndef MEDMEM_FORMULAE -#define MEDMEM_FORMULAE - -#include - -inline void CalculateBarycenterDyn(const double **pts, int nbPts, int dim, double *bary); - -inline double CalculateAreaForPolyg(const double **coords, int nbOfPtsInPolygs, int spaceDim); - -inline double CalculateAreaForTria(const double *p1, const double *p2, const double *p3,int spaceDim) -{ - if (spaceDim==2) - return (-((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1]))/2.0); - else - return (sqrt(((p2[1]-p1[1])*(p3[2]-p1[2]) - (p3[1]-p1[1])*(p2[2]-p1[2]))* - ((p2[1]-p1[1])*(p3[2]-p1[2]) - (p3[1]-p1[1])*(p2[2]-p1[2])) + - ((p3[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p3[2]-p1[2]))* - ((p3[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p3[2]-p1[2])) + - ((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1]))* - ((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1])))/2.0); -} - -inline double CalculateAreaForQuad(const double *p1, const double *p2, const double *p3, const double *p4, int spaceDim) -{ - if (spaceDim==2) - { - double a1 = (p2[0]-p1[0])/4.0, a2 = (p2[1]-p1[1])/4.0; - double b1 = (p3[0]-p4[0])/4.0, b2 = (p3[1]-p4[1])/4.0; - double c1 = (p3[0]-p2[0])/4.0, c2 = (p3[1]-p2[1])/4.0; - double d1 = (p4[0]-p1[0])/4.0, d2 = (p4[1]-p1[1])/4.0; - - return (- 4.0*(b1*c2 - c1*b2 + a1*c2 - c1*a2 + b1*d2 - - d1*b2 + a1*d2 - d1*a2)); - } - else - { - return ((sqrt(((p2[1]-p1[1])*(p4[2]-p1[2]) - (p4[1]-p1[1])*(p2[2]-p1[2]))* - ((p2[1]-p1[1])*(p4[2]-p1[2]) - (p4[1]-p1[1])*(p2[2]-p1[2])) + - ((p4[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p4[2]-p1[2]))* - ((p4[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p4[2]-p1[2])) + - ((p2[0]-p1[0])*(p4[1]-p1[1]) - (p4[0]-p1[0])*(p2[1]-p1[1]))* - ((p2[0]-p1[0])*(p4[1]-p1[1]) - (p4[0]-p1[0])*(p2[1]-p1[1]))) + - sqrt(((p4[1]-p3[1])*(p2[2]-p3[2]) - (p2[1]-p3[1])*(p4[2]-p3[2]))* - ((p4[1]-p3[1])*(p2[2]-p3[2]) - (p2[1]-p3[1])*(p4[2]-p3[2])) + - ((p2[0]-p3[0])*(p4[2]-p3[2]) - (p4[0]-p3[0])*(p2[2]-p3[2]))* - ((p2[0]-p3[0])*(p4[2]-p3[2]) - (p4[0]-p3[0])*(p2[2]-p3[2])) + - ((p4[0]-p3[0])*(p2[1]-p3[1]) - (p2[0]-p3[0])*(p4[1]-p3[1]))* - ((p4[0]-p3[0])*(p2[1]-p3[1]) - (p2[0]-p3[0])*(p4[1]-p3[1]))))/2.0); - } -} - -inline void CalculateNormalForTria(const double *p1, const double *p2, const double *p3, double *normal) -{ - normal[0] = ((p2[1]-p1[1])*(p3[2]-p1[2]) - (p3[1]-p1[1])*(p2[2]-p1[2]))/2.0; - normal[1] = ((p3[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p3[2]-p1[2]))/2.0; - normal[2] = ((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1]))/2.0; -} - -inline void CalculateNormalForQuad(const double *p1, const double *p2, const double *p3, const double *p4, double *normal) -{ - double xnormal1 = (p2[1]-p1[1])*(p4[2]-p1[2]) - (p4[1]-p1[1])*(p2[2]-p1[2]); - double xnormal2 = (p4[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p4[2]-p1[2]); - double xnormal3 = (p2[0]-p1[0])*(p4[1]-p1[1]) - (p4[0]-p1[0])*(p2[1]-p1[1]); - double xarea = sqrt(xnormal1*xnormal1 + xnormal2*xnormal2 + xnormal3*xnormal3); - xnormal1 = xnormal1/xarea; - xnormal2 = xnormal2/xarea; - xnormal3 = xnormal3/xarea; - xarea = CalculateAreaForQuad(p1,p2,p3,p4,3); - normal[0] = xnormal1*xarea ; - normal[1] = xnormal2*xarea ; - normal[2] = xnormal3*xarea ; -} - -inline void CalculateNormalForPolyg(const double **coords, int nbOfPtsInPolygs, double *normal) -{ - double coordOfBary[3]; - CalculateBarycenterDyn(coords,nbOfPtsInPolygs,3,coordOfBary); - double xnormal1 = (coords[0][1]-coords[1][1])*(coordOfBary[2]-coords[1][2])-(coords[0][2]-coords[1][2])*(coordOfBary[1]-coords[1][1]); - double xnormal2 = (coords[0][2]-coords[1][2])*(coordOfBary[0]-coords[1][0])-(coords[0][0]-coords[1][0])*(coordOfBary[2]-coords[1][2]); - double xnormal3 = (coords[0][0]-coords[1][0])*(coordOfBary[1]-coords[1][1])-(coords[0][1]-coords[1][1])*(coordOfBary[0]-coords[1][0]); - double xarea = sqrt(xnormal1*xnormal1 + xnormal2*xnormal2 + xnormal3*xnormal3); - xnormal1 = xnormal1/xarea; - xnormal2 = xnormal2/xarea; - xnormal3 = xnormal3/xarea; - xarea = CalculateAreaForPolyg(coords,nbOfPtsInPolygs,3); - normal[0] = xnormal1*xarea ; - normal[1] = xnormal2*xarea ; - normal[2] = xnormal3*xarea ; -} - -inline double CalculateAreaForPolyg(const double **coords, int nbOfPtsInPolygs, int spaceDim) -{ - double coordOfBary[3]; - CalculateBarycenterDyn(coords,nbOfPtsInPolygs,spaceDim,coordOfBary); - double ret=0.; - for(int i=0;i -inline double addComponentsOfVec(const double **pts, int rk) -{ - return pts[N-1][rk]+addComponentsOfVec(pts,rk); -} - -template<> -inline double addComponentsOfVec<1>(const double **pts, int rk) -{ - return pts[0][rk]; -} - -template -inline void CalculateBarycenter(const double **pts, double *bary) -{ - bary[DIM-1]=addComponentsOfVec(pts,DIM-1)/N; - CalculateBarycenter(pts,bary); -} - -template<> -inline void CalculateBarycenter<2,0>(const double **pts, double *bary) { } - -template<> -inline void CalculateBarycenter<3,0>(const double **pts, double *bary) { } - -template<> -inline void CalculateBarycenter<4,0>(const double **pts, double *bary) { } - -template<> -inline void CalculateBarycenter<5,0>(const double **pts, double *bary) { } - -template<> -inline void CalculateBarycenter<6,0>(const double **pts, double *bary) { } - -template<> -inline void CalculateBarycenter<7,0>(const double **pts, double *bary) { } - -template<> -inline void CalculateBarycenter<8,0>(const double **pts, double *bary) { } - -inline void CalculateBarycenterDyn(const double **pts, int nbPts, int dim, double *bary) -{ - for(int i=0;i +#include #include "MEDMEM_define.hxx" #include "MEDMEM_Exception.hxx" #include "MEDMEM_ArrayInterface.hxx" @@ -33,7 +37,7 @@ using namespace MED_EN; namespace MEDMEM { - class GAUSS_LOCALIZATION_ { + class MEDMEM_EXPORT GAUSS_LOCALIZATION_ { public: virtual MED_EN::medModeSwitch getInterlacingType() const {return MED_EN::MED_UNDEFINED_INTERLACE;} virtual ~GAUSS_LOCALIZATION_() {}; //Indispensable pour détruire le vrai objet pointé @@ -92,8 +96,8 @@ namespace MEDMEM { string getName() const {return _locName;} MED_EN::medGeometryElement getType() const {return _typeGeo;} int getNbGauss() const {return _nGauss;} - ArrayNoGauss getRefCoo () const {return _cooRef;} //Ces tableaux sont petits - ArrayNoGauss getGsCoo () const {return _cooGauss;} //Ces tableaux sont petits + const ArrayNoGauss& getRefCoo () const {return _cooRef;} //Ces tableaux sont petits + const ArrayNoGauss& getGsCoo () const {return _cooGauss;} //Ces tableaux sont petits vector getWeight () const {return _wg;} //Ces tableaux sont petits inline MED_EN::medModeSwitch getInterlacingType() const { return _interlacingType;} @@ -101,7 +105,7 @@ namespace MEDMEM { template GAUSS_LOCALIZATION::GAUSS_LOCALIZATION() throw (MEDEXCEPTION) : _typeGeo(MED_EN::MED_NONE), _nGauss(-1), _interlacingType( SET_INTERLACING_TYPE::_interlacingType) - {}; + {} template GAUSS_LOCALIZATION::GAUSS_LOCALIZATION(const string & locName, const MED_EN::medGeometryElement typeGeo, @@ -113,7 +117,7 @@ namespace MEDMEM { _interlacingType(SET_INTERLACING_TYPE::_interlacingType) { const char * LOC = "GAUSS_LOCALIZATION(locName,typeGeo, nGauss, const ArrayNoGauss & cooRef,..) : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_cooRef.getDim() != _cooGauss.getDim() ) throw MEDEXCEPTION( LOCALIZED( STRING(LOC) <<"cooRef and cooGaus must have the same number of components")) ; @@ -129,15 +133,16 @@ namespace MEDMEM { throw MEDEXCEPTION( LOCALIZED( STRING(LOC) <<"wg must be of size nGauss " << _nGauss )); - END_OF(LOC); - }; + END_OF_MED(LOC); + } - template GAUSS_LOCALIZATION::GAUSS_LOCALIZATION(const string & locName, - const MED_EN::medGeometryElement typeGeo, - const int nGauss, - const double * const cooRef, - const double * const cooGauss, - const double * const wg) throw (MEDEXCEPTION) : + template GAUSS_LOCALIZATION::GAUSS_LOCALIZATION + (const string & locName, + const MED_EN::medGeometryElement typeGeo, + const int nGauss, + const double * const cooRef, + const double * const cooGauss, + const double * const wg) throw (MEDEXCEPTION) : _locName(locName),_typeGeo(typeGeo),_nGauss(nGauss), _cooRef(ArrayNoGauss(const_cast(cooRef),typeGeo/100,typeGeo%100)), _cooGauss(ArrayNoGauss(const_cast(cooGauss),typeGeo/100,_nGauss)), @@ -145,7 +150,7 @@ namespace MEDMEM { _interlacingType(SET_INTERLACING_TYPE::_interlacingType) { const char * LOC = "GAUSS_LOCALIZATION(locName,typeGeo, nGauss, const double * cooRef,..) :"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_cooRef.getDim() != _cooGauss.getDim() ) throw MEDEXCEPTION( LOCALIZED( STRING(LOC) <<"cooRef and cooGaus must have the same number of components")) ; @@ -159,8 +164,8 @@ namespace MEDMEM { if (_wg.size() != _nGauss ) throw MEDEXCEPTION( LOCALIZED( STRING(LOC) <<"wg must be of size nGauss " << _nGauss )); - END_OF(LOC); - }; + END_OF_MED(LOC); + } template GAUSS_LOCALIZATION & GAUSS_LOCALIZATION::operator=(const GAUSS_LOCALIZATION & gaussLoc) @@ -170,8 +175,10 @@ namespace MEDMEM { _locName = gaussLoc._locName; _typeGeo = gaussLoc._typeGeo; _nGauss = gaussLoc._nGauss; - _cooRef = ArrayNoGauss(gaussLoc._cooRef); //utilisation de la copie superficielle par défaut n'est pas une bonne idée - _cooGauss = ArrayNoGauss(gaussLoc._cooGauss); //dans l'opérateur = de MEDnArray + //_cooRef.setPtr((double*)gaussLoc._cooRef.getPtr(), false, true); //utilisation de la copie superficielle par défaut n'est pas une bonne idée + //_cooGauss.setPtr((double*)gaussLoc._cooGauss.getPtr(), false, true); //dans l'opérateur = de MEDnArray + _cooRef = gaussLoc._cooRef; + _cooGauss = gaussLoc._cooGauss; _wg = gaussLoc._wg; return *this; diff --git a/src/MEDMEM/MEDMEM_GenDriver.cxx b/src/MEDMEM/MEDMEM_GenDriver.cxx index 6d83a0e2c..9e27a8b20 100644 --- a/src/MEDMEM/MEDMEM_GenDriver.cxx +++ b/src/MEDMEM/MEDMEM_GenDriver.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_GenDriver.hxx" #include "MEDMEM_STRING.hxx" @@ -25,18 +27,23 @@ using namespace std; using namespace MEDMEM; using namespace MED_EN; -GENDRIVER::GENDRIVER(): _id(MED_INVALID), - _fileName(""), - _accessMode( (med_mode_acces) MED_INVALID ), - _status(MED_INVALID), - _driverType(NO_DRIVER) {} +GENDRIVER::GENDRIVER(driverTypes driverType): + _id(MED_INVALID), + _fileName(""), + _accessMode( (med_mode_acces) MED_INVALID ), + _status(MED_INVALID), + _driverType(driverType) {} GENDRIVER::GENDRIVER(const string & fileName, - med_mode_acces accessMode=(med_mode_acces) MED_INVALID): _id(MED_INVALID), - _fileName(fileName), - _accessMode(accessMode), - _status(MED_CLOSED), - _driverType(NO_DRIVER) {} + med_mode_acces accessMode/*=(med_mode_acces) MED_INVALID*/, + driverTypes driverType) + : _id(MED_INVALID), + _fileName(fileName), + _accessMode(accessMode), + _status(MED_CLOSED), + _driverType(driverType) +{ +} GENDRIVER::GENDRIVER(const GENDRIVER & genDriver): //_id(MED_INVALID), @@ -52,56 +59,58 @@ GENDRIVER::~GENDRIVER() {} GENDRIVER & MEDMEM::GENDRIVER::operator=(const GENDRIVER & genDriver) { - const char * LOC = " GENDRIVER & GENDRIVER::operator=(const GENDRIVER & genDriver) : "; - - BEGIN_OF(LOC); + const char* LOC = " GENDRIVER & GENDRIVER::operator=(const GENDRIVER & genDriver) : "; + BEGIN_OF_MED(LOC); _fileName = genDriver._fileName; _accessMode = genDriver._accessMode; _status = genDriver._status; _id = genDriver._id; + _driverType = genDriver._driverType; return *this; } -void GENDRIVER::writeFrom ( void ) {}; -void GENDRIVER::readFileStruct ( void ) {}; +void GENDRIVER::writeFrom ( void ) const {} +void GENDRIVER::readFileStruct ( void ) {} -void GENDRIVER::setMeshName (const string & ) {}; -void GENDRIVER::setFieldName (const string & ) {}; +void GENDRIVER::setMeshName (const string & ) {} +string GENDRIVER::getMeshName() const { return ""; } +void GENDRIVER::setFieldName (const string & ) {} +string GENDRIVER::getFieldName() const { return ""; } -void GENDRIVER::openAppend ( void ) {}; -void GENDRIVER::writeAppend ( void ) const {}; +void GENDRIVER::openAppend ( void ) {} +void GENDRIVER::writeAppend ( void ) const {} -void GENDRIVER::setId ( int id ) { - const char * LOC = "void GENDRIVER::setId ( int id ) : "; - - BEGIN_OF(LOC); +void GENDRIVER::setId ( int id ) +{ + const char* LOC = "void GENDRIVER::setId ( int id ) : "; + BEGIN_OF_MED(LOC); if ( id >= 0 ) _id=id; else _id = MED_INVALID ; - END_OF(LOC); -}; - -int GENDRIVER::getId ( void) const { - const char * LOC = "int GENDRIVER::getId ( void) const "; + END_OF_MED(LOC); +} - BEGIN_OF(LOC); +int GENDRIVER::getId ( void) const +{ + const char* LOC = "int GENDRIVER::getId ( void) const "; + BEGIN_OF_MED(LOC); return _id ; -}; +} string GENDRIVER::getFileName() const { - const char * LOC = "string GENDRIVER::getFileName() const : "; - BEGIN_OF(LOC); + const char* LOC = "string GENDRIVER::getFileName() const : "; + BEGIN_OF_MED(LOC); return _fileName; } -void GENDRIVER::setFileName(const string & fileName) { - +void GENDRIVER::setFileName(const string & fileName) +{ const char * LOC = "void GENDRIVER::setFileName(const string & fileName) : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if ( _status == MED_OPENED ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<" File |" << _fileName @@ -109,16 +118,15 @@ void GENDRIVER::setFileName(const string & fileName) { else _fileName = fileName; - END_OF(LOC); + END_OF_MED(LOC); } -med_mode_acces GENDRIVER::getAccessMode() const { - - const char * LOC = "med_mode_acces GENDRIVER::getAccessMode() const : "; - - BEGIN_OF(LOC); +med_mode_acces GENDRIVER::getAccessMode() const +{ + const char* LOC = "med_mode_acces GENDRIVER::getAccessMode() const : "; + BEGIN_OF_MED(LOC); return _accessMode; } @@ -127,18 +135,15 @@ ostream & MEDMEM::operator<<(ostream &os,const GENDRIVER & drv) { switch (drv._accessMode) { - case MED_RDONLY : + case RDONLY : os<<"C'est un IO de READ"<read( genDriver ) if object was not passed to genDriver, +// then object asks driverFactory to create a driver initialized by object +// and fills the new driver up using merge( genDriver ) +void GENDRIVER::merge ( const GENDRIVER &genDriver ) +{ + if ( _id == MED_INVALID ) + _id = genDriver._id; + if ( _fileName.empty() ) + _fileName = genDriver._fileName; + if ( _accessMode == MED_INVALID ) + _accessMode = genDriver._accessMode; + + if ( getMeshName().empty() ) + setMeshName( genDriver.getMeshName() ); + if ( getFieldName().empty() ) + setFieldName( genDriver.getFieldName() ); +} diff --git a/src/MEDMEM/MEDMEM_GenDriver.hxx b/src/MEDMEM/MEDMEM_GenDriver.hxx index b84a452a1..ed415c7d2 100644 --- a/src/MEDMEM/MEDMEM_GenDriver.hxx +++ b/src/MEDMEM/MEDMEM_GenDriver.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef GENDRIVER_HXX #define GENDRIVER_HXX @@ -38,12 +40,15 @@ using namespace std; */ namespace MEDMEM { -/* Modify the following line to add a new driver type (step 1) */ -typedef enum { MED_DRIVER = 0, GIBI_DRIVER = 1, PORFLOW_DRIVER = 2, ENSIGHT_DRIVER = 250, VTK_DRIVER = 254, ASCII_DRIVER = 3, NO_DRIVER = 255 } driverTypes; + /* Modify the following line to add a new driver type (step 1) */ + typedef enum { MED_DRIVER = 0, GIBI_DRIVER = 1, PORFLOW_DRIVER = 2, + ENSIGHT_DRIVER = 250, VTK_DRIVER = 254, ASCII_DRIVER = 3, + NO_DRIVER = 255 } driverTypes; + class GENDRIVER; - ostream & operator<<(ostream &os,const GENDRIVER &genDriver); + MEDMEM_EXPORT ostream & operator<<(ostream &os,const GENDRIVER &genDriver); -class MEDMEM_EXPORT GENDRIVER { + class MEDMEM_EXPORT GENDRIVER { protected : @@ -60,11 +65,12 @@ public: /*! Constructor. */ - GENDRIVER(); + GENDRIVER(driverTypes driverType); /*! Constructor. */ - GENDRIVER(const string & fileName,MED_EN::med_mode_acces accessMode); + GENDRIVER(const string & fileName, MED_EN::med_mode_acces accessMode, + driverTypes driverType); /*! Copy constructor. */ @@ -83,7 +89,7 @@ public: /*! Operator << : put GENDRIVER object information to the given stream */ - friend MEDMEM_EXPORT ostream & operator<<(ostream &os,const GENDRIVER &genDriver); + friend ostream & operator<<(ostream &os,const GENDRIVER &genDriver); bool operator ==(const GENDRIVER &genDriver) const; /*! @@ -116,22 +122,32 @@ public: // needed to duplicate arrays virtual GENDRIVER * copy ( void ) const = 0 ; + // Take missing data from other driver. + // Is for object->read( genDriver ) if object was not passed to genDriver + // (i.e. genDriver has been created through constructor without parameters), + // then object asks driverFactory to create a driver initialized by object + // and fills the new driver up using merge( genDriver ). + // Needed for drivers possessing own data + virtual void merge ( const GENDRIVER &genDriver ); + // MED related part - virtual void writeFrom ( void ); + virtual void writeFrom ( void ) const; virtual void readFileStruct ( void ); // MESH related Part virtual void setMeshName ( const string & meshName); - virtual string getMeshName() const { return string(""); } + virtual string getMeshName() const; // FIELD related Part virtual void setFieldName ( const string & fieldName); + virtual string getFieldName() const; void setId ( int id = MED_INVALID ); int getId ( void ) const ; string getFileName () const; - void setFileName ( const string & fileName); + virtual void setFileName ( const string & fileName); virtual MED_EN::med_mode_acces getAccessMode() const; + driverTypes getDriverType() const { return _driverType; } }; -}; +} #endif /* GENDRIVER_HXX */ diff --git a/src/MEDMEM/MEDMEM_GibiMeshDriver.cxx b/src/MEDMEM/MEDMEM_GibiMeshDriver.cxx index d062be8bb..836ef3dc3 100644 --- a/src/MEDMEM/MEDMEM_GibiMeshDriver.cxx +++ b/src/MEDMEM/MEDMEM_GibiMeshDriver.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include #include @@ -61,10 +63,10 @@ using namespace MEDMEM; // to see full dump of RESULTATS STRUCTURE INTERMEDIAIRES #ifdef _DEBUG_ -// #undef MESSAGE -// #define MESSAGE(txt) std::cout << txt << endl; -// #undef INFOS -// #define INFOS(txt) std::cout << txt << endl; +// #undef MESSAGE_MED +// #define MESSAGE_MED(txt) std::cout << txt << endl; +// #undef INFOS_MED +// #define INFOS_MED(txt) std::cout << txt << endl; #endif // Every memory allocation made in the MedDriver members function are desallocated in the Mesh destructor @@ -159,13 +161,45 @@ static int getGroupId(const vector& support_ids, _intermediateMED* medi) //purpose : //======================================================================= -#ifdef GIBI_READ_ONLY_NAMED_FIELD +//#ifdef GIBI_READ_ONLY_NAMED_FIELD static inline bool isNamedObject( int obj_index, const vector& indices_objets_nommes ) { return ( std::find( indices_objets_nommes.begin(), indices_objets_nommes.end(), obj_index) != indices_objets_nommes.end() ); } -#endif +//#endif + +//======================================================================= +//function : setFieldNames +//purpose : set field names +//======================================================================= + +static void setFieldNames(const vector< _fieldBase* >& fields, + const vector& objets_nommes, + const vector& indices_objets_nommes) +{ + // set field names + int i; + set fnames; + for ( i = 0; i < indices_objets_nommes.size(); ++i ) { + int fieldIndex = indices_objets_nommes[ i ]; + fnames.insert( objets_nommes[ i ]); + if ( fields[ fieldIndex - 1 ] ) + fields[ fieldIndex - 1 ]->_name = objets_nommes[ i ]; + } + int noNameIndex = 0; + for ( int i = 0; i < fields.size(); ++i ) { + if ( !fields[ i ] ) { + if ( !isNamedObject( i+1, indices_objets_nommes )) + ++noNameIndex; + } + else if ( fields[ i ]->_name.empty() ) { + do { + fields[ i ]->_name = STRING("F_") << ++noNameIndex; + } while ( !fnames.insert( fields[ i ]->_name ).second ); + } + } +} //======================================================================= //function : read @@ -173,13 +207,13 @@ static inline bool isNamedObject( int obj_index, const vector& indices_obje //======================================================================= #define GIBI_EQUAL(var_str, stat_str) \ - (strncmp (var_str, stat_str, sizeof(stat_str)-1) == 0) + (strncmp (var_str, stat_str, strlen(stat_str)) == 0) #define DUMP_LINE_NB " on line " << _lineNb bool GIBI_MESH_RDONLY_DRIVER::readFile (_intermediateMED* medi, bool readFields ) { - const char * LOC = "GIBI_MESH_RDONLY_DRIVER::readFile() : " ; - BEGIN_OF(LOC); + const char* LOC = "GIBI_MESH_RDONLY_DRIVER::readFile() : "; + BEGIN_OF_MED(LOC); // LECTURE DES DONNEES DS FICHIER GIBI @@ -229,21 +263,21 @@ bool GIBI_MESH_RDONLY_DRIVER::readFile (_intermediateMED* medi, bool readFields const char* s = " NIVEAU 15 NIVEAU ERREUR 0 DIMENSION"; space_dimension = atoi( ligne + strlen( s ) + 1 ); if ( !GIBI_EQUAL( ligne, " NIVEAU" ) || space_dimension < 1 ) { - INFOS( " Could not read file: syntax error in type 4 record" << DUMP_LINE_NB ); + INFOS_MED( " Could not read file: syntax error in type 4 record" << DUMP_LINE_NB ); return false; } } else if (numero_enregistrement == ENREG_TYPE_2 ) { if ( space_dimension == 0 ) { - INFOS( "Missing ENREGISTREMENT DE TYPE 4" << DUMP_LINE_NB ); + INFOS_MED( "Missing ENREGISTREMENT DE TYPE 4" << DUMP_LINE_NB ); return false; } // FORMAT(' PILE NUMERO',I4,'NBRE OBJETS NOMMES',I8,'NBRE OBJETS',I8) getNextLine(ligne); const char *s1 = " PILE NUMERO", *s2 = "NBRE OBJETS NOMMES", *s3 = "NBRE OBJETS"; if ( ! GIBI_EQUAL( ligne, s1 ) ) { - INFOS( " Could not read file: error in type 2 record. " << ligne << DUMP_LINE_NB ); + INFOS_MED( " Could not read file: error in type 2 record. " << ligne << DUMP_LINE_NB ); return false; } ligne = ligne + strlen(s1); @@ -253,7 +287,7 @@ bool GIBI_MESH_RDONLY_DRIVER::readFile (_intermediateMED* medi, bool readFields ligne = ligne + 8 + strlen(s3); nb_objets = atoi( ligne ); if ( nb_objets_nommes<0 || nb_objets<0 ) { - INFOS(" Could not read file: " << nb_objets << " " <points.insert(make_pair(no.number, no)); ma.sommets[n]=p_no.first; } - ma.ordre = ++order; - p=medi->maillage.insert(ma); - groupe.mailles[i] = p.first; // on stocke dans le groupe un iterateur sur la maille + ma.setOrdre( ++order ); + // on stocke dans le groupe un iterateur sur la maille + groupe.mailles[i] = medi->insert(ma); } } } // loop on groups @@ -392,7 +426,7 @@ bool GIBI_MESH_RDONLY_DRIVER::readFile (_intermediateMED* medi, bool readFields #ifdef _DEBUG cout << "Skip " << grp.nom << " of not supported CASTEM type: " << it->second << endl; #endif - //INFOS( "Skip " << grp.nom << " of not supported CASTEM type: " << it->second ); + //INFOS_MED( "Skip " << grp.nom << " of not supported CASTEM type: " << it->second ); } } @@ -409,7 +443,7 @@ bool GIBI_MESH_RDONLY_DRIVER::readFile (_intermediateMED* medi, bool readFields nb_indices = atoi ( ligne ); if (nb_indices != nb_objets) { - INFOS("Erreur de lecture dans enregistrement de pile " << + INFOS_MED("Erreur de lecture dans enregistrement de pile " << PILE_NOEUDS << DUMP_LINE_NB ); return false; } @@ -437,7 +471,7 @@ bool GIBI_MESH_RDONLY_DRIVER::readFile (_intermediateMED* medi, bool readFields unsigned nb_reels = atoi( ligne ); // PROVISOIRE : certains fichier gibi n`ont if (nb_reels < numero_noeuds.size()*(space_dimension)) { - INFOS("Erreur de lecture dans enregistrement de pile " << + INFOS_MED("Erreur de lecture dans enregistrement de pile " << PILE_COORDONNEES << DUMP_LINE_NB ); return false; } @@ -475,7 +509,7 @@ bool GIBI_MESH_RDONLY_DRIVER::readFile (_intermediateMED* medi, bool readFields #ifdef GIBI_READ_ONLY_NAMED_FIELD ignoreField = !isNamedObject( objet+1, indices_objets_nommes ); if ( ignoreField ) - INFOS("Skip non-named field " << objet+1 << DUMP_LINE_NB); + INFOS_MED("Skip non-named field " << objet+1 << DUMP_LINE_NB); #endif // EXAMPLE ( with no values ) @@ -496,7 +530,7 @@ bool GIBI_MESH_RDONLY_DRIVER::readFile (_intermediateMED* medi, bool readFields next(); // ignore IFOUR int nb_attr = getInt(); if ( nb_sub < 0 || total_nb_comp < 0 || nb_attr < 0 ) { - INFOS("Error of field reading: wrong nb of components " + INFOS_MED("Error of field reading: wrong nb of components " << nb_sub << " " << total_nb_comp << DUMP_LINE_NB); return false; } @@ -511,14 +545,14 @@ bool GIBI_MESH_RDONLY_DRIVER::readFile (_intermediateMED* medi, bool readFields { support_ids[ i_sub ] = -getInt(); next(); // (a) reference to support if ( support_ids[ i_sub ] < 1 || support_ids[ i_sub ] > medi->groupes.size() ) { - INFOS("Error of field reading: wrong mesh reference "<< + INFOS_MED("Error of field reading: wrong mesh reference "<< support_ids[ i_sub ] << DUMP_LINE_NB ); return false; } nb_values[ i_sub ] = getInt(); next(); // (b) nb points total_nb_values += nb_values[ i_sub ]; if ( nb_values[ i_sub ] < 0 ) { - INFOS(" Wrong nb of points: " << nb_values[ i_sub ] << DUMP_LINE_NB ); + INFOS_MED(" Wrong nb of points: " << nb_values[ i_sub ] << DUMP_LINE_NB ); return false; } nb_comps[ i_sub ] = getInt(); next(); // (c) nb of components in i_sub @@ -539,7 +573,7 @@ bool GIBI_MESH_RDONLY_DRIVER::readFile (_intermediateMED* medi, bool readFields fdouble->_sub[ i_sub ].setData( nb_comps[ i_sub ], support_ids[ i_sub ] ); for ( i_comp = 0; i_comp < nb_comps[ i_sub ]; ++i_comp, next() ) { - ASSERT( more() ); + ASSERT_MED( more() ); // store component name if ( fdouble ) fdouble->_sub[ i_sub ].compName( i_comp ) = getName(); @@ -578,11 +612,7 @@ bool GIBI_MESH_RDONLY_DRIVER::readFile (_intermediateMED* medi, bool readFields } // end loop on field objects // set field names - for ( i = 0; i < nb_objets_nommes; ++i ) { - int fieldIndex = indices_objets_nommes[ i ]; - if ( fields[ fieldIndex - 1 ] ) - fields[ fieldIndex - 1 ]->_name = objets_nommes[ i ]; - } + setFieldNames( fields, objets_nommes, indices_objets_nommes ); } // Fin numero_pile == PILE_NODES_FIELD @@ -619,12 +649,12 @@ bool GIBI_MESH_RDONLY_DRIVER::readFile (_intermediateMED* medi, bool readFields #ifdef GIBI_READ_ONLY_NAMED_FIELD ignoreField = !isNamedObject( objet+1, indices_objets_nommes ); if ( ignoreField ) - INFOS("Skip non-named field " << objet+1 << DUMP_LINE_NB); + INFOS_MED("Skip non-named field " << objet+1 << DUMP_LINE_NB); #endif initIntReading( 4 ); int i_sub, nb_sub = getInt(); // (1) 2 6 if ( nb_sub < 1 ) { - INFOS("Error of field reading: wrong nb of subcomponents " << + INFOS_MED("Error of field reading: wrong nb of subcomponents " << nb_sub << DUMP_LINE_NB ); return false; } @@ -652,12 +682,12 @@ bool GIBI_MESH_RDONLY_DRIVER::readFile (_intermediateMED* medi, bool readFields for ( i = 0; i < 6; ++i ) // ignore 6 ints, in example 0 0 0 -2 0 3 next(); if ( support_ids[ i_sub ] < 1 || support_ids[ i_sub ] > medi->groupes.size() ) { - INFOS("Error of field reading: wrong mesh reference "<< + INFOS_MED("Error of field reading: wrong mesh reference "<< support_ids[ i_sub ] << DUMP_LINE_NB ); return false; } - if ( nb_comp[ i_sub ] < 1 ) { - INFOS("Error of field reading: wrong nb of components " << + if ( nb_comp[ i_sub ] < 0 /*1*/ ) { // [SALOME platform 0019886] + INFOS_MED("Error of field reading: wrong nb of components " << nb_comp[ i_sub ] << DUMP_LINE_NB ); return false; } @@ -689,18 +719,18 @@ bool GIBI_MESH_RDONLY_DRIVER::readFile (_intermediateMED* medi, bool readFields comp_type[ index() ] = getName(); // component types must be the same if ( index() > 0 && comp_type[ index() ] != comp_type[ index() - 1] ) { - INFOS( "Error of field reading: diff component types <" + INFOS_MED( "Error of field reading: diff component types <" << comp_type[ index() ] << "> != <" << comp_type[ index() - 1 ] << ">" << DUMP_LINE_NB ); return false; } } // now type is known, create a field, one for all subs - bool isReal = ( comp_type[0] == "REAL*8" ); - if ( !ignoreField && !fbase ) { + bool isReal = (nb_comp[i_sub] > 0) ? (comp_type[0] == "REAL*8") : true; + if ( !ignoreField && !fbase && total_nb_comp ) { if ( !isReal ) { fbase = fint = new _field<int>( MED_INT32, nb_sub, total_nb_comp ); - INFOS( "Warning: read NOT REAL field, type <" << comp_type[0] << ">" + INFOS_MED( "Warning: read NOT REAL field, type <" << comp_type[0] << ">" << DUMP_LINE_NB); } else @@ -754,11 +784,7 @@ bool GIBI_MESH_RDONLY_DRIVER::readFile (_intermediateMED* medi, bool readFields } // end loop on field objects // set field names - for ( i = 0; i < nb_objets_nommes; ++i ) { - int fieldIndex = indices_objets_nommes[ i ] - 1; - if ( fields[ fieldIndex ]) - fields[ fieldIndex ]->_name = objets_nommes[ i ]; - } + setFieldNames( fields, objets_nommes, indices_objets_nommes ); } // numero_pile == PILE_FIELD && readFields @@ -772,43 +798,43 @@ bool GIBI_MESH_RDONLY_DRIVER::readFile (_intermediateMED* medi, bool readFields if ( donePiles.find( PILE_SOUS_MAILLAGE ) != donePiles.end() ) { if (donePiles.find( PILE_NOEUDS ) == donePiles.end() ) { - INFOS( " Missing pile " << PILE_NOEUDS ); + INFOS_MED( " Missing pile " << PILE_NOEUDS ); return false; } if (donePiles.find( PILE_COORDONNEES ) == donePiles.end()) { - INFOS( " Missing pile " << PILE_COORDONNEES ); + INFOS_MED( " Missing pile " << PILE_COORDONNEES ); return false; } } - END_OF(LOC); + END_OF_MED(LOC); return true; } GIBI_MESH_DRIVER::GIBI_MESH_DRIVER(): - GENDRIVER(), + GENDRIVER(GIBI_DRIVER), _ptrMesh(( MESH *) NULL), // A VOIR _medIdt(MED_INVALID), _meshName("") { - MESSAGE("GIBI_MESH_DRIVER()"); + MESSAGE_MED("GIBI_MESH_DRIVER()"); } GIBI_MESH_DRIVER::GIBI_MESH_DRIVER(const string & fileName, MESH * ptrMesh, MED_EN::med_mode_acces accessMode): - GENDRIVER(fileName,accessMode), + GENDRIVER(fileName, accessMode, GIBI_DRIVER), _ptrMesh(ptrMesh) // A VOIR _medIdt(MED_INVALID), { - MESSAGE( "GIBI_MESH_DRIVER(" << fileName <<","<<accessMode ); + MESSAGE_MED( "GIBI_MESH_DRIVER(" << fileName <<","<<accessMode ); // _meshName=fileName.substr(0,fileName.rfind(".")); // mesh name construction from fileName const string ext=".sauve"; // expected extension string::size_type pos=fileName.find(ext,0); string::size_type pos1=fileName.rfind('/'); _meshName = string(fileName,pos1+1,pos-pos1-1); //get rid of directory & extension - SCRUTE(_meshName); + SCRUTE_MED(_meshName); } GIBI_MESH_DRIVER::GIBI_MESH_DRIVER(const GIBI_MESH_DRIVER & driver): @@ -817,12 +843,12 @@ GIBI_MESH_DRIVER::GIBI_MESH_DRIVER(const GIBI_MESH_DRIVER & driver): // A VOIR _medIdt(MED_INVALID), _meshName(driver._meshName) { - MESSAGE("GIBI_MESH_DRIVER(const GIBI_MESH_DRIVER & driver)"); + MESSAGE_MED("GIBI_MESH_DRIVER(const GIBI_MESH_DRIVER & driver)"); } GIBI_MESH_DRIVER::~GIBI_MESH_DRIVER() { - MESSAGE("~GIBI_MESH_DRIVER()"); + MESSAGE_MED("~GIBI_MESH_DRIVER()"); } void GIBI_MESH_DRIVER::setMeshName(const string & meshName) { _meshName = meshName; }; string GIBI_MESH_DRIVER::getMeshName() const { return _meshName; }; @@ -836,12 +862,12 @@ GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER(): { } GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER(const string & fileName,MESH * ptrMesh): - GIBI_MESH_DRIVER(fileName,ptrMesh,MED_RDONLY), + GIBI_MESH_DRIVER(fileName,ptrMesh,RDONLY), _File (-1),_start(0L),_ptr (0L),_eptr (0L) { - MESSAGE("GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER" + MESSAGE_MED("GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER" "(const string & fileName, MESH * ptrMesh) has been created, " - << fileName << ", " << MED_RDONLY); + << fileName << ", " << RDONLY); } GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_RDONLY_DRIVER(const GIBI_MESH_RDONLY_DRIVER & driver): GIBI_MESH_DRIVER(driver) @@ -849,14 +875,15 @@ GIBI_MESH_DRIVER(driver) } GIBI_MESH_RDONLY_DRIVER::~GIBI_MESH_RDONLY_DRIVER() { - BEGIN_OF( "~GIBI_MESH_RDONLY_DRIVER()"); + const char* LOC = "~GIBI_MESH_RDONLY_DRIVER()"; + BEGIN_OF_MED(LOC); if (_File >= 0) { ::close (_File); if (_start != 0L) delete [] _start; } - MESSAGE("GIBI_MESH_RDONLY_DRIVER::~GIBI_MESH_RDONLY_DRIVER() has been destroyed"); + MESSAGE_MED("GIBI_MESH_RDONLY_DRIVER::~GIBI_MESH_RDONLY_DRIVER() has been destroyed"); } GENDRIVER * GIBI_MESH_RDONLY_DRIVER::copy(void) const { @@ -874,8 +901,11 @@ const int GIBI_BufferSize = 16184; // for non-stream input void GIBI_MESH_RDONLY_DRIVER::open() // throw (MEDEXCEPTION) { + if( _status == MED_OPENED ) + return; + const char * LOC = "GIBI_MESH_RDONLY_DRIVER::open()" ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // MED_EN::med_mode_acces aMode = getAccessMode(); // if ( aMode != MED_EN::MED_LECT && aMode != MED_EN::MED_REMP ) @@ -900,7 +930,7 @@ void GIBI_MESH_RDONLY_DRIVER::open() throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Could not open file "<<_fileName << " fd: " << _File)); } - END_OF(LOC); + END_OF_MED(LOC); } //======================================================================= @@ -910,20 +940,18 @@ void GIBI_MESH_RDONLY_DRIVER::open() void GIBI_MESH_RDONLY_DRIVER::close() { - const char * LOC = "GIBI_MESH_DRIVER::close() " ; - BEGIN_OF(LOC); - if ( _status == MED_OPENED) - { - if (_File >= 0) - { - ::close (_File); - if (_start != 0L) - delete [] _start; - _File = -1; - } - _status = MED_CLOSED; + const char* LOC = "GIBI_MESH_DRIVER::close() "; + BEGIN_OF_MED(LOC); + if ( _status == MED_OPENED) { + if (_File >= 0) { + ::close (_File); + if (_start != 0L) + delete [] _start; + _File = -1; } - END_OF(LOC); + _status = MED_CLOSED; + } + END_OF_MED(LOC); } //======================================================================= @@ -1050,7 +1078,7 @@ string GIBI_MESH_RDONLY_DRIVER::getName() const void GIBI_MESH_RDONLY_DRIVER::read(void) throw (MEDEXCEPTION) { const char * LOC = "_GIBI_RDONLY_DRIVER::read() : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status!=MED_OPENED) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The _idt of file " << _fileName << " is : " @@ -1062,17 +1090,17 @@ void GIBI_MESH_RDONLY_DRIVER::read(void) throw (MEDEXCEPTION) try { if ( readFile( &medi, false )) { // impression résultats - MESSAGE(LOC << "GIBI_MESH_RDONLY_DRIVER::read : RESULTATS STRUCTURE INTERMEDIAIRES : "); - MESSAGE(LOC << medi ); + MESSAGE_MED(LOC << "GIBI_MESH_RDONLY_DRIVER::read : RESULTATS STRUCTURE INTERMEDIAIRES : "); + MESSAGE_MED(LOC << medi ); fillMesh( &medi ); } } catch (MEDEXCEPTION &ex) { - INFOS( ex.what() ); + INFOS_MED( ex.what() ); } - END_OF(LOC); + END_OF_MED(LOC); } //======================================================================= @@ -1083,7 +1111,8 @@ void GIBI_MESH_RDONLY_DRIVER::read(void) throw (MEDEXCEPTION) static void getReverseVector (const medGeometryElement type, vector<pair<int,int> > & swapVec ) { - BEGIN_OF("void getReverseVector()"); + const char* LOC = "void getReverseVector()"; + BEGIN_OF_MED(LOC); swapVec.clear(); switch ( type ) { @@ -1152,7 +1181,7 @@ static void getReverseVector (const medGeometryElement type, break; default:; } - END_OF("void getReverseVector()"); + END_OF_MED(LOC); } //======================================================================= @@ -1211,7 +1240,7 @@ static inline void fixConnectivity(const _maille & aMaille ) if ( const int * conn = getGibi2MedConnectivity( aMaille.geometricType )) { _maille* ma = (_maille*) & aMaille; //cout << "###### BEFORE fixConnectivity() " << *ma << endl; - vector< _maille::iter > newSommets( ma->sommets.size() ); + vector< _maille::TNoeud > newSommets( ma->sommets.size() ); for ( int i = 0; i < newSommets.size(); ++i ) newSommets[ i ] = ma->sommets[ conn[ i ]]; ma->sommets = newSommets; @@ -1226,21 +1255,37 @@ static inline void fixConnectivity(const _maille & aMaille ) static void orientElements( _intermediateMED& medi ) { - MESSAGE("orientElements()"); - set<_maille>::iterator elemIt = medi.maillage.begin(); + MESSAGE_MED("orientElements()"); + + set<_maille>::const_iterator elemIt, elemEnd; int type = -100; vector< pair<int,int> > swapVec; - bool isQuadratic = ( getGibi2MedConnectivity( medi.maillage.rbegin()->geometricType )); - if ( elemIt->sommets[0]->second.coord.size() == 2 ) { // space dimension + bool isQuadratic = false; + _maillageByDimIterator maIt(medi); + while ( !isQuadratic && maIt.nextType() ) + isQuadratic = getGibi2MedConnectivity( maIt.type() ); + + if ( medi.points.begin()->second.coord.size() == 2 ) { // space dimension + // fix connectivity of quadratic edges + if ( isQuadratic ) { + if ( const set<_maille > * edges = _maillageByDimIterator( medi, 1 ).nextType() ) { + elemIt = edges->begin(), elemEnd = edges->end(); + for ( ; elemIt != elemEnd; ++elemIt ) + fixConnectivity( *elemIt ); + } + } // -------------------------- // Orient 2D faces clockwise // -------------------------- - for ( ; elemIt != medi.maillage.end(); elemIt++ ) - if ( elemIt->dimension() == 2 ) + _maillageByDimIterator faceMailIt( medi, 2 ); + while ( const set<_maille > * faces = faceMailIt.nextType() ) + { + elemIt = faces->begin(), elemEnd = faces->end(); + for ( ; elemIt != elemEnd; elemIt++ ) { // fix connectivity of quadratic faces if ( isQuadratic ) @@ -1288,12 +1333,7 @@ static void orientElements( _intermediateMED& medi ) } } } - else - { - // fix connectivity of quadratic edges - if ( isQuadratic ) - fixConnectivity( *elemIt ); - } + } } else { @@ -1313,8 +1353,8 @@ static void orientElements( _intermediateMED& medi ) for (unsigned int i=0; i!=medi.groupes.size(); ++i) { _groupe& grp = medi.groupes[i]; - _groupe::mailleIter maIt=grp.mailles.begin(); - if ( maIt==grp.mailles.end() || (*maIt)->dimension() != 2 ) + _groupe::TMailleIter maIt=grp.mailles.begin(); + if ( maIt==grp.mailles.end() || (*maIt)->dimensionWithPoly() != 2 ) continue; for(; maIt!=grp.mailles.end(); ++maIt) { if ( faces.insert( &(**maIt )).second ) { @@ -1342,7 +1382,7 @@ static void orientElements( _intermediateMED& medi ) while ( !linkFacesMap.empty() ) { if ( faceQueue.empty() ) { - ASSERT( !linkFacesMap.begin()->second.empty() ); + ASSERT_MED( !linkFacesMap.begin()->second.empty() ); faceQueue.push( linkFacesMap.begin()->second.front() ); } while ( !faceQueue.empty() ) @@ -1361,7 +1401,7 @@ static void orientElements( _intermediateMED& medi ) { list<const _maille*> & fList = lfIt->second; list<const _maille*>::iterator fIt = fList.begin(); - ASSERT( fIt != fList.end() ); + ASSERT_MED( fIt != fList.end() ); for ( ; fIt != fList.end(); fIt++, nbFaceByLink++ ) { ml.push_back( *fIt ); if ( *fIt != face ) // wrongly oriented neighbor face @@ -1380,7 +1420,7 @@ static void orientElements( _intermediateMED& medi ) } } badFace->reverse = true; // reverse - //INFOS( "REVERSE " << *badFace ); + //INFOS_MED( "REVERSE " << *badFace ); faceQueue.push( badFace ); } } @@ -1403,10 +1443,10 @@ static void orientElements( _intermediateMED& medi ) if ( nbFaceByLink > 2 ) { if ( manifold ) { list<const _maille*>::iterator i = ml.begin(); - INFOS(nbFaceByLink << " faces by 1 link:"); + INFOS_MED(nbFaceByLink << " faces by 1 link:"); for( ; i!= ml.end(); i++ ) { - INFOS("in object " << fgm[ *i ]->nom); - INFOS( **i ); + INFOS_MED("in object " << fgm[ *i ]->nom); + INFOS_MED( **i ); } } manifold = false; @@ -1416,108 +1456,117 @@ static void orientElements( _intermediateMED& medi ) } // while ( !linkFacesMap.empty() ) if ( !manifold ) - INFOS(" -> Non manifold mesh, faces orientation may be incorrect"); + INFOS_MED(" -> Non manifold mesh, faces orientation may be incorrect"); // --------------------------------------------------- - // Orient volumes according to MED conventions: - // normal of a bottom (first) face should be downward, // fix connectivity of quadratic elements // --------------------------------------------------- - for ( ; elemIt != medi.maillage.end(); elemIt++ ) { - - // GIBI connectivity -> MED one - if ( isQuadratic ) - fixConnectivity( *elemIt ); + for ( int dim = 1; dim <= 3; ++dim ) + { + _maillageByDimIterator mailIt( medi, dim ); + while ( const set<_maille > * elems = mailIt.nextType() ) + { + elemIt = elems->begin(), elemEnd = elems->end(); + for ( ; elemIt != elemEnd; elemIt++ ) + { + // GIBI connectivity -> MED one + if ( isQuadratic ) + fixConnectivity( *elemIt ); - // reverse quadratic faces - if ( elemIt->reverse ) { - if ( elemIt->geometricType != type ) { - type = elemIt->geometricType; - getReverseVector( type, swapVec ); + // reverse quadratic faces + if ( elemIt->reverse ) { + if ( elemIt->geometricType != type ) { + type = elemIt->geometricType; + getReverseVector( type, swapVec ); + } + reverse ( *elemIt, swapVec ); + } } - reverse ( *elemIt, swapVec ); } + } - // treate volumes - if ( elemIt->dimension() == 3 ) - { - int nbBottomNodes = 0; - switch ( elemIt->geometricType ) { - case MED_TETRA4: - case MED_TETRA10: - case MED_PENTA6: - case MED_PENTA15: - nbBottomNodes = 3; break; - case MED_PYRA5: - case MED_PYRA13: - case MED_HEXA8: - case MED_HEXA20: - nbBottomNodes = 4; break; - default: continue; - } + // --------------------------------------------------- + // Orient volumes according to MED conventions: + // normal of a bottom (first) face should be downward + // --------------------------------------------------- - // find a normal to the bottom face - const _noeud* n[4] = { - &elemIt->sommets[0]->second, // 3 bottom nodes - &elemIt->sommets[1]->second, - &elemIt->sommets[2]->second, - &elemIt->sommets[nbBottomNodes]->second };// a top node - double vec01 [3] = { // vector n[0]-n[1] - n[1]->coord[0] - n[0]->coord[0], - n[1]->coord[1] - n[0]->coord[1], - n[1]->coord[2] - n[0]->coord[2], }; - double vec02 [3] = { // vector n[0]-n[2] - n[2]->coord[0] - n[0]->coord[0], - n[2]->coord[1] - n[0]->coord[1], - n[2]->coord[2] - n[0]->coord[2] }; - double normal [3] = { // vec01 ^ vec02 - vec01[1] * vec02[2] - vec01[2] * vec02[1], - vec01[2] * vec02[0] - vec01[0] * vec02[2], - vec01[0] * vec02[1] - vec01[1] * vec02[0] }; - // check if the 102 angle is convex - if ( nbBottomNodes > 3 ) { - const _noeud* n3 = &elemIt->sommets[nbBottomNodes-1]->second;// last bottom node - double vec03 [3] = { // vector n[0]-n3 - n3->coord[0] - n[0]->coord[0], - n3->coord[1] - n[0]->coord[1], - n3->coord[2] - n[0]->coord[2], }; - if ( fabs( normal[0]+normal[1]+normal[2] ) <= DBL_MIN ) { // vec01 || vec02 - normal[0] = vec01[1] * vec03[2] - vec01[2] * vec03[1]; // vec01 ^ vec03 - normal[1] = vec01[2] * vec03[0] - vec01[0] * vec03[2]; - normal[2] = vec01[0] * vec03[1] - vec01[1] * vec03[0]; - } - else { - double vec [3] = { // normal ^ vec01 - normal[1] * vec01[2] - normal[2] * vec01[1], - normal[2] * vec01[0] - normal[0] * vec01[2], - normal[0] * vec01[1] - normal[1] * vec01[0] }; - double dot2 = vec[0]*vec03[0] + vec[1]*vec03[1] + vec[2]*vec03[2]; // vec*vec03 - if ( dot2 < 0 ) { // concave -> reverse normal - normal[0] *= -1; - normal[1] *= -1; - normal[2] *= -1; - } - } + _maillageByDimIterator mailIt( medi, 3 ); + while ( const set<_maille > * elems = mailIt.nextType() ) + { + elemIt = elems->begin(), elemEnd = elems->end(); + int nbBottomNodes = 0; + switch ( elemIt->geometricType ) { + case MED_TETRA4: + case MED_TETRA10: + case MED_PENTA6: + case MED_PENTA15: + nbBottomNodes = 3; break; + case MED_PYRA5: + case MED_PYRA13: + case MED_HEXA8: + case MED_HEXA20: + nbBottomNodes = 4; break; + default: continue; + } + // find a normal to the bottom face + const _noeud* n[4] = { + &elemIt->sommets[0]->second, // 3 bottom nodes + &elemIt->sommets[1]->second, + &elemIt->sommets[2]->second, + &elemIt->sommets[nbBottomNodes]->second };// a top node + double vec01 [3] = { // vector n[0]-n[1] + n[1]->coord[0] - n[0]->coord[0], + n[1]->coord[1] - n[0]->coord[1], + n[1]->coord[2] - n[0]->coord[2], }; + double vec02 [3] = { // vector n[0]-n[2] + n[2]->coord[0] - n[0]->coord[0], + n[2]->coord[1] - n[0]->coord[1], + n[2]->coord[2] - n[0]->coord[2] }; + double normal [3] = { // vec01 ^ vec02 + vec01[1] * vec02[2] - vec01[2] * vec02[1], + vec01[2] * vec02[0] - vec01[0] * vec02[2], + vec01[0] * vec02[1] - vec01[1] * vec02[0] }; + // check if the 102 angle is convex + if ( nbBottomNodes > 3 ) { + const _noeud* n3 = &elemIt->sommets[nbBottomNodes-1]->second;// last bottom node + double vec03 [3] = { // vector n[0]-n3 + n3->coord[0] - n[0]->coord[0], + n3->coord[1] - n[0]->coord[1], + n3->coord[2] - n[0]->coord[2], }; + if ( fabs( normal[0]+normal[1]+normal[2] ) <= DBL_MIN ) { // vec01 || vec02 + normal[0] = vec01[1] * vec03[2] - vec01[2] * vec03[1]; // vec01 ^ vec03 + normal[1] = vec01[2] * vec03[0] - vec01[0] * vec03[2]; + normal[2] = vec01[0] * vec03[1] - vec01[1] * vec03[0]; } - // direction from top to bottom - vector<double> tbDir(3); - tbDir[0] = n[0]->coord[0] - n[3]->coord[0]; - tbDir[1] = n[0]->coord[1] - n[3]->coord[1]; - tbDir[2] = n[0]->coord[2] - n[3]->coord[2]; - // compare 2 directions: normal and top-bottom - double dot = normal[0]*tbDir[0] + normal[1]*tbDir[1] + normal[2]*tbDir[2]; - if ( dot < 0. ) { // need reverse - if ( elemIt->geometricType != type ) { - type = elemIt->geometricType; - getReverseVector( type, swapVec ); + else { + double vec [3] = { // normal ^ vec01 + normal[1] * vec01[2] - normal[2] * vec01[1], + normal[2] * vec01[0] - normal[0] * vec01[2], + normal[0] * vec01[1] - normal[1] * vec01[0] }; + double dot2 = vec[0]*vec03[0] + vec[1]*vec03[1] + vec[2]*vec03[2]; // vec*vec03 + if ( dot2 < 0 ) { // concave -> reverse normal + normal[0] *= -1; + normal[1] *= -1; + normal[2] *= -1; } - reverse( *elemIt, swapVec ); } - } // dimension() == 3 - } // loop on maillage - + } + // direction from top to bottom + vector<double> tbDir(3); + tbDir[0] = n[0]->coord[0] - n[3]->coord[0]; + tbDir[1] = n[0]->coord[1] - n[3]->coord[1]; + tbDir[2] = n[0]->coord[2] - n[3]->coord[2]; + // compare 2 directions: normal and top-bottom + double dot = normal[0]*tbDir[0] + normal[1]*tbDir[1] + normal[2]*tbDir[2]; + if ( dot < 0. ) // need reverse + { + getReverseVector( elemIt->geometricType, swapVec ); + for ( ; elemIt != elemEnd; elemIt++ ) + reverse( *elemIt, swapVec ); + } + } // loop on volumes of one geometry } // space dimension == 3 } @@ -1529,27 +1578,27 @@ static void orientElements( _intermediateMED& medi ) void GIBI_MESH_RDONLY_DRIVER::fillMesh(_intermediateMED* _ptrMedi) { - const char * LOC = "GIBI_MESH_RDONLY_DRIVER::fillMesh(_intermediateMED* _ptrMedi) : " ; - BEGIN_OF(LOC); + const char* LOC = "GIBI_MESH_RDONLY_DRIVER::fillMesh(_intermediateMED* _ptrMedi) : "; + BEGIN_OF_MED(LOC); _ptrMesh->_name = _meshName; if (_ptrMedi) { - if (_ptrMedi->maillage.size()==0 || - _ptrMedi->groupes.size()==0 || - _ptrMedi->points.size()==0) { - INFOS(" Error while reading file: the data read are not completed " ) ; + if (!_maillageByDimIterator(*_ptrMedi).nextType() || + _ptrMedi->groupes.empty() || + _ptrMedi->points.empty()) { + INFOS_MED(" Error while reading file: the data read are not completed " ) ; return; } // fix element orientation orientElements( *_ptrMedi ); _ptrMesh->_spaceDimension = _ptrMedi->points.begin()->second.coord.size(); - _ptrMesh->_meshDimension = _ptrMedi->maillage.rbegin()->dimension(); - _ptrMesh->_numberOfNodes = _ptrMedi->points.size(); - _ptrMesh->_isAGrid = 0; - _ptrMesh->_coordinate = _ptrMedi->getCoordinate(); + _ptrMesh->_meshDimension = _ptrMedi->getMeshDimension(); + _ptrMesh->_numberOfNodes = _ptrMedi->points.size(); + _ptrMesh->_isAGrid = 0; + _ptrMesh->_coordinate = _ptrMedi->getCoordinate(); //Construction des groupes _ptrMedi->getGroups(_ptrMesh->_groupCell, @@ -1613,7 +1662,7 @@ void GIBI_MESH_RDONLY_DRIVER::fillMesh(_intermediateMED* _ptrMedi) } } } - END_OF(LOC); + END_OF_MED(LOC); } void GIBI_MESH_RDONLY_DRIVER::write( void ) const @@ -1630,9 +1679,9 @@ GIBI_MESH_WRONLY_DRIVER::GIBI_MESH_WRONLY_DRIVER():GIBI_MESH_DRIVER() } GIBI_MESH_WRONLY_DRIVER::GIBI_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh): - GIBI_MESH_DRIVER(fileName,ptrMesh,MED_WRONLY) + GIBI_MESH_DRIVER(fileName,ptrMesh,WRONLY) { - MESSAGE("GIBI_MESH_WRONLY_DRIVER::GIBI_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); + MESSAGE_MED("GIBI_MESH_WRONLY_DRIVER::GIBI_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); } GIBI_MESH_WRONLY_DRIVER::GIBI_MESH_WRONLY_DRIVER(const GIBI_MESH_WRONLY_DRIVER & driver): GIBI_MESH_DRIVER(driver) @@ -1640,7 +1689,7 @@ GIBI_MESH_WRONLY_DRIVER::GIBI_MESH_WRONLY_DRIVER(const GIBI_MESH_WRONLY_DRIVER & } GIBI_MESH_WRONLY_DRIVER::~GIBI_MESH_WRONLY_DRIVER() { - //MESSAGE("GIBI_MESH_WRONLY_DRIVER::GIBI_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed"); + //MESSAGE_MED("GIBI_MESH_WRONLY_DRIVER::GIBI_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed"); } GENDRIVER * GIBI_MESH_WRONLY_DRIVER::copy(void) const { @@ -1660,13 +1709,16 @@ void GIBI_MESH_WRONLY_DRIVER::read (void) void GIBI_MESH_WRONLY_DRIVER::open() // throw (MEDEXCEPTION) { + if( _status == MED_OPENED ) + return; + const char * LOC = "GIBI_MESH_DRIVER::open()" ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); MED_EN::med_mode_acces aMode = getAccessMode(); switch (aMode) { - case MED_EN::MED_REMP: - case MED_EN::MED_ECRI: // should never append !! + case MED_EN::RDWR: + case MED_EN::WRONLY: // should never append !! _gibi.open(_fileName.c_str(), ios::out); break; default: @@ -1688,7 +1740,7 @@ void GIBI_MESH_WRONLY_DRIVER::open() { _status = MED_OPENED; } - END_OF(LOC); + END_OF_MED(LOC); } //======================================================================= @@ -1699,14 +1751,14 @@ void GIBI_MESH_WRONLY_DRIVER::open() void GIBI_MESH_WRONLY_DRIVER::close() // throw (MEDEXCEPTION) { - const char * LOC = "GIBI_MESH_DRIVER::close() " ; - BEGIN_OF(LOC); + const char* LOC = "GIBI_MESH_DRIVER::close() "; + BEGIN_OF_MED(LOC); if ( _status == MED_OPENED) { _gibi.close(); _status = MED_CLOSED; } - END_OF(LOC); + END_OF_MED(LOC); } //======================================================================= @@ -1717,8 +1769,8 @@ void GIBI_MESH_WRONLY_DRIVER::close() void GIBI_MESH_WRONLY_DRIVER::write(void) const throw (MEDEXCEPTION) { - const char * LOC = "void GIBI_MESH_WRONLY_DRIVER::write(void) const : "; - BEGIN_OF(LOC); + const char* LOC = "void GIBI_MESH_WRONLY_DRIVER::write(void) const : "; + BEGIN_OF_MED(LOC); // we are going to modify the _gibi field GIBI_MESH_WRONLY_DRIVER * me = const_cast<GIBI_MESH_WRONLY_DRIVER *>(this); @@ -1728,10 +1780,10 @@ void GIBI_MESH_WRONLY_DRIVER::write(void) const // } // catch (MEDEXCEPTION &ex) // { -// INFOS( ex.what() ); +// INFOS_MED( ex.what() ); // } - END_OF(LOC); + END_OF_MED(LOC); } //======================================================================= @@ -1804,7 +1856,7 @@ bool GIBI_MESH_WRONLY_DRIVER::addSupport( const SUPPORT * support ) // nodal connectivity for a support entity exists medEntityMesh entity = support->getEntity(); if ( entity != MED_NODE && !_ptrMesh->existConnectivity( MED_NODAL, entity )) { - INFOS("Do not save " << supType << " of entity " << entity + INFOS_MED("Do not save " << supType << " of entity " << entity << " named <" << data._cleanName << "> nodal connectivity not defined"); return false; } @@ -1828,6 +1880,8 @@ bool GIBI_MESH_WRONLY_DRIVER::addSupport( const SUPPORT * support ) types = _ptrMesh->getTypes( entity ); for ( int iType = 0; iType < nbTypes; ++iType ) { + if ( types && types[ iType ] > MED_HEXA20 ) + continue; // poly medGeometryElement geomType = types ? types[ iType ] : MED_ALL_ELEMENTS; const int * ptrElemIDs = 0; int elemID1 = 0, nbElems = 0; @@ -1847,7 +1901,7 @@ bool GIBI_MESH_WRONLY_DRIVER::addSupport( const SUPPORT * support ) } if ( data.getNumberOfTypes() == 0 ) { - INFOS("Do not save " << supType << " of entity " << entity + INFOS_MED("Do not save " << supType << " of entity " << entity << " named <" << data._cleanName << "> no geometric types"); return false; } @@ -1925,7 +1979,7 @@ void GIBI_MESH_WRONLY_DRIVER::writeElements (medGeometryElement geomType, // NBEL : nombre d'鬩ments int castemType = GIBI_MESH_DRIVER::med2gibiGeom( geomType ); - char* zeroI8 = " 0"; // FORMAT(I8) + const char* zeroI8 = " 0"; // FORMAT(I8) int nbElemNodes = geomType % 100; // indices to transform MED connectivity to GIBI one @@ -1954,7 +2008,7 @@ void GIBI_MESH_WRONLY_DRIVER::writeElements (medGeometryElement geomType, setw(8) << nbElements << // NBEL endl; - MESSAGE("writeElements(): geomType=" << geomType << " nbElements= " << nbElements) + MESSAGE_MED("writeElements(): geomType=" << geomType << " nbElements= " << nbElements) // L 'enregistrement donnant le num? de la couleur des 鬩ments. // * 8000 FORMAT(10I8) @@ -2029,7 +2083,7 @@ void GIBI_MESH_WRONLY_DRIVER::addName(map<string,int>& nameMap, ok = nameMap.insert( make_pair( str, index )).second; j++; } while ( !ok ); - INFOS( "Save <" << name << "> as <" << str << ">"); + INFOS_MED( "Save <" << name << "> as <" << str << ">"); delete [] str; } #endif @@ -2074,7 +2128,7 @@ void GIBI_MESH_WRONLY_DRIVER::writeNames( map<string,int>& nameNbMap ) void GIBI_MESH_WRONLY_DRIVER::writeSupportsAndMesh() { const char * LOC = "void GIBI_MESH_WRONLY_DRIVER::writeSupportsAndMesh() "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status!=MED_OPENED) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "file " << _fileName<< " is not opened." )); @@ -2101,7 +2155,7 @@ void GIBI_MESH_WRONLY_DRIVER::writeSupportsAndMesh() // Collect object names // -------------------------------------------------------------------- - vector<int> nbSuppElemsByType(MED_HEXA20,0); + vector<int> nbSuppElemsByType(MED_HEXA20+1,0); map<string,int> nameNbMap; map<const SUPPORT*,supportData>::iterator supIt = _supports.begin(); int i, nb_objects = 0; @@ -2115,7 +2169,7 @@ void GIBI_MESH_WRONLY_DRIVER::writeSupportsAndMesh() nb_objects += nbSupObj; addName( nameNbMap, data._cleanName, data._id, "C" ); - MESSAGE( "obj " << data._id << " " << data._cleanName); + MESSAGE_MED( "obj " << data._id << " " << data._cleanName); // count elements: take into account supports on all elements and families only const SUPPORT* support = supIt->first; @@ -2198,14 +2252,14 @@ void GIBI_MESH_WRONLY_DRIVER::writeSupportsAndMesh() // la liste des r馩rences , les num?s des couleurs puis les connectivité³® TFieldCounter fcount( _gibi, 10 ); - char* zeroI8 = " 0"; // FORMAT(I8) + const char* zeroI8 = " 0"; // FORMAT(I8) for ( supIt = _supports.begin(); supIt != _supports.end(); supIt++ ) { supportData & data = supIt->second; int nbSupObj = data.getNumberObjects(); if ( nbSupObj == 0 ) continue; - MESSAGE("support " << data._id << "<" << data._cleanName << ">"); + MESSAGE_MED("support " << data._id << "<" << data._cleanName << ">"); // write a compound object int nbTypes = data.getNumberOfTypes(); @@ -2320,7 +2374,7 @@ void GIBI_MESH_WRONLY_DRIVER::writeSupportsAndMesh() } fcount.stop(); - END_OF(LOC); + END_OF_MED(LOC); } //======================================================================= @@ -2341,23 +2395,24 @@ GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER():GIBI_MESH_DRIVER() } GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh): - GIBI_MESH_DRIVER(fileName,ptrMesh,MED_RDWR) + GIBI_MESH_DRIVER(fileName,ptrMesh,RDWR) { - MESSAGE("GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); + MESSAGE_MED("GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); } GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER(const GIBI_MESH_RDWR_DRIVER & driver): GIBI_MESH_RDONLY_DRIVER::GIBI_MESH_DRIVER(driver) { - MESSAGE("GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER(driver) has been created"); + MESSAGE_MED("GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER(driver) has been created"); } GIBI_MESH_RDWR_DRIVER::~GIBI_MESH_RDWR_DRIVER() { - MESSAGE("GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed"); + MESSAGE_MED("GIBI_MESH_RDWR_DRIVER::GIBI_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed"); } GENDRIVER * GIBI_MESH_RDWR_DRIVER::copy(void) const { - BEGIN_OF( "GIBI_MESH_RDWR_DRIVER::copy()"); + const char* LOC = "GIBI_MESH_RDWR_DRIVER::copy()"; + BEGIN_OF_MED(LOC); GENDRIVER * driver = new GIBI_MESH_RDWR_DRIVER(*this); - END_OF( "GIBI_MESH_RDWR_DRIVER::copy()"); + END_OF_MED(LOC); return driver; } void GIBI_MESH_RDWR_DRIVER::write(void) const @@ -2371,11 +2426,12 @@ void GIBI_MESH_RDWR_DRIVER::write(void) const void GIBI_MESH_RDWR_DRIVER::read (void) throw (MEDEXCEPTION) { - BEGIN_OF( "GIBI_MESH_RDWR_DRIVER::read()"); + const char* LOC = "GIBI_MESH_RDWR_DRIVER::read()"; + BEGIN_OF_MED(LOC); GIBI_MESH_RDONLY_DRIVER::open(); GIBI_MESH_RDONLY_DRIVER::read(); GIBI_MESH_RDONLY_DRIVER::close(); - END_OF( "GIBI_MESH_RDWR_DRIVER::read()"); + END_OF_MED(LOC); } void GIBI_MESH_RDWR_DRIVER::open() // throw (MEDEXCEPTION) @@ -2396,9 +2452,9 @@ GIBI_MED_RDONLY_DRIVER::GIBI_MED_RDONLY_DRIVER():GIBI_MESH_RDONLY_DRIVER() GIBI_MED_RDONLY_DRIVER::GIBI_MED_RDONLY_DRIVER(const string & fileName, MED * ptrMed): GIBI_MESH_RDONLY_DRIVER(fileName,NULL), _med( ptrMed ) { - MESSAGE("GIBI_MED_RDONLY_DRIVER(const string & fileName, MED * ptrMed) has been created"); + MESSAGE_MED("GIBI_MED_RDONLY_DRIVER(const string & fileName, MED * ptrMed) has been created"); _fileName = fileName; - _accessMode = MED_RDONLY; + _accessMode = RDONLY; } GIBI_MED_RDONLY_DRIVER::GIBI_MED_RDONLY_DRIVER(const GIBI_MED_RDONLY_DRIVER & driver) { @@ -2419,7 +2475,7 @@ GENDRIVER * GIBI_MED_RDONLY_DRIVER::copy ( void ) const void GIBI_MED_RDONLY_DRIVER::read ( void ) throw (MEDEXCEPTION) { const char * LOC = "GIBI_MED_RDONLY_DRIVER::read() : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status!=MED_OPENED) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "file " << _fileName<<" is not opened." )); @@ -2431,30 +2487,14 @@ void GIBI_MED_RDONLY_DRIVER::read ( void ) throw (MEDEXCEPTION) if ( !readFile( &medi, true ) ) return; - // set name of field if it is empty - set<string> fnames; - list< _fieldBase* >::iterator fIt = medi.fields.begin(); - for ( ; fIt != medi.fields.end(); fIt++ ) - fnames.insert( (*fIt)->_name ); - int i = 0; - for (fIt = medi.fields.begin(); fIt != medi.fields.end(); fIt++ ) { - _fieldBase* f = *fIt; - if ( f->_name.empty() ) { - do { - ostringstream name; - name << "F_" << ++i; - f->_name = name.str(); - } while ( !fnames.insert( f->_name ).second ); - } - } - //MESSAGE(LOC << medi ); + //MESSAGE_MED(LOC << medi ); fillMesh( &medi ); - MESSAGE(LOC << "GIBI_MED_RDONLY_DRIVER::read : RESULTATS STRUCTURE INTERMEDIAIRES : "); - MESSAGE(LOC << medi ); + MESSAGE_MED(LOC << "GIBI_MED_RDONLY_DRIVER::read : RESULTATS STRUCTURE INTERMEDIAIRES : "); + MESSAGE_MED(LOC << medi ); list< FIELD_* > fields; medi.getFields( fields ); - MESSAGE( "nb fields: " << fields.size() ); + MESSAGE_MED( "nb fields: " << fields.size() ); if ( _ptrMesh->getName().empty() ) _ptrMesh->setName( "MESH" ); @@ -2479,10 +2519,10 @@ void GIBI_MED_RDONLY_DRIVER::read ( void ) throw (MEDEXCEPTION) } catch (MEDEXCEPTION &ex) { - INFOS( ex.what() ); + INFOS_MED( ex.what() ); } - END_OF(LOC); + END_OF_MED(LOC); } //============================== ==================================================== @@ -2499,10 +2539,10 @@ GIBI_MED_WRONLY_DRIVER::GIBI_MED_WRONLY_DRIVER(const string & fileName, { const char * LOC = "GIBI_MED_WRONLY_DRIVER(const string & fileName, MED * ptrMed, MESH * ptrMesh)" ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); _fileName = fileName; - _accessMode = MED_WRONLY; + _accessMode = WRONLY; _ptrMesh = ptrMesh; if ( !_med || !_ptrMesh ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " Bad params " << ptrMed << " " << ptrMesh )); @@ -2530,7 +2570,7 @@ static void writeDataSection (fstream& file, const int id2) throw (MEDEXCEPTION) { const char * LOC="writeDataSection (.....) :"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); int nbGauss, nbComp = field->getNumberOfComponents(); @@ -2589,7 +2629,7 @@ static void writeDataSection (fstream& file, } fcount.stop(); } - END_OF(LOC); + END_OF_MED(LOC); } //======================================================================= @@ -2599,15 +2639,15 @@ static void writeDataSection (fstream& file, void GIBI_MED_WRONLY_DRIVER::write( void ) const throw (MEDEXCEPTION) { - const char * LOC = "void GIBI_MED_WRONLY_DRIVER::write(void) const : "; - BEGIN_OF(LOC); + const char* LOC = "void GIBI_MED_WRONLY_DRIVER::write(void) const : "; + BEGIN_OF_MED(LOC); // we are going to modify the _gibi field GIBI_MED_WRONLY_DRIVER * me = const_cast<GIBI_MED_WRONLY_DRIVER *>(this); // get all fields on _ptrMesh and add their support to be written list<FIELD_*> fields; - int iField, nbFileds = _med->getNumberOfFields(); + int iField, nbFields = _med->getNumberOfFields(); int nb_obj = 0; list<int> nb_sub_list; map<string,int> nameNbMap; @@ -2615,9 +2655,9 @@ void GIBI_MED_WRONLY_DRIVER::write( void ) const throw (MEDEXCEPTION) list<pair<int,int> > subIdSizeList; // pair( <submesh id>, <submesh size> ); list<pair<int,int> >::iterator idsize; - string *names=new string[ nbFileds ]; + string *names=new string[ nbFields ]; _med->getFieldNames( names ); - for ( iField = 0; iField < nbFileds; ++iField ) + for ( iField = 0; iField < nbFields; ++iField ) { int nb_sub = 0; deque<DT_IT_> dtit = _med->getFieldIteration( names[ iField ]); @@ -2627,7 +2667,7 @@ void GIBI_MED_WRONLY_DRIVER::write( void ) const throw (MEDEXCEPTION) FIELD_ * f = _med->getField( names[ iField ], fIt->dt, fIt->it ); if ( f->getValueType() != MED_EN::MED_REEL64 ) { - MESSAGE("GIBI_MED_WRONLY_DRIVER::write( FIELD< int > ) not implemented"); + MESSAGE_MED("GIBI_MED_WRONLY_DRIVER::write( FIELD< int > ) not implemented"); continue; } const SUPPORT * sup = f->getSupport(); @@ -2649,7 +2689,7 @@ void GIBI_MED_WRONLY_DRIVER::write( void ) const throw (MEDEXCEPTION) // } // catch (MEDEXCEPTION &ex) // { -// INFOS( ex.what() ); +// INFOS_MED( ex.what() ); // return; // } @@ -2676,12 +2716,16 @@ void GIBI_MED_WRONLY_DRIVER::write( void ) const throw (MEDEXCEPTION) // start the next field writting nb_sub = *(itNbSub++); string description = (*itF)->getDescription(); + if ( description.size() > 72 ) + description = description.substr(0,72); gibi << setw(8) << nb_sub << setw(8) << -1 << setw(8) << 6 - << setw(8) << description.size() << endl; + << setw(8) << 72 /*description.size()*/ << endl; // PAL19100 if ( !description.empty() ) gibi << setw(72) << description << endl; + else + gibi << setw(72) << "Field" << endl; gibi << setw(72) << " " << endl; // Sub Components section @@ -2762,5 +2806,5 @@ void GIBI_MED_WRONLY_DRIVER::write( void ) const throw (MEDEXCEPTION) } me->writeLastRecord(); delete [] names; - END_OF(LOC); + END_OF_MED(LOC); } diff --git a/src/MEDMEM/MEDMEM_GibiMeshDriver.hxx b/src/MEDMEM/MEDMEM_GibiMeshDriver.hxx index 9176f39bf..cdc487baf 100644 --- a/src/MEDMEM/MEDMEM_GibiMeshDriver.hxx +++ b/src/MEDMEM/MEDMEM_GibiMeshDriver.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef GIBI_MESH_DRIVER_HXX #define GIBI_MESH_DRIVER_HXX @@ -479,7 +481,7 @@ private: // GENDRIVER * copy(void) const ; // }; -}; +} #endif /* GIBI_MESH_DRIVER_HXX */ diff --git a/src/MEDMEM/MEDMEM_Grid.cxx b/src/MEDMEM/MEDMEM_Grid.cxx index 0119aa1c9..213cba3a9 100644 --- a/src/MEDMEM/MEDMEM_Grid.cxx +++ b/src/MEDMEM/MEDMEM_Grid.cxx @@ -1,31 +1,30 @@ - -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // File : MEDMEM_Grid.hxx // Created : Wed Dec 18 08:35:26 2002 // Descr : class containing structured mesh data - // Author : Edward AGAPOV (eap) // Project : SALOME Pro // Module : MED -// $Header$ #include "MEDMEM_Grid.hxx" @@ -37,6 +36,22 @@ using namespace std; using namespace MEDMEM; using namespace MED_EN; + +// Block defining the comments for the MEDMEM_ug documentation + +/*! + +\defgroup GRID_axes Information about axes +This group of methods retrieves information about the axes of the grid. + +\defgroup GRID_connectivity Utility methods for defining element positions in the grid +These methods enable the user to convert a position on the grid to a global element number + +\defgroup GRID_constructors Constructors +These methods are the different constructors for the grid objects. + +*/ + //======================================================================= //function : GRID //purpose : empty constructor @@ -44,17 +59,33 @@ using namespace MED_EN; GRID::GRID() { init(); - MESSAGE("A GRID CREATED"); + MESSAGE_MED("A GRID CREATED"); } // //======================================================================= ////function : GRID ////purpose : array constructor ////======================================================================= -GRID::GRID(const std::vector<std::vector<double> >& xyz_array, - const std::vector<std::string>& coord_name, - const std::vector<std::string>& coord_unit, - const med_grid_type type) : _gridType(type) +/*! +\if MEDMEM_ug +\addtogroup GRID_constructors +@{ +\endif +*/ +/*! + * \brief Constructor specifying the axes of the grid + * + * This constructor describes the grid by specifying the location of the nodes on +each of the axis. The dimension of the grid is implicitly defined by the +size of vector \a xyz_array. + * + *\param xyz_array specifies the node coordinates for each direction + *\param coord_name names of the different coordinates + *\param coord_unit names of the different coordinate units + *\param type grid type (MED_POLAR, MED_CARTESIAN) +*/ +GRID::GRID(const std::vector<std::vector<double> >& xyz_array,const std::vector<std::string>& coord_name, + const std::vector<std::string>& coord_unit, const MED_EN::med_grid_type type) : _gridType(type) { init(); // PAL 12136 _is_default_gridType = false; @@ -101,18 +132,19 @@ GRID::GRID(const std::vector<std::vector<double> >& xyz_array, _is_connectivity_filled = false; _isAGrid = true; } +/*!\if MEDMEM_ug @} \endif */ //======================================================================= //function : GRID //purpose : empty constructor //======================================================================= -GRID::GRID(const med_grid_type type) +GRID::GRID(const MED_EN::med_grid_type type) { init(); _gridType = type; _is_default_gridType = false; - MESSAGE("A TYPED GRID CREATED"); + MESSAGE_MED("A TYPED GRID CREATED"); } //======================================================================= @@ -130,7 +162,7 @@ GRID::GRID(const GRID& otherGrid) { //======================================================================= GRID::~GRID() { - MESSAGE("GRID::~GRID() : Destroying the Grid"); + MESSAGE_MED("GRID::~GRID() : Destroying the Grid"); if ( _iArray != (double* ) NULL) delete [] _iArray; if ( _jArray != (double* ) NULL) delete [] _jArray; if ( _kArray != (double* ) NULL) delete [] _kArray; @@ -179,12 +211,12 @@ GRID & GRID::operator=(const GRID & otherGrid) GRID::GRID(driverTypes driverType, const string & fileName, const string & driverName)// : MESH(driverType, fileName, driverName) { - const char * LOC ="GRID::GRID(driverTypes , const string & , const string &) : "; - BEGIN_OF(LOC); + const char* LOC = "GRID::GRID(driverTypes , const string & , const string &) : "; + BEGIN_OF_MED(LOC); init(); - GENDRIVER *myDriver=DRIVERFACTORY::buildDriverForMesh(driverType,fileName,this,driverName,MED_LECT); + GENDRIVER *myDriver=DRIVERFACTORY::buildDriverForMesh(driverType,fileName,this,driverName,RDONLY); int current = addDriver(*myDriver); delete myDriver; _drivers[current]->open(); @@ -193,13 +225,13 @@ GRID::GRID(driverTypes driverType, const string & fileName, fillMeshAfterRead(); - END_OF(LOC); + END_OF_MED(LOC); }; /*! return the GRID Geometric type, without computing all connectivity */ -const medGeometryElement * GRID::getTypes(medEntityMesh entity) const +const medGeometryElement * GRID::getTypes(MED_EN::medEntityMesh entity) const { static const medGeometryElement _gridGeometry[4]={MED_HEXA8,MED_QUAD4,MED_SEG2,MED_POINT1}; int i=0; @@ -243,7 +275,7 @@ void GRID::fillMeshAfterRead() // nb of nodes in each direction is not known, set anything // in order to be able to work anyhow -// INFOS("GRID::fillMeshAfterRead(): This stub must be removed"); +// INFOS_MED("GRID::fillMeshAfterRead(): This stub must be removed"); // switch (_spaceDimension) { // case 1: // _iArrayLength = _numberOfNodes; @@ -284,9 +316,12 @@ void GRID::fillCoordinates() const { if (_is_coordinates_filled) return; + + if (!_coordinate) + return; - const char * LOC ="GRID::fillCoordinates()"; - BEGIN_OF(LOC); + const char* LOC = "GRID::fillCoordinates()"; + BEGIN_OF_MED(LOC); // if coordonate has not been allocated, perform shalow copy, transfer ownership of matrix if(_coordinate->getSpaceDimension()*_coordinate->getNumberOfNodes() == 0) @@ -322,7 +357,7 @@ void GRID::fillCoordinates() const } (const_cast <GRID *> (this))->_is_coordinates_filled = true; - END_OF(LOC); + END_OF_MED(LOC); } //======================================================================= @@ -330,8 +365,8 @@ void GRID::fillCoordinates() const //purpose : //======================================================================= -CONNECTIVITY * GRID::makeConnectivity (medEntityMesh Entity, - medGeometryElement Geometry, +CONNECTIVITY * GRID::makeConnectivity (MED_EN::medEntityMesh Entity, + MED_EN::medGeometryElement Geometry, int NbEntities, int NbNodes, int nbMeshNodes, @@ -394,12 +429,12 @@ void GRID::fillConnectivity() const { if (_is_connectivity_filled) { - MESSAGE("GRID::fillConnectivity(): Already filled"); + MESSAGE_MED("GRID::fillConnectivity(): Already filled"); return; } const char * LOC = "GRID::fillConnectivity() "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); int nbCells, nbFaces, nbEdges; int nbCNodes, nbFNodes, nbENodes, nbMeshNodes; @@ -663,7 +698,7 @@ void GRID::fillConnectivity() const } } if (nbENodes != indexE+1) { - throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Wrong nbFNodes : " \ + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Wrong nbENodes : " \ << nbENodes << " indexE : " << indexE )); } @@ -739,14 +774,20 @@ void GRID::fillConnectivity() const (const_cast <GRID *> (this))->_is_connectivity_filled = true; - END_OF(LOC); + END_OF_MED(LOC); } //======================================================================= //function : getArrayLength //purpose : return array length. Axis = [1,2,3] meaning [i,j,k], //======================================================================= - +/*!\if MEDMEM_ug +\addtogroup GRID_axes +@{ +\endif +*/ +/*! Returns the number of nodes on axis number \a Axis (axis numbering starts at 1). +*/ int GRID::getArrayLength( const int Axis ) const throw (MEDEXCEPTION) { switch (Axis) { @@ -765,7 +806,9 @@ int GRID::getArrayLength( const int Axis ) const throw (MEDEXCEPTION) // exception if Axis out of [1-3] range // exception if i is out of range 0 <= i < getArrayLength(Axis); //======================================================================= - +/*! +Returns the value of node coordinate \a i on axis \a Axis. + */ const double GRID::getArrayValue (const int Axis, const int i) const throw (MEDEXCEPTION) { if (i < 0 || i >= getArrayLength(Axis)) @@ -780,17 +823,43 @@ const double GRID::getArrayValue (const int Axis, const int i) const throw (MEDE return 0.0; } +/*! +\if MEDMEM_ug +@} +\endif + */ + //======================================================================= //function : getEdgeNumber //purpose : //======================================================================= +/*! +\if MEDMEM_ug +\addtogroup GRID_connectivity +@{ +\endif +*/ +/*! +@{ +\name Position to number conversion methods +\a getXXXNumber methods enable the user to convert an \f$ (i,j,k)\f$ position into a global number in the array. + +Axis [1,2,3] means one of directions: along \a i, \a j or \a k. +For cell constituents (FACE or EDGE), Axis selects one of those having same \f$ (i, j, k )\f$ : +- a FACE which is normal to direction along given \a Axis; +- an EDGE going along given \a Axis. + +Exception for \a Axis out of range. +For 2D grids, \a k is a dummy argument. */ +/*! Edge position to number conversion method*/ + int GRID::getEdgeNumber(const int Axis, const int i, const int j, const int k) const throw (MEDEXCEPTION) { const char * LOC = "GRID::getEdgeNumber(Axis, i,j,k) :"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); int Len[4] = {0,_iArrayLength, _jArrayLength, _kArrayLength }, I=1, J=2, K=3; int maxAxis = Len[ K ] ? 3 : 2; @@ -815,27 +884,26 @@ int GRID::getEdgeNumber(const int Axis, const int i, const int j, const int k) Nb += Len[ I ]*Len[ J ]*Len[ K ]; } - END_OF(LOC); + END_OF_MED(LOC); return Nb; } -//======================================================================= -//function : getFaceNumber -//purpose : return a NODE, EDGE, FACE, CELL number by its position in the grid. -// Axis [1,2,3] means one of directions: along i, j or k -// For Cell contituents (FACE or EDGE), Axis selects one of those having same (i,j,k): -// * a FACE which is normal to direction along given Axis; -// * an EDGE going along given Axis. -// Exception for Axis out of range -//======================================================================= +/*! +Returns a NODE, EDGE, FACE, CELL number by its position in the grid. +Axis [1,2,3] means one of directions: along i, j or k +For Cell contituents (FACE or EDGE), Axis selects one of those having same (i,j,k): +- a FACE which is normal to direction along given Axis; +- an EDGE going along given Axis. +Exception for Axis out of range +*/ int GRID::getFaceNumber(const int Axis, const int i, const int j, const int k) const throw (MEDEXCEPTION) { const char * LOC = "GRID::getFaceNumber(Axis, i,j,k) :"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // if (Axis <= 0 || Axis > 3) if (Axis < 0 || Axis > 3) @@ -857,22 +925,33 @@ int GRID::getFaceNumber(const int Axis, const int i, const int j, const int k) Nb += Len[ I ]*Len[ J ]*Len[ K ]; } - END_OF(LOC); + END_OF_MED(LOC); return Nb; } +/*! @} */ -//======================================================================= -//function : getNodePosition -//purpose : -//======================================================================= +/*! +@{ +\name Number to position conversion methods + +\a getXXXPosition functions enable the user to convert +a number into a \f$ (i,j,k) \f$ position. + Axis [1,2,3] means one of directions: along i, j or k + For Cell contituents (FACE or EDGE), Axis selects one of those having same (i,j,k): + - a FACE which is normal to direction along given Axis; + - an EDGE going along given Axis. + + Exception for Number out of range. +*/ +/*! Node number to position conversion method */ void GRID::getNodePosition(const int Number, int& i, int& j, int& k) const throw (MEDEXCEPTION) { const char * LOC = "GRID::getNodePosition(Number, i,j,k) :"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (Number <= 0 || Number > _numberOfNodes) throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number)); @@ -889,7 +968,7 @@ void GRID::getNodePosition(const int Number, int& i, int& j, int& k) const ////cout <<" NODE POS: " << Number << " - " << i << ", " << j << ", " << k << endl; - END_OF(LOC); + END_OF_MED(LOC); } @@ -897,13 +976,13 @@ void GRID::getNodePosition(const int Number, int& i, int& j, int& k) const //function : getCellPosition //purpose : //======================================================================= - +/*! Cell number to position conversion method */ void GRID::getCellPosition(const int Number, int& i, int& j, int& k) const throw (MEDEXCEPTION) { - const char * LOC = "GRID::getCellPosition(Number, i,j,k) :"; - BEGIN_OF(LOC); + const char* LOC = "GRID::getCellPosition(Number, i,j,k) :"; + BEGIN_OF_MED(LOC); int Len[4] = {0,_iArrayLength-1, _jArrayLength-1, _kArrayLength-1 }, I=1, J=2; // , K=3; !! UNUSED VARIABLE !! @@ -918,20 +997,20 @@ void GRID::getCellPosition(const int Number, int& i, int& j, int& k) const j = kLen / Len[J]; k = (Number - 1) / ijLen; - END_OF(LOC); + END_OF_MED(LOC); } //======================================================================= //function : getEdgePosition //purpose : //======================================================================= - +/*! Edge number to poistion conversion method*/ void GRID::getEdgePosition(const int Number, int& Axis, int& i, int& j, int& k) const throw (MEDEXCEPTION) { const char * LOC = "GRID::getEdgePosition(Number, i,j,k) :"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (!_jArrayLength) throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "no edges in the grid: ")); @@ -973,7 +1052,7 @@ void GRID::getEdgePosition(const int Number, int& Axis, int& i, int& j, int& k) k = (theNb - 1) / ijLen; } - END_OF(LOC); + END_OF_MED(LOC); return; } @@ -990,13 +1069,13 @@ void GRID::getEdgePosition(const int Number, int& Axis, int& i, int& j, int& k) // * an EDGE going along given Axis. // Exception for Number out of range //======================================================================= - +/*! Face number to position convertion method*/ void GRID::getFacePosition(const int Number, int& Axis, int& i, int& j, int& k) const throw (MEDEXCEPTION) { const char * LOC = "GRID::getFacePosition(Number, i,j,k) :"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_kArrayLength == 0) { getCellPosition(Number, i, j, k); @@ -1042,14 +1121,19 @@ void GRID::getFacePosition(const int Number, int& Axis, int& i, int& j, int& k) k = (theNb - 1) / ijLen; } - END_OF(LOC); + END_OF_MED(LOC); return; } throw MED_EXCEPTION ( LOCALIZED(STRING(LOC) << "Number is out of range: " << Number)); } - +/*! +@} +\if MEDMEM_ug +@} +\endif +*/ //======================================================================= //function : writeUnstructured //purpose : write a Grid as an Unstructured mesh @@ -1058,7 +1142,7 @@ void GRID::getFacePosition(const int Number, int& Axis, int& i, int& j, int& k) void GRID::writeUnstructured(int index, const string & driverName) { const char * LOC = "GRID::writeUnstructured(int index=0, const string & driverName) : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if ( _drivers[index] ) { @@ -1078,13 +1162,13 @@ void GRID::writeUnstructured(int index, const string & driverName) << _drivers.size() ) ); - END_OF(LOC); + END_OF_MED(LOC); } void GRID::read(int index) { const char * LOC = "GRID::read(int index=0) : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_drivers[index]) { _drivers[index]->open(); @@ -1100,5 +1184,5 @@ void GRID::read(int index) if (_isAGrid) fillMeshAfterRead(); - END_OF(LOC); + END_OF_MED(LOC); } diff --git a/src/MEDMEM/MEDMEM_Grid.hxx b/src/MEDMEM/MEDMEM_Grid.hxx index fd79c098a..708a6ccfc 100644 --- a/src/MEDMEM/MEDMEM_Grid.hxx +++ b/src/MEDMEM/MEDMEM_Grid.hxx @@ -1,30 +1,30 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // // File : MEDMEM_Grid.hxx // Created : Wed Dec 18 08:35:26 2002 // Descr : class containing structured mesh data - // Author : Edward AGAPOV (eap) // Project : SALOME Pro // Module : MED -// $Header$ #ifndef MEDMEM_Grid_HeaderFile #define MEDMEM_Grid_HeaderFile @@ -101,8 +101,10 @@ class MEDMEM_EXPORT GRID: public MESH GRID(const MED_EN::med_grid_type type); GRID(const GRID &m); GRID( driverTypes driverType, const string & fileName="",const string & meshName=""); - GRID(const std::vector<std::vector<double> >& xyz_array,const std::vector<std::string>& coord_name, - const std::vector<std::string>& coord_unit, const MED_EN::med_grid_type type=MED_EN::MED_CARTESIAN); + GRID(const std::vector<std::vector<double> >& xyz_array, + const std::vector<std::string>& coord_name, + const std::vector<std::string>& coord_unit, + const MED_EN::med_grid_type type=MED_EN::MED_CARTESIAN); GRID & operator=(const GRID &m); virtual ~GRID(); virtual void init(); @@ -233,7 +235,7 @@ class MEDMEM_EXPORT GRID: public MESH inline int getNumberOfTypesWithPoly(MED_EN::medEntityMesh Entity) const; - inline const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const; + const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const; MED_EN::medGeometryElement * getTypesWithPoly(MED_EN::medEntityMesh Entity) const; @@ -250,9 +252,6 @@ class MEDMEM_EXPORT GRID: public MESH inline bool existConnectivity(MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; - inline bool existConnectivityWithPoly(MED_EN::medConnectivity ConnectivityType, - MED_EN::medEntityMesh Entity) const; - inline MED_EN::medGeometryElement getElementType(MED_EN::medEntityMesh Entity, int Number) const; @@ -289,6 +288,7 @@ class MEDMEM_EXPORT GRID: public MESH friend class MED_MESH_WRONLY_DRIVER21; friend class MED_MESH_RDONLY_DRIVER22; friend class MED_MESH_WRONLY_DRIVER22; + friend class ENSIGHT_MESH_RDONLY_DRIVER; }; @@ -373,14 +373,14 @@ inline const double GRID::getCoordinate(int number, int axis) const */ inline int GRID::getNumberOfTypes(MED_EN::medEntityMesh entity) const { - MESSAGE("GRID::getNumberOfTypes(medEntityMesh entity) : "<<entity); + MESSAGE_MED("GRID::getNumberOfTypes(medEntityMesh entity) : "<<entity); return 1; // a grid has one type } inline int GRID::getNumberOfTypesWithPoly(MED_EN::medEntityMesh entity) const { - MESSAGE("GRID::getNumberOfTypes(medEntityMesh entity) : "<<entity); + MESSAGE_MED("GRID::getNumberOfTypes(medEntityMesh entity) : "<<entity); return 1; // a grid has one type } @@ -426,25 +426,10 @@ inline int GRID::getNumberOfElements(MED_EN::medEntityMesh entity, MED_EN::medGe // Cas où le nombre d'éléments n'est pas nul if (entity==MED_EN::MED_FACE && (Type==MED_EN::MED_QUAD4 || Type==MED_EN::MED_ALL_ELEMENTS) && _spaceDimension>2) - if ( _meshDimension == 2 ) numberOfElements=(_iArrayLength-1)*(_jArrayLength-1); - else - numberOfElements= - (_iArrayLength-1)*(_jArrayLength-1)*_kArrayLength + - (_jArrayLength-1)*(_kArrayLength-1)*_iArrayLength + - (_iArrayLength-1)*(_kArrayLength-1)*_jArrayLength; else if (entity==MED_EN::MED_EDGE && (Type==MED_EN::MED_SEG2 || Type==MED_EN::MED_ALL_ELEMENTS) && _spaceDimension>1) - if ( _meshDimension == 1 ) numberOfElements=_iArrayLength-1; - else if ( _meshDimension == 2 ) - numberOfElements= - (_iArrayLength-1)*_jArrayLength + (_jArrayLength-1)*_iArrayLength; - else - numberOfElements= - (_iArrayLength-1)*_jArrayLength*_kArrayLength + - (_jArrayLength-1)*_kArrayLength*_iArrayLength + - (_kArrayLength-1)*_iArrayLength*_jArrayLength; else if (entity==MED_EN::MED_NODE && (Type==MED_EN::MED_NONE || Type==MED_EN::MED_ALL_ELEMENTS) && _spaceDimension>0) numberOfElements=_numberOfNodes; @@ -458,8 +443,8 @@ inline int GRID::getNumberOfElements(MED_EN::medEntityMesh entity, MED_EN::medGe else if (entity==MED_EN::MED_CELL && _spaceDimension==1 && (Type==MED_EN::MED_SEG2 || Type==MED_EN::MED_ALL_ELEMENTS) ) numberOfElements=_iArrayLength-1; - MESSAGE("GRID::getNumberOfElements - entity=" << entity << " Type=" << Type); - MESSAGE("_spaceDimension=" << _spaceDimension << " numberOfElements=" << numberOfElements); + MESSAGE_MED("GRID::getNumberOfElements - entity=" << entity << " Type=" << Type); + MESSAGE_MED("_spaceDimension=" << _spaceDimension << " numberOfElements=" << numberOfElements); return numberOfElements; } @@ -483,15 +468,6 @@ inline bool GRID::existConnectivity(MED_EN::medConnectivity connectivityType, ME return _connectivity->existConnectivity(connectivityType,entity); } -/*! - Same as the previous - */ -inline bool GRID::existConnectivityWithPoly(MED_EN::medConnectivity ConnectivityType, - MED_EN::medEntityMesh Entity) const -{ - return existConnectivity(ConnectivityType,Entity); -} - /*! Return the geometric type of global element Number of entity Entity. diff --git a/src/MEDMEM/MEDMEM_Group.cxx b/src/MEDMEM/MEDMEM_Group.cxx index 4030e10d4..2b0b010aa 100644 --- a/src/MEDMEM/MEDMEM_Group.cxx +++ b/src/MEDMEM/MEDMEM_Group.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // /* File Group.cxx @@ -32,23 +34,23 @@ using namespace MED_EN; GROUP::GROUP():SUPPORT(),_numberOfFamilies(0),_family() { - MESSAGE("GROUP()"); -}; + MESSAGE_MED("GROUP()"); +} GROUP::~GROUP() { - MESSAGE("~GROUP()"); -}; + MESSAGE_MED("~GROUP()"); +} GROUP & GROUP::operator=(const GROUP &group) { - MESSAGE("GROUP::operator="); + MESSAGE_MED("GROUP::operator="); if ( &group == this ) return *this; SUPPORT::operator=(group); _numberOfFamilies = group._numberOfFamilies ; _family = group._family ; return *this; -}; +} ostream & MEDMEM::operator<<(ostream &os, GROUP &myGroup) { @@ -60,15 +62,15 @@ ostream & MEDMEM::operator<<(ostream &os, GROUP &myGroup) os << " * "<<myGroup.getFamily(j)->getName().c_str()<<endl ; return os; -}; +} GROUP::GROUP(const string & name, const list<FAMILY*> & families) throw (MEDEXCEPTION) { const char * LOC = "GROUP( const string & , const list<FAMILY*> & ) : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); - MESSAGE(LOC<<name); + MESSAGE_MED(LOC<<name); int numberOfFamilies = families.size(); _name = name ; @@ -80,8 +82,8 @@ GROUP::GROUP(const string & name, const list<FAMILY*> & families) throw (MEDEXCE _entity = myFamily->getEntity() ; bool isOnAllElts = myFamily->isOnAllElements() ; - SCRUTE(isOnAllElts); - SCRUTE(numberOfFamilies); + SCRUTE_MED(isOnAllElts); + SCRUTE_MED(numberOfFamilies); if ((numberOfFamilies==1) && (isOnAllElts)) @@ -104,13 +106,13 @@ GROUP::GROUP(const string & name, const list<FAMILY*> & families) throw (MEDEXCE const medGeometryElement * geometricType = myFamily->getTypes() ; //int * geometricTypeNumber = myFamily->getGeometricTypeNumber() ; - SCRUTE(_numberOfGeometricType); + SCRUTE_MED(_numberOfGeometricType); for (int i=0 ; i<_numberOfGeometricType; i++) { _geometricType[i]= geometricType[i] ; // _geometricTypeNumber[i] = geometricTypeNumber[i] ; _numberOfElements[i]=myFamily->getNumberOfElements(geometricType[i]); - MESSAGE(LOC << " Type : " << _geometricType[i] << " number of element(s) " << _numberOfElements[i]); + MESSAGE_MED(LOC << " Type : " << _geometricType[i] << " number of element(s) " << _numberOfElements[i]); } _isOnAllElts = false ; //_totalNumberOfEntities = myFamily->getNumberOfElements(MED_ALL_ELEMENTS) ; @@ -125,28 +127,28 @@ GROUP::GROUP(const string & name, const list<FAMILY*> & families) throw (MEDEXCE int famNumberCount = famNumber->getNumberOf(); int famNumberLength = famNumber->getLength(); - SCRUTE(famNumber); - SCRUTE(famNumberCount); - SCRUTE(famNumberLength); - SCRUTE(famNumberValue); - SCRUTE(famNumberIndex); + SCRUTE_MED(famNumber); + SCRUTE_MED(famNumberCount); + SCRUTE_MED(famNumberLength); + SCRUTE_MED(famNumberValue); + SCRUTE_MED(famNumberIndex); // _number = new MEDSKYLINEARRAY(*famNumber) ; _number = new MEDSKYLINEARRAY(famNumberCount,famNumberLength, famNumberIndex,famNumberValue) ; - SCRUTE(_number); + SCRUTE_MED(_number); _numberOfFamilies = families.size(); - SCRUTE(numberOfFamilies); + SCRUTE_MED(numberOfFamilies); - //SCRUTE(_numberOfFamilies); + //SCRUTE_MED(_numberOfFamilies); _family.resize(_numberOfFamilies) ; list<FAMILY*>::const_iterator li ; - // MESSAGE(LOC<<"Printing of the object GROUP built right before the blending"<< (SUPPORT) *this); + // MESSAGE_MED(LOC<<"Printing of the object GROUP built right before the blending"<< (SUPPORT) *this); int it = 0 ; @@ -156,35 +158,34 @@ GROUP::GROUP(const string & name, const list<FAMILY*> & families) throw (MEDEXCE it++ ; } - //MESSAGE(LOC<<"Printing of the object GROUP built "<< (GROUP)*this); + //MESSAGE_MED(LOC<<"Printing of the object GROUP built "<< (GROUP)*this); - END_OF(LOC); -}; + END_OF_MED(LOC); +} GROUP::GROUP(const GROUP & m):SUPPORT(m) { _numberOfFamilies = m._numberOfFamilies; _family = m._family; //Copie profonde dans FAMILY Rmq from EF -}; +} // void GROUP::init(const list<FAMILY*> & families) // { -// const char * LOC = "GROUP::init( const list<FAMILY*> & ) : " ; -// BEGIN_OF(LOC); +// BEGIN_OF_MED(LOC); // FAMILY * myFamily = families.front() ; // _mesh = myFamily->getMesh() ; // _isOnAllElts = myFamily->isOnAllElements() ; -// SCRUTE(_mesh); +// SCRUTE_MED(_mesh); -// SCRUTE(_isOnAllElts); +// SCRUTE_MED(_isOnAllElts); // _entity = myFamily->getEntity() ; -// SCRUTE(_mesh->getNumberOfTypes(_entity)); +// SCRUTE_MED(_mesh->getNumberOfTypes(_entity)); // _numberOfGeometricType = myFamily->getNumberOfTypes() ; // _geometricType = new medGeometryElement[_numberOfGeometricType]; @@ -217,6 +218,6 @@ GROUP::GROUP(const GROUP & m):SUPPORT(m) // it++ ; // } -// END_OF(LOC); +// END_OF_MED(); // }; diff --git a/src/MEDMEM/MEDMEM_Group.hxx b/src/MEDMEM/MEDMEM_Group.hxx index 4832d3d5e..a516004ff 100644 --- a/src/MEDMEM/MEDMEM_Group.hxx +++ b/src/MEDMEM/MEDMEM_Group.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // /* File Group.hxx @@ -96,7 +98,7 @@ inline void GROUP::setNumberOfFamilies(int numberOfFamilies) //---------------------------------------------------------- { _numberOfFamilies = numberOfFamilies; -}; +} /*! set the attribut _family to Family */ @@ -105,7 +107,7 @@ inline void GROUP::setFamilies(vector<FAMILY*> Family) //---------------------------------------------------- { _family = Family; -}; +} /*! returns number of families in the group */ //-------------------------------------------- @@ -113,7 +115,7 @@ inline int GROUP::getNumberOfFamilies() const //------------------------------------------- { return _numberOfFamilies; -}; +} /*! returns the vector of families in the group */ //------------------------------------------------ @@ -121,7 +123,7 @@ inline vector<FAMILY*> GROUP::getFamilies() const //------------------------------------------------ { return _family; -}; +} /*! returns a reference on family I of the group */ //-------------------------------------------------- @@ -129,7 +131,7 @@ FAMILY * GROUP::getFamily(int i) const //-------------------------------------------------- { return _family[i-1]; -}; +} }//End namespace MEDMEM #endif /* GROUP_HXX */ diff --git a/src/MEDMEM/MEDMEM_IndexCheckingPolicy.hxx b/src/MEDMEM/MEDMEM_IndexCheckingPolicy.hxx index 98761aed4..8b303f80a 100644 --- a/src/MEDMEM/MEDMEM_IndexCheckingPolicy.hxx +++ b/src/MEDMEM/MEDMEM_IndexCheckingPolicy.hxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #ifndef MEDMEM_INDEX_CHECKING_POLICY_HXX #define MEDMEM_INDEX_CHECKING_POLICY_HXX diff --git a/src/MEDMEM/MEDMEM_Init.cxx b/src/MEDMEM/MEDMEM_Init.cxx index aca96a49a..b6eb5c1d2 100644 --- a/src/MEDMEM/MEDMEM_Init.cxx +++ b/src/MEDMEM/MEDMEM_Init.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include <stdlib.h> #include <string.h> @@ -55,5 +57,5 @@ MEDMEM::INIT::INIT() assert(traceKind); } - MESSAGE("Med Memory Initialization with $SALOME_trace = " << traceKind); + MESSAGE_MED("Med Memory Initialization with $SALOME_trace = " << traceKind); } diff --git a/src/MEDMEM/MEDMEM_InterlacingPolicy.hxx b/src/MEDMEM/MEDMEM_InterlacingPolicy.hxx index a411955a1..64bc56657 100644 --- a/src/MEDMEM/MEDMEM_InterlacingPolicy.hxx +++ b/src/MEDMEM/MEDMEM_InterlacingPolicy.hxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #ifndef MEDMEM_INTERLACING_HXX #define MEDMEM_INTERLACING_HXX @@ -55,7 +58,8 @@ public : InterlacingPolicy & operator=(const InterlacingPolicy & intpol) { if ( this == &intpol ) return *this; - BEGIN_OF("InterlacingPolicy operator ="); + const char* LOC = "InterlacingPolicy operator ="; + BEGIN_OF_MED(LOC); _dim = intpol._dim; _nbelem = intpol._nbelem; //ne prend pas en compte les points de Gauss @@ -211,7 +215,8 @@ public : NoInterlaceByTypeNoGaussPolicy & operator=(const NoInterlaceByTypeNoGaussPolicy & policy) { if ( this == &policy) return *this; - BEGIN_OF("NoInterlaceNoGaussPolicy operator ="); + const char* LOC = "NoInterlaceNoGaussPolicy operator ="; + BEGIN_OF_MED(LOC); InterlacingPolicy::operator=(policy); this->_G.set(policy._G); this->_T.set(policy._T); @@ -324,7 +329,8 @@ public : } FullInterlaceGaussPolicy & operator=(const FullInterlaceGaussPolicy & policy) { - BEGIN_OF("FullInterlaceGaussPolicy operator ="); + const char* LOC = "FullInterlaceGaussPolicy operator ="; + BEGIN_OF_MED(LOC); if ( this == &policy) return *this; @@ -420,7 +426,7 @@ public : NoInterlaceGaussPolicy(const NoInterlaceGaussPolicy & policy, bool shallowcopie=true) - : InterlacingPolicy(policy),_cumul(policy._cumul),_nbtypegeo(policy._nbtypegeo) + : InterlacingPolicy(policy),_nbtypegeo(policy._nbtypegeo),_cumul(policy._cumul) { //Seuls les tableaux de grande taille sont recopiés superficiellement if(shallowcopie) { @@ -438,7 +444,8 @@ public : NoInterlaceGaussPolicy & operator=(const NoInterlaceGaussPolicy & policy) { if ( this == &policy) return *this; - BEGIN_OF("NoInterlaceGaussPolicy operator ="); + const char* LOC = "NoInterlaceGaussPolicy operator ="; + BEGIN_OF_MED(LOC); InterlacingPolicy::operator=(policy); this->_G.set(policy._G); this->_S.set(policy._S); @@ -543,7 +550,8 @@ public : NoInterlaceByTypeGaussPolicy & operator=(const NoInterlaceByTypeGaussPolicy & policy) { if ( this == &policy) return *this; - BEGIN_OF("NoInterlaceGaussPolicy operator ="); + const char* LOC = "NoInterlaceGaussPolicy operator ="; + BEGIN_OF_MED(LOC); InterlacingPolicy::operator=(policy); this->_G.set(policy._G); this->_T.set(policy._T); diff --git a/src/MEDMEM/MEDMEM_InterlacingTraits.hxx b/src/MEDMEM/MEDMEM_InterlacingTraits.hxx index 3d1cb2a5d..bf8b3ab36 100644 --- a/src/MEDMEM/MEDMEM_InterlacingTraits.hxx +++ b/src/MEDMEM/MEDMEM_InterlacingTraits.hxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #ifndef MEDMEM_INTERLACING_TRAITS_HXX #define MEDMEM_INTERLACING_TRAITS_HXX diff --git a/src/MEDMEM/MEDMEM_MEDMEMchampLire.cxx b/src/MEDMEM/MEDMEM_MEDMEMchampLire.cxx index 785fbe3bf..f7beba6b1 100644 --- a/src/MEDMEM/MEDMEM_MEDMEMchampLire.cxx +++ b/src/MEDMEM/MEDMEM_MEDMEMchampLire.cxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #include "MEDMEM_MEDMEMchampLire.hxx" /* * En attendant une correction de la gestion du mode d'accès au fichier dans MEDfichier @@ -31,18 +34,18 @@ namespace med_2_3 { fflush(stderr) ; \ } -# define ISCRUTE(entier) { \ +# define ISCRUTE_MED(entier) { \ ICI ; \ fprintf(stderr,"%s = %d\n",#entier,entier) ; \ fflush(stderr) ; \ } -# define SSCRUTE(chaine) { \ +# define SSCRUTE_MED(chaine) { \ ICI ; \ fprintf(stderr,"%s = \"%s\"\n",#chaine,chaine) ; \ fflush(stderr) ; \ } -# define MESSAGE(chaine) { \ +# define MESSAGE_MED(chaine) { \ ICI ; \ fprintf(stderr,"%s\n",chaine) ; \ fflush(stderr) ; \ @@ -50,24 +53,6 @@ namespace med_2_3 { extern void _MEDmodeErreurVerrouiller(void); - /************************************************************************* - * COPYRIGHT (C) 1999 - 2003 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 - * - *************************************************************************/ - #include <med.h> #include <med_outils.h> @@ -200,14 +185,14 @@ namespace med_2_3 { /* Lire le nbre des points de GAUSS*/ if (_MEDattrEntierLire(datagroup3,MED_NOM_NGA,&ngauss) < 0) { - MESSAGE("Erreur à la lecture de l'attribut MED_NOM_NGA : "); - ISCRUTE(ngauss);goto ERROR; + MESSAGE_MED("Erreur à la lecture de l'attribut MED_NOM_NGA : "); + ISCRUTE_MED(ngauss);goto ERROR; }; /* Lire l'identificateur de localisation des points de GAUSS*/ if ( _MEDattrStringLire(datagroup3,MED_NOM_GAU,MED_TAILLE_NOM,locname) < 0) { - MESSAGE("Erreur à la lecture de l'attribut MED_NOM_GAU : "); - SSCRUTE(locname); goto ERROR; + MESSAGE_MED("Erreur à la lecture de l'attribut MED_NOM_GAU : "); + SSCRUTE_MED(locname); goto ERROR; } /* @@ -266,32 +251,32 @@ namespace med_2_3 { if ( pfluse ) { free(pfltab); free(pfltabtmp);} if (datagroup3>0) if (_MEDdatagroupFermer(datagroup3) < 0) { - MESSAGE("Impossible de fermer le datagroup : "); - ISCRUTE(datagroup3); ret = -1; + MESSAGE_MED("Impossible de fermer le datagroup : "); + ISCRUTE_MED(datagroup3); ret = -1; } if (datagroup2>0) if (_MEDdatagroupFermer(datagroup2) < 0) { - MESSAGE("Impossible de fermer le datagroup : "); - ISCRUTE(datagroup2); ret = -1; + MESSAGE_MED("Impossible de fermer le datagroup : "); + ISCRUTE_MED(datagroup2); ret = -1; } if (datagroup1>0) if (_MEDdatagroupFermer(datagroup1) < 0) { - MESSAGE("Impossible de fermer le datagroup : "); - ISCRUTE(datagroup1); ret = -1; + MESSAGE_MED("Impossible de fermer le datagroup : "); + ISCRUTE_MED(datagroup1); ret = -1; } if (gid>0) if (_MEDdatagroupFermer(gid) < 0) { - MESSAGE("Impossible de fermer le datagroup : "); - ISCRUTE(gid); ret = -1; + MESSAGE_MED("Impossible de fermer le datagroup : "); + ISCRUTE_MED(gid); ret = -1; } return ret; } -#undef MESSAGE -#undef SSCRUTE -#undef ISCRUTE +#undef MESSAGE_MED +#undef SSCRUTE_MED +#undef ISCRUTE_MED } } diff --git a/src/MEDMEM/MEDMEM_MEDMEMchampLire.hxx b/src/MEDMEM/MEDMEM_MEDMEMchampLire.hxx index ed6c7c93f..c2726baf1 100644 --- a/src/MEDMEM/MEDMEM_MEDMEMchampLire.hxx +++ b/src/MEDMEM/MEDMEM_MEDMEMchampLire.hxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #ifndef MEDMEM_MEDMEMCHAMPLIRE_HXX #define MEDMEM_MEDMEMCHAMPLIRE_HXX diff --git a/src/MEDMEM/MEDMEM_MEDMEMgaussEcr.cxx b/src/MEDMEM/MEDMEM_MEDMEMgaussEcr.cxx index 280b87c9e..413e94402 100644 --- a/src/MEDMEM/MEDMEM_MEDMEMgaussEcr.cxx +++ b/src/MEDMEM/MEDMEM_MEDMEMgaussEcr.cxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #include "MEDMEM_MEDMEMgaussEcr.hxx" /* * En attendant une correction de la gestion du mode d'accès au fichier dans MEDfichier @@ -30,18 +33,18 @@ namespace med_2_3 { fflush(stderr) ;\ } -# define ISCRUTE(entier) {\ +# define ISCRUTE_MED(entier) {\ ICI ;\ fprintf(stderr,"%s = %d\n",#entier,entier) ;\ fflush(stderr) ;\ } -# define SSCRUTE(chaine) {\ +# define SSCRUTE_MED(chaine) {\ ICI ;\ fprintf(stderr,"%s = \"%s\"\n",#chaine,chaine) ;\ fflush(stderr) ;\ } -# define MESSAGE(chaine) {\ +# define MESSAGE_MED(chaine) {\ ICI ;\ fprintf(stderr,"%s\n",chaine) ;\ fflush(stderr) ;\ @@ -49,24 +52,6 @@ namespace med_2_3 { extern void _MEDmodeErreurVerrouiller(void); - /************************************************************************* - * COPYRIGHT (C) 1999 - 2003 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 - * - *************************************************************************/ - /* * - Nom de la fonction : MEDgaussEcr * - Description : Itérateur renvoyant (n°pdt,n°or), le nbre de point de GAUSS pour le type d'élément, @@ -108,8 +93,8 @@ namespace med_2_3 { chemin[MED_TAILLE_GAUSS-1] = '\0'; if ((gid = _MEDdatagroupOuvrir(fid,chemin)) < 0) if ((gid = _MEDdatagroupCreer(fid,chemin)) < 0) { - MESSAGE("Impossible de creer le groupe MED_GAUSS : "); - SSCRUTE(chemin); goto ERROR; + MESSAGE_MED("Impossible de creer le groupe MED_GAUSS : "); + SSCRUTE_MED(chemin); goto ERROR; } /* @@ -119,8 +104,8 @@ namespace med_2_3 { if ((chid = _MEDdatagroupOuvrir(gid,locname)) >= 0) { if ( false )//MED_MODE_ACCES != MED_LECTURE_ECRITURE ) { - MESSAGE("Le nom de localisation existe déjà : "); - SSCRUTE(locname); goto ERROR; + MESSAGE_MED("Le nom de localisation existe déjà : "); + SSCRUTE_MED(locname); goto ERROR; } } else if ((chid = _MEDdatagroupCreer(gid,locname)) < 0) @@ -130,8 +115,8 @@ namespace med_2_3 { * On stocke <ngauss> sous forme d'attribut */ if (_MEDattrEntierEcrire(chid,MED_NOM_NBR,&ngauss) < 0) { - MESSAGE("Erreur à l'écriture de l'attribut MED_NOM_NBR : "); - ISCRUTE(ngauss);goto ERROR; + MESSAGE_MED("Erreur à l'écriture de l'attribut MED_NOM_NBR : "); + ISCRUTE_MED(ngauss);goto ERROR; }; /* @@ -145,8 +130,8 @@ namespace med_2_3 { un enum. */ if (_MEDattrEntierEcrire(chid,MED_NOM_GEO,&typegeo) < 0) { - MESSAGE("Erreur à l'écriture de l'attribut MED_NOM_GEO : "); - ISCRUTE(type_geo);goto ERROR; + MESSAGE_MED("Erreur à l'écriture de l'attribut MED_NOM_GEO : "); + ISCRUTE_MED(type_geo);goto ERROR; }; @@ -157,8 +142,8 @@ namespace med_2_3 { dimd[0] = (type_geo%100)*(type_geo/100); if ( _MEDdatasetNumEcrire(chid,MED_NOM_COO,MED_FLOAT64,mode_coo,(type_geo/100),MED_ALL,MED_NOPF,MED_NO_PFLMOD,0,MED_NOPG,dimd, (unsigned char*) refcoo) < 0 ) { - MESSAGE("Impossible d'ecrire le dataset : ");SSCRUTE(MED_NOM_COO); - ISCRUTE(dimd); goto ERROR; + MESSAGE_MED("Impossible d'ecrire le dataset : ");SSCRUTE_MED(MED_NOM_COO); + ISCRUTE_MED(dimd); goto ERROR; } /* @@ -168,8 +153,8 @@ namespace med_2_3 { dimd[0] = ngauss*(type_geo/100); if ( _MEDdatasetNumEcrire(chid,MED_NOM_GAU,MED_FLOAT64,mode_coo,(type_geo/100),MED_ALL,MED_NOPF,MED_NO_PFLMOD,0,MED_NOPG,dimd, (unsigned char*) gscoo) < 0 ) { - MESSAGE("Impossible d'ecrire le dataset : ");SSCRUTE(MED_NOM_GAU); - ISCRUTE(dimd); goto ERROR; + MESSAGE_MED("Impossible d'ecrire le dataset : ");SSCRUTE_MED(MED_NOM_GAU); + ISCRUTE_MED(dimd); goto ERROR; } /* @@ -179,8 +164,8 @@ namespace med_2_3 { dimd[0] = ngauss; if ( _MEDdatasetNumEcrire(chid,MED_NOM_VAL,MED_FLOAT64,mode_coo,1,MED_ALL,MED_NOPF,MED_NO_PFLMOD,0,MED_NOPG,dimd, (unsigned char*) wg) < 0 ) { - MESSAGE("Impossible d'ecrire le dataset : ");SSCRUTE(MED_NOM_VAL); - ISCRUTE(dimd); goto ERROR; + MESSAGE_MED("Impossible d'ecrire le dataset : ");SSCRUTE_MED(MED_NOM_VAL); + ISCRUTE_MED(dimd); goto ERROR; } @@ -193,21 +178,21 @@ namespace med_2_3 { */ if (chid>0) if (_MEDdatagroupFermer(chid) < 0) { - MESSAGE("Impossible de fermer le datagroup : "); - ISCRUTE(chid); ret = -1; + MESSAGE_MED("Impossible de fermer le datagroup : "); + ISCRUTE_MED(chid); ret = -1; } if (gid>0) if (_MEDdatagroupFermer(gid) < 0) { - MESSAGE("Impossible de fermer le datagroup : "); - ISCRUTE(gid); ret = -1; + MESSAGE_MED("Impossible de fermer le datagroup : "); + ISCRUTE_MED(gid); ret = -1; } return ret; } -#undef MESSAGE -#undef SSCRUTE -#undef ISCRUTE +#undef MESSAGE_MED +#undef SSCRUTE_MED +#undef ISCRUTE_MED } } diff --git a/src/MEDMEM/MEDMEM_MEDMEMgaussEcr.hxx b/src/MEDMEM/MEDMEM_MEDMEMgaussEcr.hxx index 74fbf06e5..770392445 100644 --- a/src/MEDMEM/MEDMEM_MEDMEMgaussEcr.hxx +++ b/src/MEDMEM/MEDMEM_MEDMEMgaussEcr.hxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #ifndef MEDMEM_MEDMEMGAUSSECR_HXX #define MEDMEM_MEDMEMGAUSSECR_HXX diff --git a/src/MEDMEM/MEDMEM_MEDMEMprofilEcr.cxx b/src/MEDMEM/MEDMEM_MEDMEMprofilEcr.cxx index 1a6bfb887..f9c681ac8 100644 --- a/src/MEDMEM/MEDMEM_MEDMEMprofilEcr.cxx +++ b/src/MEDMEM/MEDMEM_MEDMEMprofilEcr.cxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #include "MEDMEM_MEDMEMprofilEcr.hxx" /* * En attendant une correction de la gestion du mode d'accès au fichier dans MEDfichier @@ -31,18 +34,18 @@ namespace med_2_3 { fflush(stderr) ; \ } -# define ISCRUTE(entier) { \ +# define ISCRUTE_MED(entier) { \ ICI ; \ fprintf(stderr,"%s = %d\n",#entier,entier) ; \ fflush(stderr) ; \ } -# define SSCRUTE(chaine) { \ +# define SSCRUTE_MED(chaine) { \ ICI ; \ fprintf(stderr,"%s = \"%s\"\n",#chaine,chaine) ; \ fflush(stderr) ; \ } -# define MESSAGE(chaine) { \ +# define MESSAGE_MED(chaine) { \ ICI ; \ fprintf(stderr,"%s\n",chaine) ; \ fflush(stderr) ; \ @@ -50,24 +53,6 @@ namespace med_2_3 { extern void _MEDmodeErreurVerrouiller(void); - /************************************************************************* - * COPYRIGHT (C) 1999 - 2003 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 - * - *************************************************************************/ - #include <med.h> #include <med_outils.h> @@ -94,8 +79,8 @@ namespace med_2_3 { chemin[MED_TAILLE_PROFILS-1] = '\0'; if ((gid = _MEDdatagroupOuvrir(fid,chemin)) < 0) if ((gid = _MEDdatagroupCreer(fid,chemin)) < 0) { - MESSAGE("Impossible de creer le groupe MED_PROFILS : "); - SSCRUTE(chemin); goto ERROR; + MESSAGE_MED("Impossible de creer le groupe MED_PROFILS : "); + SSCRUTE_MED(chemin); goto ERROR; } /* @@ -105,8 +90,8 @@ namespace med_2_3 { if ((chid = _MEDdatagroupOuvrir(gid,profilname)) >= 0) { if ( false )//MED_MODE_ACCES != MED_LECTURE_ECRITURE ) { - MESSAGE("Le profil existe déjà : "); - SSCRUTE(profilname); goto ERROR; + MESSAGE_MED("Le profil existe déjà : "); + SSCRUTE_MED(profilname); goto ERROR; } } else if ((chid = _MEDdatagroupCreer(gid,profilname)) < 0) @@ -116,8 +101,8 @@ namespace med_2_3 { * On stocke "n" sous forme d'attribut */ if ((ret = _MEDattrEntierEcrire(chid,MED_NOM_NBR,&n)) < 0) { - MESSAGE("Erreur à l'écriture de l'attribut MED_NOM_NBR : "); - ISCRUTE(n); goto ERROR; + MESSAGE_MED("Erreur à l'écriture de l'attribut MED_NOM_NBR : "); + ISCRUTE_MED(n); goto ERROR; }; /* @@ -132,8 +117,8 @@ namespace med_2_3 { (unsigned char*) pflval); #endif if (ret < 0 ) { - MESSAGE("Impossible d'ecrire le dataset pflval de taille : "); - ISCRUTE(n); goto ERROR; + MESSAGE_MED("Impossible d'ecrire le dataset pflval de taille : "); + ISCRUTE_MED(n); goto ERROR; } ret = 0; @@ -142,21 +127,21 @@ namespace med_2_3 { * On ferme tout */ if (chid>0) if (_MEDdatagroupFermer(chid) < 0) { - MESSAGE("Impossible de fermer le datagroup : "); - ISCRUTE(chid); ret = -1; + MESSAGE_MED("Impossible de fermer le datagroup : "); + ISCRUTE_MED(chid); ret = -1; } if (gid>0) if (_MEDdatagroupFermer(gid) < 0) { - MESSAGE("Impossible de fermer le datagroup : "); - ISCRUTE(gid); ret = -1; + MESSAGE_MED("Impossible de fermer le datagroup : "); + ISCRUTE_MED(gid); ret = -1; } return ret; } -#undef MESSAGE -#undef SSCRUTE -#undef ISCRUTE +#undef MESSAGE_MED +#undef SSCRUTE_MED +#undef ISCRUTE_MED } } diff --git a/src/MEDMEM/MEDMEM_MEDMEMprofilEcr.hxx b/src/MEDMEM/MEDMEM_MEDMEMprofilEcr.hxx index d8e13630b..19850ac7d 100644 --- a/src/MEDMEM/MEDMEM_MEDMEMprofilEcr.hxx +++ b/src/MEDMEM/MEDMEM_MEDMEMprofilEcr.hxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #ifndef MEDMEM_MEDMEMPROFILECR_HXX #define MEDMEM_MEDMEMPROFILECR_HXX diff --git a/src/MEDMEM/MEDMEM_Med.cxx b/src/MEDMEM/MEDMEM_Med.cxx index 8476aa2a1..fa94ee35b 100644 --- a/src/MEDMEM/MEDMEM_Med.cxx +++ b/src/MEDMEM/MEDMEM_Med.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // # include <string> # include <math.h> @@ -40,38 +42,64 @@ using namespace MED_EN; #define MED_NOPDT -1 /*! - Constructor. + +\defgroup MED_constructors Constructors + +\defgroup MED_query Query methods +These methods enable the user to retrieve information +about a MED file structure, i.e. the meshes, supports +and fields that it contains. + +\defgroup MED_io File I/O methods +These methods are similar to their MESH counterparts. +Reading should be achieved thrfough the MED constructor, while writing +is performed thanks to two calls : one attaching a driver to the MED +object, the other one writing the file. + */ MED::MED() { - MESSAGE("MED::MED()"); -}; + MESSAGE_MED("MED::MED()"); +} + +/*! \if MEDMEM_ug +\addtogroup MED_constructors +@{ +\endif +*/ /*! - Constructor. +This constructor constructs the Med object from the file \a filename. +The driver type can specify whether the file is opened in read, write or +read/write mode. Specifying MED_DRIVER as a \a driverType opens the file in read/write mode. +It is also possible to use VTK_DRIVER to open a VTK ascii file. */ MED::MED(driverTypes driverType, const string & fileName) { - const char * LOC = "MED::MED(driverTypes driverType, const string & fileName) : "; - BEGIN_OF(LOC); + const char* LOC = "MED::MED(driverTypes driverType, const string & fileName) : "; + BEGIN_OF_MED(LOC); - MESSAGE(LOC << "driverType = " << driverType); + MESSAGE_MED(PREFIX_MED << "driverType = " << driverType); - int current = addDriver(driverType,fileName,MED_LECT); + int current = addDriver(driverType,fileName,RDONLY); _drivers[current]->open(); _drivers[current]->readFileStruct(); _drivers[current]->close(); - END_OF(LOC); -}; + END_OF_MED(LOC); +} -/*! +/*!\if MEDMEM_ug @} \endif */ + + +/*!\ifnot MEDMEM_ug Destructor. +\endif */ MED::~MED() { - const char * LOC = "MED::~MED() : "; - BEGIN_OF(LOC); + const char* LOC = "MED::~MED() : "; + BEGIN_OF_MED(LOC); // Analysis of the object MED @@ -83,9 +111,9 @@ MED::~MED() if ( (*currentField).first != NULL) index++; } - MESSAGE(LOC << " there is(are) " << index << " field(s):"); + MESSAGE_MED(PREFIX_MED << " there is(are) " << index << " field(s):"); for ( currentField=_meshName.begin();currentField != _meshName.end(); currentField++ ) { - if ( (*currentField).first != NULL) MESSAGE(" " << ((*currentField).first)->getName().c_str()); + if ( (*currentField).first != NULL) MESSAGE_MED(" " << ((*currentField).first)->getName().c_str()); } map<MESH_NAME_, map<MED_EN::medEntityMesh,SUPPORT *> >::iterator itSupportOnMesh ; @@ -96,7 +124,7 @@ MED::~MED() index++; } - MESSAGE(LOC << " there is(are) " << index << " support(s):"); + MESSAGE_MED(PREFIX_MED << " there is(are) " << index << " support(s):"); map<MESH_NAME_,MESH*>::const_iterator currentMesh; index =0; @@ -105,15 +133,15 @@ MED::~MED() index++; } - MESSAGE(LOC << " there is(are) " << index << " meshe(s):"); + MESSAGE_MED(PREFIX_MED << " there is(are) " << index << " meshe(s):"); // for ( currentMesh=_meshes.begin();currentMesh != _meshes.end(); currentMesh++ ) { // if ( (*currentMesh).second != NULL) // { -// SCRUTE((*currentMesh).second); +// SCRUTE_MED((*currentMesh).second); // string meshName = ((*currentMesh).second)->getName(); -// MESSAGE(" " << meshName); +// MESSAGE_MED(" " << meshName); // } // } @@ -130,7 +158,7 @@ MED::~MED() delete (FIELD<double>*) (*currentField).first ; break ; default : - MESSAGE(LOC << "Field has type different of int or double, could not destroy its values array !") ; + MESSAGE_MED(PREFIX_MED << "Field has type different of int or double, could not destroy its values array !") ; delete (*currentField).first; } } @@ -157,19 +185,24 @@ MED::~MED() index =_drivers.size(); - MESSAGE(LOC << "In this object MED there is(are) " << index << " driver(s):"); + MESSAGE_MED(PREFIX_MED << "In this object MED there is(are) " << index << " driver(s):"); for (unsigned int ind=0; ind < _drivers.size(); ind++ ) { - SCRUTE(_drivers[ind]); + SCRUTE_MED(_drivers[ind]); if ( _drivers[ind] != NULL) delete _drivers[ind]; } - END_OF(LOC); -} ; + END_OF_MED(LOC); +} +/*! \if MEDMEM_ug +\addtogroup MED_io +@{ +\endif +*/ /*! Create the specified driver and return its index reference to path to @@ -177,16 +210,16 @@ MED::~MED() */ int MED::addDriver(driverTypes driverType, const string & fileName="Default File Name.med", - MED_EN::med_mode_acces access) { - - const char * LOC = "MED::addDriver(driverTypes driverType, const string & fileName=\"Default File Name.med\") : "; + MED_EN::med_mode_acces access) +{ - BEGIN_OF(LOC); + const char* LOC = "MED::addDriver(driverTypes driverType, const string & fileName=\"Default File Name.med\") : "; + BEGIN_OF_MED(LOC); - MESSAGE(LOC << " the file name is " << fileName); + MESSAGE_MED(PREFIX_MED << " the file name is " << fileName); - SCRUTE(driverType); - SCRUTE(access); + SCRUTE_MED(driverType); + SCRUTE_MED(access); GENDRIVER *driver = DRIVERFACTORY::buildDriverForMed(driverType,fileName, this,access); @@ -197,7 +230,7 @@ int MED::addDriver(driverTypes driverType, driver->setId(current); - END_OF(LOC); + END_OF_MED(LOC); return current; } @@ -207,29 +240,30 @@ int MED::addDriver(driverTypes driverType, read or write methods. */ int MED::addDriver(GENDRIVER & driver) { - const char * LOC = "MED::addDriver(GENDRIVER &) : "; int current; - BEGIN_OF(LOC); + const char* LOC = "MED::addDriver(GENDRIVER &) : "; + BEGIN_OF_MED(LOC); - SCRUTE(_drivers.size()); + SCRUTE_MED(_drivers.size()); _drivers.push_back(&driver); - SCRUTE(_drivers.size()); + SCRUTE_MED(_drivers.size()); - SCRUTE(_drivers[0]); - SCRUTE(driver); + SCRUTE_MED(_drivers[0]); + SCRUTE_MED(driver); current = _drivers.size()-1; - SCRUTE(current); + SCRUTE_MED(current); driver.setId(current); - END_OF(LOC); + END_OF_MED(LOC); return current; } +/*! \if MEDMEM_ug @} \endif */ /*! Remove the driver referenced by its index. @@ -238,18 +272,20 @@ void MED::rmDriver (int index/*=0*/) throw (MED_EXCEPTION) { const char * LOC = "MED::rmDriver (int index=0): "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); - if (_drivers[index]) + if (index >= 0 && index < _drivers.size() && _drivers[index]) { + delete _drivers[index]; + _drivers[index] = 0; //_drivers.erase(&_drivers[index]); - {} + } else throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "The index given is invalid, index must be between 0 and |" << _drivers.size() ) ); - END_OF(LOC); + END_OF_MED(LOC); } /*! @@ -259,19 +295,27 @@ void MED::writeFrom (int index/*=0*/) throw (MED_EXCEPTION) { const char * LOC = "MED::write (int index=0): "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); - if (_drivers[index]) { + if (index >= 0 && index < _drivers.size() && _drivers[index]) { // open and close are made by all objects ! _drivers[index]->writeFrom(); } - throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) - << "The index given is invalid, index must be between 0 and |" - << _drivers.size() - ) - ); - END_OF(LOC); -}; + else { + throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) + << "The index given is invalid, index must be between 0 and |" + << _drivers.size() + ) + ); + } + END_OF_MED(LOC); +} + +/*!\if MEDMEM_ug +\addtogroup MED_io +@{ +\endif +*/ /*! Write all objects with the driver given by its index. @@ -280,7 +324,7 @@ void MED::write (int index/*=0*/) throw (MED_EXCEPTION) { const char * LOC = "MED::write (int index=0): "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_drivers[index]) { // open and close are made by the subsequent objects ! @@ -292,8 +336,9 @@ void MED::write (int index/*=0*/) << _drivers.size() ) ); - END_OF(LOC); -}; + END_OF_MED(LOC); +} +/*!\if MEDMEM_ug @} \endif */ /*! Parse all the file and generate empty object. @@ -301,13 +346,13 @@ void MED::write (int index/*=0*/) All object must be read explicitly later with their own method read or use MED::read to read all. - This method is automaticaly call by constructor with driver information. + This method is automatically called by constructor with driver information. */ void MED::readFileStruct (int index/*=0*/) throw (MED_EXCEPTION) { const char * LOC = "MED::readFileStruct (int index=0): "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_drivers[index]) { _drivers[index]->open(); @@ -329,15 +374,15 @@ void MED::read (int index/*=0*/) throw (MED_EXCEPTION) { const char * LOC = "MED::read (int index=0): "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); - SCRUTE(index); + SCRUTE_MED(index); if (_drivers[index]) { // open and close are made by all objects ! - SCRUTE(index); - SCRUTE(_drivers[index]); - SCRUTE(&_drivers[index]); + SCRUTE_MED(index); + SCRUTE_MED(_drivers[index]); + SCRUTE_MED(&_drivers[index]); // _drivers[index]->open(); _drivers[index]->read(); // _drivers[index]->close(); @@ -348,36 +393,42 @@ void MED::read (int index/*=0*/) << _drivers.size()-1 ) ); - END_OF(LOC); + END_OF_MED(LOC); -}; +} // ------- End Of Drivers Management Part -/*! - Get the number of MESH objects. +/*! \if MEDMEM_ug +\addtogroup MED_query +@{ +\endif */ -int MED::getNumberOfMeshes ( void ) const { - const char * LOC = "MED::getNumberOfMeshes ( void ) const : "; - BEGIN_OF(LOC); +/*! + Gets the number of MESH objects. +*/ +int MED::getNumberOfMeshes ( void ) const +{ + const char* LOC = "MED::getNumberOfMeshes ( void ) const : "; + BEGIN_OF_MED(LOC); return _meshes.size(); -}; +} /*! - Get the number of FIELD objects. + Gets the number of FIELD objects. */ -int MED::getNumberOfFields ( void ) const { - - const char * LOC = "MED::getNumberOfFields ( void ) const : "; - BEGIN_OF(LOC); +int MED::getNumberOfFields ( void ) const +{ + const char* LOC = "MED::getNumberOfFields ( void ) const : "; + BEGIN_OF_MED(LOC); return _fields.size(); // we get number of field with different name -}; +} /*! - Get the names of all MESH objects. + Gets the names of all MESH objects. meshNames is an in/out argument. @@ -388,8 +439,8 @@ int MED::getNumberOfFields ( void ) const { void MED::getMeshNames ( string * meshNames ) const throw (MED_EXCEPTION) { - const char * LOC = "MED::getMeshNames ( string * ) const : "; - BEGIN_OF(LOC); + const char* LOC = "MED::getMeshNames ( string * ) const : "; + BEGIN_OF_MED(LOC); // REM : ALLOCATION D'UN TABLEAU DE POINTEURS SUR STRING FAITE PAR LE CLIENT map<MESH_NAME_,MESH*>::const_iterator currentMesh; // ??ITERATEUR CONST SUR UN OBJET NON CONST ?? @@ -401,18 +452,18 @@ void MED::getMeshNames ( string * meshNames ) const meshNamesIndex++; // CF OPTIMISATION } - END_OF(LOC); -}; + END_OF_MED(LOC); +} /*! - Get the names of all MESH objects. + Gets the names of all MESH objects. - Return a deque<string> object which contain the name of all MESH objects. + Returns a deque<string> object which contain the name of all MESH objects. */ -deque<string> MED::getMeshNames () const { - - const char * LOC = "MED::getMeshNames () const : "; - BEGIN_OF(LOC); +deque<string> MED::getMeshNames () const +{ + const char* LOC = "MED::getMeshNames () const : "; + BEGIN_OF_MED(LOC); deque<string> meshNames(_meshes.size()); @@ -425,20 +476,20 @@ deque<string> MED::getMeshNames () const { meshNamesIndex++; // CF OPTIMISATION } - END_OF(LOC); + END_OF_MED(LOC); return meshNames ; -}; +} /*! - Return a reference to the MESH object named meshName. + Returns a reference to the MESH object named meshName. */ MESH * MED::getMesh ( const string & meshName ) const throw (MED_EXCEPTION) { const char * LOC = "MED::getMesh ( const string & meshName ) const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); map<MESH_NAME_,MESH*>::const_iterator itMeshes = _meshes.find(meshName); @@ -451,11 +502,11 @@ MESH * MED::getMesh ( const string & meshName ) const return (*itMeshes).second; - END_OF(LOC); + END_OF_MED(LOC); } /*! - \internal Return a reference to the MESH object associated with + \internal Returns a reference to the MESH object associated with field argument. */ MESH * MED::getMesh (const FIELD_ * const field ) const @@ -463,7 +514,7 @@ MESH * MED::getMesh (const FIELD_ * const field ) const { const char * LOC = "MED::getMesh ( const FIELD * field ) const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); FIELD_ * f = const_cast< FIELD_* > (field); // Comment faire mieux ? map<FIELD_ *, MESH_NAME_>::const_iterator itMeshName = _meshName.find(f); @@ -485,14 +536,14 @@ MESH * MED::getMesh (const FIELD_ * const field ) const ) ); - END_OF(LOC); + END_OF_MED(LOC); return (*itMeshes).second; -}; +} /*! - Get the names of all FIELD objects. + Gets the names of all FIELD objects. fieldNames is an in/out argument. @@ -503,8 +554,8 @@ MESH * MED::getMesh (const FIELD_ * const field ) const void MED::getFieldNames ( string * fieldNames ) const throw (MED_EXCEPTION) { - const char * LOC = "MED::getFieldNames ( string * ) const : "; - BEGIN_OF(LOC); + const char* LOC = "MED::getFieldNames ( string * ) const : "; + BEGIN_OF_MED(LOC); // unsigned int fieldNamesSize = sizeof(fieldNames) / sizeof(string *); @@ -525,19 +576,19 @@ void MED::getFieldNames ( string * fieldNames ) const fieldNamesIndex++; // CF OPTIMISATION } - END_OF(LOC); + END_OF_MED(LOC); -}; +} /*! - Get the names of all FIELD objects. + Gets the names of all FIELD objects. - Return a deque<string> object which contain the name of all FIELD objects. + Returns a deque<string> object which contain the name of all FIELD objects. */ -deque<string> MED::getFieldNames () const { - - const char * LOC = "MED::getFieldNames ( ) const : "; - BEGIN_OF(LOC); +deque<string> MED::getFieldNames () const +{ + const char* LOC = "MED::getFieldNames ( ) const : "; + BEGIN_OF_MED(LOC); deque<string> fieldNames(_fields.size()); @@ -550,20 +601,27 @@ deque<string> MED::getFieldNames () const { fieldNamesIndex++; // CF OPTIMISATION } - END_OF(LOC); + END_OF_MED(LOC); return fieldNames ; -}; +} /*! - Return a deque<DT_IT_> which contain all iteration step for the FIELD - identified by its name. + Returns a deque<DT_IT_> which contain all iteration step for the FIELD + identified by its name. DT_IT_ definition is +\verbatim +typedef struct { int dt; int it; } DT_IT_; +\endverbatim + +\a dt represents the time iteration number, while \a it represents +the inner iteration number. + */ deque<DT_IT_> MED::getFieldIteration (const string & fieldName) const throw (MED_EXCEPTION) { const char * LOC = "MED::getFieldIteration ( const string & ) const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); map<FIELD_NAME_,MAP_DT_IT_>::const_iterator itFields = _fields.find(fieldName); @@ -579,7 +637,7 @@ deque<DT_IT_> MED::getFieldIteration (const string & fieldName) const int iterationSize = myIterationMap.size(); - SCRUTE(iterationSize); + SCRUTE_MED(iterationSize); deque<DT_IT_> Iteration(iterationSize); @@ -588,24 +646,24 @@ deque<DT_IT_> MED::getFieldIteration (const string & fieldName) const for (currentIterator = myIterationMap.begin(); currentIterator != myIterationMap.end(); currentIterator++ ) { - SCRUTE(((*currentIterator).first).dt); - SCRUTE(((*currentIterator).first).it); + SCRUTE_MED(((*currentIterator).first).dt); + SCRUTE_MED(((*currentIterator).first).it); Iteration[iterationIndex].dt = ((*currentIterator).first).dt; Iteration[iterationIndex].it = ((*currentIterator).first).it; // Iteration[iterationIndex]=(*currentIterator).first; - SCRUTE(Iteration[iterationIndex].dt); - SCRUTE(Iteration[iterationIndex].it); + SCRUTE_MED(Iteration[iterationIndex].dt); + SCRUTE_MED(Iteration[iterationIndex].it); iterationIndex++; // CF OPTIMISATION } - END_OF(LOC); + END_OF_MED(LOC); return Iteration ; -}; +} /*! - Return a reference to the FIELD object named fieldName with + Returns a reference to the FIELD object named fieldName with time step number dt and order number it. */ FIELD_ * MED::getField ( const string & fieldName, const int dt=MED_NOPDT, const int it=MED_NOPDT ) const @@ -613,9 +671,9 @@ FIELD_ * MED::getField ( const string & fieldName, const int dt=MED_NO { const char * LOC = "MED::getField ( const string &, const int, const int ) const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); - MESSAGE(LOC << "fieldName = "<<fieldName<<", dt ="<<dt<<", it = "<<it); + MESSAGE_MED(LOC << "fieldName = "<<fieldName<<", dt ="<<dt<<", it = "<<it); DT_IT_ dtIt; @@ -642,15 +700,20 @@ FIELD_ * MED::getField ( const string & fieldName, const int dt=MED_NO ) ); - END_OF(LOC); + END_OF_MED(LOC); //return _fields[fieldName][dtIt]; return (*itMap_dtIt).second; -}; +} +/*!\if MEDMEM_ug + @} + \endif +*/ + /*! - Return a reference to the FIELD object named fieldName with + Returns a reference to the FIELD object named fieldName with time and iteration nb it. */ FIELD_ *MED::getField2(const string & fieldName, double time, int it) const throw (MEDEXCEPTION) @@ -673,22 +736,23 @@ FIELD_ *MED::getField2(const string & fieldName, double time, int it) const thr if(!found) throw MED_EXCEPTION(LOCALIZED( STRING(LOC) << "There is no known field existing at specified time and iteration !!! ")); return ret; - END_OF(LOC); + //END_OF_MED(); } // fiend ostream & MED::operator<<(ostream &os,const MED & med) const { // return os; // }; + /*! - Return a map<MED_EN::medEntityMesh,SUPPORT*> which contain + Returns a map<MED_EN::medEntityMesh,SUPPORT*> which contain foreach entity, a reference to the SUPPORT on all elements. */ const map<MED_EN::medEntityMesh,SUPPORT*> & MED::getSupports(const string & meshName) const throw (MED_EXCEPTION) { const char * LOC = "MED::getSupports ( const string ) const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); map<MESH_NAME_, map<MED_EN::medEntityMesh,SUPPORT *> >::const_iterator itSupportOnMesh = _support.find(meshName) ; @@ -698,19 +762,26 @@ const map<MED_EN::medEntityMesh,SUPPORT*> & MED::getSupports(const string & mesh << meshName << "|" ) ); - END_OF(LOC); + END_OF_MED(LOC); return (*itSupportOnMesh).second ; } + +/*! \if MEDMEM_ug +\addtogroup MED_query +@{ +\endif +*/ + /*! - Return a reference to the SUPPORT object on all elements of entity + Returns a reference to the SUPPORT object on all elements of entity for the MESH named meshName. */ SUPPORT * MED::getSupport (const string & meshName,MED_EN::medEntityMesh entity) const throw (MED_EXCEPTION) { const char * LOC = "MED::getSupport ( const string, MED_EN::medEntityMesh ) const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); int index = 0; map<MESH_NAME_, map<MED_EN::medEntityMesh,SUPPORT *> >::const_iterator const_itSupportOnMesh; @@ -723,7 +794,7 @@ SUPPORT * MED::getSupport (const string & meshName,MED_EN::medEntityMesh entity const_itSupport!=(*const_itSupportOnMesh).second.end();const_itSupport++) index++; } - MESSAGE(LOC << "In this MED object there is(are) " << index << " support(s):"); + MESSAGE_MED(LOC << "In this MED object there is(are) " << index << " support(s):"); for (const_itSupportOnMesh=_support.begin();const_itSupportOnMesh != _support.end(); const_itSupportOnMesh++ ) { @@ -731,7 +802,7 @@ SUPPORT * MED::getSupport (const string & meshName,MED_EN::medEntityMesh entity for (const_itSupport=(*const_itSupportOnMesh).second.begin(); const_itSupport!=(*const_itSupportOnMesh).second.end();const_itSupport++) { - MESSAGE(LOC << "Support on mesh " << (*const_itSupportOnMesh).first << " on entity " << (*const_itSupport).first << " : " << *((*const_itSupport).second)); + MESSAGE_MED(LOC << "Support on mesh " << (*const_itSupportOnMesh).first << " on entity " << (*const_itSupport).first << " : " << *((*const_itSupport).second)); } } @@ -767,18 +838,30 @@ SUPPORT * MED::getSupport (const string & meshName,MED_EN::medEntityMesh entity << meshName << "|" ) ); - END_OF(LOC); + END_OF_MED(LOC); return (*itSupport).second ; -}; +} +/*!\if MEDMEM_ug @} \endif */ + + /*! - Temporary method : when all MESH objects are read, this methods - update all SUPPORT objects with the rigth dimension. +The need for this method arises from the following situation. +When loading a mesh, Medmem reads the constituent elements +in the Med file. It is possible at this stage that not all +constituent elements are stored in memory (For instance, reading +a 2D mesh, not all the edges are present, because only +the boundaries were stored in the file). +When computing descending connectivities, Medmem stores all the +faces and has a corresponding numbering. This introduces a +discrepancy between the support numbering which was determined at +file loading and the new numbering. The following method +synchronizes the two numberings. */ void MED::updateSupport () { - const char * LOC = "MED::updateSupport () : "; - BEGIN_OF(LOC); + const char* LOC = "MED::updateSupport () : "; + BEGIN_OF_MED(LOC); map<MESH_NAME_, map<MED_EN::medEntityMesh,SUPPORT *> >::iterator itSupportOnMesh ; for ( itSupportOnMesh=_support.begin();itSupportOnMesh != _support.end(); itSupportOnMesh++ ) { @@ -795,7 +878,7 @@ void MED::updateSupport () } catch (MEDEXCEPTION & ex) { // entity not defined in mesh -> we remove support on it ! - MESSAGE(LOC<<ex.what()); + MESSAGE_MED(PREFIX_MED<<ex.what()); delete (*itSupport).second ; //(*itSupportOnMesh).second.erase(itSupport) ; // that's right ???? //itSupport-- ; @@ -817,11 +900,11 @@ void MED::updateSupport () } } - END_OF(LOC); + END_OF_MED(LOC); } /*! - Add the given MESH object. MED object control it, + Adds the given MESH object. MED object control it, and destroy it, so you must not destroy it after. The meshName is given by the MESH object. @@ -830,7 +913,7 @@ void MED::addMesh( MESH * const ptrMesh) throw (MED_EXCEPTION) { const char * LOC = "MED::addMesh(const MESH * ptrMesh): "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if ( ! ptrMesh ) throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrMesh must not be NULL !")); @@ -845,7 +928,7 @@ void MED::addMesh( MESH * const ptrMesh) // _meshes[meshName] = meshToMed; - END_OF(LOC); + END_OF_MED(LOC); } /*! @@ -858,7 +941,7 @@ void MED::addField( FIELD_ * const ptrField) throw (MED_EXCEPTION) { const char * LOC = "MED::addField(const FIELD_ * const ptrField): "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if ( ! ptrField ) throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrField must not be NULL !")); @@ -891,5 +974,5 @@ void MED::addField( FIELD_ * const ptrField) _support [meshName][ptrSupport->getEntity()] = ptrSupport;// if it already exists it is replaced - END_OF(LOC); + END_OF_MED(LOC); } diff --git a/src/MEDMEM/MEDMEM_Med.hxx b/src/MEDMEM/MEDMEM_Med.hxx index b7251676a..f14802c3e 100644 --- a/src/MEDMEM/MEDMEM_Med.hxx +++ b/src/MEDMEM/MEDMEM_Med.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // # ifndef MED_HXX # define MED_HXX @@ -106,7 +108,7 @@ public: void addMesh ( MESH * const ptrMesh ) throw (MED_EXCEPTION) ; int addDriver (driverTypes driverType, const string & fileName, - MED_EN::med_mode_acces access=MED_EN::MED_REMP); + MED_EN::med_mode_acces access=MED_EN::RDWR); int addDriver (GENDRIVER & driver); void rmDriver (int index=0) throw (MEDEXCEPTION) ; @@ -152,7 +154,7 @@ template<class T> FIELD<T> * MED::getFieldT( const string & fieldName, const int dt, const int it) const throw (MEDEXCEPTION) { const char *LOC="Unexpected type of field"; - FIELD_ retUp=getField(fieldName,dt,it); + FIELD_* retUp=getField(fieldName,dt,it); FIELD<T> *ret=dynamic_cast< FIELD<T> * >(retUp); if(!ret) throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) ) ); diff --git a/src/MEDMEM/MEDMEM_MedFieldDriver.hxx b/src/MEDMEM/MEDMEM_MedFieldDriver.hxx index c9ef5b812..42d25210e 100644 --- a/src/MEDMEM/MEDMEM_MedFieldDriver.hxx +++ b/src/MEDMEM/MEDMEM_MedFieldDriver.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef MED_FIELD_DRIVER_HXX #define MED_FIELD_DRIVER_HXX @@ -61,8 +63,10 @@ public : /*! Constructor. */ - MED_FIELD_DRIVER():_ptrField((FIELD<T> *) MED_NULL), - _fieldName(""),_fieldNum(MED_INVALID) + MED_FIELD_DRIVER(): + GENDRIVER(MED_DRIVER), + _ptrField((FIELD<T> *) MED_NULL), + _fieldName(""),_fieldNum(MED_INVALID) {} /*! Constructor. @@ -70,7 +74,7 @@ public : template <class INTERLACING_TAG> MED_FIELD_DRIVER(const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField, MED_EN::med_mode_acces accessMode) - : GENDRIVER(fileName,accessMode), + : GENDRIVER(fileName, accessMode, MED_DRIVER), _ptrField((FIELD<T> *) ptrField), _fieldName(""),_fieldNum(MED_INVALID) { @@ -92,7 +96,7 @@ public : */ virtual ~MED_FIELD_DRIVER() { - MESSAGE("MED_FIELD_DRIVER::~MED_FIELD_DRIVER() has been destroyed"); + MESSAGE_MED("MED_FIELD_DRIVER::~MED_FIELD_DRIVER() has been destroyed"); } virtual void open() throw (MEDEXCEPTION) = 0; @@ -140,10 +144,11 @@ public : template <class INTERLACING_TAG> IMED_FIELD_RDONLY_DRIVER(const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField): - MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::MED_RDONLY) + MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::RDONLY) { - BEGIN_OF("IMED_FIELD_RDONLY_DRIVER::IMED_FIELD_RDONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)"); - END_OF("IMED_FIELD_RDONLY_DRIVER::IMED_FIELD_RDONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)"); + const char* LOC = "IMED_FIELD_RDONLY_DRIVER::IMED_FIELD_RDONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)"; + BEGIN_OF_MED(LOC); + END_OF_MED(LOC); } /*! @@ -190,10 +195,11 @@ public : template <class INTERLACING_TAG> IMED_FIELD_WRONLY_DRIVER(const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField): - MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::MED_WRONLY) + MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::WRONLY) { - BEGIN_OF("MED_FIELD_WRONLY_DRIVER::MED_FIELD_WRONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)"); - END_OF("MED_FIELD_WRONLY_DRIVER::MED_FIELD_WRONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)"); + const char* LOC = "MED_FIELD_WRONLY_DRIVER::MED_FIELD_WRONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)"; + BEGIN_OF_MED(LOC); + END_OF_MED(LOC); } /*! @@ -242,11 +248,12 @@ public : FIELD<T, INTERLACING_TAG> * ptrField): IMED_FIELD_RDONLY_DRIVER<T>(fileName,ptrField), IMED_FIELD_WRONLY_DRIVER<T>(fileName,ptrField), - MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::MED_RDWR) + MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::RDWR) { - BEGIN_OF("MED_FIELD_RDWR_DRIVER::MED_FIELD_RDWR_DRIVER(const string & fileName, const FIELD<T> * ptrField)"); + const char* LOC = "MED_FIELD_RDWR_DRIVER::MED_FIELD_RDWR_DRIVER(const string & fileName, const FIELD<T> * ptrField)"; + BEGIN_OF_MED(LOC); //_accessMode = MED_RDWR ; - END_OF("MED_FIELD_RDWR_DRIVER::MED_FIELD_RDWR_DRIVER(const string & fileName, const FIELD<T> * ptrField)"); + END_OF_MED(LOC); } /*! @@ -290,6 +297,7 @@ public : virtual void close() { _concreteFieldDrv->close(); } virtual void setFieldName(const string & fieldName) { _concreteFieldDrv->setFieldName(fieldName); } virtual string getFieldName() const { return MED_FIELD_DRIVER<T>::getFieldName(); } + virtual void setFileName ( const string & fileName) {_concreteFieldDrv->setFileName(fileName); } private: virtual GENDRIVER * copy ( void ) const { return new MED_FIELD_RDONLY_DRIVER<T>(*this); } @@ -314,6 +322,7 @@ public : virtual void close() { _concreteFieldDrv->close(); } virtual void setFieldName(const string & fieldName) { _concreteFieldDrv->setFieldName(fieldName); } virtual string getFieldName() const { return MED_FIELD_DRIVER<T>::getFieldName(); } + virtual void setFileName ( const string & fileName) {_concreteFieldDrv->setFileName(fileName); } private: virtual GENDRIVER * copy ( void ) const { return new MED_FIELD_WRONLY_DRIVER<T>(*this); } protected: @@ -341,6 +350,7 @@ public: virtual void close() { _concreteFieldDrv->close(); } virtual void setFieldName(const string & fieldName) { _concreteFieldDrv->setFieldName(fieldName); } virtual string getFieldName() const { return MED_FIELD_DRIVER<T>::getFieldName(); } + virtual void setFileName ( const string & fileName) {_concreteFieldDrv->setFileName(fileName); } private: virtual GENDRIVER * copy ( void ) const { return new MED_FIELD_RDWR_DRIVER<T>(*this); } protected: @@ -378,21 +388,22 @@ template <class T> void IMED_FIELD_RDONLY_DRIVER<T>::write( void ) const } template <class T> MED_FIELD_RDONLY_DRIVER<T>::MED_FIELD_RDONLY_DRIVER() { - MESSAGE("You are using the default constructor of the Field read only Driver and it is 2.1 one"); + MESSAGE_MED("You are using the default constructor of the Field read only Driver and it is 2.1 one"); _concreteFieldDrv=new MED_FIELD_RDONLY_DRIVER21<T>(); } template <class T> template < class INTERLACING_TAG > MED_FIELD_RDONLY_DRIVER<T>::MED_FIELD_RDONLY_DRIVER(const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField): - MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::MED_RDONLY), + MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::RDONLY), IMED_FIELD_RDONLY_DRIVER<T>(fileName,ptrField) { - BEGIN_OF("MED_FIELD_RDONLY_DRIVER::MED_FIELD_RDONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)"); + const char* LOC = "MED_FIELD_RDONLY_DRIVER::MED_FIELD_RDONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)"; + BEGIN_OF_MED(LOC); - _concreteFieldDrv = DRIVERFACTORY::buildFieldDriverFromFile(fileName,ptrField,MED_EN::MED_LECT); + _concreteFieldDrv = DRIVERFACTORY::buildFieldDriverFromFile(fileName,ptrField,MED_EN::RDONLY); - END_OF("MED_FIELD_RDONLY_DRIVER::MED_FIELD_RDONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)"); + END_OF_MED(LOC); } /*--------------------- WRONLY PART -------------------------------*/ @@ -404,7 +415,7 @@ template <class T> void IMED_FIELD_WRONLY_DRIVER<T>::read (void) } template <class T> MED_FIELD_WRONLY_DRIVER<T>::MED_FIELD_WRONLY_DRIVER() { - MESSAGE("You are using the default constructor of the Field write only Driver and it is 2.1 one"); + MESSAGE_MED("You are using the default constructor of the Field write only Driver and it is 2.1 one"); _concreteFieldDrv=new MED_FIELD_WRONLY_DRIVER21<T>(); } @@ -412,20 +423,21 @@ template <class T> MED_FIELD_WRONLY_DRIVER<T>::MED_FIELD_WRONLY_DRIVER() { template <class T> template < class INTERLACING_TAG > MED_FIELD_WRONLY_DRIVER<T>::MED_FIELD_WRONLY_DRIVER(const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField): - MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::MED_WRONLY), + MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::WRONLY), IMED_FIELD_WRONLY_DRIVER<T>( fileName, ptrField) { - BEGIN_OF("MED_FIELD_WRONLY_DRIVER::MED_FIELD_WRONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)"); + const char* LOC = "MED_FIELD_WRONLY_DRIVER::MED_FIELD_WRONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)"; + BEGIN_OF_MED(LOC); - _concreteFieldDrv = DRIVERFACTORY::buildFieldDriverFromFile(fileName,ptrField,MED_EN::MED_ECRI); + _concreteFieldDrv = DRIVERFACTORY::buildFieldDriverFromFile(fileName,ptrField,MED_EN::WRONLY/*ECRI*/); - END_OF("MED_FIELD_RDONLY_DRIVER::MED_FIELD_RDONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)"); + END_OF_MED(LOC); } /*--------------------- RDWR PART -------------------------------*/ template <class T> MED_FIELD_RDWR_DRIVER<T>::MED_FIELD_RDWR_DRIVER() { - MESSAGE("You are using the default constructor of the Field read/write Driver and it is 2.1 one"); + MESSAGE_MED("You are using the default constructor of the Field read/write Driver and it is 2.1 one"); _concreteFieldDrv=new MED_FIELD_RDWR_DRIVER21<T>(); } @@ -433,14 +445,15 @@ template <class T> MED_FIELD_RDWR_DRIVER<T>::MED_FIELD_RDWR_DRIVER() { template <class T> template < class INTERLACING_TAG > MED_FIELD_RDWR_DRIVER<T>::MED_FIELD_RDWR_DRIVER(const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField): - MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::MED_REMP), + MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::RDWR), IMED_FIELD_RDWR_DRIVER<T>(fileName,ptrField) { - BEGIN_OF("MED_FIELD_RDWR_DRIVER::MED_FIELD_RDWR_DRIVER(const string & fileName, const FIELD<T> * ptrField)"); + const char* LOC = "MED_FIELD_RDWR_DRIVER::MED_FIELD_RDWR_DRIVER(const string & fileName, const FIELD<T> * ptrField)"; + BEGIN_OF_MED(LOC); - _concreteFieldDrv = DRIVERFACTORY::buildFieldDriverFromFile(fileName,ptrField,MED_EN::MED_REMP); + _concreteFieldDrv = DRIVERFACTORY::buildFieldDriverFromFile(fileName,ptrField,MED_EN::RDWR); - END_OF("MED_FIELD_RDWR_DRIVER::MED_FIELD_RDWR_DRIVER(const string & fileName, const FIELD<T> * ptrField)"); + END_OF_MED(LOC); } diff --git a/src/MEDMEM/MEDMEM_MedFieldDriver21.hxx b/src/MEDMEM/MEDMEM_MedFieldDriver21.hxx index e96d5703f..7cf3a6638 100644 --- a/src/MEDMEM/MEDMEM_MedFieldDriver21.hxx +++ b/src/MEDMEM/MEDMEM_MedFieldDriver21.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef MED_FIELD_DRIVER21_HXX #define MED_FIELD_DRIVER21_HXX @@ -102,18 +104,26 @@ public : void open() throw (MEDEXCEPTION) { const char * LOC = "MED_FIELD_DRIVER21::open() "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // we must set fieldname before open, because we must find field number in file (if it exist !!!) - if ( MED_FIELD_DRIVER<T>::_fileName == "" ) + if ( MED_FIELD_DRIVER<T>::_fileName == "" ) { throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "_fileName is |\"\"|, please set a correct fileName before calling open()" ) ); - - MESSAGE(LOC<<"_fileName.c_str : "<< MED_FIELD_DRIVER<T>::_fileName.c_str()<<",mode : "<< MED_FIELD_DRIVER<T>::_accessMode); - _medIdt = med_2_1::MEDouvrir( (const_cast <char *> (MED_FIELD_DRIVER<T>::_fileName.c_str())),(med_2_1::med_mode_acces) MED_FIELD_DRIVER<T>::_accessMode); - MESSAGE(LOC<<"_medIdt : "<< _medIdt ); + } + if ( MED_FIELD_DRIVER<T>::_status==MED_OPENED ) + return; + + MED_EN::med_mode_acces mode = dynamic_cast<GENDRIVER*>(this)->getAccessMode(); + med_2_1::med_mode_acces m21mode = (med_2_1::med_mode_acces)getMedAccessMode(mode,MED_EN::V21); + MESSAGE_MED(LOC<<"_fileName.c_str : "<< MED_FIELD_DRIVER<T>::_fileName.c_str()<<",mode : "<< MED_FIELD_DRIVER<T>::_accessMode); + _medIdt = med_2_1::MEDouvrir( (const_cast <char *> (MED_FIELD_DRIVER<T>::_fileName.c_str())), + //(med_2_1::med_mode_acces) MED_FIELD_DRIVER<T>::_accessMode); + m21mode); + // (med_2_1::med_mode_acces) mode); + MESSAGE_MED(LOC<<"_medIdt : "<< _medIdt ); if (_medIdt > 0) MED_FIELD_DRIVER<T>::_status=MED_OPENED; else { @@ -126,21 +136,22 @@ public : ); } - END_OF(LOC); + END_OF_MED(LOC); } void close() { - BEGIN_OF("MED_FIELD_DRIVER21::close()"); + const char* LOC = "MED_FIELD_DRIVER21::close()"; + BEGIN_OF_MED(LOC); med_2_1::med_int err = 0; if (MED_FIELD_DRIVER<T>::_status == MED_OPENED) { err=med_2_1::MEDfermer(MED_FIELD_DRIVER21<T>::_medIdt); //H5close(); // If we call H5close() all the files are closed. MED_FIELD_DRIVER<T>::_status = MED_CLOSED; MED_FIELD_DRIVER21<T>::_medIdt = MED_INVALID; - MESSAGE(" MED_FIELD_DRIVER21::close() : MEDfermer : MED_FIELD_DRIVER21<T>::_medIdt= " << _medIdt ); - MESSAGE(" MED_FIELD_DRIVER21::close() : MEDfermer : err = " << err ); + MESSAGE_MED(" MED_FIELD_DRIVER21::close() : MEDfermer : MED_FIELD_DRIVER21<T>::_medIdt= " << _medIdt ); + MESSAGE_MED(" MED_FIELD_DRIVER21::close() : MEDfermer : err = " << err ); } - END_OF("MED_FIELD_DRIVER21::close()"); + END_OF_MED(LOC); } @@ -162,7 +173,10 @@ public : /*! Constructor. */ - MED_FIELD_RDONLY_DRIVER21():MED_FIELD_DRIVER<T>() {}; + MED_FIELD_RDONLY_DRIVER21():MED_FIELD_DRIVER<T>() + { + this->GENDRIVER::_accessMode = MED_EN::RDONLY; + }; /*! Constructor. @@ -170,12 +184,13 @@ public : template <class INTERLACING_TAG> MED_FIELD_RDONLY_DRIVER21(const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField): - MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::MED_RDONLY), - MED_FIELD_DRIVER21<T>(fileName,ptrField,MED_EN::MED_RDONLY), + MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::RDONLY), + MED_FIELD_DRIVER21<T>(fileName,ptrField,MED_EN::RDONLY), IMED_FIELD_RDONLY_DRIVER<T>(fileName,ptrField) { - BEGIN_OF("MED_FIELD_RDONLY_DRIVER21::MED_FIELD_RDONLY_DRIVER21(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)"); - END_OF("MED_FIELD_RDONLY_DRIVER21::MED_FIELD_RDONLY_DRIVER21(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)"); + const char* LOC = "MED_FIELD_RDONLY_DRIVER21::MED_FIELD_RDONLY_DRIVER21(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)"; + BEGIN_OF_MED(LOC); + END_OF_MED(LOC); } /*! @@ -223,7 +238,10 @@ public : /*! Constructor. */ - MED_FIELD_WRONLY_DRIVER21():MED_FIELD_DRIVER<T>() {} + MED_FIELD_WRONLY_DRIVER21():MED_FIELD_DRIVER<T>() + { + this->GENDRIVER::_accessMode = MED_EN::WRONLY; + } /*! Constructor. @@ -232,11 +250,12 @@ public : MED_FIELD_WRONLY_DRIVER21(const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField): IMED_FIELD_WRONLY_DRIVER<T>(fileName,ptrField), - MED_FIELD_DRIVER21<T>(fileName,ptrField,MED_EN::MED_WRONLY), - MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::MED_WRONLY) + MED_FIELD_DRIVER21<T>(fileName,ptrField,MED_EN::WRONLY), + MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::WRONLY) { - BEGIN_OF("MED_FIELD_WRONLY_DRIVER21::MED_FIELD_WRONLY_DRIVER21(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)"); - END_OF("MED_FIELD_WRONLY_DRIVER21::MED_FIELD_WRONLY_DRIVER21(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)"); + const char* LOC = "MED_FIELD_WRONLY_DRIVER21::MED_FIELD_WRONLY_DRIVER21(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)"; + BEGIN_OF_MED(LOC); + END_OF_MED(LOC); } /*! @@ -283,7 +302,10 @@ public : /*! Constructor. */ - MED_FIELD_RDWR_DRIVER21():MED_FIELD_DRIVER21<T>() {} + MED_FIELD_RDWR_DRIVER21():MED_FIELD_DRIVER21<T>() + { + this->GENDRIVER::_accessMode = MED_EN::RDWR; + } /*! Constructor. @@ -295,13 +317,14 @@ public : MED_FIELD_RDONLY_DRIVER21<T>(fileName,ptrField), IMED_FIELD_RDONLY_DRIVER<T>(fileName,ptrField), IMED_FIELD_WRONLY_DRIVER<T>(fileName,ptrField), - MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::MED_RDWR), + MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::RDWR), IMED_FIELD_RDWR_DRIVER<T>(fileName,ptrField) { - BEGIN_OF("MED_FIELD_RDWR_DRIVER21::MED_FIELD_RDWR_DRIVER21(const string & fileName, const FIELD<T> * ptrField)"); + const char* LOC = "MED_FIELD_RDWR_DRIVER21::MED_FIELD_RDWR_DRIVER21(const string & fileName, const FIELD<T> * ptrField)"; + BEGIN_OF_MED(LOC); //_accessMode = MED_RDWR ; - END_OF("MED_FIELD_RDWR_DRIVER21::MED_FIELD_RDWR_DRIVER21(const string & fileName, const FIELD<T> * ptrField)"); - }; + END_OF_MED(LOC); + } /*! Copy constructor. @@ -346,10 +369,10 @@ MED_FIELD_DRIVER21<T>::createFieldSupport(med_2_1::med_idt id, string & meshName) const throw (MEDEXCEPTION) { - //EF : Gérer le meshName pour le driver 2.2 + //EF : Gérer le meshName pour le driver 2.2 const char * LOC="MED_FIELD_DRIVER<T>::search_field(...)"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); map<int, list<MED_EN::medGeometryElement> > CellAndNodeEntities; map<int, list<MED_EN::medGeometryElement> >::iterator currentEntity; @@ -407,7 +430,7 @@ MED_FIELD_DRIVER21<T>::createFieldSupport(med_2_1::med_idt id, numberOfElements = (numberOfElements1>numberOfElements2)?numberOfElements1:numberOfElements2; - SCRUTE(numberOfElements); + SCRUTE_MED(numberOfElements); if ( numberOfElements <= 0 ) continue; @@ -424,8 +447,8 @@ MED_FIELD_DRIVER21<T>::createFieldSupport(med_2_1::med_idt id, (med_2_1::med_entite_maillage) entityCurrent, (med_2_1::med_geometrie_element) *currentGeometry ); - SCRUTE(nbPdtIt); - SCRUTE(numberOfElements); + SCRUTE_MED(nbPdtIt); + SCRUTE_MED(numberOfElements); if ( nbPdtIt < 0 ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |" << fieldName << "| with (ndt,or) = (" @@ -456,8 +479,8 @@ MED_FIELD_DRIVER21<T>::createFieldSupport(med_2_1::med_idt id, // if ( nmaa > 1 ) { - //EF : Gérer le meshName pour le driver 2.2 - // MESSAGE(STRING(LOC)<<" Field |" << fieldName << "| with (ndt,or) = (" << ndt << "," + //EF : Gérer le meshName pour le driver 2.2 + // MESSAGE_MED(STRING(LOC)<<" Field |" << fieldName << "| with (ndt,or) = (" << ndt << "," // << ot << ") is defined on " << nmaa << " meshes, using mesh |" // << maa << "|"); // } @@ -472,7 +495,7 @@ MED_FIELD_DRIVER21<T>::createFieldSupport(med_2_1::med_idt id, } } - MESSAGE(LOC << " a (dt,it) is found ?? " << alreadyFoundPdtIt); + MESSAGE_MED(LOC << " a (dt,it) is found ?? " << alreadyFoundPdtIt); if ( !alreadyFoundPdtIt ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |" << fieldName << "| with (ndt,or) = (" @@ -487,7 +510,7 @@ MED_FIELD_DRIVER21<T>::createFieldSupport(med_2_1::med_idt id, << MED_EN::entNames[entityCurrent] << "," << MED_EN::geoNames[*currentGeometry] << ")" )); if ( ngauss > 1000 ) { // some gabage - INFOS( "Set to 1 invalid nb of Gauss points " << ngauss << " for Field |" << fieldName + INFOS_MED( "Set to 1 invalid nb of Gauss points " << ngauss << " for Field |" << fieldName << "| with (ndt,or) = (" << ndt << "," << od << ") for (entityType,geometricType)=(" << MED_EN::entNames[entityCurrent] << "," << MED_EN::geoNames[*currentGeometry] << ")" ); @@ -507,22 +530,22 @@ MED_FIELD_DRIVER21<T>::createFieldSupport(med_2_1::med_idt id, if ( alreadyFoundAnEntity) { support.setName(fieldName+"Support"); - support.setMeshName(string(maa)); // Vérifier que les différents noms de maillages lus soient identiques + support.setMeshName(string(maa)); // Vérifier que les différents noms de maillages lus soient identiques support.setEntity(entity); - // REM : Signification précédente erronée pour un champ qui ne repose pas sur toutes les entités géométriques - // du maillage mais dont le SUPPORT a été crée à partir des informations d'un maillage, comme - // celà fût la plupart du temps. + // REM : Signification précédente erronée pour un champ qui ne repose pas sur toutes les entités géométriques + // du maillage mais dont le SUPPORT a été crée à partir des informations d'un maillage, comme + // celà fût la plupart du temps. support.setNumberOfGeometricType(numberOfGeometricType); support.setGeometricType(geometricType); // Utile uniquement si setAll == false support.setNumberOfElements(numberOfElementsOfType); //setNumberOfElements effectue une copie support.setAll(true); - END_OF(LOC); + END_OF_MED(LOC); return alreadyFoundAnEntity; } else { - END_OF(LOC); + END_OF_MED(LOC); return false; } @@ -535,7 +558,7 @@ MED_FIELD_DRIVER21<T>::getMeshGeometricType(med_2_1::med_idt id, vector<MED_EN::medGeometryElement> & geoType, vector<int> &nbOfElOfType) const { - const char LOC[] = "MED_FIELD_DRIVER<T>::getMeshGeometricType(...)"; + //const char LOC[] = "MED_FIELD_DRIVER<T>::getMeshGeometricType(...)"; int numberOfGeometricType=0; MED_EN::medGeometryElement geometricType[MED_NBR_GEOMETRIE_MAILLE]; @@ -546,7 +569,7 @@ MED_FIELD_DRIVER21<T>::getMeshGeometricType(med_2_1::med_idt id, else if (entity == MED_EN::MED_NODE) quoi=med_2_1::MED_COOR; else - MESSAGE(LOC<<" Support Creation from Mesh |" << meshName + MESSAGE_MED("MED_FIELD_DRIVER<T>::getMeshGeometricType(...)"<<" Support Creation from Mesh |" << meshName << "| on entity " << MED_EN::entNames[entity] << "| is impossible, must be on MED_NODE or MED_CELL"); @@ -593,7 +616,7 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void) throw (MEDEXCEPTION) { const char * LOC = " MED_FIELD_RDONLY_DRIVER21::read() " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array ArrayNo; typedef typename MEDMEM_ArrayInterface<T,NoInterlace,Gauss>::Array ArrayNoWg; @@ -613,13 +636,13 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void) MED_FIELD_DRIVER<T>::_fieldName=MED_FIELD_DRIVER<T>::_ptrField->_name; if ( MED_FIELD_DRIVER<T>::_fieldName.size() > MED_TAILLE_NOM ) - MESSAGE(LOC << "Warning <fieldName> size in object driver FIELD is > MED_TAILLE_NOM ."); + MESSAGE_MED(LOC << "Warning <fieldName> size in object driver FIELD is > MED_TAILLE_NOM ."); // throw MEDEXCEPTION(LOCALIZED(STRING(LOC) // <<" <fieldName> size in object driver FIELD is > MED_TAILLE_NOM .")); - MESSAGE("###### "<<LOC<<" fieldNameDRIVER : "<< MED_FIELD_DRIVER<T>::_fieldName << + MESSAGE_MED("###### "<<LOC<<" fieldNameDRIVER : "<< MED_FIELD_DRIVER<T>::_fieldName << " fieldName : "<<MED_FIELD_DRIVER<T>::_fieldName); @@ -627,22 +650,22 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": Method open must be called before method read.")) ; // EF : -// Si un support a été donnée au champ, pour des raisons de compatibilité avec -// les versions précédentes, ce support sera utilisé pour +// Si un support a été donnée au champ, pour des raisons de compatibilité avec +// les versions précédentes, ce support sera utilisé pour // - Obtenir le nom du maillage sur lequel on veut lire le champ // (eventuellement on pourrait l'utiliser pour selectionner un champ qui // repose sur plusieurs maillages cf HOMARD-ASTER) -// - vérifier le type d'entité (MED_NOEUD xor MED_MAILLE xor MED_FACE xor MED_ARETE ) sur lequel -// il faut lire le champ qui est également retouvé. -// - Si le support défini une liste d'entité ( différente de MED_ALL_ELEMENTS), celle-ci est ignorée -// à la lecture et écrasé par les listes de profils lus s'il en existe - -// Si aucun support n'a été donné au champ : -// - A la lecture : Un support est crée et le type d'entité unique est lu -// (cf decision gt MED qu'un champ repose sur une entité unique ?), -// l'ensemble des types géométriques est lu, -// l'ensemble des profils par type géométrique est lu -// Le nom du maillage associé est lu mais le pointeur SUPPORT-MESH non initialisé +// - vérifier le type d'entité (MED_NOEUD xor MED_MAILLE xor MED_FACE xor MED_ARETE ) sur lequel +// il faut lire le champ qui est également retouvé. +// - Si le support défini une liste d'entité ( différente de MED_ALL_ELEMENTS), celle-ci est ignorée +// à la lecture et écrasé par les listes de profils lus s'il en existe + +// Si aucun support n'a été donné au champ : +// - A la lecture : Un support est crée et le type d'entité unique est lu +// (cf decision gt MED qu'un champ repose sur une entité unique ?), +// l'ensemble des types géométriques est lu, +// l'ensemble des profils par type géométrique est lu +// Le nom du maillage associé est lu mais le pointeur SUPPORT-MESH non initialisé char fieldName[MED_TAILLE_NOM+1] ; @@ -668,9 +691,9 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void) numberOfComponents = med_2_1::MEDnChamp(id,i) ; if ( numberOfComponents <= 0 ) // throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) - // << "Be careful there is no compound for field n°" + // << "Be careful there is no compound for field n°" // << i << "in file |"<<_fileName<<"| !")); - MESSAGE(LOC<<"Be careful there is no compound for field n°"<<i<<"in file |"<<MED_FIELD_DRIVER<T>::_fileName<<"| !"); + MESSAGE_MED(LOC<<"Be careful there is no compound for field n°"<<i<<"in file |"<<MED_FIELD_DRIVER<T>::_fileName<<"| !"); componentName = new char[numberOfComponents*MED_TAILLE_PNOM21+1] ; unitName = new char[numberOfComponents*MED_TAILLE_PNOM21+1] ; @@ -678,10 +701,10 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void) err = med_2_1::MEDchampInfo(id, i, fieldName, &type, componentName, unitName, numberOfComponents) ; - MESSAGE("Champ "<<i<<" : #" << fieldName <<"# et recherche #"<<MED_FIELD_DRIVER<T>::_fieldName.c_str()<<"#"); + MESSAGE_MED("Champ "<<i<<" : #" << fieldName <<"# et recherche #"<<MED_FIELD_DRIVER<T>::_fieldName.c_str()<<"#"); if ( !strcmp(fieldName,MED_FIELD_DRIVER<T>::_fieldName.c_str()) ) { - MESSAGE("FOUND FIELD "<< fieldName <<" : "<<i); + MESSAGE_MED("FOUND FIELD "<< fieldName <<" : "<<i); MED_FIELD_DRIVER<T>::_fieldNum = i ; break ; } @@ -696,7 +719,7 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void) if (MED_FIELD_DRIVER<T>::_fieldNum==MED_INVALID) throw MEDEXCEPTION(LOCALIZED( STRING(LOC) << ": Field "<<MED_FIELD_DRIVER<T>::_fieldName << " not found in file " << MED_FIELD_DRIVER<T>::_fileName ) ); - MESSAGE ("FieldNum : "<<MED_FIELD_DRIVER<T>::_fieldNum); + MESSAGE_MED ("FieldNum : "<<MED_FIELD_DRIVER<T>::_fieldNum); if (numberOfComponents < 1) { @@ -730,9 +753,9 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void) haveSupport = true; } - // Cherche le type d'entité, le nombre d'entité par type géométrique sur le type d'entité - // (MED_MAILLE ou MED_NOEUD uniquement car MEDMEMOIRE ne gère pas la connectivité descendante). - // et crée le support correspondant. + // Cherche le type d'entité, le nombre d'entité par type géométrique sur le type d'entité + // (MED_MAILLE ou MED_NOEUD uniquement car MEDMEMOIRE ne gère pas la connectivité descendante). + // et crée le support correspondant. SUPPORT * mySupport = new SUPPORT(); vector<int> numberOfGaussPoints; bool found = createFieldSupport(id,MED_FIELD_DRIVER<T>::_fieldName, @@ -774,7 +797,7 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void) mySupport->setDescription(MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getDescription()); } - // Test si le Support du Champ repose ou non sur toutes les entités géométriques du maillage. + // Test si le Support du Champ repose ou non sur toutes les entités géométriques du maillage. // Pour tester les profils aussi ? vector< MED_EN::medGeometryElement > meshGeoType; vector< int > meshNbOfElOfType; @@ -793,19 +816,24 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void) // If an error occurs while reading the field, these allocated FIELD member will be deleted MED_FIELD_DRIVER<T>::_ptrField->_name = MED_FIELD_DRIVER<T>::_fieldName; MED_FIELD_DRIVER<T>::_ptrField->_numberOfComponents = numberOfComponents ; - MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes = new int[numberOfComponents] ; - MED_FIELD_DRIVER<T>::_ptrField->_componentsNames = new string[numberOfComponents] ; - MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits = new UNIT[numberOfComponents] ; - MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions = new string[numberOfComponents] ; - MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits = new string[numberOfComponents] ; + //MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes = new int[numberOfComponents] ; + //MED_FIELD_DRIVER<T>::_ptrField->_componentsNames = new string[numberOfComponents] ; + //MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits = new UNIT[numberOfComponents] ; + //MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions = new string[numberOfComponents] ; + //MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits = new string[numberOfComponents] ; + MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes.resize(numberOfComponents); + MED_FIELD_DRIVER<T>::_ptrField->_componentsNames.resize(numberOfComponents); + MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits.resize(numberOfComponents); + MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions.resize(numberOfComponents); + MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits.resize(numberOfComponents); for (int i=0; i<numberOfComponents; i++) { MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes[i] = 1 ; MED_FIELD_DRIVER<T>::_ptrField->_componentsNames[i] = string(componentName+i*MED_TAILLE_PNOM21,MED_TAILLE_PNOM21) ; - SCRUTE(MED_FIELD_DRIVER<T>::_ptrField->_componentsNames[i]); + SCRUTE_MED(MED_FIELD_DRIVER<T>::_ptrField->_componentsNames[i]); MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits[i] = string(unitName+i*MED_TAILLE_PNOM21,MED_TAILLE_PNOM21) ; - SCRUTE(MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits[i]); + SCRUTE_MED(MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits[i]); } delete[] componentName; @@ -817,7 +845,7 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void) T ** myValues = new T*[NumberOfTypes] ; int * NumberOfValues = new int[NumberOfTypes] ; int TotalNumberOfValues = 0 ; // Profils a gerer en 2.2 Rmq from EF - MESSAGE ("NumberOfTypes :"<< NumberOfTypes); + MESSAGE_MED ("NumberOfTypes :"<< NumberOfTypes); MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues=0 ; bool anyGauss=false; @@ -834,8 +862,8 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void) modswt = med_2_1::MED_FULL_INTERLACE; for (int i=0; i<NumberOfTypes; i++) { - MESSAGE ("Type["<<i+1<<"] :"<< Types[i]); - MESSAGE ("Entity :"<< mySupport->getEntity()); + MESSAGE_MED ("Type["<<i+1<<"] :"<< Types[i]); + MESSAGE_MED ("Entity :"<< mySupport->getEntity()); int refNumberOfValues = MEDnVal(MED_FIELD_DRIVER21<T>::_medIdt, @@ -861,14 +889,14 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void) myValues[i] = new T[ NumberOfValues[i]*numberOfComponents ] ; TotalNumberOfValues+=NumberOfValues[i] ; char * ProfilName = new char[MED_TAILLE_NOM+1]; - MESSAGE ("NumberOfValues :"<< NumberOfValues[i]); - MESSAGE ("NumberOfComponents :"<< numberOfComponents); - MESSAGE ("MESH_NAME :"<< meshName.c_str()); - MESSAGE ("FIELD_NAME :"<< MED_FIELD_DRIVER<T>::_fieldName.c_str()); - MESSAGE ("MED_ENTITE :"<< (med_2_1::med_entite_maillage) mySupport->getEntity()); - MESSAGE("MED_GEOM :"<<(med_2_1::med_geometrie_element)Types[i]); - MESSAGE("Iteration :"<<MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber()); - MESSAGE("Order :"<<MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()); + MESSAGE_MED ("NumberOfValues :"<< NumberOfValues[i]); + MESSAGE_MED ("NumberOfComponents :"<< numberOfComponents); + MESSAGE_MED ("MESH_NAME :"<< meshName.c_str()); + MESSAGE_MED ("FIELD_NAME :"<< MED_FIELD_DRIVER<T>::_fieldName.c_str()); + MESSAGE_MED ("MED_ENTITE :"<< (med_2_1::med_entite_maillage) mySupport->getEntity()); + MESSAGE_MED("MED_GEOM :"<<(med_2_1::med_geometrie_element)Types[i]); + MESSAGE_MED("Iteration :"<<MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber()); + MESSAGE_MED("Order :"<<MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()); MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues+=mySupport->getNumberOfElements(Types[i]); // Ne doit pas prendre en compte les points de Gauss med_2_1::med_err ret; @@ -913,16 +941,21 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void) delete[] myValues; delete[] NumberOfValues ; delete[] ProfilName; - delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes ; - delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsNames ; - delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits ; - delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions ; - delete[] MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits ; - MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes = NULL ; - MED_FIELD_DRIVER<T>::_ptrField->_componentsNames = NULL ; - MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits = NULL ; - MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions = NULL ; - MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits = NULL ; + //delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes ; + //delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsNames ; + //delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits ; + //delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions ; + //delete[] MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits ; + //MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes = NULL ; + //MED_FIELD_DRIVER<T>::_ptrField->_componentsNames = NULL ; + //MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits = NULL ; + //MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions = NULL ; + //MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits = NULL ; + MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes.clear(); + MED_FIELD_DRIVER<T>::_ptrField->_componentsNames.clear(); + MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits.clear(); + MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions.clear(); + MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits.clear(); MED_FIELD_DRIVER<T>::_fieldNum = MED_INVALID ; // we have not found right field, so reset the field number throw MEDEXCEPTION( LOCALIZED( STRING(LOC) <<": ERROR when read value")) ; } @@ -1085,7 +1118,7 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void) } MED_FIELD_DRIVER<T>::_ptrField->_isRead = true ; - MED_FIELD_DRIVER<T>::_ptrField->_support=mySupport; //Prévenir l'utilisateur ? + MED_FIELD_DRIVER<T>::_ptrField->_support=mySupport; //Prévenir l'utilisateur ? // check support entity and isOnAllElements if ( haveSupport && mySupport->getEntity() != MED_EN::MED_NODE ) { @@ -1133,7 +1166,7 @@ template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void) } } - // END_OF(LOC); + // END_OF_MED(); } template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::write( void ) const @@ -1159,7 +1192,7 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const throw (MEDEXCEPTION) { const char * LOC = "MED_FIELD_WRONLY_DRIVER21::write(void) const " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array ArrayNo; typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array ArrayFull; @@ -1167,10 +1200,24 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const //if (MED_FIELD_DRIVER<T>::_status==MED_OPENED && // MED_FIELD_DRIVER<T>::_ptrField->_isRead ) - if (MED_FIELD_DRIVER<T>::_status==MED_OPENED) - { + if (MED_FIELD_DRIVER<T>::_status!=MED_OPENED) + throw MEDEXCEPTION ("MEDMEM_MedFieldDriver21: Trying to write before opening"); + else { int err ; + const SUPPORT * mySupport = MED_FIELD_DRIVER<T>::_ptrField->getSupport() ; + if (! mySupport->isOnAllElements()) + throw MEDEXCEPTION( LOCALIZED (STRING(LOC) + <<": Field must be on all entity" + ) + ); +// MESH * myMesh = mySupport->getMesh() ; +// if(!myMesh) +// throw MEDEXCEPTION( LOCALIZED (STRING(LOC) +// <<": Mesh in support is null" +// ) +// ); + int component_count=MED_FIELD_DRIVER<T>::_ptrField->getNumberOfComponents(); string component_name(component_count*MED_TAILLE_PNOM21,' ') ; string component_unit(component_count*MED_TAILLE_PNOM21,' ') ; @@ -1191,12 +1238,12 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const listcomponent_unit[i],0,length); } - MESSAGE("component_name=|"<<component_name<<"|"); - MESSAGE("component_unit=|"<<component_unit<<"|"); + MESSAGE_MED("component_name=|"<<component_name<<"|"); + MESSAGE_MED("component_unit=|"<<component_unit<<"|"); MED_EN::med_type_champ ValueType=MED_FIELD_DRIVER<T>::_ptrField->getValueType() ; - MESSAGE("Template Type =|"<<ValueType<<"|"); + MESSAGE_MED("Template Type =|"<<ValueType<<"|"); // le champ existe deja ??? char * champName = new char[MED_TAILLE_NOM+1] ; @@ -1208,6 +1255,7 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const int nbComp ; for (int i=1; i<=n; i++) { nbComp = med_2_1::MEDnChamp(MED_FIELD_DRIVER21<T>::_medIdt,i); + if ( nbComp < 1 ) continue; // nbComp can be -1 compName = new char[MED_TAILLE_PNOM21*nbComp+1]; compUnit = new char[MED_TAILLE_PNOM21*nbComp+1]; err = med_2_1::MEDchampInfo(MED_FIELD_DRIVER21<T>::_medIdt,i,champName,&type,compName,compUnit,nbComp); @@ -1228,10 +1276,10 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const ) ); // component name and unit - MESSAGE(LOC<<" Component name in file : "<<compName); - MESSAGE(LOC<<" Component name in memory : "<<component_name); - MESSAGE(LOC<<" Component unit in file : "<<compUnit); - MESSAGE(LOC<<" Component unit in memory : "<<component_unit); + MESSAGE_MED(LOC<<" Component name in file : "<<compName); + MESSAGE_MED(LOC<<" Component name in memory : "<<component_name); + MESSAGE_MED(LOC<<" Component unit in file : "<<compUnit); + MESSAGE_MED(LOC<<" Component unit in memory : "<<component_unit); delete[] compName ; delete[] compUnit ; @@ -1240,7 +1288,7 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const string dataGroupName = "/CHA/"; dataGroupName += MED_FIELD_DRIVER<T>::_ptrField->getName(); - MESSAGE(LOC << "|" << dataGroupName << "|" ); + MESSAGE_MED(LOC << "|" << dataGroupName << "|" ); med_2_1::med_idt gid = H5Gopen(MED_FIELD_DRIVER21<T>::_medIdt, dataGroupName.c_str() ); if ( gid < 0 ) { @@ -1260,16 +1308,8 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const else H5Gclose(gid); } - const SUPPORT * mySupport = MED_FIELD_DRIVER<T>::_ptrField->getSupport() ; - - if (! mySupport->isOnAllElements()) - throw MEDEXCEPTION( LOCALIZED (STRING(LOC) - <<": Field must be on all entity" - ) - ); - - MESH * myMesh = mySupport->getMesh() ; - string MeshName = myMesh->getName() ; + MESH * myMesh = mySupport->getMesh(); + string MeshName = myMesh ? myMesh->getName() : mySupport->getMeshName(); //MED_EN::medModeSwitch Mode = MED_FIELD_DRIVER<T>::_ptrField->_value->getMode() ; // on boucle sur tout les types pour ecrire les tableaux de valeur int NumberOfType = mySupport->getNumberOfTypes() ; @@ -1291,7 +1331,7 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const } else { // En attendant la convertion de FIELD, on utilise le ArrayConvert - // ( les infos _ptrField-> sont les mêmes ) + // ( les infos _ptrField-> sont les mêmes ) myArray = ArrayConvert( *( dynamic_cast< ArrayNo * > (MED_FIELD_DRIVER<T>::_ptrField->getArrayNoGauss() )) @@ -1309,17 +1349,17 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const else { value = myArray->getRow(Index) ; } - MESSAGE("MED_FIELD_DRIVER21<T>::_medIdt : "<<MED_FIELD_DRIVER21<T>::_medIdt); - MESSAGE("MeshName.c_str() : "<<MeshName.c_str()); - MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getName() : "<<MED_FIELD_DRIVER<T>::_ptrField->getName()); - MESSAGE("value : "<<value); - MESSAGE("NumberOfElements : "<<NumberOfElements); - MESSAGE("NumberOfGaussPoints : "<<NumberOfGaussPoints); - MESSAGE("mySupport->getEntity() : "<<mySupport->getEntity()); - MESSAGE("Types[i] : "<<Types[i]); - MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber() : "<<MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber()); - MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getTime() : "<<MED_FIELD_DRIVER<T>::_ptrField->getTime()); - MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber() : "<<MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()); + MESSAGE_MED("MED_FIELD_DRIVER21<T>::_medIdt : "<<MED_FIELD_DRIVER21<T>::_medIdt); + MESSAGE_MED("MeshName.c_str() : "<<MeshName.c_str()); + MESSAGE_MED("MED_FIELD_DRIVER<T>::_ptrField->getName() : "<<MED_FIELD_DRIVER<T>::_ptrField->getName()); + MESSAGE_MED("value : "<<value); + MESSAGE_MED("NumberOfElements : "<<NumberOfElements); + MESSAGE_MED("NumberOfGaussPoints : "<<NumberOfGaussPoints); + MESSAGE_MED("mySupport->getEntity() : "<<mySupport->getEntity()); + MESSAGE_MED("Types[i] : "<<Types[i]); + MESSAGE_MED("MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber() : "<<MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber()); + MESSAGE_MED("MED_FIELD_DRIVER<T>::_ptrField->getTime() : "<<MED_FIELD_DRIVER<T>::_ptrField->getTime()); + MESSAGE_MED("MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber() : "<<MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()); /* char chanom[MED_TAILLE_NOM+1]; char chacomp[MED_TAILLE_NOM+1]; @@ -1343,10 +1383,10 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64) || defined(PCLINUX64_32) if(MED_FIELD_DRIVER<T>::_ptrField->getValueType()==MED_EN::MED_INT32) { - int lgth2=MED_FIELD_DRIVER<T>::_ptrField->getNumberOfValues(); - med_2_1::med_int *temp=new med_2_1::med_int[lgth2]; + int lgth2=MED_FIELD_DRIVER<T>::_ptrField->getValueLength(); + T *temp=new T[lgth2]; for(int i2=0;i2<lgth2;i2++) - temp[i2]=(int)(value[i2]); + temp[i2]=(T)(value[i2]); err=med_2_1::MEDchampEcr(MED_FIELD_DRIVER21<T>::_medIdt, const_cast <char*> ( MeshName.c_str()) , //( string(mesh_name).resize(MED_TAILLE_NOM).c_str()) const_cast <char*> ( (MED_FIELD_DRIVER<T>::_ptrField->getName()).c_str()), @@ -1356,7 +1396,7 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const NumberOfGaussPoints, MED_ALL, MED_NOPFL, - med_2_1::MED_REMP, // PROFIL NON GERE, mode de remplacement non géré + med_2_1::MED_REMP, // PROFIL NON GERE, mode de remplacement non géré (med_2_1::med_entite_maillage)mySupport->getEntity(), (med_2_1::med_geometrie_element)Types[i], MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber(), @@ -1369,19 +1409,19 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const else #endif err=med_2_1::MEDchampEcr(MED_FIELD_DRIVER21<T>::_medIdt, - const_cast <char*> ( MeshName.c_str()) , //( string(mesh_name).resize(MED_TAILLE_NOM).c_str()) - const_cast <char*> ( (MED_FIELD_DRIVER<T>::_ptrField->getName()).c_str()), - (unsigned char*)value, + const_cast <char*> ( MeshName.c_str()) , //( string(mesh_name).resize(MED_TAILLE_NOM).c_str()) + const_cast <char*> ( (MED_FIELD_DRIVER<T>::_ptrField->getName()).c_str()), + (unsigned char*)value, modswt /*med_2_1::MED_FULL_INTERLACE*/, //PAL17011 NumberOfElements, NumberOfGaussPoints, MED_ALL, - MED_NOPFL, - med_2_1::MED_REMP, // PROFIL NON GERE, mode de remplacement non géré + (char *)MED_NOPFL, + med_2_1::MED_REMP, // PROFIL NON GERE, mode de remplacement non géré (med_2_1::med_entite_maillage)mySupport->getEntity(), (med_2_1::med_geometrie_element)Types[i], MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber(), - " ", + (char *) " ", MED_FIELD_DRIVER<T>::_ptrField->getTime(), MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber() ); @@ -1402,7 +1442,7 @@ template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const } - END_OF(LOC); + END_OF_MED(LOC); } /*--------------------- RDWR PART -------------------------------*/ @@ -1415,17 +1455,19 @@ template <class T> GENDRIVER * MED_FIELD_RDWR_DRIVER21<T>::copy(void) const template <class T> void MED_FIELD_RDWR_DRIVER21<T>::write(void) const throw (MEDEXCEPTION) { - BEGIN_OF("MED_FIELD_RDWR_DRIVER21::write(void)"); + const char* LOC = "MED_FIELD_RDWR_DRIVER21::write(void)"; + BEGIN_OF_MED(LOC); MED_FIELD_WRONLY_DRIVER21<T>::write(); - END_OF("MED_FIELD_RDWR_DRIVER21::write(void)"); + END_OF_MED(LOC); } template <class T> void MED_FIELD_RDWR_DRIVER21<T>::read (void) throw (MEDEXCEPTION) { - BEGIN_OF("MED_FIELD_RDWR_DRIVER21::read(void)"); + const char* LOC = "MED_FIELD_RDWR_DRIVER21::read(void)"; + BEGIN_OF_MED(LOC); MED_FIELD_RDONLY_DRIVER21<T>::read(); - END_OF("MED_FIELD_RDWR_DRIVER21::read(void)"); + END_OF_MED(LOC); } }//End namespace MEDMEM /*-----------------------------------------------------------------*/ diff --git a/src/MEDMEM/MEDMEM_MedFieldDriver22.hxx b/src/MEDMEM/MEDMEM_MedFieldDriver22.hxx index 59942c7e3..ce9b4089e 100644 --- a/src/MEDMEM/MEDMEM_MedFieldDriver22.hxx +++ b/src/MEDMEM/MEDMEM_MedFieldDriver22.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef MED_FIELD_DRIVER22_HXX #define MED_FIELD_DRIVER22_HXX @@ -36,6 +38,8 @@ #include "MEDMEM_MedFieldDriver.hxx" #include "MEDMEM_Unit.hxx" #include "MEDMEM_Support.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Group.hxx" #include "MEDMEM_GaussLocalization.hxx" namespace MEDMEM { @@ -55,28 +59,37 @@ protected: med_2_3::med_idt _medIdt; bool createFieldSupportPart1(med_2_3::med_idt id, - const string & fieldName, - med_2_3::med_int ndt, - med_2_3::med_int od, - SUPPORT & support, - string & meshName, - vector<int> & numberOfElementsOfTypeC, - vector<int> & numberOfGaussPoint, - int & totalNumberOfElWg - ) const throw (MEDEXCEPTION); - - void getMeshGeometricTypeFromFile(med_2_3::med_idt id, - string & meshName, - MED_EN::medEntityMesh entite, - vector<MED_EN::medGeometryElement> & geoType, - vector<int> &nbOfElOfType, - vector<int> &nbOfElOfTypeC) const throw(MEDEXCEPTION); + const string & fieldName, + med_2_3::med_int ndt, + med_2_3::med_int od, + SUPPORT & support, + string & meshName, + vector<int> & numberOfElementsOfTypeC, + vector<int> & numberOfGaussPoint, + int & totalNumberOfElWg, + MED_EN::medEntityMesh & fieldMedFileEntity + ) const throw (MEDEXCEPTION); + + void getMeshGeometricTypeFromFile(med_2_3::med_idt id, + string & meshName, + MED_EN::medEntityMesh entite, + vector<MED_EN::medGeometryElement> & geoType, + vector<int> & nbOfElOfType, + vector<int> & nbOfElOfTypeC + ) const throw(MEDEXCEPTION); void getMeshGeometricTypeFromMESH( MESH * meshPtr, MED_EN::medEntityMesh entity, vector<MED_EN::medGeometryElement> & geoType, vector<int> &nbOfElOfType, - vector<int> &nbOfElOfTypeC) const throw(MEDEXCEPTION); + vector<int> &nbOfElOfTypeC + ) const throw(MEDEXCEPTION); + + int getMeshDimensionFromFile(med_2_3::med_idt id, const string & meshName) const; + + medEntityMesh getMEDMEMEntityFromMEDType(medGeometryElement type, int mesh_dim) const; + + public : @@ -114,7 +127,7 @@ public : void open() throw (MEDEXCEPTION) { const char * LOC = "MED_FIELD_DRIVER22::open() "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // we must set fieldname before open, because we must find field number in file (if it exist !!!) if ( MED_FIELD_DRIVER<T>::_fileName == "" ) @@ -122,10 +135,13 @@ public : << "_fileName is |\"\"|, please set a correct fileName before calling open()" ) ); + if ( MED_FIELD_DRIVER<T>::_status==MED_OPENED ) + return; - MESSAGE(LOC<<"_fileName.c_str : "<< MED_FIELD_DRIVER<T>::_fileName.c_str()<<",mode : "<< MED_FIELD_DRIVER<T>::_accessMode); - MED_FIELD_DRIVER22<T>::_medIdt = med_2_3::MEDouvrir( (const_cast <char *> (MED_FIELD_DRIVER<T>::_fileName.c_str())),(med_2_3::med_mode_acces) MED_FIELD_DRIVER<T>::_accessMode); - MESSAGE(LOC<<"_medIdt : "<< MED_FIELD_DRIVER22<T>::_medIdt ); + int accessMode = getMedAccessMode( MED_FIELD_DRIVER<T>::_accessMode, MED_EN::V22 ); + MESSAGE_MED(LOC<<"_fileName.c_str : "<< MED_FIELD_DRIVER<T>::_fileName.c_str()<<",mode : "<< MED_FIELD_DRIVER<T>::_accessMode); + MED_FIELD_DRIVER22<T>::_medIdt = med_2_3::MEDouvrir( (const_cast <char *> (MED_FIELD_DRIVER<T>::_fileName.c_str())),(med_2_3::med_mode_acces) accessMode); + MESSAGE_MED(LOC<<"_medIdt : "<< MED_FIELD_DRIVER22<T>::_medIdt ); if (MED_FIELD_DRIVER22<T>::_medIdt > 0) MED_FIELD_DRIVER<T>::_status=MED_OPENED; else { @@ -138,21 +154,22 @@ public : ); } - END_OF(LOC); + END_OF_MED(LOC); } void close() { - BEGIN_OF("MED_FIELD_DRIVER22::close()"); + const char* LOC = "MED_FIELD_DRIVER22::close()"; + BEGIN_OF_MED(LOC); med_2_3::med_int err = 0; if (MED_FIELD_DRIVER<T>::_status == MED_OPENED) { err=med_2_3::MEDfermer(MED_FIELD_DRIVER22<T>::_medIdt); //H5close(); // If we call H5close() all the files are closed. MED_FIELD_DRIVER<T>::_status = MED_CLOSED; MED_FIELD_DRIVER22<T>::_medIdt = MED_INVALID; - MESSAGE(" MED_FIELD_DRIVER22::close() : MEDfermer : _medIdt= " << MED_FIELD_DRIVER22<T>::_medIdt ); - MESSAGE(" MED_FIELD_DRIVER22::close() : MEDfermer : err = " << err ); + MESSAGE_MED(" MED_FIELD_DRIVER22::close() : MEDfermer : _medIdt= " << MED_FIELD_DRIVER22<T>::_medIdt ); + MESSAGE_MED(" MED_FIELD_DRIVER22::close() : MEDfermer : err = " << err ); } - END_OF("MED_FIELD_DRIVER22::close()"); + END_OF_MED(LOC); } }; @@ -172,7 +189,10 @@ public : /*! Constructor. */ - MED_FIELD_RDONLY_DRIVER22():MED_FIELD_DRIVER<T>() {}; + MED_FIELD_RDONLY_DRIVER22():MED_FIELD_DRIVER<T>() + { + this->GENDRIVER::_accessMode = MED_EN::RDONLY; + } /*! Constructor. @@ -181,11 +201,12 @@ public : MED_FIELD_RDONLY_DRIVER22(const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField): IMED_FIELD_RDONLY_DRIVER<T>(fileName,ptrField), - MED_FIELD_DRIVER22<T>(fileName,ptrField,MED_EN::MED_RDONLY), - MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::MED_RDONLY) + MED_FIELD_DRIVER22<T>(fileName,ptrField,MED_EN::RDONLY), + MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::RDONLY) { - BEGIN_OF("MED_FIELD_RDONLY_DRIVER22::MED_FIELD_RDONLY_DRIVER22(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)"); - END_OF("MED_FIELD_RDONLY_DRIVER22::MED_FIELD_RDONLY_DRIVER22(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)"); + const char* LOC = "MED_FIELD_RDONLY_DRIVER22::MED_FIELD_RDONLY_DRIVER22(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)"; + BEGIN_OF_MED(LOC); + END_OF_MED(LOC); } /*! @@ -233,7 +254,10 @@ public : /*! Constructor. */ - MED_FIELD_WRONLY_DRIVER22():MED_FIELD_DRIVER<T>() {} + MED_FIELD_WRONLY_DRIVER22():MED_FIELD_DRIVER<T>() + { + this->GENDRIVER::_accessMode = MED_EN::WRONLY; + } /*! Constructor. @@ -242,11 +266,12 @@ public : MED_FIELD_WRONLY_DRIVER22(const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField): IMED_FIELD_WRONLY_DRIVER<T>(fileName,ptrField), - MED_FIELD_DRIVER22<T>(fileName,ptrField,MED_EN::MED_WRONLY), - MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::MED_WRONLY) + MED_FIELD_DRIVER22<T>(fileName,ptrField,MED_EN::WRONLY), + MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::WRONLY) { - BEGIN_OF("MED_FIELD_WRONLY_DRIVER22::MED_FIELD_WRONLY_DRIVER22(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)"); - END_OF("MED_FIELD_WRONLY_DRIVER22::MED_FIELD_WRONLY_DRIVER22(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)"); + const char* LOC = "MED_FIELD_WRONLY_DRIVER22::MED_FIELD_WRONLY_DRIVER22(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)"; + BEGIN_OF_MED(LOC); + END_OF_MED(LOC); } /*! @@ -293,7 +318,10 @@ public : /*! Constructor. */ - MED_FIELD_RDWR_DRIVER22():MED_FIELD_DRIVER22<T>() {} + MED_FIELD_RDWR_DRIVER22():MED_FIELD_DRIVER22<T>() + { + this->GENDRIVER::_accessMode = MED_EN::RDWR; + } /*! Constructor. @@ -305,12 +333,13 @@ public : MED_FIELD_RDONLY_DRIVER22<T>(fileName,ptrField), IMED_FIELD_RDONLY_DRIVER<T>(fileName,ptrField), IMED_FIELD_WRONLY_DRIVER<T>(fileName,ptrField), - MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::MED_RDWR), + MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::RDWR), IMED_FIELD_RDWR_DRIVER<T>(fileName,ptrField) { - BEGIN_OF("MED_FIELD_RDWR_DRIVER22::MED_FIELD_RDWR_DRIVER22(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)"); + const char* LOC = "MED_FIELD_RDWR_DRIVER22::MED_FIELD_RDWR_DRIVER22(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)"; + BEGIN_OF_MED(LOC); //_accessMode = MED_RDWR ; - END_OF("MED_FIELD_RDWR_DRIVER22::MED_FIELD_RDWR_DRIVER22(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)"); + END_OF_MED(LOC); } /*! @@ -378,22 +407,23 @@ private: */ template <class T> bool -MED_FIELD_DRIVER22<T>::createFieldSupportPart1(med_2_3::med_idt id, - const string & fieldName, - med_2_3::med_int ndt, - med_2_3::med_int od, - SUPPORT & support, - string & meshName, - vector<int> & numberOfElementsOfTypeC, - vector<int> & numberOfGaussPoint, - int & totalNumberOfElWg +MED_FIELD_DRIVER22<T>::createFieldSupportPart1(med_2_3::med_idt id, + const string & fieldName, + med_2_3::med_int ndt, + med_2_3::med_int od, + SUPPORT & support, + string & meshName, + vector<int> & numberOfElementsOfTypeC, + vector<int> & numberOfGaussPoint, + int & totalNumberOfElWg, + MED_EN::medEntityMesh & fieldMedFileEntity ) const throw (MEDEXCEPTION) { //EF : Gérer le meshName pour le driver 2.2 const char * LOC="MED_FIELD_DRIVER<T>::createFieldSupportPart1(...)"; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); map<int, list<MED_EN::medGeometryElement> > CellAndNodeEntities; map<int, list<MED_EN::medGeometryElement> >::iterator currentEntity; @@ -405,6 +435,8 @@ MED_FIELD_DRIVER22<T>::createFieldSupportPart1(med_2_3::med_idt id, MED_EN::medGeometryElement geometryCurrent; MED_EN::medEntityMesh entity; + MED_EN::medEntityMesh medmem_entity; + bool alreadyFoundAnEntity=false,alreadyFoundPdtIt = false; int numberOfElements = 0; int numberOfGeometricType = 0; @@ -423,6 +455,7 @@ MED_FIELD_DRIVER22<T>::createFieldSupportPart1(med_2_3::med_idt id, numberOfElementsOfTypeC[0] = 1; numberOfGaussPoint[0] = 1; totalNumberOfElWg = 0; + int field_dim=0; /* Détermine le type d'entité et la liste des types géométriques associés au champ <fieldName> */ @@ -434,14 +467,15 @@ MED_FIELD_DRIVER22<T>::createFieldSupportPart1(med_2_3::med_idt id, entityCurrent = (*currentEntity).first ; geometryCurrent = (*currentGeometry) ; + // That is a difference between Med File and Med Memory (NB) if (geometryCurrent == MED_EN::MED_SEG2 || geometryCurrent == MED_EN::MED_SEG3) - entityCurrent = MED_EN::MED_EDGE; + entityCurrent = MED_EN::MED_EDGE; if (geometryCurrent == MED_EN::MED_TRIA3 || geometryCurrent == MED_EN::MED_QUAD4 || - geometryCurrent == MED_EN::MED_TRIA6 || geometryCurrent == MED_EN::MED_QUAD8 || - geometryCurrent == MED_EN::MED_POLYGON) - entityCurrent = MED_EN::MED_FACE; + geometryCurrent == MED_EN::MED_TRIA6 || geometryCurrent == MED_EN::MED_QUAD8 || + geometryCurrent == MED_EN::MED_POLYGON) + entityCurrent = MED_EN::MED_FACE; nbPdtIt1 = med_2_3::MEDnPasdetemps(id, const_cast <char*> ( fieldName.c_str() ), (med_2_3::med_entite_maillage) (*currentEntity).first, @@ -451,6 +485,7 @@ MED_FIELD_DRIVER22<T>::createFieldSupportPart1(med_2_3::med_idt id, (med_2_3::med_entite_maillage) entityCurrent, (med_2_3::med_geometrie_element) geometryCurrent ); + medmem_entity=entityCurrent; if (nbPdtIt2 < nbPdtIt1) entityCurrent = (*currentEntity).first ; nbPdtIt = (nbPdtIt1>nbPdtIt2)?nbPdtIt1:nbPdtIt2; @@ -460,30 +495,53 @@ MED_FIELD_DRIVER22<T>::createFieldSupportPart1(med_2_3::med_idt id, /* Verifie que le champ n'est pas défini sur un autre type d'entité */ if ( alreadyFoundAnEntity ) - { - //if (entity != (*currentEntity).first ) (NB) - if ( entity != entityCurrent ) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |" << fieldName - << "| with (ndt,or) = (" << ndt << "," - << od << ") must not be defined on nodes and cells" )); + { + //if (entity != (*currentEntity).first ) (NB) + if ( medmem_entity != entity ) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |" << fieldName + << "| with (ndt,or) = (" << ndt << "," + << od << ") must not be defined on different entity types" )); - } + } else - { - //entity=(*currentEntity).first; (NB) - entity=entityCurrent; - alreadyFoundAnEntity = true; - }; + { + //entity=(*currentEntity).first; (NB) + entity=medmem_entity; + fieldMedFileEntity = entityCurrent; + alreadyFoundAnEntity = true; + + //at this stage, the entity is only related to the geometry dimension + // with no relation to the mesh dimension + // therefore MED_CELL refer to 3D and MED_FACE to 2D + // the correct entity (which depends on the mesh dimension, is only + // determined later + + switch (entity) + { + case MED_NODE: + field_dim=0; + break; + case MED_EDGE: + field_dim=1; + break; + case MED_FACE: + field_dim=2; + break; + case MED_CELL: + field_dim=3; + break; + } + }; /* Cherche le champ pour le <ndt>,<ot> demandé et détermine le nombre de points de Gauss*/ ret = 0; alreadyFoundPdtIt = false; ngauss =0; for ( med_2_3::med_int j=1; j <= nbPdtIt; j++ ) { - // Search how many <ngauss> (<fieldName>,<ndt>,<ot>) has (NB) - //ret += med_2_3::MEDpasdetempsInfo(id, const_cast <char*> ( fieldName.c_str() ), - // (med_2_3::med_entite_maillage) (*currentEntity).first, - // (med_2_3::med_geometrie_element) *currentGeometry, + // Search how many <ngauss> (<fieldName>,<ndt>,<ot>) has (NB) + //ret += med_2_3::MEDpasdetempsInfo(id, const_cast <char*> ( fieldName.c_str() ), + // (med_2_3::med_entite_maillage) (*currentEntity).first, + // (med_2_3::med_geometrie_element) *currentGeometry, // j, &ngauss, &numdt, &numo, dtunit, &dt, // maa, &local, &nmaa); @@ -499,7 +557,7 @@ MED_FIELD_DRIVER22<T>::createFieldSupportPart1(med_2_3::med_idt id, alreadyFoundPdtIt = true; if ( nmaa > 1 ) { - MESSAGE(LOC<<" Field |" << fieldName << "| with (ndt,or) = (" + MESSAGE_MED(LOC<<" Field |" << fieldName << "| with (ndt,or) = (" << ndt << "," << od << ") for (entityType,geometricType)=(" << MED_EN::entNames[entityCurrent] << "," << MED_EN::geoNames[*currentGeometry] << ")" @@ -507,7 +565,7 @@ MED_FIELD_DRIVER22<T>::createFieldSupportPart1(med_2_3::med_idt id, } if ( !local) { - MESSAGE(" Field |" << fieldName << "| with (ndt,or) = (" + MESSAGE_MED(" Field |" << fieldName << "| with (ndt,or) = (" << ndt << "," << od << ") for (entityType,geometricType)=(" << MED_EN::entNames[entityCurrent] << "," << MED_EN::geoNames[*currentGeometry] << ")" @@ -520,20 +578,21 @@ MED_FIELD_DRIVER22<T>::createFieldSupportPart1(med_2_3::med_idt id, // << "is using a mesh on a different file which is not yet supported" )); } - if ( ! meshName.empty() ) - if ( meshName != maa ) { - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |" << fieldName << "| with (ndt,or) = (" - << ndt << "," << od << ") for (entityType,geometricType)=(" - << MED_EN::entNames[entityCurrent] << "," - << MED_EN::geoNames[*currentGeometry] << ")" - << "is defined on mesh |" << maa << "| not on mesh |" << meshName )); - } - break; + //VB commented out to allow for fields on multiple meshes + // if ( ! meshName.empty() ) +// if ( meshName != maa ) { +// throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |" << fieldName << "| with (ndt,or) = (" +// << ndt << "," << od << ") for (entityType,geometricType)=(" +// << MED_EN::entNames[entityCurrent] << "," +// << MED_EN::geoNames[*currentGeometry] << ")" +// << "is defined on mesh |" << maa << "| not on mesh |" << meshName )); +// } + break; } } - MESSAGE(LOC << " a (dt,it) is found ?? " << alreadyFoundPdtIt); + MESSAGE_MED(LOC << " a (dt,it) is found ?? " << alreadyFoundPdtIt); if ( !alreadyFoundPdtIt ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |" << fieldName << "| with (ndt,or) = (" @@ -548,20 +607,23 @@ MED_FIELD_DRIVER22<T>::createFieldSupportPart1(med_2_3::med_idt id, << MED_EN::entNames[entityCurrent] << "," << MED_EN::geoNames[*currentGeometry] << ")" )); ; - if ( (numberOfElements = med_2_3::MEDnVal(id, const_cast <char*> ( fieldName.c_str() ), - (med_2_3::med_entite_maillage) entityCurrent, - (med_2_3::med_geometrie_element) *currentGeometry, - numdt, numo, maa, med_2_3::MED_COMPACT)) <= 0 ) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Error in MEDnVal for Field |" << fieldName - << "| with (ndt,or) = (" - << ndt << "," << od << ") for (entityType,geometricType)=(" - << MED_EN::entNames[entityCurrent] << "," - << MED_EN::geoNames[*currentGeometry] << ")" )); ; + if ( meshName.empty() ) // PAL19635: error with TestMEDSPLITTER + meshName = maa; + + if ( (numberOfElements = med_2_3::MEDnVal(id, const_cast <char*> ( fieldName.c_str() ), + (med_2_3::med_entite_maillage) entityCurrent, + (med_2_3::med_geometrie_element) *currentGeometry, + numdt, numo,(char *) meshName.c_str(), med_2_3::MED_COMPACT)) <= 0 ) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Error in MEDnVal for Field |" << fieldName + << "| with (ndt,or) = (" + << ndt << "," << od << ") for (entityType,geometricType)=(" + << MED_EN::entNames[entityCurrent] << "," + << MED_EN::geoNames[*currentGeometry] << ")" )); ; numberOfElementsOfType[numberOfGeometricType] = numberOfElements/ngauss; numberOfElementsOfTypeC[numberOfGeometricType+1]= - numberOfElementsOfTypeC[numberOfGeometricType] - + numberOfElementsOfType[numberOfGeometricType]; + numberOfElementsOfTypeC[numberOfGeometricType] + + numberOfElementsOfType[numberOfGeometricType]; numberOfGaussPoint[numberOfGeometricType+1] = ngauss; geometricType[numberOfGeometricType]= *currentGeometry; numberOfGeometricType++; @@ -571,9 +633,15 @@ MED_FIELD_DRIVER22<T>::createFieldSupportPart1(med_2_3::med_idt id, } // End Premier For + + //retrieves the right medmem entity type from field_dim and mesh_dim + int mesh_dim = MED_FIELD_DRIVER22<T>::getMeshDimensionFromFile(id,meshName); + if (mesh_dim==2 && field_dim==2) + entity=MED_CELL; + if ( alreadyFoundAnEntity) { - support.setName(fieldName+"Support"); - support.setMeshName(string(maa)); // Vérifier que les différents noms de maillages lus soient identiques + support.setName(fieldName+" Support"); + support.setMeshName(meshName); // Vérifier que les différents noms de maillages lus soient identiques support.setEntity(entity); // REM : Le nombre <numberOfGeometricType> dans la précédente version du Driver // était erronée pour un champ qui ne reposait pas sur toutes les entités géométriques @@ -587,12 +655,107 @@ MED_FIELD_DRIVER22<T>::createFieldSupportPart1(med_2_3::med_idt id, support.setAll(true); numberOfElementsOfTypeC.resize(numberOfGeometricType+1); numberOfGaussPoint.resize(numberOfGeometricType+1); - + return alreadyFoundAnEntity; } else return false; } +template <class T> MED_EN::medEntityMesh +MED_FIELD_DRIVER22<T>::getMEDMEMEntityFromMEDType(medGeometryElement type, + int mesh_dim) const +{ + int elem_dim = type/100; + if (type==MED_POLYGON) elem_dim=2; + if (type==MED_POLYHEDRA) elem_dim=3; + + if (elem_dim==3) + return MED_CELL; + if (elem_dim==2) + if (mesh_dim==2) + return MED_CELL; + else if (mesh_dim==3) + return MED_FACE; + if (elem_dim==1) + return MED_EDGE; + if(elem_dim==0) + return MED_NODE; +} + + +template <class T> int +MED_FIELD_DRIVER22<T>::getMeshDimensionFromFile(med_2_3::med_idt id, + const string & meshName) const +{ + const char* LOC = "MED_FIELD_DRIVER<T>::getMeshDimensionFromFile(...)"; + BEGIN_OF_MED(LOC); + + int numberOfGeometricType=0; + MED_EN::medGeometryElement geometricType[MED_NBR_GEOMETRIE_MAILLE]; + int numberOfElementsOfType [MED_NBR_GEOMETRIE_MAILLE]; + int numberOfElementsOfTypeC[MED_NBR_GEOMETRIE_MAILLE+1]; + med_2_3::med_int numberOfElements=0; + med_2_3::med_table quoi; + + /*in MED file, all entities are regarded as MED_CELL + (except for those related to descending connectivities), + whereas in MEDMEM the distinction between MED_CELL, MED_FACE and MED_EDGE exists + it is therefore necessary to distinguish the MED-file entity + that will be used for the call to MED-file + and the MEDMEM entity*/ + MED_EN::medEntityMesh entity=MED_EN::MED_CELL; + quoi=med_2_3::MED_CONN; + + + list<MED_EN::medGeometryElement>::const_iterator currentGeometry; + bool alreadyFoundAnEntity = false; + numberOfElementsOfTypeC[0]=0; + + for (currentGeometry = (MED_EN::meshEntities[entity]).begin(); + currentGeometry != (MED_EN::meshEntities[entity]).end(); currentGeometry++) + { + numberOfElements = + med_2_3::MEDnEntMaa(id, + const_cast<char*> (meshName.c_str()), + med_2_3::MED_CONN, + med_2_3::MED_MAILLE, + (med_2_3::med_geometrie_element) *currentGeometry, + med_2_3::MED_NOD); + if (numberOfElements <= 0) + continue; + + alreadyFoundAnEntity = true; + numberOfElementsOfType[numberOfGeometricType] = numberOfElements; + numberOfElementsOfTypeC[numberOfGeometricType+1] = + numberOfElementsOfTypeC[numberOfGeometricType]+numberOfElements; + MED_EN::medGeometryElement geomType; + + //MED_FILE uses MED_NONE as a geometricType to describe MED_NODE + //MEDMEM uses MED_POINT1 + if ( *currentGeometry==MED_NONE) + geomType=MED_POINT1; + else + geomType=*currentGeometry; + geometricType[numberOfGeometricType] = geomType; + + numberOfGeometricType++; + } + + //Because MEDFILE and MEDMEM differ on the definition of MED_CELL + //it is necessary to remove the cells that do not + //have maximum cell dimension in the range covered by geometricType + int maxdim=0; + for (int i=0; i<numberOfGeometricType; i++) + { + CELLMODEL model(geometricType[i]); + int dim = model.getDimension(); + if (dim>maxdim) maxdim=dim; + } + + return maxdim; + +} + /*! Renvoie la liste <geoType> des types géométriques définis dans le maillage <meshName> @@ -600,23 +763,26 @@ MED_FIELD_DRIVER22<T>::createFieldSupportPart1(med_2_3::med_idt id, * < nbOfElOfType > contient le nombre d'entités de chaque type * < numberOfElementsOfTypeC > contient le nombre d'entités cumulées de chaque type avec numberOfElementsOfTypeC[0]=0; - + * < allDimensions > controls dimension of returned types of entity == MED_CELL */ template <class T> void -MED_FIELD_DRIVER22<T>::getMeshGeometricTypeFromFile(med_2_3::med_idt id, - string & meshName, - MED_EN::medEntityMesh entity, +MED_FIELD_DRIVER22<T>::getMeshGeometricTypeFromFile(med_2_3::med_idt id, + string & meshName, + MED_EN::medEntityMesh entity, vector<MED_EN::medGeometryElement> & geoType, - vector<int> &nbOfElOfType, - vector<int> &nbOfElOfTypeC + vector<int> & nbOfElOfType, + vector<int> & nbOfElOfTypeC ) const throw(MEDEXCEPTION) { - BEGIN_OF("MED_FIELD_DRIVER<T>::getMeshGeometricTypeFromFile(...)"); + const char* LOC = "MED_FIELD_DRIVER<T>::getMeshGeometricTypeFromFile(...)"; + BEGIN_OF_MED(LOC); int numberOfGeometricType=0; MED_EN::medGeometryElement geometricType[MED_NBR_GEOMETRIE_MAILLE]; int numberOfElementsOfType [MED_NBR_GEOMETRIE_MAILLE]; int numberOfElementsOfTypeC[MED_NBR_GEOMETRIE_MAILLE+1]; + int dimOfType[MED_NBR_GEOMETRIE_MAILLE]; + int maxdim=0; med_2_3::med_int numberOfElements=0; med_2_3::med_table quoi; @@ -669,26 +835,22 @@ MED_FIELD_DRIVER22<T>::getMeshGeometricTypeFromFile(med_2_3::med_idt id, geomType=*currentGeometry; geometricType[numberOfGeometricType] = geomType; - numberOfGeometricType++; - } - - //Because MEDFILE and MEDMEM differ on the definition of MED_CELL - //it is necessary to remove the cells that do not - //have maximum cell dimension in the range covered by geometricType - int maxdim=0; - for (int i=0; i<numberOfGeometricType; i++) - { - CELLMODEL model(geometricType[i]); - int dim = model.getDimension(); + //Because MEDFILE and MEDMEM differ on the definition of MED_CELL + //it is necessary to remove the cells that do not + //have maximum cell dimension in the range covered by geometricType + int dim = geomType / 100; + if ( geomType==MED_POLYGON ) dim=2; + if ( geomType==MED_POLYHEDRA ) dim=3; + dimOfType[ numberOfGeometricType ] = dim; if (dim>maxdim) maxdim=dim; + + numberOfGeometricType++; } nbOfElOfTypeC.push_back(0); for (int i=0; i<numberOfGeometricType; i++) { - CELLMODEL model(geometricType[i]); - int dim = model.getDimension(); - if (dim==maxdim || entity != MED_CELL) + if (dimOfType[i]==maxdim || entity != MED_CELL) { geoType.push_back(geometricType[i]); int nbelems = numberOfElementsOfType[i]; @@ -704,7 +866,7 @@ MED_FIELD_DRIVER22<T>::getMeshGeometricTypeFromFile(med_2_3::med_idt id, // for (int j =0 ; j<= numberOfGeometricType;++j) // cout << "nbOfElOfTypeC["<<j<<"]="<<nbOfElOfTypeC[j]<<endl; - END_OF("MED_FIELD_DRIVER<T>::getMeshGeometricTypeFromFile(...)"); + END_OF_MED(LOC); } /*! @@ -724,7 +886,7 @@ MED_FIELD_DRIVER22<T>::getMeshGeometricTypeFromMESH( MESH * meshPtr, vector<int> &nbOfElOfTypeC) const throw(MEDEXCEPTION) { const char LOC[] = "MED_FIELD_DRIVER<T>::getMeshGeometricTypeFromMESH(...) : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (!meshPtr) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"ptrMesh must be non null" )); ; @@ -744,7 +906,7 @@ MED_FIELD_DRIVER22<T>::getMeshGeometricTypeFromMESH( MESH * meshPtr, nbOfElOfTypeC[j]+=nbOfElOfTypeC[j-1]+nbOfElOfType[j-1]; } - END_OF(LOC); + END_OF_MED(LOC); } /*--------------------- RDONLY PART -------------------------------*/ @@ -754,11 +916,26 @@ template <class T> GENDRIVER * MED_FIELD_RDONLY_DRIVER22<T>::copy(void) const return new MED_FIELD_RDONLY_DRIVER22<T>(*this); } +/*! + In MEDMEM, FIELDs lie on support which can be plain SUPPORT, FAMILY + or GROUP, while in MED-file, there is no link between the FAMILY and + GROUP notions and the FIELDs. FIELDs lie on profiles. + The problem arises from the fact that the MED write driver creates + profiles when treating fields that lie on MEDMEM::SUPPORT, + MEDMEM_FAMILY or MEDMEM::GROUP. The profile is named after the + support name : nameOfSupport_<type_of_geometric_entity>. + However, the read driver is unable to link supports and profiles + and it recreates a new support that corresponds to the field profile. + + To avoid this support recreation, pass the mesh to the FIELD's + constructor, and the field driver will find appropriate FAMILY or GROUP + in the mesh and use it for the field. + */ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) throw (MEDEXCEPTION) { const char * LOC = " MED_FIELD_RDONLY_DRIVER22::read() " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array ArrayNo; typedef typename MEDMEM_ArrayInterface<T,NoInterlace,Gauss>::Array ArrayNoWg; @@ -782,13 +959,13 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) if ( MED_FIELD_DRIVER<T>::_fieldName.size() > MED_TAILLE_NOM ) { - SCRUTE(MED_FIELD_DRIVER<T>::_fieldName.size()); - SCRUTE(MED_TAILLE_NOM); + SCRUTE_MED(MED_FIELD_DRIVER<T>::_fieldName.size()); + SCRUTE_MED(MED_TAILLE_NOM); // throw MEDEXCEPTION(LOCALIZED(STRING(LOC) // <<" <fieldName> size in object driver FIELD is > MED_TAILLE_NOM .")); - MESSAGE(LOC << "Warning <fieldName> size in object driver FIELD is > MED_TAILLE_NOM ."); + MESSAGE_MED(LOC << "Warning <fieldName> size in object driver FIELD is > MED_TAILLE_NOM ."); } const string & fieldName = MED_FIELD_DRIVER<T>::_fieldName; @@ -797,7 +974,7 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) bool isFullInterlace = ( interlacingType == MED_EN::MED_FULL_INTERLACE ); bool isNoInterlaceByType = ( interlacingType == MED_EN::MED_NO_INTERLACE_BY_TYPE );//PAL17011 - MESSAGE("###### "<<LOC<<" fieldNameDRIVER : "<< fieldName << " fieldName : "<< MED_FIELD_DRIVER<T>::_ptrField->_name); + MESSAGE_MED("###### "<<LOC<<" fieldNameDRIVER : "<< fieldName << " fieldName : "<< MED_FIELD_DRIVER<T>::_ptrField->_name); // EF : // Si un support a été donnée au champ, pour des raisons de compatibilité avec @@ -847,7 +1024,7 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) numberOfComponents = med_2_3::MEDnChamp(id,i) ; if ( numberOfComponents <= 0 ) - MESSAGE(LOC<<"Be careful there is no compound for field n°"<<i<<"in file |"<<MED_FIELD_DRIVER<T>::_fileName<<"| !"); + MESSAGE_MED(LOC<<"Be careful there is no compound for field n°"<<i<<"in file |"<<MED_FIELD_DRIVER<T>::_fileName<<"| !"); componentName = new char[numberOfComponents*MED_TAILLE_PNOM22+1] ; unitName = new char[numberOfComponents*MED_TAILLE_PNOM22+1] ; @@ -855,9 +1032,9 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) err = med_2_3::MEDchampInfo(id, i, tmpFieldName, &type, componentName, unitName, numberOfComponents) ; - MESSAGE("Field "<<i<<" : #" << tmpFieldName <<"# et recherche #"<<fieldName.c_str()<<"#"); + MESSAGE_MED("Field "<<i<<" : #" << tmpFieldName <<"# et recherche #"<<fieldName.c_str()<<"#"); if ( !strcmp(tmpFieldName,fieldName.c_str()) ) { - MESSAGE("FOUND FIELD "<< tmpFieldName <<" : "<<i); + MESSAGE_MED("FOUND FIELD "<< tmpFieldName <<" : "<<i); MED_FIELD_DRIVER<T>::_fieldNum = i ; break ; } @@ -875,7 +1052,7 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) throw MEDEXCEPTION(LOCALIZED( STRING(LOC) << ": Field "<< fieldName << " not found in file " << MED_FIELD_DRIVER<T>::_fileName) ); - MESSAGE ("FieldNum : "<<MED_FIELD_DRIVER<T>::_fieldNum); + MESSAGE_MED ("FieldNum : "<<MED_FIELD_DRIVER<T>::_fieldNum); if (numberOfComponents < 1) { delete[] componentName; delete[] unitName; @@ -928,12 +1105,15 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) vector<int> numberOfElementsOfTypeC; vector<int> numberOfGaussPoint; int totalNumberOfElWg=0; + MED_EN::medEntityMesh fieldMedFileEntity; bool found = createFieldSupportPart1(id,fieldName, MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber, MED_FIELD_DRIVER<T>::_ptrField->_orderNumber, *mySupport, meshName, - numberOfElementsOfTypeC, numberOfGaussPoint,totalNumberOfElWg); + numberOfElementsOfTypeC, numberOfGaussPoint, + totalNumberOfElWg, fieldMedFileEntity); + if ( !found ) { delete mySupport; delete[] componentName; delete[] unitName; @@ -946,28 +1126,35 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) << meshName << "|" )); } + + //int mesh_dim = MED_FIELD_DRIVER22<T>::getMeshDimensionFromFile(id,meshName); + MED_EN::medEntityMesh entityType = mySupport->getEntity(); //Si un SUPPORT était donné, récupère son nom, sa description et // le pointeur du maillage associé if (! haveSupport) meshName = mySupport->getMeshName(); else { - if ( mySupport->getEntity() != MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getEntity() ) { - delete mySupport; delete[] componentName; delete[] unitName; - MED_FIELD_DRIVER<T>::_fieldNum = MED_INVALID ; - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Given entity |" - << MED_EN::entNames[MED_FIELD_DRIVER<T>::_ptrField-> - getSupport()->getEntity()] - << "| for field |" - << fieldName - << "| with (it,or) = (" - << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << "," - << MED_FIELD_DRIVER<T>::_ptrField->_orderNumber << "), on mesh " - << meshName << "| differs from found entity |" - << MED_EN::entNames[entityType] << "|." - )); - } - mySupport->setName( MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getName() ); + // for bug 19782. Entity of support in field was set by med driver and was taken + // from the file without any analysis. It can differ from entity the support will + // have in MEDMEM. +// if ( entityType != MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getEntity() ) { +// delete mySupport; delete[] componentName; delete[] unitName; +// MED_FIELD_DRIVER<T>::_fieldNum = MED_INVALID ; +// throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Given entity |" +// << MED_EN::entNames[MED_FIELD_DRIVER<T>::_ptrField-> +// getSupport()->getEntity()] +// << "| for field |" +// << fieldName +// << "| with (it,or) = (" +// << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << "," +// << MED_FIELD_DRIVER<T>::_ptrField->_orderNumber << "), on mesh " +// << meshName << "| differs from found entity |" +// << MED_EN::entNames[entityType] << "|." +// )); +// } + if ( entityType == MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getEntity() ) + mySupport->setName( MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getName() ); mySupport->setMesh( MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getMesh() ); mySupport->setDescription(MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getDescription()); } @@ -985,41 +1172,41 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) vector< int > meshNbOfElOfTypeC; // Si le maillage n'est pas trouvé les tableaux renvoyés sont vides if (fileHasMesh) - { - MED_EN::medEntityMesh entityTypeLoc = entityType; - if (entityType == MED_EN::MED_FACE || entityType == MED_EN::MED_EDGE) entityTypeLoc = MED_EN::MED_CELL; + { +// MED_EN::medEntityMesh entityTypeLoc = entityType; +// if (entityType == MED_EN::MED_FACE || entityType == MED_EN::MED_EDGE) entityTypeLoc = MED_EN::MED_CELL; - this->getMeshGeometricTypeFromFile(id,meshName,entityTypeLoc,meshGeoType, - meshNbOfElOfType,meshNbOfElOfTypeC); - } + this->getMeshGeometricTypeFromFile(id,meshName,entityType,meshGeoType, + meshNbOfElOfType,meshNbOfElOfTypeC); + } - SCRUTE(meshGeoType.size()); - SCRUTE(MESHgeoType.size()); - SCRUTE(meshNbOfElOfTypeC.size()); - SCRUTE(MESHnbOfElOfTypeC.size()); + SCRUTE_MED(meshGeoType.size()); + SCRUTE_MED(MESHgeoType.size()); + SCRUTE_MED(meshNbOfElOfTypeC.size()); + SCRUTE_MED(MESHnbOfElOfTypeC.size()); if (meshGeoType.size() != MESHgeoType.size()) { for (int i = 0; i<meshGeoType.size();i++) - MESSAGE("debug meshGeotype " << meshGeoType[i]); + MESSAGE_MED("debug meshGeotype " << meshGeoType[i]); for (int i = 0; i<MESHgeoType.size();i++) - MESSAGE("debug MESHgeoType. " << MESHgeoType[i]); + MESSAGE_MED("debug MESHgeoType. " << MESHgeoType[i]); } if (meshNbOfElOfTypeC.size() == MESHnbOfElOfTypeC.size()) { for (int i = 0; i<meshNbOfElOfTypeC.size();i++) - MESSAGE("debug meshNbOfElOfTypeC " << meshNbOfElOfTypeC[i]); + MESSAGE_MED("debug meshNbOfElOfTypeC " << meshNbOfElOfTypeC[i]); for (int i = 0; i<MESHnbOfElOfTypeC.size();i++) - MESSAGE("debug MESHnbOfElOfTypeC " << MESHnbOfElOfTypeC[i]); + MESSAGE_MED("debug MESHnbOfElOfTypeC " << MESHnbOfElOfTypeC[i]); } if (fileHasMesh && haveSupport ) if ( ( meshGeoType != MESHgeoType ) || (meshNbOfElOfTypeC != MESHnbOfElOfTypeC) ) { - MESSAGE("Warning MedField driver 21 while getting mesh information from file for FIELD "<< fieldName + MESSAGE_MED("Warning MedField driver 21 while getting mesh information from file for FIELD "<< fieldName << " on entity " << MED_EN::entNames[entityType] << " with (it,or) = (" << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << "," @@ -1087,19 +1274,24 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) // If an error occurs while reading the field, these allocated FIELD member will be deleted - MED_FIELD_DRIVER<T>::_ptrField->_name = fieldName; + MED_FIELD_DRIVER<T>::_ptrField->_name = healName( fieldName ); MED_FIELD_DRIVER<T>::_ptrField->_numberOfComponents = numberOfComponents ; - MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes = new int [numberOfComponents] ; - MED_FIELD_DRIVER<T>::_ptrField->_componentsNames = new string[numberOfComponents] ; - MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits = new UNIT [numberOfComponents] ; - MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions = new string[numberOfComponents] ; - MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits = new string[numberOfComponents] ; + //MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes = new int [numberOfComponents] ; + //MED_FIELD_DRIVER<T>::_ptrField->_componentsNames = new string[numberOfComponents] ; + //MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits = new UNIT [numberOfComponents] ; + //MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions = new string[numberOfComponents] ; + //MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits = new string[numberOfComponents] ; + MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes.resize(numberOfComponents); + MED_FIELD_DRIVER<T>::_ptrField->_componentsNames.resize(numberOfComponents); + MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits.resize(numberOfComponents); + MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions.resize(numberOfComponents); + MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits.resize(numberOfComponents); for (int i=0; i<numberOfComponents; i++) { MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes[i] = 1 ; MED_FIELD_DRIVER<T>::_ptrField->_componentsNames[i] = string(componentName+i*MED_TAILLE_PNOM22,MED_TAILLE_PNOM22) ; MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits[i] = string(unitName+i*MED_TAILLE_PNOM22,MED_TAILLE_PNOM22) ; - SCRUTE(MED_FIELD_DRIVER<T>::_ptrField->_componentsNames[i]); - SCRUTE(MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits[i]); + SCRUTE_MED(MED_FIELD_DRIVER<T>::_ptrField->_componentsNames[i]); + SCRUTE_MED(MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits[i]); } delete[] componentName; delete[] unitName; @@ -1122,9 +1314,9 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) vector < vector<med_2_3::med_int> > profilListFromFile (NumberOfTypes); // IPAL13481 char * profilName = new char[MED_TAILLE_NOM+1]; - MESSAGE ("NumberOfTypes : "<< NumberOfTypes); + MESSAGE_MED ("NumberOfTypes : "<< NumberOfTypes); MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues=0 ; - + // PAL16681 (Read no interlace field from file) -> // use medModeSwitch of a field in MEDMEMchampLire() if there is one geometric type // to exclude array conversion @@ -1138,19 +1330,19 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) int numberOfValuesWc= nbOfElOfType[typeNo]*numberOfGaussPoint[typeNo+1]*numberOfComponents; char * gaussModelName = new char[MED_TAILLE_NOM+1]; - MESSAGE ("FIELD_NAME : "<< fieldName.c_str()); - MESSAGE ("MESH_NAME : "<< meshName.c_str()); - MESSAGE ("MED_ENTITE : "<< MED_EN::entNames[entityType]); - MESSAGE ("MED_GEOM : "<< MED_EN::geoNames[types[typeNo]]); - MESSAGE ("Iteration : "<< MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber()); - MESSAGE ("Order : "<< MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()); - MESSAGE ("Time : "<< MED_FIELD_DRIVER<T>::_ptrField->getTime()); - MESSAGE ("NumberOfElements : "<< nbOfElOfType[typeNo]); - MESSAGE ("NumberOfComponents : "<< numberOfComponents); - MESSAGE ("NumberOfGaussPts : "<< numberOfGaussPoint[typeNo+1]); - MESSAGE ("NumberOfValuesWg : "<< nbOfElOfType[typeNo]*numberOfGaussPoint[typeNo+1]); - MESSAGE ("NumberOfValuesWgWc : "<< numberOfValuesWc); - MESSAGE ("Index : "<< index); + MESSAGE_MED ("FIELD_NAME : "<< fieldName.c_str()); + MESSAGE_MED ("MESH_NAME : "<< meshName.c_str()); + MESSAGE_MED ("MED_ENTITE : "<< MED_EN::entNames[entityType]); + MESSAGE_MED ("MED_GEOM : "<< MED_EN::geoNames[types[typeNo]]); + MESSAGE_MED ("Iteration : "<< MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber()); + MESSAGE_MED ("Order : "<< MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()); + MESSAGE_MED ("Time : "<< MED_FIELD_DRIVER<T>::_ptrField->getTime()); + MESSAGE_MED ("NumberOfElements : "<< nbOfElOfType[typeNo]); + MESSAGE_MED ("NumberOfComponents : "<< numberOfComponents); + MESSAGE_MED ("NumberOfGaussPts : "<< numberOfGaussPoint[typeNo+1]); + MESSAGE_MED ("NumberOfValuesWg : "<< nbOfElOfType[typeNo]*numberOfGaussPoint[typeNo+1]); + MESSAGE_MED ("NumberOfValuesWgWc : "<< numberOfValuesWc); + MESSAGE_MED ("Index : "<< index); med_2_3::med_err ret=-1; med_2_3::med_int * myValuesTmp=0; @@ -1162,6 +1354,11 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) ptrTmp = (unsigned char*) &myValues[index]; //VERIFIER LE NBRE +// med_2_3::med_entite_maillage medfile_entity; +// if (entityType==MED_NODE) +// medfile_entity= (med_2_3::med_entite_maillage)MED_NODE; +// else +// medfile_entity= (med_2_3::med_entite_maillage)MED_CELL; ret=med_2_3::MEDchampLire(id,const_cast <char*> (meshName.c_str() ), const_cast <char*> (fieldName.c_str()), (unsigned char*) ptrTmp, @@ -1170,7 +1367,7 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) gaussModelName, profilName, med_2_3::MED_COMPACT, - (med_2_3::med_entite_maillage) entityType, + (med_2_3::med_entite_maillage) fieldMedFileEntity, (med_2_3::med_geometrie_element)types[typeNo], MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber(), MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber() @@ -1196,16 +1393,21 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) //delete[] NumberOfValues ; delete[] profilName; delete[] gaussModelName; - delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes ; - delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsNames ; - delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits ; - delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions ; - delete[] MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits ; - MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes = NULL ; - MED_FIELD_DRIVER<T>::_ptrField->_componentsNames = NULL ; - MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits = NULL ; - MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions = NULL ; - MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits = NULL ; + //delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes ; + //delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsNames ; + //delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits ; + //delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions ; + //delete[] MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits ; + //MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes = NULL ; + //MED_FIELD_DRIVER<T>::_ptrField->_componentsNames = NULL ; + //MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits = NULL ; + //MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions = NULL ; + //MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits = NULL ; + MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes.clear(); + MED_FIELD_DRIVER<T>::_ptrField->_componentsNames.clear(); + MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits.clear(); + MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions.clear(); + MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits.clear(); MED_FIELD_DRIVER<T>::_fieldNum = MED_INVALID ; // we have not found right field, so reset the field number throw MEDEXCEPTION( LOCALIZED( STRING(LOC) <<": ERROR while reading values")) ; } @@ -1260,15 +1462,15 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) profilListFromFile[typeNo].resize(pflSize); ret = med_2_3::MEDprofilLire(id,&profilList[typeNo][0],profilName); // cf item 16 Effective STL // IPAL13481 profilListFromFile[typeNo] = profilList[typeNo]; - profilNameList[typeNo]=string(profilName); + profilNameList[typeNo]= healName(profilName); } } delete[] profilName; - //MESSAGE ("Index : "<< index); + //MESSAGE_MED ("Index : "<< index); assert(index == totalNumberOfElWg*numberOfComponents); - assert(MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues == mySupport->getNumberOfElements(MED_ALL_ELEMENTS)); + assert(MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues == mySupport->getNumberOfElements(MED_ALL_ELEMENTS)); if (anyProfil) { @@ -1298,14 +1500,14 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) // cout << "meshNbOfElOfTypeC["<<meshTypeNo<<"]=" << meshNbOfElOfTypeC[meshTypeNo] <<endl; // Transformer les numéros locaux d'entités medfichier en numéro global medmémoire - for (int i = 0 ; i < profilList[typeNo].size(); i++ ) { - // Les numéros des entités commencent à 1 dans MEDfichier comme dans MEDmémoire - // meshNbOfElOfTypeC[0]=0 ...meshNbOfEltOfTypeC[meshTypeNo]= - // meshNbOfElOfTypeC[meshTypeNo-1]+nbrOfElem of meshTypeNo type - // rem1 : Si le meshTypeNo trouvé est 0 (premier type géométrique du maillage - // il ne faut pas décaler les numéros du profils qui commencent à 1 dans MEDFICHIER - // rem2 : meshNbOfElOfTypeC[NumberOfTypes] ne devrait jamais être utilisé - profilList[typeNo][i]+=meshNbOfElOfTypeC[meshTypeNo]; + for (int i = 0; i < profilList[typeNo].size(); i++) { + // Les numéros des entités commencent à 1 dans MEDfichier comme dans MEDmémoire + // meshNbOfElOfTypeC[0]=0 ...meshNbOfEltOfTypeC[meshTypeNo]= + // meshNbOfElOfTypeC[meshTypeNo-1]+nbrOfElem of meshTypeNo type + // rem1 : Si le meshTypeNo trouvé est 0 (premier type géométrique du maillage + // il ne faut pas décaler les numéros du profils qui commencent à 1 dans MEDFICHIER + // rem2 : meshNbOfElOfTypeC[NumberOfTypes] ne devrait jamais être utilisé + profilList[typeNo][i]+=meshNbOfElOfTypeC[meshTypeNo]; } } else { // Créer le profil <MED_ALL> pour ce type géométrique @@ -1315,18 +1517,18 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) // profils sur certains types géométriques alors qu'à la lecture il n'y en avait pas ! // Solution : Stocker les noms des profils et les utiliser pour savoir si il y avait ou non // un profil - int pflSize = meshNbOfElOfType[meshTypeNo]; + int pflSize = meshNbOfElOfType[meshTypeNo]; // profil = new int[pflSize]; profilList[typeNo].resize(pflSize); - profilSize[typeNo]=pflSize; + profilSize[typeNo] = pflSize; for (int j = 1; j <= pflSize; j++) { - profilList[typeNo][j-1]=meshNbOfElOfTypeC[meshTypeNo] + j ; // index MEDMEM commence à 1 + profilList[typeNo][j-1] = meshNbOfElOfTypeC[meshTypeNo] + j ; // index MEDMEM commence à 1 } profilNameList[typeNo] = MED_NOPFL; //Information a utiliser pour la sauvegarde : PLUTOT MED_ALL } - profilSizeC+=profilList[typeNo].size(); + profilSizeC += profilList[typeNo].size(); } MEDSKYLINEARRAY * skyLine = new MEDSKYLINEARRAY(profilList.size(), profilSizeC ); @@ -1363,12 +1565,12 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) // Créer un driver spécifique pour les modes MED_FULL_INTERLACE et MED_NO_INTERLACE // serait plus efficace. bool anyGauss = (numberOfGaussPoint != vector<int>(numberOfGaussPoint.size(),1)); - SCRUTE(anyGauss); + SCRUTE_MED(anyGauss); MEDMEM_Array_ * Values; if (anyGauss) { - SCRUTE(mySupport->getNumberOfElements(MED_ALL_ELEMENTS) ); - SCRUTE(NumberOfTypes); - SCRUTE(numberOfElementsOfTypeC[NumberOfTypes]-1); + SCRUTE_MED(mySupport->getNumberOfElements(MED_ALL_ELEMENTS) ); + SCRUTE_MED(NumberOfTypes); + SCRUTE_MED(numberOfElementsOfTypeC[NumberOfTypes]-1); assert(mySupport->getNumberOfElements(MED_ALL_ELEMENTS) == (numberOfElementsOfTypeC[NumberOfTypes]-1) ); // PAL16681. If NumberOfTypes == 1 then myValues is what should be // in a field value, inspite of InterlacingType @@ -1435,9 +1637,98 @@ template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void) MED_FIELD_DRIVER<T>::_ptrField->_isRead = true ; - MED_FIELD_DRIVER<T>::_ptrField->_support=mySupport; //Prévenir l'utilisateur ? + bool isFound = false; + MESH* aMesh = MED_FIELD_DRIVER<T>::_ptrField->_mesh; + if (!haveSupport && aMesh && anyProfil) + { + int it = -1; + for (int typeNo = 0; (typeNo < NumberOfTypes) && (it == -1); typeNo++) { + if (strcmp(profilNameList[typeNo].c_str(), MED_NOPFL) != 0) + it = typeNo; + } + // IMP 0019953: link between fields and families for MED 2.2 read driver + string aPN = profilNameList[it]; + MED_EN::medGeometryElement aPT = types[it]; + + ostringstream typestr; + typestr << "_type" << aPT; + string aSuff = typestr.str(); + + //- If the field profile name is toto_PFL and a family toto exists, + // the field will point to the corresponding FAMILY object. + const vector<FAMILY*> aFams = aMesh->getFamilies(entityType); + for (int fi = 0; fi < aFams.size() && !isFound; fi++) { + FAMILY* aF = aFams[fi]; + string aFN_suff = aF->getName() + aSuff; + if (aPN == aFN_suff) { + isFound = true; + //family found + MED_FIELD_DRIVER<T>::_ptrField->_support = aF; //Prévenir l'utilisateur ? + } + } + if (!isFound) { + // - If no family was found, lookup the groups and if a group toto + // exists, the field will point to the corresponding GROUP object. + const vector<GROUP*> aGrps = aMesh->getGroups(entityType); + for (int gi = 0; gi < aGrps.size() && !isFound; gi++) { + GROUP* aG = aGrps[gi]; + string aGN_suff = aG->getName() + aSuff; + if (aPN == aGN_suff) { + isFound = true; + //group found + MED_FIELD_DRIVER<T>::_ptrField->_support = aG; //Prévenir l'utilisateur ? + } + } + } + if (!isFound) { + // - If no family or group was found and the + // profile name is xxx_PFL, throw an exception + int pos = aPN.rfind(aSuff); + if (pos + aSuff.length() - 1 == aPN.length()) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) + << ": Can't find appropriate support (GROUP or FAMILY)" + << " in mesh " << meshName << " for field " << fieldName + << ", while one of its profiles " << aPN + << " was generated from a FAMILY or a GROUP")); + } + else { + // - Check that the found support has correct types + // and number of elements. If not, throw an exception + const SUPPORT* aSupp = MED_FIELD_DRIVER<T>::_ptrField->_support; + if (aSupp->getNumberOfTypes() != NumberOfTypes) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << ": Invalid support (GROUP or FAMILY) found in mesh " + << meshName << " for field " << fieldName << " by name of profile " + << aPN << ": different number of types in found support |" + << aSupp->getNumberOfTypes() << "| and in required |" + << NumberOfTypes << "|")); + + const MED_EN::medGeometryElement* aTypes = aSupp->getTypes(); + for (int it = 0; it < NumberOfTypes && isFound; it++) + { + MED_EN::medGeometryElement aType = aTypes[it]; + if (aType != types[it]) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << ": Invalid support (GROUP or FAMILY) found in mesh " + << meshName << " for field " << fieldName << " by name of profile " + << aPN << ": geometric type in found support |" << aType + << "| differs from required type |" << types[it] << "|")); + + if (aSupp->getNumberOfElements(aType) != nbOfElOfType[it]) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << ": Invalid support (GROUP or FAMILY) found in mesh " + << meshName << " for field " << fieldName << " by name of profile " + << aPN << ": number of elements of type " << aType + << " in found support |" << aSupp->getNumberOfElements(aType) + << "| differs from required |" << nbOfElOfType[it] << "|")); + } + } + } + + if (!isFound) { + // No corresponding support (family or group) + // found in the mesh, use the newly created one + MED_FIELD_DRIVER<T>::_ptrField->_support = mySupport; //Prévenir l'utilisateur ? + } - END_OF(LOC); + END_OF_MED(LOC); } template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::write( void ) const @@ -1463,7 +1754,7 @@ template <class T> void MED_FIELD_WRONLY_DRIVER22<T>::write(void) const throw (MEDEXCEPTION) { const char * LOC = "MED_FIELD_WRONLY_DRIVER22::write(void) const " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array ArrayNo; typedef typename MEDMEM_ArrayInterface<T,NoInterlace,Gauss>::Array ArrayNoWg; typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array ArrayFull; @@ -1487,18 +1778,18 @@ template <class T> void MED_FIELD_WRONLY_DRIVER22<T>::write(void) const // If _fieldName is not set in driver, try to use _ptrfield->_fieldName if ( ( MED_FIELD_DRIVER<T>::_fieldName.empty() ) && ( !MED_FIELD_DRIVER<T>::_ptrField->_name.empty() ) ) - fieldName = MED_FIELD_DRIVER<T>::_ptrField->_name; + fieldName = healName( MED_FIELD_DRIVER<T>::_ptrField->_name ); else - fieldName = MED_FIELD_DRIVER<T>::_fieldName; + fieldName = healName( MED_FIELD_DRIVER<T>::_fieldName ); //if ( ! MED_FIELD_DRIVER<T>::_ptrField->_isRead ) // throw MEDEXCEPTION(LOCALIZED(STRING(LOC) // <<" FIELD |"<<fieldName<<"| was not read but is being written")); - SCRUTE(fieldName); + SCRUTE_MED(fieldName); if ( fieldName.size() > MED_TAILLE_NOM ) { fieldName.substr(0,MED_TAILLE_NOM); - MESSAGE( "Be careful <fieldName> size must not be > MED_TAILLE_NOM, using fieldName : |"<< fieldName <<"|." ); + MESSAGE_MED( "Be careful <fieldName> size must not be > MED_TAILLE_NOM, using fieldName : |"<< fieldName <<"|." ); } const SUPPORT * mySupport = MED_FIELD_DRIVER<T>::_ptrField->getSupport() ; @@ -1511,11 +1802,11 @@ template <class T> void MED_FIELD_WRONLY_DRIVER22<T>::write(void) const const locMap & gaussModel = MED_FIELD_DRIVER<T>::_ptrField->_gaussModel; - string meshName = mySupport->getMeshName(); - SCRUTE(meshName); + string meshName = healName( mySupport->getMeshName() ); + SCRUTE_MED(meshName); if ( meshName.size() > MED_TAILLE_NOM ) { meshName = meshName.substr(0,MED_TAILLE_NOM); - MESSAGE( "Be careful <meshName> size must not be > MED_TAILLE_NOM, using meshName : |"<< meshName <<"|." ); + MESSAGE_MED( "Be careful <meshName> size must not be > MED_TAILLE_NOM, using meshName : |"<< meshName <<"|." ); } MED_EN::medEntityMesh entityType = mySupport->getEntity(); @@ -1541,12 +1832,12 @@ template <class T> void MED_FIELD_WRONLY_DRIVER22<T>::write(void) const listcomponent_unit[i],0,length); } - MESSAGE("using component_name=|"<<component_name<<"|"); - MESSAGE("using component_unit=|"<<component_unit<<"|"); + MESSAGE_MED("using component_name=|"<<component_name<<"|"); + MESSAGE_MED("using component_unit=|"<<component_unit<<"|"); MED_EN::med_type_champ ValueType=MED_FIELD_DRIVER<T>::_ptrField->getValueType() ; - MESSAGE("Template Type =|"<<ValueType<<"|"); + MESSAGE_MED("Template Type =|"<<ValueType<<"|"); // Vérifier si le champ existe déjà char champName[MED_TAILLE_NOM+1]; @@ -1579,11 +1870,11 @@ template <class T> void MED_FIELD_WRONLY_DRIVER22<T>::write(void) const ) ); // component name and unit - SCRUTE(nbComp); - MESSAGE(LOC<<" Component name in file : "<<compName); - MESSAGE(LOC<<" Component name in memory : "<<component_name); - MESSAGE(LOC<<" Component unit in file : "<<compUnit); - MESSAGE(LOC<<" Component unit in memory : "<<component_unit); + SCRUTE_MED(nbComp); + MESSAGE_MED(LOC<<" Component name in file : "<<compName); + MESSAGE_MED(LOC<<" Component name in memory : "<<component_name); + MESSAGE_MED(LOC<<" Component unit in file : "<<compUnit); + MESSAGE_MED(LOC<<" Component unit in memory : "<<component_unit); delete[] compName ; delete[] compUnit ; @@ -1592,7 +1883,7 @@ template <class T> void MED_FIELD_WRONLY_DRIVER22<T>::write(void) const string dataGroupName = "/CHA/"; dataGroupName += fieldName; - MESSAGE(LOC << "|" << dataGroupName << "|" ); + MESSAGE_MED(LOC << "|" << dataGroupName << "|" ); med_2_3::med_idt gid = H5Gopen(id, dataGroupName.c_str() ); if ( gid < 0 ) { @@ -1663,6 +1954,11 @@ template <class T> void MED_FIELD_WRONLY_DRIVER22<T>::write(void) const fileHasMesh = ( med_2_3::MEDdimLire(id, const_cast<char *>(meshName.c_str())) > 0); MESH * meshPtr = mySupport->getMesh(); +// if(!meshPtr) +// throw MEDEXCEPTION( LOCALIZED (STRING(LOC) +// <<": Mesh in support is null" +// ) +// ); if (fileHasMesh) this->getMeshGeometricTypeFromFile(id, meshName, @@ -1712,6 +2008,11 @@ template <class T> void MED_FIELD_WRONLY_DRIVER22<T>::write(void) const int numberOfElForMED = -1; const T * value = NULL; int index = 1 ; + + //converting MEDMEM type to MEDfile type + if (entityType != MED_EN::MED_NODE) + entityType = MED_EN::MED_CELL; + // on boucle sur tout les types pour ecrire les tableaux de valeur for (int typeNo=0;typeNo<numberOfTypes;typeNo++) { @@ -1746,9 +2047,9 @@ template <class T> void MED_FIELD_WRONLY_DRIVER22<T>::write(void) const // PAL16854(Partial support on nodes) -> //profilName = (profilNameList.size()>typeNo) ? profilNameList[typeNo].substr(0,MED_TAILLE_NOM) : MED_NOPFL; if (profilNameList[typeNo].size()>MED_TAILLE_NOM) - profilName = profilNameList[typeNo].substr(0,MED_TAILLE_NOM); + profilName = healName( profilNameList[typeNo].substr(0,MED_TAILLE_NOM) ); else - profilName= profilNameList[typeNo]; + profilName = healName( profilNameList[typeNo] ); // Rem : Si le SUPPORT n'est pas onAll mais que pour un type géométrique donné le nom // du profil associé est MED_NOPFL alors le profil n'est pas écrit dans le fichier MED. @@ -1850,7 +2151,7 @@ template <class T> void MED_FIELD_WRONLY_DRIVER22<T>::write(void) const if ( locPtr->getInterlacingType() == MED_EN::MED_FULL_INTERLACE ) { const GAUSS_LOCALIZATION<FullInterlace> & loc=*(static_cast<const GAUSS_LOCALIZATION<FullInterlace> * >(locPtr)); ngauss = loc.getNbGauss(); - locName=loc.getName(); + locName=healName( loc.getName() ); err=med_2_3::MEDgaussEcr(id, (med_2_3::med_geometrie_element) loc.getType(), (med_2_3::med_float *) loc.getRefCoo().getPtr(), @@ -1863,7 +2164,7 @@ template <class T> void MED_FIELD_WRONLY_DRIVER22<T>::write(void) const } else { const GAUSS_LOCALIZATION<NoInterlace> & loc=*(static_cast<const GAUSS_LOCALIZATION<NoInterlace> * >(locPtr)); ngauss = loc.getNbGauss(); - locName=loc.getName(); + locName=healName( loc.getName() ); err=med_2_3::MEDgaussEcr(id, (med_2_3::med_geometrie_element) loc.getType(), (med_2_3::med_float *) loc.getRefCoo().getPtr(), @@ -1887,20 +2188,20 @@ template <class T> void MED_FIELD_WRONLY_DRIVER22<T>::write(void) const numberOfElForMED *= ngauss; } - MESSAGE("MED_FIELD_DRIVER22<T>::_medIdt : "<<id); - MESSAGE("meshName.c_str() : "<<meshName.c_str()); - MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getName() : "<<MED_FIELD_DRIVER<T>::_ptrField->getName()); - MESSAGE("MED_FIELD_DRIVER<T>::_fieldName : "<<MED_FIELD_DRIVER<T>::_fieldName); - MESSAGE("value : "<<value); - MESSAGE("numberOfElements : "<<numberOfElements); - MESSAGE("numberOfElForMED : "<<numberOfElForMED); - MESSAGE("entityType : "<<MED_EN::entNames[entityType]); - MESSAGE("types[i] : "<<MED_EN::geoNames[types[typeNo]]); + MESSAGE_MED("MED_FIELD_DRIVER22<T>::_medIdt : "<<id); + MESSAGE_MED("meshName.c_str() : "<<meshName.c_str()); + MESSAGE_MED("MED_FIELD_DRIVER<T>::_ptrField->getName() : "<<MED_FIELD_DRIVER<T>::_ptrField->getName()); + MESSAGE_MED("MED_FIELD_DRIVER<T>::_fieldName : "<<MED_FIELD_DRIVER<T>::_fieldName); + MESSAGE_MED("value : "<<value); + MESSAGE_MED("numberOfElements : "<<numberOfElements); + MESSAGE_MED("numberOfElForMED : "<<numberOfElForMED); + MESSAGE_MED("entityType : "<<MED_EN::entNames[entityType]); + MESSAGE_MED("types[i] : "<<MED_EN::geoNames[types[typeNo]]); if (myField) //myField may be NULL (PAL17011) - MESSAGE("NumberOfGaussPoint[i] : "<<myField->getNumberOfGaussPoints(types[typeNo])); - MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber() : "<<MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber()); - MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getTime() : "<<MED_FIELD_DRIVER<T>::_ptrField->getTime()); - MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber() : "<<MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()); + MESSAGE_MED("NumberOfGaussPoint[i] : "<<myField->getNumberOfGaussPoints(types[typeNo])); + MESSAGE_MED("MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber() : "<<MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber()); + MESSAGE_MED("MED_FIELD_DRIVER<T>::_ptrField->getTime() : "<<MED_FIELD_DRIVER<T>::_ptrField->getTime()); + MESSAGE_MED("MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber() : "<<MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()); // Rem 1 : le nombre d'éléments passé à MEDchampEcr ne doit pas tenir compte de la taille // des profils : c'est la taille du champ sans profil. @@ -1917,7 +2218,7 @@ template <class T> void MED_FIELD_WRONLY_DRIVER22<T>::write(void) const (med_2_3::med_entite_maillage)entityType, (med_2_3::med_geometrie_element)types[typeNo], MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber(), - " ", // A FAIRE : IMPLEMENTER L'UNITE DU PAS DE TEMPS! + (char*)" ", // A FAIRE : IMPLEMENTER L'UNITE DU PAS DE TEMPS! MED_FIELD_DRIVER<T>::_ptrField->getTime(), MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber() ); @@ -1944,7 +2245,7 @@ template <class T> void MED_FIELD_WRONLY_DRIVER22<T>::write(void) const if ( !isFullInterlace ) delete myField; - END_OF(LOC); + END_OF_MED(LOC); } /*--------------------- RDWR PART -------------------------------*/ @@ -1957,17 +2258,19 @@ template <class T> GENDRIVER * MED_FIELD_RDWR_DRIVER22<T>::copy(void) const template <class T> void MED_FIELD_RDWR_DRIVER22<T>::write(void) const throw (MEDEXCEPTION) { - BEGIN_OF("MED_FIELD_RDWR_DRIVER22::write(void)"); + const char* LOC = "MED_FIELD_RDWR_DRIVER22::write(void)"; + BEGIN_OF_MED(LOC); MED_FIELD_WRONLY_DRIVER22<T>::write(); - END_OF("MED_FIELD_RDWR_DRIVER22::write(void)"); + END_OF_MED(LOC); } template <class T> void MED_FIELD_RDWR_DRIVER22<T>::read (void) throw (MEDEXCEPTION) { - BEGIN_OF("MED_FIELD_RDWR_DRIVER22::read(void)"); + const char* LOC = "MED_FIELD_RDWR_DRIVER22::read(void)"; + BEGIN_OF_MED(LOC); MED_FIELD_RDONLY_DRIVER22<T>::read(); - END_OF("MED_FIELD_RDWR_DRIVER22::read(void)"); + END_OF_MED(LOC); } } //End namespace MEDMEM diff --git a/src/MEDMEM/MEDMEM_MedMedDriver.cxx b/src/MEDMEM/MEDMEM_MedMedDriver.cxx index b85952ebf..d142c59b3 100644 --- a/src/MEDMEM/MEDMEM_MedMedDriver.cxx +++ b/src/MEDMEM/MEDMEM_MedMedDriver.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_MedMedDriver.hxx" #include "MEDMEM_Compatibility21_22.hxx" @@ -28,14 +30,15 @@ using namespace std; using namespace MED_EN; using namespace MEDMEM; -MED_MED_DRIVER::MED_MED_DRIVER(): GENDRIVER(), - _ptrMed((MED * const)MED_NULL), - _concreteMedDrv((GENDRIVER *) MED_NULL) +MED_MED_DRIVER::MED_MED_DRIVER(): GENDRIVER(MED_DRIVER), + _ptrMed(0), + _concreteMedDrv(0) {} MED_MED_DRIVER::MED_MED_DRIVER(const string & fileName, MED * const ptrMed): - GENDRIVER(fileName,MED_EN::MED_RDWR), _ptrMed(ptrMed), - _concreteMedDrv((GENDRIVER *) MED_NULL) + GENDRIVER(fileName, MED_EN::RDWR, MED_DRIVER), + _ptrMed(ptrMed), + _concreteMedDrv(0) { //_ptrMed->addDriver(*this); // The specific MED driver id is set within the addDriver method. } @@ -43,23 +46,29 @@ MED_MED_DRIVER::MED_MED_DRIVER(const string & fileName, MED * const ptrMed): MED_MED_DRIVER::MED_MED_DRIVER(const string & fileName, MED * const ptrMed, MED_EN::med_mode_acces accessMode): - GENDRIVER(fileName,accessMode), _ptrMed(ptrMed), - _concreteMedDrv((GENDRIVER *) MED_NULL) + GENDRIVER(fileName, accessMode, MED_DRIVER), + _ptrMed(ptrMed), + _concreteMedDrv(0) { } //REM : As t'on besoin du champ _status : _medIdt <-> _status ? Oui MED_MED_DRIVER::MED_MED_DRIVER(const MED_MED_DRIVER & driver): GENDRIVER(driver), - _ptrMed(driver._ptrMed), - _concreteMedDrv(driver._concreteMedDrv->copy()) + _ptrMed(driver._ptrMed) + // _concreteMedDrv(driver._concreteMedDrv->copy()) { + if ( driver._concreteMedDrv ) + _concreteMedDrv = driver._concreteMedDrv->copy(); + else + _concreteMedDrv=0; } MED_MED_DRIVER::~MED_MED_DRIVER() { - MESSAGE("MED_MED_DRIVER::~MED_MED_DRIVER() has been destroyed"); + MESSAGE_MED("MED_MED_DRIVER::~MED_MED_DRIVER() has been destroyed"); if (_concreteMedDrv) delete _concreteMedDrv; + _concreteMedDrv=0; } // ------------- Read Only Part -------------- @@ -69,9 +78,9 @@ IMED_MED_RDONLY_DRIVER::IMED_MED_RDONLY_DRIVER():MED_MED_DRIVER(),_fileStructIsR } IMED_MED_RDONLY_DRIVER::IMED_MED_RDONLY_DRIVER(const string & fileName, MED * const ptrMed): - MED_MED_DRIVER(fileName,ptrMed,MED_EN::MED_RDONLY),_fileStructIsRead(false) + MED_MED_DRIVER(fileName,ptrMed,MED_EN::RDONLY),_fileStructIsRead(false) { - MESSAGE("MED_MED_RDONLY_DRIVER::MED_MED_RDONLY_DRIVER(const string & fileName, MED * const ptrMed) Constructeur read only"); + MESSAGE_MED("MED_MED_RDONLY_DRIVER::MED_MED_RDONLY_DRIVER(const string & fileName, MED * const ptrMed) Constructeur read only"); } IMED_MED_RDONLY_DRIVER::IMED_MED_RDONLY_DRIVER(const IMED_MED_RDONLY_DRIVER & driver): @@ -81,7 +90,7 @@ IMED_MED_RDONLY_DRIVER::IMED_MED_RDONLY_DRIVER(const IMED_MED_RDONLY_DRIVER & dr IMED_MED_RDONLY_DRIVER::~IMED_MED_RDONLY_DRIVER() { - MESSAGE("MED_MED_RDONLY_DRIVER::~MED_MED_RDONLY_DRIVER() has been destroyed"); + MESSAGE_MED("MED_MED_RDONLY_DRIVER::~MED_MED_RDONLY_DRIVER() has been destroyed"); } void IMED_MED_RDONLY_DRIVER::write(void) const @@ -103,7 +112,7 @@ IMED_MED_WRONLY_DRIVER::IMED_MED_WRONLY_DRIVER() } IMED_MED_WRONLY_DRIVER::IMED_MED_WRONLY_DRIVER(const string & fileName, MED * const ptrMed): - MED_MED_DRIVER(fileName,ptrMed,MED_EN::MED_ECRI) + MED_MED_DRIVER(fileName,ptrMed,MED_EN::WRONLY) {} IMED_MED_WRONLY_DRIVER::IMED_MED_WRONLY_DRIVER(const IMED_MED_WRONLY_DRIVER & driver): @@ -112,7 +121,7 @@ IMED_MED_WRONLY_DRIVER::IMED_MED_WRONLY_DRIVER(const IMED_MED_WRONLY_DRIVER & dr IMED_MED_WRONLY_DRIVER::~IMED_MED_WRONLY_DRIVER() { - MESSAGE("MED_MED_WRONLY_DRIVER::~MED_MED_WRONLY_DRIVER() has been destroyed"); + MESSAGE_MED("MED_MED_WRONLY_DRIVER::~MED_MED_WRONLY_DRIVER() has been destroyed"); } void IMED_MED_WRONLY_DRIVER::read(void) @@ -133,7 +142,7 @@ IMED_MED_RDWR_DRIVER::IMED_MED_RDWR_DRIVER() {} IMED_MED_RDWR_DRIVER::IMED_MED_RDWR_DRIVER(const string & fileName, MED * const ptrMed): - IMED_MED_RDONLY_DRIVER(fileName,ptrMed),IMED_MED_WRONLY_DRIVER(fileName,ptrMed),MED_MED_DRIVER(fileName,ptrMed,MED_REMP) + IMED_MED_RDONLY_DRIVER(fileName,ptrMed),IMED_MED_WRONLY_DRIVER(fileName,ptrMed),MED_MED_DRIVER(fileName,ptrMed,RDWR) {} IMED_MED_RDWR_DRIVER::IMED_MED_RDWR_DRIVER(const IMED_MED_RDWR_DRIVER & driver): @@ -141,18 +150,18 @@ IMED_MED_RDWR_DRIVER::IMED_MED_RDWR_DRIVER(const IMED_MED_RDWR_DRIVER & driver): {} IMED_MED_RDWR_DRIVER::~IMED_MED_RDWR_DRIVER() { - MESSAGE("MED_MED_RDWR_DRIVER::~MED_MED_RDWR_DRIVER() has been destroyed"); + MESSAGE_MED("MED_MED_RDWR_DRIVER::~MED_MED_RDWR_DRIVER() has been destroyed"); } MED_MED_RDONLY_DRIVER::MED_MED_RDONLY_DRIVER() { - MESSAGE("You are using the default constructor of the Med read only Driver and it is 2.1 one"); + MESSAGE_MED("You are using the default constructor of the Med read only Driver and it is 2.1 one"); _concreteMedDrv = new MED_MED_RDONLY_DRIVER21(); } -MED_MED_RDONLY_DRIVER::MED_MED_RDONLY_DRIVER(const string & fileName, MED * const ptrMed):IMED_MED_RDONLY_DRIVER(fileName,ptrMed),MED_MED_DRIVER(fileName,ptrMed,MED_LECT) +MED_MED_RDONLY_DRIVER::MED_MED_RDONLY_DRIVER(const string & fileName, MED * const ptrMed):IMED_MED_RDONLY_DRIVER(fileName,ptrMed),MED_MED_DRIVER(fileName,ptrMed,RDONLY) { - _concreteMedDrv = DRIVERFACTORY::buildMedDriverFromFile(fileName,ptrMed,MED_LECT); + _concreteMedDrv = DRIVERFACTORY::buildMedDriverFromFile(fileName,ptrMed,RDONLY); } MED_MED_RDONLY_DRIVER::MED_MED_RDONLY_DRIVER(const MED_MED_RDONLY_DRIVER & driver):MED_MED_DRIVER(driver) @@ -199,14 +208,14 @@ GENDRIVER * MED_MED_RDONLY_DRIVER::copy ( void ) const MED_MED_WRONLY_DRIVER::MED_MED_WRONLY_DRIVER() { - MESSAGE("You are using the default constructor of the Med write only Driver and it is 2.1 one"); + MESSAGE_MED("You are using the default constructor of the Med write only Driver and it is 2.1 one"); _concreteMedDrv = new MED_MED_WRONLY_DRIVER21(); } -MED_MED_WRONLY_DRIVER::MED_MED_WRONLY_DRIVER(const string & fileName, MED * const ptrMed):IMED_MED_WRONLY_DRIVER(fileName,ptrMed),MED_MED_DRIVER(fileName,ptrMed,MED_ECRI) +MED_MED_WRONLY_DRIVER::MED_MED_WRONLY_DRIVER(const string & fileName, MED * const ptrMed):IMED_MED_WRONLY_DRIVER(fileName,ptrMed),MED_MED_DRIVER(fileName,ptrMed,WRONLY) { - _concreteMedDrv = DRIVERFACTORY::buildMedDriverFromFile(fileName,ptrMed,MED_ECRI); + _concreteMedDrv = DRIVERFACTORY::buildMedDriverFromFile(fileName,ptrMed,WRONLY); } MED_MED_WRONLY_DRIVER::MED_MED_WRONLY_DRIVER(const MED_MED_WRONLY_DRIVER & driver):MED_MED_DRIVER(driver) @@ -254,13 +263,13 @@ GENDRIVER * MED_MED_WRONLY_DRIVER::copy ( void ) const MED_MED_RDWR_DRIVER::MED_MED_RDWR_DRIVER() { - MESSAGE("You are using the default constructor of the Med read write Driver and it is 2.1 one"); + MESSAGE_MED("You are using the default constructor of the Med read write Driver and it is 2.1 one"); _concreteMedDrv = new MED_MED_RDWR_DRIVER21(); } -MED_MED_RDWR_DRIVER::MED_MED_RDWR_DRIVER(const string & fileName, MED * const ptrMed):IMED_MED_RDWR_DRIVER(fileName,ptrMed),MED_MED_DRIVER(fileName,ptrMed,MED_REMP) +MED_MED_RDWR_DRIVER::MED_MED_RDWR_DRIVER(const string & fileName, MED * const ptrMed):IMED_MED_RDWR_DRIVER(fileName,ptrMed),MED_MED_DRIVER(fileName,ptrMed,RDWR) { - _concreteMedDrv = DRIVERFACTORY::buildMedDriverFromFile(fileName,ptrMed,MED_REMP); + _concreteMedDrv = DRIVERFACTORY::buildMedDriverFromFile(fileName,ptrMed,RDWR); } MED_MED_RDWR_DRIVER::MED_MED_RDWR_DRIVER(const MED_MED_RDWR_DRIVER & driver): diff --git a/src/MEDMEM/MEDMEM_MedMedDriver.hxx b/src/MEDMEM/MEDMEM_MedMedDriver.hxx index 007d1fa91..a77b2fe03 100644 --- a/src/MEDMEM/MEDMEM_MedMedDriver.hxx +++ b/src/MEDMEM/MEDMEM_MedMedDriver.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef MED_MED_DRIVER_HXX #define MED_MED_DRIVER_HXX @@ -82,6 +84,7 @@ public : virtual void writeFrom ( void ) const = 0 ; virtual void read ( void ) = 0 ; virtual void readFileStruct ( void ) = 0 ; + virtual void setFileName ( const string & fileName) {_concreteMedDrv->setFileName(fileName); } protected: virtual GENDRIVER * copy ( void ) const = 0 ; diff --git a/src/MEDMEM/MEDMEM_MedMedDriver21.cxx b/src/MEDMEM/MEDMEM_MedMedDriver21.cxx index 4ec9be490..84481dde3 100644 --- a/src/MEDMEM/MEDMEM_MedMedDriver21.cxx +++ b/src/MEDMEM/MEDMEM_MedMedDriver21.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_Compatibility21_22.hxx" #include "MEDMEM_MedMedDriver21.hxx" @@ -60,7 +62,7 @@ MED_MED_DRIVER21::MED_MED_DRIVER21(const MED_MED_DRIVER21 & driver): MED_MED_DRIVER21::~MED_MED_DRIVER21() { - MESSAGE("MED_MED_DRIVER21::~MED_MED_DRIVER21() has been destroyed"); + MESSAGE_MED("MED_MED_DRIVER21::~MED_MED_DRIVER21() has been destroyed"); } void MED_MED_DRIVER21::read() @@ -85,7 +87,7 @@ void MED_MED_DRIVER21::open() { const char * LOC ="MED_MED_DRIVER21::open() : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // REFLECHIR SUR CE TEST PAR RAPPORT A L'OUVERTURE/FERMETURE // if ( _medIdt != MED_INVALID ) @@ -108,9 +110,9 @@ void MED_MED_DRIVER21::open() ) ); int accessMode = getMedAccessMode( _accessMode, MED_EN::V21 ); - MESSAGE(LOC<<"_fileName.c_str : "<< _fileName.c_str()<<",mode : "<< accessMode); + MESSAGE_MED(LOC<<"_fileName.c_str : "<< _fileName.c_str()<<",mode : "<< accessMode); _medIdt = med_2_1::MEDouvrir( (const_cast <char *> (_fileName.c_str())), (med_2_1::med_mode_acces) accessMode); - MESSAGE(LOC<<" _medIdt = "<<_medIdt); + MESSAGE_MED(LOC<<" _medIdt = "<<_medIdt); if (_medIdt > 0) _status=MED_OPENED; @@ -124,14 +126,15 @@ void MED_MED_DRIVER21::open() ); } - END_OF(LOC); + END_OF_MED(LOC); } void MED_MED_DRIVER21::close() { med_2_1::med_int err = 0; - const char * LOC = "MED_MED_DRIVER21::close() : "; + const char* LOC = "MED_MED_DRIVER21::close() : "; + BEGIN_OF_MED(LOC); // if ( _status == MED_CLOSED) @@ -158,7 +161,7 @@ void MED_MED_DRIVER21::close() _status = MED_CLOSED; _medIdt = MED_INVALID; - END_OF(LOC); + END_OF_MED(LOC); } @@ -166,12 +169,15 @@ void MED_MED_DRIVER21::close() MED_MED_RDONLY_DRIVER21::MED_MED_RDONLY_DRIVER21() { + this->GENDRIVER::_accessMode = MED_EN::RDONLY; } MED_MED_RDONLY_DRIVER21::MED_MED_RDONLY_DRIVER21(const string & fileName, MED * const ptrMed): - IMED_MED_RDONLY_DRIVER(fileName,ptrMed),MED_MED_DRIVER21(fileName,ptrMed,MED_EN::MED_RDONLY),MED_MED_DRIVER(fileName,ptrMed,MED_EN::MED_RDONLY) + IMED_MED_RDONLY_DRIVER(fileName,ptrMed), + MED_MED_DRIVER21(fileName,ptrMed,MED_EN::RDONLY), + MED_MED_DRIVER(fileName,ptrMed,MED_EN::RDONLY) { - MESSAGE("MED_MED_RDONLY_DRIVER21::MED_MED_RDONLY_DRIVER21(const string & fileName, MED * const ptrMed) Constructeur read only"); + MESSAGE_MED("MED_MED_RDONLY_DRIVER21::MED_MED_RDONLY_DRIVER21(const string & fileName, MED * const ptrMed) Constructeur read only"); } MED_MED_RDONLY_DRIVER21::MED_MED_RDONLY_DRIVER21(const MED_MED_RDONLY_DRIVER21 & driver): @@ -181,7 +187,7 @@ MED_MED_RDONLY_DRIVER21::MED_MED_RDONLY_DRIVER21(const MED_MED_RDONLY_DRIVER21 & MED_MED_RDONLY_DRIVER21::~MED_MED_RDONLY_DRIVER21() { - MESSAGE("MED_MED_RDONLY_DRIVER21::~MED_MED_RDONLY_DRIVER21() has been destroyed"); + MESSAGE_MED("MED_MED_RDONLY_DRIVER21::~MED_MED_RDONLY_DRIVER21() has been destroyed"); } GENDRIVER * MED_MED_RDONLY_DRIVER21::copy(void) const @@ -211,7 +217,7 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) else IMED_MED_RDONLY_DRIVER::_fileStructIsRead = true; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if ( _medIdt == MED_INVALID ) throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) @@ -230,7 +236,7 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) numberOfMeshes = med_2_1::MEDnMaa(_medIdt) ; if ( numberOfMeshes <= 0 ) - MESSAGE(LOC << "Be careful there is no mesh in file |"<<_fileName<<"| !"); + MESSAGE_MED(LOC << "Be careful there is no mesh in file |"<<_fileName<<"| !"); MESH_ENTITIES::const_iterator currentEntity; for (i=1;i<=numberOfMeshes;i++) { @@ -253,7 +259,7 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) << i <<" of the file |" << _fileName << "| !" ) ); - MESSAGE(LOC<<": Mesh n°"<<i<<" nammed "<<meshName); + MESSAGE_MED(LOC<<": Mesh n°"<<i<<" nammed "<<meshName); if (isAGrid) ptrMesh = new GRID((MED_EN::med_grid_type) type); @@ -285,7 +291,7 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) ptrDriver->setMeshName ( meshName ); ptrMesh->setDescription(meshDescription); - SCRUTE(ptrDriver); + SCRUTE_MED(ptrDriver); ptrMesh->addDriver(*ptrDriver); delete ptrDriver ; @@ -300,9 +306,9 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) // add by B. Secher for filter module ptrMesh->setMeshDimension(meshDim); - SCRUTE(ptrMesh); + SCRUTE_MED(ptrMesh); - MESSAGE(LOC<<"is" << (isAGrid ? "" : " NOT") << " a GRID and its name is "<<ptrMesh->getName()); + MESSAGE_MED(LOC<<"is" << (isAGrid ? "" : " NOT") << " a GRID and its name is "<<ptrMesh->getName()); // we create all global support (for each entity type : int index = 0; @@ -316,10 +322,10 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) mySupport->setEntity((MED_EN::medEntityMesh) (*currentEntity).first); mySupport->setAll(true); (_ptrMed->_support)[meshName][(MED_EN::medEntityMesh)(*currentEntity).first] = mySupport ; - MESSAGE(LOC<< "The support " << supportName.c_str() << " on entity " << (*currentEntity).first << " is built"); + MESSAGE_MED(LOC<< "The support " << supportName.c_str() << " on entity " << (*currentEntity).first << " is built"); index++; } - MESSAGE(LOC <<"The mesh " <<ptrMesh->getName() << " has " << index << " support(s)"); + MESSAGE_MED(LOC <<"The mesh " <<ptrMesh->getName() << " has " << index << " support(s)"); } map<MESH_NAME_, map<MED_EN::medEntityMesh,SUPPORT *> >::const_iterator const_itSupportOnMesh ; @@ -335,7 +341,7 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) const_itSupport!=(*const_itSupportOnMesh).second.end();const_itSupport++) index++; } - MESSAGE(LOC << "In this MED object there is(are) " << index << " support(s):"); + MESSAGE_MED(LOC << "In this MED object there is(are) " << index << " support(s):"); vectSupp.resize(index); @@ -348,8 +354,9 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) const_itSupport!=(*const_itSupportOnMesh).second.end();const_itSupport++) { vectSupp[index] = (*const_itSupport).second; - SCRUTE(vectSupp[index]); - MESSAGE(LOC << "Support number " << index << " is "<< *vectSupp[index]); + SCRUTE_MED(vectSupp[index]); + // comment the next line for PAL19767 Modification for icc and icpc (INTEL compilators) + //MESSAGE_MED(STRING(LOC) << "Support number " << index << " is "<< *vectSupp[index])); index++; } } @@ -391,7 +398,7 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) numberOfFields = med_2_1::MEDnChamp(_medIdt,0) ; if ( numberOfFields <= 0 ) - MESSAGE(LOC << "Be careful there is no field in file |"<<_fileName<<"| !"); + MESSAGE_MED(LOC << "Be careful there is no field in file |"<<_fileName<<"| !"); for (i=1;i<=numberOfFields;i++) { @@ -412,7 +419,7 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) << ": can't get information about the field n°" << i <<" of the file |" << _fileName << "| !")); - MESSAGE(LOC << "Field n°"<<i<<" nammed "<< fieldName + MESSAGE_MED(LOC << "Field n°"<<i<<" nammed "<< fieldName << " ,component(s) : " << componentName <<" ,unit(s) : " << unitName); @@ -424,11 +431,11 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) for (currentEntity=meshEntities.begin();currentEntity != meshEntities.end(); currentEntity++) { // numberOfTimeSteps MUST be given by MEDchampInfo !!!!! for (currentGeometry = (*currentEntity).second.begin();currentGeometry != (*currentEntity).second.end(); currentGeometry++) { - MESSAGE("Field information with Entity,Geom = "<<(*currentEntity).first<<","<<(*currentGeometry)); + MESSAGE_MED("Field information with Entity,Geom = "<<(*currentEntity).first<<","<<(*currentGeometry)); numberOfTimeSteps = MEDnPasdetemps(_medIdt, fieldName, (med_2_1::med_entite_maillage)(*currentEntity).first, (med_2_1::med_geometrie_element) (*currentGeometry) ); - MESSAGE("Field information 2 : NumberOfTimeStep :"<<numberOfTimeSteps); + MESSAGE_MED("Field information 2 : NumberOfTimeStep :"<<numberOfTimeSteps); if ( numberOfTimeSteps > MED_VALID ) break ; // There are value for some med_geometrie_element of this med_entite_maillage. } @@ -436,10 +443,10 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) for (currentGeometry = (*currentEntity).second.begin();currentGeometry != (*currentEntity).second.end(); currentGeometry++) { - MESSAGE("Field information 3 : Geom : "<<(*currentGeometry)); + MESSAGE_MED("Field information 3 : Geom : "<<(*currentGeometry)); for (j=1;j <= numberOfTimeSteps; j++) { - MESSAGE("Field information 4 : time step j = "<<j); + MESSAGE_MED("Field information 4 : time step j = "<<j); err = MEDpasdetempsInfo( _medIdt, fieldName, (med_2_1::med_entite_maillage) (*currentEntity).first, (med_2_1::med_geometrie_element) (*currentGeometry),j, @@ -448,7 +455,7 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) &orderNumber); if (err == MED_VALID) { // we have found for (*currentEntity).first and (*currentGeometry) - MESSAGE("Field information 5 ;: NumberOfGaussPoint : "<<NbOfGaussPts<<", timeStepNumber : "<<timeStepNumber); + MESSAGE_MED("Field information 5 ;: NumberOfGaussPoint : "<<NbOfGaussPts<<", timeStepNumber : "<<timeStepNumber); // CORRECT a bug in MEDpasdetempsInfo : // we get a value n'importe quoi in NbOfGaussPts !!!! @@ -471,14 +478,14 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) map<MESH_NAME_,MESH*>::iterator _meshesIt = _meshes.find(meshName); if ( _meshesIt == _meshes.end() ) { - MESSAGE(LOC << "There is no mesh |" + MESSAGE_MED(LOC << "There is no mesh |" << meshName <<"| in the file |" << _fileName <<"|, but |" << meshName <<"| is referenced by field |" << fieldName <<"|, entity : |" << entNames [(*currentEntity).first] <<"|, geometric element of type |" << geoNames [(*currentGeometry)] <<"|" ); - } // POURQUOI SI JE NE MET PAS DE BLOCK J'AI UN PARSE ERROR : PG : c'est la macro MESSAGE qui fait ca ! + } // POURQUOI SI JE NE MET PAS DE BLOCK J'AI UN PARSE ERROR : PG : c'est la macro MESSAGE_MED qui fait ca ! else ptrMesh = _meshes[meshName]; @@ -512,7 +519,7 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) ((FIELD<int>*) ptrField)->setSupport(ptrSupport); ((FIELD<int>*) ptrField)->setNumberOfComponents(numberOfComponents); ((FIELD<int>*) ptrField)->setName(fieldName) ; //provisoire, pour debug - MESSAGE("#### SET NAME in FIELD : "<<fieldName); + MESSAGE_MED("#### SET NAME in FIELD : "<<fieldName); MED_EN::med_mode_acces myMode = getAccessMode(); // switch (myMode) { @@ -531,7 +538,7 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) ptrDriver = DRIVERFACTORY::buildConcreteMedDriverForField<int>(_fileName, (FIELD<int> *)ptrField, myMode, V21); - SCRUTE(ptrDriver); + SCRUTE_MED(ptrDriver); break; } @@ -541,7 +548,7 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) ((FIELD<med_2_1::med_float>*) ptrField)->setSupport(ptrSupport); ((FIELD<med_2_1::med_float>*) ptrField)->setNumberOfComponents(numberOfComponents); ((FIELD<med_2_1::med_float>*) ptrField)->setName(fieldName) ; //provisoire, pour debug - MESSAGE("#### SET NAME in FIELD : "<<fieldName); + MESSAGE_MED("#### SET NAME in FIELD : "<<fieldName); MED_EN::med_mode_acces myMode = getAccessMode(); // switch (myMode) { @@ -559,7 +566,7 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) // } ptrDriver = DRIVERFACTORY::buildConcreteMedDriverForField<med_2_1::med_float>(_fileName, (FIELD<med_2_1::med_float> *)ptrField, myMode, V21); - SCRUTE(ptrDriver); + SCRUTE_MED(ptrDriver); break; } @@ -578,14 +585,14 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) } } - MESSAGE("timeStepNumber :"<<timeStepNumber<<",orderNumber :"<<orderNumber); + MESSAGE_MED("timeStepNumber :"<<timeStepNumber<<",orderNumber :"<<orderNumber); ptrField->setIterationNumber ( timeStepNumber); // A ajouter dans la classe FIELD ptrField->setOrderNumber ( orderNumber); ptrField->setTime ( timeStep); // Create a driver for this (field n°dt,n°it) ptrDriver->setId ( getId() ); - MESSAGE("###### ptrDriver->setFieldName : #"<<fieldName<<"#"); + MESSAGE_MED("###### ptrDriver->setFieldName : #"<<fieldName<<"#"); ptrDriver->setFieldName(fieldName); ptrField->addDriver(*ptrDriver); // driver is duplicated : remove it @@ -611,7 +618,7 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) // il faut lire les champs pour avoir les profils stockes !!! // il faudrait implémenter la lecture des profils dans med !!! - END_OF(LOC); + END_OF_MED(LOC); } @@ -620,9 +627,8 @@ void MED_MED_RDONLY_DRIVER21::readFileStruct( void ) void MED_MED_RDONLY_DRIVER21::read( void ) throw (MEDEXCEPTION) // from objects method read ! { - const char * LOC = "MED_MED_DRIVER21::read() : "; - - BEGIN_OF(LOC); + const char* LOC = "MED_MED_DRIVER21::read() : "; + BEGIN_OF_MED(LOC); // For PAL12192: assure that file structure is already read this->open(); @@ -646,17 +652,20 @@ void MED_MED_RDONLY_DRIVER21::read( void ) (*currentField).first->read(*this); //(*currentField).first->read(); // default reader, from readFileStruct - END_OF(LOC); + END_OF_MED(LOC); } // ------------- Write Only Part -------------- MED_MED_WRONLY_DRIVER21::MED_MED_WRONLY_DRIVER21() { + this->GENDRIVER::_accessMode = MED_EN::WRONLY; } MED_MED_WRONLY_DRIVER21::MED_MED_WRONLY_DRIVER21(const string & fileName, MED * const ptrMed): - IMED_MED_WRONLY_DRIVER(fileName,ptrMed),MED_MED_DRIVER21(fileName,ptrMed),MED_MED_DRIVER(fileName,ptrMed,MED_EN::MED_WRONLY) + IMED_MED_WRONLY_DRIVER(fileName,ptrMed), + MED_MED_DRIVER21(fileName,ptrMed), + MED_MED_DRIVER(fileName,ptrMed,MED_EN::WRONLY) {} MED_MED_WRONLY_DRIVER21::MED_MED_WRONLY_DRIVER21(const MED_MED_WRONLY_DRIVER21 & driver): @@ -665,7 +674,7 @@ MED_MED_WRONLY_DRIVER21::MED_MED_WRONLY_DRIVER21(const MED_MED_WRONLY_DRIVER21 & MED_MED_WRONLY_DRIVER21::~MED_MED_WRONLY_DRIVER21() { - MESSAGE("MED_MED_WRONLY_DRIVER21::~MED_MED_WRONLY_DRIVER21() has been destroyed"); + MESSAGE_MED("MED_MED_WRONLY_DRIVER21::~MED_MED_WRONLY_DRIVER21() has been destroyed"); } GENDRIVER * MED_MED_WRONLY_DRIVER21::copy(void) const @@ -688,9 +697,8 @@ void MED_MED_WRONLY_DRIVER21::readFileStruct ( void ) throw (MEDEXCEPTION) void MED_MED_WRONLY_DRIVER21::writeFrom( void) const throw (MEDEXCEPTION) //from object method write ! { - const char * LOC = "MED_MED_DRIVER21::writeFrom() : "; - - BEGIN_OF(LOC); + const char* LOC = "MED_MED_DRIVER21::writeFrom() : "; + BEGIN_OF_MED(LOC); const map<MESH_NAME_, MESH*> & _meshes = const_cast<const map<MESH_NAME_, MESH*>& > (_ptrMed->_meshes); map<MESH_NAME_,MESH*>::const_iterator currentMesh; @@ -717,17 +725,16 @@ void MED_MED_WRONLY_DRIVER21::writeFrom( void) const } } - END_OF(LOC); + END_OF_MED(LOC); } void MED_MED_WRONLY_DRIVER21::write(void ) const throw (MEDEXCEPTION) // from object method write ! { - const char * LOC = "MED_MED_DRIVER21::write() : "; int current; - - BEGIN_OF(LOC); + const char* LOC = "MED_MED_DRIVER21::write() : "; + BEGIN_OF_MED(LOC); // BCLE SUR LES OBJETS AVEC AJOUT DE DRIVER ET APPELS write @@ -756,23 +763,25 @@ void MED_MED_WRONLY_DRIVER21::write(void ) const // that's work, but it is more efficenty to write directly when we had driver, no ? // writeFrom(); - END_OF(LOC); + END_OF_MED(LOC); } // ------------- Read Write Part -------------- MED_MED_RDWR_DRIVER21::MED_MED_RDWR_DRIVER21() -{} +{ + this->GENDRIVER::_accessMode = MED_EN::RDWR; +} MED_MED_RDWR_DRIVER21::MED_MED_RDWR_DRIVER21(const string & fileName, MED * const ptrMed): MED_MED_RDONLY_DRIVER21(fileName,ptrMed), MED_MED_WRONLY_DRIVER21(fileName,ptrMed), IMED_MED_RDWR_DRIVER(fileName,ptrMed), - MED_MED_DRIVER21(fileName,ptrMed,MED_REMP), + MED_MED_DRIVER21(fileName,ptrMed,RDWR), IMED_MED_WRONLY_DRIVER(fileName,ptrMed), IMED_MED_RDONLY_DRIVER(fileName,ptrMed), - MED_MED_DRIVER(fileName,ptrMed,MED_REMP) + MED_MED_DRIVER(fileName,ptrMed,RDWR) {} MED_MED_RDWR_DRIVER21::MED_MED_RDWR_DRIVER21(const MED_MED_RDWR_DRIVER21 & driver): @@ -786,7 +795,7 @@ MED_MED_RDWR_DRIVER21::MED_MED_RDWR_DRIVER21(const MED_MED_RDWR_DRIVER21 & drive {} MED_MED_RDWR_DRIVER21::~MED_MED_RDWR_DRIVER21() { - MESSAGE("MED_MED_RDWR_DRIVER21::~MED_MED_RDWR_DRIVER21() has been destroyed"); + MESSAGE_MED("MED_MED_RDWR_DRIVER21::~MED_MED_RDWR_DRIVER21() has been destroyed"); } GENDRIVER * MED_MED_RDWR_DRIVER21::copy(void) const @@ -797,31 +806,35 @@ GENDRIVER * MED_MED_RDWR_DRIVER21::copy(void) const void MED_MED_RDWR_DRIVER21::read(void) throw (MEDEXCEPTION) // from MED_MED_RDONLY_DRIVER::read() { - BEGIN_OF("MED_MED_RDWR_DRIVER21::read(void)"); + const char* LOC = "MED_MED_RDWR_DRIVER21::read(void)"; + BEGIN_OF_MED(LOC); MED_MED_RDONLY_DRIVER21::read(); - END_OF("MED_MED_RDWR_DRIVER21::read(void)"); + END_OF_MED(LOC); } void MED_MED_RDWR_DRIVER21::readFileStruct(void) throw (MEDEXCEPTION) // from MED_MED_RDONLY_DRIVER::readFileStruct() { - BEGIN_OF("MED_MED_RDWR_DRIVER21::readFileStruct(void)"); + const char* LOC = "MED_MED_RDWR_DRIVER21::readFileStruct(void)"; + BEGIN_OF_MED(LOC); MED_MED_RDONLY_DRIVER21::readFileStruct(); - END_OF("MED_MED_RDWR_DRIVER21::readFileStruct(void)"); + END_OF_MED(LOC); } void MED_MED_RDWR_DRIVER21::write(void) const throw (MEDEXCEPTION) // from MED_MED_WRONLY_DRIVER::write() { - BEGIN_OF("MED_MED_RDWR_DRIVER21::write(void) const"); + const char* LOC = "MED_MED_RDWR_DRIVER21::write(void) const"; + BEGIN_OF_MED(LOC); MED_MED_WRONLY_DRIVER21::write(); - END_OF("MED_MED_RDWR_DRIVER21::write(void) const"); + END_OF_MED(LOC); } void MED_MED_RDWR_DRIVER21::writeFrom(void) const throw (MEDEXCEPTION) // from MED_MED_WRONLY_DRIVER::writeFrom(); { - BEGIN_OF("MED_MED_RDWR_DRIVER21::writeFrom(void) const"); + const char* LOC = "MED_MED_RDWR_DRIVER21::writeFrom(void) const"; + BEGIN_OF_MED(LOC); MED_MED_WRONLY_DRIVER21::writeFrom(); - END_OF("MED_MED_RDWR_DRIVER21::writeFrom(void) const"); + END_OF_MED(LOC); } diff --git a/src/MEDMEM/MEDMEM_MedMedDriver21.hxx b/src/MEDMEM/MEDMEM_MedMedDriver21.hxx index 68081c898..a801dacc0 100644 --- a/src/MEDMEM/MEDMEM_MedMedDriver21.hxx +++ b/src/MEDMEM/MEDMEM_MedMedDriver21.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef MED_MED_DRIVER21_HXX #define MED_MED_DRIVER21_HXX diff --git a/src/MEDMEM/MEDMEM_MedMedDriver22.cxx b/src/MEDMEM/MEDMEM_MedMedDriver22.cxx index c039eeaf6..5ecd9b118 100644 --- a/src/MEDMEM/MEDMEM_MedMedDriver22.cxx +++ b/src/MEDMEM/MEDMEM_MedMedDriver22.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_Compatibility21_22.hxx" # include "MEDMEM_MedMedDriver22.hxx" @@ -58,7 +60,7 @@ MED_MED_DRIVER22::MED_MED_DRIVER22(const MED_MED_DRIVER22 & driver): MED_MED_DRIVER22::~MED_MED_DRIVER22() { - MESSAGE("MED_MED_DRIVER22::~MED_MED_DRIVER22() has been destroyed"); + MESSAGE_MED("MED_MED_DRIVER22::~MED_MED_DRIVER22() has been destroyed"); } // GENDRIVER * MED_MED_DRIVER::copy(void) const @@ -89,7 +91,7 @@ void MED_MED_DRIVER22::open() { const char * LOC ="MED_MED_DRIVER22::open() : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // REFLECHIR SUR CE TEST PAR RAPPORT A L'OUVERTURE/FERMETURE // if ( _medIdt != MED_INVALID ) @@ -113,10 +115,10 @@ void MED_MED_DRIVER22::open() ); int accessMode = getMedAccessMode( _accessMode, MED_EN::V22 ); - MESSAGE(LOC<<"_fileName.c_str : "<< _fileName.c_str()<<",mode : "<< accessMode); + MESSAGE_MED(LOC<<"_fileName.c_str : "<< _fileName.c_str()<<",mode : "<< accessMode); _medIdt = med_2_3::MEDouvrir( (const_cast <char *> (_fileName.c_str())), (med_2_3::med_mode_acces) accessMode); - MESSAGE(LOC<<" _medIdt = "<<_medIdt); + MESSAGE_MED(LOC<<" _medIdt = "<<_medIdt); if (_medIdt > 0) _status=MED_OPENED; @@ -130,14 +132,13 @@ void MED_MED_DRIVER22::open() ); } - END_OF(LOC); + END_OF_MED(LOC); } void MED_MED_DRIVER22::close() { med_2_3::med_int err = 0; - const char * LOC = "MED_MED_DRIVER22::close() : "; // if ( _status == MED_CLOSED) @@ -164,7 +165,7 @@ void MED_MED_DRIVER22::close() _status = MED_CLOSED; _medIdt = MED_INVALID; - END_OF(LOC); + //END_OF_MED(); } @@ -172,12 +173,15 @@ void MED_MED_DRIVER22::close() MED_MED_RDONLY_DRIVER22::MED_MED_RDONLY_DRIVER22() { + this->GENDRIVER::_accessMode = MED_EN::RDONLY; } MED_MED_RDONLY_DRIVER22::MED_MED_RDONLY_DRIVER22(const string & fileName, MED * const ptrMed): - IMED_MED_RDONLY_DRIVER(fileName,ptrMed),MED_MED_DRIVER22(fileName,ptrMed,MED_EN::MED_RDONLY),MED_MED_DRIVER(fileName,ptrMed,MED_EN::MED_RDONLY) + IMED_MED_RDONLY_DRIVER(fileName,ptrMed), + MED_MED_DRIVER22(fileName,ptrMed,MED_EN::RDONLY), + MED_MED_DRIVER(fileName,ptrMed,MED_EN::RDONLY) { - MESSAGE("MED_MED_RDONLY_DRIVER22::MED_MED_RDONLY_DRIVER22(const string & fileName, MED * const ptrMed) Constructeur read only"); + MESSAGE_MED("MED_MED_RDONLY_DRIVER22::MED_MED_RDONLY_DRIVER22(const string & fileName, MED * const ptrMed) Constructeur read only"); } MED_MED_RDONLY_DRIVER22::MED_MED_RDONLY_DRIVER22(const MED_MED_RDONLY_DRIVER22 & driver): @@ -187,7 +191,7 @@ MED_MED_RDONLY_DRIVER22::MED_MED_RDONLY_DRIVER22(const MED_MED_RDONLY_DRIVER22 & MED_MED_RDONLY_DRIVER22::~MED_MED_RDONLY_DRIVER22() { - MESSAGE("MED_MED_RDONLY_DRIVER22::~MED_MED_RDONLY_DRIVER22() has been destroyed"); + MESSAGE_MED("MED_MED_RDONLY_DRIVER22::~MED_MED_RDONLY_DRIVER22() has been destroyed"); } GENDRIVER * MED_MED_RDONLY_DRIVER22::copy(void) const @@ -217,7 +221,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) else IMED_MED_RDONLY_DRIVER::_fileStructIsRead = true; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if ( _medIdt == MED_INVALID ) throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) @@ -239,7 +243,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) numberOfMeshes = med_2_3::MEDnMaa(_medIdt) ; if ( numberOfMeshes <= 0 ) - MESSAGE(LOC << "Be careful there is no mesh in file |"<<_fileName<<"| !"); + MESSAGE_MED(LOC << "Be careful there is no mesh in file |"<<_fileName<<"| !"); MESH_ENTITIES::const_iterator currentEntity; for (i=1;i<=numberOfMeshes;i++) @@ -255,7 +259,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) switch (meshType) { case med_2_3::MED_STRUCTURE: - MESSAGE(LOC<<": Mesh n°"<< i <<" nammed "<< meshName << " with the description " << meshDescription << " is structured"); + MESSAGE_MED(LOC<<": Mesh n°"<< i <<" nammed "<< meshName << " with the description " << meshDescription << " is structured"); med_2_3::med_type_grille type; @@ -267,7 +271,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) ptrMesh = new GRID((MED_EN::med_grid_type) type); break; case med_2_3::MED_NON_STRUCTURE: - MESSAGE(LOC<<": Mesh n°"<< i <<" nammed "<< meshName << " with the description " << meshDescription << " is not structured"); + MESSAGE_MED(LOC<<": Mesh n°"<< i <<" nammed "<< meshName << " with the description " << meshDescription << " is not structured"); ptrMesh = new MESH(); break; @@ -310,16 +314,16 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) // _ptrMed->_meshes[meshName] = ptrMesh; - ptrMesh->setName(meshName); + ptrMesh->setName( healName( meshName )); ptrMesh->setDescription(meshDescription); // add by B. Secher for filter module ptrMesh->setMeshDimension(meshDim); - SCRUTE(ptrMesh); + SCRUTE_MED(ptrMesh); - MESSAGE(LOC<<"is" << (isAGrid ? "" : " NOT") << " a GRID and its name is "<<ptrMesh->getName()); + MESSAGE_MED(LOC<<"is" << (isAGrid ? "" : " NOT") << " a GRID and its name is "<<ptrMesh->getName()); // we create all global support (for each entity type : int index = 0; @@ -332,10 +336,10 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) mySupport->setEntity((MED_EN::medEntityMesh) (*currentEntity).first); mySupport->setAll(true); (_ptrMed->_support)[meshName][(MED_EN::medEntityMesh)(*currentEntity).first] = mySupport ; - MESSAGE(LOC<< "The support " << supportName.c_str() << " on entity " << (*currentEntity).first << " is built"); + MESSAGE_MED(LOC<< "The support " << supportName.c_str() << " on entity " << (*currentEntity).first << " is built"); index++; } - MESSAGE(LOC <<"The mesh " <<ptrMesh->getName() << " has " << index << " support(s)"); + MESSAGE_MED(LOC <<"The mesh " <<ptrMesh->getName() << " has " << index << " support(s)"); } map<MESH_NAME_, map<MED_EN::medEntityMesh,SUPPORT *> >::iterator itSupportOnMesh ; @@ -356,7 +360,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) } } - MESSAGE(LOC << "In this MED object there is(are) " << index << " support(s):"); + MESSAGE_MED(LOC << "In this MED object there is(are) " << index << " support(s):"); vectSupp.resize(index); @@ -371,8 +375,8 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) const_itSupport!=(*const_itSupportOnMesh).second.end();const_itSupport++) { vectSupp[index] = (*const_itSupport).second; - SCRUTE(vectSupp[index]); - MESSAGE(LOC << "Support number " << index << " is "<< *vectSupp[index]); + SCRUTE_MED(vectSupp[index]); + MESSAGE_MED(LOC << "Support number " << index << " is "<< *vectSupp[index]); index++; } } @@ -416,7 +420,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) numberOfFields = med_2_3::MEDnChamp(_medIdt,0) ; if ( numberOfFields <= 0 ) - MESSAGE(LOC << "Be careful there is no field in file |"<< + MESSAGE_MED(LOC << "Be careful there is no field in file |"<< _fileName<<"| !"); for (i=1;i<=numberOfFields;i++) @@ -433,14 +437,14 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) err = MEDchampInfo(_medIdt, i, fieldName, &type, componentName, unitName, numberOfComponents) ; - MESSAGE("Field n°" << i << " nammed " << fieldName << endl + MESSAGE_MED("Field n°" << i << " nammed " << fieldName << endl << "Name real length = " << strlen(fieldName) << ", while reserved " << MED_TAILLE_NOM); if (err != MED_VALID) throw MED_EXCEPTION(LOCALIZED(STRING(LOC) << ": can't get information about the field n°" << i <<" of the file |" << _fileName << "| !")); - MESSAGE(LOC << "Field n°"<<i<<" nammed "<< fieldName + MESSAGE_MED(LOC << "Field n°"<<i<<" nammed "<< fieldName << " ,component(s) : " << componentName <<" ,unit(s) : " << unitName); @@ -458,7 +462,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) currentGeometry != (*currentEntity).second.end(); currentGeometry++) { - MESSAGE("Field information with Entity,Geom = "<< + MESSAGE_MED("Field information with Entity,Geom = "<< (*currentEntity).first<<","<<(*currentGeometry)); numberOfTimeSteps = @@ -466,7 +470,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) (med_2_3::med_entite_maillage)(*currentEntity).first, (med_2_3::med_geometrie_element) (*currentGeometry) ); - MESSAGE("Field information 2 : NumberOfTimeStep :"<< + MESSAGE_MED("Field information 2 : NumberOfTimeStep :"<< numberOfTimeSteps); /* if ( numberOfTimeSteps > MED_VALID ) @@ -480,11 +484,11 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) currentGeometry != (*currentEntity).second.end(); currentGeometry++) {*/ - MESSAGE("Field information 3 : Geom : "<<(*currentGeometry)); + MESSAGE_MED("Field information 3 : Geom : "<<(*currentGeometry)); for (j=1;j <= numberOfTimeSteps; j++) { - MESSAGE("Field information 4 : time step j = "<<j); + MESSAGE_MED("Field information 4 : time step j = "<<j); // err = MEDpasdetempsInfo( _medIdt, fieldName, // (med_2_3::med_entite_maillage) (*currentEntity).first, @@ -505,7 +509,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) if (err == MED_VALID) { // we have found for (*currentEntity).first and // (*currentGeometry) - MESSAGE("Field information 5 ;: NumberOfGaussPoint : " << NbOfGaussPts << ", timeStepNumber : " << timeStepNumber << ", orderNumber : " << orderNumber); + MESSAGE_MED("Field information 5 ;: NumberOfGaussPoint : " << NbOfGaussPts << ", timeStepNumber : " << timeStepNumber << ", orderNumber : " << orderNumber); // CORRECT a bug in MEDpasdetempsInfo : // we get a value n'importe quoi in NbOfGaussPts !!!! @@ -516,7 +520,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) { NbOfGaussPts = 1; numberOfRefMesh=1; - MESSAGE("This field is Med Memory compliant because NumberOfGaussPoint : " << NbOfGaussPts << ", or numberOfRefMesh : " << numberOfRefMesh << ", or meshLink : " << meshLink); + MESSAGE_MED("This field is Med Memory compliant because NumberOfGaussPoint : " << NbOfGaussPts << ", or numberOfRefMesh : " << numberOfRefMesh << ", or meshLink : " << meshLink); } // ATTENTION TRAITER L'EXCEPTION CI DESSUS !!!!!!!! @@ -534,7 +538,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) _meshes.find(meshName); if ( _meshesIt == _meshes.end() ) { - MESSAGE(LOC << "There is no mesh |" << meshName << + MESSAGE_MED(LOC << "There is no mesh |" << meshName << "| in the file |" << _fileName << "|, but |" << meshName << "| is referenced by field |" << @@ -545,7 +549,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) geoNames [(*currentGeometry)] <<"|"); } // POURQUOI SI JE NE MET PAS DE BLOCK J'AI UN PARSE - // ERROR : PG : c'est la macro MESSAGE qui fait ca ! + // ERROR : PG : c'est la macro MESSAGE_MED qui fait ca ! else ptrMesh = _meshes[meshName]; @@ -575,7 +579,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) ((FIELD<int>*) ptrField)->setName(fieldName) ; //provisoire, pour debug - MESSAGE("#### SET NAME in FIELD : "<<fieldName); + MESSAGE_MED("#### SET NAME in FIELD : "<<fieldName); MED_EN::med_mode_acces myMode = getAccessMode(); // switch (myMode) { @@ -603,7 +607,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) ptrDriver = DRIVERFACTORY::buildConcreteMedDriverForField<int>(_fileName, (FIELD<int> *)ptrField, myMode, V22); - SCRUTE(ptrDriver); + SCRUTE_MED(ptrDriver); break; @@ -619,7 +623,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) ((FIELD<double>*) ptrField)->setName(fieldName) ; //provisoire, pour debug - MESSAGE("#### SET NAME in FIELD : "<<fieldName); + MESSAGE_MED("#### SET NAME in FIELD : "<<fieldName); MED_EN::med_mode_acces myMode = getAccessMode(); // switch (myMode) { @@ -646,7 +650,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) // } ptrDriver = DRIVERFACTORY::buildConcreteMedDriverForField<double>(_fileName, (FIELD<double> *)ptrField, myMode, V22); - SCRUTE(ptrDriver); + SCRUTE_MED(ptrDriver); break; } @@ -658,7 +662,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) } // need to write field ! - MESSAGE("timeStepNumber :"<<timeStepNumber<< + MESSAGE_MED("timeStepNumber :"<<timeStepNumber<< ",orderNumber :"<<orderNumber); ptrField->setIterationNumber ( timeStepNumber); // A ajouter dans la classe FIELD @@ -667,7 +671,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) // Create a driver for this (field n°dt,n°it) ptrDriver->setId ( getId() ); - MESSAGE("###### ptrDriver->setFieldName : #"<< + MESSAGE_MED("###### ptrDriver->setFieldName : #"<< fieldName<<"#"); ptrDriver->setFieldName(fieldName); ptrField->addDriver(*ptrDriver); @@ -694,7 +698,7 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) // il faut lire les champs pour avoir les profils stockes !!! // il faudrait implémenter la lecture des profils dans med !!! - END_OF(LOC); + END_OF_MED(LOC); } @@ -703,9 +707,9 @@ void MED_MED_RDONLY_DRIVER22::readFileStruct( void ) void MED_MED_RDONLY_DRIVER22::read( void ) throw (MEDEXCEPTION) // from objects method read ! { - const char * LOC = "MED_MED_DRIVER22::read() : "; - BEGIN_OF(LOC); + const char* LOC = "MED_MED_DRIVER22::read() : "; + BEGIN_OF_MED(LOC); // For PAL12192: assure that file structure is already read this->open(); @@ -719,36 +723,41 @@ void MED_MED_RDONLY_DRIVER22::read( void ) map<FIELD_ *, MESH_NAME_>::const_iterator currentField; for ( currentMesh=_meshes.begin();currentMesh != _meshes.end(); currentMesh++ ) - (*currentMesh).second->read(*this); - //(*currentMesh).second->read(); // default reader, from readFileStruct + //(*currentMesh).second->read(*this); -> crash in MEDMEMTest_TopLevel.cxx + (*currentMesh).second->read(); // default reader, from readFileStruct // PROVISOIRE _ptrMed->updateSupport() ; for ( currentField =_meshName.begin(); currentField != _meshName.end(); currentField++ ) - (*currentField).first->read(*this); - //(*currentField).first->read(); // default reader, from readFileStruct + //(*currentField).first->read(*this); + (*currentField).first->read(); // default reader, from readFileStruct - END_OF(LOC); + END_OF_MED(LOC); } // ------------- Write Only Part -------------- MED_MED_WRONLY_DRIVER22::MED_MED_WRONLY_DRIVER22() { + this->GENDRIVER::_accessMode = MED_EN::WRONLY; } MED_MED_WRONLY_DRIVER22::MED_MED_WRONLY_DRIVER22(const string & fileName, MED * const ptrMed): - IMED_MED_WRONLY_DRIVER(fileName,ptrMed),MED_MED_DRIVER22(fileName,ptrMed),MED_MED_DRIVER(fileName,ptrMed,MED_EN::MED_WRONLY) + IMED_MED_WRONLY_DRIVER(fileName,ptrMed), + MED_MED_DRIVER22(fileName,ptrMed), + MED_MED_DRIVER(fileName,ptrMed,MED_EN::WRONLY) {} MED_MED_WRONLY_DRIVER22::MED_MED_WRONLY_DRIVER22(const MED_MED_WRONLY_DRIVER22 & driver): - IMED_MED_WRONLY_DRIVER(driver),MED_MED_DRIVER(driver),MED_MED_DRIVER22(driver) + IMED_MED_WRONLY_DRIVER(driver), + MED_MED_DRIVER(driver), + MED_MED_DRIVER22(driver) {} MED_MED_WRONLY_DRIVER22::~MED_MED_WRONLY_DRIVER22() { - MESSAGE("MED_MED_WRONLY_DRIVER22::~MED_MED_WRONLY_DRIVER22() has been destroyed"); + MESSAGE_MED("MED_MED_WRONLY_DRIVER22::~MED_MED_WRONLY_DRIVER22() has been destroyed"); } GENDRIVER * MED_MED_WRONLY_DRIVER22::copy(void) const @@ -773,9 +782,9 @@ void MED_MED_WRONLY_DRIVER22::readFileStruct(void) void MED_MED_WRONLY_DRIVER22::writeFrom( void) const throw (MEDEXCEPTION) //from object method write ! { - const char * LOC = "MED_MED_DRIVER22::writeFrom() : "; - BEGIN_OF(LOC); + const char* LOC = "MED_MED_DRIVER22::writeFrom() : "; + BEGIN_OF_MED(LOC); const map<MESH_NAME_, MESH*> & _meshes = const_cast<const map<MESH_NAME_, MESH*>& > (_ptrMed->_meshes); map<MESH_NAME_,MESH*>::const_iterator currentMesh; @@ -802,17 +811,17 @@ void MED_MED_WRONLY_DRIVER22::writeFrom( void) const } } - END_OF(LOC); + END_OF_MED(LOC); } void MED_MED_WRONLY_DRIVER22::write(void ) const throw (MEDEXCEPTION) // from object method write ! { - const char * LOC = "MED_MED_DRIVER22::write() : "; int current; - BEGIN_OF(LOC); + const char* LOC = "MED_MED_DRIVER22::write() : "; + BEGIN_OF_MED(LOC); // BCLE SUR LES OBJETS AVEC AJOUT DE DRIVER ET APPELS write @@ -824,6 +833,7 @@ void MED_MED_WRONLY_DRIVER22::write(void ) const for ( currentMesh=_meshes.begin();currentMesh != _meshes.end(); currentMesh++ ) { //current = (*currentMesh).second->addDriver(MED_DRIVER,_fileName); + MESSAGE_MED((*currentMesh).second->getName()); current = (*currentMesh).second->addDriver(MED_DRIVER,_fileName,(*currentMesh).second->getName()); // put right _id in Mesh driver (same as this._id) (*currentMesh).second->_drivers[current]->setId( getId() ); @@ -831,8 +841,10 @@ void MED_MED_WRONLY_DRIVER22::write(void ) const } for ( currentField=_meshName.begin();currentField != _meshName.end(); currentField++ ) { - //current = (*currentField).first->addDriver(MED_DRIVER,_fileName); - current = (*currentField).first->addDriver(MED_DRIVER,_fileName,(*currentField).first->getName()); + //current = (*currentField).first->addDriver(MED_DRIVER,_fileName);getName()) + MESSAGE_MED((*currentField).first->getName()); + FIELD_* myField = (*currentField).first; + current = (*currentField).first->addDriver(MED_DRIVER,_fileName,myField->getName()); // put right _id in Field driver (same as this._id) (*currentField).first->_drivers[current]->setId( getId() ); (*currentField).first->write(current) ; @@ -841,23 +853,25 @@ void MED_MED_WRONLY_DRIVER22::write(void ) const // that's work, but it is more efficenty to write directly when we had driver, no ? //writeFrom(); - END_OF(LOC); + END_OF_MED(LOC); } // ------------- Read Write Part -------------- MED_MED_RDWR_DRIVER22::MED_MED_RDWR_DRIVER22() -{} +{ + this->GENDRIVER::_accessMode = MED_EN::RDWR; +} MED_MED_RDWR_DRIVER22::MED_MED_RDWR_DRIVER22(const string & fileName, MED * const ptrMed): MED_MED_RDONLY_DRIVER22(fileName,ptrMed), MED_MED_WRONLY_DRIVER22(fileName,ptrMed), IMED_MED_RDWR_DRIVER(fileName,ptrMed), - MED_MED_DRIVER22(fileName,ptrMed,MED_REMP), + MED_MED_DRIVER22(fileName,ptrMed,RDWR), IMED_MED_WRONLY_DRIVER(fileName,ptrMed), IMED_MED_RDONLY_DRIVER(fileName,ptrMed), - MED_MED_DRIVER(fileName,ptrMed,MED_REMP) + MED_MED_DRIVER(fileName,ptrMed,RDWR) {} MED_MED_RDWR_DRIVER22::MED_MED_RDWR_DRIVER22(const MED_MED_RDWR_DRIVER22 & driver): @@ -871,7 +885,7 @@ MED_MED_RDWR_DRIVER22::MED_MED_RDWR_DRIVER22(const MED_MED_RDWR_DRIVER22 & drive {} MED_MED_RDWR_DRIVER22::~MED_MED_RDWR_DRIVER22() { - MESSAGE("MED_MED_RDWR_DRIVER22::~MED_MED_RDWR_DRIVER22() has been destroyed"); + MESSAGE_MED("MED_MED_RDWR_DRIVER22::~MED_MED_RDWR_DRIVER22() has been destroyed"); } GENDRIVER * MED_MED_RDWR_DRIVER22::copy(void) const @@ -882,31 +896,35 @@ GENDRIVER * MED_MED_RDWR_DRIVER22::copy(void) const void MED_MED_RDWR_DRIVER22::read(void) throw (MEDEXCEPTION) // from MED_MED_RDONLY_DRIVER::read() { - BEGIN_OF("MED_MED_RDWR_DRIVER22::read(void)"); + const char* LOC = "MED_MED_RDWR_DRIVER22::read(void)"; + BEGIN_OF_MED(LOC); MED_MED_RDONLY_DRIVER22::read(); - END_OF("MED_MED_RDWR_DRIVER22::read(void)"); + END_OF_MED(LOC); } void MED_MED_RDWR_DRIVER22::readFileStruct(void) throw (MEDEXCEPTION) // from MED_MED_RDONLY_DRIVER::readFileStruct() { - BEGIN_OF("MED_MED_RDWR_DRIVER22::readFileStruct(void)"); + const char* LOC = "MED_MED_RDWR_DRIVER22::readFileStruct(void)"; + BEGIN_OF_MED(LOC); MED_MED_RDONLY_DRIVER22::readFileStruct(); - END_OF("MED_MED_RDWR_DRIVER22::readFileStruct(void)"); + END_OF_MED(LOC); } void MED_MED_RDWR_DRIVER22::write(void) const throw (MEDEXCEPTION) // from MED_MED_WRONLY_DRIVER::write() { - BEGIN_OF("MED_MED_RDWR_DRIVER22::write(void) const"); + const char* LOC = "MED_MED_RDWR_DRIVER22::write(void) const"; + BEGIN_OF_MED(LOC); MED_MED_WRONLY_DRIVER22::write(); - END_OF("MED_MED_RDWR_DRIVER22::write(void) const"); + END_OF_MED(LOC); } void MED_MED_RDWR_DRIVER22::writeFrom(void) const throw (MEDEXCEPTION) // from MED_MED_WRONLY_DRIVER::writeFrom(); { - BEGIN_OF("MED_MED_RDWR_DRIVER22::writeFrom(void) const"); + const char* LOC = "MED_MED_RDWR_DRIVER22::writeFrom(void) const"; + BEGIN_OF_MED(LOC); MED_MED_WRONLY_DRIVER22::writeFrom(); - END_OF("MED_MED_RDWR_DRIVER22::writeFrom(void) const"); + END_OF_MED(LOC); } diff --git a/src/MEDMEM/MEDMEM_MedMedDriver22.hxx b/src/MEDMEM/MEDMEM_MedMedDriver22.hxx index f8fa0e400..dc6d65325 100644 --- a/src/MEDMEM/MEDMEM_MedMedDriver22.hxx +++ b/src/MEDMEM/MEDMEM_MedMedDriver22.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef MED_MED_DRIVER22_HXX #define MED_MED_DRIVER22_HXX @@ -254,6 +256,6 @@ private: virtual GENDRIVER * copy ( void ) const ; }; -}; +} #endif /* MED_MED_DRIVER22_HXX */ diff --git a/src/MEDMEM/MEDMEM_MedMeshDriver.cxx b/src/MEDMEM/MEDMEM_MedMeshDriver.cxx index 983798b92..28849c4be 100644 --- a/src/MEDMEM/MEDMEM_MedMeshDriver.cxx +++ b/src/MEDMEM/MEDMEM_MedMeshDriver.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_MedMeshDriver.hxx" #include "MEDMEM_MedMeshDriver21.hxx" @@ -38,7 +40,7 @@ using namespace MED_EN; // Every memory allocation made in the MedDriver members function are desallocated in the Mesh destructor MED_MESH_DRIVER::MED_MESH_DRIVER(): - GENDRIVER(), + GENDRIVER(MED_DRIVER), _ptrMesh(( MESH *)MED_NULL), _meshName(""), _meshNum(MED_INVALID) @@ -48,7 +50,7 @@ MED_MESH_DRIVER::MED_MESH_DRIVER(): MED_MESH_DRIVER::MED_MESH_DRIVER(const string & fileName, MESH * ptrMesh, MED_EN::med_mode_acces accessMode): - GENDRIVER(fileName,accessMode), + GENDRIVER(fileName, accessMode, MED_DRIVER), _ptrMesh(ptrMesh), _meshName(""), _meshNum(MED_INVALID) @@ -66,7 +68,7 @@ MED_MESH_DRIVER::MED_MESH_DRIVER(const MED_MESH_DRIVER & driver): MED_MESH_DRIVER::~MED_MESH_DRIVER() { - MESSAGE("MED_MESH_DRIVER::~MED_MESH_DRIVER()has been destroyed"); + MESSAGE_MED("MED_MESH_DRIVER::~MED_MESH_DRIVER()has been destroyed"); } @@ -88,9 +90,9 @@ IMED_MESH_RDONLY_DRIVER::IMED_MESH_RDONLY_DRIVER(): MED_MESH_DRIVER() IMED_MESH_RDONLY_DRIVER::IMED_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh): - MED_MESH_DRIVER(fileName, ptrMesh, MED_EN::MED_RDONLY) + MED_MESH_DRIVER(fileName, ptrMesh, MED_EN::RDONLY) { - MESSAGE("IMED_MESH_RDONLY_DRIVER::IMED_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); + MESSAGE_MED("IMED_MESH_RDONLY_DRIVER::IMED_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); } IMED_MESH_RDONLY_DRIVER::IMED_MESH_RDONLY_DRIVER(const IMED_MESH_RDONLY_DRIVER & driver): @@ -100,58 +102,57 @@ IMED_MESH_RDONLY_DRIVER::IMED_MESH_RDONLY_DRIVER(const IMED_MESH_RDONLY_DRIVER & int IMED_MESH_RDONLY_DRIVER::getDescendingConnectivity(CONNECTIVITY * Connectivity) { - const char * LOC = "MED_MESH_RDONLY_DRIVER::getDescendingConnectivity : " ; if (_status==MED_OPENED) { - MESSAGE(LOC<<"call on the object " << Connectivity); - MESSAGE(LOC<<"Not yet implemented !"); + MESSAGE_MED("MED_MESH_RDONLY_DRIVER::getDescendingConnectivity : "<<"call on the object " << Connectivity); + MESSAGE_MED("MED_MESH_RDONLY_DRIVER::getDescendingConnectivity : "<<"Not yet implemented !"); } return MED_ERROR; } void IMED_MESH_RDONLY_DRIVER::buildAllGroups(vector<GROUP*> & Groups, vector<FAMILY*> & Families) { - const char * LOC = "MED_MESH_RDONLY_DRIVER::buildAllGroups " ; - BEGIN_OF(LOC); + const char* LOC = "MED_MESH_RDONLY_DRIVER::buildAllGroups "; + BEGIN_OF_MED(LOC); int numberOfFamilies = Families.size() ; - //SCRUTE(numberOfFamilies); + //SCRUTE_MED(numberOfFamilies); map< string,list<FAMILY*> > groupsNames ; for(int i=0; i<numberOfFamilies; i++) { FAMILY * myFamily = Families[i] ; int numberOfGroups_ = myFamily->getNumberOfGroups(); - //SCRUTE(i); - //SCRUTE(numberOfGroups_); + //SCRUTE_MED(i); + //SCRUTE_MED(numberOfGroups_); for (int j=0; j<numberOfGroups_; j++) { - //SCRUTE(j); - //SCRUTE(myFamily->getGroupName(j+1)); + //SCRUTE_MED(j); + //SCRUTE_MED(myFamily->getGroupName(j+1)); groupsNames[myFamily->getGroupName(j+1)].push_back(myFamily); } } int numberOfGroups = groupsNames.size() ; - SCRUTE(numberOfGroups); + SCRUTE_MED(numberOfGroups); Groups.resize(numberOfGroups); map< string,list<FAMILY*> >::const_iterator currentGroup ; int it = 0 ; for(currentGroup=groupsNames.begin();currentGroup!=groupsNames.end();currentGroup++) { - GROUP * myGroup = new GROUP((*currentGroup).first,(*currentGroup).second) ; + GROUP * myGroup = new GROUP(healName((*currentGroup).first),(*currentGroup).second) ; // GROUP * myGroup = new GROUP() ; // myGroup->setName((*currentGroup).first); -// SCRUTE(myGroup->getName()); +// SCRUTE_MED(myGroup->getName()); // //myGroup->setMesh(_ptrMesh); // myGroup->init((*currentGroup).second); Groups[it]=myGroup; - //SCRUTE(it); + //SCRUTE_MED(it); it++; } - END_OF(LOC); + END_OF_MED(LOC); } void IMED_MESH_RDONLY_DRIVER::updateFamily() { - const char * LOC = "MED_MESH_RDONLY_DRIVER::updateFamily() " ; - BEGIN_OF(LOC); + const char* LOC = "MED_MESH_RDONLY_DRIVER::updateFamily() "; + BEGIN_OF_MED(LOC); // we need to update family on constituent if we have constituent, but no // descending connectivity, so, we must calculate all constituent and @@ -159,7 +160,7 @@ void IMED_MESH_RDONLY_DRIVER::updateFamily() _ptrMesh->_connectivity->updateFamily(_ptrMesh->_familyFace) ; // in 2d, do nothing _ptrMesh->_connectivity->updateFamily(_ptrMesh->_familyEdge) ; // in 3d, do nothing - END_OF(LOC); + END_OF_MED(LOC); } @@ -179,7 +180,7 @@ IMED_MESH_WRONLY_DRIVER::IMED_MESH_WRONLY_DRIVER(const string & fileName, MED_EN::med_mode_acces access): MED_MESH_DRIVER(fileName,ptrMesh,access) { - MESSAGE("MED_MESH_WRONLY_DRIVER::MED_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); + MESSAGE_MED("MED_MESH_WRONLY_DRIVER::MED_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); } IMED_MESH_WRONLY_DRIVER::IMED_MESH_WRONLY_DRIVER(const IMED_MESH_WRONLY_DRIVER & driver): @@ -189,7 +190,7 @@ IMED_MESH_WRONLY_DRIVER::IMED_MESH_WRONLY_DRIVER(const IMED_MESH_WRONLY_DRIVER & IMED_MESH_WRONLY_DRIVER::~IMED_MESH_WRONLY_DRIVER() { - //MESSAGE("MED_MESH_WRONLY_DRIVER::MED_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed"); + //MESSAGE_MED("MED_MESH_WRONLY_DRIVER::MED_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed"); } void IMED_MESH_WRONLY_DRIVER::read (void) @@ -205,9 +206,9 @@ IMED_MESH_RDWR_DRIVER::IMED_MESH_RDWR_DRIVER() IMED_MESH_RDWR_DRIVER::IMED_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh): - IMED_MESH_RDONLY_DRIVER(fileName,ptrMesh),IMED_MESH_WRONLY_DRIVER(fileName,ptrMesh),MED_MESH_DRIVER(fileName,ptrMesh,MED_RDWR) + IMED_MESH_RDONLY_DRIVER(fileName,ptrMesh),IMED_MESH_WRONLY_DRIVER(fileName,ptrMesh),MED_MESH_DRIVER(fileName,ptrMesh,RDWR) { - MESSAGE("MED_MESH_RDWR_DRIVER::MED_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); + MESSAGE_MED("MED_MESH_RDWR_DRIVER::MED_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); } IMED_MESH_RDWR_DRIVER::IMED_MESH_RDWR_DRIVER(const IMED_MESH_RDWR_DRIVER & driver): @@ -216,21 +217,21 @@ IMED_MESH_RDWR_DRIVER::IMED_MESH_RDWR_DRIVER(const IMED_MESH_RDWR_DRIVER & drive } IMED_MESH_RDWR_DRIVER::~IMED_MESH_RDWR_DRIVER() { - //MESSAGE("MED_MESH_RDWR_DRIVER::MED_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed"); + //MESSAGE_MED("MED_MESH_RDWR_DRIVER::MED_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed"); } /////////// Concrete MED_MESH_DRIVERS implementations MED_MESH_RDONLY_DRIVER::MED_MESH_RDONLY_DRIVER() { - MESSAGE("You are using the default constructor of the Mesh read only Driver and it is 2.1 one"); + MESSAGE_MED("You are using the default constructor of the Mesh read only Driver and it is 2.1 one"); _concreteMeshDrv = new MED_MESH_RDONLY_DRIVER21(); } MED_MESH_RDONLY_DRIVER::MED_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh): - IMED_MESH_RDONLY_DRIVER(fileName,ptrMesh),MED_MESH_DRIVER(fileName,ptrMesh,MED_LECT) + IMED_MESH_RDONLY_DRIVER(fileName,ptrMesh),MED_MESH_DRIVER(fileName,ptrMesh,RDONLY) { - _concreteMeshDrv = DRIVERFACTORY::buildMeshDriverFromFile(fileName,ptrMesh,MED_LECT); + _concreteMeshDrv = DRIVERFACTORY::buildMeshDriverFromFile(fileName,ptrMesh,RDONLY); } MED_MESH_RDONLY_DRIVER::MED_MESH_RDONLY_DRIVER(const MED_MESH_RDONLY_DRIVER & driver):MED_MESH_DRIVER(driver) @@ -292,6 +293,14 @@ GENDRIVER * MED_MESH_RDONLY_DRIVER::copy ( void ) const return new MED_MESH_RDONLY_DRIVER(*this); } +void MED_MESH_RDONLY_DRIVER::merge ( const GENDRIVER& driver ) +{ + const MED_MESH_RDONLY_DRIVER *other=dynamic_cast<const MED_MESH_RDONLY_DRIVER *>(&driver); + if(other) + _concreteMeshDrv->merge( *other->_concreteMeshDrv ); + else + _concreteMeshDrv->merge( driver ); +} // int MED_MESH_RDONLY_DRIVER::getCOORDINATE() // { // return _concreteMeshDrv->getCOORDINATE(); @@ -334,7 +343,7 @@ GENDRIVER * MED_MESH_RDONLY_DRIVER::copy ( void ) const MED_MESH_WRONLY_DRIVER::MED_MESH_WRONLY_DRIVER() { - MESSAGE("You are using the default constructor of the Mesh write only Driver and it is 2.1 one"); + MESSAGE_MED("You are using the default constructor of the Mesh write only Driver and it is 2.1 one"); _concreteMeshDrv = new MED_MESH_WRONLY_DRIVER21(); } @@ -389,6 +398,15 @@ void MED_MESH_WRONLY_DRIVER::write( void ) const _concreteMeshDrv->write(); } +void MED_MESH_WRONLY_DRIVER::merge ( const GENDRIVER& driver ) +{ + const MED_MESH_WRONLY_DRIVER *other=dynamic_cast<const MED_MESH_WRONLY_DRIVER *>(&driver); + if(other) + _concreteMeshDrv->merge( *other->_concreteMeshDrv ); + else + _concreteMeshDrv->merge( driver ); +} + // int MED_MESH_WRONLY_DRIVER::MED_MESH_WRONLY_DRIVER::writeCoordinates () const // { // return _concreteMeshDrv->writeCoordinates(); @@ -420,9 +438,9 @@ MED_MESH_RDWR_DRIVER::MED_MESH_RDWR_DRIVER() } MED_MESH_RDWR_DRIVER::MED_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh): - IMED_MESH_RDWR_DRIVER(fileName,ptrMesh),MED_MESH_DRIVER(fileName,ptrMesh,MED_REMP) + IMED_MESH_RDWR_DRIVER(fileName,ptrMesh),MED_MESH_DRIVER(fileName,ptrMesh,RDWR) { - _concreteMeshDrv = DRIVERFACTORY::buildMeshDriverFromFile(fileName,ptrMesh,MED_REMP); + _concreteMeshDrv = DRIVERFACTORY::buildMeshDriverFromFile(fileName,ptrMesh,RDWR); } MED_MESH_RDWR_DRIVER::MED_MESH_RDWR_DRIVER(const MED_MESH_RDWR_DRIVER & driver): MED_MESH_DRIVER(driver) @@ -548,3 +566,12 @@ GENDRIVER * MED_MESH_RDWR_DRIVER::copy ( void ) const { return new MED_MESH_RDWR_DRIVER(*this); } + +void MED_MESH_RDWR_DRIVER::merge ( const GENDRIVER& driver ) +{ + const MED_MESH_RDWR_DRIVER *other=dynamic_cast<const MED_MESH_RDWR_DRIVER *>(&driver); + if(other) + _concreteMeshDrv->merge( *other->_concreteMeshDrv ); + else + _concreteMeshDrv->merge( driver ); +} diff --git a/src/MEDMEM/MEDMEM_MedMeshDriver.hxx b/src/MEDMEM/MEDMEM_MedMeshDriver.hxx index 3bdc41744..7ddb90f25 100644 --- a/src/MEDMEM/MEDMEM_MedMeshDriver.hxx +++ b/src/MEDMEM/MEDMEM_MedMeshDriver.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef MED_MESH_DRIVER_HXX #define MED_MESH_DRIVER_HXX @@ -166,7 +168,7 @@ public : /*! Constructor. */ - IMED_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh, MED_EN::med_mode_acces access=MED_EN::MED_WRONLY) ; + IMED_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh, MED_EN::med_mode_acces access=MED_EN::WRONLY) ; /*! Copy constructor. */ @@ -242,6 +244,8 @@ public: void read ( void ); void open(); void close(); + virtual void merge ( const GENDRIVER& driver ); + virtual void setFileName ( const string & fileName) {_concreteMeshDrv->setFileName(fileName); } protected: GENDRIVER * _concreteMeshDrv; // int getCOORDINATE(); @@ -258,7 +262,7 @@ protected: class MEDMEM_EXPORT MED_MESH_WRONLY_DRIVER : public virtual IMED_MESH_WRONLY_DRIVER { public : MED_MESH_WRONLY_DRIVER(); - MED_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh, MED_EN::med_mode_acces access=MED_EN::MED_ECRI); + MED_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh, MED_EN::med_mode_acces access=MED_EN::WRONLY); MED_MESH_WRONLY_DRIVER(const MED_MESH_WRONLY_DRIVER & driver); ~MED_MESH_WRONLY_DRIVER(); void setMeshName(const string & meshName); @@ -267,6 +271,8 @@ public : void write( void ) const; void open(); void close(); + virtual void merge ( const GENDRIVER& driver ); + virtual void setFileName ( const string & fileName) {_concreteMeshDrv->setFileName(fileName); } protected: GENDRIVER * _concreteMeshDrv; // int writeCoordinates () const; @@ -291,6 +297,8 @@ public : void desactivateFacesComputation(); void open(); void close(); + virtual void merge ( const GENDRIVER& driver ); + virtual void setFileName ( const string & fileName) {_concreteMeshDrv->setFileName(fileName); } protected: GENDRIVER * _concreteMeshDrv; // int getCOORDINATE(); @@ -309,6 +317,6 @@ protected: GENDRIVER * copy ( void ) const; }; -}; +} #endif /* MED_MESH_DRIVER_HXX */ diff --git a/src/MEDMEM/MEDMEM_MedMeshDriver21.cxx b/src/MEDMEM/MEDMEM_MedMeshDriver21.cxx index ea6624017..d5f79ec05 100644 --- a/src/MEDMEM/MEDMEM_MedMeshDriver21.cxx +++ b/src/MEDMEM/MEDMEM_MedMeshDriver21.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_MedMeshDriver21.hxx" @@ -39,6 +41,9 @@ namespace med_2_1 { extern "C" { extern med_idt _MEDdatagroupOuvrir(med_idt pid, char *nom); extern med_err _MEDdatagroupFermer(med_idt id); + extern med_err _MEDparametresGeometrie(med_entite_maillage type_ent, + med_geometrie_element type_geo, + int *dim, int *nnoe,int *ndes); } } @@ -67,11 +72,11 @@ MED_MESH_DRIVER21::~MED_MESH_DRIVER21() void MED_MESH_DRIVER21::open() { const char * LOC = "MED_MESH_DRIVER21::open()" ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); int accessMode = getMedAccessMode( _accessMode, MED_EN::V21 ); - MESSAGE(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< accessMode); + MESSAGE_MED(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< accessMode); _medIdt = med_2_1::MEDouvrir( (const_cast <char *> (_fileName.c_str())),(med_2_1::med_mode_acces) accessMode); - MESSAGE(LOC<<" _medIdt : "<< _medIdt ); + MESSAGE_MED(LOC<<" _medIdt : "<< _medIdt ); if (_medIdt > 0) _status = MED_OPENED; else { @@ -80,13 +85,13 @@ void MED_MESH_DRIVER21::open() throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Could not open file "<<_fileName<<" in mode "<<_accessMode)); } - END_OF(LOC); + END_OF_MED(LOC); } void MED_MESH_DRIVER21::close() { const char * LOC = "MED_MESH_DRIVER21::close() " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); int err = 0; if ( _status == MED_OPENED) { err=med_2_1::MEDfermer(_medIdt); @@ -98,12 +103,12 @@ void MED_MESH_DRIVER21::close() <<" Error when closing file !" ) ); - MESSAGE(LOC <<": _medIdt= " << _medIdt ); - MESSAGE(LOC<<": MEDfermer : err = " << err ); + MESSAGE_MED(LOC <<": _medIdt= " << _medIdt ); + MESSAGE_MED(LOC<<": MEDfermer : err = " << err ); _status = MED_CLOSED; _medIdt = MED_INVALID; } - END_OF(LOC); + END_OF_MED(LOC); } //A FAIRE UTILISER LES MAPS... @@ -121,16 +126,17 @@ const char * const MED_MESH_DRIVER21::all_cell_type_tab [MED_NBR_GEOMETRIE_MAILL MED_MESH_RDONLY_DRIVER21::MED_MESH_RDONLY_DRIVER21():_computeFaces(true) { + this->GENDRIVER::_accessMode = MED_EN::RDONLY; } MED_MESH_RDONLY_DRIVER21::MED_MESH_RDONLY_DRIVER21(const string & fileName, MESH * ptrMesh): IMED_MESH_RDONLY_DRIVER(fileName,ptrMesh), - MED_MESH_DRIVER21(fileName,ptrMesh,MED_RDONLY), - MED_MESH_DRIVER(fileName,ptrMesh,MED_RDONLY), + MED_MESH_DRIVER21(fileName,ptrMesh,RDONLY), + MED_MESH_DRIVER(fileName,ptrMesh,RDONLY), _computeFaces(true) { - MESSAGE("MED_MESH_RDONLY_DRIVER21::MED_MESH_RDONLY_DRIVER21(const string & fileName, MESH * ptrMesh) has been created"); + MESSAGE_MED("MED_MESH_RDONLY_DRIVER21::MED_MESH_RDONLY_DRIVER21(const string & fileName, MESH * ptrMesh) has been created"); } MED_MESH_RDONLY_DRIVER21::MED_MESH_RDONLY_DRIVER21(const MED_MESH_RDONLY_DRIVER21 & driver): @@ -143,7 +149,7 @@ MED_MESH_RDONLY_DRIVER21::MED_MESH_RDONLY_DRIVER21(const MED_MESH_RDONLY_DRIVER2 MED_MESH_RDONLY_DRIVER21::~MED_MESH_RDONLY_DRIVER21() { - //MESSAGE("MED_MESH_RDONLY_DRIVER21::~MED_MESH_RDONLY_DRIVER21() has been destroyed"); + //MESSAGE_MED("MED_MESH_RDONLY_DRIVER21::~MED_MESH_RDONLY_DRIVER21() has been destroyed"); } GENDRIVER * MED_MESH_RDONLY_DRIVER21::copy(void) const @@ -154,13 +160,13 @@ GENDRIVER * MED_MESH_RDONLY_DRIVER21::copy(void) const void MED_MESH_RDONLY_DRIVER21::read(void) { const char * LOC = "MED_MESH_RDONLY_DRIVER21::read() : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status!=MED_OPENED) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The _idt of file " << _fileName << " is : " << _medIdt << " (the file is not opened)." )) ; _ptrMesh->_name = _meshName; - SCRUTE(_ptrMesh->getIsAGrid()); + SCRUTE_MED(_ptrMesh->getIsAGrid()); if (_ptrMesh->getIsAGrid()) { @@ -172,30 +178,32 @@ void MED_MESH_RDONLY_DRIVER21::read(void) buildAllGroups(_ptrMesh->_groupNode,_ptrMesh->_familyNode) ; } - END_OF(LOC); + END_OF_MED(LOC); return; } - else // check that the mesh is really unstructured (PAL14113) - { - char meshName[MED_TAILLE_NOM+1]=""; - char meshDescription[MED_TAILLE_DESC+1]=""; - med_2_3::med_int meshDim; - med_2_3::med_maillage meshType; - int numberOfMeshes = med_2_3::MEDnMaa(_medIdt); - for (int i=1;i<=numberOfMeshes;i++) - { - MEDmaaInfo(_medIdt, i ,meshName, &meshDim, &meshType, meshDescription); - if (_meshName == string(meshName)) { - if ( meshType == med_2_3::MED_STRUCTURE ) { - throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << - "class GRID must be used for a structured mesh")); - } - else { - break; - } - } - } - } + // (EAP at EDF): Commented for MEDMEMTest_VtkMedDriver.cxx:126 - + // aMedMeshRdDriver21->read(); +// else // check that the mesh is really unstructured (PAL14113) +// { +// char meshName[MED_TAILLE_NOM+1]=""; +// char meshDescription[MED_TAILLE_DESC+1]=""; +// med_2_3::med_int meshDim; +// med_2_3::med_maillage meshType; +// int numberOfMeshes = med_2_3::MEDnMaa(_medIdt); +// for (int i=1;i<=numberOfMeshes;i++) +// { +// MEDmaaInfo(_medIdt, i ,meshName, &meshDim, &meshType, meshDescription); +// if (_meshName == string(meshName)) { +// if ( meshType == med_2_3::MED_STRUCTURE ) { +// throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << +// "class GRID must be used for a structured mesh")); +// } +// else { +// break; +// } +// } +// } +// } if (getCOORDINATE()!=MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getCOORDINATE" )) ; @@ -223,15 +231,15 @@ void MED_MESH_RDONLY_DRIVER21::read(void) // on edge buildAllGroups(_ptrMesh->_groupEdge,_ptrMesh->_familyEdge) ; -// MESSAGE(LOC<<"Checking of CellModel !!!!!!!"); +// MESSAGE_MED(LOC<<"Checking of CellModel !!!!!!!"); // int nbOfTypes = _ptrMesh->_connectivity->_numberOfTypes; // for(int i=0;i<nbOfTypes;i++) // { -// MESSAGE(LOC << _ptrMesh->_connectivity->_type[i]) ; +// MESSAGE_MED(LOC << _ptrMesh->_connectivity->_type[i]) ; // } - END_OF(LOC); + END_OF_MED(LOC); } //======================================================================= @@ -242,7 +250,7 @@ void MED_MESH_RDONLY_DRIVER21::read(void) void MED_MESH_RDONLY_DRIVER21::getGRID() { const char * LOC = "MED_MESH_RDONLY_DRIVER21::getGRID() : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status!=MED_OPENED) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "med file is not opened")); @@ -289,7 +297,7 @@ void MED_MESH_RDONLY_DRIVER21::getGRID() // Read node coordinates for MED_BODY_FITTED grid - SCRUTE(ptrGrid->getGridType()); + SCRUTE_MED(ptrGrid->getGridType()); if (ptrGrid->getGridType() == MED_EN::MED_BODY_FITTED) { @@ -336,13 +344,13 @@ void MED_MESH_RDONLY_DRIVER21::getGRID() MEDArrayNodeFamily, NumberOfNodes); - MESSAGE(LOC << " NumberOfNodes = " << NumberOfNodes << " SpaceDimension = " << SpaceDimension); + MESSAGE_MED(LOC << " NumberOfNodes = " << NumberOfNodes << " SpaceDimension = " << SpaceDimension); ptrGrid->_is_coordinates_filled = true; // for (int icoor = 0 ; icoor<NumberOfNodes ; icoor++) // for(int jcoor = 0 ; jcoor<SpaceDimension ; jcoor++) -// MESSAGE(LOC << " icoor = " << icoor << " jcoor = " << jcoor << " COOR = " << _ptrMesh->getCoordinates(MED_FULL_INTERLACE)[icoor*SpaceDimension+jcoor]); +// MESSAGE_MED(LOC << " icoor = " << icoor << " jcoor = " << jcoor << " COOR = " << _ptrMesh->getCoordinates(MED_FULL_INTERLACE)[icoor*SpaceDimension+jcoor]); delete[] MEDArrayNodeFamily; if (err != MED_VALID) @@ -410,7 +418,7 @@ void MED_MESH_RDONLY_DRIVER21::getGRID() _ptrMesh->_coordinate->setCoordinatesSystem(coordinateSystem); - END_OF(LOC); + END_OF_MED(LOC); } //======================================================================= @@ -420,7 +428,7 @@ void MED_MESH_RDONLY_DRIVER21::getGRID() int MED_MESH_RDONLY_DRIVER21::getCOORDINATE() { const char * LOC = "MED_MESH_RDONLY_DRIVER21::getCOORDINATE() : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status==MED_OPENED) { @@ -524,7 +532,7 @@ int MED_MESH_RDONLY_DRIVER21::getCOORDINATE() tmp_node_name,NumberOfNodes*MED_TAILLE_PNOM21,med_2_1::MED_NOEUD, (med_2_1::med_geometrie_element) MED_NONE); if (err == MED_VALID) - MESSAGE(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : WARNING : Nodes have names but we do not read them !"); + MESSAGE_MED(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : WARNING : Nodes have names but we do not read them !"); delete[] tmp_node_name ; @@ -533,10 +541,10 @@ int MED_MESH_RDONLY_DRIVER21::getCOORDINATE() err=MEDnumLire(_medIdt,const_cast <char*> (_ptrMesh->_name.c_str()), tmp_node_number,NumberOfNodes,med_2_1::MED_NOEUD,(med_2_1::med_geometrie_element)0); if (err == MED_VALID) { - // INFOS(LOC<<"WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING"); - // INFOS(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : WARNING : Nodes have numbers but we do not take care of them !"); - // INFOS(LOC<<"WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING"); - MESSAGE(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : Nodes have numbers, we DO TAKE care of them !"); + // INFOS_MED(LOC<<"WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING"); + // INFOS_MED(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : WARNING : Nodes have numbers but we do not take care of them !"); + // INFOS_MED(LOC<<"WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING"); + MESSAGE_MED(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : Nodes have numbers, we DO TAKE care of them !"); _ptrMesh->_coordinate->_nodeNumber.set(NumberOfNodes) ; #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64) for(med_2_1::med_int i2=0;i2<NumberOfNodes;i2++) @@ -562,7 +570,7 @@ int MED_MESH_RDONLY_DRIVER21::getCOORDINATE() delete[] tmp_node_number ; - END_OF(LOC); + END_OF_MED(LOC); return MED_VALID; } return MED_ERROR; @@ -572,7 +580,7 @@ int MED_MESH_RDONLY_DRIVER21::getCOORDINATE() int MED_MESH_RDONLY_DRIVER21::getCONNECTIVITY() { const char * LOC = "MED_MESH_RDONLY_DRIVER21::getCONNECTIVITY : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status==MED_OPENED) { @@ -616,17 +624,17 @@ int MED_MESH_RDONLY_DRIVER21::getCONNECTIVITY() if(Connectivity->_constituent==NULL) { - SCRUTE(_ptrMesh->_meshDimension); + SCRUTE_MED(_ptrMesh->_meshDimension); if (_ptrMesh->_meshDimension == 3) { - MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DES FACES..." ); + MESSAGE_MED(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DES FACES..." ); CONNECTIVITY * ConnectivityFace = new CONNECTIVITY(MED_EN::MED_FACE) ; ConnectivityFace->_typeConnectivity = Connectivity->_typeConnectivity ; // NODAL or DESCENDING - SCRUTE(ConnectivityFace->_typeConnectivity); + SCRUTE_MED(ConnectivityFace->_typeConnectivity); if (Connectivity->_typeConnectivity == MED_DESCENDING) { - MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DESCENDANTE DES FACES" ); + MESSAGE_MED(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DESCENDANTE DES FACES" ); err = getDescendingConnectivity(ConnectivityFace) ; if (err!=MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << @@ -635,7 +643,7 @@ int MED_MESH_RDONLY_DRIVER21::getCONNECTIVITY() } else { - MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE NODALE DES FACES" ); + MESSAGE_MED(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE NODALE DES FACES" ); err = getNodalConnectivity(ConnectivityFace) ; if (err!=MED_VALID) { // or error ????? we are in NODAL mode. @@ -648,11 +656,11 @@ int MED_MESH_RDONLY_DRIVER21::getCONNECTIVITY() if (err!=MED_VALID) { delete ConnectivityFace ; - MESSAGE(LOC<<"No FACE defined.") ; + MESSAGE_MED(LOC<<"No FACE defined.") ; } else { - MESSAGE(LOC<<" SAUVEGARDE DE LA CONNECTIVITE DES " << + MESSAGE_MED(LOC<<" SAUVEGARDE DE LA CONNECTIVITE DES " << "FACES DANS L'OBJET CONNECTIVITY" ); Connectivity->_constituent=ConnectivityFace ; } @@ -661,12 +669,12 @@ int MED_MESH_RDONLY_DRIVER21::getCONNECTIVITY() // read MED_EDGE connectivity if (_ptrMesh->_meshDimension > 1) { // we are in 3 or 2D - MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DES ARRETES...." ); + MESSAGE_MED(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DES ARRETES...." ); CONNECTIVITY * ConnectivityEdge = new CONNECTIVITY(MED_EDGE) ; ConnectivityEdge->_typeConnectivity = Connectivity->_typeConnectivity ; if (Connectivity->_typeConnectivity == MED_DESCENDING) { - MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DESCENDANTE " << + MESSAGE_MED(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DESCENDANTE " << "DES ARRETES" ); err = getDescendingConnectivity(ConnectivityEdge) ; if (err!=MED_VALID) @@ -676,7 +684,7 @@ int MED_MESH_RDONLY_DRIVER21::getCONNECTIVITY() } else { - MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE NODALE DES ARRETES" ); + MESSAGE_MED(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE NODALE DES ARRETES" ); err = getNodalConnectivity(ConnectivityEdge) ; if (err!=MED_VALID) { // or error ????? we are in NODAL mode. @@ -689,7 +697,7 @@ int MED_MESH_RDONLY_DRIVER21::getCONNECTIVITY() if (err!=MED_VALID) { delete ConnectivityEdge ; - MESSAGE(LOC<<"No EDGE defined.") ; + MESSAGE_MED(LOC<<"No EDGE defined.") ; } else { @@ -700,7 +708,7 @@ int MED_MESH_RDONLY_DRIVER21::getCONNECTIVITY() throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<< "EDGE defined but there are no FACE !")) ; else { // IN 2D - MESSAGE(LOC<<" SAUVEGARDE DE LA CONNECTIVITE DES " << + MESSAGE_MED(LOC<<" SAUVEGARDE DE LA CONNECTIVITE DES " << "ARETES DANS L'OBJET CONNECTIVITY" ); Connectivity->_constituent=ConnectivityEdge ; } @@ -726,7 +734,7 @@ int MED_MESH_RDONLY_DRIVER21::getCONNECTIVITY() // } - END_OF(LOC); + END_OF_MED(LOC); return MED_VALID; } return MED_ERROR; @@ -735,7 +743,7 @@ int MED_MESH_RDONLY_DRIVER21::getCONNECTIVITY() int MED_MESH_RDONLY_DRIVER21::getNodalConnectivity(CONNECTIVITY * Connectivity) { const char * LOC = "MED_MESH_RDONLY_DRIVER21::getNodalConnectivity : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status==MED_OPENED) { @@ -893,7 +901,7 @@ int MED_MESH_RDONLY_DRIVER21::getNodalConnectivity(CONNECTIVITY * Connectivity) size+=tmp_cells_count[i]*((MED_MESH_DRIVER21::all_cell_type[i])%100) ; - MESSAGE(LOC + MESSAGE_MED(LOC << Connectivity->_count[typeNumber]-1 << " cells of type " << all_cell_type_tab[i] ); @@ -944,7 +952,7 @@ int MED_MESH_RDONLY_DRIVER21::getNodalConnectivity(CONNECTIVITY * Connectivity) delete[] tmp_cells_count; delete[] tmpFaceCount; delete[] tmpEdgeCount; - MESSAGE(LOC<<": MEDconnLire returns "<<err) ; + MESSAGE_MED(LOC<<": MEDconnLire returns "<<err) ; return MED_ERROR ; } @@ -1053,7 +1061,7 @@ int MED_MESH_RDONLY_DRIVER21::getNodalConnectivity(CONNECTIVITY * Connectivity) tmp_constituentArray = new med_2_1::med_int[(NumberOfNodeByFace+1)*tmp_numberOfFaces] ; else { tmp_constituentArray = new med_2_1::med_int[NumberOfNodeByFace*tmp_numberOfFaces] ; - MESSAGE(LOC<<": WE ARE USING MED2.2 so there is no +1 for calculating the size of tmp_constituentArray !") ; + MESSAGE_MED(LOC<<": WE ARE USING MED2.2 so there is no +1 for calculating the size of tmp_constituentArray !") ; } int err=MEDconnLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()), @@ -1061,7 +1069,7 @@ int MED_MESH_RDONLY_DRIVER21::getNodalConnectivity(CONNECTIVITY * Connectivity) med_2_1::MED_FULL_INTERLACE,NULL,0,med_2_1::MED_MAILLE,med_type,med_2_1::MED_NOD); if ( err != MED_VALID) { - MESSAGE(LOC<<": MEDconnLire returns "<<err) ; + MESSAGE_MED(LOC<<": MEDconnLire returns "<<err) ; delete constituent ; delete[] tmp_constituentArray; delete[] tmpFaceCount; @@ -1166,7 +1174,7 @@ int MED_MESH_RDONLY_DRIVER21::getNodalConnectivity(CONNECTIVITY * Connectivity) tmp_constituentArray = new med_2_1::med_int[(NumberOfNodeByEdge+1)*tmp_numberOfEdges] ; else { tmp_constituentArray = new med_2_1::med_int[NumberOfNodeByEdge*tmp_numberOfEdges] ; - MESSAGE(LOC<<": WE ARE USING MED2.2 so there is no +1 for calculating the size of tmp_constituentArray !") ; + MESSAGE_MED(LOC<<": WE ARE USING MED2.2 so there is no +1 for calculating the size of tmp_constituentArray !") ; } int err=MEDconnLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()), @@ -1174,7 +1182,7 @@ int MED_MESH_RDONLY_DRIVER21::getNodalConnectivity(CONNECTIVITY * Connectivity) med_2_1::MED_FULL_INTERLACE,NULL,0,med_2_1::MED_MAILLE, med_type,med_2_1::MED_NOD); if ( err != MED_VALID) { - MESSAGE(LOC<<": MEDconnLire returns "<<err) ; + MESSAGE_MED(LOC<<": MEDconnLire returns "<<err) ; delete constituent ; delete[] tmp_constituentArray; delete[] tmpEdgeCount; @@ -1239,7 +1247,7 @@ int MED_MESH_RDONLY_DRIVER21::getNodalConnectivity(CONNECTIVITY * Connectivity) int MED_MESH_RDONLY_DRIVER21::getFAMILY() { const char * LOC = "MED_MESH_RDONLY_DRIVER21::getFAMILY() : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status==MED_OPENED) { int err = 0 ; @@ -1257,7 +1265,7 @@ int MED_MESH_RDONLY_DRIVER21::getFAMILY() err = getNodesFamiliesNumber(MEDArrayNodeFamily) ; // error only if (_status!=MED_OPENED), other case exeception ! // CELL - MESSAGE(LOC << "error returned from getNodesFamiliesNumber " << err); + MESSAGE_MED(LOC << "error returned from getNodesFamiliesNumber " << err); MEDArrayCellFamily = new int*[_ptrMesh->getNumberOfTypes(MED_CELL)] ; // ET SI IL N'Y A PAS DE CELLS ? const medGeometryElement * myTypes = _ptrMesh->getTypes(MED_CELL); @@ -1266,7 +1274,7 @@ int MED_MESH_RDONLY_DRIVER21::getFAMILY() err = getCellsFamiliesNumber(MEDArrayCellFamily,_ptrMesh->_connectivity,MED_CELL) ; - MESSAGE(LOC << "error returned from getCellsFamiliesNumber for Cells " << err); + MESSAGE_MED(LOC << "error returned from getCellsFamiliesNumber for Cells " << err); if (_ptrMesh->_connectivity->_constituent != NULL) { if (_ptrMesh->_connectivity->_constituent->_entity == MED_EN::MED_FACE) { @@ -1278,7 +1286,7 @@ int MED_MESH_RDONLY_DRIVER21::getFAMILY() err = getCellsFamiliesNumber(MEDArrayFaceFamily,_ptrMesh->_connectivity->_constituent,MED_FACE) ; - MESSAGE(LOC << "error returned from getCellsFamiliesNumber for Faces " << err); + MESSAGE_MED(LOC << "error returned from getCellsFamiliesNumber for Faces " << err); } else { // EDGE in 2D @@ -1288,7 +1296,7 @@ int MED_MESH_RDONLY_DRIVER21::getFAMILY() MEDArrayEdgeFamily[i] = new int[_ptrMesh->getNumberOfElements(MED_EDGE,myTypes[i])] ; err = getCellsFamiliesNumber(MEDArrayEdgeFamily,_ptrMesh->_connectivity->_constituent,MED_EDGE) ; - MESSAGE(LOC << "error returned from getCellsFamiliesNumber for Edges in 2D " << err); + MESSAGE_MED(LOC << "error returned from getCellsFamiliesNumber for Edges in 2D " << err); } // EDGE in 3D @@ -1299,7 +1307,7 @@ int MED_MESH_RDONLY_DRIVER21::getFAMILY() MEDArrayEdgeFamily[i] = new int[_ptrMesh->getNumberOfElements(MED_EDGE,myTypes[i])] ; err = getCellsFamiliesNumber(MEDArrayEdgeFamily,_ptrMesh->_connectivity->_constituent->_constituent,MED_EDGE) ; // we are in 3D ! - MESSAGE(LOC << "error returned from getCellsFamiliesNumber for Edges in 3D " << err); + MESSAGE_MED(LOC << "error returned from getCellsFamiliesNumber for Edges in 3D " << err); } } @@ -1334,7 +1342,7 @@ int MED_MESH_RDONLY_DRIVER21::getFAMILY() if ( NumberOfFamilies < 1 ) // at least family 0 must exist throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"There is no FAMILY, FAMILY 0 must exists" )); - SCRUTE(NumberOfFamilies); + SCRUTE_MED(NumberOfFamilies); vector<FAMILY*> &NodeFamilyVector = _ptrMesh->_familyNode ; vector<FAMILY*> &CellFamilyVector = _ptrMesh->_familyCell ; @@ -1390,10 +1398,10 @@ int MED_MESH_RDONLY_DRIVER21::getFAMILY() ); #endif - SCRUTE(GroupsNames); - SCRUTE(FamilyName); - SCRUTE(err); - SCRUTE(i); + SCRUTE_MED(GroupsNames); + SCRUTE_MED(FamilyName); + SCRUTE_MED(err); + SCRUTE_MED(i); if (err != MED_VALID) throw MEDEXCEPTION("MED_MESH_RDONLY_DRIVER21::getFAMILY() : ERROR when get FAMILY informations" ); @@ -1411,12 +1419,12 @@ int MED_MESH_RDONLY_DRIVER21::getFAMILY() // if nothing found, delete Family - //MESSAGE(LOC << " Well is that OK now ?? " << (*Family)); + //MESSAGE_MED(LOC << " Well is that OK now ?? " << (*Family)); if (Family->getNumberOfTypes() == 0) { - MESSAGE(LOC<<"Nothing found for family "<<FamilyName<< " : skip"); + MESSAGE_MED(LOC<<"Nothing found for family "<<FamilyName<< " : skip"); delete Family; } else switch (Family->getEntity()) { @@ -1438,7 +1446,7 @@ int MED_MESH_RDONLY_DRIVER21::getFAMILY() break ; } - // MESSAGE(LOC << (*Family)); + // MESSAGE_MED(LOC << (*Family)); @@ -1467,7 +1475,7 @@ int MED_MESH_RDONLY_DRIVER21::getFAMILY() delete[] MEDArrayEdgeFamily ; } - END_OF(LOC); + END_OF_MED(LOC); return MED_VALID ; } return MED_ERROR; @@ -1476,7 +1484,7 @@ int MED_MESH_RDONLY_DRIVER21::getFAMILY() int MED_MESH_RDONLY_DRIVER21::getNodesFamiliesNumber(int * MEDArrayNodeFamily) { const char * LOC = "MED_MESH_RDONLY_DRIVER21::getNodesFamiliesNumber() : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status==MED_OPENED) { int err = 0 ; #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64) @@ -1500,7 +1508,7 @@ int MED_MESH_RDONLY_DRIVER21::getNodesFamiliesNumber(int * MEDArrayNodeFamily) << "| nodes in mesh |" << _ptrMesh->_name.c_str() << "|" )); } - END_OF(LOC); + END_OF_MED(LOC); return MED_VALID; } return MED_ERROR; @@ -1511,7 +1519,7 @@ int MED_MESH_RDONLY_DRIVER21::getCellsFamiliesNumber(int **MEDArrayFamily, MED_EN::medEntityMesh entity) { const char * LOC = "MED_MESH_RDONLY_DRIVER21::getCellsFamiliesNumber " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status==MED_OPENED) { int i, err = 0 ; @@ -1537,7 +1545,7 @@ int MED_MESH_RDONLY_DRIVER21::getCellsFamiliesNumber(int **MEDArrayFamily, // provisoire : si les faces ou les aretes sont des mailles !!! if (err != MED_VALID) { - MESSAGE(LOC<<"search face/edge family on cell !!!"); + MESSAGE_MED(LOC<<"search face/edge family on cell !!!"); #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64) int lgthI=_ptrMesh->getNumberOfElements(entity,myTypes[i]); med_2_1::med_int *temp=new med_2_1::med_int[lgthI]; @@ -1569,13 +1577,16 @@ int MED_MESH_RDONLY_DRIVER21::getCellsFamiliesNumber(int **MEDArrayFamily, MED_MESH_WRONLY_DRIVER21::MED_MESH_WRONLY_DRIVER21() { + this->GENDRIVER::_accessMode = MED_EN::WRONLY; } MED_MESH_WRONLY_DRIVER21::MED_MESH_WRONLY_DRIVER21(const string & fileName, MESH * ptrMesh): - MED_MESH_DRIVER21(fileName,ptrMesh,MED_WRONLY),IMED_MESH_WRONLY_DRIVER(fileName,ptrMesh),MED_MESH_DRIVER(fileName,ptrMesh,MED_WRONLY) + MED_MESH_DRIVER21(fileName,ptrMesh,WRONLY), + IMED_MESH_WRONLY_DRIVER(fileName,ptrMesh), + MED_MESH_DRIVER(fileName,ptrMesh,WRONLY) { - MESSAGE("MED_MESH_WRONLY_DRIVER21::MED_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); + MESSAGE_MED("MED_MESH_WRONLY_DRIVER21::MED_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); } MED_MESH_WRONLY_DRIVER21::MED_MESH_WRONLY_DRIVER21(const MED_MESH_WRONLY_DRIVER21 & driver): @@ -1585,7 +1596,7 @@ MED_MESH_WRONLY_DRIVER21::MED_MESH_WRONLY_DRIVER21(const MED_MESH_WRONLY_DRIVER2 MED_MESH_WRONLY_DRIVER21::~MED_MESH_WRONLY_DRIVER21() { - //MESSAGE("MED_MESH_WRONLY_DRIVER21::MED_MESH_WRONLY_DRIVER21(const string & fileName, MESH * ptrMesh) has been destroyed"); + //MESSAGE_MED("MED_MESH_WRONLY_DRIVER21::MED_MESH_WRONLY_DRIVER21(const string & fileName, MESH * ptrMesh) has been destroyed"); } GENDRIVER * MED_MESH_WRONLY_DRIVER21::copy(void) const @@ -1596,14 +1607,21 @@ GENDRIVER * MED_MESH_WRONLY_DRIVER21::copy(void) const void MED_MESH_WRONLY_DRIVER21::write(void) const { const char * LOC = "void MED_MESH_WRONLY_DRIVER21::write(void) const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // we must first create mesh !! - MESSAGE(LOC << "MeshName : |" << _meshName << "| FileName : |"<<_fileName<<"| MedIdt : | "<< _medIdt << "|"); + MESSAGE_MED(LOC << "MeshName : |" << _meshName << "| FileName : |"<<_fileName<<"| MedIdt : | "<< _medIdt << "|"); if (_status!=MED_OPENED) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "File "<<_fileName<<" is not open. Open it before write !")); + if (_ptrMesh->_spaceDimension == MED_INVALID ) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Mesh was not defined before calling write()")); + + if (_meshName.size() > MED_TAILLE_NOM ) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Mesh name |"<<_meshName<< + "| in object driver MESH is longer than " << MED_TAILLE_NOM)); + if (_ptrMesh->getIsAGrid()) { if ( writeGRID() != MED_VALID ) @@ -1631,14 +1649,14 @@ void MED_MESH_WRONLY_DRIVER21::write(void) const int err ; // test if the family already exists (HDF trick waiting a MED evolution to be replaced) string dataGroupFam = "/ENS_MAA/"+_meshName+"/FAS/FAMILLE_0/"; - MESSAGE("|"<<dataGroupFam<<"|"); + MESSAGE_MED("|"<<dataGroupFam<<"|"); err = med_2_1::_MEDdatagroupOuvrir(_medIdt,const_cast <char *> (dataGroupFam.c_str()) ); if ( err < MED_VALID ) { - SCRUTE(err); + SCRUTE_MED(err); err = med_2_1::MEDfamCr( _medIdt, const_cast <char *> ( _meshName.c_str() ), - "FAMILLE_0", 0, + (char*)"FAMILLE_0", 0, (med_2_1::med_int*)NULL, (med_2_1::med_int*)NULL, (char*)NULL, 0, (char*)NULL, 0); @@ -1650,23 +1668,23 @@ void MED_MESH_WRONLY_DRIVER21::write(void) const } - MESSAGE(LOC<<"writeFamilies(_ptrMesh->_familyNode)"); + MESSAGE_MED(LOC<<"writeFamilies(_ptrMesh->_familyNode)"); if (writeFamilies(_ptrMesh->_familyNode) !=MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyNode)" )) ; - MESSAGE(LOC<<"writeFamilies(_ptrMesh->_familyCell)"); + MESSAGE_MED(LOC<<"writeFamilies(_ptrMesh->_familyCell)"); if (writeFamilies(_ptrMesh->_familyCell) !=MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyCell)" )) ; - MESSAGE(LOC<<"writeFamilies(_ptrMesh->_familyFace)"); + MESSAGE_MED(LOC<<"writeFamilies(_ptrMesh->_familyFace)"); if (writeFamilies(_ptrMesh->_familyFace) !=MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyFace)" )) ; - MESSAGE(LOC<<"writeFamilies(_ptrMesh->_familyEdge)"); + MESSAGE_MED(LOC<<"writeFamilies(_ptrMesh->_familyEdge)"); if (writeFamilies(_ptrMesh->_familyEdge) !=MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyEdge)" )) ; - END_OF(LOC); + END_OF_MED(LOC); } //======================================================================= @@ -1677,11 +1695,11 @@ void MED_MESH_WRONLY_DRIVER21::write(void) const int MED_MESH_WRONLY_DRIVER21::writeGRID() const { const char * LOC = "MED_MESH_WRONLY_DRIVER21::writeGRID() : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status!=MED_OPENED) { - MESSAGE (LOC<<" Not open !!!"); + MESSAGE_MED (LOC<<" Not open !!!"); return MED_ERROR; } GRID * ptrGrid = (GRID*) _ptrMesh; @@ -1705,7 +1723,7 @@ int MED_MESH_WRONLY_DRIVER21::writeGRID() const if (err != MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Unable to create Grid")); else - MESSAGE(LOC<<"Grid "<<_meshName<<" created in file "<<_fileName<<" !"); + MESSAGE_MED(LOC<<"Grid "<<_meshName<<" created in file "<<_fileName<<" !"); } else if (dim != _ptrMesh->_spaceDimension) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Grid |" << _meshName.c_str() << @@ -1718,7 +1736,7 @@ int MED_MESH_WRONLY_DRIVER21::writeGRID() const int lengthString ; string valueString ; for (int i=0;i<_ptrMesh->_spaceDimension;i++) { - SCRUTE(i); + SCRUTE_MED(i); valueString = _ptrMesh->_coordinate->_coordinateName[i] ; lengthString = (MED_TAILLE_PNOM21<valueString.size())?MED_TAILLE_PNOM21:valueString.size() ; tmp_name.replace(i*MED_TAILLE_PNOM21,i*MED_TAILLE_PNOM21+lengthString,valueString,0,lengthString); @@ -1812,7 +1830,7 @@ int MED_MESH_WRONLY_DRIVER21::writeGRID() const } // end Write Cartesian or Polar Grid - END_OF(LOC); + END_OF_MED(LOC); return MED_VALID; } @@ -1824,7 +1842,7 @@ int MED_MESH_WRONLY_DRIVER21::writeGRID() const int MED_MESH_WRONLY_DRIVER21::writeCoordinates() const { const char * LOC = "int MED_MESH_WRONLY_DRIVER21::writeCoordinates() const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); med_2_1::med_err err = MED_ERROR; med_2_1::med_repere rep; @@ -1853,7 +1871,7 @@ int MED_MESH_WRONLY_DRIVER21::writeCoordinates() const { throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Unable to create Mesh : |" << _meshName << "|")); else { - MESSAGE(LOC<<"Mesh "<<_meshName<<" created in file "<<_fileName<<" !"); + MESSAGE_MED(LOC<<"Mesh "<<_meshName<<" created in file "<<_fileName<<" !"); } else if (dim != _ptrMesh->_spaceDimension) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Mesh |" << _meshName.c_str() << "| already exists in file |" << _fileName @@ -1925,7 +1943,7 @@ int MED_MESH_WRONLY_DRIVER21::writeCoordinates() const { } ////////////////////////////////////////////////////////////////////////////////////// - END_OF(LOC); + END_OF_MED(LOC); return MED_VALID; } @@ -1936,7 +1954,7 @@ int MED_MESH_WRONLY_DRIVER21::writeCoordinates() const { int MED_MESH_WRONLY_DRIVER21::writeConnectivities(medEntityMesh entity) const { const char * LOC="int MED_MESH_WRONLY_DRIVER21::writeConnectivities() const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); med_2_1::med_err err; @@ -2040,11 +2058,31 @@ int MED_MESH_WRONLY_DRIVER21::writeConnectivities(medEntityMesh entity) const { const int * connectivity = _ptrMesh->getConnectivity(MED_EN::MED_FULL_INTERLACE, MED_DESCENDING, entity, types[i]); // Pour l'instant la class utilise le multi..... + int multi = 0 ; + if (entity==MED_EN::MED_CELL) + if ( (types[i]/ 100) < _ptrMesh->_spaceDimension) + multi=1 ; + + int dim, numberOfNod, numberOfDesc ; + if (_MEDparametresGeometrie(med_2_1::med_entite_maillage(entity), + med_2_1::med_geometrie_element(types[i]), + &dim,&numberOfNod,&numberOfDesc) < 0 ) + continue; + + int * connectivityArray = new int[numberOfElements*(numberOfDesc+multi)]; + for (int j=0 ; j<numberOfElements; j++) + { + for (int k=0; k<numberOfDesc; k++) + connectivityArray[j*(numberOfDesc+multi)+k]=connectivity[j*numberOfDesc+k] ; + + if (multi>0) connectivityArray[j*(numberOfDesc+multi)+numberOfDesc]=0; + } + #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64) - int lgth=_ptrMesh->getConnectivityLength(MED_EN::MED_FULL_INTERLACE, MED_DESCENDING, entity, types[i]); + int lgth=numberOfElements*(numberOfDesc+multi); med_2_1::med_int *temp=new med_2_1::med_int[lgth]; for(int i2=0;i2<lgth;i2++) - temp[i2]=(med_2_1::med_int)(connectivity[i2]); + temp[i2]=(med_2_1::med_int)(connectivityArray[i2]); err = med_2_1::MEDconnEcr( _medIdt, const_cast <char *> ( _meshName.c_str()), _ptrMesh->_spaceDimension, @@ -2060,7 +2098,7 @@ int MED_MESH_WRONLY_DRIVER21::writeConnectivities(medEntityMesh entity) const { err = med_2_1::MEDconnEcr( _medIdt, const_cast <char *> ( _meshName.c_str()), _ptrMesh->_spaceDimension, - const_cast <int *> (connectivity), + const_cast <int *> (connectivityArray), med_2_1::MED_FULL_INTERLACE, numberOfElements, med_2_1::MED_REMP, @@ -2068,7 +2106,7 @@ int MED_MESH_WRONLY_DRIVER21::writeConnectivities(medEntityMesh entity) const { (med_2_1::med_geometrie_element) types[i], med_2_1::MED_DESC ); #endif - + delete[] connectivityArray ; if (err<0) // ETENDRE LES EXPLICATIONS throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't write connectivities of mesh |" << _meshName.c_str() << "| in file |" << _fileName << "| with dimension |" << _ptrMesh->_spaceDimension <<"| and" @@ -2076,14 +2114,14 @@ int MED_MESH_WRONLY_DRIVER21::writeConnectivities(medEntityMesh entity) const { } } - END_OF(LOC); + END_OF_MED(LOC); return MED_VALID; } int MED_MESH_WRONLY_DRIVER21::writeFamilyNumbers() const { const char * LOC="int MED_MESH_WRONLY_DRIVER21::writeFamilyNumbers() const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); med_2_1::med_err err; @@ -2115,8 +2153,8 @@ int MED_MESH_WRONLY_DRIVER21::writeFamilyNumbers() const { NumberOfNodesFamilies=myFamilies->size() ; } for (int i=0 ; i<NumberOfNodesFamilies; i++) { - //SCRUTE(i); - //SCRUTE(myFamilies[i]->getName()); + //SCRUTE_MED(i); + //SCRUTE_MED(myFamilies[i]->getName()); int FamilyIdentifier = (*myFamilies)[i]->getIdentifier() ; int TotalNumber = (*myFamilies)[i]->getNumberOfElements(MED_ALL_ELEMENTS) ; if ((*myFamilies)[i]->isOnAllElements()) @@ -2129,7 +2167,7 @@ int MED_MESH_WRONLY_DRIVER21::writeFamilyNumbers() const { } } for(int j=0; j<NumberOfNodes; j++) { - SCRUTE(MEDArrayNodeFamily[j]); + SCRUTE_MED(MEDArrayNodeFamily[j]); } if ( !_ptrMesh->getIsAGrid() ){ #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64) @@ -2204,7 +2242,7 @@ int MED_MESH_WRONLY_DRIVER21::writeFamilyNumbers() const { int NumberOfGroups = myGroups.size() ; // build families from groups for (int i=0; i<NumberOfGroups; i++) { - SCRUTE( myGroups[i]->getName() ); + SCRUTE_MED( myGroups[i]->getName() ); SUPPORT * mySupport = myGroups[i] ; FAMILY* myFamily = new FAMILY(*mySupport); myFamily->setIdentifier(-i-1); @@ -2248,7 +2286,7 @@ int MED_MESH_WRONLY_DRIVER21::writeFamilyNumbers() const { (med_2_1::med_geometrie_element) types[i] ); #endif - MESSAGE("OK "<<i); + MESSAGE_MED("OK "<<i); if ( err != MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't write family for the |"<< _ptrMesh->getNumberOfElements(entity, types[i]) << "| cells of geometric type |" << geoNames[ types[i]] <<"|in mesh |" @@ -2273,7 +2311,7 @@ int MED_MESH_WRONLY_DRIVER21::writeFamilyNumbers() const { int numberOfTypes = _ptrMesh->getNumberOfTypes (entity) ; const medGeometryElement * types = _ptrMesh->getTypes (entity) ; - SCRUTE(numberOfTypes); + SCRUTE_MED(numberOfTypes); int numberOfElements = _ptrMesh->getNumberOfElements(entity, MED_ALL_ELEMENTS) ; int * familyArray = new int[numberOfElements] ; @@ -2290,7 +2328,7 @@ int MED_MESH_WRONLY_DRIVER21::writeFamilyNumbers() const { int NumberOfGroups = myGroups.size() ; // build families from groups for (int i=0; i<NumberOfGroups; i++) { - SCRUTE( myGroups[i]->getName() ); + SCRUTE_MED( myGroups[i]->getName() ); SUPPORT * mySupport = myGroups[i] ; FAMILY* myFamily = new FAMILY(*mySupport); myFamily->setIdentifier(-i-1000); @@ -2375,7 +2413,7 @@ int MED_MESH_WRONLY_DRIVER21::writeFamilyNumbers() const { int NumberOfGroups = myGroups.size() ; // build families from groups for (int i=0; i<NumberOfGroups; i++) { - SCRUTE( myGroups[i]->getName() ); + SCRUTE_MED( myGroups[i]->getName() ); SUPPORT * mySupport = myGroups[i] ; FAMILY* myFamily = new FAMILY(*mySupport); myFamily->setIdentifier(-i-2000); @@ -2436,23 +2474,24 @@ int MED_MESH_WRONLY_DRIVER21::writeFamilyNumbers() const { } } - END_OF(LOC); + END_OF_MED(LOC); return MED_VALID; } int MED_MESH_WRONLY_DRIVER21::writeFamilies(vector<FAMILY*> & families ) const { const char * LOC="int MED_MESH_WRONLY_DRIVER21::writeFamilies(vector<FAMILY*> families) const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); med_2_1::med_err err; - MESSAGE(LOC<<" families.size() :"<<families.size()); + MESSAGE_MED(LOC<<" families.size() :"<<families.size()); for (unsigned int i=0; i< families.size(); i++) { int numberOfAttributes = families[i]->getNumberOfAttributes (); - string attributesDescriptions = ""; + string attributesDescriptions (numberOfAttributes*MED_TAILLE_DESC,'\0'); + //string attributesDescriptions = ""; // Recompose the attributes descriptions arg for MED for (int j=0; j < numberOfAttributes; j++) { @@ -2464,7 +2503,9 @@ int MED_MESH_WRONLY_DRIVER21::writeFamilies(vector<FAMILY*> & families ) const { << "| with identifier |" << families[i]->getIdentifier() << "| is |" << attributeDescription.size() <<"| and is more than |" << MED_TAILLE_DESC << "|")) ; - attributesDescriptions += attributeDescription; + int length = min(MED_TAILLE_LNOM,(int)attributeDescription.size()); + attributesDescriptions.replace(j*MED_TAILLE_DESC,length, attributeDescription,0,length); + //attributesDescriptions += attributeDescription; } @@ -2488,10 +2529,10 @@ int MED_MESH_WRONLY_DRIVER21::writeFamilies(vector<FAMILY*> & families ) const { // test if the family already exists (HDF trick waiting a MED evolution to be replaced) string dataGroupFam = "/ENS_MAA/"+_meshName+"/FAS/"+families[i]->getName()+"/"; - SCRUTE("|"<<dataGroupFam<<"|"); + SCRUTE_MED("|"<<dataGroupFam<<"|"); err =med_2_1::_MEDdatagroupOuvrir(_medIdt,const_cast <char *> (dataGroupFam.c_str()) ) ; if ( err < MED_VALID ) { - SCRUTE(err); + SCRUTE_MED(err); if ( families[i]->getName().size() > MED_TAILLE_NOM ) throw MEDEXCEPTION ( LOCALIZED(STRING(LOC) << "The size of the name of the family |" << i+1 @@ -2500,16 +2541,16 @@ int MED_MESH_WRONLY_DRIVER21::writeFamilies(vector<FAMILY*> & families ) const { << families[i]->getName().size() <<"| and is more than |" << MED_TAILLE_NOM << "|")) ; - MESSAGE(LOC<<"families[i]->getName().c_str() : "<<families[i]->getName().c_str()); - MESSAGE(LOC<<"_meshName.c_str() : "<<_meshName.c_str()); - MESSAGE(LOC<<"families[i]->getIdentifier() : "<<families[i]->getIdentifier()); - MESSAGE(LOC<<"numberOfAttributes : "<<numberOfAttributes); + MESSAGE_MED(LOC<<"families[i]->getName().c_str() : "<<families[i]->getName().c_str()); + MESSAGE_MED(LOC<<"_meshName.c_str() : "<<_meshName.c_str()); + MESSAGE_MED(LOC<<"families[i]->getIdentifier() : "<<families[i]->getIdentifier()); + MESSAGE_MED(LOC<<"numberOfAttributes : "<<numberOfAttributes); - //MESSAGE(LOC<<"families[i]->getAttributesIdentifiers() : "<<families[i]->getAttributesIdentifiers()[0]); - //MESSAGE(LOC<<"families[i]->getAttributesValues() : "<<families[i]->getAttributesValues()[0]); - MESSAGE(LOC<<"attributesDescriptions.c_str() : "<<attributesDescriptions.c_str()); - MESSAGE(LOC<<"numberOfGroups : "<<numberOfGroups); - MESSAGE(LOC<<"groupsNames.c_str() : "<<groupsNames.c_str()); + //MESSAGE_MED(LOC<<"families[i]->getAttributesIdentifiers() : "<<families[i]->getAttributesIdentifiers()[0]); + //MESSAGE_MED(LOC<<"families[i]->getAttributesValues() : "<<families[i]->getAttributesValues()[0]); + MESSAGE_MED(LOC<<"attributesDescriptions.c_str() : "<<attributesDescriptions.c_str()); + MESSAGE_MED(LOC<<"numberOfGroups : "<<numberOfGroups); + MESSAGE_MED(LOC<<"groupsNames.c_str() : "<<groupsNames.c_str()); #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64) int lgth=families[i]->getNumberOfAttributes(); med_2_1::med_int * AttributesIdentifier2 = new med_2_1::med_int[lgth] ; @@ -2543,7 +2584,7 @@ int MED_MESH_WRONLY_DRIVER21::writeFamilies(vector<FAMILY*> & families ) const { const_cast <char *> (groupsNames.c_str()), numberOfGroups); #endif - SCRUTE(err); + SCRUTE_MED(err); if ( err != MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't create family |" << families[i]->getName() << "| with identifier |" << families[i]->getIdentifier() << "| groups names |" @@ -2555,7 +2596,7 @@ int MED_MESH_WRONLY_DRIVER21::writeFamilies(vector<FAMILY*> & families ) const { } - END_OF(LOC); + END_OF_MED(LOC); return MED_VALID; } @@ -2569,19 +2610,20 @@ int MED_MESH_WRONLY_DRIVER21::writeFamilies(vector<FAMILY*> & families ) const { MED_MESH_RDWR_DRIVER21::MED_MESH_RDWR_DRIVER21() { + this->GENDRIVER::_accessMode = MED_EN::RDWR; } MED_MESH_RDWR_DRIVER21::MED_MESH_RDWR_DRIVER21(const string & fileName, MESH * ptrMesh): - MED_MESH_DRIVER(fileName,ptrMesh,MED_RDWR), + MED_MESH_DRIVER(fileName,ptrMesh,RDWR), IMED_MESH_RDONLY_DRIVER(fileName,ptrMesh), IMED_MESH_WRONLY_DRIVER(fileName,ptrMesh), IMED_MESH_RDWR_DRIVER(fileName,ptrMesh), - MED_MESH_DRIVER21(fileName,ptrMesh,MED_RDWR), + MED_MESH_DRIVER21(fileName,ptrMesh,RDWR), MED_MESH_RDONLY_DRIVER21(fileName,ptrMesh), MED_MESH_WRONLY_DRIVER21(fileName,ptrMesh) { - MESSAGE("MED_MESH_RDWR_DRIVER21::MED_MESH_RDWR_DRIVER21(const string & fileName, MESH * ptrMesh) has been created"); + MESSAGE_MED("MED_MESH_RDWR_DRIVER21::MED_MESH_RDWR_DRIVER21(const string & fileName, MESH * ptrMesh) has been created"); } MED_MESH_RDWR_DRIVER21::MED_MESH_RDWR_DRIVER21(const MED_MESH_RDWR_DRIVER21 & driver): @@ -2596,7 +2638,7 @@ MED_MESH_RDWR_DRIVER21::MED_MESH_RDWR_DRIVER21(const MED_MESH_RDWR_DRIVER21 & dr } MED_MESH_RDWR_DRIVER21::~MED_MESH_RDWR_DRIVER21() { - //MESSAGE("MED_MESH_RDWR_DRIVER21::MED_MESH_RDWR_DRIVER21(const string & fileName, MESH * ptrMesh) has been destroyed"); + //MESSAGE_MED("MED_MESH_RDWR_DRIVER21::MED_MESH_RDWR_DRIVER21(const string & fileName, MESH * ptrMesh) has been destroyed"); } GENDRIVER * MED_MESH_RDWR_DRIVER21::copy(void) const diff --git a/src/MEDMEM/MEDMEM_MedMeshDriver21.hxx b/src/MEDMEM/MEDMEM_MedMeshDriver21.hxx index 0bc7b6787..8cefdcdc0 100644 --- a/src/MEDMEM/MEDMEM_MedMeshDriver21.hxx +++ b/src/MEDMEM/MEDMEM_MedMeshDriver21.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef MED_MESH_DRIVER21_HXX #define MED_MESH_DRIVER21_HXX @@ -215,6 +217,6 @@ private: GENDRIVER * copy(void) const ; }; -}; +} #endif /* MED_MESH_DRIVER21_HXX */ diff --git a/src/MEDMEM/MEDMEM_MedMeshDriver22.cxx b/src/MEDMEM/MEDMEM_MedMeshDriver22.cxx index 44a38366e..bdb7c29b6 100644 --- a/src/MEDMEM/MEDMEM_MedMeshDriver22.cxx +++ b/src/MEDMEM/MEDMEM_MedMeshDriver22.cxx @@ -1,24 +1,27 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// This 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. // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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 +// +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_GenDriver.hxx" #include "MEDMEM_MedMeshDriver22.hxx" - #include "MEDMEM_DriversDef.hxx" #include "MEDMEM_Family.hxx" @@ -66,12 +69,12 @@ MED_MESH_DRIVER22::~MED_MESH_DRIVER22() void MED_MESH_DRIVER22::open() { const char * LOC = "MED_MESH_DRIVER22::open()" ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); int accessMode = getMedAccessMode( _accessMode, MED_EN::V22 ); - MESSAGE(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< accessMode); + MESSAGE_MED(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< accessMode); _medIdt = med_2_3::MEDouvrir( (const_cast <char *> (_fileName.c_str())),(med_2_3::med_mode_acces) accessMode); - MESSAGE(LOC<<" _medIdt : "<< _medIdt ); + MESSAGE_MED(LOC<<" _medIdt : "<< _medIdt ); if (_medIdt > 0) _status = MED_OPENED; else { @@ -80,13 +83,13 @@ void MED_MESH_DRIVER22::open() throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Could not open file "<<_fileName<<" in mode "<<_accessMode)); } - END_OF(LOC); + END_OF_MED(LOC); } void MED_MESH_DRIVER22::close() { const char * LOC = "MED_MESH_DRIVER22::close() " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); int err = 0; if ( _status == MED_OPENED) { err = med_2_3::MEDfermer(_medIdt); @@ -98,12 +101,12 @@ void MED_MESH_DRIVER22::close() <<" Error when closing file !" ) ); - MESSAGE(LOC <<": _medIdt= " << _medIdt ); - MESSAGE(LOC<<": MEDfermer : err = " << err ); + MESSAGE_MED(LOC <<": _medIdt= " << _medIdt ); + MESSAGE_MED(LOC<<": MEDfermer : err = " << err ); _status = MED_CLOSED; _medIdt = MED_INVALID; } - END_OF(LOC); + END_OF_MED(LOC); } //A FAIRE UTILISER LES MAPS... @@ -122,16 +125,17 @@ const char * const MED_MESH_DRIVER22::all_cell_type_tab [MED_NBR_GEOMETRIE_MAILL MED_MESH_RDONLY_DRIVER22::MED_MESH_RDONLY_DRIVER22():_computeFaces(true) { + this->GENDRIVER::_accessMode = MED_EN::RDONLY; } MED_MESH_RDONLY_DRIVER22::MED_MESH_RDONLY_DRIVER22(const string & fileName, MESH * ptrMesh): IMED_MESH_RDONLY_DRIVER(fileName,ptrMesh), - MED_MESH_DRIVER22(fileName,ptrMesh,MED_RDONLY), - MED_MESH_DRIVER(fileName,ptrMesh,MED_RDONLY), + MED_MESH_DRIVER22(fileName,ptrMesh,RDONLY), + MED_MESH_DRIVER(fileName,ptrMesh,RDONLY), _computeFaces(true) { - MESSAGE("MED_MESH_RDONLY_DRIVER22::MED_MESH_RDONLY_DRIVER22(const string & fileName, MESH * ptrMesh) has been created"); + MESSAGE_MED("MED_MESH_RDONLY_DRIVER22::MED_MESH_RDONLY_DRIVER22(const string & fileName, MESH * ptrMesh) has been created"); } MED_MESH_RDONLY_DRIVER22::MED_MESH_RDONLY_DRIVER22(const MED_MESH_RDONLY_DRIVER22 & driver): @@ -144,7 +148,7 @@ MED_MESH_RDONLY_DRIVER22::MED_MESH_RDONLY_DRIVER22(const MED_MESH_RDONLY_DRIVER2 MED_MESH_RDONLY_DRIVER22::~MED_MESH_RDONLY_DRIVER22() { - //MESSAGE("MED_MESH_RDONLY_DRIVER22::~MED_MESH_RDONLY_DRIVER() has been destroyed"); + //MESSAGE_MED("MED_MESH_RDONLY_DRIVER22::~MED_MESH_RDONLY_DRIVER() has been destroyed"); } GENDRIVER * MED_MESH_RDONLY_DRIVER22::copy(void) const @@ -152,53 +156,82 @@ GENDRIVER * MED_MESH_RDONLY_DRIVER22::copy(void) const return new MED_MESH_RDONLY_DRIVER22(*this); } +void MED_MESH_RDONLY_DRIVER22::merge ( const GENDRIVER& driver ) +{ + MED_MESH_DRIVER::merge( driver ); + + const MED_MESH_RDONLY_DRIVER22* other = + dynamic_cast< const MED_MESH_RDONLY_DRIVER22* >( &driver ); + if ( other ) { + _computeFaces = other->_computeFaces; + } +} + void MED_MESH_RDONLY_DRIVER22::read(void) { const char * LOC = "MED_MESH_RDONLY_DRIVER22::read() : " ; - BEGIN_OF(LOC); - if (_status!=MED_OPENED) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The _idt of file " << _fileName << " is : " << _medIdt << " (the file is not opened)." )) ; + BEGIN_OF_MED(LOC); + if (_status != MED_OPENED) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The _idt of file " << _fileName + << " is : " << _medIdt << " (the file is not opened).")); - if ( ( _meshName.empty() ) && ( _ptrMesh->_name.empty() ) ) + if ( ( _meshName.empty() ) && ( _ptrMesh->_name.empty() ) ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) - <<" neither <meshName> is set in driver nor in object MESH.")) ; + <<" neither <meshName> is set in driver nor in object MESH.")); // If _meshName is not set in driver, try to use _ptrMesh->_name - if ( ( _meshName.empty() ) && ( !_ptrMesh->_name.empty() ) ) - _meshName=_ptrMesh->_name; + if ( ( _meshName.empty() ) && ( !_ptrMesh->_name.empty() ) ) + _meshName = _ptrMesh->_name; if ( _meshName.size() > MED_TAILLE_NOM ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<" <meshName> size in object driver MESH is > MED_TAILLE_NOM .")); + _ptrMesh->_name = _meshName; - _ptrMesh->_name = _meshName; + // 0020058: Check version of med, which was used to save the file. + // 0020058: An assertion happens in MEDcoordLire(), if this version + // 0020058: is higher than the currently used version of med product. + med_2_3::med_int aMajor, aMinor, aRelease; + med_2_3::med_int aMajorCurr, aMinorCurr, aReleaseCurr; - SCRUTE(_ptrMesh->getIsAGrid()); + med_err aRet = med_2_3::MEDversionLire(_medIdt, &aMajor, &aMinor, &aRelease); + med_2_3::MEDversionDonner(&aMajorCurr, &aMinorCurr, &aReleaseCurr); + + int aVersionHex = (aMajor << 16 | aMinor << 8 | aRelease); + int aVersionHexCurr = (aMajorCurr << 16 | aMinorCurr << 8 | aReleaseCurr); + + if (aRet != 0 || aVersionHex > aVersionHexCurr) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) + <<" cannot read a file of version higher than the currently used version of med.")); + // 0020058: end of version check + + SCRUTE_MED(_ptrMesh->getIsAGrid()); if (_ptrMesh->getIsAGrid()) { - getGRID( ); + getGRID(); { - if (getFAMILY()!=MED_VALID) + if (getFAMILY() != MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getFAMILY when the mesh is a grid")) ; - buildAllGroups(_ptrMesh->_groupNode,_ptrMesh->_familyNode) ; + buildAllGroups(_ptrMesh->_groupNode, _ptrMesh->_familyNode); } - END_OF(LOC); + END_OF_MED(LOC); return; } else // check that the mesh is really unstructured (PAL14113) { - char meshName[MED_TAILLE_NOM+1]=""; - char meshDescription[MED_TAILLE_DESC+1]=""; + char meshName[MED_TAILLE_NOM+1] = ""; + char meshDescription[MED_TAILLE_DESC+1] = ""; med_2_3::med_int meshDim; med_2_3::med_maillage meshType; - int numberOfMeshes = med_2_3::MEDnMaa(_medIdt); - for (int i=1;i<=numberOfMeshes;i++) + int numberOfMeshes = med_2_3::MEDnMaa(_medIdt); + + for (int i = 1; i <= numberOfMeshes; i++) { - MEDmaaInfo(_medIdt, i ,meshName, &meshDim, &meshType, meshDescription); + MEDmaaInfo(_medIdt, i, meshName, &meshDim, &meshType, meshDescription); if (_meshName == string(meshName)) { - if ( meshType == med_2_3::MED_STRUCTURE ) { + if (meshType == med_2_3::MED_STRUCTURE) { throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "class GRID must be used for a structured mesh")); } @@ -209,14 +242,14 @@ void MED_MESH_RDONLY_DRIVER22::read(void) } } - if (getCOORDINATE()!=MED_VALID) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getCOORDINATE" )) ; - - if (getCONNECTIVITY()!=MED_VALID) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getCOONECTIVITY")) ; - - if (getFAMILY()!=MED_VALID) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getFAMILY" )) ; + if (getCOORDINATE() != MED_VALID) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getCOORDINATE" )); + + if (getCONNECTIVITY() != MED_VALID) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getCOONECTIVITY")); + + if (getFAMILY() != MED_VALID) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERREUR in getFAMILY" )); if (_computeFaces) updateFamily(); @@ -235,15 +268,16 @@ void MED_MESH_RDONLY_DRIVER22::read(void) // on edge buildAllGroups(_ptrMesh->_groupEdge,_ptrMesh->_familyEdge) ; -// MESSAGE(LOC<<"Checking of CellModel !!!!!!!"); + _ptrMesh->_name = healName( _ptrMesh->_name ); +// MESSAGE_MED(LOC<<"Checking of CellModel !!!!!!!"); // int nbOfTypes = _ptrMesh->_connectivity->_numberOfTypes; // for(int i=0;i<nbOfTypes;i++) // { -// MESSAGE(LOC << _ptrMesh->_connectivity->_type[i]) ; +// MESSAGE_MED(LOC << _ptrMesh->_connectivity->_type[i]) ; // } - END_OF(LOC); + END_OF_MED(LOC); } //======================================================================= @@ -254,14 +288,14 @@ void MED_MESH_RDONLY_DRIVER22::read(void) void MED_MESH_RDONLY_DRIVER22::getGRID() { const char * LOC = "MED_MESH_RDONLY_DRIVER22::getGRID() : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status!=MED_OPENED) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "med file is not opened")); GRID * ptrGrid = (GRID *) _ptrMesh; - SCRUTE(ptrGrid); + SCRUTE_MED(ptrGrid); int err, i; @@ -281,7 +315,7 @@ void MED_MESH_RDONLY_DRIVER22::getGRID() err = med_2_3::MEDmaaInfo(_medIdt, (index+1),meshName, &meshDim, &meshType, meshDescription) ; - MESSAGE(LOC<<": Mesh n°"<< (index+1) <<" nammed "<< meshName << " with the description " << meshDescription << " is structured"); + MESSAGE_MED(LOC<<": Mesh n°"<< (index+1) <<" nammed "<< meshName << " with the description " << meshDescription << " is structured"); if (_meshName == string(meshName)) { @@ -304,7 +338,7 @@ void MED_MESH_RDONLY_DRIVER22::getGRID() ptrGrid->_is_default_gridType = false; } - MESSAGE(LOC<<": Mesh processed is nammed "<< _ptrMesh->_name << " with the description " << _ptrMesh->_description << " is structured with the type " << gridType); + MESSAGE_MED(LOC<<": Mesh processed is nammed "<< _ptrMesh->_name << " with the description " << _ptrMesh->_description << " is structured with the type " << gridType); // Read the dimension of the mesh <_meshName> int MeshDimension = med_2_3::MEDdimLire(_medIdt, const_cast <char *> @@ -339,7 +373,7 @@ void MED_MESH_RDONLY_DRIVER22::getGRID() & ptrGrid->_jArrayLength, & ptrGrid->_kArrayLength }; - MESSAGE(LOC << "The mesh is a " << _ptrMesh->_meshDimension << "D mesh on a " << _ptrMesh->_spaceDimension << "D space"); + MESSAGE_MED(LOC << "The mesh is a " << _ptrMesh->_meshDimension << "D mesh on a " << _ptrMesh->_spaceDimension << "D space"); int NumberOfNodes; @@ -361,7 +395,7 @@ void MED_MESH_RDONLY_DRIVER22::getGRID() for (int idim = 0; idim < MeshDimension; idim++) { - MESSAGE(LOC<<"structure dim " << idim << " " << structure[idim]); + MESSAGE_MED(LOC<<"structure dim " << idim << " " << structure[idim]); ArrayLen [idim][0] = structure[idim]; NumberOfNodes = NumberOfNodes*structure[idim]; @@ -496,7 +530,7 @@ void MED_MESH_RDONLY_DRIVER22::getGRID() _ptrMesh->_coordinate->setCoordinatesSystem(coordinateSystem); - END_OF(LOC); + END_OF_MED(LOC); } //======================================================================= @@ -507,18 +541,19 @@ int MED_MESH_RDONLY_DRIVER22::getCOORDINATE() { const char * LOC = "MED_MESH_RDONLY_DRIVER22::getCOORDINATE() : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status==MED_OPENED) - { - int err ; - - int numberOfMeshesInFile = med_2_3::MEDnMaa(_medIdt); + { + int err; - if (numberOfMeshesInFile == MED_INVALID) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Problem in File where the mesh " << _meshName << " is supposed to be stored")); + int numberOfMeshesInFile = med_2_3::MEDnMaa(_medIdt); - for (int index = 0; index < numberOfMeshesInFile; index++) + if (numberOfMeshesInFile == MED_INVALID) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Problem in File where the mesh " << _meshName + << " is supposed to be stored")); + + for (int index = 0; index < numberOfMeshesInFile; index++) { char meshName[MED_TAILLE_NOM+1]=""; char meshDescription[MED_TAILLE_DESC+1]=""; @@ -527,170 +562,165 @@ int MED_MESH_RDONLY_DRIVER22::getCOORDINATE() med_2_3::med_maillage meshType; err = med_2_3::MEDmaaInfo(_medIdt, (index+1), meshName, &meshDim, - &meshType, meshDescription) ; + &meshType, meshDescription) ; - MESSAGE(LOC<<": Mesh n°"<< (index+1) <<" nammed "<< meshName << " with the description " << meshDescription << " is structured"); + MESSAGE_MED(LOC<<": Mesh n°"<< (index+1) <<" nammed "<< meshName + << " with the description " << meshDescription << " is structured"); if (_meshName == string(meshName)) - { - _ptrMesh->_description = meshDescription; - } + { + _ptrMesh->_description = meshDescription; + } } + // Read the dimension of the mesh <_meshName> + int MeshDimension = med_2_3::MEDdimLire(_medIdt, const_cast <char *> + (_meshName.c_str())) ; + + if ( MeshDimension == MED_INVALID ) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The mesh dimension |" << MeshDimension + << "| seems to be incorrect for the mesh : |" << _meshName << "|")); + + _ptrMesh->_meshDimension = MeshDimension; + + // Read or get the dimension of the space for the mesh <_meshName> + int SpaceDimension = MeshDimension; + + int SpaceDimensionRead = med_2_3::MEDdimEspaceLire(_medIdt, + const_cast <char *> + (_meshName.c_str())) ; + + if (SpaceDimensionRead != MED_INVALID) + SpaceDimension = SpaceDimensionRead; + + _ptrMesh->_spaceDimension = SpaceDimension; + + // Read the number of nodes used in the mesh <_meshName> + // to be able to create a COORDINATE object + int NumberOfNodes=MEDnEntMaa(_medIdt, + const_cast <char *> (_meshName.c_str()), + med_2_3::MED_COOR, + med_2_3::MED_NOEUD, + (med_2_3::med_geometrie_element) MED_NONE, + (med_2_3::med_connectivite) MED_NONE); + if ( NumberOfNodes <= MED_VALID ) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"The number of nodes |" << NumberOfNodes + << "| seems to be incorrect for the mesh : |" << _meshName << "|" )); + _ptrMesh->_numberOfNodes = NumberOfNodes; + + // create a COORDINATE object + if (_ptrMesh->_coordinate) + delete _ptrMesh->_coordinate; + _ptrMesh->_coordinate = new COORDINATE(SpaceDimension, NumberOfNodes, MED_EN::MED_FULL_INTERLACE); + + med_2_3::med_repere rep; // ATTENTION ---> DOIT ETRE INTEGRE DS MESH EF: FAIT NON? + string tmp_nom_coord (MED_TAILLE_PNOM22*(_ptrMesh->_spaceDimension)+1,'\0'); + string tmp_unit_coord(MED_TAILLE_PNOM22*(_ptrMesh->_spaceDimension)+1,'\0'); + char * tmp_nom = (const_cast <char *> ( tmp_nom_coord.c_str()) ) ; + char * tmp_unit= (const_cast <char *> ( tmp_unit_coord.c_str()) ) ; + + err=MEDcoordLire(_medIdt, + const_cast <char *> (_ptrMesh->_name.c_str()), + _ptrMesh->_spaceDimension, + const_cast<double *>(_ptrMesh->_coordinate->_coordinate.get(MED_EN::MED_FULL_INTERLACE)), + med_2_3::MED_FULL_INTERLACE, + MED_ALL, // we read all the coordinates + NULL, // we don't use a profile + 0, // so the profile's size is 0 + &rep,tmp_nom,tmp_unit); + if (err != MED_VALID) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't read coordinates of the |" << NumberOfNodes + << "| nodes for the mesh : |" << _meshName + << "| of space dimension |" << SpaceDimension + << "| with units names |" << tmp_nom + << "| and units |" << tmp_unit + << " |")) ; + + for (int i=0;i<_ptrMesh->_spaceDimension;i++) { + string myStringName(tmp_nom_coord,i*MED_TAILLE_PNOM22,MED_TAILLE_PNOM22) ; + string myStringUnit(tmp_unit_coord,i*MED_TAILLE_PNOM22,MED_TAILLE_PNOM22) ; + // suppress space at the end + int j ; + for(j=MED_TAILLE_PNOM22-1;j>=0;j--) + if (myStringName[j] != ' ') break ; + _ptrMesh->_coordinate->_coordinateName[i]=string(myStringName,0,j+1); + for(j=MED_TAILLE_PNOM22-1;j>=0;j--) + if (myStringUnit[j] != ' ') break ; + _ptrMesh->_coordinate->_coordinateUnit[i]=string(myStringUnit,0,j+1); + } - // Read the dimension of the mesh <_meshName> - int MeshDimension = med_2_3::MEDdimLire(_medIdt, const_cast <char *> - (_meshName.c_str())) ; - - if ( MeshDimension == MED_INVALID ) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The mesh dimension |" << - MeshDimension << - "| seems to be incorrect " << - "for the mesh : |" << _meshName << "|")) ; - - _ptrMesh->_meshDimension = MeshDimension; - - // Read or get the dimension of the space for the mesh <_meshName> - int SpaceDimension = MeshDimension; - - int SpaceDimensionRead = med_2_3::MEDdimEspaceLire(_medIdt, - const_cast <char *> - (_meshName.c_str())) ; - - if (SpaceDimensionRead != MED_INVALID) - SpaceDimension = SpaceDimensionRead; - - _ptrMesh->_spaceDimension = SpaceDimension; - - // Read the number of nodes used in the mesh <_meshName> - // to be able to create a COORDINATE object - int NumberOfNodes=MEDnEntMaa(_medIdt, - const_cast <char *> (_meshName.c_str()), - med_2_3::MED_COOR, - med_2_3::MED_NOEUD, - (med_2_3::med_geometrie_element) MED_NONE, - (med_2_3::med_connectivite) MED_NONE); - if ( NumberOfNodes <= MED_VALID ) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"The number of nodes |" << NumberOfNodes << "| seems to be incorrect " - << "for the mesh : |" << _meshName << "|" )) ; - _ptrMesh->_numberOfNodes = NumberOfNodes ; - - // create a COORDINATE object - if (_ptrMesh->_coordinate) - delete _ptrMesh->_coordinate; - _ptrMesh->_coordinate = new COORDINATE(SpaceDimension, NumberOfNodes, MED_EN::MED_FULL_INTERLACE); - - med_2_3::med_repere rep ; // ATTENTION ---> DOIT ETRE INTEGRE DS MESH EF: FAIT NON? - string tmp_nom_coord (MED_TAILLE_PNOM22*(_ptrMesh->_spaceDimension)+1,'\0'); - string tmp_unit_coord(MED_TAILLE_PNOM22*(_ptrMesh->_spaceDimension)+1,'\0'); - char * tmp_nom = (const_cast <char *> ( tmp_nom_coord.c_str()) ) ; - char * tmp_unit= (const_cast <char *> ( tmp_unit_coord.c_str()) ) ; - - err=MEDcoordLire(_medIdt, - const_cast <char *> (_ptrMesh->_name.c_str()), - _ptrMesh->_spaceDimension, - //const_cast <double *> ( _ptrMesh->_coordinate->_coordinate->get(MED_EN::MED_FULL_INTERLACE) ), - const_cast <double *> ( _ptrMesh->_coordinate->_coordinate.get(MED_EN::MED_FULL_INTERLACE) ), - med_2_3::MED_FULL_INTERLACE, - MED_ALL, // we read all the coordinates - NULL, // we don't use a profile - 0, // so the profile's size is 0 - &rep,tmp_nom,tmp_unit); - if (err != MED_VALID) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"Can't read coordinates of the |" << NumberOfNodes << "| nodes " - << "for the mesh : |" << _meshName - << "| of space dimension |" << SpaceDimension - << "| with units names |" << tmp_nom - << "| and units |" << tmp_unit - << " |")) ; - - - for (int i=0;i<_ptrMesh->_spaceDimension;i++) { - string myStringName(tmp_nom_coord,i*MED_TAILLE_PNOM22,MED_TAILLE_PNOM22) ; - string myStringUnit(tmp_unit_coord,i*MED_TAILLE_PNOM22,MED_TAILLE_PNOM22) ; - // suppress space at the end - int j ; - for(j=MED_TAILLE_PNOM22-1;j>=0;j--) - if (myStringName[j] != ' ') break ; - _ptrMesh->_coordinate->_coordinateName[i]=string(myStringName,0,j+1); - for(j=MED_TAILLE_PNOM22-1;j>=0;j--) - if (myStringUnit[j] != ' ') break ; - _ptrMesh->_coordinate->_coordinateUnit[i]=string(myStringUnit,0,j+1); + // Pourquoi le stocker sous forme de chaîne ? + switch (rep) + { + case med_2_3::MED_CART : + { + _ptrMesh->_coordinate->_coordinateSystem = "CARTESIAN"; + break ; } + case med_2_3::MED_CYL : + { + _ptrMesh->_coordinate->_coordinateSystem = "CYLINDRICAL"; + break ; + } + case med_2_3::MED_SPHER : + { + _ptrMesh->_coordinate->_coordinateSystem = "SPHERICAL"; + break ; + } + default : + { + _ptrMesh->_coordinate->_coordinateSystem = "UNDEFINED"; // ?Erreur ? + break ; + } + } - // Pourquoi le stocker sous forme de chaîne ? - switch (rep) - { - case med_2_3::MED_CART : - { - _ptrMesh->_coordinate->_coordinateSystem = "CARTESIAN"; - break ; - } - case med_2_3::MED_CYL : - { - _ptrMesh->_coordinate->_coordinateSystem = "CYLINDRICAL"; - break ; - } - case med_2_3::MED_SPHER : - { - _ptrMesh->_coordinate->_coordinateSystem = "SPHERICAL"; - break ; - } - default : - { - _ptrMesh->_coordinate->_coordinateSystem = "UNDEFINED"; // ?Erreur ? - break ; - } - } - - // Read the unused optional node Names - char * tmp_node_name = new char[NumberOfNodes*MED_TAILLE_PNOM22+1]; - tmp_node_name[NumberOfNodes]='\0' ; - err=MEDnomLire(_medIdt,const_cast <char*> (_ptrMesh->_name.c_str()), - tmp_node_name,NumberOfNodes*MED_TAILLE_PNOM22,med_2_3::MED_NOEUD, - (med_2_3::med_geometrie_element) MED_NONE); - if (err == MED_VALID) - MESSAGE(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : WARNING : Nodes have names but we do not read them !"); - delete[] tmp_node_name ; - - - // ??? Read the unused optional node Numbers ??? - med_2_3::med_int * tmp_node_number = new med_2_3::med_int[NumberOfNodes] ; - err=MEDnumLire(_medIdt,const_cast <char*> (_ptrMesh->_name.c_str()), - tmp_node_number,NumberOfNodes,med_2_3::MED_NOEUD,(med_2_3::med_geometrie_element)0); - if (err == MED_VALID) { - // INFOS(LOC<<"WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING"); - // INFOS(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : WARNING : Nodes have numbers but we do not take care of them !"); - // INFOS(LOC<<"WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING"); - MESSAGE(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : Nodes have numbers, we DO TAKE care of them !"); - _ptrMesh->_coordinate->_nodeNumber.set(NumberOfNodes) ; + // Read the unused optional node Names + char * tmp_node_name = new char[NumberOfNodes*MED_TAILLE_PNOM22+1]; + tmp_node_name[NumberOfNodes]='\0' ; + err=MEDnomLire(_medIdt,const_cast <char*> (_ptrMesh->_name.c_str()), + tmp_node_name,NumberOfNodes*MED_TAILLE_PNOM22,med_2_3::MED_NOEUD, + (med_2_3::med_geometrie_element) MED_NONE); + if (err == MED_VALID) + MESSAGE_MED(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : WARNING : Nodes have names but we do not read them !"); + delete[] tmp_node_name ; + + // ??? Read the unused optional node Numbers ??? + med_2_3::med_int * tmp_node_number = new med_2_3::med_int[NumberOfNodes] ; + err=MEDnumLire(_medIdt,const_cast <char*> (_ptrMesh->_name.c_str()), + tmp_node_number,NumberOfNodes,med_2_3::MED_NOEUD,(med_2_3::med_geometrie_element)0); + if (err == MED_VALID) { + // INFOS_MED(LOC<<"WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING"); + // INFOS_MED(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : WARNING : Nodes have numbers but we do not take care of them !"); + // INFOS_MED(LOC<<"WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING"); + MESSAGE_MED(LOC<<"MED_MESH_RDONLY_DRIVER::getNoeuds() : Nodes have numbers, we DO TAKE care of them !"); + _ptrMesh->_coordinate->_nodeNumber.set(NumberOfNodes) ; #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64) - for(med_2_3::med_int i2=0;i2<NumberOfNodes;i2++) - _ptrMesh->_coordinate->_nodeNumber[i2]=(int)(tmp_node_number[i2]); + for(med_2_3::med_int i2=0;i2<NumberOfNodes;i2++) + _ptrMesh->_coordinate->_nodeNumber[i2]=(int)(tmp_node_number[i2]); #else - memcpy((int*)_ptrMesh->_coordinate->_nodeNumber,tmp_node_number,sizeof(int)*NumberOfNodes) ; + memcpy((int*)_ptrMesh->_coordinate->_nodeNumber,tmp_node_number,sizeof(int)*NumberOfNodes) ; #endif - - ////////////////////////////////////////////////////////////////////////////////////// - /// Modification pour prise en compte de la numérotation optionnelle des noeuds /// - ////////////////////////////////////////////////////////////////////////////////////// - /// - /// Calcule _optionnalToCanonicNodesNumbers de telle sorte que _optionnalToCanonicNodesNumbers[OptionnalNumber]==CanonicNumber - -// _ptrMesh->_arePresentOptionnalNodesNumbers=1; -// for (int canonicNumber=1;canonicNumber<=NumberOfNodes;canonicNumber++) _ptrMesh->_optionnalToCanonicNodesNumbers[tmp_node_number[canonicNumber-1]]=canonicNumber; -// ICI RETOUR A LA NORMALE::: AUCUNE PRISE EN COMPTE D'UN NUMEROTATION OPTIONNEL - _ptrMesh->_arePresentOptionnalNodesNumbers=0; - } - else _ptrMesh->_arePresentOptionnalNodesNumbers=0; - ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + /// Modification pour prise en compte de la numérotation optionnelle des noeuds /// + ////////////////////////////////////////////////////////////////////////////////////// + /// + /// Calcule _optionnalToCanonicNodesNumbers de telle sorte que _optionnalToCanonicNodesNumbers[OptionnalNumber]==CanonicNumber - delete[] tmp_node_number ; - - END_OF(LOC); - return MED_VALID; + // _ptrMesh->_arePresentOptionnalNodesNumbers=1; + // for (int canonicNumber=1;canonicNumber<=NumberOfNodes;canonicNumber++) _ptrMesh->_optionnalToCanonicNodesNumbers[tmp_node_number[canonicNumber-1]]=canonicNumber; + // ICI RETOUR A LA NORMALE::: AUCUNE PRISE EN COMPTE D'UN NUMEROTATION OPTIONNEL + _ptrMesh->_arePresentOptionnalNodesNumbers=0; } + else _ptrMesh->_arePresentOptionnalNodesNumbers=0; + + ////////////////////////////////////////////////////////////////////////////////////// + + delete[] tmp_node_number; + + END_OF_MED(LOC); + return MED_VALID; + } return MED_ERROR; } @@ -698,7 +728,7 @@ int MED_MESH_RDONLY_DRIVER22::getCOORDINATE() int MED_MESH_RDONLY_DRIVER22::getCONNECTIVITY() { const char * LOC = "MED_MESH_RDONLY_DRIVER22::getCONNECTIVITY : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status==MED_OPENED) { @@ -729,7 +759,7 @@ int MED_MESH_RDONLY_DRIVER22::getCONNECTIVITY() } if (Connectivity->_entityDimension != _ptrMesh->_meshDimension) - MESSAGE(LOC << "Small mesh dimension problem on the med file mounted in memory : diim stored " << _ptrMesh->_meshDimension << " dim computed using the connectivity " << Connectivity->_entityDimension); + MESSAGE_MED(LOC << "Small mesh dimension problem on the med file mounted in memory : diim stored " << _ptrMesh->_meshDimension << " dim computed using the connectivity " << Connectivity->_entityDimension); _ptrMesh->_meshDimension = Connectivity->_entityDimension ; @@ -745,21 +775,21 @@ int MED_MESH_RDONLY_DRIVER22::getCONNECTIVITY() if(Connectivity->_constituent==NULL) { - SCRUTE(_ptrMesh->_meshDimension); - SCRUTE(Connectivity->_entityDimension); + SCRUTE_MED(_ptrMesh->_meshDimension); + SCRUTE_MED(Connectivity->_entityDimension); if (_ptrMesh->_meshDimension == 3) { - MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DES FACES..." ); + MESSAGE_MED(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DES FACES..." ); CONNECTIVITY * ConnectivityFace = new CONNECTIVITY(MED_EN::MED_FACE) ; ConnectivityFace->_typeConnectivity = Connectivity->_typeConnectivity ; // NODAL or DESCENDING - SCRUTE(ConnectivityFace->_typeConnectivity); + SCRUTE_MED(ConnectivityFace->_typeConnectivity); if (Connectivity->_typeConnectivity == MED_DESCENDING) { - MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DESCENDANTE DES FACES" ); + MESSAGE_MED(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DESCENDANTE DES FACES" ); err = getDescendingConnectivity(ConnectivityFace) ; if (err!=MED_VALID) throw MEDEXCEPTION ( LOCALIZED(STRING(LOC) << "No FACE in descending connectivity")) ; getNodalConnectivity(ConnectivityFace) ; // if any ! } else { - MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE NODALE DES FACES" ); + MESSAGE_MED(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE NODALE DES FACES" ); err = getNodalConnectivity(ConnectivityFace) ; if (err!=MED_VALID) { // or error ????? we are in NODAL mode. err = getDescendingConnectivity(ConnectivityFace) ; @@ -768,9 +798,9 @@ int MED_MESH_RDONLY_DRIVER22::getCONNECTIVITY() } if (err!=MED_VALID) { delete ConnectivityFace ; - MESSAGE(LOC<<"No FACE defined.") ; + MESSAGE_MED(LOC<<"No FACE defined.") ; } else { - MESSAGE(LOC<<" SAUVEGARDE DE LA CONNECTIVITE DES FACES DANS L'OBJET CONNECTIVITY" ); + MESSAGE_MED(LOC<<" SAUVEGARDE DE LA CONNECTIVITE DES FACES DANS L'OBJET CONNECTIVITY" ); delete Connectivity->_constituent; Connectivity->_constituent=ConnectivityFace; } @@ -778,17 +808,17 @@ int MED_MESH_RDONLY_DRIVER22::getCONNECTIVITY() // read MED_EDGE connectivity if (_ptrMesh->_meshDimension > 1) { // we are in 3 or 2D - MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DES ARRETES...." ); + MESSAGE_MED(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DES ARRETES...." ); CONNECTIVITY * ConnectivityEdge = new CONNECTIVITY(MED_EDGE) ; ConnectivityEdge->_typeConnectivity = Connectivity->_typeConnectivity ; if (Connectivity->_typeConnectivity == MED_DESCENDING) { - MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DESCENDANTE DES ARRETES" ); + MESSAGE_MED(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE DESCENDANTE DES ARRETES" ); err = getDescendingConnectivity(ConnectivityEdge) ; if (err!=MED_VALID) throw MEDEXCEPTION ( LOCALIZED(STRING(LOC) << "No EDGE in descending connectivity")) ; getNodalConnectivity(ConnectivityEdge) ; // if any ! } else { - MESSAGE(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE NODALE DES ARRETES" ); + MESSAGE_MED(LOC<<" ESSAI DE LECTURE DE LA CONNECTIVITE NODALE DES ARRETES" ); err = getNodalConnectivity(ConnectivityEdge) ; if (err!=MED_VALID) { // or error ????? we are in NODAL mode. err = getDescendingConnectivity(ConnectivityEdge) ; @@ -797,7 +827,7 @@ int MED_MESH_RDONLY_DRIVER22::getCONNECTIVITY() } if (err!=MED_VALID) { delete ConnectivityEdge ; - MESSAGE(LOC<<"No EDGE defined.") ; + MESSAGE_MED(LOC<<"No EDGE defined.") ; } else { if (_ptrMesh->_meshDimension == 3) if (Connectivity->_constituent != NULL) @@ -805,7 +835,7 @@ int MED_MESH_RDONLY_DRIVER22::getCONNECTIVITY() else throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<< "EDGE defined but there are no FACE !")) ; else { // IN 2D - MESSAGE(LOC<<" SAUVEGARDE DE LA CONNECTIVITE DES ARETES DANS L'OBJET CONNECTIVITY" ); + MESSAGE_MED(LOC<<" SAUVEGARDE DE LA CONNECTIVITE DES ARETES DANS L'OBJET CONNECTIVITY" ); Connectivity->_constituent=ConnectivityEdge ; } } @@ -832,7 +862,7 @@ int MED_MESH_RDONLY_DRIVER22::getCONNECTIVITY() // } - END_OF(LOC); + END_OF_MED(LOC); return MED_VALID; } return MED_ERROR; @@ -841,12 +871,12 @@ int MED_MESH_RDONLY_DRIVER22::getCONNECTIVITY() int MED_MESH_RDONLY_DRIVER22::getNodalConnectivity(CONNECTIVITY * Connectivity) { const char * LOC = "MED_MESH_RDONLY_DRIVER22::getNodalConnectivity : " ; - BEGIN_OF(LOC); - + BEGIN_OF_MED(LOC); + if (_status==MED_OPENED) { int spaceDimension = _ptrMesh->_spaceDimension; - + // Get the type of entity to work on (previously set in the Connectivity Object) med_2_3::med_entite_maillage Entity = (med_2_3::med_entite_maillage) Connectivity->getEntity(); @@ -858,8 +888,8 @@ int MED_MESH_RDONLY_DRIVER22::getNodalConnectivity(CONNECTIVITY * Connectivity) tmp_cells_count[i]=MEDnEntMaa(_medIdt,(const_cast <char *> (_ptrMesh->_name.c_str())), med_2_3::MED_CONN,(med_2_3::med_entite_maillage) Entity, all_cell_type[i],med_2_3::MED_NOD); - - + + // Get the greatest dimension of the cells : Connectivity->_entityDimension // We suppose there is no cells used as faces in MED 2.2.x , this is forbidden !!! // In version prior to 2.2.x, it is possible @@ -897,506 +927,471 @@ int MED_MESH_RDONLY_DRIVER22::getNodalConnectivity(CONNECTIVITY * Connectivity) // begin classic geometric types if (Connectivity->_numberOfTypes > 0) - { - // if MED version < 2.2.x, we read only entity with dimention = Connectivity->_entityDimension. Lesser dimension are face or edge ! - + { + // if MED version < 2.2.x, we read only entity with dimention = Connectivity->_entityDimension. Lesser dimension are face or edge ! + med_2_3::med_int major, minor, release; - + if ( med_2_3::MEDversionLire(_medIdt, &major, &minor, &release) != 0 ) - { - // error : we suppose we have not a good med file ! - delete[] tmp_cells_count ; - return MED_ERROR ; - } - - // we get MED version number - // If MED version is < 2.2 then the cells which dimension - // is lesser than the main dimension ( Connectivity->_entityDimension ) - // are either faces or edges - - // string medVersion(version_med); - // int firstNumber = - int * tmpEdgeCount = new int[MED_NBR_GEOMETRIE_MAILLE] ; - tmpEdgeCount[0] = 0 ; - int numberOfEdgesTypes = 0; - int * tmpFaceCount = new int[MED_NBR_GEOMETRIE_MAILLE] ; - tmpFaceCount[0] = 0 ; - int numberOfFacesTypes = 0; - -// if ((version_med != "2.2")&(Entity==MED_FR::MED_MAILLE)) -// { -// Connectivity->_numberOfTypes=0; - -// for ( i=1;i<MED_NBR_GEOMETRIE_MAILLE;i++) -// { -// tmpFaceCount[i]=0; -// tmpEdgeCount[i]=0; -// if (tmp_cells_count[i]!=0) -// { -// int dimension = all_cell_type[i]/100 ; -// if (Connectivity->_entityDimension==dimension) -// Connectivity->_numberOfTypes++ ; - -// if (dimension == 2) -// if (Connectivity->_entityDimension==3) -// { -// tmpFaceCount[i]=tmp_cells_count[i] ; -// tmp_cells_count[i]=0 ; -// numberOfFacesTypes++; -// } -// if (dimension == 1) -// if (Connectivity->_entityDimension>dimension) -// { -// tmpEdgeCount[i]=tmp_cells_count[i] ; -// tmp_cells_count[i]=0; -// numberOfEdgesTypes++ ; -// } -// } -// } -// } - - if (Entity==med_2_3::MED_MAILLE) - { - Connectivity->_numberOfTypes=0; - - for ( i=1;i<MED_NBR_GEOMETRIE_MAILLE;i++) - { - tmpFaceCount[i]=0; - tmpEdgeCount[i]=0; - if (tmp_cells_count[i]!=0) - { - int dimension = all_cell_type[i]/100 ; - if (Connectivity->_entityDimension==dimension) - Connectivity->_numberOfTypes++ ; + { + // error : we suppose we have not a good med file ! + delete[] tmp_cells_count ; + return MED_ERROR ; + } + + // we get MED version number + // If MED version is < 2.2 then the cells which dimension + // is lesser than the main dimension ( Connectivity->_entityDimension ) + // are either faces or edges + + int * tmpEdgeCount = new int[MED_NBR_GEOMETRIE_MAILLE] ; + tmpEdgeCount[0] = 0 ; + int numberOfEdgesTypes = 0; + int * tmpFaceCount = new int[MED_NBR_GEOMETRIE_MAILLE] ; + tmpFaceCount[0] = 0 ; + int numberOfFacesTypes = 0; - if (dimension == 2) - if (Connectivity->_entityDimension==3) - { - tmpFaceCount[i]=tmp_cells_count[i] ; - //tmp_cells_count[i]=0 ; - //Connectivity->_numberOfTypes++ ; - numberOfFacesTypes++; - } - if (dimension == 1) - if (Connectivity->_entityDimension>dimension) - { - tmpEdgeCount[i]=tmp_cells_count[i] ; - //tmp_cells_count[i]=0; - //Connectivity->_numberOfTypes++ ; - numberOfEdgesTypes++ ; - } - } - } - } - - // bloc to read CELL : - { - // Prepare an array of indexes on the different cell types to create a MEDSKYLINEARRAY - // We use <tmp_cells_count> to calculate <Connectivity->_count> then we release it - Connectivity->_geometricTypes = new MED_EN::medGeometryElement [Connectivity->_numberOfTypes] ; // Double emploi pour des raisons pratiques - Connectivity->_type = new CELLMODEL [Connectivity->_numberOfTypes] ; // - Connectivity->_count = new int [Connectivity->_numberOfTypes+1] ; - Connectivity->_count[0] = 1; - - int size = 0 ; - int typeNumber=1 ; - int i; - for ( i=1;i<MED_NBR_GEOMETRIE_MAILLE;i++) - { // no point1 cell type (?) - int dimension = all_cell_type[i]/100 ; - if ((tmp_cells_count[i]>0) && (Connectivity->_entityDimension == dimension)) - { - Connectivity->_count[typeNumber]=Connectivity->_count[typeNumber-1]+tmp_cells_count[i]; - - CELLMODEL t( (MED_EN::medGeometryElement) MED_MESH_DRIVER22::all_cell_type[i]) ; - - Connectivity->_type[typeNumber-1] = t ; - - Connectivity->_geometricTypes[typeNumber-1]=( MED_EN::medGeometryElement) MED_MESH_DRIVER22::all_cell_type[i] ; - - // probleme avec les mailles de dimension < a dimension du maillage : - // Il faut oter le zero a la lecture est le remettre a l'ecriture : ce n'est pas fait !!!!! On interdit ce cas pour l'instant !!! - - - size+=tmp_cells_count[i]*((MED_MESH_DRIVER22::all_cell_type[i])%100) ; - - MESSAGE(LOC - << Connectivity->_count[typeNumber]-1 << " cells of type " - << all_cell_type_tab[i] ); - typeNumber++; - } - } - - // Creation of the MEDSKYLINEARRAY - //Connectivity->_nodal = new MEDSKYLINEARRAY(Connectivity->_count[Connectivity->_numberOfTypes]-1,size) ; + + if (Entity==med_2_3::MED_MAILLE) + { + Connectivity->_numberOfTypes=0; + + for ( i=1;i<MED_NBR_GEOMETRIE_MAILLE;i++) + { + tmpFaceCount[i]=0; + tmpEdgeCount[i]=0; + if (tmp_cells_count[i]!=0) + { + int dimension = all_cell_type[i]/100 ; + if (Connectivity->_entityDimension==dimension) + Connectivity->_numberOfTypes++ ; + + if (dimension == 2) + if (Connectivity->_entityDimension==3) + { + tmpFaceCount[i]=tmp_cells_count[i] ; + //tmp_cells_count[i]=0 ; + //Connectivity->_numberOfTypes++ ; + numberOfFacesTypes++; + } + if (dimension == 1) + if (Connectivity->_entityDimension>dimension) + { + tmpEdgeCount[i]=tmp_cells_count[i] ; + //tmp_cells_count[i]=0; + //Connectivity->_numberOfTypes++ ; + numberOfEdgesTypes++ ; + } + } + } + } + + // bloc to read CELL : + { + // Prepare an array of indexes on the different cell types to create a MEDSKYLINEARRAY + // We use <tmp_cells_count> to calculate <Connectivity->_count> then we release it + Connectivity->_geometricTypes = new MED_EN::medGeometryElement [Connectivity->_numberOfTypes] ; // Double emploi pour des raisons pratiques + Connectivity->_type = new CELLMODEL [Connectivity->_numberOfTypes] ; // + if(Connectivity->_count) + delete [] Connectivity->_count; + Connectivity->_count = new int [Connectivity->_numberOfTypes+1] ; + Connectivity->_count[0] = 1; + + int size = 0 ; + int typeNumber=1 ; + int i; + for ( i=1;i<MED_NBR_GEOMETRIE_MAILLE;i++) + { // no point1 cell type (?) + int dimension = all_cell_type[i]/100 ; + if ((tmp_cells_count[i]>0) && (Connectivity->_entityDimension == dimension)) + { + Connectivity->_count[typeNumber]=Connectivity->_count[typeNumber-1]+tmp_cells_count[i]; + + CELLMODEL t( (MED_EN::medGeometryElement) MED_MESH_DRIVER22::all_cell_type[i]) ; + + Connectivity->_type[typeNumber-1] = t ; + + Connectivity->_geometricTypes[typeNumber-1]=( MED_EN::medGeometryElement) MED_MESH_DRIVER22::all_cell_type[i] ; + + // probleme avec les mailles de dimension < a dimension du maillage : + // Il faut oter le zero a la lecture est le remettre a l'ecriture : ce n'est pas fait !!!!! On interdit ce cas pour l'instant !!! + + + size+=tmp_cells_count[i]*((MED_MESH_DRIVER22::all_cell_type[i])%100) ; + + MESSAGE_MED(LOC + << Connectivity->_count[typeNumber]-1 << " cells of type " + << all_cell_type_tab[i] ); + typeNumber++; + } + } + + // Creation of the MEDSKYLINEARRAY + //Connectivity->_nodal = new MEDSKYLINEARRAY(Connectivity->_count[Connectivity->_numberOfTypes]-1,size) ; //int * NodalIndex = Connectivity->_nodal->getIndex() ; - int * NodalValue = new int[size] ; - int * NodalIndex = new int[Connectivity->_count[Connectivity->_numberOfTypes]] ; - NodalIndex[0]=1 ; - - // Fill the MEDSKYLINEARRAY by reading the MED file. - int j=0; - for ( i=0;i<Connectivity->_numberOfTypes;i++) - { - int multi = 0 ; - med_2_3::med_geometrie_element med_type = (med_2_3::med_geometrie_element) Connectivity->_type[i].getType() ; - // if ( Connectivity->_type[i].getDimension() < Connectivity->_entityDimension) - // if (Connectivity->_entity == MED_CELL) - // if ( Connectivity->_type[i].getDimension() < _ptrMesh->_spaceDimension) - // multi=1; - - // int NumberOfCell = Connectivity->_count[i+1]-Connectivity->_count[i] ; - int NumberOfNodeByCell = Connectivity->_type[i].getNumberOfNodes() ; - - // initialise index - for ( j=Connectivity->_count[i]; j<Connectivity->_count[i+1];j++) - NodalIndex[j]=NodalIndex[j-1]+NumberOfNodeByCell ; - - int tmp_numberOfCells = Connectivity->_count[i+1]-Connectivity->_count[i] ; -//CCRT int * tmp_ConnectivityArray = new int[(NumberOfNodeByCell+multi)*tmp_numberOfCells]; - med_2_3::med_int * tmp_ConnectivityArray = new med_2_3::med_int[(NumberOfNodeByCell+multi)*tmp_numberOfCells]; - - // int err=MEDconnLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()), - // Connectivity->_entityDimension,tmp_ConnectivityArray, - // MED_FR::MED_FULL_INTERLACE,NULL,0,Entity,med_type,MED_FR::MED_NOD); - int err=MEDconnLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()), - spaceDimension,tmp_ConnectivityArray, - med_2_3::MED_FULL_INTERLACE,NULL,0,Entity,med_type,med_2_3::MED_NOD); - - if ( err != MED_VALID) - { - delete[] tmp_ConnectivityArray; - delete[] tmp_cells_count; - delete[] tmpFaceCount; - delete[] tmpEdgeCount; - MESSAGE(LOC<<": MEDconnLire returns "<<err) ; - return MED_ERROR ; - } - - int * ConnectivityArray = NodalValue + NodalIndex[Connectivity->_count[i]-1]-1 ; - - // version originale sans prise en compte des numéros optionnels - // - for ( j=0; j<tmp_numberOfCells; j++) for (int k=0; k<NumberOfNodeByCell; k++) - ConnectivityArray[j*NumberOfNodeByCell+k]=tmp_ConnectivityArray[j*(NumberOfNodeByCell+multi)+k] ; - - ////////////////////////////////////////////////////////////////////////////// - // Modification pour prise en compte de la numérotation optionnelle des noeuds /// - ////////////////////////////////////////////////////////////////////////////// - // - // Rénumérote le tableau temporaire tmp_ConnectivityArray en utilisant _optionnalToCanonicNodesNumbers - // Le traitement est identique à la version originelle s'il n'y a pas de numérotation optionnelle + int * NodalValue = new int[size] ; + int * NodalIndex = new int[Connectivity->_count[Connectivity->_numberOfTypes]] ; + NodalIndex[0]=1 ; + + // Fill the MEDSKYLINEARRAY by reading the MED file. + int j=0; + for ( i=0;i<Connectivity->_numberOfTypes;i++) + { + int multi = 0 ; + med_2_3::med_geometrie_element med_type = (med_2_3::med_geometrie_element) Connectivity->_type[i].getType() ; + // if ( Connectivity->_type[i].getDimension() < Connectivity->_entityDimension) + // if (Connectivity->_entity == MED_CELL) + // if ( Connectivity->_type[i].getDimension() < _ptrMesh->_spaceDimension) + // multi=1; + + // int NumberOfCell = Connectivity->_count[i+1]-Connectivity->_count[i] ; + int NumberOfNodeByCell = Connectivity->_type[i].getNumberOfNodes() ; + + // initialise index + for ( j=Connectivity->_count[i]; j<Connectivity->_count[i+1];j++) + NodalIndex[j]=NodalIndex[j-1]+NumberOfNodeByCell ; + + int tmp_numberOfCells = Connectivity->_count[i+1]-Connectivity->_count[i] ; + //CCRT int * tmp_ConnectivityArray = new int[(NumberOfNodeByCell+multi)*tmp_numberOfCells]; + med_2_3::med_int * tmp_ConnectivityArray = new med_2_3::med_int[(NumberOfNodeByCell+multi)*tmp_numberOfCells]; + int err=MEDconnLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()), + spaceDimension,tmp_ConnectivityArray, + med_2_3::MED_FULL_INTERLACE,NULL,0,Entity,med_type,med_2_3::MED_NOD); + + if ( err != MED_VALID) + { + delete[] tmp_ConnectivityArray; + delete[] tmp_cells_count; + delete[] tmpFaceCount; + delete[] tmpEdgeCount; + MESSAGE_MED(LOC<<": MEDconnLire returns "<<err) ; + return MED_ERROR ; + } + + int * ConnectivityArray = NodalValue + NodalIndex[Connectivity->_count[i]-1]-1 ; + + // version originale sans prise en compte des numéros optionnels + // + for ( j=0; j<tmp_numberOfCells; j++) for (int k=0; k<NumberOfNodeByCell; k++) + ConnectivityArray[j*NumberOfNodeByCell+k]=tmp_ConnectivityArray[j*(NumberOfNodeByCell+multi)+k] ; + + ////////////////////////////////////////////////////////////////////////////// + // Modification pour prise en compte de la numérotation optionnelle des noeuds /// + ////////////////////////////////////////////////////////////////////////////// + // + // Rénumérote le tableau temporaire tmp_ConnectivityArray en utilisant _optionnalToCanonicNodesNumbers + // Le traitement est identique à la version originelle s'il n'y a pas de numérotation optionnelle - // if (_ptrMesh->_arePresentOptionnalNodesNumbers==1) - // { - // for ( j=0; j<tmp_numberOfCells; j++) for (int k=0; k<NumberOfNodeByCell; k++) - // ConnectivityArray[j*NumberOfNodeByCell+k]=_ptrMesh->_optionnalToCanonicNodesNumbers[tmp_ConnectivityArray[j*(NumberOfNodeByCell+multi)+k]] ; - // } - // else - // { - // for ( j=0; j<tmp_numberOfCells; j++) for (int k=0; k<NumberOfNodeByCell; k++) - // ConnectivityArray[j*NumberOfNodeByCell+k]=tmp_ConnectivityArray[j*(NumberOfNodeByCell+multi)+k] ; - // } - //////////////////////////////////////////////////////////////////////////// + // if (_ptrMesh->_arePresentOptionnalNodesNumbers==1) + // { + // for ( j=0; j<tmp_numberOfCells; j++) for (int k=0; k<NumberOfNodeByCell; k++) + // ConnectivityArray[j*NumberOfNodeByCell+k]=_ptrMesh->_optionnalToCanonicNodesNumbers[tmp_ConnectivityArray[j*(NumberOfNodeByCell+multi)+k]] ; + // } + // else + // { + // for ( j=0; j<tmp_numberOfCells; j++) for (int k=0; k<NumberOfNodeByCell; k++) + // ConnectivityArray[j*NumberOfNodeByCell+k]=tmp_ConnectivityArray[j*(NumberOfNodeByCell+multi)+k] ; + // } + //////////////////////////////////////////////////////////////////////////// - delete[] tmp_ConnectivityArray; + delete[] tmp_ConnectivityArray; - } + } - Connectivity->_nodal = new MEDSKYLINEARRAY(Connectivity->_count[Connectivity->_numberOfTypes]-1, - size, - NodalIndex, - NodalValue) ; + Connectivity->_nodal = new MEDSKYLINEARRAY(Connectivity->_count[Connectivity->_numberOfTypes]-1, + size, + NodalIndex, + NodalValue) ; - delete[] NodalIndex; - delete[] NodalValue; + delete[] NodalIndex; + delete[] NodalValue; - } // end of bloc to read CELL + } // end of bloc to read CELL - // Get Face if any - // =============== + // Get Face if any + // =============== - if (numberOfFacesTypes!=0) - { - - // Create a CONNECTIVITY constituent to put in the top level CONNECTIVITY recursive class - CONNECTIVITY * constituent = new CONNECTIVITY(numberOfFacesTypes,MED_EN::MED_FACE) ; - constituent->_entityDimension = 2 ; - constituent->_count[0]=1 ; - - // In order to create the MEDSKYLINEARRAY of the constituent object we need : - // 1: - // To initialize the _count array of the constituent object (containning cumulated face count by geometric type) - // _count[0]=1 and _count[_numberOfTypes] give the size of NodalIndex - // 2: - // To calculate the total number of face nodes whatever the geometric type is. - // The result is the size of the array containning all the nodes : NodalValue - // 3 : - // To calculate the starting indexes of the different face types in NodalValue, - // this is the NodalIndex array. + if (numberOfFacesTypes!=0) + { + + // Create a CONNECTIVITY constituent to put in the top level CONNECTIVITY recursive class + CONNECTIVITY * constituent = new CONNECTIVITY(numberOfFacesTypes,MED_EN::MED_FACE) ; + constituent->_entityDimension = 2 ; + constituent->_count[0]=1 ; + + // In order to create the MEDSKYLINEARRAY of the constituent object we need : + // 1: + // To initialize the _count array of the constituent object (containning cumulated face count by geometric type) + // _count[0]=1 and _count[_numberOfTypes] give the size of NodalIndex + // 2: + // To calculate the total number of face nodes whatever the geometric type is. + // The result is the size of the array containning all the nodes : NodalValue + // 3 : + // To calculate the starting indexes of the different face types in NodalValue, + // this is the NodalIndex array. - int size = 0 ; - int typeNumber = 1 ; - int i; - for ( i=1; i < MED_NBR_GEOMETRIE_MAILLE; i++) - { // no point1 cell type (?) - if (tmpFaceCount[i]>0) - { - constituent->_count[typeNumber] = constituent->_count[typeNumber-1] + tmpFaceCount[i]; - CELLMODEL t( (MED_EN::medGeometryElement) MED_MESH_DRIVER22::all_cell_type[i]) ; - constituent->_type[typeNumber-1]=t ; + int size = 0 ; + int typeNumber = 1 ; + int i; + for ( i=1; i < MED_NBR_GEOMETRIE_MAILLE; i++) + { // no point1 cell type (?) + if (tmpFaceCount[i]>0) + { + constituent->_count[typeNumber] = constituent->_count[typeNumber-1] + tmpFaceCount[i]; + CELLMODEL t( (MED_EN::medGeometryElement) MED_MESH_DRIVER22::all_cell_type[i]) ; + constituent->_type[typeNumber-1]=t ; - constituent->_geometricTypes[typeNumber-1]=( MED_EN::medGeometryElement) MED_MESH_DRIVER22::all_cell_type[i] ; + constituent->_geometricTypes[typeNumber-1]=( MED_EN::medGeometryElement) MED_MESH_DRIVER22::all_cell_type[i] ; - size+=tmpFaceCount[i]*((MED_MESH_DRIVER22::all_cell_type[i])%100) ; - typeNumber++; - } - } + size+=tmpFaceCount[i]*((MED_MESH_DRIVER22::all_cell_type[i])%100) ; + typeNumber++; + } + } - // Creation of the MEDSKYLINEARRAY - //constituent->_nodal = new MEDSKYLINEARRAY(constituent->_count[constituent->_numberOfTypes]-1,size) ; - //int * NodalIndex = constituent->_nodal->getIndex() ; - int * NodalValue = new int[size] ; - int * NodalIndex = new int[constituent->_count[constituent->_numberOfTypes]] ; - NodalIndex[0]=1 ; + // Creation of the MEDSKYLINEARRAY + //constituent->_nodal = new MEDSKYLINEARRAY(constituent->_count[constituent->_numberOfTypes]-1,size) ; + //int * NodalIndex = constituent->_nodal->getIndex() ; + int * NodalValue = new int[size] ; + int * NodalIndex = new int[constituent->_count[constituent->_numberOfTypes]] ; + NodalIndex[0]=1 ; - // Fill the MEDSKYLINEARRAY by reading the MED file. - for ( i=0; i<constituent->_numberOfTypes; i++) - { - med_2_3::med_geometrie_element med_type = (med_2_3::med_geometrie_element) constituent->_type[i].getType() ; + // Fill the MEDSKYLINEARRAY by reading the MED file. + for ( i=0; i<constituent->_numberOfTypes; i++) + { + med_2_3::med_geometrie_element med_type = (med_2_3::med_geometrie_element) constituent->_type[i].getType() ; - int NumberOfNodeByFace = constituent->_type[i].getNumberOfNodes() ; + int NumberOfNodeByFace = constituent->_type[i].getNumberOfNodes() ; - // initialise NodalIndex - for (int j=constituent->_count[i]; j<constituent->_count[i+1];j++) - NodalIndex[j]=NodalIndex[j-1]+NumberOfNodeByFace ; + // initialise NodalIndex + for (int j=constituent->_count[i]; j<constituent->_count[i+1];j++) + NodalIndex[j]=NodalIndex[j-1]+NumberOfNodeByFace ; - int tmp_numberOfFaces = constituent->_count[i+1]-constituent->_count[i] ; - // Il faut ajouter 1 pour le zero a la lecture !!! - // ATTENTION UNIQUEMENT POUR MED < 2.2.x -//CCRT int * tmp_constituentArray = NULL; - med_2_3::med_int * tmp_constituentArray = NULL; - - MESSAGE(LOC << "Med file version used here " << major << " " << minor << " " << release); - - if ((major == 2) && (minor <= 1)) -//CCRT tmp_constituentArray = new int[(NumberOfNodeByFace+1)*tmp_numberOfFaces] ; - tmp_constituentArray = new med_2_3::med_int[(NumberOfNodeByFace+1)*tmp_numberOfFaces] ; - else if ((major == 2) && (minor >= 2)) - { -//CCRT tmp_constituentArray = new int[NumberOfNodeByFace*tmp_numberOfFaces] ; - tmp_constituentArray = new med_2_3::med_int[NumberOfNodeByFace*tmp_numberOfFaces] ; - MESSAGE(LOC<<": WE ARE USING MED2.2 so there is no +1 for calculating the size of tmp_constituentArray !") ; - } - - int err=MEDconnLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()), - Connectivity->_entityDimension,tmp_constituentArray, - med_2_3::MED_FULL_INTERLACE,NULL,0,med_2_3::MED_MAILLE,med_type,med_2_3::MED_NOD); - - if ( err != MED_VALID) - { - MESSAGE(LOC<<": MEDconnLire returns "<<err) ; - delete constituent ; - delete[] tmp_constituentArray; - delete[] tmpFaceCount; - delete[] tmpEdgeCount; - return MED_ERROR ; - } - - int * constituentArray = NodalValue + NodalIndex[constituent->_count[i]-1]-1 ; + int tmp_numberOfFaces = constituent->_count[i+1]-constituent->_count[i] ; + // Il faut ajouter 1 pour le zero a la lecture !!! + // ATTENTION UNIQUEMENT POUR MED < 2.2.x + //CCRT int * tmp_constituentArray = NULL; + med_2_3::med_int * tmp_constituentArray = NULL; + + MESSAGE_MED(LOC << "Med file version used here " << major << " " << minor << " " << release); + + if ((major == 2) && (minor <= 1)) + //CCRT tmp_constituentArray = new int[(NumberOfNodeByFace+1)*tmp_numberOfFaces] ; + tmp_constituentArray = new med_2_3::med_int[(NumberOfNodeByFace+1)*tmp_numberOfFaces] ; + else if ((major == 2) && (minor >= 2)) + { + //CCRT tmp_constituentArray = new int[NumberOfNodeByFace*tmp_numberOfFaces] ; + tmp_constituentArray = new med_2_3::med_int[NumberOfNodeByFace*tmp_numberOfFaces] ; + MESSAGE_MED(LOC<<": WE ARE USING MED2.2 so there is no +1 for calculating the size of tmp_constituentArray !") ; + } + + int err=MEDconnLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()), + Connectivity->_entityDimension,tmp_constituentArray, + med_2_3::MED_FULL_INTERLACE,NULL,0,med_2_3::MED_MAILLE,med_type,med_2_3::MED_NOD); + + if ( err != MED_VALID) + { + MESSAGE_MED(LOC<<": MEDconnLire returns "<<err) ; + delete constituent ; + delete[] tmp_constituentArray; + delete[] tmpFaceCount; + delete[] tmpEdgeCount; + return MED_ERROR ; + } + + int * constituentArray = NodalValue + NodalIndex[constituent->_count[i]-1]-1 ; - // version originale sans prise en compte des numéros optionnels - // - int multi = 0; // quand est-ce que multi vaut 1 ?? en MED-fichier < 2.2 ?? - MESSAGE(LOC << "Med file version used here " << major << " " << minor << " " << release); - - if ((major == 2) && (minor <= 1)) - for (int j=0; j<tmp_numberOfFaces; j++) - for (int k=0; k<NumberOfNodeByFace; k++) - constituentArray[j*NumberOfNodeByFace+k]=tmp_constituentArray[j*(NumberOfNodeByFace+1)+k] ; - else if ((major == 2) && (minor >= 2)) - for (int j=0; j<tmp_numberOfFaces; j++) - for (int k=0; k<NumberOfNodeByFace; k++) - constituentArray[j*NumberOfNodeByFace+k]=tmp_constituentArray[j*(NumberOfNodeByFace+multi)+k] ; - - ////////////////////////////////////////////////////////////////////////////////////// - /// Modification pour prise en compte de la numérotation optionnelle des noeuds /// - ////////////////////////////////////////////////////////////////////////////////////// - /// - /// Rénumérote le tableau temporaire tmp_constituentArray en utilisant _optionnalToCanonicNodesNumbers - /// Le traitement est identique à la version originelle s'il n'y a pas de numérotation optionnelle + // version originale sans prise en compte des numéros optionnels + // + int multi = 0; // quand est-ce que multi vaut 1 ?? en MED-fichier < 2.2 ?? + MESSAGE_MED(LOC << "Med file version used here " << major << " " << minor << " " << release); + + if ((major == 2) && (minor <= 1)) + for (int j=0; j<tmp_numberOfFaces; j++) + for (int k=0; k<NumberOfNodeByFace; k++) + constituentArray[j*NumberOfNodeByFace+k]=tmp_constituentArray[j*(NumberOfNodeByFace+1)+k] ; + else if ((major == 2) && (minor >= 2)) + for (int j=0; j<tmp_numberOfFaces; j++) + for (int k=0; k<NumberOfNodeByFace; k++) + constituentArray[j*NumberOfNodeByFace+k]=tmp_constituentArray[j*(NumberOfNodeByFace+multi)+k] ; + + ////////////////////////////////////////////////////////////////////////////////////// + /// Modification pour prise en compte de la numérotation optionnelle des noeuds /// + ////////////////////////////////////////////////////////////////////////////////////// + /// + /// Rénumérote le tableau temporaire tmp_constituentArray en utilisant _optionnalToCanonicNodesNumbers + /// Le traitement est identique à la version originelle s'il n'y a pas de numérotation optionnelle - // if (_ptrMesh->_arePresentOptionnalNodesNumbers) - // { - // for (int j=0; j<tmp_numberOfFaces; j++) for (int k=0; k<NumberOfNodeByFace; k++) - // constituentArray[j*NumberOfNodeByFace+k]=_ptrMesh->_optionnalToCanonicNodesNumbers[tmp_constituentArray[j*(NumberOfNodeByFace+1)+k]] ; - // } - // else - // { - // for (int j=0; j<tmp_numberOfFaces; j++) for (int k=0; k<NumberOfNodeByFace; k++) - // constituentArray[j*NumberOfNodeByFace+k]=tmp_constituentArray[j*(NumberOfNodeByFace+1)+k] ; - // } + // if (_ptrMesh->_arePresentOptionnalNodesNumbers) + // { + // for (int j=0; j<tmp_numberOfFaces; j++) for (int k=0; k<NumberOfNodeByFace; k++) + // constituentArray[j*NumberOfNodeByFace+k]=_ptrMesh->_optionnalToCanonicNodesNumbers[tmp_constituentArray[j*(NumberOfNodeByFace+1)+k]] ; + // } + // else + // { + // for (int j=0; j<tmp_numberOfFaces; j++) for (int k=0; k<NumberOfNodeByFace; k++) + // constituentArray[j*NumberOfNodeByFace+k]=tmp_constituentArray[j*(NumberOfNodeByFace+1)+k] ; + // } - ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// - delete[] tmp_constituentArray; - } + delete[] tmp_constituentArray; + } - constituent->_nodal = new MEDSKYLINEARRAY(constituent->_count[constituent->_numberOfTypes]-1, - size, - NodalIndex, - NodalValue) ; - delete[] NodalIndex ; - delete[] NodalValue ; - - - Connectivity->_constituent = constituent ; - } - - delete[] tmpFaceCount; - - - // get Edge if any - // =============== - if (numberOfEdgesTypes!=0) - { - CONNECTIVITY * constituent = new CONNECTIVITY(numberOfEdgesTypes,MED_EDGE) ; - constituent->_entityDimension = 1 ; - constituent->_count[0]=1 ; - - int size = 0 ; - int typeNumber=1 ; - // if you declare a variable <i> in two <for> initialization statement, - // compiler gcc2.95.3 says nothing but there are two <i> variables in the same block - //and the value you get in the common block seems to be the value of the first variable ! - int i; - - for ( i=1; i<MED_NBR_GEOMETRIE_MAILLE; i++) - { // no point1 cell type (?) - if (tmpEdgeCount[i]>0) - { + constituent->_nodal = new MEDSKYLINEARRAY(constituent->_count[constituent->_numberOfTypes]-1, + size, + NodalIndex, + NodalValue) ; + delete[] NodalIndex ; + delete[] NodalValue ; + + + Connectivity->_constituent = constituent ; + } + + delete[] tmpFaceCount; + + + // get Edge if any + // =============== + if (numberOfEdgesTypes!=0) + { + CONNECTIVITY * constituent = new CONNECTIVITY(numberOfEdgesTypes,MED_EDGE) ; + constituent->_entityDimension = 1 ; + constituent->_count[0]=1 ; + + int size = 0 ; + int typeNumber=1 ; + // if you declare a variable <i> in two <for> initialization statement, + // compiler gcc2.95.3 says nothing but there are two <i> variables in the same block + //and the value you get in the common block seems to be the value of the first variable ! + int i; + + for ( i=1; i<MED_NBR_GEOMETRIE_MAILLE; i++) + { // no point1 cell type (?) + if (tmpEdgeCount[i]>0) + { - constituent->_count[typeNumber]=constituent->_count[typeNumber-1]+tmpEdgeCount[i]; - CELLMODEL t( (MED_EN::medGeometryElement) MED_MESH_DRIVER22::all_cell_type[i]) ; - constituent->_type[typeNumber-1]=t ; + constituent->_count[typeNumber]=constituent->_count[typeNumber-1]+tmpEdgeCount[i]; + CELLMODEL t( (MED_EN::medGeometryElement) MED_MESH_DRIVER22::all_cell_type[i]) ; + constituent->_type[typeNumber-1]=t ; - constituent->_geometricTypes[typeNumber-1]=( MED_EN::medGeometryElement) MED_MESH_DRIVER22::all_cell_type[i] ; + constituent->_geometricTypes[typeNumber-1]=( MED_EN::medGeometryElement) MED_MESH_DRIVER22::all_cell_type[i] ; - size+=tmpEdgeCount[i]*((MED_MESH_DRIVER22::all_cell_type[i])%100) ; - typeNumber++; - } - } + size+=tmpEdgeCount[i]*((MED_MESH_DRIVER22::all_cell_type[i])%100) ; + typeNumber++; + } + } - // Creation of the MEDSKYLINEARRAY - //constituent->_nodal = new MEDSKYLINEARRAY(constituent->_count[constituent->_numberOfTypes]-1,size) ; - //int * NodalIndex = constituent->_nodal->getIndex() ; - int * NodalValue = new int[size] ; - int * NodalIndex = new int[constituent->_count[constituent->_numberOfTypes]] ; - NodalIndex[0]=1 ; + // Creation of the MEDSKYLINEARRAY + //constituent->_nodal = new MEDSKYLINEARRAY(constituent->_count[constituent->_numberOfTypes]-1,size) ; + //int * NodalIndex = constituent->_nodal->getIndex() ; + int * NodalValue = new int[size] ; + int * NodalIndex = new int[constituent->_count[constituent->_numberOfTypes]] ; + NodalIndex[0]=1 ; - // Fill the MEDSKYLINEARRAY by reading the MED file. - for ( i=0; i<constituent->_numberOfTypes; i++) - { - med_2_3::med_geometrie_element med_type = (med_2_3::med_geometrie_element) constituent->_type[i].getType() ; + // Fill the MEDSKYLINEARRAY by reading the MED file. + for ( i=0; i<constituent->_numberOfTypes; i++) + { + med_2_3::med_geometrie_element med_type = (med_2_3::med_geometrie_element) constituent->_type[i].getType() ; - int NumberOfNodeByEdge = constituent->_type[i].getNumberOfNodes() ; + int NumberOfNodeByEdge = constituent->_type[i].getNumberOfNodes() ; - // initialise index - for (int j=constituent->_count[i]; j<constituent->_count[i+1];j++) - NodalIndex[j]=NodalIndex[j-1]+NumberOfNodeByEdge ; + // initialise index + for (int j=constituent->_count[i]; j<constituent->_count[i+1];j++) + NodalIndex[j]=NodalIndex[j-1]+NumberOfNodeByEdge ; - int tmp_numberOfEdges = constituent->_count[i+1]-constituent->_count[i] ; - // Il faut ajouter 1 pour le zero a la lecture !!! - - // ATTENTION UNIQUEMENT POUR MED < 2.2.x -//CCRT int * tmp_constituentArray = NULL; - med_2_3::med_int * tmp_constituentArray = NULL; - - MESSAGE(LOC << "Med file version used here " << major << " " << minor << " " << release); - - if ((major == 2) && (minor <= 1)) -//CCRT tmp_constituentArray = new int[(NumberOfNodeByEdge+1)*tmp_numberOfEdges] ; - tmp_constituentArray = new med_2_3::med_int[(NumberOfNodeByEdge+1)*tmp_numberOfEdges] ; - else if ((major == 2) && (minor >= 2)) - { -//CCRT tmp_constituentArray = new int[NumberOfNodeByEdge*tmp_numberOfEdges] ; - tmp_constituentArray = new med_2_3::med_int[NumberOfNodeByEdge*tmp_numberOfEdges] ; - MESSAGE(LOC<<": WE ARE USING MED2.2 so there is no +1 for calculating the size of tmp_constituentArray !") ; - } + int tmp_numberOfEdges = constituent->_count[i+1]-constituent->_count[i] ; + // Il faut ajouter 1 pour le zero a la lecture !!! + + // ATTENTION UNIQUEMENT POUR MED < 2.2.x + //CCRT int * tmp_constituentArray = NULL; + med_2_3::med_int * tmp_constituentArray = NULL; + + MESSAGE_MED(LOC << "Med file version used here " << major << " " << minor << " " << release); + + if ((major == 2) && (minor <= 1)) + //CCRT tmp_constituentArray = new int[(NumberOfNodeByEdge+1)*tmp_numberOfEdges] ; + tmp_constituentArray = new med_2_3::med_int[(NumberOfNodeByEdge+1)*tmp_numberOfEdges] ; + else if ((major == 2) && (minor >= 2)) + { + //CCRT tmp_constituentArray = new int[NumberOfNodeByEdge*tmp_numberOfEdges] ; + tmp_constituentArray = new med_2_3::med_int[NumberOfNodeByEdge*tmp_numberOfEdges] ; + MESSAGE_MED(LOC<<": WE ARE USING MED2.2 so there is no +1 for calculating the size of tmp_constituentArray !") ; + } - int err=MEDconnLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()), - spaceDimension,tmp_constituentArray, - med_2_3::MED_FULL_INTERLACE,NULL,0,med_2_3::MED_MAILLE,med_type,med_2_3::MED_NOD); - if ( err != MED_VALID) - { - MESSAGE(LOC<<": MEDconnLire returns "<<err) ; - delete constituent ; - delete[] tmp_constituentArray; - delete[] tmpEdgeCount; - return MED_ERROR ; - } - - int * constituentArray = NodalValue + NodalIndex[constituent->_count[i]-1]-1 ; + int err=MEDconnLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()), + spaceDimension,tmp_constituentArray, + med_2_3::MED_FULL_INTERLACE,NULL,0,med_2_3::MED_MAILLE,med_type,med_2_3::MED_NOD); + if ( err != MED_VALID) + { + MESSAGE_MED(LOC<<": MEDconnLire returns "<<err) ; + delete constituent ; + delete[] tmp_constituentArray; + delete[] tmpEdgeCount; + return MED_ERROR ; + } + + int * constituentArray = NodalValue + NodalIndex[constituent->_count[i]-1]-1 ; - // version originale sans prise en compte des numéros optionnels - // - int multi = 0; // quand est-ce que multi vaut 1 ?? en MED-fichier < 2.2 ?? - MESSAGE(LOC << "Med file version used here " << major << " " << minor << " " << release); - - if ((major == 2) && (minor <= 1)) - for (int j=0; j<tmp_numberOfEdges; j++) - for (int k=0; k<NumberOfNodeByEdge; k++) - constituentArray[j*NumberOfNodeByEdge+k]=tmp_constituentArray[j*(NumberOfNodeByEdge+multi)+k] ; - else if ((major == 2) && (minor >= 2)) - for (int j=0; j<tmp_numberOfEdges; j++) - for (int k=0; k<NumberOfNodeByEdge; k++) - constituentArray[j*NumberOfNodeByEdge+k]=tmp_constituentArray[j*(NumberOfNodeByEdge)+k] ; - - ////////////////////////////////////////////////////////////////////////////////////// - /// Modification pour prise en compte de la numérotation optionnelle des noeuds /// - ////////////////////////////////////////////////////////////////////////////////////// - /// - /// Rénumérote le tableau temporaire tmp_constituentArray en utilisant _optionnalToCanonicNodesNumbers - /// Le traitement est identique à la version originelle s'il n'y a pas de numérotation optionnelle + // version originale sans prise en compte des numéros optionnels + // + int multi = 0; // quand est-ce que multi vaut 1 ?? en MED-fichier < 2.2 ?? + MESSAGE_MED(LOC << "Med file version used here " << major << " " << minor << " " << release); + + if ((major == 2) && (minor <= 1)) + for (int j=0; j<tmp_numberOfEdges; j++) + for (int k=0; k<NumberOfNodeByEdge; k++) + constituentArray[j*NumberOfNodeByEdge+k]=tmp_constituentArray[j*(NumberOfNodeByEdge+multi)+k] ; + else if ((major == 2) && (minor >= 2)) + for (int j=0; j<tmp_numberOfEdges; j++) + for (int k=0; k<NumberOfNodeByEdge; k++) + constituentArray[j*NumberOfNodeByEdge+k]=tmp_constituentArray[j*(NumberOfNodeByEdge)+k] ; + + ////////////////////////////////////////////////////////////////////////////////////// + /// Modification pour prise en compte de la numérotation optionnelle des noeuds /// + ////////////////////////////////////////////////////////////////////////////////////// + /// + /// Rénumérote le tableau temporaire tmp_constituentArray en utilisant _optionnalToCanonicNodesNumbers + /// Le traitement est identique à la version originelle s'il n'y a pas de numérotation optionnelle - // if (_ptrMesh->_arePresentOptionnalNodesNumbers) - // { - // for (int j=0; j<tmp_numberOfEdges; j++) for (int k=0; k<NumberOfNodeByEdge; k++) - // constituentArray[j*NumberOfNodeByEdge+k]=_ptrMesh->_optionnalToCanonicNodesNumbers[tmp_constituentArray[j*(NumberOfNodeByEdge+1)+k]] ; - // } - // else - // { - // for (int j=0; j<tmp_numberOfEdges; j++) for (int k=0; k<NumberOfNodeByEdge; k++) - // constituentArray[j*NumberOfNodeByEdge+k]=tmp_constituentArray[j*(NumberOfNodeByEdge+1)+k] ; - // } + // if (_ptrMesh->_arePresentOptionnalNodesNumbers) + // { + // for (int j=0; j<tmp_numberOfEdges; j++) for (int k=0; k<NumberOfNodeByEdge; k++) + // constituentArray[j*NumberOfNodeByEdge+k]=_ptrMesh->_optionnalToCanonicNodesNumbers[tmp_constituentArray[j*(NumberOfNodeByEdge+1)+k]] ; + // } + // else + // { + // for (int j=0; j<tmp_numberOfEdges; j++) for (int k=0; k<NumberOfNodeByEdge; k++) + // constituentArray[j*NumberOfNodeByEdge+k]=tmp_constituentArray[j*(NumberOfNodeByEdge+1)+k] ; + // } - ////////////////////////////////////////////////////////////////////////////////////// - - delete[] tmp_constituentArray; - } - - constituent->_nodal = new MEDSKYLINEARRAY(constituent->_count[constituent->_numberOfTypes]-1, - size, - NodalIndex, - NodalValue) ; - - delete[] NodalIndex ; - delete[] NodalValue ; - - if (Connectivity->_entityDimension == 3) - { - if (Connectivity->_constituent==NULL) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Edges are defined but there are no Faces !")); - Connectivity->_constituent->_constituent = constituent ; - } else - Connectivity->_constituent = constituent ; - } - - delete[] tmpEdgeCount; - - - } // end classic geometric types + ////////////////////////////////////////////////////////////////////////////////////// + + delete[] tmp_constituentArray; + } + + constituent->_nodal = new MEDSKYLINEARRAY(constituent->_count[constituent->_numberOfTypes]-1, + size, + NodalIndex, + NodalValue) ; + + delete[] NodalIndex ; + delete[] NodalValue ; + + if (Connectivity->_entityDimension == 3) + { + if (Connectivity->_constituent==NULL) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Edges are defined but there are no Faces !")); + Connectivity->_constituent->_constituent = constituent ; + } else + Connectivity->_constituent = constituent ; + } + + delete[] tmpEdgeCount; + + + } // end classic geometric types else {//Polyg/Polh only... delete [] Connectivity->_count; @@ -1404,24 +1399,23 @@ int MED_MESH_RDONLY_DRIVER22::getNodalConnectivity(CONNECTIVITY * Connectivity) Connectivity->_count[0]=1; } delete[] tmp_cells_count; - - // Lecture des polygones MED_CELL - int NumberOfPolygons = MEDnEntMaa(_medIdt, - const_cast <char *> (_ptrMesh->_name.c_str()), - med_2_3::MED_CONN, - med_2_3::MED_MAILLE, - med_2_3::MED_POLYGONE, - med_2_3::MED_NOD); - - // Correction to permit the loading of mesh dimensionned at 2 even - // if it has only MED_POLYGON elements - - if (NumberOfPolygons > 0) + + int NumberOfPolygons = MEDnEntMaa(_medIdt, + const_cast <char *> (_ptrMesh->_name.c_str()), + med_2_3::MED_CONN, + med_2_3::MED_MAILLE, + med_2_3::MED_POLYGONE, + med_2_3::MED_NOD); + + // Correction to permit the loading of mesh dimensionned at 2 even + // if it has only MED_POLYGON elements + + if (NumberOfPolygons > 0) { if (Connectivity->_entityDimension < 2) Connectivity->_entityDimension = 2; } - - if (NumberOfPolygons > 0) + + if (NumberOfPolygons > 0) { // By consequence this exception will never occur if (Connectivity->_entityDimension == 1) @@ -1433,14 +1427,14 @@ int MED_MESH_RDONLY_DRIVER22::getNodalConnectivity(CONNECTIVITY * Connectivity) med_2_3::MED_NOD, &ConnectivitySize); if (err1 != MED_VALID) - { - MESSAGE(LOC<<": MEDpolygoneInfo returns "<<err1); - return MED_ERROR; - } - + { + MESSAGE_MED(LOC<<": MEDpolygoneInfo returns "<<err1); + return MED_ERROR; + } + med_2_3::med_int* PolygonsConnectivity = new med_2_3::med_int[ConnectivitySize]; med_2_3::med_int* PolygonsConnectivityIndex = new med_2_3::med_int[NumberOfPolygons+1]; - + med_2_3::med_err err2 = MEDpolygoneConnLire(_medIdt, const_cast <char *> (_ptrMesh->_name.c_str()), PolygonsConnectivityIndex, @@ -1449,153 +1443,153 @@ int MED_MESH_RDONLY_DRIVER22::getNodalConnectivity(CONNECTIVITY * Connectivity) med_2_3::MED_MAILLE, med_2_3::MED_NOD); if (err2 != MED_VALID) - { - MESSAGE(LOC<<": MEDpolygoneConnLire returns "<<err2); - return MED_ERROR; - } + { + MESSAGE_MED(LOC<<": MEDpolygoneConnLire returns "<<err2); + return MED_ERROR; + } if (Connectivity->_entityDimension == 2) // 2D mesh : polygons in Connectivity - { -//CCRT + { + //CCRT #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64) - int* tmp_PolygonsConnectivity = new int[ConnectivitySize]; - int i ; - for ( i = 0 ; i < ConnectivitySize ; i++ ) - tmp_PolygonsConnectivity[i] = PolygonsConnectivity[i] ; + int* tmp_PolygonsConnectivity = new int[ConnectivitySize]; + int i ; + for ( i = 0 ; i < ConnectivitySize ; i++ ) + tmp_PolygonsConnectivity[i] = PolygonsConnectivity[i] ; - int* tmp_PolygonsConnectivityIndex = new int[NumberOfPolygons+1]; - for ( i = 0 ; i < NumberOfPolygons+1 ; i++ ) - tmp_PolygonsConnectivityIndex[i] = PolygonsConnectivityIndex[i] ; + int* tmp_PolygonsConnectivityIndex = new int[NumberOfPolygons+1]; + for ( i = 0 ; i < NumberOfPolygons+1 ; i++ ) + tmp_PolygonsConnectivityIndex[i] = PolygonsConnectivityIndex[i] ; - Connectivity->setPolygonsConnectivity - (MED_NODAL, (medEntityMesh) Entity, tmp_PolygonsConnectivity, - tmp_PolygonsConnectivityIndex, ConnectivitySize, NumberOfPolygons); + Connectivity->setPolygonsConnectivity + (MED_NODAL, (medEntityMesh) Entity, tmp_PolygonsConnectivity, + tmp_PolygonsConnectivityIndex, ConnectivitySize, NumberOfPolygons); - delete [] tmp_PolygonsConnectivity ; - delete [] tmp_PolygonsConnectivityIndex ; + delete [] tmp_PolygonsConnectivity ; + delete [] tmp_PolygonsConnectivityIndex ; #else - Connectivity->setPolygonsConnectivity - (MED_NODAL, (medEntityMesh) Entity, PolygonsConnectivity, - PolygonsConnectivityIndex, ConnectivitySize, NumberOfPolygons); + Connectivity->setPolygonsConnectivity + (MED_NODAL, (medEntityMesh) Entity, PolygonsConnectivity, + PolygonsConnectivityIndex, ConnectivitySize, NumberOfPolygons); #endif - } + } else if (Connectivity->_entityDimension == 3) - { - if (Connectivity->_constituent == NULL) // 3D mesh : polygons in Connectivity->_constituent - Connectivity->_constituent = new CONNECTIVITY(MED_FACE); -//CCRT + { + if (Connectivity->_constituent == NULL) // 3D mesh : polygons in Connectivity->_constituent + Connectivity->_constituent = new CONNECTIVITY(MED_FACE); + //CCRT #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64) - int* tmp_PolygonsConnectivity = new int[ConnectivitySize]; - int i ; - for ( i = 0 ; i < ConnectivitySize ; i++ ) - tmp_PolygonsConnectivity[i] = PolygonsConnectivity[i] ; + int* tmp_PolygonsConnectivity = new int[ConnectivitySize]; + int i ; + for ( i = 0 ; i < ConnectivitySize ; i++ ) + tmp_PolygonsConnectivity[i] = PolygonsConnectivity[i] ; - int* tmp_PolygonsConnectivityIndex = new int[NumberOfPolygons+1]; - for ( i = 0 ; i < NumberOfPolygons+1 ; i++ ) - tmp_PolygonsConnectivityIndex[i] = PolygonsConnectivityIndex[i] ; + int* tmp_PolygonsConnectivityIndex = new int[NumberOfPolygons+1]; + for ( i = 0 ; i < NumberOfPolygons+1 ; i++ ) + tmp_PolygonsConnectivityIndex[i] = PolygonsConnectivityIndex[i] ; - Connectivity->_constituent->setPolygonsConnectivity - (MED_NODAL, MED_FACE, tmp_PolygonsConnectivity, - tmp_PolygonsConnectivityIndex, ConnectivitySize, NumberOfPolygons); + Connectivity->_constituent->setPolygonsConnectivity + (MED_NODAL, MED_FACE, tmp_PolygonsConnectivity, + tmp_PolygonsConnectivityIndex, ConnectivitySize, NumberOfPolygons); - delete [] tmp_PolygonsConnectivity ; - delete [] tmp_PolygonsConnectivityIndex ; + delete [] tmp_PolygonsConnectivity ; + delete [] tmp_PolygonsConnectivityIndex ; #else - Connectivity->_constituent->setPolygonsConnectivity - (MED_NODAL, MED_FACE, PolygonsConnectivity, - PolygonsConnectivityIndex, ConnectivitySize, NumberOfPolygons); + Connectivity->_constituent->setPolygonsConnectivity + (MED_NODAL, MED_FACE, PolygonsConnectivity, + PolygonsConnectivityIndex, ConnectivitySize, NumberOfPolygons); #endif - } + } delete[] PolygonsConnectivity; delete[] PolygonsConnectivityIndex; } // end polygons - - + + // Lecture des polyedres MED_CELL med_int NumberOfPolyhedron = MEDnEntMaa(_medIdt, - const_cast <char *> (_ptrMesh->_name.c_str()), - med_2_3::MED_CONN, - Entity, - med_2_3::MED_POLYEDRE, - med_2_3::MED_NOD); + const_cast <char *> (_ptrMesh->_name.c_str()), + med_2_3::MED_CONN, + Entity, + med_2_3::MED_POLYEDRE, + med_2_3::MED_NOD); // Correction to permit the loading of mesh dimensionned at 3 even // if it has only MED_POLYEDRE elements if (NumberOfPolyhedron > 0) - { - Connectivity->_entityDimension = 3; - } + { + Connectivity->_entityDimension = 3; + } if (NumberOfPolyhedron > 0) - { - // By consequence this exception will never occur - if (Connectivity->_entityDimension == 2 || Connectivity->_entityDimension == 1) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"In a 3D mesh, polyhedron need at least one 3D cell of a classic geometric type !")); - med_2_3::med_int FacesIndexSize, NumberOfNodes, NumberOfFaces; - med_2_3::med_err err3 = MEDpolyedreInfo(_medIdt, - const_cast <char *> (_ptrMesh->_name.c_str()), - med_2_3::MED_NOD, - &FacesIndexSize, - &NumberOfNodes); - NumberOfFaces = FacesIndexSize-1; - if (err3 != MED_VALID) - { - MESSAGE(LOC<<": MEDpolyhedreInfo returns "<<err3); - return MED_ERROR; - } + { + // By consequence this exception will never occur + if (Connectivity->_entityDimension == 2 || Connectivity->_entityDimension == 1) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"In a 3D mesh, polyhedron need at least one 3D cell of a classic geometric type !")); + med_2_3::med_int FacesIndexSize, NumberOfNodes, NumberOfFaces; + med_2_3::med_err err3 = MEDpolyedreInfo(_medIdt, + const_cast <char *> (_ptrMesh->_name.c_str()), + med_2_3::MED_NOD, + &FacesIndexSize, + &NumberOfNodes); + NumberOfFaces = FacesIndexSize-1; + if (err3 != MED_VALID) + { + MESSAGE_MED(LOC<<": MEDpolyhedreInfo returns "<<err3); + return MED_ERROR; + } - med_2_3::med_int* Nodes = new med_2_3::med_int[NumberOfNodes]; - med_2_3::med_int* FacesIndex = new med_2_3::med_int[NumberOfFaces+1]; - med_2_3::med_int* PolyhedronIndex = new med_2_3::med_int[NumberOfPolyhedron+1]; + med_2_3::med_int* Nodes = new med_2_3::med_int[NumberOfNodes]; + med_2_3::med_int* FacesIndex = new med_2_3::med_int[NumberOfFaces+1]; + med_2_3::med_int* PolyhedronIndex = new med_2_3::med_int[NumberOfPolyhedron+1]; - med_2_3::med_err err4 = MEDpolyedreConnLire(_medIdt, - const_cast <char *> (_ptrMesh->_name.c_str()), - PolyhedronIndex, - NumberOfPolyhedron+1, - FacesIndex, - NumberOfFaces+1, - Nodes, - med_2_3::MED_NOD); - if (err4 != MED_VALID) - { - MESSAGE(LOC<<": MEDpolyedreConnLire returns "<<err4); - return MED_ERROR; - } + med_2_3::med_err err4 = MEDpolyedreConnLire(_medIdt, + const_cast <char *> (_ptrMesh->_name.c_str()), + PolyhedronIndex, + NumberOfPolyhedron+1, + FacesIndex, + NumberOfFaces+1, + Nodes, + med_2_3::MED_NOD); + if (err4 != MED_VALID) + { + MESSAGE_MED(LOC<<": MEDpolyedreConnLire returns "<<err4); + return MED_ERROR; + } -//CCRT + //CCRT #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64) - int* tmp_Nodes = new int[NumberOfNodes]; + int* tmp_Nodes = new int[NumberOfNodes]; int i ; for ( i = 0 ; i < NumberOfNodes ; i++ ) - tmp_Nodes[i] = Nodes[i] ; - int* tmp_FacesIndex = new int[NumberOfFaces+1]; + tmp_Nodes[i] = Nodes[i] ; + int* tmp_FacesIndex = new int[NumberOfFaces+1]; for ( i = 0 ; i < NumberOfFaces+1 ; i++ ) - tmp_FacesIndex[i] = FacesIndex[i] ; - int* tmp_PolyhedronIndex = new int[NumberOfPolyhedron+1]; + tmp_FacesIndex[i] = FacesIndex[i] ; + int* tmp_PolyhedronIndex = new int[NumberOfPolyhedron+1]; for ( i = 0 ; i < NumberOfPolyhedron+1 ; i++ ) - tmp_PolyhedronIndex[i] = PolyhedronIndex[i] ; - Connectivity->setPolyhedronConnectivity(MED_NODAL,tmp_Nodes,tmp_PolyhedronIndex,NumberOfNodes,NumberOfPolyhedron,tmp_FacesIndex,NumberOfFaces); - delete[] tmp_Nodes; - delete[] tmp_FacesIndex; - delete[] tmp_PolyhedronIndex; + tmp_PolyhedronIndex[i] = PolyhedronIndex[i] ; + Connectivity->setPolyhedronConnectivity(MED_NODAL,tmp_Nodes,tmp_PolyhedronIndex,NumberOfNodes,NumberOfPolyhedron,tmp_FacesIndex,NumberOfFaces); + delete[] tmp_Nodes; + delete[] tmp_FacesIndex; + delete[] tmp_PolyhedronIndex; #else - Connectivity->setPolyhedronConnectivity(MED_NODAL,Nodes,PolyhedronIndex,NumberOfNodes,NumberOfPolyhedron,FacesIndex,NumberOfFaces); + Connectivity->setPolyhedronConnectivity(MED_NODAL,Nodes,PolyhedronIndex,NumberOfNodes,NumberOfPolyhedron,FacesIndex,NumberOfFaces); #endif - delete[] Nodes; - delete[] FacesIndex; - delete[] PolyhedronIndex; - } // end polyhedron + delete[] Nodes; + delete[] FacesIndex; + delete[] PolyhedronIndex; + } // end polyhedron // If there is no nodal connectivity, we return MED_ERROR ! if (Connectivity->_numberOfTypes == 0 && NumberOfPolygons == 0 && NumberOfPolyhedron == 0) - return MED_ERROR; + return MED_ERROR; else - return MED_VALID; + return MED_VALID; } return MED_ERROR; @@ -1604,7 +1598,7 @@ int MED_MESH_RDONLY_DRIVER22::getNodalConnectivity(CONNECTIVITY * Connectivity) int MED_MESH_RDONLY_DRIVER22::getFAMILY() { const char * LOC = "MED_MESH_RDONLY_DRIVER22::getFAMILY() : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status==MED_OPENED) { @@ -1622,7 +1616,7 @@ int MED_MESH_RDONLY_DRIVER22::getFAMILY() // error only if (_status!=MED_OPENED), other case exeception ! // CELL - MESSAGE(LOC << "error returned from getNodesFamiliesNumber " << err); + MESSAGE_MED(LOC << "error returned from getNodesFamiliesNumber " << err); MEDArrayCellFamily = new int* [_ptrMesh->getNumberOfTypesWithPoly(MED_CELL)] ; // ET SI IL N'Y A PAS DE CELLS ? @@ -1639,7 +1633,7 @@ int MED_MESH_RDONLY_DRIVER22::getFAMILY() _ptrMesh->_connectivity,MED_CELL) ; delete [] myTypes; - MESSAGE(LOC << "error returned from getCellsFamiliesNumber for Cells " << err); + MESSAGE_MED(LOC << "error returned from getCellsFamiliesNumber for Cells " << err); if (_ptrMesh->_connectivity->_constituent != NULL) { @@ -1650,15 +1644,16 @@ int MED_MESH_RDONLY_DRIVER22::getFAMILY() int* [_ptrMesh->getNumberOfTypesWithPoly(MED_FACE)] ; myTypes = _ptrMesh->getTypesWithPoly(MED_FACE); - for (int i=0;i<_ptrMesh->getNumberOfTypesWithPoly(MED_FACE);i++) - MEDArrayFaceFamily[i] = new - int[_ptrMesh->getNumberOfElementsWithPoly(MED_FACE,myTypes[i])] ; + for (int i=0;i<_ptrMesh->getNumberOfTypesWithPoly(MED_FACE);i++) { + int nbOfElements = _ptrMesh->_connectivity->_constituent->getNumberOfElementsWithPoly(MED_FACE,myTypes[i]); + MEDArrayFaceFamily[i] = new int[nbOfElements]; + } err = getCellsFamiliesNumber(MEDArrayFaceFamily, _ptrMesh->_connectivity->_constituent,MED_FACE) ; delete [] myTypes; - MESSAGE(LOC << "error returned from getCellsFamiliesNumber for Faces " << err); + MESSAGE_MED(LOC << "error returned from getCellsFamiliesNumber for Faces " << err); } else { @@ -1673,9 +1668,9 @@ int MED_MESH_RDONLY_DRIVER22::getFAMILY() err = getCellsFamiliesNumber(MEDArrayEdgeFamily, - _ptrMesh->_connectivity->_constituent,MED_FACE) ; + _ptrMesh->_connectivity->_constituent,MED_EDGE) ; - MESSAGE(LOC << "error returned from getCellsFamiliesNumber for Edges in 2D " << err); + MESSAGE_MED(LOC << "error returned from getCellsFamiliesNumber for Edges in 2D " << err); } // EDGE in 3D if (_ptrMesh->_connectivity->_constituent->_constituent != NULL) @@ -1684,16 +1679,17 @@ int MED_MESH_RDONLY_DRIVER22::getFAMILY() int* [_ptrMesh->getNumberOfTypes(MED_EDGE)] ; const medGeometryElement *myTypes2 = _ptrMesh->getTypes(MED_EDGE); - for (int i=0;i<_ptrMesh->getNumberOfTypes(MED_EDGE);i++) - MEDArrayEdgeFamily[i] = new - int[_ptrMesh->getNumberOfElements(MED_EDGE,myTypes2[i])] ; + for (int i=0;i<_ptrMesh->getNumberOfTypes(MED_EDGE);i++) { + int nbOfElements = _ptrMesh->_connectivity->_constituent->_constituent->getNumberOfElementsWithPoly(MED_EDGE,myTypes2[i]); + MEDArrayEdgeFamily[i] = new int[nbOfElements] ; + } err = getCellsFamiliesNumber(MEDArrayEdgeFamily, _ptrMesh->_connectivity->_constituent->_constituent,MED_EDGE); // we are in 3D ! - MESSAGE(LOC << "error returned from getCellsFamiliesNumber for Edges in 3D " << err); + MESSAGE_MED(LOC << "error returned from getCellsFamiliesNumber for Edges in 3D " << err); } } @@ -1704,7 +1700,7 @@ int MED_MESH_RDONLY_DRIVER22::getFAMILY() if ( NumberOfFamilies < 1 ) // at least family 0 must exist throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"There is no FAMILY, FAMILY 0 must exists" )); - SCRUTE(NumberOfFamilies); + SCRUTE_MED(NumberOfFamilies); vector<FAMILY*> &NodeFamilyVector = _ptrMesh->_familyNode ; vector<FAMILY*> &CellFamilyVector = _ptrMesh->_familyCell ; @@ -1749,14 +1745,20 @@ int MED_MESH_RDONLY_DRIVER22::getFAMILY() int FamilyIdentifier ; string FamilyName(MED_TAILLE_NOM,'\0'); - int * AttributesIdentifier = new int[NumberOfAttributes] ; - int * AttributesValues = new int[NumberOfAttributes] ; + // 0020071: Crash of V4_1_4rc2 (of testMedMemGeneral.py) + // Pb with Mistrat_import22.med: it's zero family has non-empty AttributesIdentifier's and + // AttributesValues' but MEDnAttribut() returns 0 (0 is hardcoded for zero family). + // So we allocate nothing but MEDfamInfo() reads file contents so overwritting + // stranger's memory. Stupid solution: allocate more than MEDnAttribut() + const int iSafe = 10; + int * AttributesIdentifier = new int[NumberOfAttributes+iSafe] ; + int * AttributesValues = new int[NumberOfAttributes+iSafe] ; string AttributesDescription(MED_TAILLE_DESC*NumberOfAttributes,' ') ; string GroupsNames(MED_TAILLE_LNOM*NumberOfGroups+1,'\0') ; #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64) med_2_3::med_int tmp_FamilyIdentifier ; - med_2_3::med_int * tmp_AttributesIdentifier = new med_2_3::med_int[NumberOfAttributes] ; - med_2_3::med_int * tmp_AttributesValues = new med_2_3::med_int[NumberOfAttributes] ; + med_2_3::med_int * tmp_AttributesIdentifier = new med_2_3::med_int[NumberOfAttributes+iSafe] ; + med_2_3::med_int * tmp_AttributesValues = new med_2_3::med_int[NumberOfAttributes+iSafe] ; err = med_2_3::MEDfamInfo(_medIdt, const_cast <char *>(_meshName.c_str()), (i+1), @@ -1791,10 +1793,10 @@ int MED_MESH_RDONLY_DRIVER22::getFAMILY() #endif - SCRUTE(GroupsNames); - SCRUTE(FamilyName); - SCRUTE(err); - SCRUTE(i); + SCRUTE_MED(GroupsNames); + SCRUTE_MED(FamilyName); + SCRUTE_MED(err); + SCRUTE_MED(i); if (err != MED_VALID) throw MEDEXCEPTION("MED_MESH_RDONLY_DRIVER22::getFAMILY() : ERROR when get FAMILY informations" ); @@ -1821,7 +1823,7 @@ int MED_MESH_RDONLY_DRIVER22::getFAMILY() if (Family->getNumberOfTypes() == 0) { - MESSAGE(LOC<<"Nothing found for family "<<FamilyName<< + MESSAGE_MED(LOC<<"Nothing found for family "<<FamilyName<< " : skip"); delete Family; } @@ -1845,7 +1847,7 @@ int MED_MESH_RDONLY_DRIVER22::getFAMILY() numberOfEdgesFamilies++ ; break ; } - // MESSAGE(LOC << (*Family)); + // MESSAGE_MED(LOC << (*Family)); } delete [] AttributesIdentifier ; @@ -1876,7 +1878,7 @@ int MED_MESH_RDONLY_DRIVER22::getFAMILY() delete[] MEDArrayEdgeFamily ; } - END_OF(LOC); + END_OF_MED(LOC); return MED_VALID ; } @@ -1887,7 +1889,7 @@ int MED_MESH_RDONLY_DRIVER22::getNodesFamiliesNumber(int * MEDArrayNodeFamily) { const char * LOC = "MED_MESH_RDONLY_DRIVER22::getNodesFamiliesNumber() : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status==MED_OPENED) { @@ -1912,7 +1914,7 @@ int MED_MESH_RDONLY_DRIVER22::getNodesFamiliesNumber(int * MEDArrayNodeFamily) if ( err != MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "There is no family for the |"<< _ptrMesh->getNumberOfNodes() << "| nodes in mesh |" << _ptrMesh->_name.c_str() << "|")); - END_OF(LOC); + END_OF_MED(LOC); return MED_VALID; } @@ -1925,7 +1927,7 @@ int MED_MESH_RDONLY_DRIVER22::getCellsFamiliesNumber(int **MEDArrayFamily, { const char * LOC = "MED_MESH_RDONLY_DRIVER22::getCellsFamiliesNumber " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status==MED_OPENED) { @@ -1940,15 +1942,15 @@ int MED_MESH_RDONLY_DRIVER22::getCellsFamiliesNumber(int **MEDArrayFamily, tmp_MEDArrayFamily,NumberOfCell, (med_2_3::med_entite_maillage) Connectivity->_entity, (med_2_3::med_geometrie_element)types[i]); - if (err != MED_VALID) + if (err != MED_VALID + && !_ptrMesh->getIsAGrid()) // it's normal for a grid (PAL14113) { err=MEDfamLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()), tmp_MEDArrayFamily,NumberOfCell, med_2_3::MED_MAILLE, (med_2_3::med_geometrie_element)types[i]); - if (err != MED_VALID - && !_ptrMesh->getIsAGrid() ) // (skl for IPAL14260) + if (err != MED_VALID ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Family not found for entity "<<Connectivity->_entity<<" and geometric type "<<types[i])); } if (err == MED_VALID) { @@ -1962,21 +1964,21 @@ int MED_MESH_RDONLY_DRIVER22::getCellsFamiliesNumber(int **MEDArrayFamily, MEDArrayFamily[i],NumberOfCell, (med_2_3::med_entite_maillage) Connectivity->_entity, (med_2_3::med_geometrie_element)types[i]); - if (err != MED_VALID) - { + if (err != MED_VALID + && !_ptrMesh->getIsAGrid() ) // it's normal for a grid (PAL14113) + { err=MEDfamLire(_medIdt,const_cast <char *> (_ptrMesh->_name.c_str()), MEDArrayFamily[i],NumberOfCell, med_2_3::MED_MAILLE, (med_2_3::med_geometrie_element)types[i]); - if (err != MED_VALID - && !_ptrMesh->getIsAGrid() ) // it's normal for a grid (PAL14113) + if (err != MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Family not found for entity "<<Connectivity->_entity<<" and geometric type "<<types[i])); } #endif } delete [] types; - return MED_VALID; + return err ? MED_INVALID : MED_VALID; } return MED_ERROR; } @@ -1985,6 +1987,7 @@ int MED_MESH_RDONLY_DRIVER22::getCellsFamiliesNumber(int **MEDArrayFamily, MED_MESH_WRONLY_DRIVER22::MED_MESH_WRONLY_DRIVER22() { + this->GENDRIVER::_accessMode = MED_EN::WRONLY; } MED_MESH_WRONLY_DRIVER22::MED_MESH_WRONLY_DRIVER22(const string & fileName, @@ -1992,17 +1995,18 @@ MED_MESH_WRONLY_DRIVER22::MED_MESH_WRONLY_DRIVER22(const string & fileName, MED_EN::med_mode_acces access): MED_MESH_DRIVER22(fileName,ptrMesh,access),IMED_MESH_WRONLY_DRIVER(fileName,ptrMesh),MED_MESH_DRIVER(fileName,ptrMesh,access) { - MESSAGE("MED_MESH_WRONLY_DRIVER22::MED_MESH_WRONLY_DRIVER22(const string & fileName, MESH * ptrMesh) has been created"); + MESSAGE_MED("MED_MESH_WRONLY_DRIVER22::MED_MESH_WRONLY_DRIVER22(const string & fileName, MESH * ptrMesh) has been created"); } MED_MESH_WRONLY_DRIVER22::MED_MESH_WRONLY_DRIVER22(const MED_MESH_WRONLY_DRIVER22 & driver): IMED_MESH_WRONLY_DRIVER(driver),MED_MESH_DRIVER22(driver),MED_MESH_DRIVER(driver) { + } MED_MESH_WRONLY_DRIVER22::~MED_MESH_WRONLY_DRIVER22() { - //MESSAGE("MED_MESH_WRONLY_DRIVER22::MED_MESH_WRONLY_DRIVER22(const string & fileName, MESH * ptrMesh) has been destroyed"); + //MESSAGE_MED("MED_MESH_WRONLY_DRIVER22::MED_MESH_WRONLY_DRIVER22(const string & fileName, MESH * ptrMesh) has been destroyed"); } @@ -2013,15 +2017,20 @@ GENDRIVER * MED_MESH_WRONLY_DRIVER22::copy(void) const void MED_MESH_WRONLY_DRIVER22::write(void) const { + + if (_ptrMesh==NULL || _ptrMesh->getCoordinateptr()==NULL) + throw MEDEXCEPTION("Error trying to write an empty mesh"); + const char * LOC = "void MED_MESH_WRONLY_DRIVER22::write(void) const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // we must first create mesh !! - MESSAGE(LOC << "MeshName : |" << _meshName << "| FileName : |"<<_fileName<<"| MedIdt : | "<< _medIdt << "|"); + MESSAGE_MED(LOC << "MeshName : |" << _meshName << "| FileName : |"<<_fileName<<"| MedIdt : | "<< _medIdt << "|"); if (_status!=MED_OPENED) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "File "<<_fileName<<" is not open. Open it before write !")); + string fieldName; if ( ( _meshName.empty() ) && ( _ptrMesh->_name.empty() ) ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) @@ -2029,7 +2038,7 @@ void MED_MESH_WRONLY_DRIVER22::write(void) const // If _meshName is not set in driver, try to use _ptrmesh->_meshName if ( ( _meshName.empty() ) && ( !_ptrMesh->_name.empty() ) ) - _meshName=_ptrMesh->_name; + _meshName = healName(_ptrMesh->_name ); if ( _meshName.size() > MED_TAILLE_NOM ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) @@ -2063,10 +2072,10 @@ void MED_MESH_WRONLY_DRIVER22::write(void) const int err ; // test if the family already exists (HDF trick waiting a MED evolution to be replaced) string dataGroupFam = "/ENS_MAA/"+_meshName+"/FAS/FAMILLE_ZERO/"; - MESSAGE("|"<<dataGroupFam<<"|"); + MESSAGE_MED("|"<<dataGroupFam<<"|"); err =med_2_3::_MEDdatagroupOuvrir(_medIdt,const_cast <char *> (dataGroupFam.c_str()) ); if ( err < MED_VALID ) { - SCRUTE(err); + SCRUTE_MED(err); char familyName[MED_TAILLE_NOM+1]; // strcpy(familyName,"FAMILLE_ZERO"); @@ -2077,7 +2086,7 @@ void MED_MESH_WRONLY_DRIVER22::write(void) const (med_2_3::med_int*)NULL, (med_2_3::med_int*)NULL, (char*)NULL, 0, (char*)NULL, 0); - SCRUTE(familyName); + SCRUTE_MED(familyName); if ( err != MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't create family |FAMILLE_ZERO| with identifier |0| groups names || and attributes descriptions ||")) ; @@ -2087,23 +2096,23 @@ void MED_MESH_WRONLY_DRIVER22::write(void) const } - MESSAGE(LOC<<"writeFamilies(_ptrMesh->_familyNode)"); + MESSAGE_MED(LOC<<"writeFamilies(_ptrMesh->_familyNode)"); if (writeFamilies(_ptrMesh->_familyNode) !=MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyNode)" )) ; - MESSAGE(LOC<<"writeFamilies(_ptrMesh->_familyCell)"); + MESSAGE_MED(LOC<<"writeFamilies(_ptrMesh->_familyCell)"); if (writeFamilies(_ptrMesh->_familyCell) !=MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyCell)" )) ; - MESSAGE(LOC<<"writeFamilies(_ptrMesh->_familyFace)"); + MESSAGE_MED(LOC<<"writeFamilies(_ptrMesh->_familyFace)"); if (writeFamilies(_ptrMesh->_familyFace) !=MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyFace)" )) ; - MESSAGE(LOC<<"writeFamilies(_ptrMesh->_familyEdge)"); + MESSAGE_MED(LOC<<"writeFamilies(_ptrMesh->_familyEdge)"); if (writeFamilies(_ptrMesh->_familyEdge) !=MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "ERROR in writeFamilies(_ptrMesh->_familyEdge)" )) ; - END_OF(LOC); + END_OF_MED(LOC); } //======================================================================= @@ -2114,11 +2123,11 @@ void MED_MESH_WRONLY_DRIVER22::write(void) const int MED_MESH_WRONLY_DRIVER22::writeGRID() const { const char * LOC = "MED_MESH_WRONLY_DRIVER22::writeGRID() : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status!=MED_OPENED) { - MESSAGE (LOC<<" Not open !!!"); + MESSAGE_MED (LOC<<" Not open !!!"); return MED_ERROR; } GRID * ptrGrid = (GRID*) _ptrMesh; @@ -2141,9 +2150,9 @@ int MED_MESH_WRONLY_DRIVER22::writeGRID() const (_meshName.c_str()) ); - MESSAGE(LOC << "spacedim " << spaceDimension << " meshdim " << meshDimension); + MESSAGE_MED(LOC << "spacedim " << spaceDimension << " meshdim " << meshDimension); - MESSAGE(LOC << "From the mesh spacedim " << _ptrMesh->_spaceDimension << " meshdim " << _ptrMesh->_meshDimension); + MESSAGE_MED(LOC << "From the mesh spacedim " << _ptrMesh->_spaceDimension << " meshdim " << _ptrMesh->_meshDimension); if ((spaceDimension <= MED_VALID) && (meshDimension <= MED_VALID)) { @@ -2157,7 +2166,7 @@ int MED_MESH_WRONLY_DRIVER22::writeGRID() const if (err != MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Unable to create Grid")); else - MESSAGE(LOC<<"Grid "<<_meshName<<" created in file "<<_fileName<<" !"); + MESSAGE_MED(LOC<<"Grid "<<_meshName<<" created in file "<<_fileName<<" !"); } else if ((spaceDimension != _ptrMesh->_spaceDimension) && (meshDimension != _ptrMesh->_meshDimension)) @@ -2182,7 +2191,7 @@ int MED_MESH_WRONLY_DRIVER22::writeGRID() const int lengthString ; string valueString ; for (int i=0;i<_ptrMesh->_spaceDimension;i++) { - SCRUTE(i); + SCRUTE_MED(i); valueString = _ptrMesh->_coordinate->_coordinateName[i] ; lengthString = (MED_TAILLE_PNOM22<valueString.size())?MED_TAILLE_PNOM22:valueString.size() ; tmp_name.replace(i*MED_TAILLE_PNOM22,i*MED_TAILLE_PNOM22+lengthString,valueString,0,lengthString); @@ -2246,7 +2255,7 @@ int MED_MESH_WRONLY_DRIVER22::writeGRID() const if (err != MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<"error in writing the structure of the grid |" << _meshName.c_str())); - delete structure; + delete [] structure; } else if ((gridType == MED_EN::MED_CARTESIAN) || (gridType == MED_EN::MED_POLAR)) @@ -2280,7 +2289,7 @@ int MED_MESH_WRONLY_DRIVER22::writeGRID() const } } // end Write Cartesian or Polar Grid - END_OF(LOC); + END_OF_MED(LOC); return MED_VALID; } @@ -2292,7 +2301,7 @@ int MED_MESH_WRONLY_DRIVER22::writeGRID() const int MED_MESH_WRONLY_DRIVER22::writeCoordinates() const { const char * LOC = "int MED_MESH_WRONLY_DRIVER22::writeCoordinates() const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); med_2_3::med_err err = MED_ERROR; med_2_3::med_repere rep; @@ -2323,10 +2332,10 @@ int MED_MESH_WRONLY_DRIVER22::writeCoordinates() const { int meshDimension = med_2_3::MEDdimLire(_medIdt, const_cast <char *> (_meshName.c_str()) ); - SCRUTE(spaceDimension); - SCRUTE(meshDimension); - SCRUTE(_ptrMesh->_spaceDimension); - SCRUTE(_ptrMesh->_meshDimension); + SCRUTE_MED(spaceDimension); + SCRUTE_MED(meshDimension); + SCRUTE_MED(_ptrMesh->_spaceDimension); + SCRUTE_MED(_ptrMesh->_meshDimension); if ((spaceDimension != MED_VALID) && (meshDimension < MED_VALID)) { @@ -2337,7 +2346,7 @@ int MED_MESH_WRONLY_DRIVER22::writeCoordinates() const { if (err < MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Unable to create Mesh : |" << _meshName << "|")); else - MESSAGE(LOC<<"Mesh "<<_meshName<<" created in file "<<_fileName<<" !"); + MESSAGE_MED(LOC<<"Mesh "<<_meshName<<" created in file "<<_fileName<<" !"); // PAL14544. Write _spaceDimension if _spaceDimension != _meshDimension if ( _ptrMesh->_spaceDimension != _ptrMesh->_meshDimension ) @@ -2436,7 +2445,7 @@ int MED_MESH_WRONLY_DRIVER22::writeCoordinates() const { } ////////////////////////////////////////////////////////////////////////////////////// - END_OF(LOC); + END_OF_MED(LOC); return MED_VALID; } @@ -2447,7 +2456,7 @@ int MED_MESH_WRONLY_DRIVER22::writeCoordinates() const { int MED_MESH_WRONLY_DRIVER22::writeConnectivities(medEntityMesh entity) const { const char * LOC="int MED_MESH_WRONLY_DRIVER22::writeConnectivities() const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); med_2_3::med_err err; @@ -2829,7 +2838,7 @@ int MED_MESH_WRONLY_DRIVER22::writeConnectivities(medEntityMesh entity) const } - END_OF(LOC); + END_OF_MED(LOC); return MED_VALID; } @@ -2849,7 +2858,8 @@ int MED_MESH_WRONLY_DRIVER22::writeConnectivities(medEntityMesh entity) const void MED_MESH_WRONLY_DRIVER22::groupFamilyConverter(const vector <GROUP*>& myGroups, vector <FAMILY*>& myFamilies ) const { - BEGIN_OF("MED_MESH_WRONLY_DRIVER::groupFamilyConverter"); + const char* LOC = "MED_MESH_WRONLY_DRIVER::groupFamilyConverter"; + BEGIN_OF_MED(LOC); if (myGroups.empty()) return; // if (!myFamilies.empty()) @@ -2990,7 +3000,7 @@ void MED_MESH_WRONLY_DRIVER22::groupFamilyConverter(const vector <GROUP*>& myGro else sprintf(family_name,"family%d",ifamily); - myFamily->setName(family_name); + myFamily->setName( healName( family_name )); string* groupnames=new string[key.size()]; //myFamily->getGroupsNames(); @@ -3018,22 +3028,23 @@ void MED_MESH_WRONLY_DRIVER22::groupFamilyConverter(const vector <GROUP*>& myGro //have different name sizes strncpy(family_name,myGroups[i]->getName().c_str(),MED_TAILLE_NOM); family_name[MED_TAILLE_NOM-1]='\0'; - myFamily->setName(family_name); + myFamily->setName( healName( family_name )); myFamily->setIdentifier(ifamily); ifamily++; vector<string> groupnames; groupnames.push_back(myGroups[i]->getName()); + myFamily->setNumberOfGroups(1); myFamily->setGroupsNames(&groupnames[0]); myFamilies.push_back(myFamily); } } - END_OF("MED_MESH_WRONLY_DRIVER::groupFamilyConverter"); + END_OF_MED(LOC); } int MED_MESH_WRONLY_DRIVER22::writeFamilyNumbers() const { const char * LOC="int MED_MESH_WRONLY_DRIVER22::writeFamilyNumbers() const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); med_2_3::med_err err; @@ -3061,8 +3072,8 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilyNumbers() const { NumberOfNodesFamilies=myFamilies->size() ; } for (int i=0 ; i<NumberOfNodesFamilies; i++) { - //SCRUTE(i); - //SCRUTE(myFamilies[i]->getName()); + //SCRUTE_MED(i); + //SCRUTE_MED(myFamilies[i]->getName()); int FamilyIdentifier = (*myFamilies)[i]->getIdentifier() ; int TotalNumber = (*myFamilies)[i]->getNumberOfElements(MED_ALL_ELEMENTS) ; if ((*myFamilies)[i]->isOnAllElements()) @@ -3076,7 +3087,7 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilyNumbers() const { } // for(int j=0; j<NumberOfNodes; j++) { -// SCRUTE(MEDArrayNodeFamily[j]); +// SCRUTE_MED(MEDArrayNodeFamily[j]); // } // if ( !_ptrMesh->getIsAGrid() ) @@ -3146,7 +3157,7 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilyNumbers() const { // for (int i=0; i<NumberOfElements; i++) -// SCRUTE(MEDArrayFamily[i]); +// SCRUTE_MED(MEDArrayFamily[i]); //const int * typeCount = _ptrMesh->getGlobalNumberingIndex(entity); @@ -3175,7 +3186,7 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilyNumbers() const { (med_2_3::med_entite_maillage) MED_CELL, (med_2_3::med_geometrie_element) types[i]); #endif - MESSAGE("OK "<<i); + MESSAGE_MED("OK "<<i); if ( err != MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't write family for the |"<< typeNumberOfElements << "| cells of geometric type |" << geoNames[types[i]] <<"|in mesh |" @@ -3196,6 +3207,8 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilyNumbers() const { } } + if (!_ptrMesh->getIsAGrid() || _ptrMesh->_meshDimension == 3 ) // for grid - only in 3D mesh + { // FACE RELATED BLOCK medEntityMesh entity=MED_EN::MED_FACE; // SOLUTION TEMPORAIRE CAR _ptrMesh->_MEDArray____Family DOIT ETRE ENLEVER DE LA CLASSE MESH @@ -3205,7 +3218,7 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilyNumbers() const { { int numberOfTypes = _ptrMesh->getNumberOfTypesWithPoly(entity) ; medGeometryElement * types = _ptrMesh->getTypesWithPoly(entity) ; - SCRUTE(numberOfTypes); + SCRUTE_MED(numberOfTypes); int numberOfElements = _ptrMesh->getNumberOfElementsWithPoly(entity, MED_ALL_ELEMENTS) ; int * familyArray = new int[numberOfElements] ; @@ -3238,7 +3251,7 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilyNumbers() const { } for (int i=0;i<numberOfElements;i++) - SCRUTE(familyArray[i]); + SCRUTE_MED(familyArray[i]); //CCRT Clutter #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64) @@ -3247,12 +3260,12 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilyNumbers() const { for(int i2=0;i2<lgth;i2++) temp[i2]=(med_2_3::med_int) (familyArray[i2]); #endif - SCRUTE(numberOfTypes); + SCRUTE_MED(numberOfTypes); int offset=0; for (int i=0; i<numberOfTypes; i++) { int typeNumberOfElements = _ptrMesh->getNumberOfElementsWithPoly(entity,types[i]) ; - SCRUTE(typeNumberOfElements); - SCRUTE(offset); + SCRUTE_MED(typeNumberOfElements); + SCRUTE_MED(offset); #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64) err = MEDfamEcr(_medIdt, const_cast <char *> ( _meshName.c_str() ), (temp+offset), typeNumberOfElements, @@ -3260,7 +3273,7 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilyNumbers() const { (med_2_3::med_entite_maillage) MED_CELL, (med_2_3::med_geometrie_element) types[i]); #else - MESSAGE("On est bien la !!! entity = " << entity << " type " << types[i]); + MESSAGE_MED("On est bien la !!! entity = " << entity << " type " << types[i]); err = MEDfamEcr(_medIdt, const_cast <char *> ( _meshName.c_str() ), (familyArray+offset), typeNumberOfElements, @@ -3289,6 +3302,8 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilyNumbers() const { } } + if (!_ptrMesh->getIsAGrid() || _ptrMesh->_meshDimension > 1 ) // for grid - only in 3D and 2D mesh + { // EDGE RELATED BLOCK //medEntityMesh entity=MED_EN::MED_FACE; medEntityMesh entity=MED_EN::MED_EDGE; @@ -3335,7 +3350,7 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilyNumbers() const { for (int i=0;i<numberOfElements;i++) - SCRUTE(familyArray[i]); + SCRUTE_MED(familyArray[i]); const int * typeCount = _ptrMesh->getGlobalNumberingIndex(entity) ; @@ -3346,13 +3361,13 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilyNumbers() const { for(int i2=0;i2<lgth;i2++) temp[i2]=(med_2_3::med_int) (familyArray[i2]); #endif - SCRUTE(numberOfTypes); + SCRUTE_MED(numberOfTypes); for (int i=0; i<numberOfTypes; i++) { int typeNumberOfElements = typeCount[i+1] - typeCount[i] ; - SCRUTE(typeNumberOfElements); - SCRUTE(typeCount[i+1]); - SCRUTE(typeCount[i]); + SCRUTE_MED(typeNumberOfElements); + SCRUTE_MED(typeCount[i+1]); + SCRUTE_MED(typeCount[i]); #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64) err = MEDfamEcr(_medIdt, const_cast <char *> ( _meshName.c_str() ), (temp+(typeCount[i]-1)), typeNumberOfElements, @@ -3384,7 +3399,7 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilyNumbers() const { } } - END_OF(LOC); + END_OF_MED(LOC); return MED_VALID; } @@ -3392,11 +3407,11 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilies(vector<FAMILY*> & families ) const { const char * LOC="int MED_MESH_WRONLY_DRIVER22::writeFamilies(vector<FAMILY*> families) const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); med_2_3::med_err err; - MESSAGE(LOC<<" families.size() :"<<families.size()); + MESSAGE_MED(LOC<<" families.size() :"<<families.size()); for (unsigned int i=0; i< families.size(); i++) { @@ -3447,10 +3462,10 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilies(vector<FAMILY*> & families ) const else dataGroupFam = "/ENS_MAA/"+_meshName+"/FAS/ELEME/"+families[i]->getName()+"/"; - SCRUTE("|"<<dataGroupFam<<"|"); + SCRUTE_MED("|"<<dataGroupFam<<"|"); err = med_2_3::_MEDdatagroupOuvrir(_medIdt,const_cast <char *> (dataGroupFam.c_str()) ) ; if ( err < MED_VALID ) { - SCRUTE(err); + SCRUTE_MED(err); if ( families[i]->getName().size() > MED_TAILLE_NOM ) throw MEDEXCEPTION ( LOCALIZED(STRING(LOC) << "The size of the name of the family |" << i+1 @@ -3459,16 +3474,16 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilies(vector<FAMILY*> & families ) const << families[i]->getName().size() <<"| and is more than |" << MED_TAILLE_NOM << "|")) ; - MESSAGE(LOC<<"families[i]->getName().c_str() : "<<families[i]->getName().c_str()); - MESSAGE(LOC<<"_meshName.c_str() : "<<_meshName.c_str()); - MESSAGE(LOC<<"families[i]->getIdentifier() : "<<families[i]->getIdentifier()); - MESSAGE(LOC<<"numberOfAttributes : "<<numberOfAttributes); + MESSAGE_MED(LOC<<"families[i]->getName().c_str() : "<<families[i]->getName().c_str()); + MESSAGE_MED(LOC<<"_meshName.c_str() : "<<_meshName.c_str()); + MESSAGE_MED(LOC<<"families[i]->getIdentifier() : "<<families[i]->getIdentifier()); + MESSAGE_MED(LOC<<"numberOfAttributes : "<<numberOfAttributes); - //MESSAGE(LOC<<"families[i]->getAttributesIdentifiers() : "<<families[i]->getAttributesIdentifiers()[0]); - //MESSAGE(LOC<<"families[i]->getAttributesValues() : "<<families[i]->getAttributesValues()[0]); - MESSAGE(LOC<<"attributesDescriptions.c_str() : "<<attributesDescriptions.c_str()); - MESSAGE(LOC<<"numberOfGroups : "<<numberOfGroups); - MESSAGE(LOC<<"groupsNames.c_str() : "<<groupsNames.c_str()); + //MESSAGE_MED(LOC<<"families[i]->getAttributesIdentifiers() : "<<families[i]->getAttributesIdentifiers()[0]); + //MESSAGE_MED(LOC<<"families[i]->getAttributesValues() : "<<families[i]->getAttributesValues()[0]); + MESSAGE_MED(LOC<<"attributesDescriptions.c_str() : "<<attributesDescriptions.c_str()); + MESSAGE_MED(LOC<<"numberOfGroups : "<<numberOfGroups); + MESSAGE_MED(LOC<<"groupsNames.c_str() : "<<groupsNames.c_str()); #if defined(IRIX64) || defined(OSF1) || defined(VPP5000) || defined(PCLINUX64) int lgth=families[i]->getNumberOfAttributes(); med_2_3::med_int * AttributesIdentifier2 = new med_2_3::med_int[lgth] ; @@ -3480,7 +3495,7 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilies(vector<FAMILY*> & families ) const } err = med_2_3::MEDfamCr( _medIdt, const_cast <char *> ( _meshName.c_str() ), - const_cast <char *> ( families[i]->getName().c_str() ), + const_cast <char *> ( healName(families[i]->getName()).c_str() ), families[i]->getIdentifier(), AttributesIdentifier2, AttributesValues2, @@ -3493,7 +3508,7 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilies(vector<FAMILY*> & families ) const #else err = med_2_3::MEDfamCr( _medIdt, const_cast <char *> ( _meshName.c_str() ), - const_cast <char *> ( families[i]->getName().c_str() ), + const_cast <char *> ( healName(families[i]->getName()).c_str() ), families[i]->getIdentifier(), (med_2_3::med_int*)families[i]->getAttributesIdentifiers(), (med_2_3::med_int*)families[i]->getAttributesValues(), @@ -3502,7 +3517,7 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilies(vector<FAMILY*> & families ) const const_cast <char *> (groupsNames.c_str()), numberOfGroups); #endif - SCRUTE(err); + SCRUTE_MED(err); if (err != MED_VALID) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Can't create family |" << families[i]->getName() << "| with identifier |" << families[i]->getIdentifier() @@ -3514,7 +3529,7 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilies(vector<FAMILY*> & families ) const } - END_OF(LOC); + END_OF_MED(LOC); return MED_VALID; } @@ -3528,34 +3543,37 @@ int MED_MESH_WRONLY_DRIVER22::writeFamilies(vector<FAMILY*> & families ) const MED_MESH_RDWR_DRIVER22::MED_MESH_RDWR_DRIVER22() { + this->GENDRIVER::_accessMode = MED_EN::RDWR; } MED_MESH_RDWR_DRIVER22::MED_MESH_RDWR_DRIVER22(const string & fileName, MESH * ptrMesh): - MED_MESH_DRIVER(fileName,ptrMesh,MED_RDWR), + MED_MESH_DRIVER(fileName,ptrMesh,RDWR), IMED_MESH_RDONLY_DRIVER(fileName,ptrMesh), IMED_MESH_WRONLY_DRIVER(fileName,ptrMesh), IMED_MESH_RDWR_DRIVER(fileName,ptrMesh), - MED_MESH_DRIVER22(fileName,ptrMesh,MED_RDWR), + MED_MESH_DRIVER22(fileName,ptrMesh,RDWR), MED_MESH_RDONLY_DRIVER22(fileName,ptrMesh), MED_MESH_WRONLY_DRIVER22(fileName,ptrMesh) { - MESSAGE("MED_MESH_RDWR_DRIVER22::MED_MESH_RDWR_DRIVER22(const string & fileName, MESH * ptrMesh) has been created"); + + MESSAGE_MED("MED_MESH_RDWR_DRIVER22::MED_MESH_RDWR_DRIVER22(const string & fileName, MESH * ptrMesh) has been created"); } MED_MESH_RDWR_DRIVER22::MED_MESH_RDWR_DRIVER22(const MED_MESH_RDWR_DRIVER22 & driver): MED_MESH_DRIVER(driver), IMED_MESH_RDONLY_DRIVER(driver), IMED_MESH_WRONLY_DRIVER(driver), - IMED_MESH_RDWR_DRIVER(driver), MED_MESH_DRIVER22(driver), MED_MESH_RDONLY_DRIVER22(driver), - MED_MESH_WRONLY_DRIVER22(driver) + MED_MESH_WRONLY_DRIVER22(driver), + IMED_MESH_RDWR_DRIVER(driver) + { } MED_MESH_RDWR_DRIVER22::~MED_MESH_RDWR_DRIVER22() { - //MESSAGE("MED_MESH_RDWR_DRIVER22::MED_MESH_RDWR_DRIVER22(const string & fileName, MESH * ptrMesh) has been destroyed"); + //MESSAGE_MED("MED_MESH_RDWR_DRIVER22::MED_MESH_RDWR_DRIVER22(const string & fileName, MESH * ptrMesh) has been destroyed"); } GENDRIVER * MED_MESH_RDWR_DRIVER22::copy(void) const diff --git a/src/MEDMEM/MEDMEM_MedMeshDriver22.hxx b/src/MEDMEM/MEDMEM_MedMeshDriver22.hxx index 14f6a2589..c2791b545 100644 --- a/src/MEDMEM/MEDMEM_MedMeshDriver22.hxx +++ b/src/MEDMEM/MEDMEM_MedMeshDriver22.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef MED_MESH_DRIVER22_HXX #define MED_MESH_DRIVER22_HXX @@ -132,6 +134,7 @@ private: void getGRID (); GENDRIVER * copy ( void ) const ; + virtual void merge ( const GENDRIVER& driver ); private: bool _computeFaces; @@ -156,7 +159,7 @@ public : /*! Constructor. */ - MED_MESH_WRONLY_DRIVER22(const string & fileName, MESH * ptrMesh, MED_EN::med_mode_acces access=MED_EN::MED_WRONLY) ; + MED_MESH_WRONLY_DRIVER22(const string & fileName, MESH * ptrMesh, MED_EN::med_mode_acces access=MED_EN::WRONLY) ; /*! Copy constructor. */ @@ -227,6 +230,6 @@ private: GENDRIVER * copy(void) const ; }; -}; +} #endif /* MED_MESH_DRIVER22_HXX */ diff --git a/src/MEDMEM/MEDMEM_MedVersion.cxx b/src/MEDMEM/MEDMEM_MedVersion.cxx index 3cbc7031d..62df06def 100644 --- a/src/MEDMEM/MEDMEM_MedVersion.cxx +++ b/src/MEDMEM/MEDMEM_MedVersion.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_MedVersion.hxx" #include "MEDMEM_Utilities.hxx" @@ -63,7 +65,7 @@ medFileVersion MEDMEM::getMedFileVersion(const string & fileName) if ((minor21 == -1) || (release21 == -1)) { - MESSAGE("getMedFileVersion the file may have been produced by a version 2.1.x x<5"); + MESSAGE_MED("getMedFileVersion the file may have been produced by a version 2.1.x x<5"); minor21 = 1; release21 = 5; } @@ -90,7 +92,7 @@ medFileVersion MEDMEM::getMedFileVersion(const string & fileName) if ((minor22 == -1) || (release22 == -1)) { - MESSAGE("getMedFileVersion the file may have been produced by a version 2.1.x x<5"); + MESSAGE_MED("getMedFileVersion the file may have been produced by a version 2.1.x x<5"); minor22 = 1; release22 = 5; } @@ -103,9 +105,9 @@ medFileVersion MEDMEM::getMedFileVersion(const string & fileName) if ((major21 != major22) || (minor21 != minor22) || (release21 != release22)) throw MEDEXCEPTION("Problem in getMedFileVersion(const string &) Med file V21 and V22 version numbers are different"); - MESSAGE("getMedFileVersion: status version 21 of the file major " << major21 << " minor " << minor21 << " release " << release21); + MESSAGE_MED("getMedFileVersion: status version 21 of the file major " << major21 << " minor " << minor21 << " release " << release21); - MESSAGE("getMedFileVersion: status version 22 of the file major " << major22 << " minor " << minor22 << " release " << release22); + MESSAGE_MED("getMedFileVersion: status version 22 of the file major " << major22 << " minor " << minor22 << " release " << release22); if (major21 == 2) { @@ -117,7 +119,7 @@ medFileVersion MEDMEM::getMedFileVersion(const string & fileName) else version = V22; - MESSAGE("getMedFileVersion the version of the file is " << version); + MESSAGE_MED("getMedFileVersion the version of the file is " << version); return version; } @@ -133,12 +135,12 @@ medFileVersion MEDMEM::getMedFileVersion(const string & fileName) */ //================================================================================ -int MEDMEM::getMedAccessMode(MED_EN::med_mode_acces mode, - MED_EN::medFileVersion medVersion) - throw (MEDEXCEPTION) -{ - switch ( medVersion ) { - case V21: +//int MEDMEM::getMedAccessMode(MED_EN::med_mode_acces mode, +// MED_EN::medFileVersion medVersion) +// throw (MEDEXCEPTION) +//{ +// switch ( medVersion ) { +// case V21: /* from MEDouvrir.c: switch(mode_acces) @@ -167,14 +169,14 @@ int MEDMEM::getMedAccessMode(MED_EN::med_mode_acces mode, return -1; break; */ - switch ( mode ) { - case MED_EN::MED_LECT: return med_2_1::MED_LECT; - case MED_EN::MED_ECRI: return med_2_1::MED_ECRI; - case MED_EN::MED_REMP: return med_2_1::MED_ECRI; - default: - throw MEDEXCEPTION("getMedAccessMode(): Wrong access mode"); - } - case V22: +// switch ( mode ) { +// case MED_EN::MED_LECT: return med_2_1::MED_LECT; +// case MED_EN::MED_ECRI: return med_2_1::MED_ECRI; +// case MED_EN::MED_REMP: return med_2_1::MED_ECRI; +// default: +// throw MEDEXCEPTION("getMedAccessMode(): Wrong access mode"); +// } +// case V22: /* from med.h: MED_LECTURE : Ouverture en lecture seule @@ -182,15 +184,15 @@ int MEDMEM::getMedAccessMode(MED_EN::med_mode_acces mode, MED_LECTURE_AJOUT : Ouverture en lecture/ecriture, si un élément existe une erreur est générée MED_CREATION : Créer le fichier s'il n'existe pas, l'écrase sinon */ - switch ( mode ) { - case MED_EN::MED_LECT: return med_2_3::MED_LECTURE; - case MED_EN::MED_ECRI: return med_2_3::MED_LECTURE_ECRITURE; - case MED_EN::MED_REMP: return med_2_3::MED_LECTURE_ECRITURE; - case MED_EN::MED_CREA: return med_2_3::MED_CREATION; - default: - throw MEDEXCEPTION("getMedAccessMode(): Wrong access mode"); - } - default:; - } - throw MEDEXCEPTION("getMedAccessMode(): Unknown med version"); -} +// switch ( mode ) { +// case MED_EN::MED_LECT: return med_2_3::MED_LECTURE; +// case MED_EN::MED_ECRI: return med_2_3::MED_LECTURE_ECRITURE; +// case MED_EN::MED_REMP: return med_2_3::MED_LECTURE_ECRITURE; +// case MED_EN::MED_CREA: return med_2_3::MED_CREATION; +// default: +// throw MEDEXCEPTION("getMedAccessMode(): Wrong access mode"); +// } +// default:; +// } +// throw MEDEXCEPTION("getMedAccessMode(): Unknown med version"); +//} diff --git a/src/MEDMEM/MEDMEM_MedVersion.hxx b/src/MEDMEM/MEDMEM_MedVersion.hxx index d08f3dbdd..6af090a7f 100644 --- a/src/MEDMEM/MEDMEM_MedVersion.hxx +++ b/src/MEDMEM/MEDMEM_MedVersion.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef MED_VERSION_HXX #define MED_VERSION_HXX @@ -31,13 +33,13 @@ namespace MEDMEM { MEDMEM_EXPORT MED_EN::medFileVersion getMedFileVersion(const string & fileName) throw (MEDEXCEPTION); - int getMedAccessMode(MED_EN::med_mode_acces mode, - MED_EN::medFileVersion medVersion) - throw (MEDEXCEPTION); + //int getMedAccessMode(MED_EN::med_mode_acces mode, + // MED_EN::medFileVersion medVersion) + // throw (MEDEXCEPTION); - int getMedAccessMode(MED_EN::med_mode_acces mode, - MED_EN::medFileVersion medVersion) - throw (MEDEXCEPTION); + //int getMedAccessMode(MED_EN::med_mode_acces mode, + // MED_EN::medFileVersion medVersion) + // throw (MEDEXCEPTION); } #endif /* MED_VERSION_HXX */ diff --git a/src/MEDMEM/MEDMEM_Mesh.cxx b/src/MEDMEM/MEDMEM_Mesh.cxx index 76b82d3a8..3ca73cf6f 100644 --- a/src/MEDMEM/MEDMEM_Mesh.cxx +++ b/src/MEDMEM/MEDMEM_Mesh.cxx @@ -1,25 +1,26 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // /* File Mesh.cxx - $Header$ */ #include <math.h> @@ -36,7 +37,7 @@ #include "MEDMEM_Coordinate.hxx" #include "MEDMEM_Connectivity.hxx" #include "MEDMEM_CellModel.hxx" -#include "MEDMEM_Formulae.hxx" +#include "VolSurfFormulae.hxx" #include "MEDMEM_InterpolationHighLevelObjects.hxx" #include "MEDMEM_DriverFactory.hxx" @@ -47,6 +48,47 @@ using namespace MED_EN; #define MED_NOPDT -1 #define MED_NONOR -1 +// Block defining groups for the MEDMEM_ug documentation +/*! +\defgroup MESH_constructors MESH Constructors + +The MESH class provides only two constructors : a copy constructor and +a constructor enabling creation from file reading. The creation of +a user-defined mesh implies the use of the MESHING class. + +\defgroup MESH_advanced MESH Advanced features +These functions provide access to high-level manipulation of the meshes, giving +information about the cells or extracting supports from the mesh. + +\defgroup MESH_connectivity MESH Connectivity information +These methods are related to the extraction of connectivity information +from the mesh. + +\defgroup MESH_nodes MESH Nodes information +These methods are related to the extraction of information about the mesh nodes. + +\defgroup MESH_general MESH General information + +These methods are related to the retrieval of general information about the mesh. + +\defgroup MESH_poly MESH Polygons and Polyhedra information + +These methods are specific methods used for retrieving connectivity +information for MED_POLYGON and MED_POLYHEDRON elements. + + +\defgroup MESH_families Families and Groups handling + +The methods described in this section enable the manipulation of families and groups. These +notions define subsets of MED elements in a mesh. They differ because families are non +overlapping (a mesh element is associated to zero or one family) while groups are more general. + +\defgroup MESH_io Mesh I/O +These methods describe how to read and write meshes. Generally speaking, meshes should be read +via a constructor and should be written with the addDriver()/write() methods. + +*/ + // ------- Drivers Management Part /*! Add a %MESH driver of type %driverTypes (MED_DRIVER, ....) associated with file fileName. The meshname used in the file @@ -54,15 +96,14 @@ using namespace MED_EN; int MESH::addDriver(driverTypes driverType, const string & fileName/*="Default File Name.med"*/, const string & driverName/*="Default Mesh Name"*/, - med_mode_acces access) { - - const char * LOC = "MESH::addDriver(driverTypes driverType, const string & fileName=\"Default File Name.med\",const string & driverName=\"Default Mesh Name\",MED_EN::med_mode_acces access) : "; + MED_EN::med_mode_acces access) +{ + const char* LOC = "MESH::addDriver(driverTypes driverType, const string & fileName=\"Default File Name.med\",const string & driverName=\"Default Mesh Name\",MED_EN::med_mode_acces access) : "; + BEGIN_OF_MED(LOC); GENDRIVER * driver; - BEGIN_OF(LOC); - - SCRUTE(driverType); + SCRUTE_MED(driverType); driver = DRIVERFACTORY::buildDriverForMesh(driverType,fileName,this, driverName,access) ; @@ -73,34 +114,49 @@ int MESH::addDriver(driverTypes driverType, _drivers[current]->setMeshName(driverName); - END_OF(LOC); + END_OF_MED(LOC); return current; } /*! Add an existing MESH driver. */ -int MESH::addDriver(GENDRIVER & driver) { - const char * LOC = "MESH::addDriver(GENDRIVER &) : "; - BEGIN_OF(LOC); +int MESH::addDriver(GENDRIVER & driver) +{ + const char* LOC = "MESH::addDriver(GENDRIVER &) : "; + BEGIN_OF_MED(LOC); // A faire : Vérifier que le driver est de type MESH. - GENDRIVER * newDriver = driver.copy() ; + // For the case where driver does not know about me, i.e. has been created through + // constructor witout parameters: create newDriver knowing me and get missing data + // from driver using merge() + //GENDRIVER * newDriver = driver.copy() ; + GENDRIVER* newDriver = DRIVERFACTORY::buildDriverForMesh(driver.getDriverType(), + driver.getFileName(), this, + driver.getMeshName(), + driver.getAccessMode()); _drivers.push_back(newDriver); - return _drivers.size()-1; - END_OF(LOC); + int current = _drivers.size()-1; + driver.setId(current); + + newDriver->merge( driver ); + newDriver->setId( current ); + + return current; + + END_OF_MED(LOC); } /*! Remove an existing MESH driver. */ void MESH::rmDriver (int index/*=0*/) { const char * LOC = "MESH::rmDriver (int index=0): "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); - if ( _drivers[index] ) { - //_drivers.erase(&_drivers[index]); - // why not ???? - MESSAGE ("detruire"); + if (index >= 0 && index < _drivers.size() && _drivers[index]) { + delete _drivers[index]; + _drivers[index] = 0; + MESSAGE_MED ("detruire"); } else throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) @@ -109,18 +165,18 @@ void MESH::rmDriver (int index/*=0*/) { ) ); - END_OF(LOC); + END_OF_MED(LOC); }; // ------ End of Drivers Management Part -void MESH::init() { - - const char * LOC = "MESH::init(): "; +void MESH::init() +{ - BEGIN_OF(LOC); + const char* LOC = "MESH::init(): "; + BEGIN_OF_MED(LOC); _name = "NOT DEFINED"; // A POSITIONNER EN FCT DES IOS ? @@ -135,7 +191,7 @@ void MESH::init() { _arePresentOptionnalNodesNumbers = 0; - END_OF(LOC); + END_OF_MED(LOC); }; /*! Create an empty MESH. */ @@ -143,6 +199,14 @@ MESH::MESH():_coordinate(NULL),_connectivity(NULL), _isAGrid(false) { init(); }; +/*! \if MEDMEM_ug + \addtogroup MESH_constructors +@{ +\endif +*/ +/*! +Copy constructor +*/ MESH::MESH(MESH &m) { _name=m._name; @@ -221,9 +285,15 @@ MESH::MESH(MESH &m) //_drivers = m._drivers; //Recopie des drivers? } +/*! +\if MEDMEM_ug +@} +\endif +*/ + MESH::~MESH() { - MESSAGE("MESH::~MESH() : Destroying the Mesh"); + MESSAGE_MED("MESH::~MESH() : Destroying the Mesh"); if (_coordinate != ((COORDINATE *) NULL)) delete _coordinate ; if (_connectivity != ((CONNECTIVITY *) NULL)) delete _connectivity ; int size ; @@ -252,17 +322,28 @@ MESH::~MESH() { for (int i=0;i<size;i++) delete _groupEdge[i] ; - MESSAGE("In this object MESH there is(are) " << _drivers.size() << " driver(s)"); + map<medEntityMesh,SUPPORT*>::iterator it = _entitySupport.begin(); + for(;it!=_entitySupport.end();it++) + if((*it).second != NULL) + delete (*it).second; + + MESSAGE_MED("In this object MESH there is(are) " << _drivers.size() << " driver(s)"); for (unsigned int index=0; index < _drivers.size(); index++ ) { - SCRUTE(_drivers[index]); + SCRUTE_MED(_drivers[index]); if ( _drivers[index] != NULL) delete _drivers[index]; } } -/* + +/*! \if MEDMEM_ug +\addtogroup MESH_poly +@{ +\endif +*/ +/*! Method equivalent to getNumberOfTypes except that it includes not only classical Types but polygons/polyhedra also. */ int MESH::getNumberOfTypesWithPoly(MED_EN::medEntityMesh Entity) const @@ -305,6 +386,9 @@ int MESH::getNumberOfElementsWithPoly(MED_EN::medEntityMesh Entity, MED_EN::medG return getNumberOfElements(Entity,Type); } +/*! \if MEDMEM_ug +@} +\endif*/ bool MESH::existConnectivityWithPoly(MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const { @@ -315,10 +399,10 @@ bool MESH::existConnectivityWithPoly(MED_EN::medConnectivity ConnectivityType, MESH & MESH::operator=(const MESH &m) { - const char * LOC = "MESH & MESH::operator=(const MESH &m) : "; - BEGIN_OF(LOC); + const char* LOC = "MESH & MESH::operator=(const MESH &m) : "; + BEGIN_OF_MED(LOC); - MESSAGE(LOC <<"Not yet implemented, operating on the object " << m); + MESSAGE_MED(PREFIX_MED <<"Not yet implemented, operating on the object " << m); // A FAIRE......... // ATTENTION CET OPERATEUR DE RECOPIE EST DANGEREUX POUR LES @@ -351,59 +435,94 @@ MESH & MESH::operator=(const MESH &m) // reverse_nodal_connectivity = m.reverse_nodal_connectivity; // reverse_nodal_connectivity_index = m.reverse_nodal_connectivity_index ; // } - END_OF(LOC); + END_OF_MED(LOC); return *this; } bool MESH::operator==(const MESH& other) const { - BEGIN_OF("MESH::operator=="); + const char* LOC = "MESH::operator=="; + BEGIN_OF_MED(LOC); return this==&other; } -/*! Create a %MESH object using a %MESH driver of type %driverTypes (MED_DRIVER, ....) associated with file fileName. - The meshname driverName must already exists in the file.*/ +/*!\if MEDMEM_ug +\addtogroup MESH_constructors +@{ +\endif +*/ +/*! + Creates a %MESH object using a %MESH driver of type %driverTypes (MED_DRIVER, GIBI_DRIVER, ...) associated with file \a fileName. As several meshes can coexist in the same file (notably in MED files) , the constructor takes a third argument that specifies the name of the mesh. +The constructor will throw an exception if the file does not exist, has no reading permissions or if the mesh does not exist in the file. +*/ MESH::MESH(driverTypes driverType, const string & fileName/*=""*/, const string & driverName/*=""*/) throw (MEDEXCEPTION) { - const char * LOC ="MESH::MESH(driverTypes driverType, const string & fileName="", const string & driverName="") : "; - int current; + const char * LOC = "MESH::MESH(driverTypes driverType, const string & fileName="", const string & driverName/="") : "; + BEGIN_OF_MED(LOC); - BEGIN_OF(LOC); + int current; init(); - GENDRIVER *myDriver=DRIVERFACTORY::buildDriverForMesh(driverType,fileName,this,driverName,MED_LECT); + GENDRIVER *myDriver=DRIVERFACTORY::buildDriverForMesh(driverType,fileName,this,driverName,RDONLY); current = addDriver(*myDriver); delete myDriver; _drivers[current]->open(); _drivers[current]->read(); _drivers[current]->close(); - END_OF(LOC); + END_OF_MED(LOC); }; +/*!\if MEDMEM_ug + @} +\endif +*/ -/* - for a deep comparison of 2 meshes. +/*! +\addtogroup MESH_general +@{ +*/ +/*! +Returns true if mesh \a other has same +coordinates (to 1E-15 precision ) and same connectivity as the calling object. +Information like name or description is not taken into account +for the comparison. */ + bool MESH::deepCompare(const MESH& other) const { int size1=getSpaceDimension()*getNumberOfNodes(); int size2=other.getSpaceDimension()*other.getNumberOfNodes(); if(size1!=size2) return false; - const double* coord1=getCoordinates(MED_FULL_INTERLACE); - const double* coord2=other.getCoordinates(MED_FULL_INTERLACE); + + const COORDINATE* CRD = other.getCoordinateptr(); + if( (!CRD && _coordinate) || (CRD && !(_coordinate)) ) { + return false; + } + bool ret=true; - for(int i=0;i<size1 && ret;i++) - { + if( _coordinate ) { + const double* coord1=getCoordinates(MED_FULL_INTERLACE); + const double* coord2=other.getCoordinates(MED_FULL_INTERLACE); + for(int i=0;i<size1 && ret;i++) { ret=(fabs(coord1[i]-coord2[i])<1e-15); } - if(ret) - { + } + if(ret) { + const CONNECTIVITY* CNV = other.getConnectivityptr(); + if( (!CNV && _connectivity) || (CNV && !(_connectivity)) ) { + return false; + } + if(_connectivity) { return _connectivity->deepCompare(*other._connectivity); } + } return ret; } +/*! +@} +*/ /*! * \brief print my contents @@ -420,6 +539,11 @@ void MESH::printMySelf(ostream &os) const int meshdimension = myMesh.getMeshDimension(); int numberofnodes = myMesh.getNumberOfNodes(); + if ( spacedimension == MED_INVALID ) { + os << " Empty mesh ..."; + return; + } + os << "Space Dimension : " << spacedimension << endl << endl; os << "Mesh Dimension : " << meshdimension << endl << endl; @@ -430,15 +554,19 @@ void MESH::printMySelf(ostream &os) const os << "SHOW NODES COORDINATES : " << endl; os << "Name :" << endl; const string * coordinatesnames = myMesh.getCoordinatesNames(); - for(int i=0; i<spacedimension ; i++) - { - os << " - " << coordinatesnames[i] << endl; + if ( coordinatesnames ) { + for(int i=0; i<spacedimension ; i++) + { + os << " - " << coordinatesnames[i] << endl; + } } os << "Unit :" << endl; const string * coordinatesunits = myMesh.getCoordinatesUnits(); - for(int i=0; i<spacedimension ; i++) - { - os << " - " << coordinatesunits[i] << endl; + if ( coordinatesunits ) { + for(int i=0; i<spacedimension ; i++) + { + os << " - " << coordinatesunits[i] << endl; + } } for(int i=0; i<numberofnodes ; i++) { @@ -495,10 +623,13 @@ void MESH::printMySelf(ostream &os) const Return -1 if not found. */ -int MESH::getElementNumber(medConnectivity ConnectivityType, medEntityMesh Entity, medGeometryElement Type, int * connectivity) const +int MESH::getElementNumber(MED_EN::medConnectivity ConnectivityType, + MED_EN::medEntityMesh Entity, + MED_EN::medGeometryElement Type, + int * connectivity) const { const char* LOC="MESH::getElementNumber " ; - BEGIN_OF(LOC) ; + BEGIN_OF_MED(LOC) ; int numberOfValue ; // size of connectivity array CELLMODEL myType(Type) ; @@ -546,21 +677,38 @@ int MESH::getElementNumber(medConnectivity ConnectivityType, medEntityMesh Entit if (cellsList.size()==0) return -1; - END_OF(LOC); + END_OF_MED(LOC); return cellsList.front() ; } /*! - Return a support which reference all elements on the boundary of mesh. +\addtogroup MESH_advanced +@{ +The methods described in this section are algorithms that perform a computation +and return a result in the form of a SUPPORT or a FIELD to the user. For large meshes, +as the returned information is not stored in the mesh but is rather computed, the +computation time can be large. +*/ + +/*! + Returns a support which reference all elements on the boundary of mesh. + For a d-dimensional mesh, a boundary element is defined as a d-1 dimension + element that is referenced by only one element in the full descending connectivity. + + This method can also return the list of nodes that belong to the boundary elements. + + WARNING: This method can recalculate descending connectivity from partial to full form, + so that partial SUPPORT on d-1 dimension elements becomes invalid. - For instance, we could get only face in 3D and edge in 2D. + \param Entity entity on which the boundary is desired. It has to be either \a MED_NODE or the + d-1 dimension entity type (MED_FACE in 3D, MED_EDGE in 2D). */ -SUPPORT * MESH::getBoundaryElements(medEntityMesh Entity) +SUPPORT * MESH::getBoundaryElements(MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION) { const char * LOC = "MESH::getBoundaryElements : " ; - BEGIN_OF(LOC) ; + BEGIN_OF_MED(LOC) ; // some test : // actually we could only get face (in 3D) and edge (in 2D) medEntityMesh entityToParse=Entity; @@ -577,6 +725,11 @@ SUPPORT * MESH::getBoundaryElements(medEntityMesh Entity) else throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not defined in 2D mesh for entity "<<Entity<<" !")); + // assure that descending connectivity is full + if ( !_connectivity ) + throw MEDEXCEPTION("MESH::getgetBoundaryElements() : no connectivity defined in MESH !"); + _connectivity->calculateFullDescendingConnectivity(MED_CELL); + const int * myConnectivityValue = getReverseConnectivity(MED_DESCENDING) ; const int * myConnectivityIndex = getReverseConnectivityIndex(MED_DESCENDING) ; int numberOf = getNumberOfElementsWithPoly(entityToParse,MED_ALL_ELEMENTS) ; @@ -586,12 +739,46 @@ SUPPORT * MESH::getBoundaryElements(medEntityMesh Entity) if (myConnectivityValue[myConnectivityIndex[i]] == 0) { myElementsList.push_back(i+1); } + if ( myElementsList.empty() && numberOf != 0 ) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No boundary elements found by reverse descending connectivity for entity "<<Entity<<" !")); if(Entity==MED_NODE) return buildSupportOnNodeFromElementList(myElementsList,entityToParse); else return buildSupportOnElementsFromElementList(myElementsList,entityToParse); } +/*! +@} +*/ + +/*! + Method return a reference on a support define on all the element of an entity. +*/ + +SUPPORT * MESH::getSupportOnAll(medEntityMesh entity) + throw(MEDEXCEPTION) +{ + const char * LOC = "MESH::getSupportOnAll : " ; + BEGIN_OF_MED(LOC) ; + if(entity == MED_ALL_ENTITIES) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support not defined on entity MED_ALL_ENTITIES !")); + + map<medEntityMesh,SUPPORT*>::const_iterator it = _entitySupport.find(entity); + + // find support and return is if exists + if(it != _entitySupport.end()) + return (*it).second; + else{ + + //build, store and return support + string aSuppName = "SupportOnAll_"+entNames[entity]; + SUPPORT * aSupport = new SUPPORT((MESH *)this,aSuppName,entity); + + _entitySupport.insert(make_pair(entity,aSupport)); + return aSupport; + } +} + /*! Method that do the same thing as buildSupportOnNodeFromElementList except that a SUPPORT is not created. @@ -604,17 +791,22 @@ void MESH::fillSupportOnNodeFromElementList(const list<int>& listOfElt, SUPPORT int i; set<int> nodes; - for(list<int>::const_iterator iter=listOfElt.begin();iter!=listOfElt.end();iter++) + if ( entity == MED_NODE ) { + supportToFill->fillFromNodeList(listOfElt); + } + else { + for(list<int>::const_iterator iter=listOfElt.begin();iter!=listOfElt.end();iter++) { int lgth; const int *conn=_connectivity->getConnectivityOfAnElementWithPoly(MED_NODAL,entity,*iter,lgth); for(i=0;i<lgth;i++) nodes.insert(conn[i]); } - list<int> nodesList; - for(set<int>::iterator iter2=nodes.begin();iter2!=nodes.end();iter2++) - nodesList.push_back(*iter2); - supportToFill->fillFromNodeList(nodesList); + list<int> nodesList; + for(set<int>::iterator iter2=nodes.begin();iter2!=nodes.end();iter2++) + nodesList.push_back(*iter2); + supportToFill->fillFromNodeList(nodesList); + } } /*! @@ -634,18 +826,25 @@ SUPPORT *MESH::buildSupportOnNodeFromElementList(const list<int>& listOfElt,MED_ */ SUPPORT *MESH::buildSupportOnElementsFromElementList(const list<int>& listOfElt, MED_EN::medEntityMesh entity) const throw (MEDEXCEPTION) { - const char * LOC = "MESH::buildSupportOnElementsFromElementList : " ; - BEGIN_OF(LOC); + const char* LOC = "MESH::buildSupportOnElementsFromElementList : "; + BEGIN_OF_MED(LOC); SUPPORT *mySupport=new SUPPORT((MESH *)this,"Boundary",entity); mySupport->fillFromElementList(listOfElt); - END_OF(LOC) ; + END_OF_MED(LOC); return mySupport ; } +/*! +\addtogroup MESH_advanced +@{ +*/ +/*! Retrieves the volume of all the elements contained in \a Support. This method returns +a FIELD structure based on this support. It only works on MED_CELL for 3D meshes. +*/ FIELD<double, FullInterlace>* MESH::getVolume(const SUPPORT *Support) const throw (MEDEXCEPTION) { const char * LOC = "MESH::getVolume(SUPPORT*) : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // Support must be on 3D elements @@ -731,7 +930,7 @@ FIELD<double, FullInterlace>* MESH::getVolume(const SUPPORT *Support) const thro int N2 = global_connectivity[tetra_index+1]-1; int N3 = global_connectivity[tetra_index+2]-1; int N4 = global_connectivity[tetra_index+3]-1; - xvolume=CalculateVolumeForTetra(coord+dim_space*N1,coord+dim_space*N2,coord+dim_space*N3,coord+dim_space*N4); + xvolume=INTERP_KERNEL::calculateVolumeForTetra(coord+dim_space*N1,coord+dim_space*N2,coord+dim_space*N3,coord+dim_space*N4); volume->setIJ(index,1,xvolume) ; index++; } @@ -747,7 +946,7 @@ FIELD<double, FullInterlace>* MESH::getVolume(const SUPPORT *Support) const thro int N3 = global_connectivity[pyra_index+2]-1; int N4 = global_connectivity[pyra_index+3]-1; int N5 = global_connectivity[pyra_index+4]-1; - xvolume=CalculateVolumeForPyra(coord+dim_space*N1,coord+dim_space*N2,coord+dim_space*N3,coord+dim_space*N4,coord+dim_space*N5); + xvolume=INTERP_KERNEL::calculateVolumeForPyra(coord+dim_space*N1,coord+dim_space*N2,coord+dim_space*N3,coord+dim_space*N4,coord+dim_space*N5); volume->setIJ(index,1,xvolume) ; index++; } @@ -764,7 +963,7 @@ FIELD<double, FullInterlace>* MESH::getVolume(const SUPPORT *Support) const thro int N4 = global_connectivity[penta_index+3]-1; int N5 = global_connectivity[penta_index+4]-1; int N6 = global_connectivity[penta_index+5]-1; - xvolume=CalculateVolumeForPenta(coord+dim_space*N1,coord+dim_space*N2,coord+dim_space*N3,coord+dim_space*N4,coord+dim_space*N5,coord+dim_space*N6); + xvolume=INTERP_KERNEL::calculateVolumeForPenta(coord+dim_space*N1,coord+dim_space*N2,coord+dim_space*N3,coord+dim_space*N4,coord+dim_space*N5,coord+dim_space*N6); volume->setIJ(index,1,xvolume) ; index++; } @@ -784,7 +983,7 @@ FIELD<double, FullInterlace>* MESH::getVolume(const SUPPORT *Support) const thro int N6 = global_connectivity[hexa_index+5]-1; int N7 = global_connectivity[hexa_index+6]-1; int N8 = global_connectivity[hexa_index+7]-1; - xvolume=CalculateVolumeForHexa(coord+dim_space*N1,coord+dim_space*N2,coord+dim_space*N3,coord+dim_space*N4,coord+dim_space*N5,coord+dim_space*N6,coord+dim_space*N7,coord+dim_space*N8); + xvolume=INTERP_KERNEL::calculateVolumeForHexa(coord+dim_space*N1,coord+dim_space*N2,coord+dim_space*N3,coord+dim_space*N4,coord+dim_space*N5,coord+dim_space*N6,coord+dim_space*N7,coord+dim_space*N8); volume->setIJ(index,1,xvolume) ; index++; } @@ -813,10 +1012,10 @@ FIELD<double, FullInterlace>* MESH::getVolume(const SUPPORT *Support) const thro pts1[iFaces][iPtsInFace]=(double *)(coord+3*(nodes1[iFaces][iPtsInFace]-1)); } delete [] nodes1; - CalculateBarycenterDyn((const double **)pts,lgthNodes,3,bary); + INTERP_KERNEL::calculateBarycenterDyn((const double **)pts,lgthNodes,3,bary); delete [] nodes; delete [] pts; - xvolume=CalculateVolumeForPolyh((const double ***)pts1,nbOfNodesPerFaces,nbOfFaces,bary); + xvolume=INTERP_KERNEL::calculateVolumeForPolyh((const double ***)pts1,nbOfNodesPerFaces,nbOfFaces,bary); delete [] nbOfNodesPerFaces; for(iFaces=0;iFaces<nbOfFaces;iFaces++) delete [] pts1[iFaces]; @@ -845,10 +1044,10 @@ FIELD<double, FullInterlace>* MESH::getVolume(const SUPPORT *Support) const thro pts1[iFaces][iPtsInFace]=(double *)(coord+3*(nodes1[iFaces][iPtsInFace]-1)); } delete [] nodes1; - CalculateBarycenterDyn((const double **)pts,lgthNodes,3,bary); + INTERP_KERNEL::calculateBarycenterDyn((const double **)pts,lgthNodes,3,bary); delete [] nodes; delete [] pts; - xvolume=CalculateVolumeForPolyh((const double ***)pts1,nbOfNodesPerFaces,nbOfFaces,bary); + xvolume=INTERP_KERNEL::calculateVolumeForPolyh((const double ***)pts1,nbOfNodesPerFaces,nbOfFaces,bary); delete [] nbOfNodesPerFaces; for(iFaces=0;iFaces<nbOfFaces;iFaces++) delete [] pts1[iFaces]; @@ -870,11 +1069,15 @@ FIELD<double, FullInterlace>* MESH::getVolume(const SUPPORT *Support) const thro return Volume; } +/*! Retrieves the area of all the elements contained in \a Support. This method returns +a FIELD structure based on this support. It only works on MED_CELL for 2D meshes or MED_FACE +for 3D meshes. +*/ FIELD<double, FullInterlace>* MESH::getArea(const SUPPORT * Support) const throw (MEDEXCEPTION) { const char * LOC = "MESH::getArea(SUPPORT*) : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // Support must be on 2D elements @@ -927,9 +1130,10 @@ FIELD<double, FullInterlace>* MESH::getArea(const SUPPORT * Support) const throw { medGeometryElement type = types[i] ; nb_entity_type = Support->getNumberOfElements(type); - const int *global_connectivityIndex = getConnectivityIndex(MED_NODAL,support_entity); + const int *global_connectivityIndex = 0; if(type != MED_EN::MED_POLYGON && type != MED_EN::MED_POLYHEDRA) { + global_connectivityIndex = getConnectivityIndex(MED_NODAL,support_entity); if (onAll) { global_connectivity = getConnectivity(MED_FULL_INTERLACE,MED_NODAL,support_entity,type); @@ -960,7 +1164,7 @@ FIELD<double, FullInterlace>* MESH::getArea(const SUPPORT * Support) const throw int N2 = global_connectivity[tria_index+1]-1; int N3 = global_connectivity[tria_index+2]-1; - area[index]=CalculateAreaForTria(coord+(dim_space*N1), + area[index]=INTERP_KERNEL::calculateAreaForTria(coord+(dim_space*N1), coord+(dim_space*N2), coord+(dim_space*N3),dim_space); index++; @@ -978,7 +1182,7 @@ FIELD<double, FullInterlace>* MESH::getArea(const SUPPORT * Support) const throw int N3 = global_connectivity[quad_index+2]-1; int N4 = global_connectivity[quad_index+3]-1; - area[index]=CalculateAreaForQuad(coord+dim_space*N1, + area[index]=INTERP_KERNEL::calculateAreaForQuad(coord+dim_space*N1, coord+dim_space*N2, coord+dim_space*N3, coord+dim_space*N4,dim_space); @@ -998,7 +1202,7 @@ FIELD<double, FullInterlace>* MESH::getArea(const SUPPORT * Support) const throw double **pts=new double * [size]; for(int iPts=0;iPts<size;iPts++) pts[iPts]=(double *)(coord+dim_space*(connectivity[connectivity_index[polygs]+iPts-1]-1)); - area[index] = CalculateAreaForPolyg((const double **)pts,size,dim_space); + area[index] = INTERP_KERNEL::calculateAreaForPolyg((const double **)pts,size,dim_space); delete [] pts; index++; } @@ -1015,7 +1219,7 @@ FIELD<double, FullInterlace>* MESH::getArea(const SUPPORT * Support) const throw double **pts=new double * [size]; for(int iPts=0;iPts<size;iPts++) pts[iPts]=(double *)(coord+dim_space*(connectivity[connectivity_index[supp_number[polygs]-offsetWithClassicType-1]+iPts-1]-1)); - area[index]=CalculateAreaForPolyg((const double **)pts,size,dim_space); + area[index]=INTERP_KERNEL::calculateAreaForPolyg((const double **)pts,size,dim_space); delete [] pts; index++; } @@ -1033,11 +1237,13 @@ FIELD<double, FullInterlace>* MESH::getArea(const SUPPORT * Support) const throw } return Area; } - +/*! Retrieves the length of all the elements contained in \a Support. This method returns +a FIELD structure based on this support. It only works on MED_EDGE supports. +*/ FIELD<double, FullInterlace>* MESH::getLength(const SUPPORT * Support) const throw (MEDEXCEPTION) { const char * LOC = "MESH::getLength(SUPPORT*) : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // Support must be on 1D elements @@ -1139,10 +1345,17 @@ FIELD<double, FullInterlace>* MESH::getLength(const SUPPORT * Support) const thr return Length; } +/*! Retrieves the normal for all elements contained in SUPPORT \a Support. +The method is only functional for 2D supports for 3D meshes and 1D supports +for 2D meshes. It returns +a FIELD for which the number of components is equal to the dimension of the +mesh and which represents coordinates of the vector normal to the element. +The direction of the vector is undetermined. +*/ FIELD<double, FullInterlace>* MESH::getNormal(const SUPPORT * Support) const throw (MEDEXCEPTION) { const char * LOC = "MESH::getNormal(SUPPORT*) : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // Support must be on 2D or 1D elements @@ -1236,7 +1449,7 @@ FIELD<double, FullInterlace>* MESH::getNormal(const SUPPORT * Support) const thr int N1 = global_connectivity[tria_index]-1; int N2 = global_connectivity[tria_index+1]-1; int N3 = global_connectivity[tria_index+2]-1; - CalculateNormalForTria(coord+dim_space*N1,coord+dim_space*N2,coord+dim_space*N3,normal+3*index); + INTERP_KERNEL::calculateNormalForTria(coord+dim_space*N1,coord+dim_space*N2,coord+dim_space*N3,normal+3*index); index++; } break; @@ -1250,7 +1463,7 @@ FIELD<double, FullInterlace>* MESH::getNormal(const SUPPORT * Support) const thr int N2 = global_connectivity[quad_index+1]-1; int N3 = global_connectivity[quad_index+2]-1; int N4 = global_connectivity[quad_index+3]-1; - CalculateNormalForQuad(coord+dim_space*N1,coord+dim_space*N2,coord+dim_space*N3,coord+dim_space*N4,normal+3*index); + INTERP_KERNEL::calculateNormalForQuad(coord+dim_space*N1,coord+dim_space*N2,coord+dim_space*N3,coord+dim_space*N4,normal+3*index); index++; } break; @@ -1293,7 +1506,7 @@ FIELD<double, FullInterlace>* MESH::getNormal(const SUPPORT * Support) const thr double **pts=new double * [size]; for(int iPts=0;iPts<size;iPts++) pts[iPts]=(double *)(coord+dim_space*(connectivity[connectivity_index[polygs]+iPts-1])-1); - CalculateNormalForPolyg((const double **)pts,size,normal+3*index); + INTERP_KERNEL::calculateNormalForPolyg((const double **)pts,size,normal+3*index); delete [] pts; index++; } @@ -1311,7 +1524,7 @@ FIELD<double, FullInterlace>* MESH::getNormal(const SUPPORT * Support) const thr double **pts=new double * [size]; for(int iPts=0;iPts<size;iPts++) pts[iPts]=(double *)(coord+dim_space*(connectivity[connectivity_index[localPolygsNbP1-1]+iPts-1])-1); - CalculateNormalForPolyg((const double **)pts,size,normal+3*index); + INTERP_KERNEL::calculateNormalForPolyg((const double **)pts,size,normal+3*index); delete [] pts; index++; } @@ -1325,11 +1538,14 @@ FIELD<double, FullInterlace>* MESH::getNormal(const SUPPORT * Support) const thr if (!onAll && type!=MED_EN::MED_POLYGON) delete [] global_connectivity ; } - END_OF(LOC); + END_OF_MED(LOC); return Normal; } - +/*!Returns the barycenter for each element in the support. The barycenter positions are returned +as a field with a number of components equal to the mesh dimension. +The barycenter computed by this method is actually the barycenter of the set of nodes of the elements, each having the same weight. +*/ FIELD<double, FullInterlace>* MESH::getBarycenter(const SUPPORT * Support) const throw (MEDEXCEPTION) { const char * LOC = "MESH::getBarycenter(SUPPORT*) : "; @@ -1410,7 +1626,7 @@ FIELD<double, FullInterlace>* MESH::getBarycenter(const SUPPORT * Support) const pts[1]=(double *)coord+dim_space*N2; pts[2]=(double *)coord+dim_space*N3; pts[3]=(double *)coord+dim_space*N4; - CalculateBarycenter<4,3>((const double **)pts,barycenter+3*index); + INTERP_KERNEL::calculateBarycenter<4,3>((const double **)pts,barycenter+3*index); index++; } break; @@ -1432,7 +1648,7 @@ FIELD<double, FullInterlace>* MESH::getBarycenter(const SUPPORT * Support) const pts[2]=(double *)coord+dim_space*N3; pts[3]=(double *)coord+dim_space*N4; pts[4]=(double *)coord+dim_space*N5; - CalculateBarycenter<5,3>((const double **)pts,barycenter+3*index); + INTERP_KERNEL::calculateBarycenter<5,3>((const double **)pts,barycenter+3*index); index++; } break; @@ -1456,7 +1672,7 @@ FIELD<double, FullInterlace>* MESH::getBarycenter(const SUPPORT * Support) const pts[3]=(double *)coord+dim_space*N4; pts[4]=(double *)coord+dim_space*N5; pts[5]=(double *)coord+dim_space*N6; - CalculateBarycenter<6,3>((const double **)pts,barycenter+3*index); + INTERP_KERNEL::calculateBarycenter<6,3>((const double **)pts,barycenter+3*index); index++; } break; @@ -1484,7 +1700,7 @@ FIELD<double, FullInterlace>* MESH::getBarycenter(const SUPPORT * Support) const pts[5]=(double *)coord+dim_space*N6; pts[6]=(double *)coord+dim_space*N7; pts[7]=(double *)coord+dim_space*N8; - CalculateBarycenter<8,3>((const double **)pts,barycenter+3*index); + INTERP_KERNEL::calculateBarycenter<8,3>((const double **)pts,barycenter+3*index); index++; } break; @@ -1502,9 +1718,9 @@ FIELD<double, FullInterlace>* MESH::getBarycenter(const SUPPORT * Support) const pts[1]=(double *)coord+dim_space*N2; pts[2]=(double *)coord+dim_space*N3; if (dim_space==2) - CalculateBarycenter<3,2>((const double **)pts,barycenter+2*index); + INTERP_KERNEL::calculateBarycenter<3,2>((const double **)pts,barycenter+2*index); else - CalculateBarycenter<3,3>((const double **)pts,barycenter+3*index); + INTERP_KERNEL::calculateBarycenter<3,3>((const double **)pts,barycenter+3*index); index++; } break; @@ -1524,9 +1740,9 @@ FIELD<double, FullInterlace>* MESH::getBarycenter(const SUPPORT * Support) const pts[2]=(double *)coord+dim_space*N3; pts[3]=(double *)coord+dim_space*N4; if (dim_space==2) - CalculateBarycenter<4,2>((const double **)pts,barycenter+2*index); + INTERP_KERNEL::calculateBarycenter<4,2>((const double **)pts,barycenter+2*index); else - CalculateBarycenter<4,3>((const double **)pts,barycenter+3*index); + INTERP_KERNEL::calculateBarycenter<4,3>((const double **)pts,barycenter+3*index); index++; } break; @@ -1542,9 +1758,9 @@ FIELD<double, FullInterlace>* MESH::getBarycenter(const SUPPORT * Support) const pts[0]=(double *)coord+dim_space*N1; pts[1]=(double *)coord+dim_space*N2; if (dim_space==2) - CalculateBarycenter<2,2>((const double **)pts,barycenter+2*index); + INTERP_KERNEL::calculateBarycenter<2,2>((const double **)pts,barycenter+2*index); else - CalculateBarycenter<2,3>((const double **)pts,barycenter+3*index); + INTERP_KERNEL::calculateBarycenter<2,3>((const double **)pts,barycenter+3*index); index++; } break; @@ -1561,7 +1777,7 @@ FIELD<double, FullInterlace>* MESH::getBarycenter(const SUPPORT * Support) const double **pts=new double * [size]; for(int iPts=0;iPts<size;iPts++) pts[iPts]=(double *)coord+dim_space*(connectivity[connectivity_index[polygs]+iPts-1]-1); - CalculateBarycenterDyn((const double **)pts,size,dim_space,barycenter+dim_space*index); + INTERP_KERNEL::calculateBarycenterDyn((const double **)pts,size,dim_space,barycenter+dim_space*index); delete [] pts; } } @@ -1578,7 +1794,7 @@ FIELD<double, FullInterlace>* MESH::getBarycenter(const SUPPORT * Support) const double **pts=new double * [size]; for(int iPts=0;iPts<size;iPts++) pts[iPts]=(double *)coord+dim_space*(connectivity[connectivity_index[localPolygsNbP1-1]+iPts-1]-1); - CalculateBarycenterDyn((const double **)pts,size,dim_space,barycenter+dim_space*index); + INTERP_KERNEL::calculateBarycenterDyn((const double **)pts,size,dim_space,barycenter+dim_space*index); delete [] pts; } } @@ -1597,7 +1813,7 @@ FIELD<double, FullInterlace>* MESH::getBarycenter(const SUPPORT * Support) const double **pts=new double * [lgthNodes]; for(int iPts=0;iPts<lgthNodes;iPts++) pts[iPts]=(double *)coord+3*(nodes[iPts]-1); - CalculateBarycenterDyn((const double **)pts,lgthNodes,3,barycenter+3*index); + INTERP_KERNEL::calculateBarycenterDyn((const double **)pts,lgthNodes,3,barycenter+3*index); delete [] pts; delete [] nodes; index++; @@ -1613,7 +1829,7 @@ FIELD<double, FullInterlace>* MESH::getBarycenter(const SUPPORT * Support) const double **pts=new double * [lgthNodes]; for(int iPts=0;iPts<lgthNodes;iPts++) pts[iPts]=(double *)coord+3*(nodes[iPts]-1); - CalculateBarycenterDyn((const double **)pts,lgthNodes,3,barycenter+3*index); + INTERP_KERNEL::calculateBarycenterDyn((const double **)pts,lgthNodes,3,barycenter+3*index); delete [] pts; delete [] nodes; index++; @@ -1630,9 +1846,12 @@ FIELD<double, FullInterlace>* MESH::getBarycenter(const SUPPORT * Support) const if(type != MED_EN::MED_POLYGON && type != MED_EN::MED_POLYHEDRA) delete [] global_connectivity; } - END_OF(LOC); + //END_OF_MED(); return Barycenter; } +/*! +@} +*/ bool MESH::isEmpty() const { @@ -1649,7 +1868,7 @@ bool MESH::isEmpty() const void MESH::read(int index) { const char * LOC = "MESH::read(int index=0) : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_drivers[index]) { _drivers[index]->open(); @@ -1662,14 +1881,28 @@ void MESH::read(int index) << _drivers.size() ) ); - END_OF(LOC); + END_OF_MED(LOC); } -/*! Write all the content of the MESH using driver referenced by the integer handler index.*/ +/*! +\addtogroup MESH_io +@{ + */ +/*! Writes all the content of the MESH using driver referenced by the integer handle returned by a \a addDriver call. + +Example : +\verbatim +//... +// Attaching the driver to file "output.med", meshname "Mesh" +int driver_handle = mesh.addDriver(MED_DRIVER, "output.med", "Mesh"); +// Writing the content of mesh to the file +mesh.write(driver_handle); +\endverbatim +*/ void MESH::write(int index/*=0*/, const string & driverName/* = ""*/) { const char * LOC = "MESH::write(int index=0, const string & driverName = \"\") : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if ( _drivers[index] ) { _drivers[index]->open(); @@ -1683,45 +1916,61 @@ void MESH::write(int index/*=0*/, const string & driverName/* = ""*/) << _drivers.size() ) ); - END_OF(LOC); + END_OF_MED(LOC); } +/*! +@} +*/ -//======================================================================= -//function : getSkin -//purpose : -//======================================================================= +/*! +\addtogroup MESH_advanced +@{ + */ + +/*! +Retrieves the skin of support \a Support3D. This method is only available in 3D. +On output, it returns a MED_FACE support with the skin of all elements contained in support. +The skin is defined as the list of faces that are compnents of only one volume in the input +support. +WARNING: This method can recalculate descending connectivity from partial to full form, +so that partial SUPPORT on MED_FACE on this mesh becomes invalid. + */ SUPPORT * MESH::getSkin(const SUPPORT * Support3D) throw (MEDEXCEPTION) { const char * LOC = "MESH::getSkin : " ; - BEGIN_OF(LOC) ; + BEGIN_OF_MED(LOC) ; // some test : if (this != Support3D->getMesh()) throw MEDEXCEPTION(STRING(LOC) << "no compatibility between *this and SUPPORT::_mesh !"); if (_meshDimension != 3 || Support3D->getEntity() != MED_CELL) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Defined on 3D cells only")); + throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Defined on 3D cells only")); // well, all rigth ! SUPPORT * mySupport = new SUPPORT(this,"Skin",MED_FACE); mySupport->setAll(false); - list<int> myElementsList ; - int i,j, size = 0 ; + list<int> myElementsList; + int i,j, size = 0; - calculateConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, MED_CELL); + // assure that descending connectivity is full + if ( !_connectivity ) + throw MEDEXCEPTION(STRING(LOC) << "no connectivity defined in MESH !"); + _connectivity->calculateFullDescendingConnectivity(MED_CELL); + //calculateConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, MED_CELL); if (Support3D->isOnAllElements()) { - int * myConnectivityValue = const_cast <int*> (getReverseConnectivity(MED_DESCENDING)) ; + const int* value = getReverseConnectivity(MED_DESCENDING); + const int* index = getReverseConnectivityIndex(MED_DESCENDING); + int nbFaces = getNumberOfElements(MED_FACE,MED_ALL_ELEMENTS); - for (i=0, j=1 ; j<=nbFaces; ++j, i += 2) + for (int i = 0; i < nbFaces; i++) { - int cellNb1 = myConnectivityValue [i]; - int cellNb2 = myConnectivityValue [i+1]; - //MESSAGE( " FACE # " << j << " -- Cells: " << cellNb1 << ", " << cellNb2 ); - if ((cellNb1 == 0 || cellNb2 == 0) && (cellNb1 + cellNb2 > 0)) - { - myElementsList.push_back( j ) ; - size++ ; + //a face is in skin if it is linked to one element or if one of the elements + //it is linked to is "virtual" + if ((index[i+1]-index[i]==1) || (value[index[i]-1]==0) || (value[index[i]]==0)) { + myElementsList.push_back( i+1 ); + size++; } } } @@ -1743,7 +1992,7 @@ SUPPORT * MESH::getSkin(const SUPPORT * Support3D) throw (MEDEXCEPTION) for (j = faceFirst; j < faceLast; ++j) { int faceNb = abs( myConnectivityValue [ j-1 ] ); - //MESSAGE( "Cell # " << i << " -- Face: " << faceNb); + //MESSAGE_MED( "Cell # " << i << " -- Face: " << faceNb); if (FaceNbEncounterNb.find( faceNb ) == FaceNbEncounterNb.end()) FaceNbEncounterNb[ faceNb ] = 1; else @@ -1823,7 +2072,7 @@ SUPPORT * MESH::getSkin(const SUPPORT * Support3D) throw (MEDEXCEPTION) mySupport->setGeometricType(geometricType) ; // mySupport->setGeometricTypeNumber(geometricTypeNumber) ; mySupport->setNumberOfElements(numberOfEntities) ; - mySupport->setTotalNumberOfElements(size) ; + //mySupport->setTotalNumberOfElements(size) ; mySupport->setNumber(mySkyLineArray) ; delete[] numberOfEntities; @@ -1833,7 +2082,7 @@ SUPPORT * MESH::getSkin(const SUPPORT * Support3D) throw (MEDEXCEPTION) delete[] myListArray; // delete mySkyLineArray; - END_OF(LOC) ; + END_OF_MED(LOC); return mySupport ; } @@ -1845,7 +2094,7 @@ SUPPORT * MESH::getSkin(const SUPPORT * Support3D) throw (MEDEXCEPTION) SUPPORT * MESH::mergeSupports(const vector<SUPPORT *> Supports) throw (MEDEXCEPTION) { const char * LOC = "MESH:::mergeSupports(const vector<SUPPORT *> ) : " ; - BEGIN_OF(LOC) ; + BEGIN_OF_MED(LOC) ; SUPPORT * returnedSupport; string returnedSupportName; @@ -1854,9 +2103,13 @@ SUPPORT * MESH::mergeSupports(const vector<SUPPORT *> Supports) throw (MEDEXCEPT char * returnedSupportDescriptionChar; int size = Supports.size(); + if (size == 0) + throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << + " mergeSupports() does't accept zero size vector")); + if (size == 1) { - MESSAGE(LOC <<" there is only one SUPPORT in the argument list, the method return a copy of this object !"); + MESSAGE_MED(LOC <<" there is only one SUPPORT in the argument list, the method return a copy of this object !"); SUPPORT * obj = const_cast <SUPPORT *> (Supports[0]); returnedSupport = new SUPPORT(*obj); @@ -1953,7 +2206,7 @@ SUPPORT * MESH::mergeSupports(const vector<SUPPORT *> Supports) throw (MEDEXCEPT delete [] returnedSupportDescriptionChar; } - END_OF(LOC) ; + END_OF_MED(LOC); return returnedSupport; } @@ -1964,8 +2217,8 @@ SUPPORT * MESH::mergeSupports(const vector<SUPPORT *> Supports) throw (MEDEXCEPT */ SUPPORT * MESH::intersectSupports(const vector<SUPPORT *> Supports) throw (MEDEXCEPTION) { - const char * LOC = "MESH:::intersectSupports(const vector<SUPPORT *> ) : " ; - BEGIN_OF(LOC) ; + const char* LOC = "MESH:::intersectSupports(const vector<SUPPORT *> ) : "; + BEGIN_OF_MED(LOC); SUPPORT * returnedSupport; string returnedSupportName; @@ -1976,7 +2229,7 @@ SUPPORT * MESH::intersectSupports(const vector<SUPPORT *> Supports) throw (MEDEX if (size == 1) { - MESSAGE(LOC <<" there is only one SUPPORT in the argument list, the method return a copy of this object !"); + MESSAGE_MED(PREFIX_MED <<" there is only one SUPPORT in the argument list, the method return a copy of this object !"); SUPPORT * obj = const_cast <SUPPORT *> (Supports[0]); returnedSupport = new SUPPORT(*obj); @@ -2087,10 +2340,12 @@ SUPPORT * MESH::intersectSupports(const vector<SUPPORT *> Supports) throw (MEDEX } } - END_OF(LOC) ; + END_OF_MED(LOC); return returnedSupport; } - +/*! +@} +*/ // internal helper type struct _cell @@ -2099,12 +2354,97 @@ struct _cell MED_EN::medGeometryElement geometricType; }; +/*!\addtogroup MESH_families +@{ +*/ + +/*! Retrieves the group named \a name. +The method browses all the entities in order to find the group. +If two groups with the same name coexist, the first one found will be +returned. If no group with the correct name is found, the method throws +an exception. + */ +const GROUP* MESH::getGroup(const string& name) const throw (MEDEXCEPTION) +{ + const vector<GROUP*>* group_vectors [4]={&_groupNode, &_groupEdge,&_groupFace,&_groupCell}; + for (int ientity=0;ientity<4;ientity++) + for (int igroup=0; igroup< group_vectors[ientity]->size();igroup++) + { + const vector<GROUP*>& group_vect = *group_vectors[ientity]; + GROUP* group=group_vect[igroup]; + if (group->getName()==name) + return group; + } + cerr << "MESH::getGroup("<<name<<") : group "<<name <<" was not found"<<endl; + throw MEDEXCEPTION("MESH::getGroup(name) : name not found"); +} +/*! +@} +*/ + +const GROUP* MESH::getGroup(MED_EN::medEntityMesh entity, int i) const +{ + const char * LOC = "MESH::getGroup(medEntityMesh entity, int i) : "; + if (i<=0) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"argument i must be > 0")); + vector<GROUP*> Group; + switch (entity) { + case MED_EN::MED_NODE : { + Group = _groupNode; + break; + } + case MED_EN::MED_CELL : { + Group = _groupCell; + break; + } + case MED_EN::MED_FACE : { + Group = _groupFace; + break; + } + case MED_EN::MED_EDGE : { + Group = _groupEdge; + break; + } + default : + throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Unknown entity")); + } + if (i>(int)Group.size()) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"argument i="<<i<<" must be <= _numberOfGroups="<<Group.size())); + return Group[i-1]; +} + + +/*! +\addtogroup MESH_families +@{ +*/ +/*! Returns the groups of type \a entity present in the mesh as a vector of pointers. The GROUP class inheriting from the SUPPORT class, the +methods that can be used on these groups are explained in the related section.*/ +const vector<GROUP*> MESH::getGroups(MED_EN::medEntityMesh entity) const +{ + switch (entity) { + case MED_EN::MED_NODE : + return _groupNode; + case MED_EN::MED_CELL : + return _groupCell; + case MED_EN::MED_FACE : + return _groupFace; + case MED_EN::MED_EDGE : + return _groupEdge; + default : + throw MEDEXCEPTION("MESH::getGroups : Unknown entity"); + } +} +/*! +@} +*/ + /*! -Create groups from families. + Create groups from families. -It is used to create groups that have only one family -for meshes that come from codes that use families instead -of groups to define a subregion. + It is used to create groups that have only one family + for meshes that come from codes that use families instead + of groups to define a subregion. */ void MESH::createGroups() { @@ -2114,37 +2454,36 @@ void MESH::createGroups() vector<FAMILY*>* myFamilies; vector<GROUP*>* myGroups; switch ( entity ) - { - case MED_CELL : - myFamilies = & _familyCell; - myGroups = & _groupCell; - break; - case MED_FACE : - myFamilies = & _familyFace; - myGroups = & _groupFace; - break; - case MED_EDGE : - myFamilies = & _familyEdge; - myGroups = & _groupEdge; - break; - case MED_NODE : - myFamilies = & _familyNode; - myGroups = & _groupNode; - break; - } + { + case MED_CELL : + myFamilies = & _familyCell; + myGroups = & _groupCell; + break; + case MED_FACE : + myFamilies = & _familyFace; + myGroups = & _groupFace; + break; + case MED_EDGE : + myFamilies = & _familyEdge; + myGroups = & _groupEdge; + break; + case MED_NODE : + myFamilies = & _familyNode; + myGroups = & _groupNode; + break; + } - for (int i=0; i< myFamilies->size(); i++) - { - list <FAMILY*> fam_list; - fam_list.push_back((*myFamilies)[i]); - //creates a group with the family name and only one family - GROUP* group=new GROUP((*myFamilies)[i]->getName(),fam_list); - (*myGroups).push_back(group); - } + for (int i=0; i< myFamilies->size(); i++) + { + list <FAMILY*> fam_list; + fam_list.push_back((*myFamilies)[i]); + //creates a group with the family name and only one family + GROUP* group=new GROUP((*myFamilies)[i]->getName(),fam_list); + (*myGroups).push_back(group); + } } } - // Create families from groups void MESH::createFamilies() { @@ -2187,17 +2526,19 @@ void MESH::createFamilies() // 1 - Create a vector containing for each cell (of the entity) an information structure // giving geometric type and the groups it belong to - med_int numberOfTypes=getNumberOfTypes(entity); - const int * index=getGlobalNumberingIndex(entity); - const medGeometryElement* geometricTypes=_connectivity->getGeometricTypes(entity); // pb avec entity=MED_NODE??? - med_int numberOfCells=index[numberOfTypes]-1; // total number of cells for that entity - SCRUTE(numberOfTypes); - SCRUTE(numberOfCells); + med_int numberOfTypes=getNumberOfTypesWithPoly(entity); + medGeometryElement* geometricTypes=_connectivity->getGeometricTypesWithPoly(entity); // pb avec entity=MED_NODE??? + med_int numberOfCells=getNumberOfElementsWithPoly(entity, MED_ALL_ELEMENTS); // total number of cells for that entity + SCRUTE_MED(numberOfTypes); + SCRUTE_MED(numberOfCells); vector< _cell > tab_cell(numberOfCells); - for(med_int t=0; t!=numberOfTypes; ++t) - for(int n=index[t]-1; n!=index[t+1]-1; ++n) - tab_cell[n].geometricType=geometricTypes[t]; - + vector< _cell >::iterator cell = tab_cell.begin(); + for(med_int t=0; t!=numberOfTypes; ++t) { + int nbCellsOfType = getNumberOfElementsWithPoly(entity,geometricTypes[t]); + for(int n=0; n!=nbCellsOfType; ++n, ++cell) + cell->geometricType=geometricTypes[t]; + } + delete [] geometricTypes; // 2 - Scan cells in groups and update in tab_cell the container of groups a cell belong to @@ -2272,9 +2613,11 @@ void MESH::createFamilies() famName = famName.substr(4); } else { // try to make a unique name by cutting off char by char from the tail - famName.substr(0, MED_TAILLE_NOM); + famName = famName.substr(0, MED_TAILLE_NOM); map< string,vector<int> >::iterator foundName = tab_families.find( famName ); - while ( foundName != tab_families.end() && !famName.empty() ) { + while ( !famName.empty() && + ( foundName != tab_families.end() || famName[ famName.size()-1 ] == ' ' )) + { famName = famName.substr( 0, famName.size() - 1 ); foundName = tab_families.find( famName ); } @@ -2284,7 +2627,7 @@ void MESH::createFamilies() // create an empty MED FAMILY and fill it with the tabs we constructed FAMILY* newFam = new FAMILY(); - newFam->setTotalNumberOfElements(fam->second.size()); + //newFam->setTotalNumberOfElements(fam->second.size()); newFam->setName(famName); newFam->setMeshDirectly(this); newFam->setNumberOfGeometricType(tab_types_geometriques.size()); @@ -2337,9 +2680,8 @@ void MESH::createFamilies() newFam->setGroupsNames(groupNames); } - int sizeOfFamVect = myFamilies->size(); - - MESSAGE(" MESH::createFamilies() entity " << entity << " size " << sizeOfFamVect); + MESSAGE_MED(" MESH::createFamilies() entity " << entity << + " size " << myFamilies->size()); myFamilies->push_back(newFam); } @@ -2384,6 +2726,177 @@ int MESH::getElementContainingPoint(const double *coord) throw MEDEXCEPTION("MESH::getElementContainingPoint : invalid _spaceDimension must be equal to 2 or 3 !!!"); } +//! Converts MED_CELL connectivity to polyhedra connectivity +//! Converts MED_FACE connectivity to polygon connectivity +//! Wil work only for 3D meshes with nodal connectivity + +void MESH::convertToPoly() +{ + if (getMeshDimension()!=3) return; + + CONNECTIVITY* newpolygonconnectivity = new CONNECTIVITY(MED_EN::MED_FACE); + CONNECTIVITY* newpolyhedraconnectivity = new CONNECTIVITY(MED_EN::MED_CELL); + + { + ////////////////////////////////////////////: + // First step : Treating polygons connectivity + /////////////////////////////////////////// + + const int* oldconn = getConnectivity(MED_EN::MED_FULL_INTERLACE,MED_EN::MED_NODAL, MED_EN::MED_FACE, MED_EN::MED_ALL_ELEMENTS); + + const int* oldconnindex= getConnectivityIndex(MED_EN::MED_NODAL,MED_EN::MED_FACE); + int oldnbface = getNumberOfElements(MED_EN::MED_FACE,MED_EN::MED_ALL_ELEMENTS); + const int* oldconnpoly =0; + const int* oldconnpolyindex =0; + if(existPolygonsConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE)) + { + oldconnpoly = getPolygonsConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE); + oldconnpolyindex = getPolygonsConnectivityIndex(MED_EN::MED_NODAL,MED_EN::MED_FACE); + } + int oldnbtotalface = getNumberOfElementsWithPoly(MED_EN::MED_FACE,MED_EN::MED_ALL_ELEMENTS); + + int nbnodes=0; + + if (oldconnindex !=0) + nbnodes += oldconnindex[oldnbface] -1 ; + + if (oldconnpolyindex !=0) + nbnodes+= oldconnpolyindex[oldnbtotalface-oldnbface]-1; + + int* newconn = new int[nbnodes]; + int* newconnindex= new int [oldnbtotalface+1]; + + //copying classical types connectivity + memcpy(newconn, oldconn, sizeof(int)*(oldconnindex[oldnbface]-1) ); + + //copying poly types connectivity + if(oldconnpoly) + memcpy (newconn+oldconnindex[oldnbface]-1, oldconnpoly, sizeof(int)*(oldconnpolyindex[oldnbtotalface-oldnbface]-1) ); + + newconnindex[0]=1; + for (int i=0; i<oldnbface;i++) + newconnindex[i+1]=newconnindex[i]+oldconnindex[i+1]-oldconnindex[i]; + for (int i=oldnbface; i<oldnbtotalface;i++) + newconnindex[i+1]=newconnindex[i]+ + oldconnpolyindex[i-oldnbface+1]-oldconnpolyindex[i-oldnbface]; + + + newpolygonconnectivity->setPolygonsConnectivity(MED_EN::MED_NODAL, + MED_EN::MED_FACE, + newconn, + newconnindex, + nbnodes, + oldnbtotalface); + // _connectivity->setConstituent(newconnectivity); + } + /////////////////////////////////////////// + // 2nd step : Treating polyhedra connectivity + ////////////////////////////////////////// + { + + const int* oldconn = getConnectivity(MED_EN::MED_FULL_INTERLACE,MED_EN::MED_NODAL, MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); + + const int* oldconnindex= getConnectivityIndex(MED_EN::MED_NODAL,MED_EN::MED_CELL); + int oldnbelem = getNumberOfElements(MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS); + const int* oldconnpoly = 0; + const int* oldconnpolyindex = 0; + const int* oldfaceindex = 0; + if(existPolyhedronConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL)) + { + oldconnpoly = getPolyhedronConnectivity(MED_EN::MED_NODAL); + oldconnpolyindex = getPolyhedronIndex(MED_EN::MED_NODAL); + oldfaceindex = getPolyhedronFacesIndex(); + } + const MED_EN::medGeometryElement* oldtypes = getTypes(MED_EN::MED_CELL); + int nboldtypes=getNumberOfTypes(MED_EN::MED_CELL); + int nboldpolyhedra=getNumberOfPolyhedron(); + int oldnbtotalelem = getNumberOfElementsWithPoly(MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS); + + int nbnodes=0; + + if (oldconnindex !=0) + nbnodes += oldconnindex[oldnbelem] -1 ; + + if (oldconnpolyindex !=0) + nbnodes+= oldconnpolyindex[oldnbtotalelem-oldnbelem]-1; + + //computing number of faces + int nbfaces=0; + // first part : number of faces for the classical types + for (int itype=0; itype<nboldtypes; itype++) + { + MED_EN::medGeometryElement type = oldtypes[itype]; + MEDMEM::CELLMODEL cellmodel(type); + int nb_elems=getNumberOfElements(MED_EN::MED_CELL,type); + int nbfacespertype = cellmodel.getNumberOfConstituents(1); + nbfaces+=nb_elems*nbfacespertype; + } + // second part : number of faces for the polyhedra + nbfaces += getNumberOfPolyhedronFaces(); + + //allocating tables for new connectivity + vector<int> newconn; + vector<int> newconnindex(1,1); + vector<int> newfaceindex(1,1); + + for (int itype=0; itype<nboldtypes; itype++) + { + MED_EN::medGeometryElement type = oldtypes[itype]; + MEDMEM::CELLMODEL cellmodel(type); + int nb_elems=getNumberOfElements(MED_EN::MED_CELL,type); + int nbfacespertype = cellmodel.getNumberOfConstituents(1); + for (int ielem = 0; ielem<nb_elems; ielem++) + { + for (int iface =0; iface< nbfacespertype; iface ++) + { + //local conn contains the local nodal connectivity for the iface-th face of type type + const int* local_conn = cellmodel.getNodesConstituent(1,iface+1); // iface+1 for MED numbering + MED_EN::medGeometryElement facetype = cellmodel.getConstituentType(1,iface+1); + int nbface_nodes=facetype%100; + for ( int inode=0; inode<nbface_nodes;inode++) + { + newconn.push_back(oldconn[oldconnindex[newconnindex.size()-1]-1+local_conn[inode]-1]); + } + newfaceindex.push_back(newfaceindex[newfaceindex.size()-1]+nbface_nodes); + } + newconnindex.push_back(newconnindex[newconnindex.size()-1]+nbfacespertype); + } + } + + for (int i=0; i<nboldpolyhedra; i++) + { + newconnindex.push_back(newconnindex[newconnindex.size()-1]+oldconnpolyindex[i+1]-oldconnpolyindex[i]); + } + if(oldconnpolyindex) + { + for (int i=0; i<oldconnpolyindex[nboldpolyhedra]-1;i++) + { + newfaceindex.push_back(newfaceindex[newfaceindex.size()-1]+oldfaceindex[i+1]-oldfaceindex[i]); + } + for (int i=0; i< oldfaceindex[oldconnpolyindex[nboldpolyhedra]-1]-1; i++) + newconn.push_back(oldconnpoly[i]); + } + // memcpy(newconn_ptr,oldconnpoly,sizeof(int)*(oldfaceindex[oldconnpoly[nboldpolyhedra]-1]-1)); + + + newpolyhedraconnectivity->setPolyhedronConnectivity(MED_EN::MED_NODAL, + &newconn[0], + &newconnindex[0], + newfaceindex[newfaceindex.size()-1]-1, + newconnindex.size()-1, + &newfaceindex[0], + newfaceindex.size()-1); + + newpolyhedraconnectivity->setEntityDimension(3); + + delete _connectivity; + + _connectivity=newpolyhedraconnectivity; + _connectivity->setConstituent(newpolygonconnectivity); + + } +} + vector< vector<double> > MESH::getBoundingBox() const { const double *myCoords=_coordinate->getCoordinates(MED_EN::MED_FULL_INTERLACE); diff --git a/src/MEDMEM/MEDMEM_Mesh.hxx b/src/MEDMEM/MEDMEM_Mesh.hxx index 69bbb70be..f91b42d2c 100644 --- a/src/MEDMEM/MEDMEM_Mesh.hxx +++ b/src/MEDMEM/MEDMEM_Mesh.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef MESH_HXX #define MESH_HXX @@ -37,6 +39,16 @@ #include "MEDMEM_RCBase.hxx" #include "MEDMEM_FieldForward.hxx" +namespace MEDMEM { + +class CELLMODEL; +class FAMILY; +class GROUP; +class SUPPORT; +class MESH; + +MEDMEM_EXPORT ostream & operator<<(ostream &os, const MESH &my); + /*! This class contains all the informations related with a MESH : - COORDINATES - CONNECTIVITIES @@ -50,16 +62,6 @@ */ -namespace MEDMEM { - -class CELLMODEL; -class FAMILY; -class GROUP; -class SUPPORT; -class MESH; - -ostream & operator<<(ostream &os, const MESH &my); - class MEDMEM_EXPORT MESH : public RCBASE { //-----------------------// @@ -108,6 +110,8 @@ protected : bool _isAGrid; // am I a GRID or not + map<MED_EN::medEntityMesh,SUPPORT*> _entitySupport; + //-----------------------// // Methods //-----------------------// @@ -154,13 +158,13 @@ public : MESH( driverTypes driverType, const string & fileName="", const string & meshName="") throw (MEDEXCEPTION); virtual ~MESH(); - friend MEDMEM_EXPORT ostream & operator<<(ostream &os, const MESH &my); + friend ostream & operator<<(ostream &os, const MESH &my); virtual void printMySelf(ostream &os) const; int addDriver(driverTypes driverType, const string & fileName ="Default File Name.med", const string & driverName="Default Mesh Name", - MED_EN::med_mode_acces access=MED_EN::MED_REMP); + MED_EN::med_mode_acces access=MED_EN::RDWR); int addDriver(GENDRIVER & driver); void rmDriver(int index=0); @@ -257,11 +261,15 @@ public : virtual inline const vector<FAMILY*> getFamilies(MED_EN::medEntityMesh Entity) const; virtual inline const FAMILY* getFamily(MED_EN::medEntityMesh Entity,int i) const; virtual int getNumberOfGroups(MED_EN::medEntityMesh Entity) const; - virtual inline const vector<GROUP*> getGroups(MED_EN::medEntityMesh Entity) const; - virtual inline const GROUP* getGroup(MED_EN::medEntityMesh Entity,int i) const; - virtual inline const CONNECTIVITY* getConnectivityptr() const; + virtual const vector<GROUP*> getGroups(MED_EN::medEntityMesh Entity) const; + virtual const GROUP* getGroup(MED_EN::medEntityMesh Entity,int i) const; + virtual const GROUP* getGroup(const string& name) const throw (MEDEXCEPTION); + virtual inline const CONNECTIVITY* getConnectivityptr() const; + inline void setConnectivityptr(CONNECTIVITY*); virtual SUPPORT * getBoundaryElements(MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); + virtual SUPPORT * getSupportOnAll(MED_EN::medEntityMesh Entity) + throw (MEDEXCEPTION); // problème avec le maillage dans le support : // le pointeur n'est pas const, mais sa valeur oui. A voir !!! PG @@ -316,6 +324,8 @@ public : vector< vector<double> > getBoundingBox() const; template<class T> static FIELD<T> * mergeFields(const vector< FIELD<T> * > & others, bool meshCompare=false); + void convertToPoly(); + /*! *For ref counter. Only for client */ @@ -333,23 +343,38 @@ inline const CONNECTIVITY* MESH::getConnectivityptr() const return _connectivity; } - +inline void MESH::setConnectivityptr(CONNECTIVITY* conn) +{ + _connectivity=conn; +} // This method is MED specific : don't use it // must be private. inline void MESH::write(const GENDRIVER & genDriver) { - const char * LOC = "MESH::write(const MED_MED_DRIVER & genDriver): "; - BEGIN_OF(LOC); + const char* LOC = "MESH::write(const MED_MED_DRIVER & genDriver): "; + BEGIN_OF_MED(LOC); for (unsigned int index=0; index < _drivers.size(); index++ ) if ( *_drivers[index] == genDriver ) { + + // EAP for MEDMEMTest_Med.cxx:305 : + // CPPUNIT_ASSERT_MED_NO_THROW(myMed->writeFrom(idMedV21_from)); + // CPPUNIT_ASSERT_MED(access(filenameout21_from.data(), F_OK) != 0); + string myDrvName = _drivers[index]->getFileName(); + string otherName = genDriver.getFileName(); + if ( !otherName.empty() ) + _drivers[index]->setFileName( otherName ); + // end EAP for MEDMEMTest_Med.cxx:305 + _drivers[index]->open(); _drivers[index]->write(); _drivers[index]->close(); + + _drivers[index]->setFileName( myDrvName );// EAP for MEDMEMTest_Med.cxx:305 // ? FINALEMENT PAS BESOIN DE L'EXCEPTION ? } - END_OF(LOC); + END_OF_MED(LOC); } @@ -357,8 +382,8 @@ inline void MESH::write(const GENDRIVER & genDriver) // must be private. inline void MESH::read(const GENDRIVER & genDriver) { - const char * LOC = "MESH::read(const MED_MED_DRIVER & genDriver): "; - BEGIN_OF(LOC); + const char* LOC = "MESH::read(const MED_MED_DRIVER & genDriver): "; + BEGIN_OF_MED(LOC); for (unsigned int index=0; index < _drivers.size(); index++ ) if ( *_drivers[index] == genDriver ) { @@ -368,17 +393,25 @@ inline void MESH::read(const GENDRIVER & genDriver) // ? FINALEMENT PAS BESOIN DE L'EXCEPTION ? } - END_OF(LOC); + END_OF_MED(LOC); } -/*! Set the MESH name */ +/*! Sets the MESH name. Name should not exceed MED_TAILLE_NOM +length defined in Med (i.e. 32 characters).*/ inline void MESH::setName(string name) { _name=name; //NOM interne à la classe } -/*! Get the MESH name */ +/*! \if MEDMEM_ug +\addtogroup MESH_general +@{ +\endif +*/ + +/*! +Gets the MESH name.*/ inline string MESH::getName() const { return _name; @@ -390,49 +423,72 @@ inline void MESH::setMeshDimension(int dim) } /*! Set the MESH description */ +/*! \ifnot MEDMEM_ug +Sets the MESH description. Description should not exceed MED_TAILLE_DESC length defined in Med (i.e. 200 characters). +\endif */ inline void MESH::setDescription(string description) { _description=description; //NOM interne à la classe } -/*! Get the MESH description */ +/*! Gets the MESH description. The string returned contains +a short description of the mesh, which is stored for +information purposes only.*/ inline string MESH::getDescription() const { return _description; } -/*! Get the dimension of the space */ +/*! Gets the dimension of the space in which the +mesh is described (2 for planar meshes, 3 for volumes and +3D surfaces) . */ inline int MESH::getSpaceDimension() const { return _spaceDimension; } -/*! Get the dimension of the MESH */ +/*! Gets the dimension of the mesh (2 for 2D- and 3D-surfaces, 3 for volumes). */ inline int MESH::getMeshDimension() const { return _meshDimension; } -/*! Get the number of nodes used in the MESH */ +/*! \if MEDMEM_ug +The retrieval of general information about a mesh is illustrated in the following C++ example. Its Python equivalent can be found in \a MESHgeneral.py. +This example illustrates how to retrieve the name, description, mesh and space dimensions. + +\example MESHgeneral.cxx +@} +\endif +*/ +/*! \if MEDMEM_ug +\addtogroup MESH_nodes +@{ +\endif +*/ +/*! Gets the number of nodes used in the mesh. */ inline int MESH::getNumberOfNodes() const { return _numberOfNodes; } -/*! Get the COORDINATES object. Use it only if you need COORDINATES informations not provided by the MESH class.*/ +/*! \ifnot MEDMEM_ug + Gets the COORDINATES object. Use it only if you need COORDINATES informations not provided by the MESH class. +\endif +*/ inline const COORDINATE * MESH::getCoordinateptr() const { // checkGridFillCoords(); return _coordinate; } -/*! Get the system in which coordinates are given (CARTESIAN,CYLINDRICAL,SPHERICAL) __??MED_CART??__. */ +/*! Retrieves the system in which coordinates are given (CARTESIAN,CYLINDRICAL,SPHERICAL). */ inline string MESH::getCoordinatesSystem() const { return _coordinate->getCoordinatesSystem(); } -/*! Get the whole coordinates array in a given interlacing mode. The interlacing mode are : +/*! Gets the whole coordinates array in a given interlacing mode. The interlacing mode are : - MED_NO_INTERLACE : X1 X2 Y1 Y2 Z1 Z2 - MED_FULL_INTERLACE : X1 Y1 Z1 X2 Y2 Z2 */ @@ -442,47 +498,63 @@ inline const double * MESH::getCoordinates(MED_EN::medModeSwitch Mode) const return _coordinate->getCoordinates(Mode); } -/*! Get the coordinate n° number on axis n°axis*/ +/*! Gets the coordinate number \a number on axis \a axis.*/ inline const double MESH::getCoordinate(int number, int axis) const { // checkGridFillCoords(); return _coordinate->getCoordinate(number,axis); } -/*! Get the coordinate names array ("x ","y ","z ") - of size n*MED_TAILLE_PNOM +/*! Gets a pointer to the coordinate names array. */ inline const string * MESH::getCoordinatesNames() const { return _coordinate->getCoordinatesNames(); } -/*! Get the coordinate unit names array ("cm ","cm ","cm ") - of size n*MED_TAILLE_PNOM +/*! Gets a pointer to the coordinate units array. */ inline const string * MESH::getCoordinatesUnits() const { return _coordinate->getCoordinatesUnits(); } +/*!\if MEDMEM_ug + +Here is a small C++ example program for which the +Python version may be found in +\a MESHcoordinates.py. + +\example MESHcoordinates.cxx + +@} +\endif +*/ + // int * MESH::getNodesNumbers() const // { // return nodesNumbers; // } -/*! Get the number of different geometric types for a given entity type. +/*!\if MEDMEM_ug +\addtogroup MESH_connectivity +@{ +\endif +*/ - For exemple getNumberOfTypes(MED_CELL) would return 3 if the MESH - have some MED_TETRA4, MED_PYRA5 and MED_HEXA6 in it. +/*! Gets the number of different geometric types for a given entity type. - medEntityMesh entity : MED_CELL, MED_FACE, MED_EDGE, MED_NODE, MED_ALL_ENTITIES + For example getNumberOfTypes(MED_CELL) would return 3 if the MESH + have some MED_TETRA4, MED_PYRA5 and MED_HEXA8 in it. + If entity is not defined, returns 0. + If there is no connectivity, returns an exception. - If entity is not defined, return 0. + \param entity entity type (MED_CELL, MED_FACE, MED_EDGE, MED_NODE, MED_ALL_ENTITIES) - If there is no connectivity, return an exception. + */ inline int MESH::getNumberOfTypes(MED_EN::medEntityMesh entity) const { - MESSAGE("MESH::getNumberOfTypes(medEntityMesh entity) : "<<entity); + MESSAGE_MED("MESH::getNumberOfTypes(medEntityMesh entity) : "<<entity); if (entity == MED_EN::MED_NODE) return 1; // checkGridFillConnectivity(); @@ -493,11 +565,9 @@ inline int MESH::getNumberOfTypes(MED_EN::medEntityMesh entity) const /*! Gets the list of geometric types used by a given entity. - medEntityMesh entity : MED_CELL, MED_FACE, MED_EDGE, MED_ALL_ENTITIES - - REM : Don't use MED_NODE - - If entity is not defined, it returns an exception. + If entity is not defined, it returns an exception. +\param entity Entity type must be MED_CELL, MED_FACE, MED_EDGE or MED_ALL_ENTITIES. + Passing MED_NODE as an entity type will throw an exception. */ inline const MED_EN::medGeometryElement * MESH::getTypes(MED_EN::medEntityMesh entity) const { @@ -510,11 +580,11 @@ inline const MED_EN::medGeometryElement * MESH::getTypes(MED_EN::medEntityMesh e return _connectivity->getGeometricTypes(entity); throw MEDEXCEPTION(LOCALIZED("MESH::getTypes( medEntityMesh ) : Connectivity not defined !")); } +/*! \if MEDMEM_ug @} \endif */ /*! Get the whole list of CELLMODEL used by cells of given type (medEntityMesh). - - REMARK : Don't use MED_NODE as medEntityMesh + Passing MED_NODE as an entity type will throw an exception. */ inline const CELLMODEL * MESH::getCellsTypes(MED_EN::medEntityMesh Entity) const { @@ -537,8 +607,13 @@ inline string * MESH::getCellTypeNames(MED_EN::medEntityMesh Entity) const return _connectivity->getCellTypeNames(Entity); throw MEDEXCEPTION(LOCALIZED("MESH::getCellTypesName( medEntityMesh ) : Connectivity not defined !")); } +/*!\if MEDMEM_ug +\addtogroup MESH_connectivity +@{ +\endif +*/ -/*! Returns an array of size NumbreOfTypes+1 which contains, for each +/*! Returns an array of size NumberOfTypes+1 which contains, for each geometric type of the given entity, the first global element number of this type. @@ -556,19 +631,18 @@ inline const int * MESH::getGlobalNumberingIndex(MED_EN::medEntityMesh entity) c throw MEDEXCEPTION(LOCALIZED("MESH::getNumberOfTypes( medEntityMesh ) : Connectivity not defined !")); } /*! - Returns the number of element of given geometric type of given entity. Return 0 if query is not defined. + Returns the number of elements of given geometric type of given entity. Returns 0 if query is not defined. Example : - - getNumberOfElements(MED_NODE,MED_NONE) : number of node + - getNumberOfElements(MED_NODE,MED_NONE) : number of nodes - getNumberOfElements(MED_NODE,MED_TRIA3) : returns 0 (not defined) - - getNumberOfElements(MED_FACE,MED_TRIA3) : returns number of triangles + - getNumberOfElements(MED_FACE,MED_TRIA3) : returns number of triangle elements defined in face entity (0 if not defined) - getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) : returns total number of elements defined in cell entity */ inline int MESH::getNumberOfElements(MED_EN::medEntityMesh entity, MED_EN::medGeometryElement Type) const { - // const char * LOC = "MESH::getNumberOfElements(medEntityMesh,medGeometryElement) : "; if (entity==MED_EN::MED_NODE) if ((Type==MED_EN::MED_NONE)|(Type==MED_EN::MED_ALL_ELEMENTS)) return _numberOfNodes; @@ -585,6 +659,33 @@ inline int MESH::getNumberOfElements(MED_EN::medEntityMesh entity, MED_EN::medGe //throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"connectivity not defined !")); } } +/*! \if MEDMEM_ug + +This example shows the use of connectivity retrieval methods on a mesh which +corresponds to the four-element mesh given in figure ??. Note +the use of connectivity and connnectivity index tables, and the +offsets used to convert Fortran-style numbering to C arrays. + +The output of this program reads : +\code +Number of types : 3 +Type #0 +Element 1 : 1 2 3 +Type #1 +Element 1 : 2 4 5 3 +Element 2 : 5 6 7 8 +Type #2 +Element 1 : 4 6 5 10 11 9 +\endcode + +\example read_example.cxx + +A more complete example involving descending connectivities +can be found in \c MESHconnectivities.cxx and \c MESHconnectivities.py. + +@} +\endif +*/ /*! Returns true if the wanted connectivity exist, else returns false (to use before a getSomething method). @@ -614,10 +715,17 @@ inline bool MESH::existPolyhedronConnectivity(MED_EN::medConnectivity connectivi throw MEDEXCEPTION("MESH::existPolyhedronConnectivity(medConnectivity,medEntityMesh) : no connectivity defined !"); return _connectivity->existPolyhedronConnectivity(connectivityType,entity); } + +/*!\if MEDMEM_ug +\addtogroup MESH_connectivity +@{ +\endif +*/ + /*! - Returns the geometric type of global element Number of entity Entity. + Returns the geometric type of global element number \a Number of entity \a Entity. - Throw an exception if Entity is not defined or Number are wrong (too big). + Throw an exception if \a Entity is not defined or if \a Numberis wrong. */ inline MED_EN::medGeometryElement MESH::getElementType(MED_EN::medEntityMesh Entity,int Number) const { @@ -626,8 +734,19 @@ inline MED_EN::medGeometryElement MESH::getElementType(MED_EN::medEntityMesh Ent throw MEDEXCEPTION("MESH::getElementType(medEntityMesh,int) : no connectivity defined !"); return _connectivity->getElementType(Entity,Number); } +/*! +\if MEDMEM_ug +@} +\endif + */ + +/*!\if MEDMEM_ug +\addtogroup MESH_poly +@{ +\endif +*/ -/* +/*! Method equivalent to getElementType except that it includes not only classical Types but polygons/polyhedra also. */ MED_EN::medGeometryElement MESH::getElementTypeWithPoly(MED_EN::medEntityMesh Entity, int Number) const @@ -638,7 +757,13 @@ MED_EN::medGeometryElement MESH::getElementTypeWithPoly(MED_EN::medEntityMesh En } /*! - Calculate the ask connectivity. Returns an exception if this could not be +\if MEDMEM_ug +@} +\endif + */ + +/*! + Calculates the required connectivity. Returns an exception if this could not be done. Do nothing if connectivity already exist. */ @@ -665,16 +790,27 @@ inline int MESH::getConnectivityLength(MED_EN::medModeSwitch Mode,MED_EN::medCon } else { - size = nbOfElm*(((int) Type)%100); + if ( ConnectivityType==MED_EN::MED_NODAL ) + size = nbOfElm*(((int) Type)%100); + else + size = _connectivity->getConnectivityLength(ConnectivityType,entity,Type); // issue 19983 } return size; } + +/*!\if MEDMEM_ug +\addtogroup MESH_connectivity +@{ +\endif +*/ + /*! - Returns the required connectivity in the right mode for the given - geometric type of the given entity. + Returns the required connectivity in mode \a Mode for the + geometric type \a Type of the entity type \a entity. +\a ConnectivityType specifies descending or nodal connectivity. - To get connectivity for all geometric type, use Mode=MED_FULL_INTERLACE - and Type=MED_ALL_ELEMENTS. + To get connectivity for all geometric type, use \a Mode=MED_FULL_INTERLACE + and \a Type=MED_ALL_ELEMENTS. You must also get the corresponding index array. */ inline const int * MESH::getConnectivity(MED_EN::medModeSwitch Mode,MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh entity, MED_EN::medGeometryElement Type) const @@ -686,20 +822,26 @@ inline const int * MESH::getConnectivity(MED_EN::medModeSwitch Mode,MED_EN::medC } /*! Returns the required index array for a connectivity received in - MED_FULL_ENTERLACE mode and MED_ALL_ELEMENTS type. + MED_FULL_INTERLACE mode and MED_ALL_ELEMENTS type. - This array allow to find connectivity of each elements. + This array allows to find connectivity of each element. - Example : Connectivity of i^{th} elements (1<=i<=NumberOfElement) begin - at index ConnectivityIndex[i-1] and end at index ConnectivityIndex[i]-1 + Example : Connectivity of i-th element (1<=i<=NumberOfElement) begins + at index ConnectivityIndex[i-1] and ends at index ConnectivityIndex[i]-1 in Connectivity array (Connectivity[ConnectivityIndex[i-1]-1] is the - first value) + first node of the element) */ inline const int * MESH::getConnectivityIndex(MED_EN::medConnectivity ConnectivityType,MED_EN::medEntityMesh entity) const { // checkGridFillConnectivity(); return _connectivity->getConnectivityIndex(ConnectivityType, entity); } + +/*!\if MEDMEM_ug @} \endif */ + + + + /*! Returns the corresponding length of the array returned by MESH::getPolygonsConnectivity. Used particulary for wrapping CORBA and python. @@ -709,6 +851,12 @@ inline int MESH::getPolygonsConnectivityLength(MED_EN::medConnectivity Connectiv { return getPolygonsConnectivityIndex (ConnectivityType,Entity)[ getNumberOfPolygons(Entity) ] - 1; } + +/*!\if MEDMEM_ug +\addtogroup MESH_poly +@{ +\endif +*/ /*! Return the required connectivity of polygons for the given entity. You must also get the corresponding index array. @@ -733,6 +881,8 @@ inline int MESH::getNumberOfPolygons(MED_EN::medEntityMesh Entity) const { return _connectivity->getNumberOfPolygons(Entity); } +/*! \if MEDMEM_ug @} \endif */ + /*! Returns the corresponding length of the array returned by MESH::getPolyhedronConnectivity with exactly the same arguments. Used particulary for wrapping CORBA and python. @@ -744,8 +894,13 @@ inline int MESH::getPolyhedronConnectivityLength(MED_EN::medConnectivity Connect return getPolyhedronFacesIndex()[ getNumberOfPolyhedronFaces() ] - 1; } + +/*! \if MEDMEM_ug +\addtogroup MESH_poly +@{ \endif */ + /*! - Return the required connectivity of polyhedron : + Returns the required connectivity of polyhedron : - in nodal mode, it gives you the polyhedron faces nodal connectivity. - in descending mode, it gives you the polyhedron faces list. You must also get : @@ -757,7 +912,7 @@ inline const int * MESH::getPolyhedronConnectivity(MED_EN::medConnectivity Conne return _connectivity->getPolyhedronConnectivity(ConnectivityType); } /*! - Return the index array of polyhedron faces in nodal mode. + Returns the index array of polyhedron faces in nodal mode. You must also get the polyhedron index array. */ inline const int * MESH::getPolyhedronFacesIndex() const @@ -765,26 +920,32 @@ inline const int * MESH::getPolyhedronFacesIndex() const return _connectivity->getPolyhedronFacesIndex(); } /*! - Return the required polyhedron index array. + Returns the required polyhedron index array. */ inline const int * MESH::getPolyhedronIndex(MED_EN::medConnectivity ConnectivityType) const { return _connectivity->getPolyhedronIndex(ConnectivityType); } /*! - Return the number of polyhedron faces. + Returns the number of polyhedron faces. */ inline int MESH::getNumberOfPolyhedronFaces() const { return _connectivity->getNumberOfPolyhedronFaces(); } /*! - Return the number of polyhedron. + Returns the number of polyhedron. */ inline int MESH::getNumberOfPolyhedron() const { return _connectivity->getNumberOfPolyhedron(); } + +/*!\if MEDMEM_ug +@} +\endif +*/ + /*! Returns the corresponding length of the array returned by MESH::getReverseConnectivity with exactly the same arguments. Used particulary for wrapping CORBA and python. @@ -809,7 +970,7 @@ inline int MESH::getReverseConnectivityLength(MED_EN::medConnectivity Connectivi nb = getNumberOfElements(MED_EN::MED_FACE, MED_EN::MED_ALL_ELEMENTS); } - return getReverseConnectivityIndex(ConnectivityType)[nb]-1; + return getReverseConnectivityIndex(ConnectivityType,Entity)[nb]-1; } /*! Returns the reverse connectivity required by ConnectivityType : @@ -872,6 +1033,9 @@ inline const int * MESH::getReverseConnectivityIndex(MED_EN::medConnectivity Con } +/*! +Retrieves the number of families in the mesh for entity type \a entity +*/ inline int MESH::getNumberOfFamilies (MED_EN::medEntityMesh entity) const { switch (entity) { @@ -887,6 +1051,10 @@ inline int MESH::getNumberOfFamilies (MED_EN::medEntityMesh entity) const throw MEDEXCEPTION("MESH::getNumberOfFamilies : Unknown entity"); } } + +/*! Retrieves the number of groups in the mesh for entity type \a entity + */ + inline int MESH::getNumberOfGroups (MED_EN::medEntityMesh entity) const { switch (entity) { @@ -902,6 +1070,7 @@ inline int MESH::getNumberOfGroups (MED_EN::medEntityMesh entity) const throw MEDEXCEPTION("MESH::getNumberOfGroups : Unknown entity"); } } +/*! Returns the families of type \a entity present in the mesh as a vector of pointers */ const vector<MEDMEM::FAMILY*> MESH::getFamilies(MED_EN::medEntityMesh entity) const { switch (entity) { @@ -918,21 +1087,7 @@ const vector<MEDMEM::FAMILY*> MESH::getFamilies(MED_EN::medEntityMesh entity) co } } -const vector<GROUP*> MESH::getGroups(MED_EN::medEntityMesh entity) const -{ - switch (entity) { - case MED_EN::MED_NODE : - return _groupNode; - case MED_EN::MED_CELL : - return _groupCell; - case MED_EN::MED_FACE : - return _groupFace; - case MED_EN::MED_EDGE : - return _groupEdge; - default : - throw MEDEXCEPTION("MESH::getGroups : Unknown entity"); - } -} + const MEDMEM::FAMILY* MESH::getFamily(MED_EN::medEntityMesh entity, int i) const { @@ -964,37 +1119,6 @@ const MEDMEM::FAMILY* MESH::getFamily(MED_EN::medEntityMesh entity, int i) const return Family[i-1]; } -const GROUP* MESH::getGroup(MED_EN::medEntityMesh entity, int i) const -{ - const char * LOC = "MESH::getGroup(medEntityMesh entity, int i) : "; - if (i<=0) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"argument i must be > 0")); - vector<GROUP*> Group; - switch (entity) { - case MED_EN::MED_NODE : { - Group = _groupNode; - break; - } - case MED_EN::MED_CELL : { - Group = _groupCell; - break; - } - case MED_EN::MED_FACE : { - Group = _groupFace; - break; - } - case MED_EN::MED_EDGE : { - Group = _groupEdge; - break; - } - default : - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Unknown entity")); - } - if (i>(int)Group.size()) - throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"argument i="<<i<<" must be <= _numberOfGroups="<<Group.size())); - return Group[i-1]; -} - // int * get_() { // return ; @@ -1006,7 +1130,7 @@ const GROUP* MESH::getGroup(MED_EN::medEntityMesh entity, int i) const inline bool MESH::getIsAGrid() { - SCRUTE(_isAGrid); + SCRUTE_MED(_isAGrid); return _isAGrid; } @@ -1023,7 +1147,7 @@ FIELD<T, FullInterlace> * MESH::mergeFields(const vector< FIELD<T, FullInterlace bool meshCompare) { const char * LOC = "MESH::mergeFields(const vector< FIELD<T>* >& others,bool meshCompare): "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); int i,j; if(others.size()==0) return 0; @@ -1078,7 +1202,7 @@ FIELD<T, FullInterlace> * MESH::mergeFields(const vector< FIELD<T, FullInterlace } } delete [] tempValues; - END_OF(LOC); + END_OF_MED(LOC); return ret; } diff --git a/src/MEDMEM/MEDMEM_Meshing.cxx b/src/MEDMEM/MEDMEM_Meshing.cxx index 6ff636659..c9aa29323 100644 --- a/src/MEDMEM/MEDMEM_Meshing.cxx +++ b/src/MEDMEM/MEDMEM_Meshing.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // /* File MEDMEM_Meshing.cxx @@ -36,34 +38,78 @@ using namespace std; using namespace MEDMEM; using namespace MED_EN; -/*! Create an empty MESH. */ +namespace MEDMEM { +/*! + +\defgroup MESHING_constructors Constructors + +\defgroup MESHING_general General information settings + +\defgroup MESHING_nodes Node coordinates settings + +\defgroup MESHING_connectivity Connectivity settings + +When defining the connectivity, MED_CELL elements connectivity +should be defined first. If necessary, constituent connectivities (MED_FACE and/or MED_EDGE) can be defined afterwards. + +\warning It should be kept in mind that when defining connectivities, +elements should be sorted in ascending type order (the type order +being defined by the number of nodes). + + +\defgroup MESHING_group Group creation + +\defgroup MESHING_poly Polygons and Polyhedra creation + +These methods belong to the meshing class and are necessary for +creating the connectivities of MED_POLYHEDRON and MED_POLYGON +elements. + +*/ + +/*! +\addtogroup MESHING_constructors + @{ +*/ + +/*! Creates an empty MESH. */ MESHING::MESHING(): MESH() { - MESSAGE("MESHING::MESHING()"); - SCRUTE(_coordinate); - SCRUTE(_connectivity); + MESSAGE_MED("MESHING::MESHING()"); + SCRUTE_MED(_coordinate); + SCRUTE_MED(_connectivity); } +/*! @} */ MESHING::~MESHING() { - MESSAGE("Deletinh MESHING !!"); + MESSAGE_MED("Deleting MESHING !!"); } -/*! Set the dimension of the space */ -void MESHING::setSpaceDimension(const int SpaceDimension) +/*! +\addtogroup MESHING_general + @{ */ + +/*! Sets the dimension of the space. */ +void MESHING::setSpaceDimension(int SpaceDimension) { _spaceDimension = SpaceDimension ; } -/*! Set the dimension of the MESHING */ +/*! Sets the dimension of the mesh. */ void MESHING::setMeshDimension(const int MeshDimension) { _meshDimension = MeshDimension ; if (_connectivity) _connectivity->setEntityDimension(MeshDimension); } +/*! @} */ + +/*! +\addtogroup MESHING_nodes + @{ */ -/*! Set the number of nodes used in the MESH */ +/*! Sets the number of nodes used in the mesh. */ void MESHING::setNumberOfNodes(const int NumberOfNodes) { _numberOfNodes = NumberOfNodes ; @@ -72,26 +118,38 @@ void MESHING::setNumberOfNodes(const int NumberOfNodes) } /*! - Set the whole coordinates array in a given system and interlacing mode. + Sets the whole coordinates array in a given system and interlacing mode. The system coordinates are : - - "CARTESIAN" - - "CYLINDRICAL" - - "SPHERICAL" + - "MED_CART" + - "MED_CYL" + - "MED_SPHER" The interlacing mode are : - MED_NO_INTERLACE : X1 X2 Y1 Y2 Z1 Z2 - MED_FULL_INTERLACE : X1 Y1 Z1 X2 Y2 Z2 + +Example : +\verbatim +MESHING myMeshing ; +const int SpaceDimension=2; +const int NumberOfNodes=6; +int * Coordinates = new int[SpaceDimension*NumberOfNodes] ; +string System="CARTESIAN"; +medModeSwitch Mode = MED_FULL_INTERLACE ; +myMeshing.setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,System,Mode); +\endverbatim + */ void MESHING::setCoordinates(const int SpaceDimension, - const int NumberOfNodes, - const double * Coordinates, - const string System, - const medModeSwitch Mode) + const int NumberOfNodes, + const double * Coordinates, + const string System, + const MED_EN::medModeSwitch Mode) { setSpaceDimension(SpaceDimension); setNumberOfNodes(NumberOfNodes); - SCRUTE(_coordinate); - SCRUTE(_connectivity); + SCRUTE_MED(_coordinate); + SCRUTE_MED(_connectivity); //if (NULL != _coordinate) delete _coordinate; _coordinate = new COORDINATE(SpaceDimension, @@ -100,9 +158,11 @@ void MESHING::setCoordinates(const int SpaceDimension, _coordinate->setCoordinates(Mode,Coordinates); _coordinate->setCoordinatesSystem(System); } +/*! @} */ + -/*! Set the system in which coordinates are given (CARTESIAN,CYLINDRICAL,SPHERICAL) __??MED_CART??__. */ -void MESHING::setCoordinatesSystem(const string System) +/*! Sets the system in which coordinates are given (MED_CART,MED_CYL,MED_SPHER). */ +void MESHING::setCoordinatesSystem(const string& System) throw (MEDEXCEPTION) { if (NULL == _coordinate) @@ -110,8 +170,18 @@ void MESHING::setCoordinatesSystem(const string System) _coordinate->setCoordinatesSystem(System); } -/*! Set the coordinate names array ("x ","y ","z ") - of size n*MED_TAILLE_PNOM +/*! + \addtogroup MESHING_general + @{ */ +/*! Sets the coordinate names array. +Coordinates names must not exceed the storage length +defined in MED-file : MED_TAILLE_PNOM (8). + +Example: +\verbatim +string coord[3]={"x","y","z"}; +meshing.setCoordinatesNames(coord); +\endverbatim */ void MESHING::setCoordinatesNames(const string * name) { @@ -120,17 +190,29 @@ void MESHING::setCoordinatesNames(const string * name) _coordinate->setCoordinatesNames(name); } -/*! - Set the (i+1)^th component of coordinate names array - ("x ","y ","z ") of size n*MED_TAILLE_PNOM + + +/*! \ifnot MEDMEM_ug + Sets the (i+1)-th component of coordinate names array. + Coordinates names must not exceed the storage length +defined in MED-file : MED_TAILLE_PNOM (8). +\endif + */ void MESHING::setCoordinateName(const string name, const int i) { _coordinate->setCoordinateName(name,i); } -/*! Set the coordinate unit names array ("cm ","cm ","cm ") - of size n*MED_TAILLE_PNOM +/*! Sets the coordinate unit names array + of size n*MED_TAILLE_PNOM. Coordinates units must not exceed the storage length +defined in MED-file : MED_TAILLE_PNOM (8). + +Example: +\verbatim +string coord[3]={"cm","cm","cm"}; +meshing.setCoordinatesUnits(coord); +\endverbatim */ void MESHING::setCoordinatesUnits(const string * units) { @@ -139,28 +221,35 @@ void MESHING::setCoordinatesUnits(const string * units) _coordinate->setCoordinatesUnits(units); } -/*! - Set the (i+1)^th component of the coordinate unit names array +/*!\ifnot MEDMEM_ug + Sets the \f$ (i+1)^th \f$ component of the coordinate unit names array ("cm ","cm ","cm ") of size n*MED_TAILLE_PNOM + \endif */ void MESHING::setCoordinateUnit(const string unit, const int i) { _coordinate->setCoordinateUnit(unit,i); } +/*! @} */ + +/*! + \addtogroup MESHING_connectivity + @{ +*/ /*! - Create a new connectivity object with the given number of type and - entity. If a connectivity already exist, delete it ! + Creates a new connectivity object with the given number of type and + entity. If a connectivity already exist, it is deleted by the call. - For exemple setNumberOfTypes(3,MED_CELL) create a connectivity with 3 + For exemple setNumberOfTypes(3,MED_CELL) creates a connectivity with 3 medGeometryElement in MESH for MED_CELL entity (like MED_TETRA4, MED_PYRA5 and MED_HEXA6 for example). - Return an exception if could not create the connectivity (as if we set + Returns an exception if it could not create the connectivity (as if we set MED_FACE connectivity before MED_CELL). */ void MESHING::setNumberOfTypes(const int NumberOfTypes, - const medEntityMesh Entity) + const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION) { const char * LOC = "MESHING::setNumberOfTypes( medEntityMesh ) : "; @@ -170,11 +259,13 @@ void MESHING::setNumberOfTypes(const int NumberOfTypes, throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not required with MED_NODE !")); if (MED_CELL == Entity) { - SCRUTE(_connectivity); + SCRUTE_MED(_connectivity); // if (_connectivity != (CONNECTIVITY *) NULL) // delete _connectivity ; _connectivity = new CONNECTIVITY(NumberOfTypes,Entity) ; + _connectivity->setNumberOfNodes( _numberOfNodes ); + } else { if (_connectivity == NULL) // we must have defined MED_CELL connectivity @@ -192,23 +283,28 @@ void MESHING::setNumberOfTypes(const int NumberOfTypes, if (2 != getSpaceDimension()) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Could not set connectivity on MED_EDGE !")); } - // all rigth, we could create connectivity ! + // all right, we could create connectivity ! CONNECTIVITY * myConnectivity = new CONNECTIVITY(NumberOfTypes,Entity) ; myConnectivity->setEntityDimension(_connectivity->getEntityDimension()-1); + myConnectivity->setNumberOfNodes(_connectivity->getNumberOfNodes()); _connectivity->setConstituent(myConnectivity); } } /*! - Set the list of geometric types used by a given entity. - medEntityMesh entity could be : MED_CELL, MED_FACE, MED_EDGE + Sets the list of geometric types used by a given entity. + medEntityMesh entity could be : MED_CELL, MED_FACE, MED_EDGE. + This method is used to set the differents geometrics types +({MED_TETRA4,MED_PYRA5,MED_HEXA8} for example). Geometric types should be given in increasing order of number of nodes for entity type \a entity. + + Remark : Don't use MED_NODE and MED_ALL_ENTITIES. - REM : Don't use MED_NODE and MED_ALL_ENTITIES +If \a entity is not defined, the method will throw an exception. - If entity is not defined, throw an exception. */ -void MESHING::setTypes(const medGeometryElement * Types, - const medEntityMesh entity) + +void MESHING::setTypes(const MED_EN::medGeometryElement * Types, + const MED_EN::medEntityMesh entity) throw (MEDEXCEPTION) { if (entity == MED_NODE) @@ -221,14 +317,14 @@ void MESHING::setTypes(const medGeometryElement * Types, } /*! - Set the number of elements for each geometric type of given entity. + Sets the number of elements for each geometric type of given entity. - Example : setNumberOfElements({12,23},MED_FACE) - if we have two type of face (MED_TRIA3 and MED_QUAD4), - we set 12 triangles and 23 quadrangles. + Example : setNumberOfElements(\{12,23\},MED_FACE); + If there are two types of face (MED_TRIA3 and MED_QUAD4), + this sets 12 triangles and 23 quadrangles. */ void MESHING::setNumberOfElements(const int * NumberOfElements, - const medEntityMesh Entity) + const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION) { const char * LOC = "MESHING::setNumberOfElements(const int *, medEntityMesh) : " ; @@ -249,14 +345,29 @@ void MESHING::setNumberOfElements(const int * NumberOfElements, } /*! - Set the nodal connectivity for one geometric type of the given entity. + Sets the nodal connectivity for geometric type \a Type of entity \a Entity. + The nodal connectivity must be defined one element type at a time : + \a MED_ALL_ELEMENTS is not a valid \a Type argument. + + Example : + +\verbatim +MESHING myMeshing ; +myMeshing.setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,System,Mode); + +myMeshing.setNumberOfTypes(2,MED_CELL); +myMeshing.setTypes({MED_TRIA3,MED_QUAD4},MED_CELL); +myMeshing.setNumberOfElements({3,2},MED_CELL); // 3 MED_TRIA3 and 2 MED_QUAD4 +myMeshing.setConnectivity({1,2,3,6,8,9,4,5,6},MED_CELL,MED_TRIA3); +myMeshing.setConnectivity({1,3,4,5,4,5,7,8},MED_CELL,MED_QUAD4); +\endverbatim Example : setConnectivity({1,2,3,1,4,2},MED_FACE,MED_TRIA3) Define 2 triangles face defined with nodes 1,2,3 and 1,4,2. */ void MESHING::setConnectivity(const int * Connectivity, - const medEntityMesh Entity, - const medGeometryElement Type) + const MED_EN::medEntityMesh Entity, + const MED_EN::medGeometryElement Type) throw (MEDEXCEPTION) { const char * LOC = "MESHING::setConnectivity : " ; @@ -267,11 +378,42 @@ void MESHING::setConnectivity(const int * Connectivity, if (_connectivity == (CONNECTIVITY*)NULL) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"No connectivity defined !")); + _connectivity->setNumberOfNodes(_numberOfNodes); _connectivity->setNodal(Connectivity,Entity,Type) ; } +/*! @} */ + +/*! +\addtogroup MESHING_poly + @{ + */ + +/*! Method setting the connectivity for MED_POLYGON +elements +\param ConnectivityIndex polygon connectivity index +\param Connectivity polygon connectivity +\param nbOfPolygons number of polygons defined +\param Entity entity of the polygon + +The \a Entity parameter specifies whether the polygon is the highest order + element (MED_CELL) or it is a 2D element in a 3D mesh (MED_FACE). + +This method is fully compatible with the MESHING::setConnectivity method. +The following code excerpt creates two polygons with 5 and 4 nodes respectively. +\verbatim +MESHING myMeshing ; +myMeshing.setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,System,Mode); + +int conn_index[3]={1,6,10}; +int conn[9]={1,2,3,4,5,5,4,6,7}; +int nb_poly=2; +meshing.setPolygonsConnectivity(conn_index, conn, nb_poly, MED_CELL) +\endverbatim + +*/ void MESHING::setPolygonsConnectivity (const int * ConnectivityIndex, - const int * ConnectivityValue, + const int * Connectivity, int nbOfPolygons, const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION) @@ -279,9 +421,18 @@ void MESHING::setPolygonsConnectivity (const int * ConnectivityIndex, if (_connectivity == (CONNECTIVITY*)NULL) throw MEDEXCEPTION("No connectivity defined !"); - _connectivity->setPolygonsConnectivity(MED_NODAL, Entity, ConnectivityValue, ConnectivityIndex,ConnectivityIndex[nbOfPolygons]-1,nbOfPolygons) ; + _connectivity->setPolygonsConnectivity(MED_NODAL, Entity, Connectivity, ConnectivityIndex,ConnectivityIndex[nbOfPolygons]-1,nbOfPolygons) ; } + +/*! Method setting the connectivity for MED_POLYHEDRON +elements +\param PolyhedronIndex polyhedra connectivity index +\param FacesIndex polyhedra face connectivity index +\param Nodes polyhedra connectivity +\param nbOfPolyhedra number of polyhedra defined +\param Entity deprecated parameter +*/ void MESHING::setPolyhedraConnectivity (const int * PolyhedronIndex, const int * FacesIndex, const int * Nodes, @@ -299,21 +450,22 @@ void MESHING::setPolyhedraConnectivity (const int * PolyhedronIndex, else throw MEDEXCEPTION("Invalid connectivity for polyhedra !!!"); } +/*! @} */ /*! NOT YET IMPLEMENTED !! WARNING */ void MESHING::setConnectivities (const int * ConnectivityIndex, const int * ConnectivityValue, - const medConnectivity ConnectivityType, - const medEntityMesh Entity) + const MED_EN::medConnectivity ConnectivityType, + const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION) { const char * LOC = "MESHING::setConnectivities : " ; - SCRUTE(Entity); - SCRUTE(ConnectivityType); - SCRUTE(ConnectivityValue); - SCRUTE(ConnectivityIndex); + SCRUTE_MED(Entity); + SCRUTE_MED(ConnectivityType); + SCRUTE_MED(ConnectivityValue); + SCRUTE_MED(ConnectivityIndex); throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Not Yet Implemented :: Warning !")); } @@ -340,6 +492,17 @@ void MESHING::setConnectivities (const int * ConnectivityIndex, // myGroup->setNumber(Number) ; // } +/*! +\addtogroup MESHING_group + @{ */ + +/*!Adds group \a Group to the mesh. +This function registers the group in the list +of groups contained in the mesh, so that +when the mesh is used for file writing, the group +is written in the corresponding MED-file. +*/ + void MESHING::addGroup(const GROUP & Group) throw (MEDEXCEPTION) { @@ -367,3 +530,6 @@ void MESHING::addGroup(const GROUP & Group) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Bad Entity !")); } } + +}; +/*! @} */ diff --git a/src/MEDMEM/MEDMEM_Meshing.hxx b/src/MEDMEM/MEDMEM_Meshing.hxx index 76fc175d8..a785ecb02 100644 --- a/src/MEDMEM/MEDMEM_Meshing.hxx +++ b/src/MEDMEM/MEDMEM_Meshing.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // /* File MEDMEM_Meshing.hxx @@ -29,11 +31,13 @@ #include "MEDMEM_Mesh.hxx" + +namespace MEDMEM { + /*! This class MESHING is a special class to set a MESH object. */ -namespace MEDMEM { class MEDMEM_EXPORT MESHING: public MESH { public : @@ -48,7 +52,7 @@ public : const double * Coordinates, const string System, const MED_EN::medModeSwitch Mode) ; - void setCoordinatesSystem(const string System) + void setCoordinatesSystem(const string& System) throw (MEDEXCEPTION) ; void setCoordinatesNames (const string * names) ; void setCoordinateName (const string name, const int i) ; diff --git a/src/MEDMEM/MEDMEM_ModulusArray.hxx b/src/MEDMEM/MEDMEM_ModulusArray.hxx index f6dd5587f..dcb118a86 100644 --- a/src/MEDMEM/MEDMEM_ModulusArray.hxx +++ b/src/MEDMEM/MEDMEM_ModulusArray.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef __MEDMODULUSARRAY_H__ #define __MEDMODULUSARRAY_H__ @@ -44,43 +46,26 @@ private: int _length2; const int * _array ; - bool compareNotVertexNodes(const MEDMODULUSARRAY &modulusArray) const; + inline bool compareNotVertexNodes(const MEDMODULUSARRAY &modulusArray) const; public: - MEDMODULUSARRAY(int length, const int * array) ; - MEDMODULUSARRAY(int vertexLength, int totalLength, const int * array); - ~MEDMODULUSARRAY() ; - - const int operator[](const int &i) const ; + MEDMODULUSARRAY(int length, const int * array) : + _length(length), _length2(length), _array(array) {} - int compare(const MEDMODULUSARRAY &modulusArray) const; + MEDMODULUSARRAY(int vertexLength, int totalLength, const int * array): + _length(vertexLength), _length2( totalLength ), _array(array) {} - const int *getArray(int& length) const { length=_length; return _array; } -}; + ~MEDMODULUSARRAY() {} + inline const int operator[](const int &i) const ; -MEDMODULUSARRAY::MEDMODULUSARRAY(int length, const int * array) : - _length(length), _array(array), _length2(0) -{ -// SCRUTE(_length); -// for (int i=0;i<_length;i++){ -// MESSAGE("MEDMODULUSARRAY["<<i<<"]="<<_array[i]); -// } -}; + inline int compare(const MEDMODULUSARRAY &modulusArray) const; - MEDMODULUSARRAY::MEDMODULUSARRAY(int vertexLength, int totalLength, const int * array): - _length(vertexLength), _length2( totalLength ), _array(array) -{ -} - -MEDMODULUSARRAY::~MEDMODULUSARRAY() -{ - // do nothing because nothing is allocated ! - // MESSAGE("MEDMODULUSARRAY::~MEDMODULUSARRAY()") ; + const int *getArray(int& length) const { length=_length; return _array; } }; -const int MEDMODULUSARRAY::operator[](const int &i) const +inline const int MEDMODULUSARRAY::operator[](const int &i) const { int position = i%_length ; //int position = i%_length2 ; @@ -88,9 +73,9 @@ const int MEDMODULUSARRAY::operator[](const int &i) const position+=_length ; //position += _length2 ; return _array[position] ; -}; +} -int MEDMODULUSARRAY::compare(const MEDMODULUSARRAY &modulusArray) const +inline int MEDMODULUSARRAY::compare(const MEDMODULUSARRAY &modulusArray) const { int ret = 0 ; @@ -149,7 +134,7 @@ int MEDMODULUSARRAY::compare(const MEDMODULUSARRAY &modulusArray) const * \brief Check presence of the same not vertex nodes * \retval bool - comparison result */ -bool MEDMODULUSARRAY::compareNotVertexNodes(const MEDMODULUSARRAY &modulusArray) const +inline bool MEDMODULUSARRAY::compareNotVertexNodes(const MEDMODULUSARRAY &modulusArray) const { if ( _length2 > _length ) { for ( int i = _length; i < _length2; ++i ) { diff --git a/src/MEDMEM/MEDMEM_OptionManager.hxx b/src/MEDMEM/MEDMEM_OptionManager.hxx new file mode 100644 index 000000000..97b2b748e --- /dev/null +++ b/src/MEDMEM/MEDMEM_OptionManager.hxx @@ -0,0 +1,125 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#ifndef _OPTION_MANAGER_HXX +#define _OPTION_MANAGER_HXX + +#include <string> +#include <map> +#include "MEDMEM_Exception.hxx" +namespace MEDMEM +{ + class OptionGeneric + { + //dummy method to have some polymorphism... + virtual void dummy()=0; + }; + + template < class T > + class Option : public OptionGeneric + { + private: + T * _var; + public: + Option( T defaut, T * var): + _var(var) + { + *_var= defaut; + } + void setValue(T value) + { + *_var=value; + } + T getValue() + { + return * _var; + } + + //dummy method to have some polymorphism... + void dummy(){} + }; + + class OptionManager + { + private: + std::map< std::string, OptionGeneric* > _optionList; + + public: + + ~OptionManager() + { + std::map< std::string, OptionGeneric*>::iterator mi; + for(mi = _optionList.begin() ; mi != _optionList.end() ; mi++) delete (*mi).second; + } + + template <class T> void registerOption( T * var, const std::string& name, T defaut) + { + OptionGeneric * newoption = new Option<T>( defaut, var); + _optionList.insert(make_pair(name, newoption)); + } + + template <class T> void getOption(const std::string& name, T& var) + { + if(_optionList.find(name) != _optionList.end()) + { + Option<T>* option_ptr = dynamic_cast<Option<T>*>(_optionList.find(name)->second); + var= option_ptr->getValue(); + } + else throw MEDEXCEPTION + ("Option is not listed, please register the option before using the getOption command"); + } + + template <class T> void setOption(const std::string& name, T value) + { + if(_optionList.find(name) != _optionList.end()) + { + Option<T>* option_ptr = dynamic_cast<Option<T>*>(_optionList.find(name)->second); + if (option_ptr != 0 ) + option_ptr->setValue(value); + else throw MEDEXCEPTION ("Error setOption: Option is registered with a different type"); + } + else throw MEDEXCEPTION + ("Option is not listed, please register the option before using the setOption command"); + } + + void setOption(const std::string& name, int value) + { + if(_optionList.find(name) != _optionList.end()) + { + Option<double>* option_double_ptr = dynamic_cast<Option<double>*> (_optionList.find(name)->second); + if (option_double_ptr!=0) + setOption(name,(double) value); + else + { + Option<int>* option_ptr =dynamic_cast<Option<int>*>(_optionList.find(name)->second); + if (option_ptr != 0 ) + option_ptr->setValue(value); + else throw MEDEXCEPTION ("Error setOption: Option is registered with a different type"); + } + } + else throw MEDEXCEPTION + ("Option is not listed, please register the option before using the setOption command"); + } + + }; +} + +#endif diff --git a/src/MEDMEM/MEDMEM_PointerOf.hxx b/src/MEDMEM/MEDMEM_PointerOf.hxx index 6834c0c5a..6dc7355ae 100644 --- a/src/MEDMEM/MEDMEM_PointerOf.hxx +++ b/src/MEDMEM/MEDMEM_PointerOf.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // # if ! defined( __PointerOf_HXX__ ) # define __PointerOf_HXX__ @@ -49,7 +51,7 @@ public : PointerOf( const T *pointer ) ; PointerOf( const int &size, const T *pointer ) ; PointerOf( const PointerOf<T> & pointerOf ) ; - PointerOf( const int &size, const PointerOf<T> & pointerOf ) ; + ///PointerOf( const int &size, const PointerOf<T> & pointerOf ) ; operator T*() ; operator const T*() const ; void set( const int &size ) ; @@ -79,20 +81,21 @@ template <typename T> PointerOf<T>::PointerOf() : _pointer(0), _done(false) template <typename T> PointerOf<T>::PointerOf(const PointerOf<T> & pointerOf) : _pointer((T*)(const T* const)pointerOf), _done(false) { - BEGIN_OF("PointerOf<T>::PointerOf(const PointerOf<T> & pointerOf)"); - MESSAGE("Warning ! No Propriety Transfer"); - END_OF ("PointerOf<T>::PointerOf(const PointerOf<T> & pointerOf)"); + const char* LOC = "PointerOf<T>::PointerOf(const PointerOf<T> & pointerOf)"; + BEGIN_OF_MED(LOC); + MESSAGE_MED("Warning ! No Propriety Transfer"); + END_OF_MED(LOC); } /*! Duplicate array of size size pointed in pointerOf. */ -template <typename T> PointerOf<T>::PointerOf( const int &size, const PointerOf<T> & pointerOf) : - _pointer((size,(T*)pointerOf)) -{ -} +//template <typename T> PointerOf<T>::PointerOf( const int &size, const PointerOf<T> & pointerOf) : +// _pointer((size,(T*)pointerOf)) +//{ +//} -/*! If size <= 0, creates a null "T*" pointer\n +/*! If size < 0, creates a null "T*" pointer\n Else allocates memory and sets desallocation boolean to true.\n Memory will be desallocated when erasing this PointerOf*/ template <typename T> PointerOf<T>::PointerOf( const int &size ) @@ -116,13 +119,13 @@ template <typename T> PointerOf<T>::PointerOf( const T* pointer ) : _pointer( (T { } -/*! If size <= 0, return an exception\n +/*! If size < 0, return an exception\n Else duplicate array and sets desallocation boolean to true.\n Memory will be desallocated when erasing this PointerOf*/ template <typename T> PointerOf<T>::PointerOf( const int &size, const T* pointer) { if (size < 0) - throw MEDEXCEPTION("PointerOf( const int,const T*) : array size <= 0"); + throw MEDEXCEPTION("PointerOf( const int,const T*) : array size < 0"); _pointer = new T[ size ] ; memcpy(_pointer,pointer,size*sizeof(T)); @@ -137,13 +140,13 @@ template <typename T> PointerOf<T>::~PointerOf() { if( _done ) { - MESSAGE("PointerOf<T>::~PointerOf() --> deleting _pointer") ; + MESSAGE_MED("PointerOf<T>::~PointerOf() --> deleting _pointer") ; delete [] _pointer ; _done = false ; } else { - MESSAGE("_pointer is only nullified") ; + MESSAGE_MED("_pointer is only nullified") ; } _pointer = 0 ; } @@ -158,12 +161,13 @@ template <typename T> PointerOf<T>::~PointerOf() - it works the same way as PointerOf(const PointerOf<T> & pointerOf) */ template <typename T> PointerOf<T>& PointerOf<T>::operator=( const PointerOf<T> &pointer ) { - BEGIN_OF("PointerOf<T>::operator=( const PointerOf<T> &pointer )") ; + const char* LOC = "PointerOf<T>::operator=( const PointerOf<T> &pointer )"; + BEGIN_OF_MED(LOC); if ( &pointer != this ) { this->set( pointer._pointer ) ; } - END_OF("PointerOf<T>::operator=( const PointerOf<T> &pointer )") ; + END_OF_MED(LOC); return *this ; } @@ -191,6 +195,7 @@ template <typename T> void PointerOf<T>::set( const int &size ) delete [] _pointer ; _pointer=0 ; } + // if (size < 0) TODO: analyse why it does not work if (size <= 0) { _pointer=(T*)NULL; @@ -209,24 +214,24 @@ template <typename T> void PointerOf<T>::set( const int &size ) memory will not be released when erasing this PointerOf*/ template <typename T> void PointerOf<T>::set( const T *pointer ) { - MESSAGE( "BEGIN PointerOf<T>::set( const T *pointer )" ) ; - SCRUTE(pointer) ; - SCRUTE(_done) ; + MESSAGE_MED( "BEGIN PointerOf<T>::set( const T *pointer )" ) ; + SCRUTE_MED(pointer) ; + SCRUTE_MED(_done) ; if ( _pointer && _done ) { - MESSAGE("PointerOf<T>::set --> deleting _pointer") ; + MESSAGE_MED("PointerOf<T>::set --> deleting _pointer") ; delete [] _pointer ; _pointer=0 ; _done=false ; } _pointer=(T*)pointer ; _done=false ; - MESSAGE( "END PointerOf<T>::set( const T *pointer )" ) ; + MESSAGE_MED( "END PointerOf<T>::set( const T *pointer )" ) ; return ; } /*! If necessary, released memory holded by PointerOf\n. - If size <= 0, return an exception\n. + If size < 0, return an exception\n. Else allocates memory and sets desallocation boolean to true.\n Can be used in order to "nullify" an existing PointerOf\n Memory will be desallocated when erasing this PointerOf*/ @@ -238,7 +243,7 @@ template <typename T> void PointerOf<T>::set( const int &size, const T *pointer) _pointer = NULL ; } if (size < 0) - throw MEDEXCEPTION("PointerOf( const int,const T*) : array size <= 0"); + throw MEDEXCEPTION("PointerOf( const int,const T*) : array size < 0"); _pointer = new T[ size ] ; memcpy(_pointer,pointer,size*sizeof(T)); diff --git a/src/MEDMEM/MEDMEM_PolyhedronArray.cxx b/src/MEDMEM/MEDMEM_PolyhedronArray.cxx index fe6f7ac3c..42b7247d0 100644 --- a/src/MEDMEM/MEDMEM_PolyhedronArray.cxx +++ b/src/MEDMEM/MEDMEM_PolyhedronArray.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_PolyhedronArray.hxx" diff --git a/src/MEDMEM/MEDMEM_PolyhedronArray.hxx b/src/MEDMEM/MEDMEM_PolyhedronArray.hxx index 46275ae46..6f34ec9c0 100644 --- a/src/MEDMEM/MEDMEM_PolyhedronArray.hxx +++ b/src/MEDMEM/MEDMEM_PolyhedronArray.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // # ifndef __POLYHEDRONARRAY_H__ # define __POLYHEDRONARRAY_H__ @@ -60,27 +62,27 @@ public : inline MED_EN::med_int POLYHEDRONARRAY::getNumberOfPolyhedron() const { return _numberOfPolyhedron; -}; +} inline MED_EN::med_int POLYHEDRONARRAY::getNumberOfFaces() const { return _numberOfFaces; -}; +} inline MED_EN::med_int POLYHEDRONARRAY::getNumberOfNodes() const { return _numberOfNodes; -}; +} inline const MED_EN::med_int* POLYHEDRONARRAY::getPolyhedronIndex() const { return (const MED_EN::med_int*) _polyhedronIndex; -}; +} inline const MED_EN::med_int* POLYHEDRONARRAY::getFacesIndex() const { return (const MED_EN::med_int*) _facesIndex; -}; +} inline const MED_EN::med_int* POLYHEDRONARRAY::getNodes() const { return (const MED_EN::med_int*) _nodes; -}; +} inline void POLYHEDRONARRAY::setPolyhedronIndex(const MED_EN::med_int* polyhedronindex) diff --git a/src/MEDMEM/MEDMEM_PorflowMeshDriver.cxx b/src/MEDMEM/MEDMEM_PorflowMeshDriver.cxx index 539fe988b..e30113ebb 100644 --- a/src/MEDMEM/MEDMEM_PorflowMeshDriver.cxx +++ b/src/MEDMEM/MEDMEM_PorflowMeshDriver.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_PorflowMeshDriver.hxx" #include "MEDMEM_DriversDef.hxx" @@ -79,7 +81,7 @@ inline static medGeometryElement get2DMedGeomType(int nbSommets); // Every memory allocation made in the MedDriver members function are desallocated in the Mesh destructor PORFLOW_MESH_DRIVER::PORFLOW_MESH_DRIVER(): - GENDRIVER(), + GENDRIVER(PORFLOW_DRIVER), _ptrMesh(( MESH *) NULL), // A VOIR _medIdt(MED_INVALID), _meshName("") @@ -89,7 +91,7 @@ PORFLOW_MESH_DRIVER::PORFLOW_MESH_DRIVER(): PORFLOW_MESH_DRIVER::PORFLOW_MESH_DRIVER(const string & fileName, MESH * ptrMesh, MED_EN::med_mode_acces accessMode): - GENDRIVER(fileName,accessMode), + GENDRIVER(fileName, accessMode, PORFLOW_DRIVER), _ptrMesh(ptrMesh) { // mesh name construction from fileName @@ -97,7 +99,7 @@ PORFLOW_MESH_DRIVER::PORFLOW_MESH_DRIVER(const string & fileName, string::size_type pos=fileName.find(ext,0); string::size_type pos1=fileName.rfind('/'); _meshName = string(fileName,pos1+1,pos-pos1-1); //get rid of directory & extension - SCRUTE(_meshName); + SCRUTE_MED(_meshName); } PORFLOW_MESH_DRIVER::PORFLOW_MESH_DRIVER(const PORFLOW_MESH_DRIVER & driver): @@ -116,7 +118,11 @@ void PORFLOW_MESH_DRIVER::open() throw (MEDEXCEPTION) { const char * LOC = "PORFLOW_MESH_DRIVER::open()" ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); + + if (_status == MED_OPENED) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"File "<<_fileName<<" is already open")); + _porflow.open(_fileName.c_str(), ios::in); if(_porflow) _status = MED_OPENED; @@ -125,20 +131,19 @@ void PORFLOW_MESH_DRIVER::open() _status = MED_CLOSED; throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Could not open file "<<_fileName<<" in mode ios::in")); } - END_OF(LOC); + END_OF_MED(LOC); } void PORFLOW_MESH_DRIVER::close() throw (MEDEXCEPTION) { - const char * LOC = "PORFLOW_MESH_DRIVER::close() " ; - BEGIN_OF(LOC); - if ( _status == MED_OPENED) - { - _porflow.close(); - _status = MED_CLOSED; - } - END_OF(LOC); + const char* LOC = "PORFLOW_MESH_DRIVER::close() "; + BEGIN_OF_MED(LOC); + if ( _status == MED_OPENED) { + _porflow.close(); + _status = MED_CLOSED; + } + END_OF_MED(LOC); } void PORFLOW_MESH_DRIVER::setMeshName(const string & meshName) { _meshName = meshName; }; @@ -153,9 +158,9 @@ PORFLOW_MESH_RDONLY_DRIVER::PORFLOW_MESH_RDONLY_DRIVER(): PORFLOW_MESH_DRIVER() PORFLOW_MESH_RDONLY_DRIVER::PORFLOW_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh): - PORFLOW_MESH_DRIVER(fileName,ptrMesh,MED_RDONLY) + PORFLOW_MESH_DRIVER(fileName,ptrMesh,RDONLY) { - MESSAGE("PORFLOW_MESH_RDONLY_DRIVER::PORFLOW_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); + MESSAGE_MED("PORFLOW_MESH_RDONLY_DRIVER::PORFLOW_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); } PORFLOW_MESH_RDONLY_DRIVER::PORFLOW_MESH_RDONLY_DRIVER(const PORFLOW_MESH_RDONLY_DRIVER & driver): @@ -165,7 +170,7 @@ PORFLOW_MESH_RDONLY_DRIVER::PORFLOW_MESH_RDONLY_DRIVER(const PORFLOW_MESH_RDONLY PORFLOW_MESH_RDONLY_DRIVER::~PORFLOW_MESH_RDONLY_DRIVER() { - //MESSAGE("PORFLOW_MESH_RDONLY_DRIVER::~PORFLOW_MESH_RDONLY_DRIVER() has been destroyed"); + //MESSAGE_MED("PORFLOW_MESH_RDONLY_DRIVER::~PORFLOW_MESH_RDONLY_DRIVER() has been destroyed"); } GENDRIVER * PORFLOW_MESH_RDONLY_DRIVER::copy(void) const @@ -288,13 +293,14 @@ void PORFLOW_MESH_RDONLY_DRIVER::readPorflowConnectivityFile(bool hybride,const } _maille maille; - unsigned int code, nodes_number, node; - pair<set<_maille>::iterator,bool> p_ma; + unsigned int code, nodes_number, node, ordre; + set<_maille>::iterator p_ma; if (hybride) // "HYBR" key-word while (connFile) { - connFile >> maille.ordre; + connFile >> ordre; + maille.setOrdre( ordre ); if (!connFile) // for spaces at the end of the file break; connFile >> code; @@ -302,9 +308,9 @@ void PORFLOW_MESH_RDONLY_DRIVER::readPorflowConnectivityFile(bool hybride,const maille.geometricType = geomPORFLOWtoMED[code-1]; if(maille.geometricType%100!=nodes_number) // following incohenrences founded in some porflow files! { - MESSAGE("WARNING : the read node number don't seem to be compatible with geometric type!"); - SCRUTE(maille.geometricType); - SCRUTE(nodes_number); + MESSAGE_MED("WARNING : the read node number don't seem to be compatible with geometric type!"); + SCRUTE_MED(maille.geometricType); + SCRUTE_MED(nodes_number); } maille.sommets.resize(nodes_number); for (unsigned i=0; i!=nodes_number; ++i) @@ -312,10 +318,10 @@ void PORFLOW_MESH_RDONLY_DRIVER::readPorflowConnectivityFile(bool hybride,const connFile >> node; maille.sommets[numPORFLOWtoMED[code-1][i]-1] = medi.points.find(node); } - p_ma = medi.maillage.insert(maille); - if (maille.ordre > p_ma_table.size()-1) // construction of a vector of iterators on _maille structures - p_ma_table.resize(2*maille.ordre); - p_ma_table[maille.ordre] = p_ma.first; + p_ma = medi.insert(maille); + if (maille.ordre() > p_ma_table.size()-1) // construction of a vector of iterators on _maille structures + p_ma_table.resize(2*maille.ordre()); + p_ma_table[maille.ordre()] = p_ma; } else // default case (or "VERT" key-word) { @@ -337,7 +343,7 @@ void PORFLOW_MESH_RDONLY_DRIVER::readPorflowConnectivityFile(bool hybride,const throw MEDEXCEPTION("PORFLOW_MESH_RDONLY_DRIVER::read()\nError, can't determine geometric type for this VERT mesh"); while (connFile) { - connFile >> maille.ordre; + connFile >> ordre; maille.setOrdre(ordre); if (!connFile) // for spaces at the end of the file break; for (unsigned i=0; i!=nodes_number; ++i) @@ -345,10 +351,10 @@ void PORFLOW_MESH_RDONLY_DRIVER::readPorflowConnectivityFile(bool hybride,const connFile >> node; maille.sommets[numPORFLOWtoMED[code-1][i]-1] = medi.points.find(node); } - p_ma = medi.maillage.insert(maille); - if (maille.ordre > p_ma_table.size()-1) // construction of a vector of iterators on _maille structures - p_ma_table.resize(2*maille.ordre); - p_ma_table[maille.ordre] = p_ma.first; + p_ma = medi.insert(maille); + if (maille.ordre() > p_ma_table.size()-1) // construction of a vector of iterators on _maille structures + p_ma_table.resize(2*maille.ordre()); + p_ma_table[maille.ordre()] = p_ma; } } connFile.close(); @@ -358,7 +364,7 @@ void PORFLOW_MESH_RDONLY_DRIVER::read(void) throw (MEDEXCEPTION) { const char * LOC = "PORFLOW_MESH_RDONLY_DRIVER::read() : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status!=MED_OPENED) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The _idt of file " << _fileName @@ -418,7 +424,7 @@ void PORFLOW_MESH_RDONLY_DRIVER::read(void) // the syntax corresponding to the use of input file is not implemented if ( isKeyWord(buf_ligne,"LOCA") ) { - MESSAGE("Mot clé LOCA détecté"); + MESSAGE_MED("Mot clé LOCA détecté"); processLoca=true; // if currentGroup is not empty, a group has been precessed // -> we store it, clear currentGroup, and start the precessing of a new group @@ -456,7 +462,7 @@ void PORFLOW_MESH_RDONLY_DRIVER::read(void) // the syntax corresponding to structured grids is not implemented else if ( isKeyWord(buf_ligne,"GRID") ) { - MESSAGE("Mot clé GRID détecté"); + MESSAGE_MED("Mot clé GRID détecté"); processLoca=false; pos=buf_ligne.find("UNST",0); if ( pos != string::npos ) // unstructured grid @@ -488,7 +494,7 @@ void PORFLOW_MESH_RDONLY_DRIVER::read(void) // the default option is HYBR else if ( isKeyWord(buf_ligne,"CONN") ) { - MESSAGE("Mot clé CONN détecté"); + MESSAGE_MED("Mot clé CONN détecté"); processLoca=false; string fileCONN=getPorflowFileName(buf_ligne,"CONN"); @@ -509,7 +515,7 @@ void PORFLOW_MESH_RDONLY_DRIVER::read(void) // expected syntax : COOR {VERT} {filename} else if ( isKeyWord(buf_ligne,"COOR") ) { - MESSAGE("Mot clé COOR"); + MESSAGE_MED("Mot clé COOR"); processLoca=false; string fileCOOR=getPorflowFileName(buf_ligne,"COOR"); @@ -621,7 +627,7 @@ void PORFLOW_MESH_RDONLY_DRIVER::read(void) // the corresponding 2D MED geometric type depends upon the number of nodes maille2D.sommets.resize(l); maille2D.geometricType = get2DMedGeomType(l); - p_ma = medi.maillage.insert(maille2D).first; // we insert the face in our mesh + p_ma = medi.insert(maille2D); // we insert the face in our mesh medi.groupes[i].mailles[ielem++]=p_ma; // and insert an iterator on it in our group maille2D.sommets.clear(); } @@ -632,14 +638,14 @@ void PORFLOW_MESH_RDONLY_DRIVER::read(void) } p_ma_table.clear(); // we don't need it anymore - MESSAGE(LOC << "PORFLOW_MESH_RDONLY_DRIVER::read : RESULTATS STRUCTURE INTERMEDIAIRES : "); - MESSAGE(LOC << medi ); + MESSAGE_MED(LOC << "PORFLOW_MESH_RDONLY_DRIVER::read : RESULTATS STRUCTURE INTERMEDIAIRES : "); + MESSAGE_MED(LOC << medi ); // TRANSFORMATION EN STRUCTURES MED if ( ! _ptrMesh->isEmpty() ) { throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Mesh object not empty : can't fill it!")); } - else if ( medi.maillage.size()==0 || medi.groupes.size()==0 || medi.points.size()==0) + else if ( /*medi.maillage.size()==0 || */medi.groupes.size()==0 || medi.points.size()==0) { throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << " Error while reading file " << _fileName << " The data read are not completed " ) ) ; @@ -648,7 +654,7 @@ void PORFLOW_MESH_RDONLY_DRIVER::read(void) { _ptrMesh->_name = _meshName; _ptrMesh->_spaceDimension = medi.points.begin()->second.coord.size(); - _ptrMesh->_meshDimension = medi.maillage.rbegin()->dimension(); + _ptrMesh->_meshDimension = medi.getMeshDimension(); _ptrMesh->_numberOfNodes = medi.points.size(); _ptrMesh->_isAGrid = 0; _ptrMesh->_coordinate = medi.getCoordinate(); @@ -663,7 +669,7 @@ void PORFLOW_MESH_RDONLY_DRIVER::read(void) // appele en dernier car cette fonction detruit le maillage intermediaire! _ptrMesh->_connectivity = medi.getConnectivity(); - MESSAGE(LOC << "PORFLOW_MESH_RDONLY_DRIVER::read : FIN "); + MESSAGE_MED(LOC << "PORFLOW_MESH_RDONLY_DRIVER::read : FIN "); // calcul de la connectivite d-1 complete, avec renumerotation des groupes // if (_ptrMesh->_spaceDimension==3) @@ -676,7 +682,7 @@ void PORFLOW_MESH_RDONLY_DRIVER::read(void) } - END_OF(LOC); + END_OF_MED(LOC); } void PORFLOW_MESH_RDONLY_DRIVER::write( void ) const @@ -694,9 +700,9 @@ PORFLOW_MESH_WRONLY_DRIVER::PORFLOW_MESH_WRONLY_DRIVER():PORFLOW_MESH_DRIVER() PORFLOW_MESH_WRONLY_DRIVER::PORFLOW_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh): - PORFLOW_MESH_DRIVER(fileName,ptrMesh,MED_WRONLY) + PORFLOW_MESH_DRIVER(fileName,ptrMesh,WRONLY) { - MESSAGE("PORFLOW_MESH_WRONLY_DRIVER::PORFLOW_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); + MESSAGE_MED("PORFLOW_MESH_WRONLY_DRIVER::PORFLOW_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); } PORFLOW_MESH_WRONLY_DRIVER::PORFLOW_MESH_WRONLY_DRIVER(const PORFLOW_MESH_WRONLY_DRIVER & driver): @@ -706,7 +712,7 @@ PORFLOW_MESH_WRONLY_DRIVER::PORFLOW_MESH_WRONLY_DRIVER(const PORFLOW_MESH_WRONLY PORFLOW_MESH_WRONLY_DRIVER::~PORFLOW_MESH_WRONLY_DRIVER() { - //MESSAGE("PORFLOW_MESH_WRONLY_DRIVER::PORFLOW_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed"); + //MESSAGE_MED("PORFLOW_MESH_WRONLY_DRIVER::PORFLOW_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed"); } GENDRIVER * PORFLOW_MESH_WRONLY_DRIVER::copy(void) const @@ -724,11 +730,11 @@ void PORFLOW_MESH_WRONLY_DRIVER::write(void) const throw (MEDEXCEPTION) { const char * LOC = "void PORFLOW_MESH_WRONLY_DRIVER::write(void) const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<< "Write Driver isn\'t implemented")); - END_OF(LOC); + END_OF_MED(LOC); } @@ -741,9 +747,9 @@ PORFLOW_MESH_RDWR_DRIVER::PORFLOW_MESH_RDWR_DRIVER():PORFLOW_MESH_DRIVER() PORFLOW_MESH_RDWR_DRIVER::PORFLOW_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh): - PORFLOW_MESH_DRIVER(fileName,ptrMesh,MED_RDWR) + PORFLOW_MESH_DRIVER(fileName,ptrMesh,RDWR) { - MESSAGE("PORFLOW_MESH_RDWR_DRIVER::PORFLOW_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); + MESSAGE_MED("PORFLOW_MESH_RDWR_DRIVER::PORFLOW_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); } PORFLOW_MESH_RDWR_DRIVER::PORFLOW_MESH_RDWR_DRIVER(const PORFLOW_MESH_RDWR_DRIVER & driver): @@ -752,7 +758,7 @@ PORFLOW_MESH_RDWR_DRIVER::PORFLOW_MESH_RDWR_DRIVER(const PORFLOW_MESH_RDWR_DRIVE } PORFLOW_MESH_RDWR_DRIVER::~PORFLOW_MESH_RDWR_DRIVER() { - //MESSAGE("PORFLOW_MESH_RDWR_DRIVER::PORFLOW_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed"); + //MESSAGE_MED("PORFLOW_MESH_RDWR_DRIVER::PORFLOW_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed"); } GENDRIVER * PORFLOW_MESH_RDWR_DRIVER::copy(void) const diff --git a/src/MEDMEM/MEDMEM_PorflowMeshDriver.hxx b/src/MEDMEM/MEDMEM_PorflowMeshDriver.hxx index 589eb0afe..43ee43229 100644 --- a/src/MEDMEM/MEDMEM_PorflowMeshDriver.hxx +++ b/src/MEDMEM/MEDMEM_PorflowMeshDriver.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef PORFLOW_MESH_DRIVER_HXX #define PORFLOW_MESH_DRIVER_HXX @@ -257,7 +259,7 @@ private: GENDRIVER * copy(void) const ; }; -}; +} #endif /* PORFLOW_MESH_DRIVER_HXX */ diff --git a/src/MEDMEM/MEDMEM_RCBase.hxx b/src/MEDMEM/MEDMEM_RCBase.hxx index 25be7c54e..0288d4035 100644 --- a/src/MEDMEM/MEDMEM_RCBase.hxx +++ b/src/MEDMEM/MEDMEM_RCBase.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef __MEDMEM_RCBASE_HXX__ #define __MEDMEM_RCBASE_HXX__ diff --git a/src/MEDMEM/MEDMEM_STRING.hxx b/src/MEDMEM/MEDMEM_STRING.hxx index f7fac0072..20feef90d 100644 --- a/src/MEDMEM/MEDMEM_STRING.hxx +++ b/src/MEDMEM/MEDMEM_STRING.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // # ifndef MEDMEM_STRING_HXX # define MEDMEM_STRING_HXX @@ -47,6 +49,20 @@ namespace MEDMEM { STRING() :string(), _s() { } + STRING(const STRING& s) :string(s) + { + _s << s ; + this->string::operator =( s ); + } + STRING& operator= (const STRING& s) + { + _s.str(""); + _s << s ; + + this->string::operator = ( _s.str() ) ; // freeze is true by now + + return *this ; + } ~STRING() { @@ -74,6 +90,6 @@ namespace MEDMEM { return *this ; } } ; -} ; +} # endif diff --git a/src/MEDMEM/MEDMEM_SetInterlacingType.hxx b/src/MEDMEM/MEDMEM_SetInterlacingType.hxx index 3d6e15a20..653693d0e 100644 --- a/src/MEDMEM/MEDMEM_SetInterlacingType.hxx +++ b/src/MEDMEM/MEDMEM_SetInterlacingType.hxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #ifndef MEDMEM_SET_INTERLACING_TYPE #define MEDMEM_SET_INTERLACING_TYPE diff --git a/src/MEDMEM/MEDMEM_SkyLineArray.cxx b/src/MEDMEM/MEDMEM_SkyLineArray.cxx index ba0774293..eba3e4df7 100644 --- a/src/MEDMEM/MEDMEM_SkyLineArray.cxx +++ b/src/MEDMEM/MEDMEM_SkyLineArray.cxx @@ -1,24 +1,27 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_SkyLineArray.hxx" #include "MEDMEM_Utilities.hxx" +#include <map> using namespace std; using namespace MEDMEM; @@ -26,22 +29,23 @@ using namespace MEDMEM; MEDSKYLINEARRAY::MEDSKYLINEARRAY(): _count(0), _length(0), _index((int*)NULL),_value((int*)NULL) { - MESSAGE("Constructeur MEDSKYLINEARRAY sans parametre"); + MESSAGE_MED("Constructeur MEDSKYLINEARRAY sans parametre"); } MEDSKYLINEARRAY::MEDSKYLINEARRAY(const MEDSKYLINEARRAY &myArray): _count(myArray._count),_length(myArray._length), _index(_count+1),_value(_length) { - BEGIN_OF("MEDSKYLINEARRAY(const MEDSKYLINEARRAY &)"); - memcpy(_index,myArray._index,sizeof(int)*(_count+1)); - memcpy(_value,myArray._value,sizeof(int)*_length); - END_OF("MEDSKYLINEARRAY(const MEDSKYLINEARRAY &)"); + const char* LOC = "MEDSKYLINEARRAY(const MEDSKYLINEARRAY &)"; + BEGIN_OF_MED(LOC); + memcpy(_index,myArray._index,sizeof(int)*(_count+1)); + memcpy(_value,myArray._value,sizeof(int)*_length); + END_OF_MED(LOC); } MEDSKYLINEARRAY::~MEDSKYLINEARRAY() { - MESSAGE("Destructeur ~MEDSKYLINEARRAY"); + MESSAGE_MED("Destructeur ~MEDSKYLINEARRAY"); //if (_index != NULL) delete [] _index; //if (_value != NULL) delete [] _value; @@ -51,14 +55,14 @@ MEDSKYLINEARRAY::MEDSKYLINEARRAY(const int count, const int length): _count(count), _length(length), _index(_count+1),_value(_length) { - MESSAGE("Constructeur MEDSKYLINEARRAY(count="<<count<<", length="<<length<<") avec parametres"); + MESSAGE_MED("Constructeur MEDSKYLINEARRAY(count="<<count<<", length="<<length<<") avec parametres"); } MEDSKYLINEARRAY::MEDSKYLINEARRAY(const int count, const int length, const int* index, const int* value,bool shallowCopy): _count(count), _length(length) { -// MESSAGE("Constructeur MEDSKYLINEARRAY(count="<<count<<", length="<<length<<") avec parametres"); +// MESSAGE_MED("Constructeur MEDSKYLINEARRAY(count="<<count<<", length="<<length<<") avec parametres"); if(shallowCopy) { _index.setShallowAndOwnership(index); @@ -71,6 +75,50 @@ MEDSKYLINEARRAY::MEDSKYLINEARRAY(const int count, const int length, } } +//creates the reverse array +//creates an array with count maxvalue, where maxvalue +//is the maximum of the value_ of the present array +//length is the same as present array +// +// For instance +// 1 : 2 4 +// 2 : 1 2 +// +//will give +// 1 : 2 +// 2 : 1 2 +// 3 : +// 4 : 1 + +MEDSKYLINEARRAY* MEDSKYLINEARRAY::makeReverseArray() +{ + multimap<int,int > reverse; + int size=0; + for (int i=0; i<_count;i++) + for (int j=_index[i];j<_index[i+1];j++) + { + int value=_value[j-1]; + reverse.insert(make_pair(value,i+1)); + if (value>size) size=value; + } + int* r_index=new int [size+1]; + int* r_value=new int [_length]; + r_index[0]=1; + pair<multimap<int,int>::iterator,multimap<int,int>::iterator>piter; + int* ptr_value=r_value; + for (int i=0; i<size;i++) + { + piter=reverse.equal_range(i); + int index_incr=0; + for (multimap<int,int>::iterator iter=piter.first; iter!=piter.second; iter++) + { + *ptr_value++=iter->second; + index_incr++; + } + r_index[i+1]=r_index[i]+index_incr; + } + return new MEDSKYLINEARRAY(size,_length,r_index,r_value,true); +} ostream& MEDMEM::operator<<(ostream &os, const MEDSKYLINEARRAY &sky) { os << "_count : " << sky._count << " ,_length : " << sky._length; for (int i = 0; i < sky._count ; i++) { @@ -83,7 +131,7 @@ ostream& MEDMEM::operator<<(ostream &os, const MEDSKYLINEARRAY &sky) { // void MEDSKYLINEARRAY::setMEDSKYLINEARRAY( const int count , const int length, int* index , int* value ) // { -// MESSAGE("void MEDSKYLINEARRAY::setMEDSKYLINEARRAY(count, length, index, value)"); +// MESSAGE_MED("void MEDSKYLINEARRAY::setMEDSKYLINEARRAY(count, length, index, value)"); // _count = count ; // _length = length ; diff --git a/src/MEDMEM/MEDMEM_SkyLineArray.hxx b/src/MEDMEM/MEDMEM_SkyLineArray.hxx index 4d9be82f9..44afe037a 100644 --- a/src/MEDMEM/MEDMEM_SkyLineArray.hxx +++ b/src/MEDMEM/MEDMEM_SkyLineArray.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // # ifndef __MEDSKYLINEARRAY_H__ # define __MEDSKYLINEARRAY_H__ @@ -81,6 +83,8 @@ public : inline void setIndexValue(int i, int value) throw (MEDEXCEPTION) ; friend ostream& operator<<(ostream &os, const MEDSKYLINEARRAY &sky); + MEDSKYLINEARRAY* makeReverseArray(); + }; // --------------------------------------- @@ -89,19 +93,19 @@ public : inline int MEDSKYLINEARRAY::getNumberOf() const { return _count ; -}; +} inline int MEDSKYLINEARRAY::getLength() const { return _length ; -}; +} inline const int* MEDSKYLINEARRAY::getIndex() const { return (const int*)_index ; -} ; +} inline const int* MEDSKYLINEARRAY::getValue() const { return (const int*)_value ; -} ; +} inline int MEDSKYLINEARRAY::getNumberOfI(int i) const throw (MEDEXCEPTION) { if (i<1) @@ -109,7 +113,7 @@ inline int MEDSKYLINEARRAY::getNumberOfI(int i) const throw (MEDEXCEPTION) if (i>_count) throw MEDEXCEPTION("MEDSKYLINEARRAY::getNumberOfI : argument is out of range"); return _index[i]-_index[i-1] ; -} ; +} inline const int* MEDSKYLINEARRAY::getI(int i) const throw (MEDEXCEPTION) { if (i<1) diff --git a/src/MEDMEM/MEDMEM_Support.cxx b/src/MEDMEM/MEDMEM_Support.cxx index d74b7293d..7480f8dc0 100644 --- a/src/MEDMEM/MEDMEM_Support.cxx +++ b/src/MEDMEM/MEDMEM_Support.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // /* File Support.cxx @@ -36,6 +38,25 @@ using namespace MEDMEM; #define MED_NBR_GEOMETRIE_MAILLE 15 +/*! +\defgroup SUPPORT_general General information + +\defgroup SUPPORT_creation Creation methods +The creation of a support requires a number of information +which is supplied to the MedMem library with the following methods. +When the support is defined on all elements, the creation method is +very simple, for the element list is implicitly defined. + +\defgroup SUPPORT_query Query methods + +\defgroup SUPPORT_constructors Constructors + +\defgroup SUPPORT_advanced Advanced methods + +*/ + + + /* This class is a generic class for family and group */ /*! @@ -49,20 +70,31 @@ SUPPORT::SUPPORT(): _name(""), _description("None"), _mesh((MESH*)NULL), _number((MEDSKYLINEARRAY*)NULL) //-------------------------------------------------------------------------- { - MESSAGE("SUPPORT::SUPPORT()"); + MESSAGE_MED("SUPPORT::SUPPORT()"); }; /*! - Constructor. +\addtogroup SUPPORT_constructors +@{ +*/ + +/*! + Constructor of a support lying on mesh \a Mesh. By default, +the support lies on all elements of type \a Entity. +Partial support can be described using \a setpartial method. + +\param Mesh Pointer to the mesh on which the support lies +\param Name Support name (should not exceed MED_TAILLE_NOM as defined in Med - i.e. 32 characters) +\param Entity Entity type of the support (MED_CELL,MED_FACE,MED_EDGE, MED_NODE) */ //-------------------------------------------------------------------------- -SUPPORT::SUPPORT(MESH* Mesh, string Name/*=""*/, medEntityMesh Entity/*=MED_CELL*/): +SUPPORT::SUPPORT(MESH* Mesh, string Name/*=""*/, MED_EN::medEntityMesh Entity/*=MED_CELL*/): _name(Name), _description("None"), _mesh(Mesh), _entity(Entity), _numberOfGeometricType(0), _isOnAllElts(true), _totalNumberOfElements(0), _number((MEDSKYLINEARRAY*)NULL) //-------------------------------------------------------------------------- { - MESSAGE("SUPPORT::SUPPORT(MESH*Mesh,string Name,medEntityMesh Entity)"); + MESSAGE_MED("SUPPORT::SUPPORT(MESH*Mesh,string Name,medEntityMesh Entity)"); update() ; }; @@ -73,8 +105,8 @@ SUPPORT::SUPPORT(MESH* Mesh, string Name/*=""*/, medEntityMesh Entity/*=MED_CELL SUPPORT::SUPPORT(const SUPPORT & m) //-------------------------------------------------------------------------- { - const char * LOC = "SUPPORT::SUPPORT(SUPPORT & m) : " ; - BEGIN_OF(LOC) ; + const char* LOC = "SUPPORT::SUPPORT(SUPPORT & m) : "; + BEGIN_OF_MED(LOC); _name = m._name ; _description = m._description ; @@ -99,17 +131,22 @@ SUPPORT::SUPPORT(const SUPPORT & m) _profilNames=m._profilNames; - END_OF(LOC) ; + END_OF_MED(LOC); }; /*! +@} + */ + +/*!\ifnot MEDMEM_ug Affectation operator. operator = perform et deep copy except for attribute _mesh +\endif */ //-------------------------------------------------------------------------- SUPPORT & SUPPORT::operator=(const SUPPORT & m) //-------------------------------------------------------------------------- { - const char * LOC = "SUPPORT::operator=(const SUPPORT & m) : " ; - BEGIN_OF(LOC) ; + const char* LOC = "SUPPORT::operator=(const SUPPORT & m) : "; + BEGIN_OF_MED(LOC); if ( this == &m ) return *this; @@ -124,17 +161,20 @@ SUPPORT & SUPPORT::operator=(const SUPPORT & m) if (m._numberOfElements) _numberOfElements.set(_numberOfGeometricType,m._numberOfElements); _totalNumberOfElements = m._totalNumberOfElements; + if (m._isOnAllElts == false) { if (_number) delete _number; if ( m._number ) // m may be not filled SUPPORTClient _number = new MEDSKYLINEARRAY(* m._number); else _number = (MEDSKYLINEARRAY *) NULL; - } else + } + else _number = (MEDSKYLINEARRAY *) NULL; + _profilNames=m._profilNames; - END_OF(LOC) ; + END_OF_MED(LOC); return *this; } @@ -145,7 +185,7 @@ SUPPORT & SUPPORT::operator=(const SUPPORT & m) SUPPORT::~SUPPORT() //----------------- { - MESSAGE("Destructeur ~SUPPORT()"); + MESSAGE_MED("Destructeur ~SUPPORT()"); clearDataOnNumbers(); } @@ -182,11 +222,16 @@ ostream & MEDMEM::operator<<(ostream &os, const SUPPORT &my) os << " On Type "<<MED_EN::geoNames[types[j]] <<" : there is(are) "<<numberOfElements<<" element(s) and " <<endl; } + int nbProfilNames = my._profilNames.size(); + os<<"Number of profil names = "<<nbProfilNames<<endl; + for(int j=0; j<nbProfilNames; j++) { + os<<" Profil Name N"<<j+1<<" = "<<my._profilNames[j]<<endl; + } return os ; } /*! - Updade the SUPPORT attributs with rigth MESH information. + Updade the SUPPORT attributs with right MESH information. It has an effect only if SUPPORT is on all elements. @@ -196,8 +241,8 @@ ostream & MEDMEM::operator<<(ostream &os, const SUPPORT &my) void SUPPORT::update() //------------------- { - const char * LOC = "SUPPORT::update() : " ; - BEGIN_OF(LOC) ; + const char* LOC = "SUPPORT::update() : "; + BEGIN_OF_MED(LOC); if (_isOnAllElts) { @@ -207,13 +252,13 @@ void SUPPORT::update() _geometricType.set(1); _geometricType[0]=MED_POINT1; _numberOfElements.set(1); - _numberOfElements[0]=_mesh->getNumberOfNodes(); // Vérifier le pointeur ! + _numberOfElements[0]=_mesh->getNumberOfNodes(); // Vérifier le pointeur ! _totalNumberOfElements=_numberOfElements[0]; } else { // we duplicate information from _mesh _numberOfGeometricType=_mesh->getNumberOfTypesWithPoly(_entity); - SCRUTE(_numberOfGeometricType); + SCRUTE_MED(_numberOfGeometricType); medGeometryElement * allType = _mesh->getTypesWithPoly(_entity); _geometricType.set(_numberOfGeometricType,allType ); _numberOfElements.set(_numberOfGeometricType); @@ -226,10 +271,10 @@ void SUPPORT::update() delete [] allType; } - SCRUTE(_name); - SCRUTE(_numberOfGeometricType); + SCRUTE_MED(_name); + SCRUTE_MED(_numberOfGeometricType); } - END_OF(LOC); + END_OF_MED(LOC); }; /*! Get the field value index (in fortran mode) from the support global number. @@ -240,7 +285,7 @@ int SUPPORT::getValIndFromGlobalNumber(const int number) const throw (MEDEXCEPTI //------------------- { const char * LOC="getValIndFromGlobalNumber(const int number) : "; - //BEGIN_OF(LOC); + //BEGIN_OF_MED(LOC); if (_isOnAllElts) return number; @@ -272,18 +317,33 @@ int SUPPORT::getValIndFromGlobalNumber(const int number) const throw (MEDEXCEPTI // It should never arrive here !! return 0; - //END_OF(LOC); + //END_OF_MED(); } /*! - Blend the given SUPPORT mySupport into the calling object SUPPORT. +\addtogroup SUPPORT_advanced +@{ + + */ + +/*! +Blends the given SUPPORT mySupport into the calling object SUPPORT. +Example : +\verbatim +SUPPORT mySupport ; +SUPPORT myOtherSupport ; +... +mySupport.blending(myOtherSupport) ; +\endverbatim +Support \a mySupport now contains a union of the elements originally +contained in \a mySupport and \a myOtherSupport. */ //------------------- void SUPPORT::blending(SUPPORT * mySupport) throw (MEDEXCEPTION) //------------------- { const char * LOC="SUPPORT::blending(SUPPORT *) : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_entity!=mySupport->getEntity()) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Entities are different !")); if(!(*_mesh == *mySupport->getMesh())) @@ -312,7 +372,7 @@ void SUPPORT::blending(SUPPORT * mySupport) throw (MEDEXCEPTION) for(iter=idsSet.begin();iter!=idsSet.end();iter++) idsList.push_back(*iter); - MESSAGE(LOC << " size Set " << idsSet.size() << " size List " << idsList.size()); + MESSAGE_MED(LOC << " size Set " << idsSet.size() << " size List " << idsList.size()); if(_entity==MED_NODE) fillFromNodeList(idsList); @@ -321,26 +381,62 @@ void SUPPORT::blending(SUPPORT * mySupport) throw (MEDEXCEPTION) } else clearDataOnNumbers(); - END_OF(LOC); + END_OF_MED(LOC); } +/*! @} */ + +/*! +\addtogroup SUPPORT_creation +@{ +*/ /*! - This function allows the user to set a support not on all entities Entity, - it should be used after an initialisation with the constructor - SUPPORT(MESH* Mesh, string Name="", medEntityMesh Entity=MED_CELL) and - after the call to the function setAll(false). - It allocates and initialises all the attributs of the class SUPPORT. +This function allows the user to set a support not on all entities Entity, +it should be used after an initialisation with the constructor +SUPPORT(MESH* Mesh, string Name="", medEntityMesh Entity=MED_CELL). +It allocates and initialises all the attributs of the class SUPPORT. + +\param Description string describing the support for information purposes (should not exceed MED_TAILLE_DESC length - i.e. 200 characters) +\param NumberOfGeometricType number of geometric types contained in the support +\param TotalNumberOfElements number of elements in the support +\param GeometricType array describing the geometric types (must be consistent with the entity that was passed as an argument to the support constructor) +\param NumberOfElements array describing the number of elements for each type +\param NumberValue array of IDs of the elements that constitute the group. + +The following example refers to the mesh given in the mesh connectivity example. +It creates a group containing the two cells on the right (the quadratic triangle and the quadrangle on the right). + +\verbatim +// creating SUPPORT on cells with one value per cell +SUPPORT right_group(mesh, MED_CELL, 1); + +string description = "right group"; +int number_of_types=2; +int number_of_elements=2; +medGeometryElement geom_types[2]={MED_QUAD4, MED_TRIA6}; +int number_of_elem_per_type[2]={1,1}; +int number_value[2]={3,4}; + +//defining the region of the support +right_group.setpartial(description, number_of_types, + number_of_elements, geom_types, + number_of_elem_per_type, number_value); +\endverbatim + +When MED_POLYGON or MED_POLYHEDRON elements are included in the support, +their global number should be given. For instance, on a mesh having ten MED_TRIA3 +and five MED_POLYGON, the number of the first polygonal element is 11. */ //------------------- void SUPPORT::setpartial(string Description, int NumberOfGeometricType, int TotalNumberOfElements, - medGeometryElement *GeometricType, + MED_EN::medGeometryElement *GeometricType, int *NumberOfElements, int *NumberValue) //------------------- { const char * LOC = "SUPPORT::setpartial(string , int , int , medGeometryElement * , int * , int *) : " ; - BEGIN_OF(LOC) ; + BEGIN_OF_MED(LOC) ; _isOnAllElts = false ; @@ -376,22 +472,25 @@ void SUPPORT::setpartial(string Description, int NumberOfGeometricType, for (int itype=0; itype < NumberOfGeometricType; itype++) { ostringstream typestr; - typestr<<_name<<"_type"<<itype; + typestr<<_name<<"_type"<<_geometricType[itype]; prof_names[itype]=typestr.str(); } setProfilNames(prof_names); - END_OF(LOC); + END_OF_MED(LOC); }; +/*! @} */ /*! +\ifnot MEDMEM_ug This function allows the user to set a support not on all entities Entity, it should be used after an initialisation of : SUPPORT(MESH* Mesh, string Name="", medEntityMesh Entity=MED_CELL) and after calling at least setGeometricType and perharps setEntity. It allocates and initialises all the attributs of the class SUPPORT but doesn't set a description, a SUPPORT name, a meshName and an associated MESH. +\endif */ //------------------- @@ -399,7 +498,7 @@ void SUPPORT::setpartial(MEDSKYLINEARRAY * number, bool shallowCopy) throw (MEDE //------------------- { const char * LOC = "SUPPORT::setpartial(MEDSKYLINEARRAY * number) : " ; - BEGIN_OF(LOC) ; + BEGIN_OF_MED(LOC) ; if ( ! _geometricType ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"SUPPORT must contains" @@ -425,27 +524,27 @@ void SUPPORT::setpartial(MEDSKYLINEARRAY * number, bool shallowCopy) throw (MEDE // cout << *_number << endl; - END_OF(LOC); + END_OF_MED(LOC); }; void SUPPORT::setpartial_fromfile(MEDSKYLINEARRAY * number, bool shallowCopy) throw (MEDEXCEPTION) //------------------- { - const char * LOC = "SUPPORT::setpartial_fromfile(MEDSKYLINEARRAY * number) : " ; - BEGIN_OF(LOC) ; + const char* LOC = "SUPPORT::setpartial_fromfile(MEDSKYLINEARRAY * number) : "; + BEGIN_OF_MED(LOC); if ( shallowCopy ) _number_fromfile = number; else _number_fromfile = new MEDSKYLINEARRAY(*number); - END_OF(LOC); + END_OF_MED(LOC); }; void SUPPORT::setProfilNames(vector<string> profilNames) throw (MEDEXCEPTION){ const char * LOC = "SUPPORT::setProfilNames(vector<string> profilNames) : " ; - BEGIN_OF(LOC) ; + BEGIN_OF_MED(LOC) ; if ( _isOnAllElts ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"SUPPORT shouldn't be on all elements" @@ -472,7 +571,7 @@ void SUPPORT::setProfilNames(vector<string> profilNames) throw (MEDEXCEPTION){ _profilNames = profilNames; - END_OF(LOC); + END_OF_MED(LOC); }; @@ -481,6 +580,10 @@ vector<string> SUPPORT::getProfilNames() const throw (MEDEXCEPTION) return _profilNames; }; +/*! +\addtogroup SUPPORT_advanced +@{ +*/ /*! This method gets the boundary elements of the mesh. The support has to be @@ -493,7 +596,7 @@ void SUPPORT::getBoundaryElements() throw (MEDEXCEPTION) //------------------- { const char * LOC = "SUPPORT::getBoundaryElements() : " ; - BEGIN_OF(LOC) ; + BEGIN_OF_MED(LOC) ; if (_mesh == (MESH*)NULL) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"You shlould use the appropriate SUPPORT Constructor before calling this method")); @@ -513,22 +616,22 @@ void SUPPORT::getBoundaryElements() throw (MEDEXCEPTION) int numberOf = _mesh->getNumberOfElements(_entity,MED_ALL_ELEMENTS) ; list<int> myElementsList ; int size = 0 ; - SCRUTE(numberOf) ; + SCRUTE_MED(numberOf) ; for (int i=0 ; i<numberOf; i++) if (myConnectivityValue[myConnectivityIndex[i]] == 0) { - SCRUTE(i+1) ; + SCRUTE_MED(i+1) ; myElementsList.push_back(i+1) ; size++ ; } - SCRUTE(size) ; + SCRUTE_MED(size) ; // Well, we must know how many geometric type we have found int * myListArray = new int[size] ; int id = 0 ; list<int>::iterator myElementsListIt ; for (myElementsListIt=myElementsList.begin();myElementsListIt!=myElementsList.end();myElementsListIt++) { myListArray[id]=(*myElementsListIt) ; - SCRUTE(id); - SCRUTE(myListArray[id]); + SCRUTE_MED(id); + SCRUTE_MED(myListArray[id]); id ++ ; } @@ -583,14 +686,14 @@ void SUPPORT::getBoundaryElements() throw (MEDEXCEPTION) MEDSKYLINEARRAY * mySkyLineArray = new MEDSKYLINEARRAY(numberOfGeometricType,size,mySkyLineArrayIndex,myListArray) ; setNumberOfGeometricType(numberOfGeometricType) ; - // setGeometricType(geometricType) ; - for (int i=0;i<numberOfGeometricType;i++) - { - _geometricType[i] = geometricType[i]; - } + setGeometricType(geometricType) ; + //for (int i=0;i<numberOfGeometricType;i++) + // { + // _geometricType[i] = geometricType[i]; + // } setNumberOfElements(numberOfElements) ; - setTotalNumberOfElements(size) ; + //setTotalNumberOfElements(size) ; // setNumber(mySkyLineArray) ; _number = new MEDSKYLINEARRAY(numberOfGeometricType,size); @@ -609,17 +712,18 @@ void SUPPORT::getBoundaryElements() throw (MEDEXCEPTION) delete[] myListArray; delete mySkyLineArray; - END_OF(LOC) ; + END_OF_MED(LOC); } /*! - intersect the given SUPPORT mySupport into the calling SUPPORT object. +Intersects \a mySupport into the calling SUPPORT object. +If A.intersecting(B) is called, on output, \f$ A \f$ contains \f$A \cap B\f$. */ //------------------- void SUPPORT::intersecting(SUPPORT * mySupport) throw (MEDEXCEPTION) { const char * LOC="SUPPORT::intersecting(SUPPORT *) : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_entity!=mySupport->getEntity()) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Entities are different !")); if(!(*_mesh == *mySupport->getMesh())) @@ -646,7 +750,7 @@ void SUPPORT::intersecting(SUPPORT * mySupport) throw (MEDEXCEPTION) int size=idsSet.size(); int sizeList = idsList.size(); - MESSAGE(LOC << " size Set " << idsSet.size() << " size List " << idsList.size()); + MESSAGE_MED(LOC << " size Set " << idsSet.size() << " size List " << idsList.size()); if(size!=0 && sizeList != 0) { @@ -659,8 +763,9 @@ void SUPPORT::intersecting(SUPPORT * mySupport) throw (MEDEXCEPTION) { clearDataOnNumbers(); } - END_OF(LOC); + END_OF_MED(LOC); }; +/*! @} */ /*! Method that cleans up all the fields related to _numbers. Defined for code factorization. @@ -686,16 +791,17 @@ void MEDMEM::SUPPORT::clearDataOnNumbers() bool MEDMEM::SUPPORT::operator == (const SUPPORT &support) const //-------------------------------------------------- { - const char * LOC = "bool SUPPORT::operator ==(const SUPPORT &support) const : "; - BEGIN_OF(LOC); + const char* LOC = "bool SUPPORT::operator ==(const SUPPORT &support) const : "; + BEGIN_OF_MED(LOC); bool operatorReturn = false; operatorReturn = (*_mesh == *support._mesh) && (_entity == support._entity) && (_numberOfGeometricType == support._numberOfGeometricType) && ((_isOnAllElts && support._isOnAllElts) || (!_isOnAllElts && !support._isOnAllElts)) && - (_totalNumberOfElements == support._totalNumberOfElements); + (_totalNumberOfElements == support._totalNumberOfElements) && + (_profilNames.size() == support._profilNames.size()); if (operatorReturn) { @@ -720,7 +826,7 @@ bool MEDMEM::SUPPORT::operator == (const SUPPORT &support) const } } - END_OF(LOC); + END_OF_MED(LOC); return operatorReturn; }; @@ -872,8 +978,9 @@ list<int> *MEDMEM::SUPPORT::sub(int start,int end,const int *idsToSuppress,int l return ret; } ret=new list<int>; - int *temp=new int[lgthIdsToSuppress]; + int *temp=new int[lgthIdsToSuppress+1]; memcpy(temp,idsToSuppress,sizeof(int)*lgthIdsToSuppress); + temp[lgthIdsToSuppress] = -1; qsort(temp,lgthIdsToSuppress,sizeof(int),compareId); int k=0; for(int i=start;i<=end;i++) @@ -956,7 +1063,7 @@ SUPPORT *MEDMEM::SUPPORT::getComplement() const SUPPORT *MEDMEM::SUPPORT::substract(const SUPPORT& other) const throw (MEDEXCEPTION) { const char * LOC = "SUPPORT *MEDMEM::subtract(const SUPPORT * other) : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); SUPPORT *ret; if (_entity!=other.getEntity()) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Entities are different !")); @@ -982,7 +1089,7 @@ SUPPORT *MEDMEM::SUPPORT::substract(const SUPPORT& other) const throw (MEDEXCEPT ret=_mesh->buildSupportOnElementsFromElementList(*ids,_entity); delete ids; return ret; - END_OF(LOC); + END_OF_MED(LOC); } /*! @@ -992,7 +1099,7 @@ SUPPORT *MEDMEM::SUPPORT::substract(const SUPPORT& other) const throw (MEDEXCEPT SUPPORT *MEDMEM::SUPPORT::getBoundaryElements(MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION) { const char * LOC = "SUPPORT *MEDMEM::SUPPORT::getBoundaryElements(MED_EN::medEntityMesh Entity) : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); int spaceDimension=_mesh->getSpaceDimension(); MED_EN::medEntityMesh baseEntity=Entity; if (spaceDimension == 3) @@ -1069,7 +1176,7 @@ void MEDMEM::SUPPORT::fillFromNodeList(const list<int>& listOfNode) throw (MEDEX setNumberOfGeometricType(numberOfGeometricType); setGeometricType(geometricType); setNumberOfElements(numberOfElements); - setTotalNumberOfElements(numberOfElements[0]); + //setTotalNumberOfElements(numberOfElements[0]); setNumber(mySkyLineArray); delete[] numberOfElements; @@ -1142,8 +1249,8 @@ void MEDMEM::SUPPORT::fillFromElementList(const list<int>& listOfElt) throw (MED MEDSKYLINEARRAY * mySkyLineArray = new MEDSKYLINEARRAY(numberOfGeometricType,size,mySkyLineArrayIndex,myListArray,true) ; setNumberOfGeometricType(numberOfGeometricType) ; setGeometricType(geometricType) ; - setNumberOfElements(numberOfElements) ; - setTotalNumberOfElements(size) ; + setNumberOfElements(numberOfElements) ; + //setTotalNumberOfElements(size) ; setNumber(mySkyLineArray) ; delete[] numberOfElements; diff --git a/src/MEDMEM/MEDMEM_Support.hxx b/src/MEDMEM/MEDMEM_Support.hxx index 5e092b26b..5023671f9 100644 --- a/src/MEDMEM/MEDMEM_Support.hxx +++ b/src/MEDMEM/MEDMEM_Support.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // /* File Support.hxx @@ -39,6 +41,11 @@ #include "MEDMEM_SkyLineArray.hxx" #include "MEDMEM_RCBase.hxx" + +namespace MEDMEM { + + class MESH; + /*! This class describe a support of elements on an entity of the mesh. @@ -47,11 +54,6 @@ MED_CELL, MED_FACE or MED_EDGE). */ - -namespace MEDMEM { - - class MESH; - class MEDMEM_EXPORT SUPPORT : public RCBASE { protected: @@ -173,7 +175,6 @@ public: SUPPORT& operator=(const SUPPORT &support); bool operator == (const SUPPORT &support) const; bool deepCompare(const SUPPORT &support) const; - // function to set all value when SUPPORT was created by MedMedDriver without all MESH information !!! Change with new API ! void update(); inline void setName(string Name); @@ -186,7 +187,7 @@ public: inline void setNumberOfGeometricType(int NumberOfGeometricType); inline void setGeometricType(const MED_EN::medGeometryElement *GeometricType); inline void setNumberOfElements(const int *NumberOfElements); - inline void setTotalNumberOfElements(int TotalNumberOfElements); + //inline void setTotalNumberOfElements(int TotalNumberOfElements); inline void setNumber(MEDSKYLINEARRAY * Number); inline void setNumber(const int * index, const int* value, bool shallowCopy=false); @@ -210,7 +211,7 @@ public: void blending(SUPPORT * mySupport) throw (MEDEXCEPTION) ; - // Les numéros d'entités dans les profils doivent être croissant + // Les numéros d'entités dans les profils doivent être croissant // pour respecter la norme MED void setpartial(string Description, int NumberOfGeometricType, int TotalNumberOfEntity, MED_EN::medGeometryElement *GeometricType, @@ -221,8 +222,8 @@ public: void setpartial_fromfile(MEDSKYLINEARRAY * number, bool shallowCopy=false) throw (MEDEXCEPTION); - // Si les noms de profils ne sont pas positionnés, les profils ne seront - // pas écrits par MEDFICHIER. + // Si les noms de profils ne sont pas positionnés, les profils ne seront + // pas écrits par MEDFICHIER. void setProfilNames(vector<string> profilNames) throw (MEDEXCEPTION); //string getProfilName(const MED_EN::medGeometryElement GeometricType) const throw (MEDEXCEPTION); vector<string> getProfilNames() const throw (MEDEXCEPTION); @@ -249,17 +250,23 @@ protected: // Methodes Inline // _____________________ +/*!\if MEDMEM_ug +\addtogroup SUPPORT_query +@{ +\endif +*/ + /*! This method returns the number of all elements of the type GeometricType. If isOnAllElements is false, it returns the number of elements in the - support else it returns number of elements in the mesh. + support otherwise it returns number of elements in the mesh. Example : number of MED_TRIA3 or MED_ALL_ELEMENTS elements - in entity of support. + in support. Note : If SUPPORT is defined on MED_NODE, use MED_ALL_ELEMENTS as - medGeometryElement GeometricType and it will returns the number + medGeometryElement GeometricType and it will return the number of nodes in the support (or in the mesh). */ //----------------------------------------------------------------------------- @@ -274,6 +281,8 @@ inline int SUPPORT::getNumberOfElements(MED_EN::medGeometryElement GeometricType return _numberOfElements[i]; throw MEDEXCEPTION("Support::getNumberOfElements : Geometric type not found !") ; } + + /*! Returns the total number of elements in the support. */ //----------------------------------------------------------------------------- inline const int * SUPPORT::getNumberOfElements() const throw (MEDEXCEPTION) { //----------------------------------------------------------------------------- @@ -358,7 +367,9 @@ inline const int * SUPPORT::getNumberIndex() const throw MEDEXCEPTION("Support::getNumberIndex : Not defined, support is on all entity !") ; return _number->getIndex() ; } - +/*! \if MEDMEM_ug +@} +\endif */ /*! set the attribute _name to Name */ //-------------------------------------- @@ -390,10 +401,17 @@ inline void SUPPORT::setMeshName(const string & meshName) _meshName=meshName; } -/*! set the attribute _isOnAllElts to All - Even if _isonAllElts is true, geometric types definning the FIELD's SUPPORT + /*! \if MEDMEM_ug +\addtogroup SUPPORT_creation +@{ +\endif + */ + +/*! Creates a support on all elements of the type specified in the constructor. + + Even if _isonAllElts is true, geometric types defining the FIELD's SUPPORT must be read from the SUPPORT not from the associated MESH (the geometric - types definning the FIELD's SUPPORT may be a subset of the geometric types + types defining the FIELD's SUPPORT may be a subset of the geometric types defined in the MESH even if for each SUPPORT geometric type all MESH entities are used). */ @@ -403,6 +421,7 @@ inline void SUPPORT::setAll(bool All) { _isOnAllElts=All; } + /*! \if MEDMEM_ug @} \endif */ /*! set the attribute _entity to Entity */ //------------------------------------------ @@ -439,7 +458,7 @@ inline void SUPPORT::setGeometricType(const MED_EN::medGeometryElement *Geometri for (int itype=0; itype < _numberOfGeometricType; itype++) { ostringstream typestr; - typestr<<_name<<"_type"<<itype; + typestr<<_name<<"_type"<<_geometricType[itype]; prof_names[itype]=typestr.str(); } _profilNames=prof_names; @@ -467,17 +486,21 @@ inline void SUPPORT::setNumberOfElements(const int *NumberOfElements) /*! set the attribute _totalNumberOfElements to TotalNumberOfElements */ //-------------------------------------------------------------------- -inline void SUPPORT::setTotalNumberOfElements(int TotalNumberOfElements) +//inline void SUPPORT::setTotalNumberOfElements(int TotalNumberOfElements) //-------------------------------------------------------------------- -{ - _totalNumberOfElements=TotalNumberOfElements; -} +//{ +// _totalNumberOfElements=TotalNumberOfElements; +//} /*! set the attribute _number to Number */ //--------------------------------------------------- inline void SUPPORT::setNumber(MEDSKYLINEARRAY * Number) //--------------------------------------------------- { + const char * LOC = "SUPPORT::setNumber(MEDSKYLINEARRAY * Number)"; + if ( _isOnAllElts ) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Support is on all elements")) ; + if (_number != NULL) delete _number ; _number=Number; } diff --git a/src/MEDMEM/MEDMEM_Tags.hxx b/src/MEDMEM/MEDMEM_Tags.hxx index 69644dddf..0bf50fa44 100644 --- a/src/MEDMEM/MEDMEM_Tags.hxx +++ b/src/MEDMEM/MEDMEM_Tags.hxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #ifndef MEDMEM_TAGS_HXX #define MEDMEM_TAGS_HXX diff --git a/src/MEDMEM/MEDMEM_TopLevel.cxx b/src/MEDMEM/MEDMEM_TopLevel.cxx index 5d8e96091..8407f1811 100644 --- a/src/MEDMEM/MEDMEM_TopLevel.cxx +++ b/src/MEDMEM/MEDMEM_TopLevel.cxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #include "MEDMEM_TopLevel.hxx" #include "MEDMEM_Med.hxx" #include "MEDMEM_Mesh.hxx" @@ -28,34 +31,34 @@ using namespace MEDMEM; MED *::MEDMEM::readMedInFile(const std::string& fileName) throw(MEDEXCEPTION) { - MED *myMedObj=new MED; - driverTypes type=DRIVERFACTORY::deduceDriverTypeFromFileName(fileName); - int id=myMedObj->addDriver(type,fileName,MED_REMP); + MED *myMedObj = new MED; + driverTypes type = DRIVERFACTORY::deduceDriverTypeFromFileName(fileName); + int id = myMedObj->addDriver(type,fileName,RDWR); myMedObj->read(id); return myMedObj; } MESH *::MEDMEM::readMeshInFile(const std::string& fileName, const std::string& meshName) { - MESH *mesh=new MESH; - driverTypes type=DRIVERFACTORY::deduceDriverTypeFromFileName(fileName); - int id=mesh->addDriver(type,fileName,mesh->getName(),MED_REMP); + MESH *mesh = new MESH; + driverTypes type = DRIVERFACTORY::deduceDriverTypeFromFileName(fileName); + int id = mesh->addDriver(type,fileName,meshName,RDWR); mesh->read(id); return mesh; } void ::MEDMEM::writeMedToFile(const MED *medObj, const std::string& fileName) { - MED *medObjNoC=(MED *)medObj;//MED::write should be a const method ... As it's not the case - driverTypes type=DRIVERFACTORY::deduceDriverTypeFromFileName(fileName); - int id=medObjNoC->addDriver(type,fileName,MED_REMP); + MED *medObjNoC = (MED *)medObj;//MED::write should be a const method ... As it's not the case + driverTypes type = DRIVERFACTORY::deduceDriverTypeFromFileName(fileName); + int id = medObjNoC->addDriver(type,fileName,RDWR); medObjNoC->write(id); } void ::MEDMEM::writeMeshToFile(const MESH *meshObj, const std::string& fileName) { - MESH *meshObjNoC=(MESH *)meshObj;//MED::write should be a const method ... As it's not the case - driverTypes type=DRIVERFACTORY::deduceDriverTypeFromFileName(fileName); - int id=meshObjNoC->addDriver(type,fileName,meshObjNoC->getName(),MED_REMP); + MESH *meshObjNoC = (MESH *)meshObj;//MED::write should be a const method ... As it's not the case + driverTypes type = DRIVERFACTORY::deduceDriverTypeFromFileName(fileName); + int id = meshObjNoC->addDriver(type,fileName,meshObjNoC->getName(),RDWR); meshObjNoC->write(id); } diff --git a/src/MEDMEM/MEDMEM_TopLevel.hxx b/src/MEDMEM/MEDMEM_TopLevel.hxx index 164ef865d..1a55636fe 100644 --- a/src/MEDMEM/MEDMEM_TopLevel.hxx +++ b/src/MEDMEM/MEDMEM_TopLevel.hxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #ifndef __MEDMEM_TOPLEVEL_HXX__ #define __MEDMEM_TOPLEVEL_HXX__ diff --git a/src/MEDMEM/MEDMEM_TypeMeshDriver.cxx b/src/MEDMEM/MEDMEM_TypeMeshDriver.cxx index a3aa6c4aa..989a2c2eb 100644 --- a/src/MEDMEM/MEDMEM_TypeMeshDriver.cxx +++ b/src/MEDMEM/MEDMEM_TypeMeshDriver.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_TypeMeshDriver.hxx" #include "MEDMEM_DriversDef.hxx" @@ -66,7 +68,7 @@ void TYPE_MESH_DRIVER::open() throw (MEDEXCEPTION) { const char * LOC = "TYPE_MESH_DRIVER::open()" ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // if (_medIdt > 0) // _status = MED_OPENED; @@ -76,14 +78,14 @@ void TYPE_MESH_DRIVER::open() // throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Could not open file "<<_fileName<<" in mode "<<_accessMode)); // } - END_OF(LOC); + END_OF_MED(LOC); } void TYPE_MESH_DRIVER::close() throw (MEDEXCEPTION) { const char * LOC = "TYPE_MESH_DRIVER::close() " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // int err = 0; // if ( _status == MED_OPENED) { @@ -98,7 +100,7 @@ void TYPE_MESH_DRIVER::close() // _medIdt = MED_INVALID; // } - END_OF(LOC); + END_OF_MED(LOC); } void TYPE_MESH_DRIVER::setMeshName(const string & meshName) { _meshName = meshName; }; @@ -115,7 +117,7 @@ TYPE_MESH_RDONLY_DRIVER::TYPE_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh): TYPE_MESH_DRIVER(fileName,ptrMesh,MED_RDONLY) { - MESSAGE("TYPE_MESH_RDONLY_DRIVER::TYPE_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); + MESSAGE_MED("TYPE_MESH_RDONLY_DRIVER::TYPE_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); } TYPE_MESH_RDONLY_DRIVER::TYPE_MESH_RDONLY_DRIVER(const TYPE_MESH_RDONLY_DRIVER & driver): @@ -125,7 +127,7 @@ TYPE_MESH_RDONLY_DRIVER::TYPE_MESH_RDONLY_DRIVER(const TYPE_MESH_RDONLY_DRIVER & TYPE_MESH_RDONLY_DRIVER::~TYPE_MESH_RDONLY_DRIVER() { - //MESSAGE("TYPE_MESH_RDONLY_DRIVER::~TYPE_MESH_RDONLY_DRIVER() has been destroyed"); + //MESSAGE_MED("TYPE_MESH_RDONLY_DRIVER::~TYPE_MESH_RDONLY_DRIVER() has been destroyed"); } GENDRIVER * TYPE_MESH_RDONLY_DRIVER::copy(void) const @@ -137,7 +139,7 @@ void TYPE_MESH_RDONLY_DRIVER::read(void) throw (MEDEXCEPTION) { const char * LOC = "TYPE_MESH_RDONLY_DRIVER::read() : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if (_status!=MED_OPENED) throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "The _idt of file " << _fileName << " is : " << " (the file is not opened)." )) ; @@ -145,7 +147,7 @@ void TYPE_MESH_RDONLY_DRIVER::read(void) _ptrMesh->_name = _meshName; - END_OF(LOC); + END_OF_MED(LOC); } void TYPE_MESH_RDONLY_DRIVER::write( void ) const @@ -165,7 +167,7 @@ TYPE_MESH_WRONLY_DRIVER::TYPE_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh): TYPE_MESH_DRIVER(fileName,ptrMesh,MED_WRONLY) { - MESSAGE("TYPE_MESH_WRONLY_DRIVER::TYPE_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); + MESSAGE_MED("TYPE_MESH_WRONLY_DRIVER::TYPE_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); } TYPE_MESH_WRONLY_DRIVER::TYPE_MESH_WRONLY_DRIVER(const TYPE_MESH_WRONLY_DRIVER & driver): @@ -175,7 +177,7 @@ TYPE_MESH_WRONLY_DRIVER::TYPE_MESH_WRONLY_DRIVER(const TYPE_MESH_WRONLY_DRIVER & TYPE_MESH_WRONLY_DRIVER::~TYPE_MESH_WRONLY_DRIVER() { - //MESSAGE("TYPE_MESH_WRONLY_DRIVER::TYPE_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed"); + //MESSAGE_MED("TYPE_MESH_WRONLY_DRIVER::TYPE_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed"); } GENDRIVER * TYPE_MESH_WRONLY_DRIVER::copy(void) const @@ -193,11 +195,11 @@ void TYPE_MESH_WRONLY_DRIVER::write(void) const throw (MEDEXCEPTION) { const char * LOC = "void TYPE_MESH_WRONLY_DRIVER::write(void) const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<< "Write Driver isn\'t implemented")); - END_OF(LOC); + END_OF_MED(LOC); } @@ -212,7 +214,7 @@ TYPE_MESH_RDWR_DRIVER::TYPE_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh): TYPE_MESH_DRIVER(fileName,ptrMesh,MED_RDWR) { - MESSAGE("TYPE_MESH_RDWR_DRIVER::TYPE_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); + MESSAGE_MED("TYPE_MESH_RDWR_DRIVER::TYPE_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been created"); } TYPE_MESH_RDWR_DRIVER::TYPE_MESH_RDWR_DRIVER(const TYPE_MESH_RDWR_DRIVER & driver): @@ -221,7 +223,7 @@ TYPE_MESH_RDWR_DRIVER::TYPE_MESH_RDWR_DRIVER(const TYPE_MESH_RDWR_DRIVER & drive } TYPE_MESH_RDWR_DRIVER::~TYPE_MESH_RDWR_DRIVER() { - //MESSAGE("TYPE_MESH_RDWR_DRIVER::TYPE_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed"); + //MESSAGE_MED("TYPE_MESH_RDWR_DRIVER::TYPE_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh) has been destroyed"); } GENDRIVER * TYPE_MESH_RDWR_DRIVER::copy(void) const diff --git a/src/MEDMEM/MEDMEM_TypeMeshDriver.hxx b/src/MEDMEM/MEDMEM_TypeMeshDriver.hxx index cd5267e2c..85ffd48e0 100644 --- a/src/MEDMEM/MEDMEM_TypeMeshDriver.hxx +++ b/src/MEDMEM/MEDMEM_TypeMeshDriver.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef TYPE_MESH_DRIVER_HXX #define TYPE_MESH_DRIVER_HXX diff --git a/src/MEDMEM/MEDMEM_Unit.cxx b/src/MEDMEM/MEDMEM_Unit.cxx index e0028d11b..f0cf98d52 100644 --- a/src/MEDMEM/MEDMEM_Unit.cxx +++ b/src/MEDMEM/MEDMEM_Unit.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // /* File MEDMEM_Unit.cxx @@ -28,19 +30,19 @@ using namespace std; using namespace MEDMEM; UNIT::UNIT():_name(""),_description(""),_masse(0),_length(0),_time(0),_temperature(0),_matterQuantity(0),_currentStrength(0),_lightIntensity(0) { - MESSAGE("UNIT()"); + MESSAGE_MED("UNIT()"); }; UNIT::UNIT(string Name, string Description):_name(Name),_description(Description),_masse(0),_length(0),_time(0),_temperature(0),_matterQuantity(0),_currentStrength(0),_lightIntensity(0) { - MESSAGE("UNIT(string Name, string Description)"); + MESSAGE_MED("UNIT(string Name, string Description)"); }; UNIT::~UNIT() { - MESSAGE("~UNIT()") ; + MESSAGE_MED("~UNIT()") ; }; UNIT & UNIT::operator=(const UNIT &unit) { - MESSAGE("UNIT::operateur=") ; + MESSAGE_MED("UNIT::operateur=") ; _name=unit._name ; _description=unit._description ; _masse=unit._masse ; diff --git a/src/MEDMEM/MEDMEM_Unit.hxx b/src/MEDMEM/MEDMEM_Unit.hxx index 4c2d09c8a..0ca220f83 100644 --- a/src/MEDMEM/MEDMEM_Unit.hxx +++ b/src/MEDMEM/MEDMEM_Unit.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // /* File Unit.hxx @@ -84,41 +86,41 @@ public: inline void UNIT::setName(string Name) { _name = Name ; -}; +} inline void UNIT::setDescription(string Description) { _description = Description ; -}; +} inline void UNIT::setMasse(int Masse) { _masse=Masse ; -}; +} inline void UNIT::setLength(int Length) { _length=Length ; -}; +} inline void UNIT::setTime(int Time) { _time=Time ; -}; +} inline void UNIT::setTemperature(int Temperature) { _temperature=Temperature ; -}; +} inline void UNIT::setMatterQuantity(int MatterQuantity) { _matterQuantity=MatterQuantity ; -}; +} inline void UNIT::setCurrentStrength(int CurrentStrength) { _currentStrength=CurrentStrength ; -}; +} inline void UNIT::setLightIntensity(int LightIntensity) { _lightIntensity=LightIntensity ; -}; +} -inline string UNIT::getName() const { return _name ; } ; -inline string UNIT::getDescription() const { return _description ; } ; -inline int UNIT::getMasse() const { return _masse ; } ; -inline int UNIT::getLength() const { return _length ; } ; -inline int UNIT::getTime() const { return _time ; } ; -inline int UNIT::getTemperature() const { return _temperature ; } ; -inline int UNIT::getMatterQuantity() const { return _matterQuantity ; } ; -inline int UNIT::getCurrentStrength() const { return _currentStrength ; } ; -inline int UNIT::getLightIntensity() const { return _lightIntensity ; } ; +inline string UNIT::getName() const { return _name ; } +inline string UNIT::getDescription() const { return _description ; } +inline int UNIT::getMasse() const { return _masse ; } +inline int UNIT::getLength() const { return _length ; } +inline int UNIT::getTime() const { return _time ; } +inline int UNIT::getTemperature() const { return _temperature ; } +inline int UNIT::getMatterQuantity() const { return _matterQuantity ; } +inline int UNIT::getCurrentStrength() const { return _currentStrength ; } +inline int UNIT::getLightIntensity() const { return _lightIntensity ; } }//End namespace MEDMEM #endif /* UNIT_HXX */ diff --git a/src/MEDMEM/MEDMEM_Utilities.hxx b/src/MEDMEM/MEDMEM_Utilities.hxx index dff5421e6..ff8b9d2d6 100644 --- a/src/MEDMEM/MEDMEM_Utilities.hxx +++ b/src/MEDMEM/MEDMEM_Utilities.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef __MEDMEM_UTILITIES #define __MEDMEM_UTILITIES @@ -23,12 +25,12 @@ // standart Linux/Unix functions #include <string> -#ifndef WNT - #include <libgen.h> +#ifndef WIN32 +#include <libgen.h> #endif -inline std::string getBaseName( std::string dataname ) { +inline std::string getBaseName( const std::string& dataname ) { std::string aBaseName = ""; -#ifndef WNT +#ifndef WIN32 aBaseName = basename((char*)dataname.c_str()); #else for ( int i = dataname.size()-1; i >= 0; i-- ) { @@ -41,9 +43,9 @@ inline std::string getBaseName( std::string dataname ) { return aBaseName; } -inline std::string getDirName( std::string dataname ) { +inline std::string getDirName(const std::string& dataname ) { std::string aDirName = ""; -#ifndef WNT +#ifndef WIN32 aDirName = dirname((char*)dataname.c_str()); #else bool aFindLine = false; @@ -60,7 +62,15 @@ inline std::string getDirName( std::string dataname ) { return aDirName; } -#ifdef MED_WITHOUT_KERNEL +/*! +* \brief Make a name valid. So far, removes white spaces from name end +*/ +inline std::string healName(const std::string& name ) { + size_t last = name.size()-1; + while ( last >= 0 && isspace( name[last] )) + last--; + return name.substr( 0, last + 1 ); +} # include <cstdlib> # include <iostream> @@ -68,78 +78,75 @@ using namespace std; /* --- INFOS is always defined (without _DEBUG_): to be used for warnings, with release version --- */ -# define HEREWEARE {cout<<flush ; cerr << __FILE__ << " [" << __LINE__ << "] : " << flush ;} -# define INFOS(chain) {HEREWEARE ; cerr << chain << endl ;} -# define PYSCRIPT(chain) {cout<<flush ; cerr << "---PYSCRIPT--- " << chain << endl ;} +# define HEREWEARE_MED {cout<<flush ; cerr << __FILE__ << " [" << __LINE__ << "] : " << flush ;} +# define INFOS_MED(chain) {HEREWEARE_MED ; cerr << chain << endl ;} +# define PYSCRIPT_MED(chain) {cout<<flush ; cerr << "---PYSCRIPT--- " << chain << endl ;} /* --- To print date and time of compilation of current source on stdout --- */ # if defined ( __GNUC__ ) -# define COMPILER "g++" ; +# define COMPILER_MED "g++" ; # elif defined ( __sun ) -# define COMPILER "CC" ; +# define COMPILER_MED "CC" ; # elif defined ( __KCC ) -# define COMPILER "KCC" ; +# define COMPILER_MED "KCC" ; # elif defined ( __PGI ) -# define COMPILER "pgCC" ; +# define COMPILER_MED "pgCC" ; # else -# define COMPILER "undefined" ; +# define COMPILER_MED "undefined" ; # endif -# ifdef INFOS_COMPILATION -# undef INFOS_COMPILATION +# ifdef INFOS_COMPILATION_MED +# undef INFOS_COMPILATION_MED # endif -# define INFOS_COMPILATION {\ - cerr << flush;\ - cout << __FILE__ ;\ - cout << " [" << __LINE__ << "] : " ;\ - cout << "COMPILED with " << COMPILER ;\ - cout << ", " << __DATE__ ; \ - cout << " at " << __TIME__ << endl ;\ - cout << "\n\n" ;\ - cout << flush ;\ - } - -# ifdef _DEBUG_ - -/* --- the following MACROS are useful at debug time --- */ +# define INFOS_COMPILATION_MED {\ + cerr << flush;\ + cout << __FILE__ ;\ + cout << " [" << __LINE__ << "] : " ;\ + cout << "COMPILED with " << COMPILER_MED ;\ + cout << ", " << __DATE__ ; \ + cout << " at " << __TIME__ << endl ;\ + cout << "\n\n" ;\ + cout << flush ;\ +} -# define HERE {cout<<flush ; cerr << "- Trace " << __FILE__ << " [" << __LINE__ << "] : " << flush ;} -# define SCRUTE(var) {HERE ; cerr << #var << "=" << var << endl ;} -# define MESSAGE(chain) {HERE ; cerr << chain << endl ;} -# define INTERRUPTION(code) {HERE ; cerr << "INTERRUPTION return code= " << code << endl ; exit(code) ;} +#if ( defined(_DEBUG_) || defined(_DEBUG) ) && !defined(_NO_MED_TRACE_) -# ifndef ASSERT -# define ASSERT(condition) if (!(condition)){ HERE ; cerr << "CONDITION " << #condition << " NOT VERIFIED"<< endl ; INTERRUPTION(1) ;} -# endif /* ASSERT */ +/* --- the following MACROS are useful at debug time --- */ -#define REPERE {cout<<flush ; cerr << " --------------" << endl << flush ;} -#define BEGIN_OF(chain) {REPERE ; HERE ; cerr << "Begin of: " << chain << endl ; REPERE ; } -#define END_OF(chain) {REPERE ; HERE ; cerr << "Normal end of: " << chain << endl ; REPERE ; } +# define HERE_MED {cout<<flush ; cerr << "- Trace " << __FILE__ << " [" << __LINE__ << "] : " << flush ;} +# define SCRUTE_MED(var) {HERE_MED ; cerr << #var << "=" << var << endl ;} +# define MESSAGE_MED(chain) {HERE_MED ; cerr << chain << endl ;} +# define INTERRUPTION_MED(code) {HERE_MED ; cerr << "INTERRUPTION return code= " << code << endl ; exit(code) ;} +# ifndef ASSERT_MED +# define ASSERT_MED(condition) if (!(condition)){ HERE_MED ; cerr << "CONDITION " << #condition << " NOT VERIFIED"<< endl ; INTERRUPTION_MED(1) ;} +# endif /* ASSERT_MED */ +#define REPERE_MED {cout<<flush ; cerr << " --------------" << endl << flush ;} +#define __PREFIX_MED const char* __LOC_MED +#define PREFIX_MED __LOC_MED +#define BEGIN_OF_MED(chain) __PREFIX_MED = chain; {REPERE_MED ; HERE_MED ; cerr << "Begin of: " << PREFIX_MED << endl ; REPERE_MED ; } +#define END_OF_MED(chain) {REPERE_MED ; HERE_MED ; cerr << "Normal end of: " << chain << endl ; REPERE_MED ; } # else /* ifdef _DEBUG_*/ -# define HERE -# define SCRUTE(var) {} -# define MESSAGE(chain) {} -# define INTERRUPTION(code) {} -# ifndef ASSERT -# define ASSERT(condition) {} +# define HERE_MED +# define SCRUTE_MED(var) {} +# define MESSAGE_MED(chain) {} +# define INTERRUPTION_MED(code) {} + +# ifndef ASSERT_MED +# define ASSERT_MED(condition) {} # endif /* ASSERT */ -#define REPERE -#define BEGIN_OF(chain) {} -#define END_OF(chain) {} +# define REPERE_MED +# define BEGIN_OF_MED(chain) const char* __LOC_MED; {__LOC_MED=chain;} +# define END_OF_MED(chain) const char* __LOC_END_MED; {__LOC_END_MED=chain;} -#endif -#else -// #ifdef _SALOME +#endif /* ifdef _DEBUG_*/ -# include <utilities.h> -#endif #endif diff --git a/src/MEDMEM/MEDMEM_VtkFieldDriver.hxx b/src/MEDMEM/MEDMEM_VtkFieldDriver.hxx index c937a3071..f22151ed5 100644 --- a/src/MEDMEM/MEDMEM_VtkFieldDriver.hxx +++ b/src/MEDMEM/MEDMEM_VtkFieldDriver.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef VTK_FIELD_DRIVER_HXX #define VTK_FIELD_DRIVER_HXX @@ -73,11 +75,11 @@ public : _fieldNum(MED_INVALID) { const char * LOC = "VTK_FIELD_DRIVER::VTK_FIELD_DRIVER() "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); _vtkFile = new ofstream(); - END_OF(LOC); + END_OF_MED(LOC); } /*! Constructor. @@ -85,16 +87,16 @@ public : template <class INTERLACING_TAG> VTK_FIELD_DRIVER(const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField): - GENDRIVER(fileName,MED_EN::MED_WRONLY), + GENDRIVER(fileName, MED_EN::WRONLY, VTK_DRIVER), _ptrField((FIELD<T> *) ptrField), _fieldName(fileName),_fieldNum(MED_INVALID) { - const char * LOC = "VTK_FIELD_DRIVER::VTK_FIELD_DRIVER(const string & fileName, FIELD<T> * ptrField) "; - BEGIN_OF(LOC); + const char* LOC = "VTK_FIELD_DRIVER::VTK_FIELD_DRIVER(const string & fileName, FIELD<T> * ptrField) "; + BEGIN_OF_MED(LOC); _vtkFile = new ofstream(); - END_OF(LOC); + END_OF_MED(LOC); } /*! @@ -115,26 +117,26 @@ public : */ ~VTK_FIELD_DRIVER() { - const char * LOC ="VTK_FIELD_DRIVER::~VTK_FIELD_DRIVER()"; - BEGIN_OF(LOC); + const char* LOC = "VTK_FIELD_DRIVER::~VTK_FIELD_DRIVER()"; + BEGIN_OF_MED(LOC); - close(); + close(); - SCRUTE(_vtkFile); + SCRUTE_MED(_vtkFile); - delete _vtkFile ; + delete _vtkFile ; - SCRUTE(_vtkFile); + SCRUTE_MED(_vtkFile); - END_OF(LOC); + END_OF_MED(LOC); } void openConst() const throw (MEDEXCEPTION) { const char * LOC = "VTK_FIELD_DRIVER::openConst()" ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); - MESSAGE(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode); + MESSAGE_MED(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode); if ( _fileName == "" ) throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) @@ -149,8 +151,8 @@ public : // else - SCRUTE((*_vtkFile).is_open()); - SCRUTE(_vtkFile); + SCRUTE_MED((*_vtkFile).is_open()); + SCRUTE_MED(_vtkFile); @@ -158,15 +160,15 @@ public : throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file " << _fileName) ); - END_OF(LOC); + END_OF_MED(LOC); } void openConstAppend() const throw (MEDEXCEPTION) { const char * LOC = "VTK_FIELD_DRIVER::openConstAppend()" ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); - MESSAGE(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode); + MESSAGE_MED(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode); if ( _fileName == "" ) throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) @@ -174,16 +176,16 @@ public : ) ); - SCRUTE((*_vtkFile).is_open()); + SCRUTE_MED((*_vtkFile).is_open()); if (!(*_vtkFile).is_open()) { - MESSAGE(LOC<<"The file is already close and it is opened with the right option"); + MESSAGE_MED(LOC<<"The file is already close and it is opened with the right option"); (*_vtkFile).open(_fileName.c_str(), ofstream::out | ofstream::app) ; } else { - MESSAGE(LOC<<"The file is still open, it is closed to make sure that it will be opened with the right option"); + MESSAGE_MED(LOC<<"The file is still open, it is closed to make sure that it will be opened with the right option"); // closeConst(); @@ -196,8 +198,8 @@ public : // else - SCRUTE((*_vtkFile).is_open()); - SCRUTE(_vtkFile); + SCRUTE_MED((*_vtkFile).is_open()); + SCRUTE_MED(_vtkFile); @@ -205,7 +207,7 @@ public : throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file " << _fileName) ); - END_OF(LOC); + END_OF_MED(LOC); } void open() throw (MEDEXCEPTION) @@ -221,10 +223,10 @@ public : void closeConst() const throw (MEDEXCEPTION) { const char * LOC = "VTK_FIELD_DRIVER::closeConst() " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); - SCRUTE(_vtkFile); - SCRUTE(*_vtkFile); + SCRUTE_MED(_vtkFile); + SCRUTE_MED(*_vtkFile); if ((*_vtkFile).is_open()) @@ -234,15 +236,16 @@ public : // _status = MED_CLOSED ; // else - SCRUTE(_vtkFile); - SCRUTE(*_vtkFile); + SCRUTE_MED(_vtkFile); + SCRUTE_MED(*_vtkFile); - if (!(*_vtkFile)) + if ( (*_vtkFile) && _vtkFile->is_open() ) + //if (!(*_vtkFile)) throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not close file " << _fileName) ); - END_OF(LOC); + END_OF_MED(LOC); } void close() { @@ -318,12 +321,14 @@ template <class T> void VTK_FIELD_DRIVER<T>::write(void) const throw (MEDEXCEPTION) { const char * LOC = "VTK_FIELD_DRIVER::write(void) const " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // we get the Support and its associated Mesh const SUPPORT * supportField = _ptrField->getSupport(); MESH * meshField = supportField->getMesh(); + if (! meshField ) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": mesh was not read before writing")) ; // Well we must open vtk file first, because there are // no other driver than MED for VTK that do it ! @@ -586,8 +591,8 @@ template <class T> void VTK_FIELD_DRIVER<T>::write(void) const MED_EN::med_type_champ fieldType = _ptrField->getValueType() ; - SCRUTE(name.str()); - SCRUTE(fieldType); + SCRUTE_MED(name.str()); + SCRUTE_MED(fieldType); switch (fieldType) { @@ -645,19 +650,21 @@ template <class T> void VTK_FIELD_DRIVER<T>::write(void) const if ( _ptrField->getInterlacingType() != MED_EN::MED_NO_INTERLACE ) delete tmpArray; - END_OF(LOC); + END_OF_MED(LOC); } template <class T> void VTK_FIELD_DRIVER<T>::writeAppend(void) const throw (MEDEXCEPTION) { const char * LOC = "VTK_FIELD_DRIVER::writeAppend(void) const " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // we get the Support and its associated Mesh const SUPPORT * supportField = _ptrField->getSupport(); MESH * meshField = supportField->getMesh(); + if (! meshField ) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": mesh was not read before writing")) ; // Well we must open vtk file first, because there are // no other driver than MED for VTK that do it ! @@ -695,8 +702,8 @@ template <class T> void VTK_FIELD_DRIVER<T>::writeAppend(void) const MED_EN::med_type_champ fieldType = _ptrField->getValueType() ; - SCRUTE(name.str()); - SCRUTE(fieldType); + SCRUTE_MED(name.str()); + SCRUTE_MED(fieldType); switch (fieldType) { case MED_EN::MED_INT32 : @@ -752,7 +759,7 @@ template <class T> void VTK_FIELD_DRIVER<T>::writeAppend(void) const if ( _ptrField->getInterlacingType() != MED_EN::MED_NO_INTERLACE ) delete tmpArray; - END_OF(LOC); + END_OF_MED(LOC); } }//End namespace MEDMEM diff --git a/src/MEDMEM/MEDMEM_VtkMedDriver.cxx b/src/MEDMEM/MEDMEM_VtkMedDriver.cxx index 1b0428dda..72f72b87e 100644 --- a/src/MEDMEM/MEDMEM_VtkMedDriver.cxx +++ b/src/MEDMEM/MEDMEM_VtkMedDriver.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_VtkMedDriver.hxx" @@ -32,7 +34,7 @@ using namespace std; using namespace MEDMEM; using namespace MED_EN; -VTK_MED_DRIVER::VTK_MED_DRIVER(): GENDRIVER(), +VTK_MED_DRIVER::VTK_MED_DRIVER(): GENDRIVER(VTK_DRIVER), _ptrMed((MED * const)MED_NULL) { _vtkFile = new ofstream(); @@ -42,7 +44,7 @@ VTK_MED_DRIVER::VTK_MED_DRIVER(): GENDRIVER(), VTK_MED_DRIVER::VTK_MED_DRIVER(const string & fileName, MED * const ptrMed): - GENDRIVER(fileName,MED_EN::MED_RDWR), _ptrMed(ptrMed) + GENDRIVER(fileName, MED_EN::RDWR, VTK_DRIVER), _ptrMed(ptrMed) { _vtkFile = new ofstream(); } @@ -59,12 +61,12 @@ VTK_MED_DRIVER::VTK_MED_DRIVER(const VTK_MED_DRIVER & driver): VTK_MED_DRIVER::~VTK_MED_DRIVER() { - const char * LOC ="VTK_MED_DRIVER::~VTK_MED_DRIVER()"; - BEGIN_OF(LOC); + const char* LOC = "VTK_MED_DRIVER::~VTK_MED_DRIVER()"; + BEGIN_OF_MED(LOC); delete _vtkFile ; - END_OF(LOC); + END_OF_MED(LOC); } GENDRIVER * VTK_MED_DRIVER::copy() const @@ -77,7 +79,7 @@ GENDRIVER * VTK_MED_DRIVER::copy() const void VTK_MED_DRIVER::openConst() const { const char * LOC ="VTK_MED_DRIVER::open() : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); if ( _fileName == "" ) throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) @@ -94,7 +96,7 @@ void VTK_MED_DRIVER::openConst() const { throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file " << _fileName) ); - END_OF(LOC); + END_OF_MED(LOC); } void VTK_MED_DRIVER::open() { @@ -103,8 +105,8 @@ void VTK_MED_DRIVER::open() { void VTK_MED_DRIVER::closeConst() const { - const char * LOC = "VTK_MED_DRIVER::close() : "; - BEGIN_OF(LOC); + const char* LOC = "VTK_MED_DRIVER::close() : "; + BEGIN_OF_MED(LOC); (*_vtkFile).close(); @@ -115,7 +117,7 @@ void VTK_MED_DRIVER::closeConst() const { // throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not close file " // << _fileName) // ); - END_OF(LOC); + END_OF_MED(LOC); } void VTK_MED_DRIVER::close() { @@ -123,10 +125,10 @@ void VTK_MED_DRIVER::close() { } -void VTK_MED_DRIVER::write() const { - - const char * LOC = "VTK_MED_DRIVER::write() : "; - BEGIN_OF(LOC); +void VTK_MED_DRIVER::write() const +{ + const char* LOC = "VTK_MED_DRIVER::write() : "; + BEGIN_OF_MED(LOC); // Well we must open vtk file first, because there are // no other driver than MED for VTK that do it ! @@ -171,7 +173,7 @@ void VTK_MED_DRIVER::write() const { name << myField->getName() << "_" << dt << "_" << it ; writeField(myField,name.str()) ; } else - MESSAGE(LOC << "Could not write field "<<myField->getName()<<" which is not on all nodes !"); + MESSAGE_MED(PREFIX_MED << "Could not write field "<<myField->getName()<<" which is not on all nodes !"); } } } @@ -192,8 +194,9 @@ void VTK_MED_DRIVER::write() const { ostringstream name ; name << myField->getName() << "_" << dt << "_" << it ; writeField(myField,name.str()) ; - } else - MESSAGE(LOC << "Could not write field "<<myField->getName()<<" which is not on all cells !"); + } + else + MESSAGE_MED(PREFIX_MED << "Could not write field "<<myField->getName()<<" which is not on all cells !"); } } } @@ -204,13 +207,13 @@ void VTK_MED_DRIVER::write() const { // no other driver than MED for VTK that do it ! // closeConst() ; - END_OF(LOC); + END_OF_MED(LOC); } void VTK_MED_DRIVER::writeMesh(MESH * myMesh) const { const char * LOC = "VTK_MED_DRIVER::writeMesh() : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); (*_vtkFile) << "DATASET UNSTRUCTURED_GRID" << endl ; // put points (all point are in 3D, so if we are in 1D or 2D, we complete by zero ! @@ -441,13 +444,13 @@ void VTK_MED_DRIVER::writeMesh(MESH * myMesh) const { return ; - END_OF(LOC); + END_OF_MED(LOC); } -void VTK_MED_DRIVER::writeField(FIELD_ * myField,string name) const { - - const char * LOC = "VTK_MED_DRIVER::writeField() : "; - BEGIN_OF(LOC); +void VTK_MED_DRIVER::writeField(FIELD_ * myField,string name) const +{ + const char* LOC = "VTK_MED_DRIVER::writeField() : "; + BEGIN_OF_MED(LOC); typedef MEDMEM_ArrayInterface<int,NoInterlace,NoGauss>::Array ArrayIntNo; typedef MEDMEM_ArrayInterface<double,NoInterlace,NoGauss>::Array ArrayDoubleNo; @@ -456,19 +459,21 @@ void VTK_MED_DRIVER::writeField(FIELD_ * myField,string name) const { int NumberOfComponents = myField->getNumberOfComponents() ; med_type_champ type = myField->getValueType() ; - SCRUTE(name); - SCRUTE(type); + SCRUTE_MED(name); + SCRUTE_MED(type); switch (type) { case MED_INT32 : { - MESSAGE("MED_INT32"); + MESSAGE_MED("MED_INT32"); if (NumberOfComponents==3) { (*_vtkFile) << "VECTORS " << name << " int" << endl ; - } else if (NumberOfComponents<=4) { + } + else if (NumberOfComponents<=4) { (*_vtkFile) << "SCALARS " << name << " int " << NumberOfComponents << endl ; (*_vtkFile) << "LOOKUP_TABLE default" << endl ; - } else { - MESSAGE(LOC << "Could not write field "<<myField->getName()<<" there are more than 4 components !"); + } + else { + MESSAGE_MED(PREFIX_MED << "Could not write field "<<myField->getName()<<" there are more than 4 components !"); return ; } @@ -501,14 +506,16 @@ void VTK_MED_DRIVER::writeField(FIELD_ * myField,string name) const { break ; } case MED_REEL64 : { - MESSAGE("MED_REEL64"); + MESSAGE_MED("MED_REEL64"); if (NumberOfComponents==3) { (*_vtkFile) << "VECTORS " << name << " float" << endl ; - } else if (NumberOfComponents<=4) { + } + else if (NumberOfComponents<=4) { (*_vtkFile) << "SCALARS " << name << " float " << NumberOfComponents << endl ; (*_vtkFile) << "LOOKUP_TABLE default" << endl ; - } else { - MESSAGE(LOC << "Could not write field "<<myField->getName()<<" there are more than 4 components !"); + } + else { + MESSAGE_MED(PREFIX_MED << "Could not write field "<<myField->getName()<<" there are more than 4 components !"); return ; } @@ -520,13 +527,15 @@ void VTK_MED_DRIVER::writeField(FIELD_ * myField,string name) const { ) ); value = myArray->getPtr(); - } else if ( myField->getInterlacingType() == MED_NO_INTERLACE_BY_TYPE ) { + } + else if ( myField->getInterlacingType() == MED_NO_INTERLACE_BY_TYPE ) { myArray = ArrayConvert2No( *( dynamic_cast< FIELD<double,NoInterlaceByType>* > (myField)->getArrayNoGauss() ) ); value = myArray->getPtr(); - } else { + } + else { value = ((FIELD<double>*)myField)->getValue() ; } @@ -541,16 +550,16 @@ void VTK_MED_DRIVER::writeField(FIELD_ * myField,string name) const { break ; } default : { - MESSAGE(LOC << "Could not write field "<<name<<" the type is not int or double !"); + MESSAGE_MED(PREFIX_MED << "Could not write field "<<name<<" the type is not int or double !"); } } - END_OF(LOC); + END_OF_MED(LOC); } void VTK_MED_DRIVER::writeSupport(SUPPORT * mySupport) const { - const char * LOC = "VTK_MED_DRIVER::writeSupport(SUPPORT *) : " ; - BEGIN_OF(LOC) ; - MESSAGE(LOC << "Not yet implemented, acting on the object " << *mySupport); - END_OF(LOC) ; + const char* LOC = "VTK_MED_DRIVER::writeSupport(SUPPORT *) : "; + BEGIN_OF_MED(LOC); + MESSAGE_MED(PREFIX_MED << "Not yet implemented, acting on the object " << *mySupport); + END_OF_MED(LOC); } diff --git a/src/MEDMEM/MEDMEM_VtkMedDriver.hxx b/src/MEDMEM/MEDMEM_VtkMedDriver.hxx index 82d0445e9..0b4eb1a61 100644 --- a/src/MEDMEM/MEDMEM_VtkMedDriver.hxx +++ b/src/MEDMEM/MEDMEM_VtkMedDriver.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef VTK_MED_DRIVER_HXX #define VTK_MED_DRIVER_HXX @@ -77,7 +79,7 @@ private : void writeField(FIELD_ * myField,string name) const ; }; -}; +} #endif /* VTK_MED_DRIVER_HXX */ diff --git a/src/MEDMEM/MEDMEM_VtkMeshDriver.cxx b/src/MEDMEM/MEDMEM_VtkMeshDriver.cxx index 0b7e57eb7..53f88f488 100644 --- a/src/MEDMEM/MEDMEM_VtkMeshDriver.cxx +++ b/src/MEDMEM/MEDMEM_VtkMeshDriver.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_VtkMeshDriver.hxx" @@ -37,7 +39,7 @@ using namespace MED_EN; #define MED_NULL NULL -VTK_MESH_DRIVER::VTK_MESH_DRIVER(): GENDRIVER(), +VTK_MESH_DRIVER::VTK_MESH_DRIVER(): GENDRIVER(VTK_DRIVER), _ptrMesh((MESH * const)MED_NULL) { _vtkFile = new ofstream(); @@ -47,10 +49,9 @@ VTK_MESH_DRIVER::VTK_MESH_DRIVER(): GENDRIVER(), VTK_MESH_DRIVER::VTK_MESH_DRIVER(const string & fileName, MESH * ptrMesh) : - GENDRIVER(fileName,MED_WRONLY), + GENDRIVER(fileName, WRONLY, VTK_DRIVER), _ptrMesh(ptrMesh) { - const char * LOC = "VTK_MESH_DRIVER::VTK_MESH_DRIVER(const string & fileName, MESH * ptrMesh) : " ; // Send an exception because a VTK_MESH_DRIVER object cannot be instantied // from a file and there is no read for that kind of driver @@ -58,7 +59,8 @@ VTK_MESH_DRIVER::VTK_MESH_DRIVER(const string & fileName, // throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "This driver is only used to write in VTK format So thie object can not be instantied using a file!")); // _ptrMesh->addDriver(*this); // OU RECUPERER L'ID. - MESSAGE(LOC << "WARNING this driver is only used to write in VTK format So the object can not be instantied using a file!"); + MESSAGE_MED("VTK_MESH_DRIVER::VTK_MESH_DRIVER(const string & fileName, MESH * ptrMesh) : " + << "WARNING this driver is only used to write in VTK format So the object can not be instantied using a file!"); _vtkFile = new ofstream(); } @@ -75,26 +77,26 @@ VTK_MESH_DRIVER::VTK_MESH_DRIVER(const VTK_MESH_DRIVER & driver): VTK_MESH_DRIVER::~VTK_MESH_DRIVER() { - const char * LOC ="VTK_MESH_DRIVER::~VTK_MESH_DRIVER()"; - BEGIN_OF(LOC); + const char* LOC = "VTK_MESH_DRIVER::~VTK_MESH_DRIVER()"; + BEGIN_OF_MED(LOC); close(); - SCRUTE(_vtkFile); + SCRUTE_MED(_vtkFile); delete _vtkFile ; - SCRUTE(_vtkFile); + SCRUTE_MED(_vtkFile); - END_OF(LOC); + END_OF_MED(LOC); } void VTK_MESH_DRIVER::openConst() const throw (MEDEXCEPTION) { const char * LOC = "VTK_MESH_DRIVER::openConst()" ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); - MESSAGE(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode); + MESSAGE_MED(LOC<<" : _fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode); if ( _fileName == "" ) throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) @@ -109,8 +111,8 @@ void VTK_MESH_DRIVER::openConst() const throw (MEDEXCEPTION) // else - SCRUTE((*_vtkFile).is_open()); - SCRUTE(_vtkFile); + SCRUTE_MED((*_vtkFile).is_open()); + SCRUTE_MED(_vtkFile); @@ -118,7 +120,7 @@ void VTK_MESH_DRIVER::openConst() const throw (MEDEXCEPTION) throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not open file " << _fileName) ); - END_OF(LOC); + END_OF_MED(LOC); } void VTK_MESH_DRIVER::open() { @@ -128,10 +130,10 @@ void VTK_MESH_DRIVER::open() { void VTK_MESH_DRIVER::closeConst() const throw (MEDEXCEPTION) { const char * LOC = "VTK_MESH_DRIVER::closeConst() " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); - SCRUTE(_vtkFile); - SCRUTE(*_vtkFile); + SCRUTE_MED(_vtkFile); + SCRUTE_MED(*_vtkFile); if ((*_vtkFile).is_open()) @@ -141,15 +143,16 @@ void VTK_MESH_DRIVER::closeConst() const throw (MEDEXCEPTION) // _status = MED_CLOSED ; // else - SCRUTE(_vtkFile); - SCRUTE(*_vtkFile); + SCRUTE_MED(_vtkFile); + SCRUTE_MED(*_vtkFile); + SCRUTE_MED(_vtkFile->is_open()); - if (!(*_vtkFile)) + if ( (*_vtkFile) && _vtkFile->is_open() ) throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "Could not close file " << _fileName) ); - END_OF(LOC); + END_OF_MED(LOC); } void VTK_MESH_DRIVER::close() { @@ -162,13 +165,13 @@ string VTK_MESH_DRIVER::getMeshName() const { return _meshName; }; void VTK_MESH_DRIVER::read(void) throw (MEDEXCEPTION) { const char * LOC = "VTK_MESH_DRIVER::read() : " ; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // Send an exception throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "This driver is only used to write in VTK format !")); - END_OF(LOC); + END_OF_MED(LOC); } @@ -176,13 +179,18 @@ void VTK_MESH_DRIVER::write(void) const throw (MEDEXCEPTION) { const char * LOC = "void VTK_MESH_DRIVER::write(void) const : "; - BEGIN_OF(LOC); + BEGIN_OF_MED(LOC); // Well we must open vtk file first, because there are // no other driver than MED for VTK that do it ! openConst(); + int SpaceDimension = _ptrMesh->getSpaceDimension() ; + int NumberOfNodes = _ptrMesh->getNumberOfNodes() ; + if ( SpaceDimension < 1 ) + throw MEDEXCEPTION(LOCALIZED(STRING(LOC) << "Mesh is empty")); + (*_vtkFile) << "# vtk DataFile Version 2.0" << endl << "maillage from MedMemory" << endl ; // only ASCII for the moment (binary came later :-) @@ -191,8 +199,6 @@ void VTK_MESH_DRIVER::write(void) const (*_vtkFile) << "DATASET UNSTRUCTURED_GRID" << endl ; // put points (all point are in 3D, so if we are in 1D or 2D, we complete by zero ! - int SpaceDimension = _ptrMesh->getSpaceDimension() ; - int NumberOfNodes = _ptrMesh->getNumberOfNodes() ; (*_vtkFile) << "POINTS " << NumberOfNodes << " float" << endl ; const double *coordinate = _ptrMesh->getCoordinates(MED_FULL_INTERLACE) ; for (int i=0;i<NumberOfNodes;i++) { @@ -408,7 +414,7 @@ void VTK_MESH_DRIVER::write(void) const (*_vtkFile) << vtkType << endl ; } - END_OF(LOC); + END_OF_MED(LOC); } GENDRIVER * VTK_MESH_DRIVER::copy(void) const diff --git a/src/MEDMEM/MEDMEM_VtkMeshDriver.hxx b/src/MEDMEM/MEDMEM_VtkMeshDriver.hxx index d7c7f9cf3..f1ac8187b 100644 --- a/src/MEDMEM/MEDMEM_VtkMeshDriver.hxx +++ b/src/MEDMEM/MEDMEM_VtkMeshDriver.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef VTK_MESH_DRIVER_HXX #define VTK_MESH_DRIVER_HXX @@ -98,6 +100,6 @@ private: GENDRIVER * copy ( void ) const; }; -}; +} #endif /* VTK_MESH_DRIVER_HXX */ diff --git a/src/MEDMEM/MEDMEM_define.hxx b/src/MEDMEM/MEDMEM_define.hxx index 19ca0c2be..59f954640 100644 --- a/src/MEDMEM/MEDMEM_define.hxx +++ b/src/MEDMEM/MEDMEM_define.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef DEFINE_HXX #define DEFINE_HXX @@ -84,7 +86,8 @@ namespace MED_EN { typedef enum {MED_CARTESIAN, MED_POLAR, MED_BODY_FITTED} med_grid_type; - typedef enum {MED_LECT,MED_ECRI,MED_REMP,MED_CREA} med_mode_acces; + //typedef enum {MED_LECT,MED_ECRI,MED_REMP,MED_CREA} med_mode_acces; + typedef enum {RDONLY,WRONLY,RDWR} med_mode_acces; typedef enum {ASCENDING=7,DESCENDING=77} med_sort_direc; @@ -204,15 +207,15 @@ typedef double med_float; #define MED_VALID 0 //#define MED_NULL NULL -#define MED_RDONLY MED_LECT - // rem: MED_WRONLY=MED_ECR n'empêche malheureusement pas de lire le fichier - // mais permet de conserver l'existant. Attention à la création d'objet - // ne prenant pas de paramètre de type mode d'accès il faut tester si il - // est déjà présent dans le fichier. Si MED_WRONLY=MED_REMP le fichier est - // réinitialisé. Cf une évolution de MED. -#define MED_WRONLY MED_ECRI -#define MED_RDWR MED_ECRI -#define MED_CREATE MED_CREA +//#define MED_RDONLY RDONLY +//// rem: MED_WRONLY=MED_ECR n'empêche malheureusement pas de lire le fichier +//// mais permet de conserver l'existant. Attention à la création d'objet +//// ne prenant pas de paramètre de type mode d'accès il faut tester si il +//// est déjà présent dans le fichier. Si MED_WRONLY=MED_REMP le fichier est +//// réinitialisé. Cf une évolution de MED. +//#define MED_WRONLY WRONLY +//#define MED_RDWR RDWR +//#define MED_CREATE MED_CREA // Fin #define FAUX 0 @@ -220,7 +223,7 @@ typedef double med_float; #define longueur_string 100 #define PRECISION 0.0000001 // #define undefined -1 -#define UNDEFINED -1 +#define MED_UNDEFINED -1 // type des connectivites //#define CONN_NOD 0 diff --git a/src/MEDMEM/MEDMEM_medimport_src.cxx b/src/MEDMEM/MEDMEM_medimport_src.cxx index e1fb5f9e3..cd75f85de 100644 --- a/src/MEDMEM/MEDMEM_medimport_src.cxx +++ b/src/MEDMEM/MEDMEM_medimport_src.cxx @@ -1,39 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // -/************************************************************************* -* COPYRIGHT (C) 1999 - 2003 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 -* -*************************************************************************/ #include "MEDMEM_medimport_src.hxx" #include <exception> @@ -45,14 +30,14 @@ using namespace MEDMEM; char * MEDMEM::med2_1_To_med2_3(char * fileNameIn) throw (MEDEXCEPTION) { // char * fileNameOut = new char[strlen(fileNameIn)+strlen("2.3")+1]; - char * fileNameOut = ""; + const char * fileNameOut = ""; int ret; // strcpy(fileNameOut,fileNameIn); // strcat(fileNameOut,"2.3"); try { - ret=MEDimport(fileNameIn,fileNameOut) ; + ret=MEDimport(fileNameIn,(char *)fileNameOut) ; } catch ( std::exception &ex) { std::cout << "An error eoccured durrnig execution of medImport" << std::endl; std::cout << ex.what() << std::endl; @@ -60,5 +45,5 @@ char * MEDMEM::med2_1_To_med2_3(char * fileNameIn) throw (MEDEXCEPTION) } - return fileNameOut; + return (char*)fileNameOut; } diff --git a/src/MEDMEM/MEDMEM_medimport_src.hxx b/src/MEDMEM/MEDMEM_medimport_src.hxx index f7876d9f7..9247c05b5 100644 --- a/src/MEDMEM/MEDMEM_medimport_src.hxx +++ b/src/MEDMEM/MEDMEM_medimport_src.hxx @@ -1,39 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // -/************************************************************************* -* COPYRIGHT (C) 1999 - 2003 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 -* -*************************************************************************/ #ifndef IMPORT_HXX #define IMPORT_HXX diff --git a/src/MEDMEM/MEDMEM_nArray.hxx b/src/MEDMEM/MEDMEM_nArray.hxx index 6df981e70..6b6fe44dc 100644 --- a/src/MEDMEM/MEDMEM_nArray.hxx +++ b/src/MEDMEM/MEDMEM_nArray.hxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #ifndef MEDMEM_ARRAY_HXX #define MEDMEM_ARRAY_HXX @@ -177,7 +180,8 @@ public : inline MEDMEM_Array<ElementType,InterlacingPolicy,CheckingPolicy> & operator=( const MEDMEM_Array & array) { if ( this == &array) return *this; - BEGIN_OF("MEDMEM_Array operator ="); + const char* LOC = "MEDMEM_Array operator ="; + BEGIN_OF_MED(LOC); InterlacingPolicy::operator=(array); //Appel des classes de base ? this->_array.set(array._array); // Le propriétaire reste le ARRAY initial @@ -197,6 +201,10 @@ public : return _array; } + const ElementType * getPtr() const { + return _array; + } + void setPtr(ElementType * values, bool shallowCopy=false, bool ownershipOfValues=false) { @@ -227,9 +235,14 @@ public : // setRow fonctionne // dans les deux modes d'entrelacement. - for (int j =1; j <= InterlacingPolicy::getDim(); j++) - for (int k = 1 ; k <= InterlacingPolicy::getNbGauss(i); k++) + // int index = -1; + for (int j =1; j <= InterlacingPolicy::getDim(); j++) { + for (int k = 1 ; k <= InterlacingPolicy::getNbGauss(i); k++) { _array[InterlacingPolicy::getIndex(i,j,k)] = value[InterlacingPolicy::getIndex(1,j,k)]; + //index++; + //_array[InterlacingPolicy::getIndex(i,j,k)] = value[index]; + } + } } inline const ElementType * getColumn(int j) const { @@ -244,9 +257,14 @@ public : // setColumn fonctionne // dans les deux modes d'entrelacement. - for (int i=1; i <= InterlacingPolicy::getNbElem(); i++) - for (int k = 1 ; k <= InterlacingPolicy::getNbGauss(i); k++) - _array[InterlacingPolicy::getIndex(i,j,k)] = value[InterlacingPolicy::getIndex(i,1,k)]; + int index = -1; + for (int i=1; i <= InterlacingPolicy::getNbElem(); i++) { + for (int k = 1 ; k <= InterlacingPolicy::getNbGauss(i); k++) { + //_array[InterlacingPolicy::getIndex(i,j,k)] = value[InterlacingPolicy::getIndex(i,1,k)]; + index++; + _array[InterlacingPolicy::getIndex(i,j,k)] = value[index]; + } + } } diff --git a/src/MEDMEM/MEDNormalizedUnstructuredMesh.hxx b/src/MEDMEM/MEDNormalizedUnstructuredMesh.hxx new file mode 100644 index 000000000..1bceeaec1 --- /dev/null +++ b/src/MEDMEM/MEDNormalizedUnstructuredMesh.hxx @@ -0,0 +1,53 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __MEDNORMALIZEDUNSTRUCTUREDMESH_HXX__ +#define __MEDNORMALIZEDUNSTRUCTUREDMESH_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace MEDMEM +{ + class MESH; +} + +template<int SPACEDIM,int MESHDIM> +class MEDNormalizedUnstructuredMesh : public INTERP_KERNEL::GenericMesh +{ +public: + static const int MY_SPACEDIM=SPACEDIM; + static const int MY_MESHDIM=MESHDIM; + typedef int MyConnType; + static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_FORTRAN_MODE; +public: + MEDNormalizedUnstructuredMesh(const MEDMEM::MESH *mesh); + void getBoundingBox(double *boundingBox) const; + INTERP_KERNEL::NormalizedCellType getTypeOfElement(int eltId) const; + unsigned char getNumberOfNodesOfElement(int eltId) const; + unsigned long getNumberOfElements() const; + unsigned long getNumberOfNodes() const; + const int *getConnectivityPtr() const; + const double *getCoordinatesPtr() const; + const int *getConnectivityIndexPtr() const; + void ReleaseTempArrays(); +protected: + const MEDMEM::MESH *_meshInMedMode; +}; + +#endif diff --git a/src/MEDMEM/MEDNormalizedUnstructuredMesh.txx b/src/MEDMEM/MEDNormalizedUnstructuredMesh.txx new file mode 100644 index 000000000..21d5f8ef9 --- /dev/null +++ b/src/MEDMEM/MEDNormalizedUnstructuredMesh.txx @@ -0,0 +1,95 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __MEDNORMALIZEDUNSTRUCTUREDMESH_TXX__ +#define __MEDNORMALIZEDUNSTRUCTUREDMESH_TXX__ + +#include "MEDNormalizedUnstructuredMesh.hxx" + +#include "MEDMEM_Mesh.hxx" + +template<int SPACEDIM,int MESHDIM> +MEDNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::MEDNormalizedUnstructuredMesh(const MEDMEM::MESH *mesh):_meshInMedMode(mesh) +{ +} + +template<int SPACEDIM,int MESHDIM> +void MEDNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::getBoundingBox(double *boundingBox) const +{ + vector< vector<double> > ret=_meshInMedMode->getBoundingBox(); + //low left corner + int i; + for(i=0;i<SPACEDIM;i++) + boundingBox[i]=ret[0][i]; + for(i=0;i<SPACEDIM;i++) + boundingBox[i+SPACEDIM]=ret[1][i]; +} + +template<int SPACEDIM,int MESHDIM> +INTERP_KERNEL::NormalizedCellType MEDNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::getTypeOfElement(int eltId) const +{ + MED_EN::medGeometryElement type=_meshInMedMode->getElementTypeWithPoly(MED_EN::MED_CELL,eltId); + if(type==MED_EN::MED_POLYGON) + return INTERP_KERNEL::NORM_POLYGON; + return (INTERP_KERNEL::NormalizedCellType)(((unsigned long)type/100-2)*10+((unsigned long)type%100)); +} + +template<int SPACEDIM,int MESHDIM> +unsigned char MEDNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::getNumberOfNodesOfElement(int eltId) const +{ + const int *ind=_meshInMedMode->getConnectivityIndex(MED_EN::MED_NODAL, MED_EN::MED_CELL); + return (unsigned char) (ind[eltId]-ind[eltId-1]); +} + +template<int SPACEDIM,int MESHDIM> +unsigned long MEDNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::getNumberOfElements() const +{ + return _meshInMedMode->getNumberOfElements(MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); +} + +template<int SPACEDIM,int MESHDIM> +unsigned long MEDNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::getNumberOfNodes() const +{ + return _meshInMedMode->getNumberOfNodes(); +} + +template<int SPACEDIM,int MESHDIM> +const int *MEDNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::getConnectivityPtr() const +{ + return _meshInMedMode->getConnectivity(MED_EN::MED_FULL_INTERLACE,MED_EN::MED_NODAL, + MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS); +} + +template<int SPACEDIM,int MESHDIM> +const double *MEDNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::getCoordinatesPtr() const +{ + return _meshInMedMode->getCoordinates(MED_EN::MED_FULL_INTERLACE); +} + +template<int SPACEDIM,int MESHDIM> +const int *MEDNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::getConnectivityIndexPtr() const +{ + return _meshInMedMode->getConnectivityIndex(MED_EN::MED_NODAL, MED_EN::MED_CELL); +} + +template<int SPACEDIM,int MESHDIM> +void MEDNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::ReleaseTempArrays() +{ +} + +#endif diff --git a/src/MEDMEM/Makefile.am b/src/MEDMEM/Makefile.am index 3dea27feb..7bf01287e 100644 --- a/src/MEDMEM/Makefile.am +++ b/src/MEDMEM/Makefile.am @@ -1,33 +1,34 @@ -# MED MEDMEM : MED files in memory +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +# MED MEDMEM : MED files in memory # - include $(top_srcdir)/adm_local/unix/make_common_starter.am # first '.' says that this folder must be compiled before Test (MEDMEM/Test uses MEDMEM) -if CPPUNIT_IS_OK - SUBDIRS=. Test -endif +#if CPPUNIT_IS_OK +# SUBDIRS=. Test +#endif -DIST_SUBDIRS= Test +#DIST_SUBDIRS= Test lib_LTLIBRARIES= libmedmem.la @@ -92,14 +93,19 @@ MEDMEM_ConnectZone.hxx \ MEDMEM_EnsightMedDriver.hxx \ MEDMEM_EnsightMeshDriver.hxx \ MEDMEM_EnsightFieldDriver.hxx \ -MEDMEM.hxx +MEDMEM.hxx \ +MEDMEM_OptionManager.hxx \ +MEDMEM_EnsightUtils.hxx \ +MEDMEM_Extractor.hxx \ +Remapper.hxx \ +PointLocator.hxx \ +MEDNormalizedUnstructuredMesh.hxx # not exported headers EXTRA_DIST+= DataTest \ MEDMEM_MEDMEMchampLire.hxx \ MEDMEM_MEDMEMgaussEcr.hxx \ -MEDMEM_MEDMEMprofilEcr.hxx \ -MEDMEM_Formulae.hxx +MEDMEM_MEDMEMprofilEcr.hxx dist_libmedmem_la_SOURCES= \ MEDMEM_Init.cxx \ @@ -118,7 +124,6 @@ MEDMEM_MedMedDriver.cxx \ MEDMEM_MedMeshDriver.cxx \ MEDMEM_GibiMeshDriver.cxx \ MEDMEM_PorflowMeshDriver.cxx \ -MEDMEM_DriverTools.cxx \ MEDMEM_SkyLineArray.cxx \ MEDMEM_Mesh.cxx \ MEDMEM_Meshing.cxx \ @@ -128,6 +133,7 @@ MEDMEM_VtkMedDriver.cxx \ MEDMEM_VtkMeshDriver.cxx \ MEDMEM_Grid.cxx \ MEDMEM_MedVersion.cxx \ +MEDMEM_Compatibility21_22.cxx \ MEDMEM_MedMeshDriver21.cxx \ MEDMEM_MedMedDriver21.cxx \ MEDMEM_medimport_src.cxx \ @@ -136,97 +142,41 @@ MEDMEM_MedMedDriver22.cxx \ MEDMEM_MedMeshDriver22.cxx \ MEDMEM_TopLevel.cxx \ MEDMEM_ConnectZone.cxx \ +MEDMEM_EnsightFieldDriver.cxx \ +MEDMEM_EnsightUtils.cxx \ MEDMEM_EnsightMedDriver.cxx \ MEDMEM_EnsightMeshDriver.cxx \ -MEDMEM_GaussLocalization.cxx +MEDMEM_DriverTools.cxx \ +MEDMEM_GaussLocalization.cxx \ +MEDMEM_Extractor.cxx \ +PointLocator.cxx \ +Remapper.cxx #libmedmem_la_LDFLAGS= -L$(top_builddir)/lib@LIB_LOCATION_SUFFIX@/salome -libmedmem_la_CPPFLAGS= $(MED2_INCLUDES) $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ \ +# libmedmem_la_CPPFLAGS= $(MED2_INCLUDES) $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ +libmedmem_la_CPPFLAGS= $(MED2_INCLUDES) $(HDF5_INCLUDES) \ -I$(srcdir)/../MEDWrapper/Base \ + -I$(srcdir)/../INTERP_KERNEL \ + -I$(srcdir)/../INTERP_KERNEL/Bases \ + -I$(srcdir)/../INTERP_KERNEL/Geometric2D \ -I$(srcdir)/../MEDWrapper/V2_1/Core -I$(srcdir)/../INTERPOLATION +libmedmem_la_CXXFLAGS= @CXXTMPDPTHFLAGS@ # change motivated by the bug KERNEL4778. libmedmem_la_LDFLAGS=$(MED2_LIBS) $(HDF5_LIBS) ../MEDWrapper/V2_1/Core/libmed_V2_1.la \ - ../MEDWrapper/Base/libMEDWrapperBase.la $(STDLIB) -if MED_ENABLE_KERNEL - libmedmem_la_CPPFLAGS+= ${KERNEL_CXXFLAGS} - libmedmem_la_LDFLAGS+= ${KERNEL_LDFLAGS} -lSALOMELocalTrace -endif + ../MEDWrapper/Base/libMEDWrapperBase.la $(STDLIB) ../INTERP_KERNEL/libinterpkernel.la -bin_PROGRAMS= \ - ensight2med med2ensight \ - med2_1_To_med2_2 med2vtk duplicateMED med_test duplicateMEDMESH test_write_groups_poly\ - test_MEDMEM_ModulusArray test_MEDMEM_Array test_MEDMEM_SkyLineArray \ - test_MEDMEM_CellModel testUPointerOf testUCoordinate testUUnit \ - testUGeoNameMeshEntities testUMedException testUModulusArray \ - testUSkyLineArray testUArray testUCellModel readEntete readCoordinate \ - test_copie_field_ test_copie_fieldT test_copie_coordinate \ - test_copie_medarray test_copie_connectivity test_copie_support \ - test_copie_family test_copie_group test_copie_mesh test_affect_medarray \ - test_MEDMEM_Meshing test_MEDMEM_MeshingPoly test_operation_fielddouble \ - test_operation_fieldint test_gibi_driver test_porflow_driver \ - test_grid test_MEDMEM_PolyhedronArray test_MEDMEM_PolyConnectivity \ - test_MEDMEM_PolyDriverMedMeshRead test_MEDMEM_PolyDriverMedMeshWrite \ - test_MEDMEM_poly3D test_MEDMEM_nArray test_MEDMEM_Meshing_poly test_profil_MedFieldDriver \ - test_profil_gauss_MedFieldDriver test_GaussLocalization testAnalFile test_MEDMEM_MeshingFlica \ - create_mesh create_mesh_c2q4s2 create_mesh_c3h8q4 create_mesh_c3h8q4_wrong \ - create_mesh_c2q4s2_wrong create_grid create_mesh_c2q4 create_mesh_c3h8 create_poly3D AM_CPPFLAGS= $(libmedmem_la_CPPFLAGS) +AM_CXXFLAGS= $(libmedmem_la_CXXFLAGS) LDADD= $(libmedmem_la_LDFLAGS) -lm libmedmem.la -if MED_ENABLE_KERNEL - LDADD+=-lSALOMEBasics -endif -dist_ensight2med_SOURCES= ensight2med.cxx -dist_med2ensight_SOURCES= med2ensight.cxx -dist_med2_1_To_med2_2_SOURCES= med2_1_To_med2_2.cxx -dist_med2vtk_SOURCES= med2vtk.cxx -dist_duplicateMED_SOURCES= duplicateMED.cxx -dist_med_test_SOURCES= med_test.cxx -dist_duplicateMEDMESH_SOURCES= duplicateMEDMESH.cxx -dist_test_write_groups_poly_SOURCES= test_write_groups_poly.cxx -dist_test_MEDMEM_ModulusArray_SOURCES= test_MEDMEM_ModulusArray.cxx -dist_test_MEDMEM_Array_SOURCES= test_MEDMEM_Array.cxx -dist_test_MEDMEM_SkyLineArray_SOURCES= test_MEDMEM_SkyLineArray.cxx -dist_test_MEDMEM_CellModel_SOURCES= test_MEDMEM_CellModel.cxx -dist_testUPointerOf_SOURCES= tests/testUPointerOf.cxx -dist_testUCoordinate_SOURCES= tests/testUCoordinate.cxx -dist_testUUnit_SOURCES= tests/testUUnit.cxx -dist_testUGeoNameMeshEntities_SOURCES= tests/testUGeoNameMeshEntities.cxx -dist_testUMedException_SOURCES= tests/testUMedException.cxx -dist_testUModulusArray_SOURCES= tests/testUModulusArray.cxx -dist_testUSkyLineArray_SOURCES= tests/testUSkyLineArray.cxx -dist_testUArray_SOURCES= tests/testUArray.cxx -dist_testUCellModel_SOURCES= tests/testUCellModel.cxx -dist_readEntete_SOURCES= tests/readEntete.cxx -dist_readCoordinate_SOURCES= tests/readCoordinate.cxx -dist_test_copie_field__SOURCES= test_copie_field_.cxx -dist_test_copie_fieldT_SOURCES= test_copie_fieldT.cxx -dist_test_copie_coordinate_SOURCES= test_copie_coordinate.cxx -dist_test_copie_medarray_SOURCES= test_copie_medarray.cxx -dist_test_copie_connectivity_SOURCES= test_copie_connectivity.cxx -dist_test_copie_support_SOURCES= test_copie_support.cxx -dist_test_copie_family_SOURCES= test_copie_family.cxx -dist_test_copie_group_SOURCES= test_copie_group.cxx -dist_test_copie_mesh_SOURCES= test_copie_mesh.cxx -dist_test_affect_medarray_SOURCES= test_affect_medarray.cxx -dist_test_MEDMEM_Meshing_SOURCES= test_MEDMEM_Meshing.cxx -dist_test_MEDMEM_MeshingPoly_SOURCES= test_MEDMEM_MeshingPoly.cxx -dist_test_operation_fielddouble_SOURCES= test_operation_fielddouble.cxx -dist_test_operation_fieldint_SOURCES= test_operation_fieldint.cxx -dist_test_gibi_driver_SOURCES= test_gibi_driver.cxx -dist_test_porflow_driver_SOURCES= test_porflow_driver.cxx -dist_test_grid_SOURCES= test_grid.cxx -dist_test_MEDMEM_PolyhedronArray_SOURCES= test_MEDMEM_PolyhedronArray.cxx -dist_test_MEDMEM_PolyConnectivity_SOURCES= test_MEDMEM_PolyConnectivity.cxx -dist_test_MEDMEM_PolyDriverMedMeshRead_SOURCES= test_MEDMEM_PolyDriverMedMeshRead.cxx -dist_test_MEDMEM_PolyDriverMedMeshWrite_SOURCES= test_MEDMEM_PolyDriverMedMeshWrite.cxx -dist_test_MEDMEM_poly3D_SOURCES= test_MEDMEM_poly3D.cxx -dist_test_MEDMEM_nArray_SOURCES= test_MEDMEM_nArray.cxx -dist_test_MEDMEM_Meshing_poly_SOURCES= test_MEDMEM_Meshing_poly.cxx -dist_test_profil_MedFieldDriver_SOURCES= test_profil_MedFieldDriver.cxx -dist_test_profil_gauss_MedFieldDriver_SOURCES= test_profil_gauss_MedFieldDriver.cxx -dist_test_GaussLocalization_SOURCES= test_GaussLocalization.cxx -dist_testAnalFile_SOURCES= testAnalFile.cxx -dist_test_MEDMEM_MeshingFlica_SOURCES= test_MEDMEM_MeshingFlica.cxx +OBSOLETE_FILES = \ + MEDMEM_MEDMEMchampLire.cxx \ + MEDMEM_MEDMEMgaussEcr.cxx \ + MEDMEM_MEDMEMprofilEcr.cxx \ + MEDMEM_TypeMeshDriver.cxx \ + MEDMEM_TypeMeshDriver.hxx \ + checkScript + +EXTRA_DIST += $(OBSOLETE_FILES) diff --git a/src/MEDMEM/PointLocator.cxx b/src/MEDMEM/PointLocator.cxx new file mode 100644 index 000000000..f1f9d74f8 --- /dev/null +++ b/src/MEDMEM/PointLocator.cxx @@ -0,0 +1,53 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <list> +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Exception.hxx" +#include "PointLocatorAlgos.txx" +#include "PointLocator.hxx" + +namespace INTERP_KERNEL { + PointLocator::PointLocator(const MEDMEM::MESH& mesh) + { + int meshdim=mesh.getMeshDimension(); + int spacedim=mesh.getSpaceDimension(); + if (meshdim != spacedim) throw MEDMEM::MEDEXCEPTION("Locator is not implemented for meshdim != spacedim"); + switch (meshdim) + { + case 2: + _medmesh = new MEDNormalizedUnstructuredMesh<2,2> (&mesh); + _point_locator=new PointLocatorAlgos<MEDNormalizedUnstructuredMesh<2,2> >(*(static_cast<MEDNormalizedUnstructuredMesh<2,2>* >(_medmesh))); + break; + case 3: + _medmesh = new MEDNormalizedUnstructuredMesh<3,3> (&mesh); + _point_locator=new PointLocatorAlgos<MEDNormalizedUnstructuredMesh<3,3> >(*(static_cast<MEDNormalizedUnstructuredMesh<3,3>* >(_medmesh))); + break; + } + } + PointLocator::~PointLocator() + { + delete _medmesh; + delete _point_locator; + } + +std::list<int> PointLocator::locate(const double* x) + { + return _point_locator->locates(x); + } +} diff --git a/src/MEDMEM/PointLocator.hxx b/src/MEDMEM/PointLocator.hxx new file mode 100644 index 000000000..1d7456d1a --- /dev/null +++ b/src/MEDMEM/PointLocator.hxx @@ -0,0 +1,41 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef _POINT_LOCATOR_HXX_ +#define _POINT_LOCATOR_HXX_ + +#include <list> +#include "MEDNormalizedUnstructuredMesh.hxx" +#include "PointLocatorAlgos.txx" +#include "MEDMEM.hxx" + +namespace INTERP_KERNEL +{ + class MEDMEM_EXPORT PointLocator + { + public: + PointLocator(const MEDMEM::MESH& mesh); + virtual ~PointLocator(); + std::list<int> locate(const double* x); + private: + GenericMesh* _medmesh; + GenericPointLocatorAlgos* _point_locator; + }; +} + +#endif diff --git a/src/MEDMEM/PointLocatorAlgos.txx b/src/MEDMEM/PointLocatorAlgos.txx new file mode 100644 index 000000000..3316982a6 --- /dev/null +++ b/src/MEDMEM/PointLocatorAlgos.txx @@ -0,0 +1,198 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef _POINT_LOCATOR_ALGOS_TXX_ +#define _POINT_LOCATOR_ALGOS_TXX_ + +#include "InterpolationUtils.hxx" +#include "CellModel.hxx" +#include "BBTree.txx" +#include <list> +#include <limits> + +namespace INTERP_KERNEL{ + + class GenericPointLocatorAlgos + { + public: + virtual ~GenericPointLocatorAlgos(){}; + virtual std::list<int> locates(const double* x)=0; + + }; + + template<class MyMeshType> + class PointLocatorAlgos: public GenericPointLocatorAlgos + { + private : + double* _bb; + BBTree<MyMeshType::MY_SPACEDIM,typename MyMeshType::MyConnType>* _tree; + const MyMeshType& _mesh; + + public: + PointLocatorAlgos(const MyMeshType& mesh):_mesh(mesh) + { + typedef typename MyMeshType::MyConnType ConnType; + const int SPACEDIM=MyMeshType::MY_SPACEDIM; + const NumberingPolicy numPol=MyMeshType::My_numPol; + int nelem = _mesh.getNumberOfElements(); + _bb = new double[SPACEDIM*2*nelem]; + const ConnType* conn = _mesh.getConnectivityPtr(); + const ConnType* conn_index = _mesh.getConnectivityIndexPtr(); + const double* coords=_mesh.getCoordinatesPtr(); + for (int i=0; i<nelem; i++) + { + for (int idim=0; idim<SPACEDIM; idim++) + { + _bb[2*(i*SPACEDIM+idim)]=std::numeric_limits<double>::max(); + _bb[2*(i*SPACEDIM+idim)+1]=-std::numeric_limits<double>::max(); + } + for (int index= conn_index[i]; index < conn_index[i+1];index++) + { + //coordelem points to the coordinates of the current node of the i-th element + const double* coordelem = coords+OTT<ConnType,numPol>::ind2C(conn[OTT<ConnType,numPol>::ind2C(index)])*SPACEDIM; + + //the bounding box is updated by checking wheher the node is at the min/max in exach dimension + for (int idim=0; idim<SPACEDIM;idim++) + { + _bb[2*(i*SPACEDIM+idim)]=(coordelem[idim]<_bb[2*(i*SPACEDIM+idim)])?coordelem[idim]:_bb[2*(i*SPACEDIM+idim)]; + _bb[2*(i*SPACEDIM+idim)+1]=(coordelem[idim]>_bb[2*(i*SPACEDIM+idim)+1])?coordelem[idim]:_bb[2*(i*SPACEDIM+idim)+1]; + } + } + } + + _tree=new BBTree<SPACEDIM,typename MyMeshType::MyConnType>(_bb,0,0,nelem); + } + ~PointLocatorAlgos() + { + delete[] _bb; + delete _tree; + } + + //returns the list of elements that contains + //the point pointed to by x + std::list<typename MyMeshType::MyConnType> locates(const double* x) + { + typedef typename MyMeshType::MyConnType ConnType; + const NumberingPolicy numPol=MyMeshType::My_numPol; + std::vector<ConnType> candidates; + _tree->getElementsAroundPoint(x,candidates); + std::list<ConnType> retlist; + for(int i=0; i< candidates.size(); i++) + { + int ielem=candidates[i]; + if (elementContainsPoint(ielem,x)) + retlist.push_back(OTT<ConnType,numPol>::indFC(ielem)); + } + return retlist; + } + + bool elementContainsPoint(typename MyMeshType::MyConnType i, const double*x) + { + //as i is extracted from the BBTRee, it is already in C numbering + //it is not necessary to convert it from F to C + typedef typename MyMeshType::MyConnType ConnType; + const int SPACEDIM=MyMeshType::MY_SPACEDIM; + const NumberingPolicy numPol=MyMeshType::My_numPol; + + const double* coords= _mesh.getCoordinatesPtr(); + const ConnType* conn=_mesh.getConnectivityPtr(); + const ConnType* conn_index= _mesh.getConnectivityIndexPtr(); + const ConnType* conn_elem=conn+OTT<ConnType,numPol>::ind2C(conn_index[i]); + NormalizedCellType type=_mesh.getTypeOfElement(OTT<ConnType,numPol>::indFC(i)); + const CellModel& cmType=CellModel::getCellModel(type); + + int nbnodes = cmType.getNumberOfNodes();//conn_index[i+1]-conn_index[i]; + + // with dimension 2, it suffices to check all the edges + // and see if the sign of double products from the point + //is always the same. + // C + // / \ + // / \ + // Xo / \ + // A-------B + // + //here XA^XC and XC^XB have different signs + // + if (SPACEDIM==2) + { + //in 2D, nbedges==nbnodes + int nbedges=nbnodes; + int* sign = new int[nbedges]; + for (int iedge=0; iedge<nbedges; iedge++) + { + const double* A=coords+SPACEDIM*(OTT<ConnType,numPol>::ind2C(conn_elem[iedge])); + const double* B; + if (iedge+1< nbedges) + B=coords+SPACEDIM*(OTT<ConnType,numPol>::ind2C(conn_elem[iedge+1])); + else + B=coords+SPACEDIM*(OTT<ConnType,numPol>::ind2C(conn_elem[0])); + + double a=mon_determinant(x, A, B); + if (a<-1e-12) + sign[iedge]=-1; + else if (a>1e-12) + sign[iedge]=1; + else + sign[iedge]=0; + } + bool ret=decide_from_sign(sign, nbedges); + delete [] sign; + return ret; + } + + if (SPACEDIM==3) + { + int nbfaces = cmType.getNumberOfSons(); + int* sign = new int[nbfaces]; + for (int iface=0; iface<nbfaces; iface++) + { + const unsigned* connface=cmType.getNodesConstituentTheSon(iface); + const double* AA=coords+SPACEDIM*(OTT<ConnType,numPol>::ind2C(conn_elem[connface[0]])); + const double* BB=coords+SPACEDIM*(OTT<ConnType,numPol>::ind2C(conn_elem[connface[1]])); + const double* CC=coords+SPACEDIM*(OTT<ConnType,numPol>::ind2C(conn_elem[connface[2]])); + + double Vol=triple_product(AA,BB,CC,x); + if (Vol<-1e-12) + sign[iface]=-1; + else if (Vol>1e-12) + sign[iface]=1; + else + sign[iface]=0; + } + bool ret=decide_from_sign(sign, nbfaces); + delete [] sign; + return ret; + } + + } + + bool decide_from_sign (const int* sign, int nbelem) + { + int min_sign =1; + int max_sign =-1; + for (int i=0; i<nbelem;i++) + { + min_sign=(sign[i]<min_sign)?sign[i]:min_sign; + max_sign=(sign[i]>max_sign)?sign[i]:max_sign; + } + return (min_sign!=-1 || max_sign!=1); + } + }; +} +#endif diff --git a/src/MEDMEM/Remapper.cxx b/src/MEDMEM/Remapper.cxx new file mode 100644 index 000000000..6ea307c68 --- /dev/null +++ b/src/MEDMEM/Remapper.cxx @@ -0,0 +1,142 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "Remapper.hxx" +#include "MEDMEM_Exception.hxx" +#include "Interpolation.hxx" +#include "Interpolation2D.txx" +#include "Interpolation3D.txx" +#include "Interpolation3DSurf.txx" +#include "MEDNormalizedUnstructuredMesh.txx" + +namespace INTERP_KERNEL +{ + + // int InterpolationOptions::_printLevel=0; + // IntersectionType InterpolationOptions::_intersectionType=Triangulation; + // double InterpolationOptions::_precision=1e-12;; + // double InterpolationOptions::_medianPlane =0.5; + // bool InterpolationOptions::_doRotate =true; + // double InterpolationOptions::_boundingBoxAdjustment =0.1; + // int InterpolationOptions::_orientation =0; + // SplittingPolicy InterpolationOptions::_splittingPolicy =GENERAL_48; + + Remapper::Remapper():_matrix(0) + { + } + + Remapper::~Remapper() + { + delete _matrix; + } + /*! This method computes the intersection matrix between + * source \a mesh_source and \a mesh_target. It is a preliminary step + * that is necessary before calling the \c transfer() method. + * The method analyses the dimensions of the meshes and checks for compatibility. + * + */ + void Remapper::prepare(const MEDMEM::MESH& mesh_source, const MEDMEM::MESH& mesh_target, const char *method) + { + const int sm_spacedim = mesh_source.getSpaceDimension(); + const int tm_spacedim = mesh_target.getSpaceDimension(); + int sm_meshdim = mesh_source.getMeshDimension(); + int tm_meshdim = mesh_target.getMeshDimension(); + + if (tm_spacedim!=sm_spacedim || tm_meshdim!=sm_meshdim) + throw MEDEXCEPTION("incompatible mesh and/or space dimensions in meshes"); + _matrix= new Matrix<double,ALL_FORTRAN_MODE>; + if ((sm_spacedim==2)&&(sm_meshdim==2)) + { + MEDNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(&mesh_source); + MEDNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(&mesh_target); + Interpolation2D interpolation; + interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,*_matrix,method); + } + else if ((sm_spacedim==3)&&(sm_meshdim==3)) + { + MEDNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(&mesh_source); + MEDNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(&mesh_target); + Interpolation3D interpolation; + interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,*_matrix,method); + } + else if ((sm_spacedim==3)&&(sm_meshdim==2)) + { + MEDNormalizedUnstructuredMesh<3,2> source_mesh_wrapper(&mesh_source); + MEDNormalizedUnstructuredMesh<3,2> target_mesh_wrapper(&mesh_target); + Interpolation3DSurf interpolation; + interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,*_matrix,method); + } + else + throw MEDEXCEPTION("no Interpolation exists for the given mesh and space dimensions"); + } + + void Remapper::transfer(const MEDMEM::FIELD<double>& field_source,MEDMEM::FIELD<double>& field_target) + { + int source_nbcomp=field_source.getNumberOfComponents(); + int target_nbcomp=field_target.getNumberOfComponents(); + if (source_nbcomp != target_nbcomp) + throw MEDMEM::MEDEXCEPTION("incoherent number of components for source and target fields"); + if (source_nbcomp>1) + throw MEDMEM::MEDEXCEPTION("interpolations with more than one component are not yet handled"); + MEDMEM::FIELD<double>* target_volumes = getSupportVolumes(*field_target.getSupport()); + int nbelem_target=field_target.getSupport()->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS); + + double* value_target = const_cast<double*> (field_target.getValue()); + const double* value_source = field_source.getValue(); + + _matrix->multiply(value_source, value_target); + for (int i=0; i< nbelem_target; i++) + value_target[i]/=target_volumes->getValueIJ(i+1,1); + + delete target_volumes; + } + + void Remapper::setOptionDouble(const std::string& key, double value) + { + } + + void Remapper::setOptionInt(const std::string& key, int value) + { + } + + /*! + \brief returns the volumes of the cells underlying the field \a field + + For 2D geometries, the returned field contains the areas. + For 3D geometries, the returned field contains the volumes. + + \param field field on which cells the volumes are required + \return field containing the volumes + */ + MEDMEM::FIELD<double>* Remapper::getSupportVolumes(const MEDMEM::SUPPORT& support) + { + const MEDMEM::MESH* mesh=support.getMesh(); + int dim = mesh->getMeshDimension(); + switch (dim) + { + case 2: + return mesh->getArea(&support); + case 3: + return mesh->getVolume(&support); + default: + throw MEDMEM::MEDEXCEPTION("interpolation is not available for this dimension"); + } + } + + +} diff --git a/src/MEDMEM/Remapper.hxx b/src/MEDMEM/Remapper.hxx new file mode 100644 index 000000000..430b93e0a --- /dev/null +++ b/src/MEDMEM/Remapper.hxx @@ -0,0 +1,47 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef REMAPPER_HXX_ +#define REMAPPER_HXX_ + +#include "InterpKernelMatrix.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM.hxx" + +namespace INTERP_KERNEL +{ + + class MEDMEM_EXPORT Remapper + { + public: + Remapper(); + virtual ~Remapper(); + void prepare(const MEDMEM::MESH& mesh_source, const MEDMEM::MESH& mesh_target, const char *method); + void transfer(const MEDMEM::FIELD<double>& field_source, MEDMEM::FIELD<double>& field_target); + void setOptionDouble(const std::string& key, double value); + void setOptionInt(const std::string& key, int value); + private : + Matrix<double,ALL_FORTRAN_MODE>* _matrix; + MEDMEM::FIELD<double>* getSupportVolumes(const MEDMEM::SUPPORT& support); + }; + +} + +#endif /*REMAPPER_HXX_*/ diff --git a/src/MEDMEM/Test/BasicMainTest.hxx b/src/MEDMEM/Test/BasicMainTest.hxx deleted file mode 100644 index 3794dcc1c..000000000 --- a/src/MEDMEM/Test/BasicMainTest.hxx +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#ifndef _BASICMAINTEST_HXX_ -#define _BASICMAINTEST_HXX_ - -#include <cppunit/CompilerOutputter.h> -#include <cppunit/TestResult.h> -#include <cppunit/TestResultCollector.h> -#include <cppunit/TextTestProgressListener.h> -#include <cppunit/BriefTestProgressListener.h> -#include <cppunit/extensions/TestFactoryRegistry.h> -#include <cppunit/TestRunner.h> -#include <stdexcept> - -#include <iostream> -#include <fstream> - -// ============================================================================ -/*! - * Main program source for Unit Tests with cppunit package does not depend - * on actual tests, so we use the same for all partial unit tests. - */ -// ============================================================================ - -int main(int argc, char* argv[]) -{ - // --- Create the event manager and test controller - CPPUNIT_NS::TestResult controller; - - // --- Add a listener that colllects test result - CPPUNIT_NS::TestResultCollector result; - controller.addListener( &result ); - - // --- Add a listener that print dots as test run. -#ifdef WIN32 - CPPUNIT_NS::TextTestProgressListener progress; -#else - CPPUNIT_NS::BriefTestProgressListener progress; -#endif - controller.addListener( &progress ); - - // --- Get the top level suite from the registry - - CPPUNIT_NS::Test *suite = - CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest(); - - // --- Adds the test to the list of test to run - - CPPUNIT_NS::TestRunner runner; - runner.addTest( suite ); - runner.run( controller); - - // --- Print test in a compiler compatible format. - - std::ofstream testFile; - testFile.open("UnitTestsResult", std::ios::out | std::ios::trunc); - //CPPUNIT_NS::CompilerOutputter outputter( &result, std::cerr ); - CPPUNIT_NS::CompilerOutputter outputter( &result, testFile ); - outputter.write(); - - // --- Run the tests. - - bool wasSucessful = result.wasSuccessful(); - testFile.close(); - - // --- Return error code 1 if the one of test failed. - - return wasSucessful ? 0 : 1; -} - -#endif diff --git a/src/MEDMEM/Test/MEDMEMTest.cxx b/src/MEDMEM/Test/MEDMEMTest.cxx deleted file mode 100644 index 42fd84996..000000000 --- a/src/MEDMEM/Test/MEDMEMTest.cxx +++ /dev/null @@ -1,701 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_Group.hxx" -#include "MEDMEM_IndexCheckingPolicy.hxx" -#include "MEDMEM_MedFieldDriver.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Meshing.hxx" -#include "MEDMEM_STRING.hxx" - -#include <sstream> -#include <cmath> - -using namespace std; - -// ============================================================================ -/*! - * Set up the environment - */ -// ============================================================================ -void MEDMEMTest::setUp() -{ -} - -// ============================================================================ -/*! - * - delete - */ -// ============================================================================ -void MEDMEMTest::tearDown() -{ -} - -// #1: MEDMEM_Array.hxx \ -// #2: MEDMEM_ArrayConvert.hxx } MEDMEMTest_Array.cxx -// #3: MEDMEM_ArrayInterface.hxx (-) / -// #4: MEDMEM_AsciiFieldDriver.hxx } MEDMEMTest_AsciiFieldDriver.cxx -// #5: MEDMEM_CellModel.hxx } MEDMEMTest.cxx (-) -// #6: MEDMEM_Compatibility21_22.hxx } nothing to test -// #7: MEDMEM_Connectivity.hxx } MEDMEMTest_Connectivity.cxx -// #8: MEDMEM_Coordinate.hxx } MEDMEMTest_Coordinate.cxx -// #9: MEDMEM_DriverFactory.hxx } MEDMEMTest_DriverFactory.cxx -// #10: MEDMEM_DriversDef.hxx } MEDMEMTest.cxx (-) -// #11: MEDMEM_DriverTools.hxx } MEDMEMTest.cxx (-) -// #12: MEDMEM_Exception.hxx } MEDMEMTest_Exception.cxx -// #13: MEDMEM_Family.hxx } MEDMEMTest.cxx -// #14: MEDMEM_Field.hxx \ -// #15: MEDMEM_FieldConvert.hxx / MEDMEMTest_Field.cxx -// #16: MEDMEM_FieldForward.hxx } no methods to test -// #17: MEDMEM_Formulae.hxx } MEDMEMTest_Formulae.cxx -// #18: MEDMEM_GaussLocalization.hxx } MEDMEMTest_GaussLocalization.cxx -// #19: MEDMEM_GenDriver.hxx } abstract class; implemented methods are tested during its successors testing -// #20: MEDMEM_GibiMeshDriver.hxx } MEDMEMTest_GibiMeshDriver.cxx -// #21: MEDMEM_Grid.cxx } MEDMEMTest_Grid.cxx -// #22: MEDMEM_Group.cxx } MEDMEMTest_Group.cxx -// #23: MEDMEM_IndexCheckingPolicy.cxx } MEDMEMTest.cxx -// #24: MEDMEM_Init.cxx } MEDMEMTest.cxx -// #25: MEDMEM_InterlacingPolicy.hxx } MEDMEMTest.cxx (-) -// #26: MEDMEM_InterlacingTraits.hxx } MEDMEMTest.cxx (-) -// #27: MEDMEM_MedFieldDriver21.hxx } MEDMEMTest_MedFieldDriver21.cxx -// #28: MEDMEM_MedFieldDriver22.hxx } MEDMEMTest_MedFieldDriver22.cxx -// #29: MEDMEM_MedFieldDriver.hxx } MEDMEMTest.cxx (-) -// #30: MEDMEM_Med.hxx } MEDMEMTest_Med.cxx -// #31: MEDMEM_MedMedDriver21.hxx } MEDMEMTest_MedMedDriver21.cxx -// #32: MEDMEM_MedMedDriver22.hxx } MEDMEMTest_MedMedDriver22.cxx -// #33: MEDMEM_MedMedDriver.hxx } MEDMEMTest.cxx (-) -// #34: MEDMEM_MEDMEMchampLire.hxx } MEDMEMTest.cxx (-) -// #35: MEDMEM_MEDMEMgaussEcr.hxx } MEDMEMTest.cxx (-) -// #36: MEDMEM_MEDMEMprofilEcr.hxx } MEDMEMTest.cxx (-) -// #37: MEDMEM_MedMeshDriver21.hxx } MEDMEMTest_MedMeshDriver21.cxx -// #38: MEDMEM_MedMeshDriver22.hxx } MEDMEMTest_MedMeshDriver22.cxx -// #39: MEDMEM_MedMeshDriver.hxx } MEDMEMTest.cxx (-) -// #40: MEDMEM_MedVersion.hxx } MEDMEMTest_MedVersion.cxx -// #41: MEDMEM_Mesh.hxx \ -// #42: MEDMEM_Meshing.hxx / MEDMEMTest_MeshAndMeshing.cxx -// #43: MEDMEM_ModulusArray.hxx } MEDMEMTest_ModulusArray.cxx -// #44: MEDMEM_nArray.hxx } MEDMEMTest_nArray.cxx -// #45: MEDMEM_PointerOf.hxx } MEDMEMTest_PointerOf.cxx -// #46: MEDMEM_PolyhedronArray.hxx } MEDMEMTest_PolyhedronArray.cxx -// #47: MEDMEM_PorflowMeshDriver.hxx } MEDMEMTest_PorflowMeshDriver.cxx -// #48: MEDMEM_RCBase.hxx } MEDMEMTest.cxx (-) -// #49: MEDMEM_SetInterlacingType.hxx } MEDMEMTest.cxx (-) -// #50: MEDMEM_SkyLineArray.hxx } MEDMEMTest_SkyLineArray.cxx -// #51: MEDMEM_STRING.hxx } MEDMEMTest.cxx -// #52: MEDMEM_Support.hxx } MEDMEMTest_Support.cxx -// #53: MEDMEM_Tags.hxx } MEDMEMTest.cxx (-) -// #54: MEDMEM_TopLevel.hxx } MEDMEMTest_TopLevel.cxx -// #55: MEDMEM_TypeMeshDriver.hxx } MEDMEMTest.cxx -// #56: MEDMEM_Unit.hxx } MEDMEMTest_Unit.cxx -// #57: MEDMEM_VtkFieldDriver.hxx } MEDMEMTest_VtkFieldDriver.cxx -// #58: MEDMEM_VtkMedDriver.hxx } MEDMEMTest_VtkMedDriver.cxx -// #59: MEDMEM_VtkMeshDriver.hxx } MEDMEMTest_VtkMeshDriver.cxx -// #60: MEDMEM_medimport_src.hxx } MEDMEMTest.cxx (-) - - -/*! - * Check methods (not in spec), defined in MEDMEM_CellModel.hxx: - */ -//void MEDMEMTest::testCellModel() -//{ -// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); -//} - -/*! - * Check methods (not in spec), defined in MEDMEM_DriversDef.hxx: - */ -//void MEDMEMTest::testDriversDef() -//{ -// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); -//} - -/*! - * Check methods (not in spec), defined in MEDMEM_DriverTools.hxx: - */ -//void MEDMEMTest::testDriverTools() -//{ -// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); -//} - -/*! - * Check methods (4), defined in MEDMEM_IndexCheckingPolicy.hxx: - * class IndexCheckPolicy { - * (+) void checkMoreThanZero(const std::string & classname, int index) const; - * (+) void checkLessOrEqualThan(const std::string & classname, int max, int index) const; - * (+) void checkInInclusiveRange(const std::string & classname, int min, int max, int index) const; - * (+) void checkEquality(const std::string & classname, int a, int b) const; - * } - * class NoIndexCheckPolicy { - * (+) void checkMoreThanZero(const string &classname, int index) const; - * (+) void checkLessOrEqualThan(const std::string & classname, int max, int index) const; - * (+) void checkInInclusiveRange(const std::string & classname, int min, int max, int index) const; - * (+) void checkEquality(const std::string & classname, int a, int b) const; - * } - */ -void MEDMEMTest::testIndexCheckingPolicy() -{ - MEDMEM::IndexCheckPolicy do_check; - MEDMEM::NoIndexCheckPolicy no_check; - - int min = 3; - int max = 10; - - string aClassName ("MEDMEMTest::testIndexCheckingPolicy"); - - // IndexCheckPolicy: throw, if index does not satisfy criteria - CPPUNIT_ASSERT_THROW(do_check.checkMoreThanZero(aClassName, -1), MEDMEM::MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(do_check.checkLessOrEqualThan(aClassName, max, 13), MEDMEM::MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(do_check.checkInInclusiveRange(aClassName, min, max, 1), MEDMEM::MEDEXCEPTION); - // checkEquality() check that values are not equal - CPPUNIT_ASSERT_THROW(do_check.checkEquality(aClassName, 21, 21), MEDMEM::MEDEXCEPTION); - - // NoIndexCheckPolicy: do not throw, if index does not satisfy criteria - CPPUNIT_ASSERT_NO_THROW(no_check.checkMoreThanZero(aClassName, -1)); - CPPUNIT_ASSERT_NO_THROW(no_check.checkLessOrEqualThan(aClassName, max, 13)); - CPPUNIT_ASSERT_NO_THROW(no_check.checkInInclusiveRange(aClassName, min, max, 1)); - CPPUNIT_ASSERT_NO_THROW(no_check.checkEquality(aClassName, 21, 21)); - - // IndexCheckPolicy: do not throw, if index satisfy criteria - CPPUNIT_ASSERT_NO_THROW(do_check.checkMoreThanZero(aClassName, 5)); - CPPUNIT_ASSERT_NO_THROW(do_check.checkLessOrEqualThan(aClassName, max, 7)); - CPPUNIT_ASSERT_NO_THROW(do_check.checkInInclusiveRange(aClassName, min, max, 6)); - CPPUNIT_ASSERT_NO_THROW(do_check.checkEquality(aClassName, 21, 28)); - - // NoIndexCheckPolicy: do not throw, if index satisfy criteria - CPPUNIT_ASSERT_NO_THROW(no_check.checkMoreThanZero(aClassName, 5)); - CPPUNIT_ASSERT_NO_THROW(no_check.checkLessOrEqualThan(aClassName, max, 7)); - CPPUNIT_ASSERT_NO_THROW(no_check.checkInInclusiveRange(aClassName, min, max, 6)); - CPPUNIT_ASSERT_NO_THROW(no_check.checkEquality(aClassName, 21, 28)); -} - -/*! - * Check initialization, done in MEDMEM_Init.cxx: - * (-) MEDMEM::INIT init; - */ -void MEDMEMTest::testInit() -{ - // We cannot check here effect of initialization, done in MEDMEM_Init.cxx, - // because environment variable, set there, is visible only in libmedmem.la - // and its child processes (if any). - - // Check effect of MEDMEM_Init.cxx - //char* traceKind = getenv("SALOME_trace"); - //CPPUNIT_ASSERT(traceKind); -} - -/*! - * Check methods (not in spec), defined in MEDMEM_InterlacingPolicy.hxx: - */ -//void MEDMEMTest::testInterlacingPolicy() -//{ -// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); -//} - -/*! - * Check methods (not in spec), defined in MEDMEM_InterlacingTraits.hxx: - */ -//void MEDMEMTest::testInterlacingTraits() -//{ -// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); -//} - -/*! - * Check methods (not in spec), defined in MEDMEM_MedFieldDriver.hxx: - */ -//void MEDMEMTest::testMedFieldDriver() -//{ -// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); -//} - -/*! - * Check methods (not in spec), defined in MEDMEM_MedMedDriver.hxx: - */ -//void MEDMEMTest::testMedMedDriver() -//{ -// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); -//} - -/*! - * Check methods (not in spec), defined in MEDMEM_MEDMEMchampLire.hxx: - */ -//void MEDMEMTest::testMEDMEMchampLire() -//{ -// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); -//} - -/*! - * Check methods (not in spec), defined in MEDMEM_MEDMEMgaussEcr.hxx: - */ -//void MEDMEMTest::testMEDMEMgaussEcr() -//{ -// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); -//} - -/*! - * Check methods (not in spec), defined in MEDMEM_MEDMEMprofilEcr.hxx: - */ -//void MEDMEMTest::testMEDMEMprofilEcr() -//{ -// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); -//} - -/*! - * Check methods (not in spec), defined in MEDMEM_MedMeshDriver.hxx: - */ -//void MEDMEMTest::testMedMeshDriver() -//{ -// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); -//} - -/*! - * Check methods (not in spec), defined in MEDMEM_RCBase.hxx: - * class RCBASE { - * (reference counter presently disconnected in C++) virtual void addReference() const = 0; - * (reference counter presently disconnected in C++) virtual void removeReference() const = 0; - * } - */ -//void MEDMEMTest::testRCBase() -//{ -// // nothing to test -//} - -/*! - * Check methods (not in spec), defined in MEDMEM_SetInterlacingType.hxx: - */ -//void MEDMEMTest::testSetInterlacingType() -//{ -// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); -//} - -/*! - * Check methods (2), defined in MEDMEM_STRING.hxx: - * class STRING : public string { - * (+) STRING() - * (+) ~STRING() - * (+) operator const char * () const - * (+) template <class T> STRING(const T &valeur) - * (+) template <class T> STRING & operator<<(const T &valeur) - * } - */ -void MEDMEMTest::testSTRING() -{ - { - // empty constructor - MEDMEM::STRING medstr; - CPPUNIT_ASSERT(strcmp(medstr.c_str(), "") == 0); - - // template <class T> STRING & operator<<(const T &valeur) with T == char* - //medstr << <char*>"filling 1"; - medstr << "filling " << 1 << " !!!"; - CPPUNIT_ASSERT(strcmp(medstr.c_str(), "filling 1 !!!") == 0); - - // operator const char * () - CPPUNIT_ASSERT(strcmp((const char *)medstr, "filling 1 !!!") == 0); - CPPUNIT_ASSERT(strcmp( medstr, "filling 1 !!!") == 0); - } - - MEDMEM::MESH * aMesh1 = MEDMEMTest_createTestMesh(); - ostringstream ostr; - ostr << *aMesh1; - - { - // template <class T> STRING & operator<<(const T &valeur) with T == MEDMEM::MESH - MEDMEM::STRING medstr; - //medstr << <char*>"filling 1"; - medstr << *aMesh1; - CPPUNIT_ASSERT(strcmp(medstr, ostr.str().c_str()) == 0); - } - - { - // Constructor STRING(const T &valeur) with T == char* - //MEDMEM::STRING medstr<char*>("filling 2"); - MEDMEM::STRING medstr ("filling 2"); - CPPUNIT_ASSERT(strcmp(medstr.c_str(), "filling 2") == 0); - CPPUNIT_ASSERT(strcmp(medstr, "filling 2") == 0); - } - - { - // Constructor STRING(const T &valeur) with T == MEDMEM::MESH - MEDMEM::STRING medstr (*aMesh1); - CPPUNIT_ASSERT(strcmp(medstr, ostr.str().c_str()) == 0); - } - - delete aMesh1; -} - -/*! - * Check methods (not in spec), defined in MEDMEM_Tags.hxx: - */ -//void MEDMEMTest::testTags() -//{ -// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); -//} - -/*! - * Check methods (15), defined in MEDMEM_TypeMeshDriver.hxx: - * class TYPE_MESH_DRIVER : public GENDRIVER { - * (-) TYPE_MESH_DRIVER(); - * (-) TYPE_MESH_DRIVER(const string & fileName, MESH * ptrMesh, med_mode_acces accessMode); - * (-) TYPE_MESH_DRIVER(const TYPE_MESH_DRIVER & driver); - * (-) virtual ~TYPE_MESH_DRIVER(); - * (-) void open() throw (MEDEXCEPTION); - * (-) void close() throw (MEDEXCEPTION); - * (-) virtual void write(void) const = 0; - * (-) virtual void read (void) = 0; - * (-) void setMeshName(const string & meshName); - * (-) string getMeshName() const; - * } - * class TYPE_MESH_RDONLY_DRIVER : public virtual TYPE_MESH_DRIVER { - * (-) TYPE_MESH_RDONLY_DRIVER(); - * (-) TYPE_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh); - * (-) TYPE_MESH_RDONLY_DRIVER(const TYPE_MESH_RDONLY_DRIVER & driver); - * (-) virtual ~TYPE_MESH_RDONLY_DRIVER(); - * (-) void write(void) const throw (MEDEXCEPTION); - * (-) void read (void) throw (MEDEXCEPTION); - * } - * class TYPE_MESH_WRONLY_DRIVER : public virtual TYPE_MESH_DRIVER { - * (-) TYPE_MESH_WRONLY_DRIVER(); - * (-) TYPE_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh); - * (-) TYPE_MESH_WRONLY_DRIVER(const TYPE_MESH_WRONLY_DRIVER & driver); - * (-) virtual ~TYPE_MESH_WRONLY_DRIVER(); - * (-) void write(void) const throw (MEDEXCEPTION); - * (-) void read (void) throw (MEDEXCEPTION); - * } - * class TYPE_MESH_RDWR_DRIVER : public TYPE_MESH_RDONLY_DRIVER, public TYPE_MESH_WRONLY_DRIVER { - * (-) TYPE_MESH_RDWR_DRIVER(); - * (-) TYPE_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh); - * (-) TYPE_MESH_RDWR_DRIVER(const TYPE_MESH_RDWR_DRIVER & driver); - * (-) ~TYPE_MESH_RDWR_DRIVER(); - * (-) void write(void) const throw (MEDEXCEPTION); - * (-) void read (void) throw (MEDEXCEPTION); - * } - */ -void MEDMEMTest::testTypeMeshDriver() -{ - CPPUNIT_FAIL("TYPE_MESH_DRIVER: not implemented"); -} - -/*! - * Check methods (not in spec), defined in MEDMEM_medimport_src.hxx: - */ -//void MEDMEMTest::testmedimport_src() -//{ -// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); -//} - -//60 -//21 not in spec - -////////////////////////////////////// -// HELP METHODS, used in many tests // -////////////////////////////////////// - -/*! - * Create a mesh with certain filling - * .n4 - * | - * | - * n16,n12,n8.---------.n7,n11,n15 - * | | | - * | | | - * n5.----|----.----|----.n3 - * | | | - * | | | - * n17,n13,n9.---------.n10,n14,n18 - * | - * | - * .n6 - * - * .n19 (0,0,5) - * | - * | - * | - * | - * n16.--|-.----.n15 - * / |/ / - * . . . - * / /| / - * n17.----.----.n18 - * | - * | - * n12.--|-.----.n11 - * / |/ / - * . . . - * / /| / - * n13.----.----.n14 - * | - * | - * n8.--|-.----.n7 - * / |/ / - * . . . - * / /| / - * n9.----.----.n10 - * | .n4 (0,2,1) - * | / - * | . - * |/ - * n5.----.----.----.----.n3 (2,0,1) - * (-2,0,1) /n2 (0,0,1) - * . | - * / | - * .n6 | - * | - * | - * .n1 (0,0,0) - */ -MEDMEM::MESH * MEDMEMTest_createTestMesh () -{ - // MESH DATA - int SpaceDimension = 3; - int meshDimension = SpaceDimension; // because there 3D cells in the mesh - - // coordinates - int NumberOfNodes = 19; - - string Names[3] = { "X","Y","Z" }; - string Units[3] = { "cm","cm","cm" }; - - double Coordinates[57] = { - 0.0, 0.0, 0.0, // n1 - 0.0, 0.0, 1.0, // n2 - 2.0, 0.0, 1.0, // n3 - 0.0, 2.0, 1.0, // n4 - -2.0, 0.0, 1.0, // n5 - 0.0, -2.0, 1.0, // n6 - 1.0, 1.0, 2.0, // n7 - -1.0, 1.0, 2.0, // n8 - -1.0, -1.0, 2.0, // n9 - 1.0, -1.0, 2.0, // n10 - 1.0, 1.0, 3.0, // n11 - -1.0, 1.0, 3.0, // n12 - -1.0, -1.0, 3.0, // n13 - 1.0, -1.0, 3.0, // n14 - 1.0, 1.0, 4.0, // n15 - -1.0, 1.0, 4.0, // n16 - -1.0, -1.0, 4.0, // n17 - 1.0, -1.0, 4.0, // n18 - 0.0, 0.0, 5.0 // n19 - }; - - // cells connectivities - const int NumberOfCellTypes = 3; - MED_EN::medGeometryElement CellTypes[NumberOfCellTypes] = - {MED_EN::MED_TETRA4, MED_EN::MED_PYRA5, MED_EN::MED_HEXA8}; - const int NumberOfCells[NumberOfCellTypes] = {12, 2, 2}; - - int ConnectivityTetra[12 * 4] = { - 1,2,3,6, - 1,2,4,3, - 1,2,5,4, - 1,2,6,5, - 2,7,4,3, - 2,8,5,4, - 2,9,6,5, - 2,10,3,6, - 2,7,3,10, - 2,8,4,7, - 2,9,5,8, - 2,10,6,9 - }; - - int ConnectivityPyra[2 * 5] = { - 7,8,9,10,2, - 15,18,17,16,19 - }; - - int ConnectivityHexa[2 * 8] = { - 11,12,13,14,7,8,9,10, - 15,16,17,18,11,12,13,14 - }; - - // faces connectivities - const int NumberOfFaceTypes = 2; - MED_EN::medGeometryElement FaceTypes[NumberOfFaceTypes] = {MED_EN::MED_TRIA3, MED_EN::MED_QUAD4}; - const int NumberOfFaces[NumberOfFaceTypes] = {4, 4}; - - int ConnectivityTria[4 * 3] = { - 1,4,3, - 1,5,4, - 1,6,5, - 1,3,6 - }; - - int ConnectivityQua[4 * 4] = { - 7,8,9,10, - 11,12,13,14, - 11,7,8,12, - 12,8,9,13 - }; - - - // CREATE THE MESH - MEDMEM::MESHING* myMeshing = new MEDMEM::MESHING; - - myMeshing->setName("meshing"); - - myMeshing->setCoordinates(SpaceDimension, NumberOfNodes, Coordinates, - "CARTESIAN", MED_EN::MED_FULL_INTERLACE); - myMeshing->setCoordinatesNames(Names); - myMeshing->setCoordinatesUnits(Units); - - // define connectivities - myMeshing->setNumberOfTypes(NumberOfCellTypes, MED_EN::MED_CELL); - myMeshing->setTypes(CellTypes, MED_EN::MED_CELL); - myMeshing->setNumberOfElements(NumberOfCells, MED_EN::MED_CELL); - - myMeshing->setConnectivity(ConnectivityTetra, MED_EN::MED_CELL, MED_EN::MED_TETRA4); - myMeshing->setConnectivity(ConnectivityPyra, MED_EN::MED_CELL, MED_EN::MED_PYRA5); - myMeshing->setConnectivity(ConnectivityHexa, MED_EN::MED_CELL, MED_EN::MED_HEXA8); - - myMeshing->setNumberOfTypes(NumberOfFaceTypes, MED_EN::MED_FACE); - myMeshing->setTypes(FaceTypes, MED_EN::MED_FACE); - myMeshing->setNumberOfElements(NumberOfFaces, MED_EN::MED_FACE); - - myMeshing->setConnectivity(ConnectivityTria, MED_EN::MED_FACE, MED_EN::MED_TRIA3); - myMeshing->setConnectivity(ConnectivityQua, MED_EN::MED_FACE, MED_EN::MED_QUAD4); - - // mesh dimension - myMeshing->setMeshDimension(meshDimension); - - // edges connectivities - // not yet implemented : if set, results are unpredictable. - - // groups of nodes - { - MEDMEM::GROUP myGroup; - myGroup.setName("SomeNodes"); - myGroup.setMesh(myMeshing); - myGroup.setEntity(MED_EN::MED_NODE); - myGroup.setNumberOfGeometricType(1); - MED_EN::medGeometryElement myTypes[1] = {MED_EN::MED_NONE}; - myGroup.setGeometricType(myTypes); - const int myNumberOfElements[1] = {4}; - myGroup.setNumberOfElements(myNumberOfElements); - const int index[1+1] = {1,5}; - const int value[4] = {1,4,5,7}; - myGroup.setNumber(index,value); - myMeshing->addGroup(myGroup); - } - { - MEDMEM::GROUP myGroup; - myGroup.setName("OtherNodes"); - myGroup.setMesh(myMeshing); - myGroup.setEntity(MED_EN::MED_NODE); - myGroup.setNumberOfGeometricType(1); - MED_EN::medGeometryElement myTypes[1] = {MED_EN::MED_NONE}; - myGroup.setGeometricType(myTypes); - const int myNumberOfElements[1] = {3}; - myGroup.setNumberOfElements(myNumberOfElements); - const int index[1+1] = {1,4}; - const int value[3] = {2,3,6}; - myGroup.setNumber(index,value); - myMeshing->addGroup(myGroup); - } - - // groups of cells - { - MEDMEM::GROUP myGroup; - myGroup.setName("SomeCells"); - myGroup.setMesh(myMeshing); - myGroup.setEntity(MED_EN::MED_CELL); - myGroup.setNumberOfGeometricType(3); - MED_EN::medGeometryElement myTypes[3] = {MED_EN::MED_TETRA4,MED_EN::MED_PYRA5,MED_EN::MED_HEXA8}; - myGroup.setGeometricType(myTypes); - const int myNumberOfElements[3] = {4,1,2}; - myGroup.setNumberOfElements(myNumberOfElements); - const int index[3+1] = {1,5,6,8}; - const int value[4+1+2] = {2,7,8,12, 13, 15,16}; - myGroup.setNumber(index,value); - myMeshing->addGroup(myGroup); - } - { - MEDMEM::GROUP myGroup; - myGroup.setName("OtherCells"); - myGroup.setMesh(myMeshing); - myGroup.setEntity(MED_EN::MED_CELL); - myGroup.setNumberOfGeometricType(2); - MED_EN::medGeometryElement myTypes[] = {MED_EN::MED_TETRA4,MED_EN::MED_PYRA5}; - myGroup.setGeometricType(myTypes); - const int myNumberOfElements[] = {4,1}; - myGroup.setNumberOfElements(myNumberOfElements); - const int index[2+1] = {1,5,6}; - const int value[4+1] = {3,4,5,9, 14}; - myGroup.setNumber(index,value); - myMeshing->addGroup(myGroup); - } - - // groups of faces - { - MEDMEM::GROUP myGroup; - myGroup.setName("SomeFaces"); - myGroup.setMesh(myMeshing); - myGroup.setEntity(MED_EN::MED_FACE); - myGroup.setNumberOfGeometricType(2); - MED_EN::medGeometryElement myTypes[2] = {MED_EN::MED_TRIA3,MED_EN::MED_QUAD4}; - myGroup.setGeometricType(myTypes); - const int myNumberOfElements[2] = {2,3}; - myGroup.setNumberOfElements(myNumberOfElements); - const int index[2+1] = {1,3,6}; - const int value[2+3] = {2,4, 5,6,8}; - myGroup.setNumber(index,value); - myMeshing->addGroup(myGroup); - } - { - MEDMEM::GROUP myGroup; - myGroup.setName("OtherFaces"); - myGroup.setMesh(myMeshing); - myGroup.setEntity(MED_EN::MED_FACE); - myGroup.setNumberOfGeometricType(1); - MED_EN::medGeometryElement myTypes[1] = {MED_EN::MED_TRIA3}; - myGroup.setGeometricType(myTypes); - const int myNumberOfElements[1] = {2}; - myGroup.setNumberOfElements(myNumberOfElements); - const int index[1+1] = {1,3}; - const int value[2] = {1,3}; - myGroup.setNumber(index,value); - myMeshing->addGroup(myGroup); - } - - return myMeshing; -} - -/*! - * Tool to remove temporary files. - * Allows automatique removal of temporary files in case of test failure. - */ -MEDMEMTest_TmpFilesRemover::~MEDMEMTest_TmpFilesRemover() -{ - set<string>::iterator it = myTmpFiles.begin(); - for (; it != myTmpFiles.end(); it++) { - if (access((*it).data(), F_OK) == 0) - remove((*it).data()); - } - myTmpFiles.clear(); - //cout << "~MEDMEMTest_TmpFilesRemover()" << endl; -} - -bool MEDMEMTest_TmpFilesRemover::Register(const string theTmpFile) -{ - return (myTmpFiles.insert(theTmpFile)).second; -} diff --git a/src/MEDMEM/Test/MEDMEMTest.hxx b/src/MEDMEM/Test/MEDMEMTest.hxx deleted file mode 100644 index 6d77598de..000000000 --- a/src/MEDMEM/Test/MEDMEMTest.hxx +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#ifndef _MEDMEMTEST_HXX_ -#define _MEDMEMTEST_HXX_ - -#include <cppunit/extensions/HelperMacros.h> - -#include <set> -#include <string> -//#include <ostream> -#include <iostream> - -namespace MEDMEM { - class MESH; -}; - -class MEDMEMTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( MEDMEMTest ); - //0 - CPPUNIT_TEST( testArray ); - CPPUNIT_TEST( testArrayConvert ); - //CPPUNIT_TEST( testArrayInterface /* not in spec */ ); - //CPPUNIT_TEST( testAsciiFieldDriver ); - //CPPUNIT_TEST( testCellModel /* not in spec */ ); - CPPUNIT_TEST( testConnectivity ); - CPPUNIT_TEST( testCoordinate ); - CPPUNIT_TEST( testDriverFactory ); - //CPPUNIT_TEST( testDriversDef /* not in spec */ ); - //10 - //CPPUNIT_TEST( testDriverTools /* not in spec */ ); - CPPUNIT_TEST( testException /* not in spec */ ); - CPPUNIT_TEST( testFamily ); - CPPUNIT_TEST( testField ); - CPPUNIT_TEST( testFieldConvert ); - CPPUNIT_TEST( testFormulae ); - CPPUNIT_TEST( testGaussLocalization ); - CPPUNIT_TEST( testGibiMeshDriver ); - //20 - CPPUNIT_TEST( testGrid ); - CPPUNIT_TEST( testGroup ); - CPPUNIT_TEST( testIndexCheckingPolicy ); - CPPUNIT_TEST( testInit /* cxx */ ); - //CPPUNIT_TEST( testInterlacingPolicy /* not in spec */ ); - //CPPUNIT_TEST( testInterlacingTraits /* not in spec */ ); - CPPUNIT_TEST( testMedFieldDriver21 ); - CPPUNIT_TEST( testMedFieldDriver22 ); - //CPPUNIT_TEST( testMedFieldDriver /* not in spec */ ); - CPPUNIT_TEST( testMed ); - //30 - CPPUNIT_TEST( testMedMedDriver21 ); - CPPUNIT_TEST( testMedMedDriver22 ); - //CPPUNIT_TEST( testMedMedDriver /* not in spec */ ); - //CPPUNIT_TEST( testMEDMEMchampLire /* not in spec */ ); - //CPPUNIT_TEST( testMEDMEMgaussEcr /* not in spec */ ); - //CPPUNIT_TEST( testMEDMEMprofilEcr /* not in spec */ ); - CPPUNIT_TEST( testMedMeshDriver21 ); - CPPUNIT_TEST( testMedMeshDriver22 ); - //CPPUNIT_TEST( testMedMeshDriver /* not in spec */ ); - CPPUNIT_TEST( testMedVersion ); - //40 - CPPUNIT_TEST( testMeshAndMeshing ); - CPPUNIT_TEST( testModulusArray ); - CPPUNIT_TEST( testnArray ); - CPPUNIT_TEST( testPointerOf ); - CPPUNIT_TEST( testPolyhedronArray ); - CPPUNIT_TEST( testPorflowMeshDriver ); - //CPPUNIT_TEST( testRCBase /* not in spec */ ); - //CPPUNIT_TEST( testSetInterlacingType /* not in spec */ ); - CPPUNIT_TEST( testSkyLineArray ); - //50 - CPPUNIT_TEST( testSTRING ); - CPPUNIT_TEST( testSupport ); - //CPPUNIT_TEST( testTags /* not in spec */ ); - CPPUNIT_TEST( testTopLevel ); - CPPUNIT_TEST( testTypeMeshDriver ); - CPPUNIT_TEST( testUnit ); - CPPUNIT_TEST( testVtkFieldDriver ); - CPPUNIT_TEST( testVtkMedDriver ); - CPPUNIT_TEST( testVtkMeshDriver ); - //CPPUNIT_TEST( testmedimport_src /* not in spec */ ); - //60 - CPPUNIT_TEST_SUITE_END(); - -public: - - void setUp(); - void tearDown(); - - void testArray(); - void testArrayConvert(); - //void testArrayInterface() /* not in spec */; - void testAsciiFieldDriver(); - //void testCellModel() /* not in spec */; - void testConnectivity(); - void testCoordinate(); - void testDriverFactory(); - //void testDriversDef() /* not in spec */; - //10 - //void testDriverTools() /* not in spec */; - void testException() /* not in spec */; - void testFamily(); - void testField(); - void testFieldConvert(); - void testFormulae(); - void testGaussLocalization(); - void testGibiMeshDriver(); - //20 - void testGrid(); - void testGroup(); - void testIndexCheckingPolicy(); - void testInit() /* cxx */; - //void testInterlacingPolicy() /* not in spec */; - //void testInterlacingTraits() /* not in spec */; - void testMedFieldDriver21(); - void testMedFieldDriver22(); - //void testMedFieldDriver /* not in spec */(); - void testMed(); - //30 - void testMedMedDriver21(); - void testMedMedDriver22(); - //void testMedMedDriver() /* not in spec */; - //void testMEDMEMchampLire() /* not in spec */; - //void testMEDMEMgaussEcr() /* not in spec */; - //void testMEDMEMprofilEcr() /* not in spec */; - void testMedMeshDriver21(); - void testMedMeshDriver22(); - //void testMedMeshDriver() /* not in spec */; - void testMedVersion(); - //40 - void testMeshAndMeshing(); - void testModulusArray(); - void testnArray(); - void testPointerOf(); - void testPolyhedronArray(); - void testPorflowMeshDriver(); - //void testRCBase() /* not in spec */; - //void testSetInterlacingType /* not in spec */(); - void testSkyLineArray(); - //50 - void testSTRING(); - void testSupport(); - //void testTags() /* not in spec */; - void testTopLevel(); - void testTypeMeshDriver(); - void testUnit(); - void testVtkFieldDriver(); - void testVtkMedDriver(); - void testVtkMeshDriver(); - //void testmedimport_src() /* not in spec */; - //60 -}; - -// to create a mesh with certain filling -MEDMEM::MESH * MEDMEMTest_createTestMesh(); - -// to automatically remove temporary files from disk -class MEDMEMTest_TmpFilesRemover -{ -public: - MEDMEMTest_TmpFilesRemover() {} - ~MEDMEMTest_TmpFilesRemover(); - bool Register(const std::string theTmpFile); - -private: - std::set<std::string> myTmpFiles; -}; - -/*! - * Tool to print array to stream. - */ -template<class T> -void MEDMEMTest_DumpArray (std::ostream & stream, const T* array, const int length, const std::string text) -{ - stream << text << ": {"; - if (length > 0) { - stream << array[0]; - for (int i = 1; i < length; i++) { - stream << ", " << array[i]; - } - } - stream << "}" << std::endl; -}; - -#endif diff --git a/src/MEDMEM/Test/MEDMEMTest_Array.cxx b/src/MEDMEM/Test/MEDMEMTest_Array.cxx deleted file mode 100644 index a83e40157..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Array.cxx +++ /dev/null @@ -1,673 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "MEDMEM_nArray.hxx" -#include "MEDMEM_ArrayConvert.hxx" -#include "MEDMEM_Array.hxx" -//#include "MEDMEM_ArrayInterface.hxx" -#include "MEDMEM_STRING.hxx" - -#include <sstream> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; - -// #1,2,3: MEDMEMTest_Array.cxx -// Check methods from MEDMEM_Array.hxx, MEDMEM_ArrayConvert.hxx, MEDMEM_ArrayInterface.hxx - -/*! - * Check methods (20), defined in MEDMEM_Array.hxx: - * template <class T> class MEDARRAY { - * (+) inline MEDARRAY(); - * (+) inline ~MEDARRAY(); - * (+) MEDARRAY (const int ld_values, const int length_values, - * const MED_EN::medModeSwitch mode=MED_EN::MED_FULL_INTERLACE); - * (+) MEDARRAY (T* values, const int ld_values, - * const int length_values, const MED_EN::medModeSwitch mode=MED_EN::MED_FULL_INTERLACE, - * bool shallowCopy=false, bool ownershipOfValues=false); - * (+) MEDARRAY (MEDARRAY const &m); - * (+) MEDARRAY (MEDARRAY const &m, bool copyOther); - * (+) MEDARRAY & operator = (const MEDARRAY & m); - * (+) MEDARRAY & shallowCopy(const MEDARRAY & m); - * (+) inline int getLeadingValue() const; - * (+) inline int getLengthValue() const; - * (+) const T * get (const MED_EN::medModeSwitch mode); - * (+) const T * getRow (const int i); - * (+) const T * getColumn (const int j); - * (+) const T getIJ (const int i, const int j) const; - * (+) inline MED_EN::medModeSwitch getMode() const; - * (+) void set (const MED_EN::medModeSwitch mode,const T* value); - * (+) void setI (const int i, const T* value); - * (+) void setJ (const int j, const T* value); - * (+) void setIJ (const int i, const int j, const T value); - * (+) void calculateOther(); - * (+) bool isOtherCalculated() const {return (const T*)_valuesOther != NULL;} - * (+) void clearOtherMode(); - * } - * - * Use code of MEDMEM/tests/testUArray.cxx, - * MEDMEM/test_MEDMEM_Array.cxx - */ -void MEDMEMTest::testArray() -{ - int SpaceDimension = 3; - int NumberOfNodes = 4; - - //////////// - // TEST 1 // - //////////// - - /* ---------------------------------------------------------- */ - /* */ - /* INITIALISATION */ - /* */ - /* - constructeur new MEDARRAY<int>(int,int,mode) */ - /* - get sur le pointeur MED_FULL_INTERLACE */ - /* - initialisation des valeurs (coordonnées ieme elt = I+1) */ - /* - get sur le pointeur MED_NO_INTERLACE */ - /* ---------------------------------------------------------- */ - - MEDARRAY<int> * myArrayfull = - new MEDARRAY<int> (SpaceDimension, NumberOfNodes, MED_EN::MED_FULL_INTERLACE); - CPPUNIT_ASSERT(myArrayfull != NULL); - - const int * myValues = myArrayfull->get(MED_EN::MED_FULL_INTERLACE); - CPPUNIT_ASSERT(myValues != NULL); - - for (int i = 0; i < NumberOfNodes; i++) { - for (int k = 0; k < SpaceDimension; k++) { - myArrayfull->setIJ(i+1, k+1, i+1); - } - } - - const int * myOthers = myArrayfull->get(MED_EN::MED_NO_INTERLACE); - CPPUNIT_ASSERT(myOthers != NULL); - - MEDARRAY<int> * myArrayno = new MEDARRAY<int>(SpaceDimension, NumberOfNodes, MED_EN::MED_NO_INTERLACE); - CPPUNIT_ASSERT(myArrayno != NULL); - const int * myValuesno = myArrayno->get(MED_EN::MED_NO_INTERLACE); - CPPUNIT_ASSERT(myValuesno != NULL); - - for (int k = 0; k < SpaceDimension; k++) { - for (int i = 0; i < NumberOfNodes; i++) { - myArrayno->setIJ(i+1, k+1, k+1); - } - } - - const int * myOthersno = myArrayno->get(MED_EN::MED_FULL_INTERLACE); - CPPUNIT_ASSERT(myOthersno != NULL); - - /* ---------------------------------------------------------- */ - /* */ - /* Tests des Fonctions Set */ - /* */ - /* - setI sur l'element 1 avec des coordonnees a 100 */ - /* - setJ sur l'element 1 avec des coordonnees a 100 */ - /* - setIJ sur (1,2) avec une coordonnee = 1992 */ - /* - set avec l ensemble des coordonnes remises à i */ - /* ---------------------------------------------------------- */ - - int * myNewLine = new int[SpaceDimension]; - for (int i = 0; i < SpaceDimension; i++) - myNewLine[i] = myValues[i] * 100; - try - { - myArrayfull->setI(1, myNewLine); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception in myArrayfull->setI()"); - } - - delete [] myNewLine; - - int * myNewCol = new int[NumberOfNodes]; - for (int i = 0; i < NumberOfNodes; i++) - myNewCol[i] = 100; - try - { - myArrayno->setJ(1, myNewCol); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception in myArrayno->setJ()"); - } - - delete [] myNewCol; - - try - { - myArrayfull->setIJ(1, 2, 1992); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception in myArrayfull->setIJ()"); - } - - try - { - myArrayno->setIJ(1, 2, 1992); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception in myArrayno->setIJ()"); - } - - int * mynewvalues = new int [ NumberOfNodes*SpaceDimension ]; - for (int i = 0; i < NumberOfNodes*SpaceDimension; i++) { - mynewvalues[i] = i; - } - try - { - myArrayfull->set(MED_EN::MED_FULL_INTERLACE, mynewvalues); - myValues = myArrayfull->get(MED_EN::MED_FULL_INTERLACE); - myOthers = myArrayfull->get(MED_EN::MED_NO_INTERLACE); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - myArrayno->set(MED_EN::MED_FULL_INTERLACE, mynewvalues); - myValuesno = myArrayfull->get(MED_EN::MED_FULL_INTERLACE); - myOthersno = NULL; - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - /* ---------------------------------------------------------- */ - /* */ - /* Tests des constructeurs */ - /* Tests des Fonctions Get */ - /* */ - /* ---------------------------------------------------------- */ - - // check sharing - MEDARRAY<int> * myArrayShare = new MEDARRAY<int>(*myArrayfull); - const int * sharevalues = myArrayShare->get(MED_EN::MED_FULL_INTERLACE); - const int * shareno = myArrayShare->get(MED_EN::MED_NO_INTERLACE); - - myArrayfull->setIJ(1, 2, 1993); - CPPUNIT_ASSERT(myArrayShare->getIJ(1,2) == 1993); - - myArrayShare->setIJ(1, 2, 1995); - CPPUNIT_ASSERT(myArrayfull->getIJ(1,2) == 1995); - - delete myArrayShare; - - // check no sharing - MEDARRAY<int> * myArrayShare2 = new MEDARRAY<int>(*myArrayfull, true); - sharevalues = myArrayShare2->get(MED_EN::MED_FULL_INTERLACE); - shareno = myArrayShare2->get(MED_EN::MED_NO_INTERLACE); - - myArrayfull->setIJ(1, 2, 18); - CPPUNIT_ASSERT(myArrayShare2->getIJ(1,2) == 1995); - myArrayShare2->setIJ(1, 2, 19); - CPPUNIT_ASSERT(myArrayfull->getIJ(1,2) == 18); - - // check myArrayno - myArrayno->set(MED_EN::MED_NO_INTERLACE, mynewvalues); - myArrayno->setIJ(2, 1, 1); - myValuesno = myArrayno->get(MED_EN::MED_NO_INTERLACE); - myOthersno = myArrayno->get(MED_EN::MED_FULL_INTERLACE); - - MEDARRAY<int> * myArrayShare3 = new MEDARRAY<int>(*myArrayno); - sharevalues = myArrayShare3->get(MED_EN::MED_FULL_INTERLACE); - shareno = myArrayShare3->get(MED_EN::MED_NO_INTERLACE); - - myArrayno->setIJ(1, 2, 1992); - CPPUNIT_ASSERT(myArrayShare3->getIJ(1,2) == 1992); - - myArrayShare3->setIJ(1, 2, 1995); - CPPUNIT_ASSERT(myArrayno->getIJ(1,2) == 1995); - - delete myArrayno; - delete [] mynewvalues; - delete myArrayfull; - delete myArrayShare2; - delete myArrayShare3; - - - //////////// - // TEST 2 // - //////////// - - MEDARRAY<int> * myArray = - new MEDARRAY<int> (SpaceDimension, NumberOfNodes, MED_EN::MED_FULL_INTERLACE); - - // - 1 1 1 - // - 2 2 2 - // - 3 3 3 - // - 4 4 4 - for (int i = 1; i <= NumberOfNodes; i++) - for (int j = 1; j <= SpaceDimension; j++) - myArray->setIJ(i, j, i); - - CPPUNIT_ASSERT(myArray->getLengthValue() == NumberOfNodes); - CPPUNIT_ASSERT(myArray->getLeadingValue() == SpaceDimension); - - int numberof = myArray->getLeadingValue(); // nb. of columns ~ space dimension - for (int i = 1; i <= myArray->getLengthValue(); i++) { - const int * node = myArray->getRow(i); - for (int j = 0; j < numberof; j++) { - CPPUNIT_ASSERT(node[j] == i); - } - } - - numberof = myArray->getLengthValue(); // nb. of rows ~ nb. of nodes - for (int i = 1; i <= myArray->getLeadingValue(); i++) { - const int * node = myArray->getColumn(i); - for (int j = 0; j < numberof; j++) { - CPPUNIT_ASSERT(node[j] == j + 1); - } - } - - numberof = myArray->getLeadingValue(); - for (int i = 1; i <= myArray->getLengthValue(); i++) { - for (int j = 1; j < numberof + 1; j++) { - CPPUNIT_ASSERT(myArray->getIJ(i,j) == i); - } - } - - numberof = myArray->getLeadingValue(); - int length = myArray->getLengthValue(); - const int * NoInterlaceArray = myArray->get(MED_EN::MED_NO_INTERLACE); - for (int i = 0; i < length; i++) { - for (int j = 0; j < numberof; j++) { - CPPUNIT_ASSERT(NoInterlaceArray[j*length+i] == i + 1); - } - } - - delete myArray; - - - //////////// - // TEST 3 // - //////////// - - // MEDARRAY (T* values, const int ld_values, - // const int length_values, const MED_EN::medModeSwitch mode=MED_EN::MED_FULL_INTERLACE, - // bool shallowCopy=false, bool ownershipOfValues=false); - - int ld = 7, nb = 4; - double rr = 13.0, h0 = 7.0; - double * aValues = new double [ld * nb]; - for (int nn = 0; nn < nb; nn++) { - aValues[nn*ld + 0] = nn; - aValues[nn*ld + 1] = rr * cos(nn * M_PI/4.); - aValues[nn*ld + 2] = rr * sin(nn * M_PI/4.); - aValues[nn*ld + 3] = h0 + nn; - aValues[nn*ld + 4] = 2.0 * rr * cos(nn * M_PI/4.); - aValues[nn*ld + 5] = 2.0 * rr * sin(nn * M_PI/4.); - aValues[nn*ld + 6] = h0 - nn; - } - - MEDARRAY<double> * aSpiral = - new MEDARRAY<double> (aValues, ld, nb, MED_EN::MED_FULL_INTERLACE, - /*shallowCopy=*/false, /*ownershipOfValues=*/false); - ///*shallowCopy=*/true, /*ownershipOfValues=*/true); - - if (aSpiral->isOtherCalculated()) - aSpiral->clearOtherMode(); - CPPUNIT_ASSERT(!aSpiral->isOtherCalculated()); - - CPPUNIT_ASSERT(aSpiral->getMode() == MED_EN::MED_FULL_INTERLACE); - aSpiral->calculateOther(); - CPPUNIT_ASSERT(aSpiral->getMode() == MED_EN::MED_FULL_INTERLACE); - CPPUNIT_ASSERT(aSpiral->getLeadingValue() == ld); - CPPUNIT_ASSERT(aSpiral->getLengthValue() == nb); - - //CPPUNIT_ASSERT_DOUBLES_EQUAL(expected, actual, delta); - double delta = 0.000001; - const double* comp5 = aSpiral->getColumn(5); - for (int nn = 0; nn < nb; nn++) { - const double* pnt = aSpiral->getRow(nn + 1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.0 * rr * cos(nn * M_PI/4.), pnt[4], delta); - CPPUNIT_ASSERT_DOUBLES_EQUAL(comp5[nn], pnt[4], delta); - } - - // Check operator= and method shallowCopy() - double c7n3 = aSpiral->getIJ(3, 7); - MEDARRAY<double> shc, cpy; - -// #ifdef ENABLE_FAULTS -// // (BUG) MEDARRAY<T>::shallowCopy() usage leads to memory leaks, -// // because on attemp to free both arrays we have Segmentation Fault -// shc.shallowCopy(*aSpiral); - -// // hangs up -// //MEDARRAY<double> arr (10, 10); -// //MEDARRAY<double> shc; -// //shc.shallowCopy(arr); - -// // Segmentation fault -// //MEDARRAY<double>* arr = new MEDARRAY<double> (10, 10); -// //MEDARRAY<double>* shc = new MEDARRAY<double> (10, 10); -// //shc->shallowCopy(*arr); -// //delete arr; -// //delete shc; -// #endif -// #ifdef ENABLE_FORCED_FAILURES -// CPPUNIT_FAIL("MEDARRAY<T>::shallowCopy(): wrong memory management"); -// #endif - - cpy = *aSpiral; - - aSpiral->setIJ(3, 7, c7n3 * 2.0); - -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_DOUBLES_EQUAL(c7n3 * 2.0, shc.getIJ(3, 7), delta); -#endif - - //CPPUNIT_ASSERT_DOUBLES_EQUAL(c7n3 * 2.0, cpy.getIJ(3, 7), delta); - CPPUNIT_ASSERT_DOUBLES_EQUAL(c7n3, cpy.getIJ(3, 7), delta); - -// #ifdef ENABLE_FORCED_FAILURES -// // Comments to deep copy constructor do not correspond to actual implementation -// CPPUNIT_FAIL("Comments to MEDARRAY<T> deep copy constructor do not correspond to actual implementation"); -// #endif - - aSpiral->clearOtherMode(); - //CPPUNIT_ASSERT_THROW(MEDARRAY<double> co (*aSpiral, true), MEDEXCEPTION); - CPPUNIT_ASSERT_NO_THROW(MEDARRAY<double> co (*aSpiral, true)); - - // invalid cases - //double arr3 [3] = {1., 2., 3.}; - double arr4 [4] = {1., 2., 3., 4.}; - double arr7 [7] = {1., 2., 3., 4., 5., 6., 7.}; - CPPUNIT_ASSERT_THROW(aSpiral->getRow(0), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSpiral->getRow(nb + 1), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSpiral->getColumn(0), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSpiral->getColumn(ld + 1), MEDEXCEPTION); - //CPPUNIT_ASSERT_THROW(aSpiral->set(MED_EN::MED_FULL_INTERLACE, NULL), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSpiral->setI(-1, arr7), MEDEXCEPTION); - //CPPUNIT_ASSERT_THROW(aSpiral->setI(1, NULL), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSpiral->setJ(-1, arr4), MEDEXCEPTION); - //CPPUNIT_ASSERT_THROW(aSpiral->setJ(1, NULL), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSpiral->setIJ(-1, -1, 13.), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSpiral->setIJ(1, 0, 13.), MEDEXCEPTION); - //CPPUNIT_ASSERT_THROW(aSpiral->setI(1, arr3), MEDEXCEPTION); // user must control itself - - delete aSpiral; - - // check empty array - - MEDARRAY<double> anEmptyArray; - //CPPUNIT_ASSERT_NO_THROW(MEDARRAY<double> anArr1 (anEmptyArray)); // INTERRUPTION - //CPPUNIT_ASSERT_NO_THROW(MEDARRAY<double> anArr2 (anEmptyArray, false)); // fails - //CPPUNIT_ASSERT_NO_THROW(MEDARRAY<double> anArr4 = anEmptyArray); // INTERRUPTION - //MEDARRAY<double> anArr5; - //CPPUNIT_ASSERT_NO_THROW(anArr5.shallowCopy(anEmptyArray)); - - // invalid cases - CPPUNIT_ASSERT_THROW(anEmptyArray.get(MED_EN::MED_FULL_INTERLACE), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(anEmptyArray.get(MED_EN::MED_NO_INTERLACE), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(anEmptyArray.getRow(0), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(anEmptyArray.getRow(5), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(anEmptyArray.getColumn(0), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(anEmptyArray.getIJ(0, 0), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(anEmptyArray.getIJ(1, 1), MEDEXCEPTION); - CPPUNIT_ASSERT_NO_THROW(anEmptyArray.set(MED_EN::MED_FULL_INTERLACE, aValues)); - CPPUNIT_ASSERT_THROW(anEmptyArray.setI(1, aValues), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(anEmptyArray.setIJ(0, 0, 3.), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(anEmptyArray.setIJ(1, 1, 3.), MEDEXCEPTION); - - CPPUNIT_ASSERT_THROW(MEDARRAY<double> bad (-1, 10), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(MEDARRAY<double> bad (10, -1), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(MEDARRAY<double> bad (-1, -1), MEDEXCEPTION); - - delete [] aValues; - - // construction with taking ownership of values - int ld1 = 7, nb1 = 4; - double * val1 = new double [ld * nb]; - for (int nn = 0; nn < nb1; nn++) { - for (int cc = 0; cc < ld1; cc++) { - val1[nn*ld1 + cc] = nn; - } - } - MEDARRAY<double> * arr1 = - new MEDARRAY<double> (val1, ld1, nb1, MED_EN::MED_FULL_INTERLACE, - /*shallowCopy=*/true, /*ownershipOfValues=*/true); - for (int nn = 1; nn <= nb1; nn++) { - for (int cc = 1; cc <= ld1; cc++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(nn - 1, arr1->getIJ(nn, cc), delta); - } - } - delete arr1; -} - -/*! - * Check methods (4), defined in MEDMEM_ArrayConvert.hxx: - * - * (+) Gauss NoInterlace->FullInterlace: - * template <class T, class CHECKING_POLICY > - * MEDMEM_Array<T, FullInterlaceGaussPolicy, CHECKING_POLICY> * - * ArrayConvert(const MEDMEM_Array< T, NoInterlaceGaussPolicy, CHECKING_POLICY > &array, T* values=0) - * - * (+) Gauss FullInterlace->NoInterlace: - * template <class T, class CHECKING_POLICY> - * MEDMEM_Array<T, NoInterlaceGaussPolicy, CHECKING_POLICY> * - * ArrayConvert(const MEDMEM_Array< T, FullInterlaceGaussPolicy, CHECKING_POLICY > &array, T* values=0) - * - * (+) NoGauss FullInterlace->NoInterlace: - * template <class T, class CHECKING_POLICY> - * MEDMEM_Array<T, NoInterlaceNoGaussPolicy, CHECKING_POLICY> * - * ArrayConvert(const MEDMEM_Array< T, FullInterlaceNoGaussPolicy, CHECKING_POLICY > &array, T* values=0) - * - * (+) NoGauss NoInterlace->FullInterlace: - * template <class T, class CHECKING_POLICY> - * MEDMEM_Array<T, FullInterlaceNoGaussPolicy, CHECKING_POLICY> * - * ArrayConvert(const MEDMEM_Array< T, NoInterlaceNoGaussPolicy, CHECKING_POLICY > &array, T* values=0) - * - * Use code of MEDMEM/test_MEDMEM_nArray.cxx - */ -void MEDMEMTest::testArrayConvert() -{ - // TEST n°1 : FullInterlaceNoGaussPolicy -> NoInterlaceNoGaussPolicy - - const int mdim = 2; - const int nbelem1 = 20; - - const double array1Ref[] = { 11 , 12 , 21 , 22 , 31 , 32 , 41 , 42 , 51 , 52 , - 61 , 62 , 71 , 72 , 81 , 82 , 91 , 92 , 101, 102, - 111, 112, 121, 122, 131, 132, 141, 142, 151, 152, - 161, 162, 171, 172, 181, 182, 191, 192, 201, 202 }; - - const double array2Ref[] = { 11 , 21 , 31 , 41 , 51 , 61 , 71 , 81 , 91 , 101, - 111, 121, 131, 141, 151, 161, 171, 181, 191, 201, - 12 , 22 , 32 , 42 , 52 , 62 , 72 , 82 , 92 , 102, - 112, 122, 132, 142, 152, 162, 172, 182, 192, 202 }; - - MEDMEM_Array<double> myArray1 (mdim, nbelem1); - - for (int i = 1; i <= nbelem1; i++) - for (int j = 1; j <= mdim; j++) - myArray1.setIJ(i, j, i*10+j); - - const double * myArray1Ptr = myArray1.getPtr(); - for (int i = 0; i < mdim*nbelem1; i++) - CPPUNIT_ASSERT(myArray1Ptr[i] == array1Ref[i]); - - MEDMEM_Array<double, NoInterlaceNoGaussPolicy> * myArray1cin = ArrayConvert(myArray1); - myArray1Ptr = myArray1cin->getPtr(); - int elemno = 0; - for (int j = 1; j <= mdim; j++) { - for (int i = 1; i <= nbelem1; i++) { - CPPUNIT_ASSERT(myArray1cin->getIJ(i,j) == array2Ref[elemno]); - CPPUNIT_ASSERT(myArray1Ptr[elemno] == array2Ref[elemno]); - elemno++; - } - } - - // TEST n°2 : NoInterlaceNoGaussPolicy -> FullInterlaceNoGaussPolicy - - MEDMEM_Array<double, NoInterlaceNoGaussPolicy> myArray2 (mdim, nbelem1); - - for (int i = 1; i <= nbelem1; i++) - for (int j = 1; j <= mdim; j++) - myArray2.setIJ(i, j, i*10+j); - - const double * myArray2Ptr = myArray2.getPtr(); - for (int i = 0; i < mdim*nbelem1; i++) - CPPUNIT_ASSERT(myArray2Ptr[i] == array2Ref[i]); - - MEDMEM_Array<double, FullInterlaceNoGaussPolicy> * myArray2cin = ArrayConvert(myArray2); - myArray2Ptr = myArray2cin->getPtr(); - elemno = 0; - for (int i = 1; i <= nbelem1; i++) { - for (int j = 1; j <= mdim; j++) { - CPPUNIT_ASSERT(myArray2cin->getIJ(i,j) == array1Ref[elemno]); - CPPUNIT_ASSERT(myArray2Ptr[elemno] == array1Ref[elemno]); - elemno++; - } - } - - // TEST n°3 : FullInterlaceGaussPolicy -> NoInterlaceGaussPolicy - - const int nbelem2 = 5; - const int nbtypegeo = 2; - const int nbelgeoc[nbtypegeo+1] = {1,3,6}; - const int nbgaussgeo[nbtypegeo+1] = {-1,2,3}; - - const double * myArray3Ptr = 0; - const double array3Ref[] = { 1.11, 1.12, 1.21, 1.22, - 2.11, 2.12, 2.21, 2.22, - 13.11, 13.12, 13.21, 13.22, 13.31, 13.32, - 14.11, 14.12, 14.21, 14.22, 14.31, 14.32, - 15.11, 15.12, 15.21, 15.22, 15.31, 15.32 }; - - const double array4Ref[] = { 1.11, 1.21, 2.11, 2.21, - 13.11, 13.21, 13.31, 14.11, 14.21, 14.31, - 15.11, 15.21, 15.31, - 1.12, 1.22, 2.12, 2.22, - 13.12, 13.22, 13.32, 14.12, 14.22, 14.32, - 15.12, 15.22, 15.32 }; - - MEDMEM_Array<double, FullInterlaceGaussPolicy> myArray3 - (mdim, nbelem2, nbtypegeo, nbelgeoc, nbgaussgeo); - - elemno = 1; - for (int ntyp = 1; ntyp <= nbtypegeo; ntyp++) { - for (int i = 0; i < (nbelgeoc[ntyp]-nbelgeoc[ntyp-1]); i++) { - for (int k = 1; k <= nbgaussgeo[ntyp]; k++) { - for (int j = 1; j <= mdim; j++) { - myArray3.setIJK(elemno, j, k, elemno+(ntyp-1)*10+0.1*k+0.01*j); - } - } - elemno++; - } - } - myArray3Ptr = myArray3.getPtr(); - for (int i = 0; i < myArray3.getArraySize(); i++) - CPPUNIT_ASSERT(myArray3Ptr[i] == array3Ref[i]); - - MEDMEM_Array<double, NoInterlaceGaussPolicy> * myArray3cin = ArrayConvert(myArray3); - myArray3Ptr = myArray3cin->getPtr(); - elemno = 0; - for (int j = 1; j <= mdim; j++) - for (int i = 1; i < nbelgeoc[nbtypegeo]; i++) - for (int k = 1; k <= myArray3cin->getNbGauss(i); k++) { - CPPUNIT_ASSERT(myArray3cin->getIJK(i,j,k) == array4Ref[elemno]); - CPPUNIT_ASSERT(myArray3Ptr[elemno] == array4Ref[elemno]); - elemno++; - } - - // TEST n°4 : NoInterlaceGaussPolicy -> FullInterlaceGaussPolicy - - const double * myArray4Ptr = 0; - - MEDMEM_Array<double, NoInterlaceGaussPolicy> myArray4 - (mdim, nbelem2, nbtypegeo, nbelgeoc, nbgaussgeo); - - elemno = 1; - for (int ntyp = 1; ntyp <= nbtypegeo; ntyp++) { - for (int i = 0; i < (nbelgeoc[ntyp]-nbelgeoc[ntyp-1]); i++) { - for (int k = 1; k <= nbgaussgeo[ntyp]; k++) { - for (int j = 1; j <= mdim; j++) { - myArray4.setIJK(elemno, j, k, elemno+(ntyp-1)*10+0.1*k+0.01*j); - } - } - elemno++; - } - } - myArray4Ptr = myArray4.getPtr(); - - for (int i = 0; i < myArray4.getArraySize(); i++) - CPPUNIT_ASSERT(myArray4Ptr[i] == array4Ref[i]); - - MEDMEM_Array<double, FullInterlaceGaussPolicy> * myArray4cin = ArrayConvert(myArray4); - myArray4Ptr = myArray4cin->getPtr(); - elemno = 0; - for (int i = 1; i < nbelgeoc[nbtypegeo]; i++) - for (int k = 1; k <= myArray4cin->getNbGauss(i); k++) - for (int j = 1; j <= mdim; j++) { - CPPUNIT_ASSERT(myArray4cin->getIJK(i,j,k) == array3Ref[elemno]); - CPPUNIT_ASSERT(myArray4cin->getIJK(i,j,k) == myArray3.getIJK(i,j,k)); - CPPUNIT_ASSERT(myArray4Ptr[elemno] == array3Ref[elemno]); - elemno++; - } -} - -/*! - * Check methods (not in spec), defined in MEDMEM_ArrayInterface.hxx: - */ -//void MEDMEMTest::testArrayInterface() -//{ -// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); -//} diff --git a/src/MEDMEM/Test/MEDMEMTest_Array_fault.cxx b/src/MEDMEM/Test/MEDMEMTest_Array_fault.cxx deleted file mode 100644 index a74037241..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Array_fault.cxx +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEM_Array.hxx" - -#include <cmath> - -using namespace std; -using namespace MEDMEM; - -/*! - * Check method shallowCopy() - */ -int main (int argc, char** argv) -{ - int ld = 7, nb = 4; - double rr = 13.0, h0 = 7.0; - double * aValues = new double [ld * nb]; - for (int nn = 0; nn < nb; nn++) { - aValues[nn*ld + 0] = nn; - aValues[nn*ld + 1] = rr * cos(nn * M_PI/4.); - aValues[nn*ld + 2] = rr * sin(nn * M_PI/4.); - aValues[nn*ld + 3] = h0 + nn; - aValues[nn*ld + 4] = 2.0 * rr * cos(nn * M_PI/4.); - aValues[nn*ld + 5] = 2.0 * rr * sin(nn * M_PI/4.); - aValues[nn*ld + 6] = h0 - nn; - } - - MEDARRAY<double> * aSpiral = - new MEDARRAY<double> (aValues, ld, nb, MED_EN::MED_FULL_INTERLACE, - /*shallowCopy=*/false, /*ownershipOfValues=*/false); - - // Check method shallowCopy() - MEDARRAY<double> shc; - - // (BUG) MEDARRAY<T>::shallowCopy() usage leads to memory leaks, - // because on attempt to free both arrays we have Segmentation Fault - shc.shallowCopy(*aSpiral); - - delete aSpiral; - - // hangs up - //MEDARRAY<double> arr (10, 10); - //MEDARRAY<double> shc; - //shc.shallowCopy(arr); - - // Segmentation fault - //MEDARRAY<double>* arr = new MEDARRAY<double> (10, 10); - //MEDARRAY<double>* shc = new MEDARRAY<double> (10, 10); - //shc->shallowCopy(*arr); - //delete arr; - //delete shc; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_AsciiFieldDriver.cxx b/src/MEDMEM/Test/MEDMEMTest_AsciiFieldDriver.cxx deleted file mode 100644 index dd94b6530..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_AsciiFieldDriver.cxx +++ /dev/null @@ -1,282 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "MEDMEM_Compatibility21_22.hxx" -#include "MEDMEM_AsciiFieldDriver.hxx" -#include "MEDMEM_STRING.hxx" - -#include <stdio.h> - -#include <sstream> -#include <fstream.h> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; - -// #4: MEDMEM_AsciiFieldDriver.hxx } MEDMEMTest_AsciiFieldDriver.cxx - -/*! - * Check methods (8), defined in MEDMEM_AsciiFieldDriver.hxx: - * - * (+) template<int N,unsigned int CODE> void fill(double *a, const double *b) - * (+) template<int N> bool compare(const double* a, const double* b) - * (+) template<> void fill<-1,0x3>(double *a, const double *b); - * (+) template<> bool compare<-1>(const double *a, const double *b); - * - * template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY> - * class SDForSorting { - * (+) SDForSorting(const double *coords, const T* comp, int nbComponents); - * (+) SDForSorting(const SDForSorting& other); - * (+) ~SDForSorting(); - * (+) bool operator< (const SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>& other) const; - * (+) void writeLine(ofstream& file) const; - * } - * - * template <class T> - * class ASCII_FIELD_DRIVER : public GENDRIVER { - * - * //MUST BE PRIVATE as there is no possibility to set _ptrField after this constructor usage - * (-) template <class INTERLACING_TAG> ASCII_FIELD_DRIVER(); - * - * (+) template <class INTERLACING_TAG> - * ASCII_FIELD_DRIVER(const string & fileName, FIELD<T,INTERLACING_TAG> * ptrField, - * MED_EN::med_sort_direc direction=MED_EN::ASCENDING, const char *priority=""); - * (+) ASCII_FIELD_DRIVER(const ASCII_FIELD_DRIVER<T>& other); - * (+) void open() throw (MEDEXCEPTION); - * (+) void close(); - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void write(void) const throw (MEDEXCEPTION); - * (+) GENDRIVER* copy() const; - * } - */ -void MEDMEMTest::testAsciiFieldDriver() -{ - // read a mesh from a MED file - string datadir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - string filename = datadir + "/MedFiles/pointe.med"; - string meshname = "maa1"; - string fieldname = "fieldcelldouble"; - - if (tmp_dir == "") - tmp_dir = "/tmp"; - string anyfile1 = tmp_dir + "/anyfile1"; - string SDFfilename = tmp_dir + "/myfile"; - ofstream aFile(SDFfilename.c_str()); - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(anyfile1); - aRemover.Register(SDFfilename); - - //Test SDForSorting class - { - double coord_1[10] = { 1.0, 2.0, - -1.0, 2.0, - 3.6, -8.7, - 10.0, -10.0, - 12.3, 9.3}; - - int comp_1[5] = {1, 3, 5, 7, 9}; - SDForSorting<int, 2, 48> aSDF_1(coord_1, comp_1, 5); - - SDForSorting<int, 2, 48> aSDFCpy_1 = SDForSorting<int, 2, 48>(aSDF_1); - CPPUNIT_ASSERT_EQUAL(aSDFCpy_1 < aSDF_1, false); - CPPUNIT_ASSERT_NO_THROW(aSDF_1.writeLine(aFile)); - } - - // Why functions - // template<> void MEDMEM::fill<-1,0x3>(double *a, const double *b) - // and - // template<> bool MEDMEM::compare<-1>(const double *a, const double *b) - // declared in MEDMEM_AsciiFieldDriver.hxx, - // are implemented in MEDMEM_DriverFactory.cxx? - - // template<int N,unsigned int CODE> void fill(double *a, const double *b) - { - // 0x3 = 110000 - double aa[3]; - double bb[3] = {1,2,3}; - - fill<2,198>(aa, bb); // ZYX // 11000110 // 012 - //MEDMEMTest_DumpArray<double>(cout, aa, 3, "aa filled with ZYX"); - CPPUNIT_ASSERT_EQUAL(aa[0], bb[0]); - CPPUNIT_ASSERT_EQUAL(aa[1], bb[1]); - CPPUNIT_ASSERT_EQUAL(aa[2], bb[2]); - - fill<2,210>(aa, bb); // ZXY // 11010010 // 102 - //MEDMEMTest_DumpArray<double>(cout, aa, 3, "aa filled with ZXY"); - CPPUNIT_ASSERT_EQUAL(aa[0], bb[1]); - CPPUNIT_ASSERT_EQUAL(aa[1], bb[0]); - CPPUNIT_ASSERT_EQUAL(aa[2], bb[2]); - - fill<2,228>(aa, bb); // XYZ // 11100100 // 210 - //MEDMEMTest_DumpArray<double>(cout, aa, 3, "aa filled with XYZ"); - CPPUNIT_ASSERT_EQUAL(aa[0], bb[2]); - CPPUNIT_ASSERT_EQUAL(aa[1], bb[1]); - CPPUNIT_ASSERT_EQUAL(aa[2], bb[0]); - } - - // template<int N> bool compare(const double* a, const double* b) - { - { - // aa < bb - double aa[8] = {1,1,1,1,1,1,1,1}; - double bb[8] = {1,1,1,1,1,1,1,2}; - CPPUNIT_ASSERT(compare<7>(aa, bb)); - } - - { - // aa < bb - double aa[8] = {1,1,1,1,1,1,1,1}; - double bb[8] = {2,1,1,1,1,1,1,1}; - CPPUNIT_ASSERT(compare<7>(aa, bb)); - } - - { - // aa > bb - double aa[8] = {2,1,1,1,1,1,1,1}; - double bb[8] = {1,1,1,1,1,1,1,1}; - CPPUNIT_ASSERT(!compare<7>(aa, bb)); - } - - { - // aa == bb - double aa[8] = {1,1,1,1,1,1,1,1}; - double bb[8] = {1,1,1,1,1,1,1,1}; - CPPUNIT_ASSERT(!compare<7>(aa, bb)); - } - - { - // compare<-1> - double aa[8] = {2,1,1,1,1,1,1,1}; - double bb[8] = {1,1,1,1,1,1,1,1}; - CPPUNIT_ASSERT(!compare<-1>(aa, bb)); - } - } - - // Test ASCII_FIELD_DRIVER - FIELD<double> * aField1 = new FIELD<double> (MED_DRIVER, filename, fieldname); - const SUPPORT * aSupport = aField1->getSupport(); - MESH * aMesh = new MESH (MED_DRIVER, filename, aSupport->getMeshName()); - aSupport->setMesh(aMesh); - - // create an ASCII driver for a field - ASCII_FIELD_DRIVER<double> * aDriver1 = - new ASCII_FIELD_DRIVER<double> (anyfile1, aField1, MED_EN::ASCENDING, ""); - CPPUNIT_ASSERT(aDriver1); - - CPPUNIT_ASSERT(aDriver1->getFileName() == anyfile1); - CPPUNIT_ASSERT(aDriver1->getAccessMode() == MED_EN::MED_ECRI); - - // and write the field on disk - - // must throw because the file is not opened - - CPPUNIT_ASSERT_THROW(aDriver1->write(), MEDEXCEPTION); - - aDriver1->open(); - - // must throw because the file is opened - - CPPUNIT_ASSERT_THROW(aDriver1->open(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aDriver1->setFileName("anyfile2"), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aDriver1->setFileName(anyfile1), MEDEXCEPTION); - - - // must throw because it is a writeonly driver - CPPUNIT_ASSERT_THROW(aDriver1->read(), MEDEXCEPTION); - - aDriver1->write(); - aDriver1->close(); - - // must throw because the file is not opened - - CPPUNIT_ASSERT_THROW(aDriver1->write(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aDriver1->close(), MEDEXCEPTION); - - // check priority definition - int spaceDimension = aMesh->getSpaceDimension(); - if (spaceDimension == 3) { - // good - CPPUNIT_ASSERT_NO_THROW(ASCII_FIELD_DRIVER<double> aDriver2 - ("anyfile2", aField1, MED_EN::ASCENDING, "XYZ")); - // too long - CPPUNIT_ASSERT_THROW(ASCII_FIELD_DRIVER<double> aDriver3 - ("anyfile3", aField1, MED_EN::ASCENDING, "XYZX"), MEDEXCEPTION); - // too short - CPPUNIT_ASSERT_THROW(ASCII_FIELD_DRIVER<double> aDriver4 - ("anyfile4", aField1, MED_EN::ASCENDING, "XY"), MEDEXCEPTION); - // invalid -#ifdef ENABLE_FORCED_FAILURES - // (BUG) This assert fails because 'A'(and 'B', and 'C') < 'X' - CPPUNIT_ASSERT_THROW(ASCII_FIELD_DRIVER<double> aDriver5 - ("anyfile5", aField1, MED_EN::ASCENDING, "ABC"), MEDEXCEPTION); -#endif - } - else if (spaceDimension == 2) { - // good - CPPUNIT_ASSERT_NO_THROW(ASCII_FIELD_DRIVER<double> aDriver2 - ("anyfile2", aField1, MED_EN::ASCENDING, "XY")); - // too long - CPPUNIT_ASSERT_THROW(ASCII_FIELD_DRIVER<double> aDriver3 - ("anyfile3", aField1, MED_EN::ASCENDING, "XYZ"), MEDEXCEPTION); - // too short - CPPUNIT_ASSERT_THROW(ASCII_FIELD_DRIVER<double> aDriver4 - ("anyfile4", aField1, MED_EN::ASCENDING, "X"), MEDEXCEPTION); - // invalid -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Invalid string is accepted for priority - CPPUNIT_ASSERT_THROW(ASCII_FIELD_DRIVER<double> aDriver5 - ("anyfile5", aField1, MED_EN::ASCENDING, "AB"), MEDEXCEPTION); -#endif - } - else { - CPPUNIT_FAIL("Cannot test ASCII_FIELD_DRIVER because file pointe.med" - " contains mesh of wrong dimension: must be 2 or 3"); - } - - //Copy constructor - ASCII_FIELD_DRIVER<double> aDriver1_Cpy1 = ASCII_FIELD_DRIVER<double> (*aDriver1); - - //Test copy() function - ASCII_FIELD_DRIVER<double> *aDriver1_Cpy2 = (ASCII_FIELD_DRIVER<double>*)aDriver1->copy(); - - //Compare objects -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_EQUAL(aDriver1_Cpy1, *aDriver1); - CPPUNIT_ASSERT_EQUAL(*aDriver1_Cpy2, *aDriver1); -#endif - - // free memory - delete aDriver1; - delete aField1; - delete aMesh; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_Connectivity.cxx b/src/MEDMEM/Test/MEDMEMTest_Connectivity.cxx deleted file mode 100644 index a770abde7..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Connectivity.cxx +++ /dev/null @@ -1,1745 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "MEDMEM_Connectivity.hxx" -#include "MEDMEM_define.hxx" -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" - -#include <sstream> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; - -// #7: MEDMEM_Connectivity.hxx } MEDMEMTest_Connectivity.cxx - -/*! - * Check methods (56), defined in MEDMEM_Connectivity.hxx: - * class CONNECTIVITY { - * (+) friend ostream & operator<<(ostream &os, CONNECTIVITY &connectivity); - * (+) CONNECTIVITY (MED_EN::medEntityMesh Entity=MED_EN::MED_CELL); - * (+) CONNECTIVITY (int numberOfTypes, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL); - * (+) CONNECTIVITY (const CONNECTIVITY & m); - * (+) virtual ~CONNECTIVITY (); - * (+) void setConstituent (CONNECTIVITY * Constituent) throw (MEDEXCEPTION); - * (+) void setGeometricTypes (const MED_EN::medGeometryElement * Types, - * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); - * (+) void setCount (const int * Count, const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); - * (+) void setNodal (const int * Connectivity, - * const MED_EN::medEntityMesh Entity, - * const MED_EN::medGeometryElement Type) throw (MEDEXCEPTION); - * (+) inline void setNumberOfNodes(int NumberOfNodes); - * (+) inline int getEntityDimension() const; - * (+) inline void setEntityDimension(int EntityDimension); - * ----------------------------------------------------------------------------------------------------- - * (+) void setPolygonsConnectivity(MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity, - * const int* PolygonsConnectivity, - * const int* PolygonsConnectivityIndex, - * int ConnectivitySize, int NumberOfPolygons); - * (+) void setPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType, - * const int* PolyhedronConnectivity, - * const int* PolyhedronIndex, int ConnectivitySize, - * int NumberOfPolyhedron, - * const int* PolyhedronFacesIndex= (int*) NULL, - * int NumberOfFaces=0); - * ----------------------------------------------------------------------------------------------------- - * (+) inline bool existConnectivity (MED_EN::medConnectivity connectivityType, - * MED_EN::medEntityMesh Entity) const; - * (+) virtual bool existPolygonsConnectivity(MED_EN::medConnectivity connectivityType, - * MED_EN::medEntityMesh Entity) const; - * (+) virtual bool existPolyhedronConnectivity(MED_EN::medConnectivity connectivityType, - * MED_EN::medEntityMesh Entity) const; - * - * (+) virtual void calculateConnectivity (MED_EN::medConnectivity connectivityType, - * MED_EN::medEntityMesh Entity); - * (?) virtual void updateFamily (const vector<FAMILY*>& myFamilies); - * - * (+) inline MED_EN::medEntityMesh getEntity() const; - * ----------------------------------------------------------------------------------------------------- - * (+) inline int getNumberOfTypes (MED_EN::medEntityMesh Entity) const; - * (+) int getNumberOfTypesWithPoly(MED_EN::medEntityMesh Entity) const; - * (+) const int * getConnectivityOfAnElementWithPoly - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity, int Number, int &lgth); - * (+) int getNumberOfPolyType() const; - * (+) int getNumberOfElementsWithPoly(MED_EN::medEntityMesh Entity, - * MED_EN::medGeometryElement Type) const; - * (+) int getNumberOfElementOfPolyType(MED_EN::medEntityMesh Entity) const; - * ----------------------------------------------------------------------------------------------------- - * (+) inline const MED_EN::medGeometryElement * getGeometricTypes - * (MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION); - * (+) MED_EN::medGeometryElement * getGeometricTypesWithPoly - * (MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION); - * ----------------------------------------------------------------------------------------------------- - * (+) MED_EN::medGeometryElement getElementType (MED_EN::medEntityMesh Entity, int Number) const; - * (+) MED_EN::medGeometryElement getElementTypeWithPoly - * (MED_EN::medEntityMesh Entity, int Number) const; - * ----------------------------------------------------------------------------------------------------- - * (+) inline MED_EN::medGeometryElement getPolyTypeRelativeTo() const; - * ----------------------------------------------------------------------------------------------------- - * (+) virtual inline const int * getGlobalNumberingIndex - * (MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION); - * ----------------------------------------------------------------------------------------------------- - * (+) virtual const int * getConnectivity (MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity, - * MED_EN::medGeometryElement Type); - * (+) virtual int getConnectivityLength (MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity, - * MED_EN::medGeometryElement Type); - * (+) virtual const int * getConnectivityIndex (MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity); - * ----------------------------------------------------------------------------------------------------- - * (+) virtual const int* getPolygonsConnectivity(MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity); - * (+) virtual const int* getPolygonsConnectivityIndex(MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity); - * (+) virtual int getNumberOfPolygons(MED_EN::medEntityMesh Entity=MED_EN::MED_ALL_ENTITIES) const; - * ----------------------------------------------------------------------------------------------------- - * (+) virtual const int* getPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType) const; - * (+) virtual const int* getPolyhedronFacesIndex() const; - * (+) virtual const int* getPolyhedronIndex(MED_EN::medConnectivity ConnectivityType) const; - * (+) virtual int getNumberOfPolyhedronFaces() const; - * (+) virtual int getNumberOfPolyhedron() const; - * (+) int *getNodesOfPolyhedron(int polyhedronId, int& lgthOfTab) const; - * (+) int **getNodesPerFaceOfPolyhedron(int polyhedronId, int& nbOfFaces, - * int* & nbOfNodesPerFaces) const; - * ----------------------------------------------------------------------------------------------------- - * (+) const CELLMODEL & getType (MED_EN::medGeometryElement Type) const; - * (+) const CELLMODEL * getCellsTypes (MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION); - * (+) string * getCellTypeNames (MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION); - * (+) int getNumberOfNodesInType (MED_EN::medGeometryElement Type) const; - * (+) int getNumberOfSubCellInType (MED_EN::medGeometryElement Type) const; - * ----------------------------------------------------------------------------------------------------- - * (+) virtual int getNumberOf (MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type) const; - * ----------------------------------------------------------------------------------------------------- - * (+) virtual const int* getValue (MED_EN::medConnectivity TypeConnectivity, - * MED_EN::medGeometryElement Type); - * (+) virtual const int* getValueIndex (MED_EN::medConnectivity TypeConnectivity); - * ----------------------------------------------------------------------------------------------------- - * (+) virtual inline const int* getReverseConnectivity (MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) throw (MEDEXCEPTION); - * (+) virtual inline const int* getReverseConnectivityIndex (MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) throw (MEDEXCEPTION); - * (NOT YET IMPLEMENTED!!!) const int* getNeighbourhood() const; - * (+) void invertConnectivityForAFace(int faceId, const int *nodalConnForFace, bool polygonFace=false); - * ----------------------------------------------------------------------------------------------------- - * (+) bool deepCompare(const CONNECTIVITY& other) const; - * - * Use code of MEDMEM/test_MEDMEM_PolyConnectivity.cxx - * MEDMEM/test_copie_connectivity.cxx - * } - */ -void showConnectivity(CONNECTIVITY * myConnectivity, - int MeshDimension, int NumberOfNodes, MED_EN::medEntityMesh Entity, - int NumberOfTypes) -{ - int entityDim = myConnectivity->getEntityDimension(); - CPPUNIT_ASSERT_EQUAL(MeshDimension, entityDim); //? - - //int nodesNb = myConnectivity->getNumberOfElements(MED_EN::MED_NODE, MED_EN::MED_NONE); - int nodesNb = myConnectivity->getNumberOfElementsWithPoly(MED_EN::MED_NODE, MED_EN::MED_NONE); - CPPUNIT_ASSERT_EQUAL(NumberOfNodes, nodesNb); //? - - // MED_EN::MED_CELL - MED_EN::medEntityMesh entity = myConnectivity->getEntity(); - CPPUNIT_ASSERT_EQUAL(Entity, entity); - - int typesNb = myConnectivity->getNumberOfTypes(Entity); - CPPUNIT_ASSERT_EQUAL(NumberOfTypes, typesNb); - - const MED_EN::medGeometryElement * Types = myConnectivity->getGeometricTypes(Entity); - - // Show Nodal Connectivity - cout << "Show Nodal Connectivity :" << endl; - for (int i = 0; i < NumberOfTypes; i++) { - cout << "For type " << Types[i] << " : " << endl; - int NumberOfElements = myConnectivity->getNumberOf(Entity, Types[i]); - const int * connectivity = - myConnectivity->getConnectivity(MED_EN::MED_NODAL, Entity, Types[i]); - int NomberOfNodesPerCell = Types[i]%100; - for (int j = 0; j < NumberOfElements; j++) { - cout << "Element " << j+1 << " : "; - for (int k = 0; k < NomberOfNodesPerCell; k++) { - cout << connectivity[j*NomberOfNodesPerCell + k] << " "; - } - cout << endl; - } - } - - // Show Reverse Nodal Connectivity - cout << "Show Reverse Nodal Connectivity :" << endl; - const int * ReverseNodalConnectivity = - myConnectivity->getReverseConnectivity(MED_EN::MED_NODAL, Entity); - const int * ReverseNodalConnectivityIndex = - myConnectivity->getReverseConnectivityIndex(MED_EN::MED_NODAL, Entity); - for (int i = 0; i < NumberOfNodes; i++) { - cout << "Node "<< i+1 << " : "; - for (int j = ReverseNodalConnectivityIndex[i]; j < ReverseNodalConnectivityIndex[i+1]; j++) - cout << ReverseNodalConnectivity[j-1] << " "; - cout << endl; - } - - // Show Descending Connectivity - cout << "Show Connectivity (Descending) :" << endl; - int NumberOfElements; - const int * connectivity; - const int * connectivity_index; - myConnectivity->calculateConnectivity(MED_EN::MED_DESCENDING, Entity); - try { - NumberOfElements = myConnectivity->getNumberOf(Entity, MED_EN::MED_ALL_ELEMENTS); - connectivity = myConnectivity->getConnectivity(MED_EN::MED_DESCENDING, Entity, - MED_EN::MED_ALL_ELEMENTS); - connectivity_index = myConnectivity->getConnectivityIndex(MED_EN::MED_DESCENDING, Entity); - } - catch (MEDEXCEPTION m) { - CPPUNIT_FAIL(m.what()); - } - - for (int j = 0; j < NumberOfElements; j++) { - cout << "Element " << j+1 << " : "; - for (int k = connectivity_index[j]; k < connectivity_index[j+1]; k++) - cout << connectivity[k-1] << " "; - cout << endl; - } - - // Get constituent entity type and quantity - int NumberOfConstituents = 0; - string constituent; - MED_EN::medEntityMesh constituentEntity; - - if (MeshDimension == 3) { - constituent = "Face"; - constituentEntity = MED_EN::MED_FACE; - } - - if (MeshDimension == 2) { - constituent = "Edge"; - constituentEntity = MED_EN::MED_EDGE; - } - - if (MeshDimension == 1) { - MESSAGE("ERROR : MeshDimension = 1 !"); - MESSAGE("We could not see Reverse Descending Connectivity."); - return; - } - - // Show Reverse Descending Connectivity - cout << "Show Reverse Descending Connectivity :" << endl; - const int * ReverseDescendingConnectivity = - myConnectivity->getReverseConnectivity(MED_EN::MED_DESCENDING, Entity); - const int * ReverseDescendingConnectivityIndex = - myConnectivity->getReverseConnectivityIndex(MED_EN::MED_DESCENDING, Entity); - - NumberOfConstituents = myConnectivity->getNumberOf(constituentEntity, MED_EN::MED_ALL_ELEMENTS); - for (int i = 0; i < NumberOfConstituents; i++) { - cout << constituent << i+1 << " : "; - for (int j = ReverseDescendingConnectivityIndex[i]; - j < ReverseDescendingConnectivityIndex[i+1]; j++) { - cout << ReverseDescendingConnectivity[j-1] << " "; - } - cout << endl; - } - - // Show <constituent> Nodal Connectivity - cout << "Show " << constituent << " Connectivity (Nodal) :" << endl; - const int * face_connectivity = - myConnectivity->getConnectivity(MED_EN::MED_NODAL, constituentEntity, MED_EN::MED_ALL_ELEMENTS); - const int * face_connectivity_index = - myConnectivity->getConnectivityIndex(MED_EN::MED_NODAL, constituentEntity); - for (int i = 0; i < NumberOfConstituents; i++) { - cout << constituent << i+1 << " : "; - for (int j = face_connectivity_index[i]; j < face_connectivity_index[i+1]; j++) - cout << face_connectivity[j-1] << " "; - cout << endl; - } -} - -///////////////////////////////////////// -// TEST 2: test_copie_connectivity.cxx // -///////////////////////////////////////// -void checkCopyConnectivity() -{ - string datadir = getenv("DATA_DIR"); - string filename = datadir + "/MedFiles/pointe.med"; - string meshname = "maa1"; - - //Construction d'un maillage - MESH * myMesh = new MESH(); - myMesh->setName(meshname); - MED_MESH_RDONLY_DRIVER myMeshDriver (filename, myMesh); - myMeshDriver.setMeshName(meshname); - myMeshDriver.open(); - myMeshDriver.read(); //A partir d'ici la connectivité est construite - myMeshDriver.close(); - - int aMeshDimension = myMesh->getMeshDimension(); - int aNumberOfNodes = myMesh->getNumberOfNodes(); - - const CONNECTIVITY * myConnectivity0 = myMesh->getConnectivityptr(); - CONNECTIVITY * myConnectivity1 = const_cast<CONNECTIVITY *>(myConnectivity0); - - // DATA: - MED_EN::medEntityMesh anEntity0 = myConnectivity0->getEntity(); - - int nbOfTypes = myConnectivity0->getNumberOfTypes(anEntity0); - - // Show - cout << "myConnectivity1 BEGIN" << endl; - cout << *myConnectivity1 << endl; - cout << "myConnectivity1 END" << endl; - showConnectivity(myConnectivity1, aMeshDimension, aNumberOfNodes, anEntity0, nbOfTypes); - cout << "myConnectivity1 END 2" << endl; - - ostringstream ostr1; - ostr1 << *myConnectivity1; - CPPUNIT_ASSERT(ostr1.str() != ""); - - // COPY - CONNECTIVITY * myConnectivity2 = new CONNECTIVITY(* myConnectivity0); - - // Compare - CPPUNIT_ASSERT(myConnectivity2->deepCompare(*myConnectivity0)); - - // Compare after deleting the initial connectivity - delete myMesh; - myMesh = NULL; - myConnectivity0 = NULL; - - MED_EN::medEntityMesh anEntity2 = myConnectivity2->getEntity(); - CPPUNIT_ASSERT_EQUAL(anEntity0, anEntity2); - - cout << "myConnectivity2 BEGIN" << endl; - cout << *myConnectivity2 << endl; - cout << "myConnectivity2 END" << endl; - showConnectivity(myConnectivity2, aMeshDimension, aNumberOfNodes, anEntity0, nbOfTypes); - cout << "myConnectivity2 END 2" << endl; - - ostringstream ostr2; - ostr2 << *myConnectivity2; - CPPUNIT_ASSERT(ostr1.str() == ostr2.str()); - - // ONE MORE COPY - CONNECTIVITY * myConnectivity3 = new CONNECTIVITY(* myConnectivity2); - delete myConnectivity2; - - MED_EN::medEntityMesh anEntity3 = myConnectivity3->getEntity(); - CPPUNIT_ASSERT_EQUAL(anEntity0, anEntity3); - - cout << "myConnectivity3 BEGIN" << endl; - cout << *myConnectivity3 << endl; - cout << "myConnectivity3 END" << endl; - showConnectivity(myConnectivity3, aMeshDimension, aNumberOfNodes, anEntity0, nbOfTypes); - cout << "myConnectivity3 END 2" << endl; - - ostringstream ostr3; - ostr3 << *myConnectivity3; - CPPUNIT_ASSERT_EQUAL(ostr1.str(), ostr3.str()); - - delete myConnectivity3; -} - -void createOrCheck (CONNECTIVITY * theC, string msg, bool create = false) -{ - // Preconditions: Entity and NumberOfTypes - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, MED_EN::MED_CELL, theC->getEntity()); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfTypes(MED_EN::MED_CELL)); - - // EntityDimension - if (create) - // It would be good to set EntityDimension automatically for EDGEs and FACEs, - // and warn about not set EntityDimension for CELLs - // (or calculate it from given geometric types) - theC->setEntityDimension(3); - else - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, theC->getEntityDimension()); - - // NumberOfNodes - int nbNodes = 20; - - if (create) { - theC->setNumberOfNodes(nbNodes); - } - else { - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nbNodes, theC->getNumberOfElementsWithPoly - (MED_EN::MED_NODE, MED_EN::MED_NONE)); - } - - // GeometricTypes - MED_EN::medGeometryElement aCellTypes[2] = {MED_EN::MED_PYRA5, MED_EN::MED_HEXA8}; - - // this variable is needed in check mode (!create) - // because of bug with getGlobalNumberingIndex() method (see below) - bool triaFirst = true; - - if (create) { - theC->setGeometricTypes(aCellTypes, MED_EN::MED_CELL); - CPPUNIT_ASSERT_THROW(theC->setGeometricTypes(aCellTypes, MED_EN::MED_NODE), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->setGeometricTypes(aCellTypes, MED_EN::MED_FACE), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->setGeometricTypes(aCellTypes, MED_EN::MED_EDGE), MEDEXCEPTION); - } - else { - // CELLS: theC - const MED_EN::medGeometryElement * aCellTypesBack = theC->getGeometricTypes(MED_EN::MED_CELL); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aCellTypes[0], aCellTypesBack[0]); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aCellTypes[1], aCellTypesBack[1]); - - const CELLMODEL * aCellModels = theC->getCellsTypes(MED_EN::MED_CELL); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aCellTypes[0], aCellModels[0].getType()); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aCellTypes[1], aCellModels[1].getType()); - - string * aCellTypesNames = theC->getCellTypeNames(MED_EN::MED_CELL); - CPPUNIT_ASSERT_MESSAGE(msg, aCellTypesNames[0] == "MED_PYRA5"); - CPPUNIT_ASSERT_MESSAGE(msg, aCellTypesNames[1] == "MED_HEXA8"); - - // FACES: theC->_constituent - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfTypes(MED_EN::MED_FACE)); - const MED_EN::medGeometryElement * aFaceTypesBack = theC->getGeometricTypes(MED_EN::MED_FACE); - triaFirst = (aFaceTypesBack[0] == MED_EN::MED_TRIA3 && aFaceTypesBack[1] == MED_EN::MED_QUAD4); - CPPUNIT_ASSERT_MESSAGE(msg, triaFirst || (aFaceTypesBack[1] == MED_EN::MED_TRIA3 && - aFaceTypesBack[0] == MED_EN::MED_QUAD4)); - - const CELLMODEL * aFaceModels = theC->getCellsTypes(MED_EN::MED_FACE); - bool case1 = (aFaceModels[0].getType() == MED_EN::MED_TRIA3 && - aFaceModels[1].getType() == MED_EN::MED_QUAD4); - bool case2 = (aFaceModels[1].getType() == MED_EN::MED_TRIA3 && - aFaceModels[0].getType() == MED_EN::MED_QUAD4); - CPPUNIT_ASSERT_MESSAGE(msg, case1 || case2); - - string * aFaceTypesNames = theC->getCellTypeNames(MED_EN::MED_FACE); - CPPUNIT_ASSERT_MESSAGE(msg, - (aFaceTypesNames[0] == "MED_TRIA3" && aFaceTypesNames[1] == "MED_QUAD4") || - (aFaceTypesNames[1] == "MED_TRIA3" && aFaceTypesNames[0] == "MED_QUAD4")); - - // EDGES: theC->_constituent->_constituent - //CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, theC->getNumberOfTypes(MED_EN::MED_EDGE)); - //const MED_EN::medGeometryElement * anEdgeTypesBack = theC->getGeometricTypes(MED_EN::MED_EDGE); - //const CELLMODEL * anEdgeModels = theC->getCellsTypes(MED_EN::MED_EDGE); - - // invalid cases - CPPUNIT_ASSERT_THROW(theC->getGeometricTypes(MED_EN::MED_NODE), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getGeometricTypes(MED_EN::MED_ALL_ENTITIES), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getCellsTypes(MED_EN::MED_NODE), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getCellTypeNames(MED_EN::MED_ALL_ENTITIES), MEDEXCEPTION); - } - - // Nodal Connectivity for standard types - int countCells[3] = {1, 3, 4}; // 2 PYRA5 and 1 HEXA8 - int nodesCells_PYRA5[10] = {2,3,4,5,1, 6,7,8,9,10}; - int nodesCells_HEXA8[8] = {2,3,4,5, 6,7,8,9}; - - // .1 - // - // 3.---------.4 - // /| /| - // / | / | - // / | / | - // 2.---------.5 | - // | | | | - // | 7.-----|---.8 - // | / | / - // | / | / - // |/ |/ - // 6.---------.9 - // - // .10 - - // cells index will be: {1, 6, 11, 19} - - if (create) { - theC->setCount(countCells, MED_EN::MED_CELL); - theC->setNodal(nodesCells_PYRA5, MED_EN::MED_CELL, MED_EN::MED_PYRA5); - theC->setNodal(nodesCells_HEXA8, MED_EN::MED_CELL, MED_EN::MED_HEXA8); - - // Invalid cases - CPPUNIT_ASSERT_THROW(theC->setCount(countCells, MED_EN::MED_NODE), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->setCount(countCells, MED_EN::MED_EDGE), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->setCount(countCells, MED_EN::MED_FACE), MEDEXCEPTION); - - CPPUNIT_ASSERT_THROW(theC->setNodal(nodesCells_PYRA5, MED_EN::MED_FACE, MED_EN::MED_PYRA5), MEDEXCEPTION); - } - else { - // CELLS(3D): theC - CPPUNIT_ASSERT_MESSAGE(msg, theC->existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL)); - CPPUNIT_ASSERT_MESSAGE(msg, theC->existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL)); - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_PYRA5)); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, theC->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_HEXA8)); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, theC->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS)); - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfElementsWithPoly(MED_EN::MED_CELL, - MED_EN::MED_PYRA5)); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, theC->getNumberOfElementsWithPoly(MED_EN::MED_CELL, - MED_EN::MED_HEXA8)); - - // sorted by geometric type (order is given by the typedef enum medGeometryElement) - const int * countCellsBack = theC->getGlobalNumberingIndex(MED_EN::MED_CELL); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, countCells[0], countCellsBack[0]); // 1: always - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, countCells[1], countCellsBack[1]); // 3: +2 PYRA5 - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, countCells[2], countCellsBack[2]); // 4: +1 HEXA8 - - // nodal connectivity length - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 18, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_CELL, - MED_EN::MED_ALL_ELEMENTS)); - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 10, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_CELL, - MED_EN::MED_PYRA5)); - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 8, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_CELL, - MED_EN::MED_HEXA8)); - - // nodal connectivity index - const int * connAllIndex = theC->getConnectivityIndex(MED_EN::MED_NODAL, MED_EN::MED_CELL); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, connAllIndex[0]); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, connAllIndex[1]); // +5 nodes of PYRA5 - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 11, connAllIndex[2]); // +5 nodes of PYRA5 - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 19, connAllIndex[3]); // +8 nodes of HEXA8 - - // nodal connectivity - const int * connAll = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL, - MED_EN::MED_ALL_ELEMENTS); - const int * connPYRA5 = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL, - MED_EN::MED_PYRA5); - const int * connHEXA8 = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL, - MED_EN::MED_HEXA8); - for (int i = 0; i < 10; i++) { - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_PYRA5[i], connPYRA5[i]); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_PYRA5[i], connAll[i]); - } - for (int i = 0; i < 8; i++) { - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_HEXA8[i], connHEXA8[i]); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_HEXA8[i], connAll[10 + i]); - } - - // descending connectivity length - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 16, theC->getConnectivityLength - (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS)); - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 10, theC->getConnectivityLength - (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_PYRA5)); - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 8, theC->getConnectivityLength - (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_HEXA8)); - - // descending connectivity index - const int * descAllIndex = theC->getConnectivityIndex(MED_EN::MED_DESCENDING, MED_EN::MED_CELL); - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, descAllIndex[0]); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, descAllIndex[1]); // +5 faces of PYRA5 - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 11, descAllIndex[2]); // +5 faces of PYRA5 - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 17, descAllIndex[3]); // +6 faces of HEXA8 - - // descending connectivity - { - const int * descAll = theC->getConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL, - MED_EN::MED_ALL_ELEMENTS); - const int * descPYRA5 = theC->getConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL, - MED_EN::MED_PYRA5); - const int * descHEXA8 = theC->getConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL, - MED_EN::MED_HEXA8); - for (int i = 0; i < 10; i++) { - CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(descPYRA5[i]) && labs(descPYRA5[i]) < 16); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, descAll[i], descPYRA5[i]); - } - for (int i = 0; i < 6; i++) { - CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(descHEXA8[i]) && labs(descHEXA8[i]) < 16); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, descAll[10 + i], descHEXA8[i]); - } - } - - // FACES: theC->_constituent - CPPUNIT_ASSERT_MESSAGE(msg, theC->existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE)); - //CPPUNIT_ASSERT_MESSAGE(msg, theC->existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_FACE)); - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 8, theC->getNumberOf(MED_EN::MED_FACE, MED_EN::MED_TRIA3)); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, theC->getNumberOf(MED_EN::MED_FACE, MED_EN::MED_QUAD4)); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 14, theC->getNumberOf(MED_EN::MED_FACE, MED_EN::MED_ALL_ELEMENTS)); - - // sorted by geometric type - const int * countFacesBack = theC->getGlobalNumberingIndex(MED_EN::MED_FACE); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, countFacesBack[0]); // always - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 9, countFacesBack[1]); // +8 TRIA3 - - // check correspondance with types - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, triaFirst ? 9 : 7, countFacesBack[1]); // +8 TRIA3 or +6 QUAD4 - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 15, countFacesBack[2]); // 1+8+6 - - // nodal connectivity length // 8*3 + 6*4 - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 48, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_FACE, - MED_EN::MED_ALL_ELEMENTS)); - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 24, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_FACE, - MED_EN::MED_TRIA3)); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 24, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_FACE, - MED_EN::MED_QUAD4)); - - // nodal connectivity index - const int * connFaceAllIndex = theC->getConnectivityIndex(MED_EN::MED_NODAL, MED_EN::MED_FACE); - { - CPPUNIT_ASSERT(triaFirst); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, connFaceAllIndex[0]); - int typeChangeIndex = triaFirst ? 8 : 6; - int nbNodes1 = triaFirst ? 3 : 4; - int nbNodes2 = triaFirst ? 4 : 3; - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 25, connFaceAllIndex[typeChangeIndex]); // + 3*8 or 4*6 - for (int i = 1; i < 14; i++) { - if (i < typeChangeIndex) - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1 + i*nbNodes1, connFaceAllIndex[i]); - else - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 25 + (i-typeChangeIndex)*nbNodes2, connFaceAllIndex[i]); - } - // + 3*8 nodes of TRIA3 + 4*6 nodes of QUAD4 - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 49, connFaceAllIndex[14]); - } - - // nodal connectivity - const int * connFaceAll = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE, - MED_EN::MED_ALL_ELEMENTS); - const int * connTRIA3 = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE, - MED_EN::MED_TRIA3); - const int * connQUAD4 = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE, - MED_EN::MED_QUAD4); - for (int i = 0; i < 24; i++) { - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, connFaceAll[ i], triaFirst ? connTRIA3[i] : connQUAD4[i]); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, connFaceAll[24+i], triaFirst ? connQUAD4[i] : connTRIA3[i]); - } - - // EDGES: theC->_constituent->_constituent - //CPPUNIT_ASSERT_MESSAGE(msg, theC->existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_EDGE)); - - // Invalid cases - CPPUNIT_ASSERT_MESSAGE(msg, !theC->existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_NODE)); - CPPUNIT_ASSERT_MESSAGE(msg, !theC->existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_EDGE)); - CPPUNIT_ASSERT_MESSAGE(msg, !theC->existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_NODE)); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 0, theC->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_TETRA4)); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 0, theC->getNumberOfElementsWithPoly(MED_EN::MED_CELL, - MED_EN::MED_TETRA4)); - CPPUNIT_ASSERT_THROW(theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_CELL, - MED_EN::MED_TRIA3), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getConnectivityLength(MED_EN::MED_DESCENDING, MED_EN::MED_CELL, - MED_EN::MED_NONE), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_FACE, - MED_EN::MED_POLYGON), MEDEXCEPTION); - } - - // 2 POLYHEDRA - const int nbPolyhedron = 2; - const int nbPolyFaces = 14; - const int nbPolyNodes = 52; - - int aPolyhedronIndex[nbPolyhedron + 1] = {1,8,15}; - - int aPolyhedronFacesIndex[nbPolyFaces + 1] = {1,7,10,14,17,20,24, 27,33,36,40,43,46,50,53}; - - int aPolyhedronNodalConnectivity[nbPolyNodes] = { - 11,15,19,20,17,13, 11,13,14, 14,13,17,18, 18,17,20, 11,14,15, 15,14,18,19, 19,18,20, - 11,13,17,20,19,15, 11,12,13, 13,12,16,17, 17,16,20, 11,15,12, 12,15,19,16, 16,19,20}; - - // .11 - // - // 13.---------.14 - // /|\ /| - // / | \ / | - // / | \ / | - // 12.---------.15 | - // | | | | - // | 17.-----|---.18 - // | / \ | / - // | / \ | / - // |/ \|/ - // 16.---------.19 - // - // .20 - - if (create) { - theC->setPolyhedronConnectivity(MED_EN::MED_NODAL, aPolyhedronNodalConnectivity, - aPolyhedronIndex, nbPolyNodes, nbPolyhedron, - aPolyhedronFacesIndex, nbPolyFaces); - } - else { - // CELLS(3D): theC - { - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, theC->getNumberOfPolyType()); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, theC->getNumberOfTypesWithPoly(MED_EN::MED_CELL)); - - { - const MED_EN::medGeometryElement * aCellTypesBack = theC->getGeometricTypesWithPoly(MED_EN::MED_CELL); - CPPUNIT_ASSERT_MESSAGE(msg, ((aCellTypesBack[0] == MED_EN::MED_PYRA5 && - aCellTypesBack[1] == MED_EN::MED_HEXA8) || - (aCellTypesBack[0] == MED_EN::MED_HEXA8 && - aCellTypesBack[1] == MED_EN::MED_PYRA5))); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, MED_EN::MED_POLYHEDRA, aCellTypesBack[2]); - } - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfElementOfPolyType(MED_EN::MED_CELL)); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfElementsWithPoly(MED_EN::MED_CELL, - MED_EN::MED_POLYHEDRA)); - //checking that 0 is returned if polygons are asked as cells instead of faces - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 0, theC->getNumberOfElementsWithPoly(MED_EN::MED_CELL, - MED_EN::MED_POLYGON)); - - - int nbCellAll = 5; // 2 (PYRA5) + 1 (HEXA8) + 2 (POLYHEDRA) - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nbCellAll, theC->getNumberOfElementsWithPoly - (MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS)); - - - // first PYRA5 {1,2,3,4,5} - { - int len; - const int * c1 = theC->getConnectivityOfAnElementWithPoly - (MED_EN::MED_NODAL, MED_EN::MED_CELL, /*Number*/1, len); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 5, len); - for (int i = 0; i < len; i++) { - if (c1[i] < 1 || 5 < c1[i]) CPPUNIT_FAIL(msg); - } - } - - // first POLYHEDRA - // This throws "NODAL Connectivity required for a polyhedron" - // Why? Because for polyhedron this has no sence without index? - { - int len; - CPPUNIT_ASSERT_THROW(theC->getConnectivityOfAnElementWithPoly - (MED_EN::MED_NODAL, MED_EN::MED_CELL, /*Number*/4, len), MEDEXCEPTION); - } - - // cells descending connectivity - for (int i = 1; i <= nbCellAll; i++) { - int len; - const int * ci = theC->getConnectivityOfAnElementWithPoly - (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, /*Number*/i, len); - - MED_EN::medGeometryElement aCurElemTypeWithPoly = theC->getElementTypeWithPoly(MED_EN::MED_CELL, i); - - if (i <= 3) { // nb.standard cells = 3 - MED_EN::medGeometryElement aCurElemType = theC->getElementType(MED_EN::MED_CELL, i); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aCurElemType, aCurElemTypeWithPoly); - // sign of connectivity array value means element direction - for (int j = 0; j < len; j++) { - CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(ci[j]) && labs(ci[j]) <= 14); // nb.standard faces = 14 - } - } - else { - CPPUNIT_ASSERT_THROW(theC->getElementType(MED_EN::MED_CELL, i), MEDEXCEPTION); - for (int j = 0; j < len; j++) { - CPPUNIT_ASSERT_MESSAGE(msg, 14 < labs(ci[j]) && labs(ci[j]) <= 27); // nb.polygons = 13 - } - } - - switch (aCurElemTypeWithPoly) { - case MED_EN::MED_PYRA5: CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 5, len); break; - case MED_EN::MED_HEXA8: CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, len); break; - case MED_EN::MED_POLYHEDRA: CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 7, len); break; - default: - CPPUNIT_FAIL(msg); // wrong element type - } - } - - // Polyhedron-specific methods - { - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfPolyhedron()); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 14, theC->getNumberOfPolyhedronFaces()); - - // Nodal - - // PolyhedronIndex: array of size (NumberOfPolyhedron + 1) - const int* polyhNodalIndex = theC->getPolyhedronIndex(MED_EN::MED_NODAL); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, polyhNodalIndex[0]); // always - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 8, polyhNodalIndex[1]); // +7 faces - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 15, polyhNodalIndex[2]); // +7 faces (= NumberOfPolyhedronFaces + 1) - - // PolyhedronFacesIndex: array of size (NumberOfPolyhedronFaces + 1) - const int* polyhFacesIndex = theC->getPolyhedronFacesIndex(); - // 1, 7,10,14,17,20,24,27, 33,36,40,43,46,50,53 - for (int i = 0; i <= 14; i++) { - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aPolyhedronFacesIndex[i], polyhFacesIndex[i]); - } - - // Polyhedron Nodal Connectivity: array of size (NumberOfPolyhedronNodes) - int nbPolyhNodes = polyhFacesIndex[14] - 1; - const int* polyhNodalConn = theC->getPolyhedronConnectivity(MED_EN::MED_NODAL); - // 11,15,19,20,17,13, 11,13,14, 14,13,17,18, 18,17,20, 11,14,15, 15,14,18,19, 19,18,20, - // 11,13,17,20,19,15, 11,12,13, 13,12,16,17, 17,16,20, 11,15,12, 12,15,19,16, 16,19,20 - for (int i = 0; i < nbPolyhNodes; i++) { - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aPolyhedronNodalConnectivity[i], polyhNodalConn[i]); - } - - // getNodesOfPolyhedron - int lenPolyh1nodes, lenPolyh2nodes; - int * polyh1nodes = theC->getNodesOfPolyhedron(/*polyhedronId*/3+1, lenPolyh1nodes); - int * polyh2nodes = theC->getNodesOfPolyhedron(/*polyhedronId*/3+2, lenPolyh2nodes); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 8, lenPolyh1nodes); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 8, lenPolyh2nodes); - - set<int> polyh1nodesCheck; - set<int> polyh2nodesCheck; - - polyh1nodesCheck.insert(11); - polyh1nodesCheck.insert(13); - polyh1nodesCheck.insert(14); - polyh1nodesCheck.insert(15); - polyh1nodesCheck.insert(17); - polyh1nodesCheck.insert(18); - polyh1nodesCheck.insert(19); - polyh1nodesCheck.insert(20); - - polyh2nodesCheck.insert(11); - polyh2nodesCheck.insert(12); - polyh2nodesCheck.insert(13); - polyh2nodesCheck.insert(15); - polyh2nodesCheck.insert(16); - polyh2nodesCheck.insert(17); - polyh2nodesCheck.insert(19); - polyh2nodesCheck.insert(20); - - for (int i = 0; i < 8; i++) { - CPPUNIT_ASSERT_MESSAGE(msg, polyh1nodesCheck.count(polyh1nodes[i])); - CPPUNIT_ASSERT_MESSAGE(msg, polyh2nodesCheck.count(polyh2nodes[i])); - } - delete [] polyh1nodes; - delete [] polyh2nodes; - - // getNodesPerFaceOfPolyhedron - int nbFaces1, nbFaces2; - int *nbNodes1, *nbNodes2; // len = nb.faces (7) - int ** polyh1nodesPerFace = - theC->getNodesPerFaceOfPolyhedron(/*polyhedronId*/3+1, nbFaces1, nbNodes1); - int ** polyh2nodesPerFace = - theC->getNodesPerFaceOfPolyhedron(/*polyhedronId*/3+2, nbFaces2, nbNodes2); - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 7, nbFaces1); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 7, nbFaces2); - - int nbNodesCheck [7] = {6,3,4,3,3,4,3}; - for (int i = 0; i < 7; i++) { - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nbNodesCheck[i], nbNodes1[i]); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nbNodesCheck[i], nbNodes2[i]); - - int startNode1 = aPolyhedronFacesIndex[0 + i] - 1; - int startNode2 = aPolyhedronFacesIndex[7 + i] - 1; - for (int j = 0; j < nbNodesCheck[i]; j++) { - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aPolyhedronNodalConnectivity[startNode1 + j], - polyh1nodesPerFace[i][j]); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aPolyhedronNodalConnectivity[startNode2 + j], - polyh2nodesPerFace[i][j]); - } - } - - delete [] nbNodes1; - delete [] nbNodes2; - delete [] polyh1nodesPerFace; - delete [] polyh2nodesPerFace; - - // invalid polyhedron Id - - int lenPolyh3nodes; - int nbFaces3; - int *nbNodes3; - - CPPUNIT_ASSERT_THROW(theC->getNodesOfPolyhedron(1, lenPolyh3nodes), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getNodesOfPolyhedron(3+3, lenPolyh3nodes), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getNodesPerFaceOfPolyhedron - (/*polyhedronId*/1, nbFaces3, nbNodes3), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getNodesPerFaceOfPolyhedron - (/*polyhedronId*/3+3, nbFaces3, nbNodes3), MEDEXCEPTION); - - - // Descending - - // PolyhedronIndex: array of size (NumberOfPolyhedron + 1) - const int* polyhDesceIndex = theC->getPolyhedronIndex(MED_EN::MED_DESCENDING); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, polyhDesceIndex[0]); // always - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 8, polyhDesceIndex[1]); // +7 faces - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 15, polyhDesceIndex[2]); // +7 faces - - // Polyhedron Descending Connectivity: array of size (NumberOfPolyhedronFaces) - const int* polyhDesceConn = theC->getPolyhedronConnectivity(MED_EN::MED_DESCENDING); - // 15,16,17,18,19,20,21, -15,22,23,24,25,26,27 - for (int i = 0; i < 14; i++) { - // nb. poly faces = 13, because one face is common for two polyhedra - // nb. standard faces < poly-face id <= 27 (27 = 14 + 13) - CPPUNIT_ASSERT_MESSAGE(msg, 14 < labs(polyhDesceConn[i]) <= 27); - } - } // Polyhedron-specific methods - - // Polygon-specific methods - { - // Invalid cases: no polygons for MED_CELL in theC - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 0, theC->getNumberOfPolygons(MED_EN::MED_CELL)); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 0, theC->getNumberOfPolygons(/*MED_EN::MED_ALL_ENTITIES*/)); - CPPUNIT_ASSERT_THROW(theC->getPolygonsConnectivity(MED_EN::MED_DESCENDING, - MED_EN::MED_CELL), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getPolygonsConnectivity(MED_EN::MED_NODAL, - MED_EN::MED_ALL_ENTITIES), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getPolygonsConnectivityIndex(MED_EN::MED_NODAL, - MED_EN::MED_CELL), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getPolygonsConnectivityIndex(MED_EN::MED_DESCENDING, - MED_EN::MED_ALL_ENTITIES), MEDEXCEPTION); - } - } // CELLS: theC - - // FACES: theC->_constituent - { - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, theC->getNumberOfTypesWithPoly(MED_EN::MED_FACE)); - - const MED_EN::medGeometryElement * aFaceTypesBack = theC->getGeometricTypesWithPoly(MED_EN::MED_FACE); - CPPUNIT_ASSERT_MESSAGE(msg, ((aFaceTypesBack[0] == MED_EN::MED_TRIA3 && - aFaceTypesBack[1] == MED_EN::MED_QUAD4) || - (aFaceTypesBack[0] == MED_EN::MED_QUAD4 && - aFaceTypesBack[1] == MED_EN::MED_TRIA3))); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, MED_EN::MED_POLYGON, aFaceTypesBack[2]); - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 13, theC->getNumberOfElementOfPolyType(MED_EN::MED_FACE)); - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 0, theC->getNumberOfElementsWithPoly - (MED_EN::MED_FACE, MED_EN::MED_POLYHEDRA)); - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 13, theC->getNumberOfElementsWithPoly - (MED_EN::MED_FACE, MED_EN::MED_POLYGON)); - - int nbFaAll = 27; // 6 (QUAD4) + 8 (TRIA3) + 13 (POLYGON) - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nbFaAll, theC->getNumberOfElementsWithPoly - (MED_EN::MED_FACE, MED_EN::MED_ALL_ELEMENTS)); - - - bool isHexagon = false; - for (int i = 1; i <= nbFaAll; i++) { - int len; - const int * ci = theC->getConnectivityOfAnElementWithPoly(MED_EN::MED_NODAL, - MED_EN::MED_FACE, /*Number*/i, len); - MED_EN::medGeometryElement aCurElemTypeWithPoly = theC->getElementTypeWithPoly(MED_EN::MED_FACE, i); - - if (len == 6) { - CPPUNIT_ASSERT_MESSAGE(msg, !isHexagon); // because only one hexagon must exist - - // check nodes {11,15,19,20,17,13} - int nij; - for (int j = 0; j < len; j++) { - nij = ci[j]; - CPPUNIT_ASSERT_MESSAGE(msg, nij==11 || nij==15 || nij==19 || nij==20 || nij==17 || nij==13); - } - - isHexagon = true; - } - - if (i > 14) { // nb.standard faces = 14 - CPPUNIT_ASSERT_THROW(theC->getElementType(MED_EN::MED_FACE, i), MEDEXCEPTION); - } - else { - MED_EN::medGeometryElement aCurElemType = theC->getElementType(MED_EN::MED_FACE, i); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aCurElemType, aCurElemTypeWithPoly); - } - - switch (aCurElemTypeWithPoly) { - case MED_EN::MED_TRIA3: CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, len); break; - case MED_EN::MED_QUAD4: CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 4, len); break; - case MED_EN::MED_POLYGON: CPPUNIT_ASSERT_MESSAGE(msg, len == 3 || len == 4 || len == 6); break; - default: - CPPUNIT_FAIL(msg); // wrong element type - } - } - CPPUNIT_ASSERT_MESSAGE(msg, isHexagon); // hexagon must exist - - // Polygon-specific methods - { - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 13, theC->getNumberOfPolygons(MED_EN::MED_FACE)); - - const int * pgIndx = theC->getPolygonsConnectivityIndex(MED_EN::MED_NODAL, MED_EN::MED_FACE); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 47, pgIndx[13]); // = length of pgConn + 1 - - const int * pgConn = theC->getPolygonsConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE); - - // face # 1: 11 15 19 20 17 13 - // face # 2: 11 13 14 - // face # 3: 14 13 17 18 - // face # 4: 18 17 20 - // face # 5: 11 14 15 - // face # 6: 15 14 18 19 - // face # 7: 19 18 20 - // face # 8: 11 12 13 - // face # 9: 13 12 16 17 - // face # 10: 17 16 20 - // face # 11: 11 15 12 - // face # 12: 12 15 19 16 - // face # 13: 16 19 20 - - for (int i = 0; i < 13; i++) { - int startNode = pgIndx[i]; - int finishNode = pgIndx[i+1]; - // check nodes uniqueness inside one polygon - set<int> curNodes; - for (int j = startNode; j < finishNode; j++) { - CPPUNIT_ASSERT_MESSAGE(msg, (curNodes.insert(pgConn[j - 1])).second); - } - } - - //CPPUNIT_ASSERT_THROW(theC->getPolygonsConnectivity(MED_EN::MED_DESCENDING, - // MED_EN::MED_FACE), MEDEXCEPTION); - //CPPUNIT_ASSERT_THROW(theC->getPolygonsConnectivityIndex(MED_EN::MED_DESCENDING, - // MED_EN::MED_FACE), MEDEXCEPTION); - } - } // FACES: theC->_constituent - - // EDGES: theC->_constituent->_constituent - //CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfTypesWithPoly(MED_EN::MED_EDGE)); - } - - if (create) { - // force _constituent computation - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfTypes(MED_EN::MED_FACE)); - - - //N-2 Connectivity not supported in MEDMEM - //CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, theC->getNumberOfTypes(MED_EN::MED_EDGE)); - - - cout << "^^^^^" << endl; - cout << *theC << endl; - cout << "^^^^^" << endl; - } - else { - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, MED_EN::MED_POLYHEDRA, theC->getPolyTypeRelativeTo()); - - // The following methods are not recursive, i.e. they return types - // of this connectivity, but do not return types of _constituent. - // And these methods do not work with poly-types. - - // getType - const CELLMODEL & aPYRA5_type = theC->getType(MED_EN::MED_PYRA5); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, MED_EN::MED_PYRA5, aPYRA5_type.getType()); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 5, aPYRA5_type.getNumberOfVertexes()); - - const CELLMODEL & aHEXA8_type = theC->getType(MED_EN::MED_HEXA8); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 8, aHEXA8_type.getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, aHEXA8_type.getDimension()); - // nb. of sub-faces (nb. of constituents with dimension = 3 - 1) - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, aHEXA8_type.getNumberOfConstituents(1)); - - CPPUNIT_ASSERT_THROW(theC->getType(MED_EN::MED_TRIA3), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getType(MED_EN::MED_POLYGON), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getType(MED_EN::MED_POLYHEDRA), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getType(MED_EN::MED_NONE), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getType(MED_EN::MED_ALL_ELEMENTS), MEDEXCEPTION); - - // getNumberOfNodesInType - int nbNodesInPYRA5 = theC->getNumberOfNodesInType(MED_EN::MED_PYRA5); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 5, nbNodesInPYRA5); - - CPPUNIT_ASSERT_THROW(theC->getNumberOfNodesInType(MED_EN::MED_TRIA3), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getNumberOfNodesInType(MED_EN::MED_POLYGON), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getNumberOfNodesInType(MED_EN::MED_NONE), MEDEXCEPTION); - - // getNumberOfSubCellInType - int nbFacesInHEXA8 = theC->getNumberOfSubCellInType(MED_EN::MED_HEXA8); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, nbFacesInHEXA8); - - CPPUNIT_ASSERT_THROW(theC->getNumberOfSubCellInType(MED_EN::MED_QUAD4), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getNumberOfSubCellInType(MED_EN::MED_POLYHEDRA), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getNumberOfSubCellInType(MED_EN::MED_ALL_ELEMENTS), MEDEXCEPTION); - - // getValueIndex - const int* nodalIndex = theC->getValueIndex(MED_EN::MED_NODAL); - const int* desceIndex = theC->getValueIndex(MED_EN::MED_DESCENDING); - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, nodalIndex[0]); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, nodalIndex[1]); // +5 nodes of PYRA5 - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 11, nodalIndex[2]); // +5 nodes of PYRA5 - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 19, nodalIndex[3]); // +8 nodes of HEXA8 - - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, desceIndex[0]); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, desceIndex[1]); // +5 faces of PYRA5 - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 11, desceIndex[2]); // +5 faces of PYRA5 - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 17, desceIndex[3]); // +6 faces of HEXA8 - - // getValue - const int* nodalValue = theC->getValue(MED_EN::MED_NODAL, MED_EN::MED_ALL_ELEMENTS); - const int* nodalPYRA5 = theC->getValue(MED_EN::MED_NODAL, MED_EN::MED_PYRA5); - const int* nodalHEXA8 = theC->getValue(MED_EN::MED_NODAL, MED_EN::MED_HEXA8); - - for (int i = 0; i < 10; i++) { - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_PYRA5[i], nodalPYRA5[i]); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_PYRA5[i], nodalValue[i]); - } - for (int i = 0; i < 8; i++) { - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_HEXA8[i], nodalHEXA8[i]); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_HEXA8[i], nodalValue[10 + i]); - } - - const int* desceValue = theC->getValue(MED_EN::MED_DESCENDING, MED_EN::MED_ALL_ELEMENTS); - const int* descePYRA5 = theC->getValue(MED_EN::MED_DESCENDING, MED_EN::MED_PYRA5); - const int* desceHEXA8 = theC->getValue(MED_EN::MED_DESCENDING, MED_EN::MED_HEXA8); - - for (int i = 0; i < 10; i++) { - CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(descePYRA5[i]) && labs(descePYRA5[i]) < 16); - - CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(desceValue[i]) && labs(desceValue[i]) < 16); - } - for (int i = 0; i < 6; i++) { - CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(desceHEXA8[i]) && labs(desceHEXA8[i]) < 16); - CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(desceValue[10 + i]) && labs(desceValue[10 + i]) < 16); - } - - CPPUNIT_ASSERT_THROW(theC->getValue(MED_EN::MED_NODAL, MED_EN::MED_QUAD4), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getValue(MED_EN::MED_NODAL, MED_EN::MED_POLYHEDRA), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getValue(MED_EN::MED_DESCENDING, MED_EN::MED_NONE), MEDEXCEPTION); - } -} - -void MEDMEMTest::testConnectivity() -{ - ////////////////////////////////////////////// - // TEST 1: test_MEDMEM_PolyConnectivity.cxx // - ////////////////////////////////////////////// - CONNECTIVITY myNodalConnectivity; // one type - CONNECTIVITY myDesceConnectivity; // one type - - myNodalConnectivity.setEntityDimension(3); - myDesceConnectivity.setEntityDimension(3); - - - //POLYGONS - const int NumberOfPolygons = 2; - const int ConnectivitySize = 12; - int PolygonsConnectivityIndex[NumberOfPolygons+1] = {1,7,13}; - - - - //Nodal - int PolygonsNodalConnectivity[ConnectivitySize] = {1,2,3,4,5,10,10,5,6,7,8,9}; - - // myNodalConnectivity.setPolygonsConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE, -// PolygonsNodalConnectivity, -// PolygonsConnectivityIndex, ConnectivitySize, -// NumberOfPolygons); - - //Descending - int PolygonsDescendingConnectivity[ConnectivitySize] = {1,2,3,4,11,10,11,5,6,7,8,9}; - - myDesceConnectivity.setPolygonsConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_FACE, - PolygonsDescendingConnectivity, - PolygonsConnectivityIndex, ConnectivitySize, - NumberOfPolygons); - - //POLYHEDRON - const int NumberOfPolyhedron = 2; - int PolyhedronIndex[NumberOfPolyhedron+1] = {1,10,20}; - - //Nodal - const int NumberOfFaces = 19; - const int NumberOfNodes = 74; - int PolyhedronFacesIndex[NumberOfFaces+1] = - {1,7,11,15,19,23,27,31,34,39,44,48,52,55,58,61,64,68,72,75}; - int PolyhedronNodalConnectivity[NumberOfNodes] = - {1,2,3,4,5,6,1,7,8,2,2,8,9,3,4,3,9,10,5,4, - 10,11,6,5,11,12,1,6,12,7,7,12,8,10,9,8,12,11,13,14, - 15,3,2,13,2,8,16,14,13,16,17,15,14,17,15,17,18,15,18,9, - 3,15,9,2,3,9,8,8,9,17,16,9,18,17}; - - myNodalConnectivity.setPolyhedronConnectivity(MED_EN::MED_NODAL, PolyhedronNodalConnectivity, - PolyhedronIndex, NumberOfNodes, NumberOfPolyhedron, - PolyhedronFacesIndex, NumberOfFaces); - - - //Descending - const int DescendingConnectivitySize = 19; - int PolyhedronDescendingConnectivity[DescendingConnectivitySize] = - {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,3,17,18}; - - myDesceConnectivity.setPolyhedronConnectivity(MED_EN::MED_DESCENDING, - PolyhedronDescendingConnectivity, - PolyhedronIndex, DescendingConnectivitySize, - NumberOfPolyhedron); - - cout << "Poly NodalConnectivity:" << endl; - cout << myNodalConnectivity; - cout << "Poly NodalConnectivity END" << endl; - cout << "Poly DescendingConnectivity:" << endl; - cout << myDesceConnectivity; - cout << "Poly DescendingConnectivity END" << endl; - - myNodalConnectivity.setNumberOfNodes(777); - CPPUNIT_ASSERT_EQUAL(777, myNodalConnectivity.getNumberOfElementsWithPoly - (MED_EN::MED_NODE, MED_EN::MED_NONE)); -// // Throws because _constituent is not calculated -// CPPUNIT_ASSERT_THROW(myNodalConnectivity.getNumberOfElementsWithPoly -// (MED_EN::MED_FACE, MED_EN::MED_NONE), MEDEXCEPTION); - -// // Returns zero, because EntityDimension is not set -// CPPUNIT_ASSERT_EQUAL(0, myNodalConnectivity.getNumberOfElementsWithPoly -// (MED_EN::MED_CELL, MED_EN::MED_POLYGON)); -// CPPUNIT_ASSERT_EQUAL(0, myNodalConnectivity.getNumberOfElementsWithPoly -// (MED_EN::MED_CELL, MED_EN::MED_POLYHEDRA)); - - // Throws because entity must differ from MED_NONE and MED_ALL_ELEMENTS - CPPUNIT_ASSERT_THROW(myNodalConnectivity.getNumberOfNodesInType(MED_EN::MED_NONE), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(myNodalConnectivity.getNumberOfNodesInType(MED_EN::MED_ALL_ELEMENTS), MEDEXCEPTION); - - // Throws because types are not defined - CPPUNIT_ASSERT_THROW(myNodalConnectivity.getNumberOfNodesInType(MED_EN::MED_ALL_ELEMENTS), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(myNodalConnectivity.getNumberOfNodesInType(MED_EN::MED_POLYGON), MEDEXCEPTION); - - - // does not throw any more exception because - // it is now possible to work on meshes with only polyhedric elements - CPPUNIT_ASSERT_NO_THROW(myNodalConnectivity.calculateConnectivity - (MED_EN::MED_DESCENDING, MED_EN::MED_CELL)); - - // existPolygonsConnectivity - CPPUNIT_ASSERT(!myNodalConnectivity.existPolygonsConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL)); - CPPUNIT_ASSERT(myNodalConnectivity.existPolygonsConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE)); - CPPUNIT_ASSERT(!myNodalConnectivity.existPolygonsConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL)); - - CPPUNIT_ASSERT(!myDesceConnectivity.existPolygonsConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL)); - CPPUNIT_ASSERT(myDesceConnectivity.existPolygonsConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_FACE)); - CPPUNIT_ASSERT(!myDesceConnectivity.existPolygonsConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL)); - - // existPolyhedronConnectivity - CPPUNIT_ASSERT(myNodalConnectivity.existPolyhedronConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL)); - CPPUNIT_ASSERT(!myNodalConnectivity.existPolyhedronConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE)); - CPPUNIT_ASSERT(myNodalConnectivity.existPolyhedronConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL)); - - CPPUNIT_ASSERT(!myDesceConnectivity.existPolyhedronConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL)); - CPPUNIT_ASSERT(!myDesceConnectivity.existPolyhedronConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_FACE)); - CPPUNIT_ASSERT(myDesceConnectivity.existPolyhedronConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL)); - - // setEntityDimension - // myNodalConnectivity and myDesceConnectivity is not good, because - // it contains cells of different dimension (2D and 3D) - // We set here EntityDimension for good work of below methods - - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_POLYHEDRA, myNodalConnectivity.getPolyTypeRelativeTo()); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_POLYHEDRA, myDesceConnectivity.getPolyTypeRelativeTo()); - - // Poly types - CPPUNIT_ASSERT_EQUAL(1, myNodalConnectivity.getNumberOfTypesWithPoly(MED_EN::MED_CELL)); - CPPUNIT_ASSERT_EQUAL(1, myDesceConnectivity.getNumberOfTypesWithPoly(MED_EN::MED_CELL)); - - CPPUNIT_ASSERT_EQUAL(1, myNodalConnectivity.getNumberOfTypesWithPoly(MED_EN::MED_FACE)); - CPPUNIT_ASSERT_EQUAL(0, myDesceConnectivity.getNumberOfTypesWithPoly(MED_EN::MED_EDGE)); - - CPPUNIT_ASSERT_EQUAL(1, myNodalConnectivity.getNumberOfPolyType()); - CPPUNIT_ASSERT_EQUAL(1, myDesceConnectivity.getNumberOfPolyType()); - - // getNumberOfElementsWithPoly - CPPUNIT_ASSERT_EQUAL(NumberOfPolyhedron, myNodalConnectivity.getNumberOfElementsWithPoly - (MED_EN::MED_CELL, MED_EN::MED_POLYHEDRA)); - CPPUNIT_ASSERT_EQUAL(0, myNodalConnectivity.getNumberOfElementsWithPoly - (MED_EN::MED_CELL, MED_EN::MED_POLYGON)); - //Minus 1 because 2,3,8,9 is a given twice in connectivity - CPPUNIT_ASSERT_EQUAL(NumberOfFaces-1, myNodalConnectivity.getNumberOfElementsWithPoly - (MED_EN::MED_FACE, MED_EN::MED_POLYGON)); - - CPPUNIT_ASSERT_EQUAL(NumberOfPolyhedron, myDesceConnectivity.getNumberOfElementsWithPoly - (MED_EN::MED_CELL, MED_EN::MED_POLYHEDRA)); - CPPUNIT_ASSERT_EQUAL(NumberOfPolygons, myDesceConnectivity.getNumberOfElementsWithPoly - (MED_EN::MED_FACE, MED_EN::MED_POLYGON)); - CPPUNIT_ASSERT_EQUAL(0, myDesceConnectivity.getNumberOfElementsWithPoly - (MED_EN::MED_CELL, MED_EN::MED_POLYGON)); - - // getNumberOfElementOfPolyType - CPPUNIT_ASSERT_EQUAL(NumberOfPolyhedron, - myNodalConnectivity.getNumberOfElementOfPolyType(MED_EN::MED_CELL)); - CPPUNIT_ASSERT_EQUAL(NumberOfFaces-1,myNodalConnectivity.getNumberOfElementOfPolyType(MED_EN::MED_FACE)); - - CPPUNIT_ASSERT_EQUAL(NumberOfPolygons, - myDesceConnectivity.getNumberOfElementOfPolyType(MED_EN::MED_CELL)); - CPPUNIT_ASSERT_EQUAL(NumberOfPolygons, myDesceConnectivity.getNumberOfElementOfPolyType(MED_EN::MED_FACE)); - - // getConnectivityOfAnElementWithPoly - { - int len_ph1; - CPPUNIT_ASSERT_THROW(myNodalConnectivity.getConnectivityOfAnElementWithPoly - (MED_EN::MED_NODAL, MED_EN::MED_CELL, /*Number*/1, len_ph1),MEDEXCEPTION); - - int len_pg1, len_pg2, len_pg3,i; - //first polyhedron - const int * dc_pg1 = myDesceConnectivity.getConnectivityOfAnElementWithPoly - (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, /*Number*/1, len_pg1); // {1,2,3,4,11,10} - CPPUNIT_ASSERT_EQUAL(9, len_pg1); - //second polyhedron - const int * dc_pg2 = myDesceConnectivity.getConnectivityOfAnElementWithPoly - (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, /*Number*/2, len_pg2); // {11,5,6,7,8,9} - CPPUNIT_ASSERT_EQUAL(10, len_pg2); - //first polygon - const int * dc_pg3 = myDesceConnectivity.getConnectivityOfAnElementWithPoly - (MED_EN::MED_DESCENDING, MED_EN::MED_FACE, /*Number*/2, len_pg3); // {11,5,6,7,8,9} - CPPUNIT_ASSERT_EQUAL(6, len_pg3); - - - for (i = 0; i < 6; i++) { - if (dc_pg1[i] < 1 || 10 < dc_pg1[i] || - dc_pg3[i] < 1 || 11 < dc_pg3[i]) - CPPUNIT_FAIL("Wrong connectivity returned"); - } - } - - // We reset here EntityDimension to check getConnectivityOfAnElementWithPoly() - //myNodalConnectivity.setEntityDimension(2); - //myDesceConnectivity.setEntityDimension(3); - - { - int len_pg1, len_pg2, i; - - CPPUNIT_ASSERT_THROW ( myNodalConnectivity.getConnectivityOfAnElementWithPoly - (MED_EN::MED_NODAL, MED_EN::MED_CELL, /*Number*/1, len_pg1),MEDEXCEPTION); - - const int * nc_pg1 = myNodalConnectivity.getConnectivityOfAnElementWithPoly - (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, /*Number*/1, len_pg1); // {1,2,3,4,5,10} - CPPUNIT_ASSERT_EQUAL(9, len_pg1); - const int * nc_pg2 = myNodalConnectivity.getConnectivityOfAnElementWithPoly - (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, /*Number*/2, len_pg2); // {10,5,6,7,8,9} - CPPUNIT_ASSERT_EQUAL(10, len_pg2); - - for (i = 0; i < 9; i++) { - if (nc_pg1[i] < 1 || 18 < nc_pg1[i] || - nc_pg2[i] < -3 || 18 < nc_pg2[i]) - CPPUNIT_FAIL("Wrong connectivity returned"); - } - - int len_ph1, len_ph2; - const int * dc_ph1 = myDesceConnectivity.getConnectivityOfAnElementWithPoly - (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, /*Number*/1, len_ph1); // {1,2,3,4,5,6,7,8,9} - CPPUNIT_ASSERT_EQUAL(9, len_ph1); - const int * dc_ph2 = myDesceConnectivity.getConnectivityOfAnElementWithPoly - (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, /*Number*/2, len_ph2); // {10,11,12,13,14,15,16,3,17,18} - CPPUNIT_ASSERT_EQUAL(10, len_ph2); - - for (i = 0; i < 9; i++) { - if (dc_ph1[i] < 1 || 9 < dc_ph1[i]) - CPPUNIT_FAIL("Wrong connectivity returned"); - } - - for (i = 0; i < 10; i++) { - if ((dc_ph2[i] != 3 && dc_ph2[i] < 10) || 18 < dc_ph2[i]) - CPPUNIT_FAIL("Wrong connectivity returned"); - } - } - - //////////// - // TEST 2 // - //////////// - checkCopyConnectivity(); - - //////////// - // TEST 3 // - //////////// - - CONNECTIVITY aCells1 (/*numberOfTypes*/2, /*Entity*/MED_EN::MED_CELL); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_CELL, aCells1.getEntity()); - CPPUNIT_ASSERT_EQUAL(2, aCells1.getNumberOfTypes(MED_EN::MED_CELL)); - CPPUNIT_ASSERT_EQUAL(2, aCells1.getNumberOfTypesWithPoly(MED_EN::MED_CELL)); - - CONNECTIVITY aCells2 (/*numberOfTypes*/3/*, Entity=MED_EN::MED_CELL*/); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_CELL, aCells2.getEntity()); - CPPUNIT_ASSERT_EQUAL(3, aCells2.getNumberOfTypes(MED_EN::MED_CELL)); - CPPUNIT_ASSERT_EQUAL(3, aCells2.getNumberOfTypesWithPoly(MED_EN::MED_CELL)); - - CONNECTIVITY * anEdges1 = new CONNECTIVITY(/*numberOfTypes*/1, /*Entity*/MED_EN::MED_EDGE); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_EDGE, anEdges1->getEntity()); - CPPUNIT_ASSERT_EQUAL(1, anEdges1->getNumberOfTypes(MED_EN::MED_EDGE)); - CPPUNIT_ASSERT_EQUAL(1, anEdges1->getNumberOfTypesWithPoly(MED_EN::MED_EDGE)); - - CONNECTIVITY * anEdges2 = new CONNECTIVITY(/*numberOfTypes*/2, /*Entity*/MED_EN::MED_EDGE); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_EDGE, anEdges2->getEntity()); - CPPUNIT_ASSERT_EQUAL(2, anEdges2->getNumberOfTypes(MED_EN::MED_EDGE)); - CPPUNIT_ASSERT_EQUAL(2, anEdges2->getNumberOfTypesWithPoly(MED_EN::MED_EDGE)); - - CONNECTIVITY * aFaces1 = new CONNECTIVITY(/*numberOfTypes*/4, /*Entity*/MED_EN::MED_FACE); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces1->getEntity()); - CPPUNIT_ASSERT_EQUAL(4, aFaces1->getNumberOfTypes(MED_EN::MED_FACE)); - CPPUNIT_ASSERT_EQUAL(4, aFaces1->getNumberOfTypesWithPoly(MED_EN::MED_FACE)); - - // No need to delete anEdges1 and aFaces1, because they are owned by aCells1 - // (anEdges1 is owned by aFaces1 to be precise) - // No need to delete anEdges2, because they are owned by aCells2 - - // EntityDimension - // It would be good to set EntityDimension automatically for EDGEs and FACEs, - // and warn about not set EntityDimension for CELLs - // (or calculate it by given geometric types) - aCells1.setEntityDimension(3); - aCells2.setEntityDimension(2); // for 2D mesh - anEdges1->setEntityDimension(1); - anEdges2->setEntityDimension(1); - aFaces1->setEntityDimension(2); - - CPPUNIT_ASSERT_EQUAL(3, aCells1.getEntityDimension()); - CPPUNIT_ASSERT_EQUAL(2, aCells2.getEntityDimension()); - CPPUNIT_ASSERT_EQUAL(1, anEdges1->getEntityDimension()); - CPPUNIT_ASSERT_EQUAL(1, anEdges2->getEntityDimension()); - CPPUNIT_ASSERT_EQUAL(2, aFaces1->getEntityDimension()); - - // getPolyTypeRelativeTo - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_POLYHEDRA, aCells1.getPolyTypeRelativeTo()); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_POLYGON , aCells2.getPolyTypeRelativeTo()); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_POLYGON , aFaces1->getPolyTypeRelativeTo()); - // because there is no poly types for edges (2D entities) - CPPUNIT_ASSERT_THROW(anEdges1->getPolyTypeRelativeTo(), MEDEXCEPTION); - - // setConstituent - CPPUNIT_ASSERT_THROW(aCells1.setConstituent(&aCells2), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aCells1.setConstituent(anEdges1), MEDEXCEPTION); - - aCells1.setConstituent(aFaces1); - aCells1.setConstituent(anEdges1); - - CPPUNIT_ASSERT_EQUAL(1, aCells1.getNumberOfTypes(MED_EN::MED_EDGE)); - CPPUNIT_ASSERT_EQUAL(4, aCells1.getNumberOfTypes(MED_EN::MED_FACE)); - - aCells2.setConstituent(anEdges2); - CPPUNIT_ASSERT_EQUAL(2, aCells2.getNumberOfTypes(MED_EN::MED_EDGE)); - - // setGeometricTypes - MED_EN::medGeometryElement aCellTypes2D[3] = {MED_EN::MED_TRIA3, MED_EN::MED_QUAD4, MED_EN::MED_TRIA6}; - MED_EN::medGeometryElement aCellTypes3D[2] = {MED_EN::MED_PYRA5, MED_EN::MED_HEXA8}; - MED_EN::medGeometryElement anEdgeTypes1[1] = {MED_EN::MED_SEG2}; - MED_EN::medGeometryElement anEdgeTypes2[2] = {MED_EN::MED_SEG2, MED_EN::MED_SEG3}; - MED_EN::medGeometryElement aFaceTypes4[4] = - {MED_EN::MED_TRIA3, MED_EN::MED_QUAD4, MED_EN::MED_TRIA6, MED_EN::MED_QUAD8}; - - aCells1.setGeometricTypes(aCellTypes3D, MED_EN::MED_CELL); - aCells1.setGeometricTypes(aFaceTypes4, MED_EN::MED_FACE); - aCells1.setGeometricTypes(anEdgeTypes1, MED_EN::MED_EDGE); - CPPUNIT_ASSERT_THROW(aCells1.setGeometricTypes(anEdgeTypes1, MED_EN::MED_NODE), MEDEXCEPTION); - - aCells2.setGeometricTypes(aCellTypes2D, MED_EN::MED_CELL); - anEdges2->setGeometricTypes(anEdgeTypes2, MED_EN::MED_EDGE); - CPPUNIT_ASSERT_THROW(aCells2.setGeometricTypes(aFaceTypes4, MED_EN::MED_FACE), MEDEXCEPTION); - - // setCount - int countCell2D[4] = {1, 5, 6, 10}; - int countCell3D[3] = {1, 3, 4}; - int countEdges1[2] = {1, 21}; - int countEdges2[3] = {1, 13, 21}; - int countFaces1[5] = {1, 9, 15, 16, 17}; - - aCells1.setCount(countCell3D, MED_EN::MED_CELL); - aCells1.setCount(countEdges1, MED_EN::MED_EDGE); - aCells1.setCount(countFaces1, MED_EN::MED_FACE); - CPPUNIT_ASSERT_THROW(aCells1.setCount(countEdges1, MED_EN::MED_NODE), MEDEXCEPTION); - - aCells2.setCount(countCell2D, MED_EN::MED_CELL); - aCells2.setCount(countEdges2, MED_EN::MED_EDGE); - CPPUNIT_ASSERT_THROW(aCells2.setCount(countFaces1, MED_EN::MED_FACE), MEDEXCEPTION); - - // setNodal - - // aCells2 - int nodesCell2D_TRIA3[12] = {3,8,7, 10,7,13, 18,13,14, 11,14,8}; - int nodesCell2D_QUAD4[4] = {7,8,14,13}; - int nodesCell2D_TRIA6[24] = {1,2,3,7,10,6, 3,4,5,9,11,8, 11,15,20,19,18,14, 18,17,16,12,10,13}; - - aCells2.setNodal(nodesCell2D_TRIA3, MED_EN::MED_CELL, MED_EN::MED_TRIA3); - aCells2.setNodal(nodesCell2D_QUAD4, MED_EN::MED_CELL, MED_EN::MED_QUAD4); - aCells2.setNodal(nodesCell2D_TRIA6, MED_EN::MED_CELL, MED_EN::MED_TRIA6); - - int nodesEdges2_SEG2[24] = {3,8, 8,11, 11,14, 14,18, 18,13, 13,10, 10,7, - 7,3, 7,8, 8,14, 14,13, 13,7}; - int nodesEdges2_SEG3[24] = {1,2,3, 3,4,5, 5,9,11, 11,15,20, - 20,19,18, 18,17,16, 16,12,10, 10,6,1}; - - aCells2.setNodal(nodesEdges2_SEG2, MED_EN::MED_EDGE, MED_EN::MED_SEG2); - aCells2.setNodal(nodesEdges2_SEG3, MED_EN::MED_EDGE, MED_EN::MED_SEG3); - - // aCells1 - int nodesCell3D_PYRA5[10] = {1,2,3,4,5, 10,6,7,8,9}; - int nodesCell3D_HEXA8[8] = {2,3,4,5, 6,7,8,9}; - - aCells1.setNodal(nodesCell3D_PYRA5, MED_EN::MED_CELL, MED_EN::MED_PYRA5); - aCells1.setNodal(nodesCell3D_HEXA8, MED_EN::MED_CELL, MED_EN::MED_HEXA8); - - int nodesFaces1_TRIA3[24] = {1,2,3, 1,3,4, 1,4,5, 1,5,2, - 10,7,6, 10,8,7, 10,9,8, 10,6,9}; - int nodesFaces1_QUAD4[24] = {2,3,4,5, 6,7,8,9, 2,3,7,6, 5,4,8,9, 2,5,9,6, 3,4,8,7}; - int nodesFaces1_TRIA6[6] = {11,12,13,14,15,16}; - int nodesFaces1_QUAD8[8] = {15,14,13,17,18,19,20,21}; - - aCells1.setNodal(nodesFaces1_TRIA3, MED_EN::MED_FACE, MED_EN::MED_TRIA3); - aCells1.setNodal(nodesFaces1_QUAD4, MED_EN::MED_FACE, MED_EN::MED_QUAD4); - aCells1.setNodal(nodesFaces1_TRIA6, MED_EN::MED_FACE, MED_EN::MED_TRIA6); - aCells1.setNodal(nodesFaces1_QUAD8, MED_EN::MED_FACE, MED_EN::MED_QUAD8); - - int nodesEdges1_SEG2[40] = {1,2, 1,3, 1,4, 1,5, 10,6, 10,7, 10,8, 10,9, - 2,3, 3,4, 4,5, 5,2, 6,7, 7,8, 8,9, 9,6, - 2,6, 3,7, 4,8, 5,9}; - - aCells1.setNodal(nodesEdges1_SEG2, MED_EN::MED_EDGE, MED_EN::MED_SEG2); - - // setNumberOfNodes - aCells2.setNumberOfNodes(20); - anEdges2->setNumberOfNodes(20); - - aCells1.setNumberOfNodes(21); - anEdges1->setNumberOfNodes(21); - aFaces1->setNumberOfNodes(21); - - // existConnectivity - CPPUNIT_ASSERT(aCells1.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL)); - CPPUNIT_ASSERT(aCells1.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE)); - CPPUNIT_ASSERT(aCells1.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_EDGE)); - CPPUNIT_ASSERT(!aCells1.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_NODE)); - - CPPUNIT_ASSERT(!aCells1.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL)); - CPPUNIT_ASSERT(!aCells1.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_FACE)); - CPPUNIT_ASSERT(!aCells1.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_EDGE)); - CPPUNIT_ASSERT(!aCells1.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_NODE)); - - CPPUNIT_ASSERT(aCells2.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL)); - CPPUNIT_ASSERT(!aCells2.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE)); - CPPUNIT_ASSERT(aCells2.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_EDGE)); - CPPUNIT_ASSERT(!aCells2.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_NODE)); - - CPPUNIT_ASSERT(!aCells2.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL)); - CPPUNIT_ASSERT(!aCells2.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_FACE)); - CPPUNIT_ASSERT(!aCells2.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_EDGE)); - CPPUNIT_ASSERT(!aCells2.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_NODE)); - - // getNumberOfPolyType - CPPUNIT_ASSERT_EQUAL(0, aCells1.getNumberOfPolyType()); - CPPUNIT_ASSERT_EQUAL(0, aCells2.getNumberOfPolyType()); - - // getConnectivityOfAnElementWithPoly - { - int len_e1, len_e2, i; - const int * nc_e1 = aCells1.getConnectivityOfAnElementWithPoly - (MED_EN::MED_NODAL, MED_EN::MED_CELL, /*Number*/1, len_e1); - CPPUNIT_ASSERT_EQUAL(5, len_e1); // PYRA5 {1,2,3,4,5} - for (i = 0; i < len_e1; i++) { - if (nc_e1[i] < 1 || 5 < nc_e1[i]) - CPPUNIT_FAIL("Wrong node in element"); - } - - const int * nc_e2 = aCells2.getConnectivityOfAnElementWithPoly - (MED_EN::MED_NODAL, MED_EN::MED_CELL, /*Number*/2, len_e2); - CPPUNIT_ASSERT_EQUAL(3, len_e2); // TRIA3 {7,10,13} - for (i = 0; i < len_e2; i++) { - if (nc_e2[i] != 7 && nc_e2[i] != 10 && nc_e2[i] != 13) - CPPUNIT_FAIL("Wrong node in element"); - } - } - - //cout << "aCells2: " << endl; - //cout << aCells2 << endl; - - //cout << "aCells1:" << endl; - //cout << aCells1 << endl; - - // aCells1 (2 types) | - // | | - // aFaces1 (4 types) | aCells2 (3 types) - // | | | - // anEdges1 (1 type) | anEdges2 (2 types) - - // updateFamily - { - FAMILY aFamilyOnFaces; - aFamilyOnFaces.setEntity(MED_EN::MED_FACE); - aFamilyOnFaces.setMeshName("Mesh 1"); - aFamilyOnFaces.setName("Support On Faces 1"); - //aFamilyOnFaces.setAll(true); - - int nbTypesFam1 = 4; - MED_EN::medGeometryElement aSCTypes[4] = {MED_EN::MED_TRIA3, MED_EN::MED_QUAD4, - MED_EN::MED_TRIA6, MED_EN::MED_QUAD8}; - int nbEltsSC[4] = {8,6,1,1}; - int indexSC[5] = {1,9,15,16,17}; // length = nb.types + 1 - int valueSC[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; // length = total nb. of elements - //int nbTypesFam1 = 1; - //MED_EN::medGeometryElement aSCTypes[1] = {MED_EN::MED_TRIA3}; - //int nbEltsSC[1] = {8}; - //int indexSC[2] = {1,9}; // length = nb.types + 1 - //int valueSC[8] = {1,3,5,7,9,11,13,15}; // length = total nb. of elements - - aFamilyOnFaces.setNumberOfGeometricType(nbTypesFam1); - aFamilyOnFaces.setGeometricType(aSCTypes); - aFamilyOnFaces.setNumberOfElements(nbEltsSC); - aFamilyOnFaces.setNumber(indexSC, valueSC); - - vector<FAMILY*> aFamsOnFaces (1); - aFamsOnFaces[0] = &aFamilyOnFaces; - -#ifdef ENABLE_UPDATE_FAMILY - // Attention!!! By default ENABLE_UPDATE_FAMILY is not defined!!! - // I do not undestand, what this method should do - // and what I must give to it to obtain good result - - //cout << "aCells1:" << endl; - //cout << aCells1 << endl; - CPPUNIT_ASSERT_NO_THROW(aCells1.updateFamily(aFamsOnFaces)); - //cout << "aCells1:" << endl; - //cout << aCells1 << endl; -#endif - } - - //////////// - // TEST 4 // - //////////// - CONNECTIVITY * c1 = new CONNECTIVITY(/*numberOfTypes*/2, MED_EN::MED_CELL); - createOrCheck(c1, "Creation", /*create*/true); - createOrCheck(c1, "Check just created", /*create*/false); - - CONNECTIVITY * c2 = new CONNECTIVITY(*c1); - createOrCheck(c2, "Check copy constructor", /*create*/false); - - // invertConnectivityForAFace - int nbFacesC2 = c2->getNumberOf(MED_EN::MED_FACE, MED_EN::MED_ALL_ELEMENTS); - for (int faceId = 1; faceId <= nbFacesC2; faceId++) { - //cout << "^^^^^ not inverted ^^^^^" << endl; - //showConnectivity(c2, 3, 20, MED_EN::MED_CELL, 2); - //cout << *c2 << endl; - //cout << "^^^^^ not inverted ^^^^^" << endl; - - // this face nodal connectivity before inversion: - int oldLen, newLen; - const int * oldConn = c2->getConnectivityOfAnElementWithPoly(MED_EN::MED_NODAL, - MED_EN::MED_FACE, faceId, oldLen); - - // descending connectivity before inversion: - int before_NumberOfElements = c2->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); - const int * before_connectivity_shared = - c2->getConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); - const int * before_connectivity_index = - c2->getConnectivityIndex(MED_EN::MED_DESCENDING, MED_EN::MED_CELL); - - // copy connectivity, because the pointer, returned by getConnectivity, - // will point to the same memory before and after inversion - int lenDC = before_connectivity_index[before_NumberOfElements] - 1; - int * before_connectivity = new int[lenDC]; - for (int i = 0; i < lenDC; i++) - before_connectivity[i] = before_connectivity_shared[i]; - - // reverse descending connectivity before inversion: - const int * before_ReverseDescendingConnectivity_shared = - c2->getReverseConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL); - const int * before_ReverseDescendingConnectivityIndex = - c2->getReverseConnectivityIndex(MED_EN::MED_DESCENDING, MED_EN::MED_CELL); - - int lenRDC = before_ReverseDescendingConnectivityIndex[nbFacesC2] - 1; - int * before_ReverseDescendingConnectivity = new int[lenRDC]; - for (int i = 0; i < lenRDC; i++) - before_ReverseDescendingConnectivity[i] = before_ReverseDescendingConnectivity_shared[i]; - - // perform inversion - int * newNodesForFace = new int[oldLen]; - if (oldLen == 3) { - newNodesForFace[0] = oldConn[1]; - newNodesForFace[1] = oldConn[0]; - newNodesForFace[2] = oldConn[2]; - } else { - newNodesForFace[0] = oldConn[2]; - newNodesForFace[1] = oldConn[1]; - newNodesForFace[2] = oldConn[0]; - newNodesForFace[3] = oldConn[3]; - } - c2->invertConnectivityForAFace(faceId, newNodesForFace, /*polygonFace*/false); - - //cout << "^^^^^ inverted ^^^^^" << endl; - //showConnectivity(c2, 3, 20, MED_EN::MED_CELL, 2); - //cout << *c2 << endl; - //cout << "^^^^^ inverted ^^^^^" << endl; - - // reverse descending connectivity after inversion: - const int * after_ReverseDescendingConnectivity = - c2->getReverseConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL); - const int * after_ReverseDescendingConnectivityIndex = - c2->getReverseConnectivityIndex(MED_EN::MED_DESCENDING, MED_EN::MED_CELL); - - // Faces, which are on bound (have one neighbouring), are not inverted. - bool isOnBound = false; - - //cout << "faceId = " << faceId << endl; - //cout << "oldLen = " << oldLen << endl; - for (int i = 0; i < nbFacesC2; i++) { - //cout << "i = " << i << endl; - int plus = after_ReverseDescendingConnectivityIndex[i] - 1; - // always two neighbourings - if ((i + 1) == faceId) { - // no second neighbouring - isOnBound = (before_ReverseDescendingConnectivity[plus + 1] == 0); - } - if ((i + 1) == faceId && oldLen == 4 && !isOnBound) { - CPPUNIT_ASSERT_EQUAL(before_ReverseDescendingConnectivity[plus + 0], - after_ReverseDescendingConnectivity[plus + 1]); - CPPUNIT_ASSERT_EQUAL(before_ReverseDescendingConnectivity[plus + 1], - after_ReverseDescendingConnectivity[plus + 0]); - } - else { - CPPUNIT_ASSERT_EQUAL(before_ReverseDescendingConnectivity[plus + 0], - after_ReverseDescendingConnectivity[plus + 0]); - CPPUNIT_ASSERT_EQUAL(before_ReverseDescendingConnectivity[plus + 1], - after_ReverseDescendingConnectivity[plus + 1]); - } - } - - // descending connectivity after inversion: - int after_NumberOfElements = c2->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); - const int * after_connectivity = - c2->getConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); - const int * after_connectivity_index = - c2->getConnectivityIndex(MED_EN::MED_DESCENDING, MED_EN::MED_CELL); - - CPPUNIT_ASSERT_EQUAL(before_NumberOfElements, after_NumberOfElements); - - for (int j = 0; j < before_NumberOfElements; j++) { - for (int k = after_connectivity_index[j]; k < after_connectivity_index[j+1]; k++) { - if (labs(before_connectivity[k-1]) == faceId && !isOnBound) { - CPPUNIT_ASSERT_EQUAL(before_connectivity[k-1], - after_connectivity[k-1]); - } - else { - CPPUNIT_ASSERT_EQUAL(before_connectivity[k-1], after_connectivity[k-1]); - } - } - } - - // this face nodal connectivity after inversion: - if (!isOnBound) { - const int * newConn = c2->getConnectivityOfAnElementWithPoly(MED_EN::MED_NODAL, - MED_EN::MED_FACE, faceId, newLen); - CPPUNIT_ASSERT_EQUAL(oldLen, newLen); - for (int i = 0; i < newLen; i++) { - CPPUNIT_ASSERT_EQUAL(newNodesForFace[i], newConn[i]); - } - } - delete [] newNodesForFace; - - delete [] before_connectivity; - delete [] before_ReverseDescendingConnectivity; - - // ATTENTION: invertConnectivityForAFace() is not tested on polygons!!! - } - - - delete c1; - delete c2; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_Connectivity_fault.cxx b/src/MEDMEM/Test/MEDMEMTest_Connectivity_fault.cxx deleted file mode 100644 index e13a05364..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Connectivity_fault.cxx +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "MEDMEM_Connectivity.hxx" -#include "MEDMEM_define.hxx" -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" - -#include <sstream> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -using namespace std; -using namespace MEDMEM; - -void createOrCheck (CONNECTIVITY * theC, string msg, bool create = false) -{ - // Preconditions: Entity and NumberOfTypes - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, MED_EN::MED_CELL, theC->getEntity()); - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfTypes(MED_EN::MED_CELL)); - - // EntityDimension - if (create) - theC->setEntityDimension(3); - - // NumberOfNodes - int nbNodes = 20; - - if (create) { - theC->setNumberOfNodes(nbNodes); - } - - // GeometricTypes - MED_EN::medGeometryElement aCellTypes[2] = {MED_EN::MED_PYRA5, MED_EN::MED_HEXA8}; - - // this variable is needed in check mode (!create) - // because of bug with getGlobalNumberingIndex() method (see below) - bool triaFirst = true; - - if (create) { - theC->setGeometricTypes(aCellTypes, MED_EN::MED_CELL); - CPPUNIT_ASSERT_THROW(theC->setGeometricTypes(aCellTypes, MED_EN::MED_NODE), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->setGeometricTypes(aCellTypes, MED_EN::MED_FACE), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->setGeometricTypes(aCellTypes, MED_EN::MED_EDGE), MEDEXCEPTION); - } - - // Nodal Connectivity for standard types - int countCells[3] = {1, 3, 4}; // 2 PYRA5 and 1 HEXA8 - int nodesCells_PYRA5[10] = {2,3,4,5,1, 6,7,8,9,10}; - int nodesCells_HEXA8[8] = {2,3,4,5, 6,7,8,9}; - - if (create) { - theC->setCount(countCells, MED_EN::MED_CELL); - theC->setNodal(nodesCells_PYRA5, MED_EN::MED_CELL, MED_EN::MED_PYRA5); - theC->setNodal(nodesCells_HEXA8, MED_EN::MED_CELL, MED_EN::MED_HEXA8); - - // Invalid cases - CPPUNIT_ASSERT_THROW(theC->setCount(countCells, MED_EN::MED_NODE), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->setCount(countCells, MED_EN::MED_EDGE), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->setCount(countCells, MED_EN::MED_FACE), MEDEXCEPTION); - - CPPUNIT_ASSERT_THROW(theC->setNodal(nodesCells_PYRA5, MED_EN::MED_FACE, MED_EN::MED_PYRA5), MEDEXCEPTION); - } - - // 2 POLYHEDRA - const int nbPolyhedron = 2; - const int nbPolyFaces = 14; - const int nbPolyNodes = 52; - - int aPolyhedronIndex[nbPolyhedron + 1] = {1,8,15}; - - int aPolyhedronFacesIndex[nbPolyFaces + 1] = {1,7,10,14,17,20,24, 27,33,36,40,43,46,50,53}; - - int aPolyhedronNodalConnectivity[nbPolyNodes] = { - 11,15,19,20,17,13, 11,13,14, 14,13,17,18, 18,17,20, 11,14,15, 15,14,18,19, 19,18,20, - 11,13,17,20,19,15, 11,12,13, 13,12,16,17, 17,16,20, 11,15,12, 12,15,19,16, 16,19,20}; - - if (create) { - theC->setPolyhedronConnectivity(MED_EN::MED_NODAL, aPolyhedronNodalConnectivity, - aPolyhedronIndex, nbPolyNodes, nbPolyhedron, - aPolyhedronFacesIndex, nbPolyFaces); - } - else { - // CELLS(3D): theC - { - // Polyhedron-specific methods - { - // invalid polyhedron Id -#ifdef ENABLE_FAULTS - int lenPolyh3nodes; - int nbFaces3; - int *nbNodes3; - // (BUG) Segmentation fault instead of MEDEXCEPTION - CPPUNIT_ASSERT_THROW(theC->getNodesOfPolyhedron(1, lenPolyh3nodes), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getNodesOfPolyhedron(3+3, lenPolyh3nodes), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getNodesPerFaceOfPolyhedron - (/*polyhedronId*/1, nbFaces3, nbNodes3), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theC->getNodesPerFaceOfPolyhedron - (/*polyhedronId*/3+3, nbFaces3, nbNodes3), MEDEXCEPTION); -#endif - } // Polyhedron-specific methods - } // CELLS: theC - } - - if (create) { - // force _constituent computation - CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfTypes(MED_EN::MED_FACE)); - } -} - -int main (int argc, char** argv) -{ - CONNECTIVITY * c1 = new CONNECTIVITY(/*numberOfTypes*/2, MED_EN::MED_CELL); - createOrCheck(c1, "Creation", /*create*/true); - createOrCheck(c1, "Check just created", /*create*/false); -} diff --git a/src/MEDMEM/Test/MEDMEMTest_Coordinate.cxx b/src/MEDMEM/Test/MEDMEMTest_Coordinate.cxx deleted file mode 100644 index 0d70c22d8..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Coordinate.cxx +++ /dev/null @@ -1,410 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/Message.h> -#include <cppunit/TestAssert.h> - -#include "MEDMEM_Array.hxx" -#include "MEDMEM_Coordinate.hxx" - -#include <sstream> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; - -// #8: MEDMEM_Coordinate.hxx } MEDMEMTest_Coordinate.cxx - -/*! - * Check methods (23), defined in MEDMEM_Coordinate.hxx: - * class COORDINATE { - * (+) COORDINATE(); - * (+) COORDINATE(int SpaceDimension, int NumberOfNodes, MED_EN::medModeSwitch Mode); - * (+) COORDINATE(int SpaceDimension,const string * CoordinateName, const string * CoordinateUnit); - * (+) COORDINATE(const COORDINATE & m); - * (+) virtual ~COORDINATE(); - * (+) void setCoordinates(MEDARRAY<double> *Coordinate,bool shallowCopy=false); - * (+) void setCoordinates(const MED_EN::medModeSwitch Mode, const double *Coordinate); - * (+) void setCoordinatesNames(const string * CoordinateName); - * (+) void setCoordinateName(const string CoordinateName, const int i); - * (+) void setCoordinatesUnits(const string * CoordinateUnit); - * (+) void setCoordinateUnit(const string CoordinateUnit, const int i); - * (+) void setCoordinatesSystem(const string CoordinateSystem); - * (+) void setNodesNumbers(const int * NodeNumber); - * (+) int getSpaceDimension() const; - * (+) int getNumberOfNodes() const; - * (+) virtual const int* getNodesNumbers() const; - * (+) string getCoordinatesSystem() const; - * (+) virtual const double * getCoordinates(MED_EN::medModeSwitch Mode); - * (+) virtual double getCoordinate(int Number,int Axis); - * (+) virtual const double * getCoordinateAxis(int Axis); - * (+) const string * getCoordinatesNames() const; - * (+) string getCoordinateName(int Axis) const; - * (+) const string * getCoordinatesUnits() const; - * (+) string getCoordinateUnit(int Axis) const; - * } - * - * Use code of MEDMEM/tests/testUCoordinate.cxx - * MEDMEM/test_copie_coordinate.cxx - */ -void MEDMEMTest::testCoordinate() -{ - ////////////////////////////////////////////// - // TEST 1: MEDMEM/tests/testUCoordinate.cxx // - ////////////////////////////////////////////// - { - const double pouieme = 0.009; - - int SpaceDim = 3; - int NbOfNodes = 5; - - string * noms = new string[3]; - noms[0] = " X "; - noms[1] = " Y "; - noms[2] = " Z "; - - string units[3]; - units[0] = " m "; - units[1] = " m "; - units[2] = " m "; - - int * numbers = new int[5]; - for (int i = 0; i < 5; i++) numbers[i] = 10 + i; - - double coor[15] = {0,0,0,0,0,1,0,1,0,1,0,0,0.5,0.5,0.5}; - CPPUNIT_ASSERT(SpaceDim * NbOfNodes == 15); - - double * coor1 = new double [SpaceDim*NbOfNodes]; - for (int k = 0; k < SpaceDim*NbOfNodes; k++) - coor1[k] = coor[k]; - - MEDARRAY<double>* CoordinateArray = - new MEDARRAY<double>(coor1, SpaceDim, NbOfNodes, MED_EN::MED_FULL_INTERLACE); - COORDINATE mycoo; - CPPUNIT_ASSERT_NO_THROW(mycoo.setCoordinates(CoordinateArray)); - - //--------------------------------------------------------------------// - // Tests des methodes // - // // - // - setCoordinatesNames // - // - setCoordinatesUnits // - // - setCoordinatesSystem // - // - setNodesNumbers // - // // - //--------------------------------------------------------------------// - - CPPUNIT_ASSERT_NO_THROW(mycoo.setCoordinatesNames(noms)); - CPPUNIT_ASSERT_NO_THROW(mycoo.setCoordinatesUnits(units)); - CPPUNIT_ASSERT_NO_THROW(mycoo.setCoordinatesSystem("cartesien")); - CPPUNIT_ASSERT_NO_THROW(mycoo.setNodesNumbers(numbers)); - - //--------------------------------------------------------------------// - // Tests des methodes // - // // - // - getCoordinatesNames // - // - getCoordinatesUnits // - // - getCoordinatesUnit // - // - getCoordinatesSystem // - // - getNodesNumbers // - // // - //--------------------------------------------------------------------// - CPPUNIT_ASSERT_NO_THROW(CPPUNIT_ASSERT(mycoo.getCoordinatesSystem() == "cartesien")); - - const string * units2; - try - { - units2 = mycoo.getCoordinatesUnits(); - for (int axe = 0; axe < SpaceDim; axe++) { - string verif = mycoo.getCoordinateUnit(axe+1); - CPPUNIT_ASSERT(verif == units2[axe]); - } - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - const string * noms2; - try - { - noms2 = mycoo.getCoordinatesNames(); - for (int axe = 0; axe < SpaceDim; axe++) { - string verif = mycoo.getCoordinateName(axe+1); - CPPUNIT_ASSERT(verif == noms2[axe]); - } - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - const double * coor2 = mycoo.getCoordinates(MED_EN::MED_FULL_INTERLACE); - - for (int axe = 0; axe < SpaceDim; axe++) { - const double * coor3 = mycoo.getCoordinateAxis(axe+1); - for (int num = 0; num < NbOfNodes; num++) { - const double d = mycoo.getCoordinate(num + 1, axe + 1); - CPPUNIT_ASSERT(fabs(d - coor3[num ]) < pouieme); - CPPUNIT_ASSERT(fabs(d - coor2[(num * SpaceDim)+axe]) < pouieme); - CPPUNIT_ASSERT(fabs(d - coor [(num * SpaceDim)+axe]) < pouieme); - } - } - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - delete [] noms; - delete [] numbers; - delete [] coor1; - - delete CoordinateArray; - } - - ////////////////////////////////////////////// - // TEST 2: MEDMEM/test_copie_coordinate.cxx // - ////////////////////////////////////////////// - { - const int numberofNodes = 5; - const int spaceDimension = 3; - const MED_EN::medModeSwitch mode = MED_EN::MED_FULL_INTERLACE; - - //construction tableau MEDARRAY des coordonnées - MEDARRAY<double> * myMedArray = new MEDARRAY<double>(spaceDimension, numberofNodes, mode); - for (int i = 1; i <= myMedArray->getLengthValue(); i++) { - for (int j = 1; j <= myMedArray->getLeadingValue(); j++) - myMedArray->setIJ(i, j, (double) i*j); - } - - //construction noms des coordonnées - string * myCoordinatesNames = new string[spaceDimension]; - if (spaceDimension >= 1) myCoordinatesNames[0] = "x"; - if (spaceDimension >= 2) myCoordinatesNames[1] = "y"; - if (spaceDimension >= 3) myCoordinatesNames[2] = "z"; - - //construction unités des coordonnées - string * myCoordinatesUnits = new string[spaceDimension]; - if (spaceDimension >= 1) myCoordinatesUnits[0] = "m"; - if (spaceDimension >= 2) myCoordinatesUnits[1] = "m"; - if (spaceDimension >= 3) myCoordinatesUnits[2] = "m"; - - //construction des indices des noeuds - int * myNodeNumber = new int[numberofNodes]; - for (int i = 0; i < numberofNodes; i++) - myNodeNumber[i] = numberofNodes - i - 1; - - //construction de l'objet COORDINATE - COORDINATE * myCoordinate = new COORDINATE(); - myCoordinate->setCoordinates(myMedArray); - myCoordinate->setCoordinatesNames(myCoordinatesNames); - myCoordinate->setCoordinatesUnits(myCoordinatesUnits); - myCoordinate->setNodesNumbers(myNodeNumber); - - delete myMedArray; - delete[] myCoordinatesNames; - delete[] myCoordinatesUnits; - delete[] myNodeNumber; - - COORDINATE * myCoordinate2 = new COORDINATE(* myCoordinate); - delete myCoordinate; - myCoordinate = NULL; - - // check copied coordinate - int _spaceDimension = myCoordinate2->getSpaceDimension(); - int _numberofNodes = myCoordinate2->getNumberOfNodes(); - CPPUNIT_ASSERT(_spaceDimension == spaceDimension); - CPPUNIT_ASSERT(_numberofNodes == numberofNodes); - - for (int i = 1; i <= _numberofNodes; i++) { - for (int j = 1; j <= _spaceDimension; j++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(i*j, myCoordinate2->getCoordinate(i, j), 0.000001); - } - } - - CPPUNIT_ASSERT(myCoordinate2->getCoordinateName(1) == "x"); - CPPUNIT_ASSERT(myCoordinate2->getCoordinateName(2) == "y"); - CPPUNIT_ASSERT(myCoordinate2->getCoordinateName(3) == "z"); - - CPPUNIT_ASSERT(myCoordinate2->getCoordinateUnit(1) == "m"); - CPPUNIT_ASSERT(myCoordinate2->getCoordinateUnit(2) == "m"); - CPPUNIT_ASSERT(myCoordinate2->getCoordinateUnit(3) == "m"); - - for (int i = 0; i < _numberofNodes; i++) - CPPUNIT_ASSERT(myCoordinate2->getNodesNumbers()[i] == _numberofNodes - i - 1); - - delete myCoordinate2; - } - - //////////// - // TEST 3 // - //////////// - { - // COORDINATE(int SpaceDimension, int NumberOfNodes, MED_EN::medModeSwitch Mode); - COORDINATE anEmptyC (2, 10, MED_EN::MED_FULL_INTERLACE); - CPPUNIT_ASSERT(anEmptyC.getSpaceDimension() == 2); - CPPUNIT_ASSERT(anEmptyC.getNumberOfNodes() == 10); - CPPUNIT_ASSERT(anEmptyC.getNodesNumbers() == NULL); - // ?: how to fill it with coordinates? - // 1. void setCoordinates(MEDARRAY<double> *Coordinate,bool shallowCopy=false); - // but this way we can override all three constructor parameters - // 2. void setCoordinates(const MED_EN::medModeSwitch Mode, const double *Coordinate); - // in this case we can override Mode - -#ifdef ENABLE_FAULTS - // (BUG) Incoherence between setCoordinateName() and getCoordinateName() - anEmptyC.setCoordinateName("alpha", 1); - anEmptyC.setCoordinateName("betta", 2); - // (BUG) Incoherence between setCoordinateUnit() and getCoordinateUnit() - anEmptyC.setCoordinateUnit("ttt", 1); - anEmptyC.setCoordinateUnit("sss", 2); -#else - anEmptyC.setCoordinateName("alpha", 0); - anEmptyC.setCoordinateName("betta", 1); - - anEmptyC.setCoordinateUnit("ttt", 0); - anEmptyC.setCoordinateUnit("sss", 1); -#endif -#ifdef ENABLE_FORCED_FAILURES - //CPPUNIT_FAIL("Incoherence between COORDINATE::setCoordinateName() and COORDINATE::getCoordinateName()"); - //CPPUNIT_FAIL("Incoherence between COORDINATE::setCoordinateUnit() and COORDINATE::getCoordinateUnit()"); -#endif - - int len = 10 * 2; - double * cc = new double[len]; - for (int i = 0; i < len; i++) { - cc[i] = (double)(i + 1); - } - anEmptyC.setCoordinates(MED_EN::MED_NO_INTERLACE, cc); - - CPPUNIT_ASSERT(anEmptyC.getCoordinateName(1) == "alpha"); - CPPUNIT_ASSERT(anEmptyC.getCoordinateName(2) == "betta"); - CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(1) == "ttt"); - CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(2) == "sss"); - for (int nn = 1; nn <= 10; nn++) { - for (int aa = 1; aa <= 2; aa++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(nn + (aa - 1) * 10, anEmptyC.getCoordinate(nn, aa), 0.000001); - } - } - - CPPUNIT_ASSERT_THROW(anEmptyC.getCoordinate(0, 0), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(anEmptyC.getCoordinate(10, 10), MEDEXCEPTION); - - MEDARRAY<double> mcc (cc, 2, 10, MED_EN::MED_FULL_INTERLACE, false, false); - anEmptyC.setCoordinates(&mcc, false); - - // coordinates names and units are not changed - CPPUNIT_ASSERT(anEmptyC.getCoordinateName(1) == "alpha"); - CPPUNIT_ASSERT(anEmptyC.getCoordinateName(2) == "betta"); - CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(1) == "ttt"); - CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(2) == "sss"); - for (int nn = 1; nn <= 10; nn++) { - for (int aa = 1; aa <= 2; aa++) { - // coordinates changed - CPPUNIT_ASSERT_DOUBLES_EQUAL((nn - 1) * 2 + aa, anEmptyC.getCoordinate(nn, aa), 0.000001); - } - } - - delete [] cc; - -#ifdef ENABLE_FAULTS - // (BUG) Segmentation Fault or Hang up after anEmptyC and mcc destruction, - // because array will be owned by two pointers (in mcc and in anEmptyC) after this call - anEmptyC.setCoordinates(&mcc, true); - // In other case (if we dynamically allocate mcc and do not free it) we will have memory leak. -#endif -#ifdef ENABLE_FORCED_FAILURES - //CPPUNIT_FAIL("Bug in COORDINATE::setCoordinates() in shallow copy mode"); -#endif - } - - //////////// - // TEST 4 // - //////////// - { - // COORDINATE(int SpaceDimension,const string * CoordinateName, const string * CoordinateUnit); - string cnames [3] = {"al", "be", "ga"}; - string cunits [3] = {"kg", "mm", "s2"}; - COORDINATE anEmptyA (3, cnames, cunits); - - CPPUNIT_ASSERT(anEmptyA.getCoordinateName(1) == "al"); - CPPUNIT_ASSERT(anEmptyA.getCoordinateName(2) == "be"); - CPPUNIT_ASSERT(anEmptyA.getCoordinateName(3) == "ga"); - - CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(1) == "kg"); - CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(2) == "mm"); - CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(3) == "s2"); - - CPPUNIT_ASSERT_EQUAL(anEmptyA.getSpaceDimension(), 0); - CPPUNIT_ASSERT_EQUAL(anEmptyA.getNumberOfNodes(), 0); - - MEDARRAY<double> mcc (3, 7, MED_EN::MED_NO_INTERLACE); - anEmptyA.setCoordinates(&mcc, false); - - CPPUNIT_ASSERT_EQUAL(anEmptyA.getSpaceDimension(), 3); - CPPUNIT_ASSERT_EQUAL(anEmptyA.getNumberOfNodes(), 7); - - CPPUNIT_ASSERT(anEmptyA.getCoordinateName(1) == "al"); - CPPUNIT_ASSERT(anEmptyA.getCoordinateName(2) == "be"); - CPPUNIT_ASSERT(anEmptyA.getCoordinateName(3) == "ga"); - - CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(1) == "kg"); - CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(2) == "mm"); - CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(3) == "s2"); - - CPPUNIT_ASSERT_THROW(anEmptyA.getCoordinate(-1, 0), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(anEmptyA.getCoordinate(10, 10), MEDEXCEPTION); - - // No COORDINATE::operator=, but this is compilable - // good - //COORDINATE anEmptyB; - //COORDINATE anEmptyD (3, cnames, cunits); - //anEmptyB = anEmptyD; - //CPPUNIT_ASSERT(anEmptyB.getCoordinateName(1) == "al"); - - // bad (assert fails) - //COORDINATE anEmptyB; - // Object, created in this line, is destructed right after it. - //anEmptyB = COORDINATE(3, cnames, cunits); - // Now a pointer _coordinateName inside anEmptyB points to a desallocated memory zone - //CPPUNIT_ASSERT(anEmptyB.getCoordinateName(1) == "al"); - } -} diff --git a/src/MEDMEM/Test/MEDMEMTest_Coordinate_fault.cxx b/src/MEDMEM/Test/MEDMEMTest_Coordinate_fault.cxx deleted file mode 100644 index 7393cf56a..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Coordinate_fault.cxx +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEM_Array.hxx" -#include "MEDMEM_Coordinate.hxx" - -using namespace std; -using namespace MEDMEM; - -int main (int argc, char** argv) -{ - COORDINATE anEmptyC (2, 10, MED_EN::MED_FULL_INTERLACE); - - // (BUG) Incoherence between setCoordinateName() and getCoordinateName() - // C++ index notation is used in "set" methods, while in "get" methods indices start from 1. - anEmptyC.setCoordinateName("alpha", 1); - anEmptyC.setCoordinateName("betta", 2); - // (BUG) Incoherence between setCoordinateUnit() and getCoordinateUnit() - // C++ index notation is used in "set" methods, while in "get" methods indices start from 1. - anEmptyC.setCoordinateUnit("ttt", 1); - anEmptyC.setCoordinateUnit("sss", 2); - - //CPPUNIT_ASSERT(anEmptyC.getCoordinateName(1) == "alpha"); - //CPPUNIT_ASSERT(anEmptyC.getCoordinateName(2) == "betta"); - //CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(1) == "ttt"); - //CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(2) == "sss"); - - int len = 10 * 2; - double * cc = new double[len]; - for (int i = 0; i < len; i++) { - cc[i] = (double)(i + 1); - } - - MEDARRAY<double> mcc (cc, 2, 10, MED_EN::MED_FULL_INTERLACE, false, false); - delete [] cc; - - // (BUG) Bug in COORDINATE::setCoordinates() in shallow copy mode: - // Segmentation Fault or Hang up after anEmptyC and mcc destruction, - // because array will be owned by two pointers (in mcc and in anEmptyC) after this call - anEmptyC.setCoordinates(&mcc, true); - // In other case (if we dynamically allocate mcc and do not free it) we will have memory leak. -} diff --git a/src/MEDMEM/Test/MEDMEMTest_DriverFactory.cxx b/src/MEDMEM/Test/MEDMEMTest_DriverFactory.cxx deleted file mode 100644 index cc6b63d0d..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_DriverFactory.cxx +++ /dev/null @@ -1,920 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/Message.h> -#include <cppunit/TestAssert.h> - -#include "MEDMEM_DriverFactory.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_GenDriver.hxx" -#include "MEDMEM_GibiMeshDriver.hxx" -#include "MEDMEM_MedFieldDriver21.hxx" -#include "MEDMEM_MedFieldDriver22.hxx" -#include "MEDMEM_MedFieldDriver.hxx" -#include "MEDMEM_Med.hxx" -#include "MEDMEM_MedMedDriver21.hxx" -#include "MEDMEM_MedMedDriver22.hxx" -#include "MEDMEM_MedMedDriver.hxx" -#include "MEDMEM_MedMeshDriver21.hxx" -#include "MEDMEM_MedMeshDriver22.hxx" -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_PorflowMeshDriver.hxx" -#include "MEDMEM_STRING.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_VtkFieldDriver.hxx" -#include "MEDMEM_VtkMedDriver.hxx" -#include "MEDMEM_VtkMeshDriver.hxx" - -#include <sstream> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; - -// #9: MEDMEM_DriverFactory.hxx } MEDMEMTest_DriverFactory.cxx - -/*! - * Check methods (11), defined in MEDMEM_DriverFactory.hxx: - * namespace DRIVERFACTORY { - * (+) MED_EN::medFileVersion getMedFileVersionForWriting(); - * (+) void setMedFileVersionForWriting(MED_EN::medFileVersion version); - * (+) driverTypes deduceDriverTypeFromFileName(const std::string & fileName); - * - * (+) GENDRIVER * buildDriverForMesh (driverTypes driverType, const std::string & fileName, - * MESH *mesh, const string & driverName, - * MED_EN::med_mode_acces access); - * (+) template<class T, class INTERLACING_TAG> - * GENDRIVER * buildDriverForField(driverTypes driverType, const std::string & fileName, - * FIELD<T,INTERLACING_TAG> *fielde, - * MED_EN::med_mode_acces access); - * (+) GENDRIVER * buildDriverForMed (driverTypes driverType, const std::string & fileName, - * MED *mede, - * MED_EN::med_mode_acces access); - * - * (+) GENDRIVER * buildMedDriverFromFile (const string & fileName, MED * const ptrMed, - * MED_EN::med_mode_acces access); - * (+) GENDRIVER * buildMeshDriverFromFile (const string & fileName, MESH * ptrMesh, - * MED_EN::med_mode_acces access); - * (+) template<class T, class INTERLACING_TAG> - * GENDRIVER * buildFieldDriverFromFile(const string & fileName, - * FIELD<T,INTERLACING_TAG> * ptrField, - * MED_EN::med_mode_acces access); - * - * (+) GENDRIVER * buildConcreteMedDriverForMesh(const std::string & fileName, MESH *mesh, - * const string & driverName, - * MED_EN::med_mode_acces access, - * MED_EN::medFileVersion version); - * (+) template<class T, class INTERLACING_TAG> - * GENDRIVER * buildConcreteMedDriverForField(const std::string & fileName, - * FIELD<T,INTERLACING_TAG> *fielde, - * MED_EN::med_mode_acces access, - * MED_EN::medFileVersion version); - * } - */ -void MEDMEMTest::testDriverFactory() -{ - /////////////////////////////////////////////////////////////////////// - // Test 1: getMedFileVersionForWriting & setMedFileVersionForWriting // - /////////////////////////////////////////////////////////////////////// - - // save current version preference - MED_EN::medFileVersion aVersionSaved = DRIVERFACTORY::getMedFileVersionForWriting(); - - // check version preference changing - MED_EN::medFileVersion aVersionToSet = - (aVersionSaved == MED_EN::V22) ? MED_EN::V21 : MED_EN::V22; - DRIVERFACTORY::setMedFileVersionForWriting(aVersionToSet); - CPPUNIT_ASSERT(aVersionToSet == DRIVERFACTORY::getMedFileVersionForWriting()); - - // restore default version preference - DRIVERFACTORY::setMedFileVersionForWriting(aVersionSaved); - - ////////////////////////////////////////// - // Test 2: deduceDriverTypeFromFileName // - ////////////////////////////////////////// - CPPUNIT_ASSERT(DRIVERFACTORY::deduceDriverTypeFromFileName("test.med") == MED_DRIVER); - CPPUNIT_ASSERT(DRIVERFACTORY::deduceDriverTypeFromFileName("t.st.sauve") == GIBI_DRIVER); - CPPUNIT_ASSERT(DRIVERFACTORY::deduceDriverTypeFromFileName("t.st.sauv") == GIBI_DRIVER); - CPPUNIT_ASSERT(DRIVERFACTORY::deduceDriverTypeFromFileName("t.st.cnc") == PORFLOW_DRIVER); - CPPUNIT_ASSERT(DRIVERFACTORY::deduceDriverTypeFromFileName("t.st.inp") == PORFLOW_DRIVER); - CPPUNIT_ASSERT(DRIVERFACTORY::deduceDriverTypeFromFileName("t.st.xyz") == PORFLOW_DRIVER); - CPPUNIT_ASSERT(DRIVERFACTORY::deduceDriverTypeFromFileName("t.st.vtk") == VTK_DRIVER); - CPPUNIT_ASSERT(DRIVERFACTORY::deduceDriverTypeFromFileName("t_st_med") == NO_DRIVER); - CPPUNIT_ASSERT(DRIVERFACTORY::deduceDriverTypeFromFileName("t.st.med1") == NO_DRIVER); - - //////////////////////////////////////////////////////// - // Test building drivers for different types of files // - //////////////////////////////////////////////////////// - GENDRIVER * aDriver = NULL; - - /////////////////////////////// - // Test 3: buildDriverForMed // - /////////////////////////////// - MED med; - - // 3.1: MED_DRIVER - - // rdonly - aDriver = DRIVERFACTORY::buildDriverForMed(MED_DRIVER, "anyfile", &med, MED_EN::MED_LECT); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) See more details below for the same problem of MED_MESH_RDONLY_DRIVER - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_LECT, aDriver->getAccessMode()); -#endif - - MED_MED_RDONLY_DRIVER * aMedRDriverForMed = dynamic_cast<MED_MED_RDONLY_DRIVER *> (aDriver); - CPPUNIT_ASSERT(aMedRDriverForMed); - - delete aDriver; - - // wronly - aDriver = DRIVERFACTORY::buildDriverForMed(MED_DRIVER, "anyfile", &med, MED_EN::MED_ECRI); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) See more details below for the same problem of MED_MESH_RDONLY_DRIVER - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_ECRI); -#endif - - MED_MED_WRONLY_DRIVER * aMedWDriverForMed = dynamic_cast<MED_MED_WRONLY_DRIVER *> (aDriver); - CPPUNIT_ASSERT(aMedWDriverForMed); - - delete aDriver; - - // rdwr - aDriver = DRIVERFACTORY::buildDriverForMed(MED_DRIVER, "anyfile", &med, MED_EN::MED_REMP); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) See more details below for the same problem of MED_MESH_RDONLY_DRIVER - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_REMP); -#endif - - MED_MED_RDWR_DRIVER * aMedRWDriverForMed = dynamic_cast<MED_MED_RDWR_DRIVER *> (aDriver); - CPPUNIT_ASSERT(aMedRWDriverForMed); - - delete aDriver; - - // 3.2: GIBI_DRIVER - - // rdonly - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMed(GIBI_DRIVER, "anyfile", &med, MED_EN::MED_LECT), - MED_EXCEPTION); - // wronly - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMed(GIBI_DRIVER, "anyfile", &med, MED_EN::MED_ECRI), - MED_EXCEPTION); - // rdwr - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMed(GIBI_DRIVER, "anyfile", &med, MED_EN::MED_REMP), - MED_EXCEPTION); - - // 3.3: PORFLOW_DRIVER - - // rdonly - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMed(PORFLOW_DRIVER, "anyfile", &med, MED_EN::MED_LECT), - MED_EXCEPTION); - // wronly - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMed(PORFLOW_DRIVER, "anyfile", &med, MED_EN::MED_ECRI), - MED_EXCEPTION); - // rdwr - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMed(PORFLOW_DRIVER, "anyfile", &med, MED_EN::MED_REMP), - MED_EXCEPTION); - - // 3.4: VTK_DRIVER - - // rdonly - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMed(VTK_DRIVER, "anyfile", &med, MED_EN::MED_LECT), - MED_EXCEPTION); - - // wronly - aDriver = DRIVERFACTORY::buildDriverForMed(VTK_DRIVER, "anyfile", &med, MED_EN::MED_ECRI); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_ECRI); - - VTK_MED_DRIVER * aVtkDriverForMed = dynamic_cast<VTK_MED_DRIVER *> (aDriver); - CPPUNIT_ASSERT(aVtkDriverForMed); - - delete aDriver; - - // rdwr - aDriver = DRIVERFACTORY::buildDriverForMed(VTK_DRIVER, "anyfile", &med, MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - //CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_RDWR); // see MEDMEM_define.hxx - - aVtkDriverForMed = dynamic_cast<VTK_MED_DRIVER *> (aDriver); - CPPUNIT_ASSERT(aVtkDriverForMed); - - delete aDriver; - - // 3.5: ASCII_DRIVER - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMed(ASCII_DRIVER, "anyfile", &med, MED_EN::MED_LECT), - MED_EXCEPTION); - - // 3.6: NO_DRIVER - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMed(NO_DRIVER, "anyfile", &med, MED_EN::MED_LECT), - MED_EXCEPTION); - - //////////////////////////////// - // Test 4: buildDriverForMesh // - //////////////////////////////// - MESH mesh; - - // 4.1: MED_DRIVER - - // rdonly - aDriver = DRIVERFACTORY::buildDriverForMesh - (MED_DRIVER, "anyfile", &mesh, "my driver name", MED_EN::MED_LECT); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_LECT); - - - MED_MESH_RDONLY_DRIVER * aMedRDriverForMesh = dynamic_cast<MED_MESH_RDONLY_DRIVER *> (aDriver); - CPPUNIT_ASSERT(aMedRDriverForMesh); - CPPUNIT_ASSERT(aMedRDriverForMesh->getMeshName() == "my driver name"); - - - delete aDriver; - - // wronly - aDriver = DRIVERFACTORY::buildDriverForMesh - (MED_DRIVER, "anyfile", &mesh, "my driver name", MED_EN::MED_ECRI); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_ECRI); - - MED_MESH_WRONLY_DRIVER * aMedWDriverForMesh = dynamic_cast<MED_MESH_WRONLY_DRIVER *> (aDriver); - CPPUNIT_ASSERT(aMedWDriverForMesh); - CPPUNIT_ASSERT(aMedWDriverForMesh->getMeshName() == "my driver name"); - - delete aDriver; - - // rdwr - aDriver = DRIVERFACTORY::buildDriverForMesh - (MED_DRIVER, "anyfile", &mesh, "my driver name", MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_REMP); - - MED_MESH_RDWR_DRIVER * aMedRWDriverForMesh = dynamic_cast<MED_MESH_RDWR_DRIVER *> (aDriver); - CPPUNIT_ASSERT(aMedRWDriverForMesh); - CPPUNIT_ASSERT(aMedRWDriverForMesh->getMeshName() == "my driver name"); - - delete aDriver; - - // 4.2: GIBI_DRIVER - - // rdonly - aDriver = DRIVERFACTORY::buildDriverForMesh - (GIBI_DRIVER, "anyfile", &mesh, "my driver name", MED_EN::MED_LECT); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_LECT); - - GIBI_MESH_RDONLY_DRIVER * aGibiDriverForMesh = dynamic_cast<GIBI_MESH_RDONLY_DRIVER *> (aDriver); - CPPUNIT_ASSERT(aGibiDriverForMesh); - - delete aDriver; - - // wronly - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMesh(GIBI_DRIVER, "anyfile", &mesh, - "my driver name", MED_EN::MED_ECRI), - MED_EXCEPTION); - // rdwr - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMesh(GIBI_DRIVER, "anyfile", &mesh, - "my driver name", MED_EN::MED_REMP), - MED_EXCEPTION); - - // 4.3: PORFLOW_DRIVER - - // rdonly - aDriver = DRIVERFACTORY::buildDriverForMesh - (PORFLOW_DRIVER, "anyfile", &mesh, "my driver name", MED_EN::MED_LECT); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_LECT); - - PORFLOW_MESH_RDONLY_DRIVER * aPorflowDriverForMesh = dynamic_cast<PORFLOW_MESH_RDONLY_DRIVER *> (aDriver); - CPPUNIT_ASSERT(aPorflowDriverForMesh); - - delete aDriver; - - // wronly - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMesh(PORFLOW_DRIVER, "anyfile", &mesh, - "my driver name", MED_EN::MED_ECRI), - MED_EXCEPTION); - // rdwr - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMesh(PORFLOW_DRIVER, "anyfile", &mesh, - "my driver name", MED_EN::MED_REMP), - MED_EXCEPTION); - - // 4.4: VTK_DRIVER - - // rdonly - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMesh(VTK_DRIVER, "anyfile", &mesh, - "my driver name", MED_EN::MED_LECT), - MED_EXCEPTION); - - // wronly - aDriver = DRIVERFACTORY::buildDriverForMesh - (VTK_DRIVER, "anyfile", &mesh, "my driver name", MED_EN::MED_ECRI); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_ECRI); - - VTK_MESH_DRIVER * aVtkDriverForMesh = dynamic_cast<VTK_MESH_DRIVER *> (aDriver); - CPPUNIT_ASSERT(aVtkDriverForMesh); - - delete aDriver; - - // rdwr - aDriver = DRIVERFACTORY::buildDriverForMesh - (VTK_DRIVER, "anyfile", &mesh, "my driver name", MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - //CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_RDWR); // see MEDMEM_define.hxx - - aVtkDriverForMesh = dynamic_cast<VTK_MESH_DRIVER *> (aDriver); - CPPUNIT_ASSERT(aVtkDriverForMesh); - - delete aDriver; - - // 4.5: ASCII_DRIVER - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMesh(ASCII_DRIVER, "anyfile", &mesh, - "my driver name", MED_EN::MED_LECT), - MED_EXCEPTION); - - // 4.6: NO_DRIVER - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMesh(NO_DRIVER, "anyfile", &mesh, - "my driver name", MED_EN::MED_LECT), - MED_EXCEPTION); - - ///////////////////////////////// - // Test 5: buildDriverForField // - ///////////////////////////////// - FIELD<double> field; - - // 5.1: MED_DRIVER - - // rdonly - aDriver = DRIVERFACTORY::buildDriverForField(MED_DRIVER, "anyfile", &field, MED_EN::MED_LECT); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_LECT); - - MED_FIELD_RDONLY_DRIVER<double> * aMedRDriverForField = - dynamic_cast<MED_FIELD_RDONLY_DRIVER<double> *> (aDriver); - CPPUNIT_ASSERT(aMedRDriverForField); - - delete aDriver; - - // wronly - aDriver = DRIVERFACTORY::buildDriverForField(MED_DRIVER, "anyfile", &field, MED_EN::MED_ECRI); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_ECRI); - - MED_FIELD_WRONLY_DRIVER<double> * aMedWDriverForField = - dynamic_cast<MED_FIELD_WRONLY_DRIVER<double> *> (aDriver); - CPPUNIT_ASSERT(aMedWDriverForField); - - delete aDriver; - - // rdwr - aDriver = DRIVERFACTORY::buildDriverForField(MED_DRIVER, "anyfile", &field, MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Wrong access mode (MED_ECRI) passed to parent class! - // confusion between MED_DRWR (defined as MED_ECRI in MEDMEM_define.hxx) - // and MED_REMP causes confusion in MEDMEM_MedFieldDriver22.hxx - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_REMP,aDriver->getAccessMode()); -#endif - - MED_FIELD_RDWR_DRIVER<double> * aMedRWDriverForField = - dynamic_cast<MED_FIELD_RDWR_DRIVER<double> *> (aDriver); - CPPUNIT_ASSERT(aMedRWDriverForField); - - delete aDriver; - - // 5.2: GIBI_DRIVER - - // rdonly - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(GIBI_DRIVER, "anyfile", &field, MED_EN::MED_LECT), - MED_EXCEPTION); - // wronly - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(GIBI_DRIVER, "anyfile", &field, MED_EN::MED_ECRI), - MED_EXCEPTION); - // rdwr - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(GIBI_DRIVER, "anyfile", &field, MED_EN::MED_REMP), - MED_EXCEPTION); - - // 5.3: PORFLOW_DRIVER - - // rdonly - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(PORFLOW_DRIVER, "anyfile", - &field, MED_EN::MED_LECT), - MED_EXCEPTION); - // wronly - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(PORFLOW_DRIVER, "anyfile", - &field, MED_EN::MED_ECRI), - MED_EXCEPTION); - // rdwr - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(PORFLOW_DRIVER, "anyfile", - &field, MED_EN::MED_REMP), - MED_EXCEPTION); - - // 5.4: VTK_DRIVER - - // rdonly - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(VTK_DRIVER, "anyfile", &field, MED_EN::MED_LECT), - MED_EXCEPTION); - - // wronly - aDriver = DRIVERFACTORY::buildDriverForField(VTK_DRIVER, "anyfile", &field, MED_EN::MED_ECRI); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_ECRI); - - VTK_FIELD_DRIVER<double> * aVtkDriverForField = dynamic_cast<VTK_FIELD_DRIVER<double> *> (aDriver); - CPPUNIT_ASSERT(aVtkDriverForField); - - delete aDriver; - - // rdwr - aDriver = DRIVERFACTORY::buildDriverForField(VTK_DRIVER, "anyfile", &field, MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - //CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_RDWR); // see MEDMEM_define.hxx - - aVtkDriverForField = dynamic_cast<VTK_FIELD_DRIVER<double> *> (aDriver); - CPPUNIT_ASSERT(aVtkDriverForField); - - delete aDriver; - - // 5.5: ASCII_DRIVER - - // rdonly - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(ASCII_DRIVER, "anyfile", &field, MED_EN::MED_LECT), - MED_EXCEPTION); - // rdwr - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(ASCII_DRIVER, "anyfile", &field, MED_EN::MED_REMP), - MED_EXCEPTION); - - // wronly - // it throws on empty field - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(ASCII_DRIVER, "anyfile", &field, MED_EN::MED_ECRI), - MED_EXCEPTION); - - // now try with valid field - string datadir = getenv("DATA_DIR"); - string filename = datadir + "/MedFiles/pointe.med"; - string meshname = "maa1"; - string fieldname = "fieldcelldouble"; - FIELD<double> * aField1 = new FIELD<double> (MED_DRIVER, filename, fieldname); - const SUPPORT * aSupport = aField1->getSupport(); - MESH * aMesh = new MESH (MED_DRIVER, filename, aSupport->getMeshName()); - aSupport->setMesh(aMesh); - - aDriver = DRIVERFACTORY::buildDriverForField(ASCII_DRIVER, "anyfile", aField1, MED_EN::MED_ECRI); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_ECRI); - - // it works! - //aDriver->open(); - //aDriver->write(); - //aDriver->close(); - - ASCII_FIELD_DRIVER<double> * anAsciiDriverForField = - dynamic_cast<ASCII_FIELD_DRIVER<double> *> (aDriver); - CPPUNIT_ASSERT(anAsciiDriverForField); - - delete aDriver; - - delete aField1; - delete aMesh; - - // 5.6: NO_DRIVER - CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(NO_DRIVER, "anyfile", &field, MED_EN::MED_LECT), - MED_EXCEPTION); - - //////////////////////////////////// - // Test 6: buildMedDriverFromFile // - //////////////////////////////////// - string aFileName1 = datadir + "/MedFiles/pointe.med"; - string aFileName2 = datadir + "/MedFiles/polyedres.med"; - medFileVersion version1, version2; - - try { - version1 = getMedFileVersion(aFileName1); - } catch (MEDEXCEPTION & ex) { - version1 = DRIVERFACTORY::globalMedFileVersionForWriting; - } - - try { - version2 = getMedFileVersion(aFileName2); - } catch (MEDEXCEPTION & ex) { - version2 = DRIVERFACTORY::globalMedFileVersionForWriting; - } - - // 6.1. Med file V2.1 - string aFileName21 = aFileName1; - if (version1 == MED_EN::V21 || version2 == MED_EN::V21) { - if (version1 == MED_EN::V22) - aFileName21 = aFileName2; - - // rdonly - aDriver = DRIVERFACTORY::buildMedDriverFromFile(aFileName21, &med, MED_EN::MED_LECT); - CPPUNIT_ASSERT(aDriver->getFileName() == aFileName21); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_LECT); - - MED_MED_RDONLY_DRIVER21 * aMedRDriverForMed21 = dynamic_cast<MED_MED_RDONLY_DRIVER21 *> (aDriver); - CPPUNIT_ASSERT(aMedRDriverForMed21); - - delete aDriver; - - // wronly - aDriver = DRIVERFACTORY::buildMedDriverFromFile(aFileName21, &med, MED_EN::MED_ECRI); - CPPUNIT_ASSERT(aDriver->getFileName() == aFileName21); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_ECRI); - - MED_MED_WRONLY_DRIVER21 * aMedWDriverForMed21 = dynamic_cast<MED_MED_WRONLY_DRIVER21 *> (aDriver); - CPPUNIT_ASSERT(aMedWDriverForMed21); - - delete aDriver; - - // rdwr - aDriver = DRIVERFACTORY::buildMedDriverFromFile(aFileName21, &med, MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getFileName() == aFileName21); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_REMP); - - MED_MED_RDWR_DRIVER21 * aMedRWDriverForMed21 = dynamic_cast<MED_MED_RDWR_DRIVER21 *> (aDriver); - CPPUNIT_ASSERT(aMedRWDriverForMed21); - - delete aDriver; - } - - // 6.2. Med file V2.2 - string aFileName22 = aFileName2; - if (version2 == MED_EN::V22 || version1 == MED_EN::V22) { - if (version2 == MED_EN::V21) - aFileName22 = aFileName1; - - // rdonly - aDriver = DRIVERFACTORY::buildMedDriverFromFile(aFileName22, &med, MED_EN::MED_LECT); - CPPUNIT_ASSERT(aDriver->getFileName() == aFileName22); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_LECT); - - MED_MED_RDONLY_DRIVER22 * aMedRDriverForMed22 = dynamic_cast<MED_MED_RDONLY_DRIVER22 *> (aDriver); - CPPUNIT_ASSERT(aMedRDriverForMed22); - - delete aDriver; - - // wronly - aDriver = DRIVERFACTORY::buildMedDriverFromFile(aFileName22, &med, MED_EN::MED_ECRI); - CPPUNIT_ASSERT(aDriver->getFileName() == aFileName22); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_ECRI); - - MED_MED_WRONLY_DRIVER22 * aMedWDriverForMed22 = dynamic_cast<MED_MED_WRONLY_DRIVER22 *> (aDriver); - CPPUNIT_ASSERT(aMedWDriverForMed22); - - delete aDriver; - - // rdwr - aDriver = DRIVERFACTORY::buildMedDriverFromFile(aFileName22, &med, MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getFileName() == aFileName22); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_REMP); - - MED_MED_RDWR_DRIVER22 * aMedRWDriverForMed22 = dynamic_cast<MED_MED_RDWR_DRIVER22 *> (aDriver); - CPPUNIT_ASSERT(aMedRWDriverForMed22); - - delete aDriver; - } - else { - CPPUNIT_FAIL("Cannot check building of drivers from file for V2.2"); - } - if (version1 != MED_EN::V21 && version2 != MED_EN::V21) { - CPPUNIT_FAIL("Cannot check building of drivers from file for V2.1"); - } - - ///////////////////////////////////// - // Test 7: buildMeshDriverFromFile // - ///////////////////////////////////// - - // 7.1. Med file V2.1 - if (version1 == MED_EN::V21 || version2 == MED_EN::V21) { - // rdonly - aDriver = DRIVERFACTORY::buildMeshDriverFromFile(aFileName21, &mesh, MED_EN::MED_LECT); - CPPUNIT_ASSERT(aDriver->getFileName() == aFileName21); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_LECT); - - MED_MESH_RDONLY_DRIVER21 * aMeshRDriverForMed21 = dynamic_cast<MED_MESH_RDONLY_DRIVER21 *> (aDriver); - CPPUNIT_ASSERT(aMeshRDriverForMed21); - - delete aDriver; - - // wronly - aDriver = DRIVERFACTORY::buildMeshDriverFromFile(aFileName21, &mesh, MED_EN::MED_ECRI); - CPPUNIT_ASSERT(aDriver->getFileName() == aFileName21); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_ECRI); - - MED_MESH_WRONLY_DRIVER21 * aMeshWDriverForMed21 = dynamic_cast<MED_MESH_WRONLY_DRIVER21 *> (aDriver); - CPPUNIT_ASSERT(aMeshWDriverForMed21); - - delete aDriver; - - // rdwr - aDriver = DRIVERFACTORY::buildMeshDriverFromFile(aFileName21, &mesh, MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getFileName() == aFileName21); - //CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_RDWR); // see MEDMEM_define.hxx - - MED_MESH_RDWR_DRIVER21 * aMeshRWDriverForMed21 = dynamic_cast<MED_MESH_RDWR_DRIVER21 *> (aDriver); - CPPUNIT_ASSERT(aMeshRWDriverForMed21); - - delete aDriver; - } - - // 7.2. Med file V2.2 - if (version2 == MED_EN::V22 || version1 == MED_EN::V22) { - // rdonly - aDriver = DRIVERFACTORY::buildMeshDriverFromFile(aFileName22, &mesh, MED_EN::MED_LECT); - CPPUNIT_ASSERT(aDriver->getFileName() == aFileName22); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_LECT); - - MED_MESH_RDONLY_DRIVER22 * aMeshRDriverForMed22 = dynamic_cast<MED_MESH_RDONLY_DRIVER22 *> (aDriver); - CPPUNIT_ASSERT(aMeshRDriverForMed22); - - delete aDriver; - - // wronly - aDriver = DRIVERFACTORY::buildMeshDriverFromFile(aFileName22, &mesh, MED_EN::MED_ECRI); - CPPUNIT_ASSERT(aDriver->getFileName() == aFileName22); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_ECRI); - - MED_MESH_WRONLY_DRIVER22 * aMeshWDriverForMed22 = dynamic_cast<MED_MESH_WRONLY_DRIVER22 *> (aDriver); - CPPUNIT_ASSERT(aMeshWDriverForMed22); - - delete aDriver; - - // rdwr - aDriver = DRIVERFACTORY::buildMeshDriverFromFile(aFileName22, &mesh, MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getFileName() == aFileName22); - //CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_RDWR); // see MEDMEM_define.hxx - - MED_MESH_RDWR_DRIVER22 * aMeshRWDriverForMed22 = dynamic_cast<MED_MESH_RDWR_DRIVER22 *> (aDriver); - CPPUNIT_ASSERT(aMeshRWDriverForMed22); - - delete aDriver; - } - - ////////////////////////////////////// - // Test 8: buildFieldDriverFromFile // - ////////////////////////////////////// - - // 8.1. Med file V2.1 - if (version1 == MED_EN::V21 || version2 == MED_EN::V21) { - // rdonly - aDriver = DRIVERFACTORY::buildFieldDriverFromFile(aFileName21, &field, MED_EN::MED_LECT); - CPPUNIT_ASSERT(aDriver->getFileName() == aFileName21); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_LECT); - - MED_FIELD_RDONLY_DRIVER21<double> * aFieldRDriverForMed21 = - dynamic_cast<MED_FIELD_RDONLY_DRIVER21<double> *> (aDriver); - CPPUNIT_ASSERT(aFieldRDriverForMed21); - - delete aDriver; - - // wronly - aDriver = DRIVERFACTORY::buildFieldDriverFromFile(aFileName21, &field, MED_EN::MED_ECRI); - CPPUNIT_ASSERT(aDriver->getFileName() == aFileName21); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_ECRI); - - MED_FIELD_WRONLY_DRIVER21<double> * aFieldWDriverForMed21 = - dynamic_cast<MED_FIELD_WRONLY_DRIVER21<double> *> (aDriver); - CPPUNIT_ASSERT(aFieldWDriverForMed21); - - delete aDriver; - - // rdwr - aDriver = DRIVERFACTORY::buildFieldDriverFromFile(aFileName21, &field, MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getFileName() == aFileName21); - //CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_RDWR); // see MEDMEM_define.hxx - - MED_FIELD_RDWR_DRIVER21<double> * aFieldRWDriverForMed21 = - dynamic_cast<MED_FIELD_RDWR_DRIVER21<double> *> (aDriver); - CPPUNIT_ASSERT(aFieldRWDriverForMed21); - - delete aDriver; - } - - // 8.2. Med file V2.2 - if (version2 == MED_EN::V22 || version1 == MED_EN::V22) { - // rdonly - aDriver = DRIVERFACTORY::buildFieldDriverFromFile(aFileName22, &field, MED_EN::MED_LECT); - CPPUNIT_ASSERT(aDriver->getFileName() == aFileName22); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_LECT); - - MED_FIELD_RDONLY_DRIVER22<double> * aFieldRDriverForMed22 = - dynamic_cast<MED_FIELD_RDONLY_DRIVER22<double> *> (aDriver); - CPPUNIT_ASSERT(aFieldRDriverForMed22); - - delete aDriver; - - // wronly - aDriver = DRIVERFACTORY::buildFieldDriverFromFile(aFileName22, &field, MED_EN::MED_ECRI); - CPPUNIT_ASSERT(aDriver->getFileName() == aFileName22); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_ECRI); - - MED_FIELD_WRONLY_DRIVER22<double> * aFieldWDriverForMed22 = - dynamic_cast<MED_FIELD_WRONLY_DRIVER22<double> *> (aDriver); - CPPUNIT_ASSERT(aFieldWDriverForMed22); - - delete aDriver; - - // rdwr - aDriver = DRIVERFACTORY::buildFieldDriverFromFile(aFileName22, &field, MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getFileName() == aFileName22); - //CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_RDWR); // see MEDMEM_define.hxx - - MED_FIELD_RDWR_DRIVER22<double> * aFieldRWDriverForMed22 = - dynamic_cast<MED_FIELD_RDWR_DRIVER22<double> *> (aDriver); - CPPUNIT_ASSERT(aFieldRWDriverForMed22); - - delete aDriver; - } - - /////////////////////////////////////////// - // Test 9: buildConcreteMedDriverForMesh // - /////////////////////////////////////////// - - // 9.1. V2.1 - - // rdonly - aDriver = DRIVERFACTORY::buildConcreteMedDriverForMesh("anyfile", &mesh, "my driver name", - MED_EN::MED_LECT, MED_EN::V21); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_LECT); - - MED_MESH_RDONLY_DRIVER21 * aMeshRDriverForMed21 = dynamic_cast<MED_MESH_RDONLY_DRIVER21 *> (aDriver); - CPPUNIT_ASSERT(aMeshRDriverForMed21); - CPPUNIT_ASSERT(aMeshRDriverForMed21->getMeshName() == "my driver name"); - - delete aDriver; - - // wronly - aDriver = DRIVERFACTORY::buildConcreteMedDriverForMesh("anyfile", &mesh, "my driver name", - MED_EN::MED_ECRI, MED_EN::V21); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_ECRI); - - MED_MESH_WRONLY_DRIVER21 * aMeshWDriverForMed21 = dynamic_cast<MED_MESH_WRONLY_DRIVER21 *> (aDriver); - CPPUNIT_ASSERT(aMeshWDriverForMed21); - CPPUNIT_ASSERT(aMeshWDriverForMed21->getMeshName() == "my driver name"); - - delete aDriver; - - // rdwr - aDriver = DRIVERFACTORY::buildConcreteMedDriverForMesh("anyfile", &mesh, "my driver name", - MED_EN::MED_REMP, MED_EN::V21); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - //CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_RDWR); // see MEDMEM_define.hxx - - MED_MESH_RDWR_DRIVER21 * aMeshRWDriverForMed21 = dynamic_cast<MED_MESH_RDWR_DRIVER21 *> (aDriver); - CPPUNIT_ASSERT(aMeshRWDriverForMed21); - CPPUNIT_ASSERT(aMeshRWDriverForMed21->getMeshName() == "my driver name"); - - delete aDriver; - - // 9.2. V2.2 - - // rdonly - aDriver = DRIVERFACTORY::buildConcreteMedDriverForMesh("anyfile", &mesh, "my driver name", - MED_EN::MED_LECT, MED_EN::V22); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_LECT); - - MED_MESH_RDONLY_DRIVER22 * aMeshRDriverForMed22 = dynamic_cast<MED_MESH_RDONLY_DRIVER22 *> (aDriver); - CPPUNIT_ASSERT(aMeshRDriverForMed22); - CPPUNIT_ASSERT(aMeshRDriverForMed22->getMeshName() == "my driver name"); - - delete aDriver; - - // wronly - aDriver = DRIVERFACTORY::buildConcreteMedDriverForMesh("anyfile", &mesh, "my driver name", - MED_EN::MED_ECRI, MED_EN::V22); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_ECRI); - - MED_MESH_WRONLY_DRIVER22 * aMeshWDriverForMed22 = dynamic_cast<MED_MESH_WRONLY_DRIVER22 *> (aDriver); - CPPUNIT_ASSERT(aMeshWDriverForMed22); - CPPUNIT_ASSERT(aMeshWDriverForMed22->getMeshName() == "my driver name"); - - delete aDriver; - - // rdwr - aDriver = DRIVERFACTORY::buildConcreteMedDriverForMesh("anyfile", &mesh, "my driver name", - MED_EN::MED_REMP, MED_EN::V22); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - //CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_RDWR); // see MEDMEM_define.hxx - - MED_MESH_RDWR_DRIVER22 * aMeshRWDriverForMed22 = dynamic_cast<MED_MESH_RDWR_DRIVER22 *> (aDriver); - CPPUNIT_ASSERT(aMeshRWDriverForMed22); - CPPUNIT_ASSERT(aMeshRWDriverForMed22->getMeshName() == "my driver name"); - - delete aDriver; - - ///////////////////////////////////////////// - // Test 10: buildConcreteMedDriverForField // - ///////////////////////////////////////////// - - // 10.1. V2.1 - - // rdonly - aDriver = DRIVERFACTORY::buildConcreteMedDriverForField("anyfile", &field, MED_EN::MED_LECT, MED_EN::V21); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_LECT); - - MED_FIELD_RDONLY_DRIVER21<double> * aFieldRDriverForMed21 = - dynamic_cast<MED_FIELD_RDONLY_DRIVER21<double> *> (aDriver); - CPPUNIT_ASSERT(aFieldRDriverForMed21); - - delete aDriver; - - // wronly - aDriver = DRIVERFACTORY::buildConcreteMedDriverForField("anyfile", &field, MED_EN::MED_ECRI, MED_EN::V21); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_ECRI); - - MED_FIELD_WRONLY_DRIVER21<double> * aFieldWDriverForMed21 = - dynamic_cast<MED_FIELD_WRONLY_DRIVER21<double> *> (aDriver); - CPPUNIT_ASSERT(aFieldWDriverForMed21); - - delete aDriver; - - // rdwr - aDriver = DRIVERFACTORY::buildConcreteMedDriverForField("anyfile", &field, MED_EN::MED_REMP, MED_EN::V21); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - //CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_RDWR); // see MEDMEM_define.hxx - - MED_FIELD_RDWR_DRIVER21<double> * aFieldRWDriverForMed21 = - dynamic_cast<MED_FIELD_RDWR_DRIVER21<double> *> (aDriver); - CPPUNIT_ASSERT(aFieldRWDriverForMed21); - - delete aDriver; - - // 10.2. V2.2 - - // rdonly - aDriver = DRIVERFACTORY::buildConcreteMedDriverForField("anyfile", &field, MED_EN::MED_LECT, MED_EN::V22); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_LECT); - - MED_FIELD_RDONLY_DRIVER22<double> * aFieldRDriverForMed22 = - dynamic_cast<MED_FIELD_RDONLY_DRIVER22<double> *> (aDriver); - CPPUNIT_ASSERT(aFieldRDriverForMed22); - - delete aDriver; - - // wronly - aDriver = DRIVERFACTORY::buildConcreteMedDriverForField("anyfile", &field, MED_EN::MED_ECRI, MED_EN::V22); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_ECRI); - - MED_FIELD_WRONLY_DRIVER22<double> * aFieldWDriverForMed22 = - dynamic_cast<MED_FIELD_WRONLY_DRIVER22<double> *> (aDriver); - CPPUNIT_ASSERT(aFieldWDriverForMed22); - - delete aDriver; - - // rdwr - aDriver = DRIVERFACTORY::buildConcreteMedDriverForField("anyfile", &field, MED_EN::MED_REMP, MED_EN::V22); - CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); - //CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_REMP); - CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::MED_RDWR); // see MEDMEM_define.hxx - - MED_FIELD_RDWR_DRIVER22<double> * aFieldRWDriverForMed22 = - dynamic_cast<MED_FIELD_RDWR_DRIVER22<double> *> (aDriver); - CPPUNIT_ASSERT(aFieldRWDriverForMed22); - - delete aDriver; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_Exception.cxx b/src/MEDMEM/Test/MEDMEMTest_Exception.cxx deleted file mode 100644 index 7c8f79dd5..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Exception.cxx +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_STRING.hxx" - -#include <sstream> -#include <cmath> - -using namespace std; -using namespace MEDMEM; - -// #12: MEDMEM_Exception.hxx } MEDMEMTest_Exception.cxx - -/*! - * Check methods (not in spec), defined in MEDMEM_Exception.hxx: - * (+) #define LOCALIZED(message) static_cast<const char *> (message) , __FILE__ , __LINE__ - * class MEDEXCEPTION : public std::exception { - * (+) MEDEXCEPTION(const char *text, const char *fileName=0, const unsigned int lineNumber=0); - * (+) MEDEXCEPTION(const MEDEXCEPTION &ex); - * (+) ~MEDEXCEPTION() throw (); - * (+) friend ostream & operator<< (ostream &os, const MEDEXCEPTION &ex); - * (+) virtual const char *what(void) const throw (); - * } - * class MED_DRIVER_NOT_FOUND_EXCEPTION : public MEDEXCEPTION { - * (+) MED_DRIVER_NOT_FOUND_EXCEPTION(const char *text, const char *fileName=0, - * const unsigned int lineNumber=0); - * (+) MED_DRIVER_NOT_FOUND_EXCEPTION(const MED_DRIVER_NOT_FOUND_EXCEPTION &ex); - * (+) ~MED_DRIVER_NOT_FOUND_EXCEPTION() throw(); - * } - * - * Use code of MEDMEM/tests/testUMedException.cxx - */ -void MEDMEMTest::testException() -{ - { - // test simple constructor - MEDEXCEPTION a = MEDEXCEPTION("test med exception"); - CPPUNIT_ASSERT(a.what()); - CPPUNIT_ASSERT(strcmp(a.what(), "MED Exception : test med exception") == 0); - - // test copy constructor - MEDEXCEPTION b (a); - CPPUNIT_ASSERT(b.what()); - CPPUNIT_ASSERT(strcmp(b.what(), "MED Exception : test med exception") == 0); - - // test dumping of exception in stream - ostringstream ostr; - ostr << b; - CPPUNIT_ASSERT(ostr.str() == "MED Exception : test med exception"); - } - - { - // test constructor from three arguments - MEDEXCEPTION c ("test med exception", "<file_name>.cxx", 14); - CPPUNIT_ASSERT(c.what()); - CPPUNIT_ASSERT(strcmp(c.what(), "MED Exception in <file_name>.cxx [14] : test med exception") == 0); - } - - { - // Test macro LOCALIZED - STRING msgErr; - msgErr << "ESSAI::ESSAI()! "<< 4 << "ieme essai "; - - const char* prefix = "MED Exception"; - const char* exctxt = static_cast<const char *>(msgErr); - char* filen = __FILE__; - unsigned int linen = __LINE__ + 5; - const size_t len = strlen(prefix) + strlen(exctxt) + strlen(filen) + - (1 + int(log10(float(linen)))) + 10 + 1; - char* excmsg = new char [len]; - sprintf(excmsg, "%s in %s [%u] : %s", prefix, filen, linen, exctxt); - CPPUNIT_ASSERT(strcmp(MEDEXCEPTION(LOCALIZED(msgErr)).what(), excmsg) == 0); - - delete [] excmsg; - } - - { - // Test function STRING<< - const char * LOC = "toto"; - CPPUNIT_ASSERT(MEDEXCEPTION(LOCALIZED(STRING(LOC) << " et titi")).what()); - - // Test throw - MEDEXCEPTION d (LOCALIZED(STRING(LOC) << " et titi")); - const char* dtxt = d.what(); - try { - throw d; - } - catch (MEDEXCEPTION dc) { - CPPUNIT_ASSERT(strcmp(dc.what(), dtxt) == 0); - } - catch (...) { - CPPUNIT_FAIL("Unknown exception"); - } - } - - { - // Test MED_DRIVER_NOT_FOUND_EXCEPTION - MED_DRIVER_NOT_FOUND_EXCEPTION g ("mdnfe"); - try { - throw g; - } - catch (MED_DRIVER_NOT_FOUND_EXCEPTION mdnfe) { - CPPUNIT_ASSERT(strcmp(mdnfe.what(), g.what()) == 0); - } - catch (MEDEXCEPTION me) { - CPPUNIT_FAIL(me.what()); - } - catch (...) { - CPPUNIT_FAIL("Unknown exception"); - } - - // Copy constructor - MED_DRIVER_NOT_FOUND_EXCEPTION gcopy (g); - CPPUNIT_ASSERT(gcopy.what()); - CPPUNIT_ASSERT(strcmp(gcopy.what(), g.what()) == 0); - } -} diff --git a/src/MEDMEM/Test/MEDMEMTest_Family.cxx b/src/MEDMEM/Test/MEDMEMTest_Family.cxx deleted file mode 100644 index 325c9065d..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Family.cxx +++ /dev/null @@ -1,491 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "MEDMEM_define.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Compatibility21_22.hxx" - -#include <sstream> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; - -// #13: MEDMEM_Family.hxx } MEDMEMTest_Family.cxx - -/*! - * Check methods (24), defined in MEDMEM_Family.hxx: - * class FAMILY : virtual public SUPPORT { - * (+) FAMILY(); - * (+) FAMILY(MESH* Mesh, int Identifier, string Name, - * int NumberOfAttribute, int *AttributeIdentifier, - * int *AttributeValue, string AttributeDescription, - * int NumberOfGroup, string GroupName, - * int * MEDArrayNodeFamily, int ** MEDArrayCellFamily, - * int ** MEDArrayFaceFamily, int ** MEDArrayEdgeFamily); - * (+) FAMILY(const FAMILY & m); - * (+) FAMILY(const SUPPORT & s); - * (+) virtual ~FAMILY(); - * - * // Does not work (Segmentation Fault of Hang up) - * (!) FAMILY & operator=(const FAMILY &fam); - * - * (+) friend ostream & operator<<(ostream &os, FAMILY &my); - * (+) friend ostream & operator<<(ostream &os, const FAMILY &my); - * - * (+) bool build(MED_EN::medEntityMesh Entity,int **FamilyNumber); - * - * (+) inline void setIdentifier (int Identifier); - * (+) inline void setNumberOfAttributes (int NumberOfAttribute); - * (+) inline void setAttributesIdentifiers (int * AttributeIdentifier); - * (+) inline void setAttributesValues (int * AttributeValue); - * (+) inline void setAttributesDescriptions (string * AttributeDescription); - * (+) inline void setNumberOfGroups (int NumberOfGroups); - * (+) inline void setGroupsNames (string * GroupName); - * - * (+) inline int getIdentifier() const; - * (+) inline int getNumberOfAttributes() const; - * (+) inline const int * getAttributesIdentifiers() const; - * (+) inline const int * getAttributesValues() const; - * (+) inline const string * getAttributesDescriptions() const; - * (+) inline int getNumberOfGroups() const; - * (+) inline const string * getGroupsNames() const; - * - * (+) inline int getAttributeIdentifier(int i) const; - * (+) inline int getAttributeValue(int i) const; - * (+) inline string getAttributeDescription(int i) const; - * (+) inline string getGroupName(int i) const; - * } - * - * Use code of MEDMEM/test_copie_family.cxx - */ -void check_support(const SUPPORT * theSupport, - string theName, string theDescr, MED_EN::medEntityMesh theEntity, int theNbTypes) -{ - string aName = theSupport->getName(); - string aDescr = theSupport->getDescription(); - MED_EN::medEntityMesh anEntity = theSupport->getEntity(); - int aNbGeomTypes = theSupport->getNumberOfTypes(); - - CPPUNIT_ASSERT_EQUAL(theName, aName); - CPPUNIT_ASSERT_EQUAL(theDescr, aDescr); - CPPUNIT_ASSERT_EQUAL(theEntity, anEntity); - CPPUNIT_ASSERT_EQUAL(theNbTypes, aNbGeomTypes); - - cout << " - Entities list : " << endl; - if (!(theSupport->isOnAllElements())) { - cout << " - NumberOfTypes : " << aNbGeomTypes << endl; - const MED_EN::medGeometryElement * Types = theSupport->getTypes(); - for (int j = 0; j < aNbGeomTypes; j++) { - cout << " * Type " << Types[j] << " : "; - int NumberOfElements = theSupport->getNumberOfElements(Types[j]); - const int * Number = theSupport->getNumber(Types[j]); - for (int k = 0; k < NumberOfElements; k++) - cout << Number[k] << " "; - cout << endl; - } - } else - cout << " Is on all entities !" << endl; -} - -void check_famille(const FAMILY * theFamily, - string theName, string theDescr, MED_EN::medEntityMesh theEntity, int theNbTypes, - int theID, int theNbAttributes, int theNbGroups) -{ - check_support(theFamily, theName, theDescr, theEntity, theNbTypes); - - // identifier - int id = theFamily->getIdentifier(); - int nbAttributes = theFamily->getNumberOfAttributes(); - int nbGroups = theFamily->getNumberOfGroups(); - - CPPUNIT_ASSERT_EQUAL(theID, id); - CPPUNIT_ASSERT_EQUAL(theNbAttributes, nbAttributes); - CPPUNIT_ASSERT_EQUAL(theNbGroups, nbGroups); - - // attributes - cout << " - Attributes (" << nbAttributes << ") :" << endl; - for (int j = 1; j < nbAttributes + 1; j++) - cout << " * " - << theFamily->getAttributeIdentifier(j) << " : " - << theFamily->getAttributeValue(j) << ", " - << theFamily->getAttributeDescription(j).c_str() << endl; - - // groups - cout << " - Groups (" << nbGroups << ") :" << endl; - for (int j = 1; j < nbGroups + 1; j++) - cout << " * " << theFamily->getGroupName(j).c_str() << endl; -} - -void MEDMEMTest::testFamily() -{ - /////////////////////////////////// - // TEST 1: test_copie_family.cxx // - /////////////////////////////////// - string datadir = getenv("DATA_DIR"); - string filename = datadir + "/MedFiles/pointe.med"; - string meshname = "maa1"; - - MESH * aMesh = new MESH(); - aMesh->setName(meshname); - MED_MESH_RDONLY_DRIVER aMeshDriver (filename, aMesh); - aMeshDriver.setMeshName(meshname); - aMeshDriver.open(); - aMeshDriver.read(); - aMeshDriver.close(); - - const FAMILY * aFamily1 = aMesh->getFamily(MED_EN::MED_NODE, 1); - - // SUPPORT attributes - string aName = aFamily1->getName(); - string aDescr = aFamily1->getDescription(); - MED_EN::medEntityMesh anEntity = aFamily1->getEntity(); - int aNbGeomTypes = aFamily1->getNumberOfTypes(); - - // FAMILY attributes - int id = aFamily1->getIdentifier(); - int nbAttributes = aFamily1->getNumberOfAttributes(); - int nbGroups = aFamily1->getNumberOfGroups(); - - // Dump - ostringstream ostr1; - ostr1 << *aFamily1; - CPPUNIT_ASSERT(ostr1.str() != ""); - - cout << "Show Family1 :" << endl; - check_famille(aFamily1, - aName, aDescr, anEntity, aNbGeomTypes, - id, nbAttributes, nbGroups); - - // Copy constructor - FAMILY * aFamily2 = new FAMILY (* aFamily1); - - // Dump - ostringstream ostr2; - ostr2 << *aFamily2; - CPPUNIT_ASSERT(ostr1.str() == ostr2.str()); - - // Compare supports - CPPUNIT_ASSERT(aFamily2->deepCompare(*aFamily1)); - - cout << "Show Family2 :" << endl; - check_famille(aFamily2, - aName, aDescr, anEntity, aNbGeomTypes, - id, nbAttributes, nbGroups); - - // One more copy - FAMILY * aFamily3 = new FAMILY (* aFamily2); - delete aFamily2; - - // Dump - ostringstream ostr3; - ostr3 << *aFamily3; - CPPUNIT_ASSERT(ostr1.str() == ostr3.str()); - - cout << "Show Family3 :" << endl; - check_famille(aFamily3, - aName, aDescr, anEntity, aNbGeomTypes, - id, nbAttributes, nbGroups); - - cout << "That's all" << endl; - - //////////// - // TEST 2 // - //////////// - { - // Prepare data - - // attributes - int newNumberOfAttribute = 3; - int * newAttributeIdentifier = new int[newNumberOfAttribute]; - int * newAttributeValue = new int[newNumberOfAttribute]; - string * newAttributeDescription = new string[newNumberOfAttribute]; - - char tmp [32]; - for (int i = 0; i < newNumberOfAttribute; i++) { - newAttributeIdentifier[i] = i+1; - newAttributeValue[i] = (i+1)*10; - sprintf(tmp, "Attribut N° %d", i+1); - newAttributeDescription[i] = tmp; - } - - // groups - int newNumberOfGroups = 4; - string * newGroups = new string[newNumberOfGroups]; - for (int i = 0; i < newNumberOfGroups; i++) { - sprintf(tmp, "Group N° %d", i+1); - newGroups[i] = tmp; - } - - // Change aFamily3 - - // attributes - aFamily3->setNumberOfAttributes(newNumberOfAttribute); - aFamily3->setAttributesIdentifiers(newAttributeIdentifier); - aFamily3->setAttributesValues(newAttributeValue); - aFamily3->setAttributesDescriptions(newAttributeDescription); - - // groups - aFamily3->setNumberOfGroups(newNumberOfGroups); - aFamily3->setGroupsNames(newGroups, /*giveOwnership = */true); - - // identifier - aFamily3->setIdentifier(77); - - // check new parameters of aFamily3 - - // attributes - CPPUNIT_ASSERT_EQUAL(newNumberOfAttribute, aFamily3->getNumberOfAttributes()); - const int * newAttributeIdentifierBack = aFamily3->getAttributesIdentifiers(); - const int * newAttributeValueBack = aFamily3->getAttributesValues(); - const string * newAttributeDescriptionBack = aFamily3->getAttributesDescriptions(); - for (int i = 1; i <= newNumberOfAttribute; i++) { - sprintf(tmp, "Attribut N° %d", i); - string descr (tmp); - - CPPUNIT_ASSERT_EQUAL(i , aFamily3->getAttributeIdentifier(i)); - CPPUNIT_ASSERT_EQUAL(i*10 , aFamily3->getAttributeValue(i)); - CPPUNIT_ASSERT_EQUAL(descr, aFamily3->getAttributeDescription(i)); - - CPPUNIT_ASSERT_EQUAL(i , newAttributeIdentifierBack[i - 1]); - CPPUNIT_ASSERT_EQUAL(i*10 , newAttributeValueBack[i - 1]); - CPPUNIT_ASSERT_EQUAL(descr, newAttributeDescriptionBack[i - 1]); - } - - delete [] newAttributeIdentifier; - delete [] newAttributeValue; - delete [] newAttributeDescription; - - // groups - CPPUNIT_ASSERT_EQUAL(newNumberOfGroups, aFamily3->getNumberOfGroups()); - const string * newGroupsBack = aFamily3->getGroupsNames(); - for (int i = 1; i <= newNumberOfGroups; i++) { - sprintf(tmp, "Group N° %d", i); - string grp (tmp); - - CPPUNIT_ASSERT_EQUAL(grp, aFamily3->getGroupName(i)); - CPPUNIT_ASSERT_EQUAL(grp, newGroupsBack[i - 1]); - } - - // identifier - CPPUNIT_ASSERT_EQUAL(77, aFamily3->getIdentifier()); - } - - ///////////////////////////////////////////////////// - // TEST 3: check default constructor and operator= // - ///////////////////////////////////////////////////// - { - FAMILY aFamily4; -#ifdef ENABLE_FAULTS - aFamily4 = (const FAMILY &)*aFamily3; -#endif -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Wrong implementation or usage of PointerOf<string>. - // Do not use memcpy() with array of std::string! - CPPUNIT_FAIL("Impossible to use FAMILY::operator= because of" - " wrong implementation or usage of PointerOf<string>"); - /*{ - int nb = 3; - string * str = new string[nb]; - - char tmp_str [32]; - for (int i = 0; i < nb; i++) { - sprintf(tmp_str, "My String N° %d", i+1); - str[i] = tmp; - } - - // bad - string* _pointer; - _pointer = new string[3]; - // This is wrong, because class string is not simple type - // and can have pointers to some data, deallocated in it's destructor, - // which (data) will not be copied by this operation. - memcpy(_pointer, str, 3*sizeof(string)); - delete [] _pointer; - - // good - //PointerOf<int> p1 (1); - //PointerOf<int> p2 (20); - //p2 = newAttributeValue; - //p1.set(3, p2); - - // bad - //PointerOf<string> p1 (1); - //PointerOf<string> p2 (20); - //p2 = str; - //p1.set(3, p2); - - delete [] str; - } - */ -#endif - } - - /////////////////////////////////////////////////// - // TEST 4: check construction from given support // - /////////////////////////////////////////////////// - { - SUPPORT s1 (*aFamily3); - FAMILY f1 (s1); - CPPUNIT_ASSERT_EQUAL(0, f1.getIdentifier()); - CPPUNIT_ASSERT_EQUAL(0, f1.getNumberOfAttributes()); - CPPUNIT_ASSERT_EQUAL(0, f1.getNumberOfGroups()); - CPPUNIT_ASSERT(s1.deepCompare(f1)); - } - - delete aFamily3; - delete aMesh; - - ///////////////////////////////////////////////////////////////// - // TEST 5: check constructor, designed to use with med driver. // - ///////////////////////////////////////////////////////////////// - { - MESH * aTestMesh = MEDMEMTest_createTestMesh(); - - // TestMesh families. Let's imagine that we would like to have - // the following nodes and elements distribution by families: - - // NumberOfNodes = 19; - int aNodeFamily[19] = {1, 1, 1, 1, 1, 1, 1, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 3, 3, 3}; - - // NumberOfCellTypes = 3; - // NumberOfCells[NumberOfCellTypes] = {12, 2, 2}; - int aCellType1Family[12] = {4,4,4,4,4,5,5,5,5,5,5,5}; - int aCellType2Family[ 2] = {5,6}; - int aCellType3Family[ 2] = {6,6}; - int * aCellFamily[3] = {aCellType1Family, aCellType2Family, aCellType3Family}; - - // NumberOfFaceTypes = 2; - // NumberOfFaces[NumberOfFaceTypes] = {4, 4}; - int aFaceType1Family[4] = {7,7,7,7}; - int aFaceType2Family[4] = {7,7,7,7}; - int * aFaceFamily[3] = {aFaceType1Family, aFaceType2Family}; - - // No edges in aTestMesh - int ** anEdgeFamily = NULL; - - // new families data - int attrId[2] = {1,2}; - int attrVa[2] = {7,8}; - - string attrDescr1 ("Attribute 1 description"); - string attrDescr2 ("Attribute 2 description"); - string attrDescrEmpty (MED_TAILLE_DESC - 23, ' '); - attrDescr1 += attrDescrEmpty; - attrDescr2 += attrDescrEmpty; - CPPUNIT_ASSERT(MED_TAILLE_DESC == attrDescr1.length()); - CPPUNIT_ASSERT(MED_TAILLE_DESC == attrDescr2.length()); - string attrDescr = attrDescr1 + attrDescr2; - - string groupName1 ("Group_1"); - string groupName2 ("Group_2"); - string groupName3 ("Group_3"); - string groupNameEmpty (MED_TAILLE_LNOM - 7, ' '); - groupName1 += groupNameEmpty; - groupName2 += groupNameEmpty; - groupName3 += groupNameEmpty; - CPPUNIT_ASSERT(MED_TAILLE_LNOM == groupName1.length()); - CPPUNIT_ASSERT(MED_TAILLE_LNOM == groupName2.length()); - CPPUNIT_ASSERT(MED_TAILLE_LNOM == groupName3.length()); - string groupNames = groupName1 + groupName2 + groupName3; - - // nodes family 1 - FAMILY aNodesF1 (aTestMesh, /*Identifier*/1, "Nodes 1", - /*NumberOfAttribute*/2, attrId, attrVa, attrDescr, - /*NumberOfGroup*/3, groupNames, - aNodeFamily, aCellFamily, aFaceFamily, anEdgeFamily); - - //cout << "Show aNodesF1 :" << endl; - //cout << aNodesF1 << endl; - - CPPUNIT_ASSERT_EQUAL(1, aNodesF1.getIdentifier()); - CPPUNIT_ASSERT(strcmp("Nodes 1", aNodesF1.getName().c_str()) == 0); - CPPUNIT_ASSERT(MED_EN::MED_NODE == aNodesF1.getEntity()); - CPPUNIT_ASSERT(!aNodesF1.isOnAllElements()); - CPPUNIT_ASSERT_EQUAL(7, aNodesF1.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - - CPPUNIT_ASSERT_EQUAL(2, aNodesF1.getNumberOfAttributes()); - CPPUNIT_ASSERT_EQUAL(1, aNodesF1.getAttributeIdentifier(1)); - CPPUNIT_ASSERT_EQUAL(2, aNodesF1.getAttributeIdentifier(2)); - CPPUNIT_ASSERT_EQUAL(7, aNodesF1.getAttributeValue(1)); - CPPUNIT_ASSERT_EQUAL(8, aNodesF1.getAttributeValue(2)); - CPPUNIT_ASSERT_EQUAL(attrDescr1, aNodesF1.getAttributeDescription(1)); - CPPUNIT_ASSERT_EQUAL(attrDescr2, aNodesF1.getAttributeDescription(2)); - - CPPUNIT_ASSERT_EQUAL(3, aNodesF1.getNumberOfGroups()); - CPPUNIT_ASSERT_EQUAL(groupName1, aNodesF1.getGroupName(1)); - CPPUNIT_ASSERT_EQUAL(groupName2, aNodesF1.getGroupName(2)); - CPPUNIT_ASSERT_EQUAL(groupName3, aNodesF1.getGroupName(3)); - - // faces family 7 - FAMILY aFacesF7 (aTestMesh, /*Identifier*/7, "Faces All", - /*NumberOfAttribute*/2, attrId, attrVa, attrDescr, - /*NumberOfGroup*/3, groupNames, - aNodeFamily, aCellFamily, aFaceFamily, anEdgeFamily); - - cout << "Show aFacesF7 :" << endl; - cout << aFacesF7 << endl; - - CPPUNIT_ASSERT_EQUAL(7, aFacesF7.getIdentifier()); - CPPUNIT_ASSERT(strcmp("Faces All", aFacesF7.getName().c_str()) == 0); - CPPUNIT_ASSERT(MED_EN::MED_FACE == aFacesF7.getEntity()); - - CPPUNIT_ASSERT_EQUAL(8, aTestMesh->getNumberOfElementsWithPoly(MED_EN::MED_FACE, - MED_EN::MED_ALL_ELEMENTS)); - CPPUNIT_ASSERT_EQUAL(8, aFacesF7.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - -#ifdef ENABLE_FORCED_FAILURES - // ? (BUG) ? Why _isOnAllElts is set to true only for nodes and cells. What about faces? - // _isOnAllElts = true ; - // See MEDMEM_Family.cxx lines 118-119 and 386-387. - CPPUNIT_ASSERT(aFacesF7.isOnAllElements()); -#endif - - CPPUNIT_ASSERT_EQUAL(2, aFacesF7.getNumberOfAttributes()); - CPPUNIT_ASSERT_EQUAL(1, aFacesF7.getAttributeIdentifier(1)); - CPPUNIT_ASSERT_EQUAL(2, aFacesF7.getAttributeIdentifier(2)); - CPPUNIT_ASSERT_EQUAL(7, aFacesF7.getAttributeValue(1)); - CPPUNIT_ASSERT_EQUAL(8, aFacesF7.getAttributeValue(2)); - CPPUNIT_ASSERT_EQUAL(attrDescr1, aFacesF7.getAttributeDescription(1)); - CPPUNIT_ASSERT_EQUAL(attrDescr2, aFacesF7.getAttributeDescription(2)); - - CPPUNIT_ASSERT_EQUAL(3, aFacesF7.getNumberOfGroups()); - CPPUNIT_ASSERT_EQUAL(groupName1, aFacesF7.getGroupName(1)); - CPPUNIT_ASSERT_EQUAL(groupName2, aFacesF7.getGroupName(2)); - CPPUNIT_ASSERT_EQUAL(groupName3, aFacesF7.getGroupName(3)); - - delete aTestMesh; - - // Method build() is not tested directly, but it is called from constructor, tested here - } -} diff --git a/src/MEDMEM/Test/MEDMEMTest_Family_fault.cxx b/src/MEDMEM/Test/MEDMEMTest_Family_fault.cxx deleted file mode 100644 index 37a9daa97..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Family_fault.cxx +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEM_define.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_Mesh.hxx" - -using namespace std; -using namespace MEDMEM; - -int main (int argc, char** argv) -{ - string datadir = getenv("DATA_DIR"); - string filename = datadir + "/MedFiles/pointe.med"; - string meshname = "maa1"; - - MESH * aMesh = new MESH(); - aMesh->setName(meshname); - MED_MESH_RDONLY_DRIVER aMeshDriver (filename, aMesh); - aMeshDriver.setMeshName(meshname); - aMeshDriver.open(); - aMeshDriver.read(); - aMeshDriver.close(); - - const FAMILY * aFamily1 = aMesh->getFamily(MED_EN::MED_NODE, 1); - - // check default constructor and operator= - FAMILY aFamily4; - - // (BUG) Wrong implementation or usage of PointerOf<string>. - // Do not use memcpy() with array of std::string! - // Impossible to use FAMILY::operator=! - aFamily4 = *aFamily1; - - /*{ - int nb = 3; - string * str = new string[nb]; - - char tmp_str [32]; - for (int i = 0; i < nb; i++) { - sprintf(tmp_str, "My String N° %d", i+1); - str[i] = tmp; - } - - // bad - string* _pointer; - _pointer = new string[3]; - // This is wrong, because class string is not simple type - // and can have pointers to some data, deallocated in it's destructor, - // which (data) will not be copied by this operation. - memcpy(_pointer, str, 3*sizeof(string)); - delete [] _pointer; - - // good - //PointerOf<int> p1 (1); - //PointerOf<int> p2 (20); - //p2 = newAttributeValue; - //p1.set(3, p2); - - // bad - //PointerOf<string> p1 (1); - //PointerOf<string> p2 (20); - //p2 = str; - //p1.set(3, p2); - - delete [] str; - } - */ - - delete aMesh; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_Field.cxx b/src/MEDMEM/Test/MEDMEMTest_Field.cxx deleted file mode 100644 index 73999c449..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Field.cxx +++ /dev/null @@ -1,1718 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "MEDMEM_FieldConvert.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Group.hxx" -#include "MEDMEM_Support.hxx" -#include <MEDMEM_VtkMeshDriver.hxx> -#include <MEDMEM_MedMeshDriver22.hxx> - - -#include <sstream> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; - -// #14,15: MEDMEMTest_Field.cxx -// Check methods from MEDMEM_Field.hxx, MEDMEM_FieldConvert.hxx - -/*! - * Check methods (48), defined in MEDMEM_Field.hxx: - * class FIELD_ { - * (+) FIELD_(); - * (+) FIELD_(const SUPPORT * Support, const int NumberOfComponents); - * (+) FIELD_(const FIELD_ &m); - * (+) virtual ~FIELD_(); - * (+) FIELD_& operator=(const FIELD_ &m); - * - * (-) virtual void rmDriver(int index=0); - * (-) virtual int addDriver(driverTypes driverType, - * const string & fileName="Default File Name.med", - * const string & driverFieldName="Default Field Nam", - * MED_EN::med_mode_acces access=MED_EN::MED_REMP); - * (-) virtual int addDriver(GENDRIVER & driver); - * - * (-) virtual void read (const GENDRIVER &); - * (-) virtual void read(int index=0); - * (-) virtual void openAppend(void); - * (-) virtual void write(const GENDRIVER &); - * (-) virtual void write(int index=0, const string & driverName=""); - * (-) virtual void writeAppend(const GENDRIVER &); - * (-) virtual void writeAppend(int index=0, const string & driverName=""); - * - * (+) inline void setName(const string Name); - * (+) inline string getName() const; - * (+) inline void setDescription(const string Description); - * (+) inline string getDescription() const; - * (+) inline const SUPPORT * getSupport() const; - * (+) inline void setSupport(const SUPPORT * support); - * (+) inline void setNumberOfComponents(const int NumberOfComponents); - * (+) inline int getNumberOfComponents() const; - * (+) inline void setNumberOfValues(const int NumberOfValues); - * (+) inline int getNumberOfValues() const; - * (+) inline void setComponentsNames(const string * ComponentsNames); - * (+) inline void setComponentName(int i, const string ComponentName); - * (+) inline const string * getComponentsNames() const; - * (+) inline string getComponentName(int i) const; - * (+) inline void setComponentsDescriptions(const string * ComponentsDescriptions); - * (+) inline void setComponentDescription(int i, const string ComponentDescription); - * (+) inline const string * getComponentsDescriptions() const; - * (+) inline string getComponentDescription(int i) const; - * (+) inline void setComponentsUnits(const UNIT * ComponentsUnits); - * (+) inline const UNIT * getComponentsUnits() const; - * (+) inline const UNIT * getComponentUnit(int i) const; - * (+) inline void setMEDComponentsUnits(const string * MEDComponentsUnits); - * (+) inline void setMEDComponentUnit(int i, const string MEDComponentUnit); - * (+) inline const string * getMEDComponentsUnits() const; - * (+) inline string getMEDComponentUnit(int i) const; - * - * (+) inline void setIterationNumber(int IterationNumber); - * (+) inline int getIterationNumber() const; - * (+) inline void setTime(double Time); - * (+) inline double getTime() const; - * (+) inline void setOrderNumber(int OrderNumber); - * (+) inline int getOrderNumber() const; - * - * (+) inline MED_EN::med_type_champ getValueType () const; - * (+) inline MED_EN::medModeSwitch getInterlacingType() const; - * (-) virtual inline bool getGaussPresence() const throw (MEDEXCEPTION); - * } - * - * template <class T, class INTERLACING_TAG> class FIELD : public FIELD_ { - * (+) FIELD(); - * (+) FIELD(const FIELD &m); - * (+) FIELD(const SUPPORT * Support, const int NumberOfComponents) throw (MEDEXCEPTION); - * (+) FIELD(driverTypes driverType, - * const string & fileName, const string & fieldDriverName, - * const int iterationNumber=-1, const int orderNumber=-1) throw (MEDEXCEPTION); - * (+) FIELD(const SUPPORT * Support, driverTypes driverType, - * const string & fileName="", const string & fieldName="", - * const int iterationNumber = -1, const int orderNumber = -1) throw (MEDEXCEPTION); - * (+) ~FIELD(); - * (+) FIELD & operator=(const FIELD &m); - * - * (+) const FIELD operator+(const FIELD& m) const; - * (+) const FIELD operator-(const FIELD& m) const; - * (+) const FIELD operator*(const FIELD& m) const; - * (+) const FIELD operator/(const FIELD& m) const; - * (+) const FIELD operator-() const; - * (+) FIELD& operator+=(const FIELD& m); - * (+) FIELD& operator-=(const FIELD& m); - * (+) FIELD& operator*=(const FIELD& m); - * (+) FIELD& operator/=(const FIELD& m); - * - * (+) static FIELD* add(const FIELD& m, const FIELD& n); - * (+) static FIELD* addDeep(const FIELD& m, const FIELD& n); - * (+) static FIELD* sub(const FIELD& m, const FIELD& n); - * (+) static FIELD* subDeep(const FIELD& m, const FIELD& n); - * (+) static FIELD* mul(const FIELD& m, const FIELD& n); - * (+) static FIELD* mulDeep(const FIELD& m, const FIELD& n); - * (+) static FIELD* div(const FIELD& m, const FIELD& n); - * (+) static FIELD* divDeep(const FIELD& m, const FIELD& n); - * - * (+) double normMax() const throw (MEDEXCEPTION); - * (+) double norm2() const throw (MEDEXCEPTION); - * - * (+) void applyLin(T a, T b); - * (+) template <T T_function(T)> void applyFunc(); - * (+) void applyPow(T scalar); - * - * (+) static FIELD* scalarProduct(const FIELD& m, const FIELD& n, bool deepCheck=false); - * - * (+) double normL2(int component, const FIELD<double,FullInterlace> * p_field_volume=NULL) const; - * (+) double normL2(const FIELD<double,FullInterlace> * p_field_volume=NULL) const; - * (+) double normL1(int component, const FIELD<double,FullInterlace> * p_field_volume=NULL) const; - * (+) double normL1(const FIELD<double,FullInterlace> * p_field_volume=NULL) const; - * - * (+) FIELD* extract(const SUPPORT *subSupport) const throw (MEDEXCEPTION); - * - * (EMPTY COMMENT, EMPTY IMPLEMENTATION!!!) void init (); - * - * (+) void rmDriver(int index=0); - * (+) int addDriver(driverTypes driverType, - * const string & fileName="Default File Name.med", - * const string & driverFieldName="Default Field Name", - * MED_EN::med_mode_acces access=MED_EN::MED_REMP); - * (+) int addDriver(GENDRIVER & driver); - * - * (+) void allocValue(const int NumberOfComponents); - * (+) void allocValue(const int NumberOfComponents, const int LengthValue); - * (+) void deallocValue(); - * - * (+) inline void read(int index=0); - * (+) inline void read(const GENDRIVER & genDriver); - * (+) inline void write(int index=0, const string & driverName = ""); - * (+) inline void write(const GENDRIVER &); - * (+) inline void writeAppend(int index=0, const string & driverName = ""); - * (+) inline void writeAppend(const GENDRIVER &); - * - * (+) inline MEDMEM_Array_ * getArray() const throw (MEDEXCEPTION); - * (+) inline ArrayGauss * getArrayGauss() const throw (MEDEXCEPTION); - * (+) inline ArrayNoGauss * getArrayNoGauss() const throw (MEDEXCEPTION); - * (+) inline bool getGaussPresence() const throw (MEDEXCEPTION); - * - * (+) inline int getValueLength() const throw (MEDEXCEPTION); - * (+) inline const T* getValue() const throw (MEDEXCEPTION); - * (+) inline const T* getRow(int i) const throw (MEDEXCEPTION); - * (+) inline const T* getColumn(int j) const throw (MEDEXCEPTION); - * (+) inline T getValueIJ(int i,int j) const throw (MEDEXCEPTION); - * (+) inline T getValueIJK(int i,int j,int k) const throw (MEDEXCEPTION); - * (+) bool getValueOnElement(int eltIdInSup,T* retValues) const throw (MEDEXCEPTION); - * - * (+) const int getNumberOfGeometricTypes() const throw (MEDEXCEPTION); - * - * (+) const GAUSS_LOCALIZATION<INTERLACING_TAG> & getGaussLocalization - * (MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION); - * (+) const GAUSS_LOCALIZATION<INTERLACING_TAG> * getGaussLocalizationPtr - * (MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION); - * (+) void setGaussLocalization(MED_EN::medGeometryElement geomElement, - * const GAUSS_LOCALIZATION<INTERLACING_TAG> & gaussloc); - * (+) const int * getNumberOfGaussPoints() const throw (MEDEXCEPTION); - * (+) const int getNumberOfGaussPoints - * (MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION); - * (+) const int getNbGaussI(int i) const throw (MEDEXCEPTION); - * - * (+) const int * getNumberOfElements() const throw (MEDEXCEPTION); - * (+) const MED_EN::medGeometryElement * getGeometricTypes() const throw (MEDEXCEPTION); - * (+) bool isOnAllElements() const throw (MEDEXCEPTION); - * - * (+) inline void setArray(MEDMEM_Array_ *value) throw (MEDEXCEPTION); - * (+) inline void setValue(T* value) throw (MEDEXCEPTION); - * (+) inline void setRow(int i, T* value) throw (MEDEXCEPTION); - * (+) inline void setColumn(int i, T* value) throw (MEDEXCEPTION); - * (+) inline void setValueIJ(int i, int j, T value) throw (MEDEXCEPTION); - * - * (NOT IMPLEMENTED!!!) void getVolume() const throw (MEDEXCEPTION); - * (NOT IMPLEMENTED!!!) void getArea() const throw (MEDEXCEPTION); - * (NOT IMPLEMENTED!!!) void getLength() const throw (MEDEXCEPTION); - * (NOT IMPLEMENTED!!!) void getNormal() const throw (MEDEXCEPTION); - * (NOT IMPLEMENTED!!!) void getBarycenter() const throw (MEDEXCEPTION); - * - * (+) void fillFromAnalytic(myFuncType f) throw (MEDEXCEPTION); - * } - * - * Use code of test_operation_fieldint.cxx - * test_operation_fielddouble.cxx - * test_copie_field_.cxx - * test_copie_fieldT.cxx - */ -void compareField_(const FIELD_ * theField_1, const FIELD_ * theField_2, bool isFIELD, bool isValue) -{ - // name, description, support - CPPUNIT_ASSERT_EQUAL(theField_1->getName(), theField_2->getName()); - CPPUNIT_ASSERT_EQUAL(theField_1->getDescription(), theField_2->getDescription()); - CPPUNIT_ASSERT_EQUAL(theField_1->getSupport(), theField_2->getSupport()); - - // components information - int aNbComps = theField_1->getNumberOfComponents(); - CPPUNIT_ASSERT_EQUAL(aNbComps, theField_2->getNumberOfComponents()); - - for (int i = 1; i <= aNbComps; i++) { - CPPUNIT_ASSERT_EQUAL(theField_1->getComponentName(i), theField_2->getComponentName(i)); - CPPUNIT_ASSERT_EQUAL(theField_1->getComponentDescription(i), theField_2->getComponentDescription(i)); - CPPUNIT_ASSERT_EQUAL(theField_1->getMEDComponentUnit(i), theField_2->getMEDComponentUnit(i)); - } - - // iteration information - CPPUNIT_ASSERT_EQUAL(theField_1->getIterationNumber(), theField_2->getIterationNumber()); - CPPUNIT_ASSERT_EQUAL(theField_1->getOrderNumber(), theField_2->getOrderNumber()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(theField_1->getTime(), theField_2->getTime(), 0.0000001); - - // Value - int nbOfValues = theField_1->getNumberOfValues(); - CPPUNIT_ASSERT_EQUAL(nbOfValues, theField_2->getNumberOfValues()); - - if (isFIELD) { - // Value type and Interlacing type - CPPUNIT_ASSERT_EQUAL(theField_1->getValueType(), theField_2->getValueType()); - CPPUNIT_ASSERT_EQUAL(theField_1->getInterlacingType(), theField_2->getInterlacingType()); - - // Gauss Presence - if (isValue) { - CPPUNIT_ASSERT_EQUAL(theField_1->getGaussPresence(), theField_2->getGaussPresence()); - } - else { - CPPUNIT_ASSERT_THROW(theField_1->getGaussPresence(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField_2->getGaussPresence(), MEDEXCEPTION); - } - } - else { - CPPUNIT_ASSERT_THROW(theField_1->getGaussPresence(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField_2->getGaussPresence(), MEDEXCEPTION); - } -} - -void checkField_(FIELD_ * theField_, const SUPPORT * theSupport, - MED_EN::med_type_champ theValueType, - MED_EN::medModeSwitch theInterlace) -{ - // name - const string aFieldName = "a_name_of_a_field"; - theField_->setName(aFieldName); - CPPUNIT_ASSERT_EQUAL(aFieldName, theField_->getName()); - - // description - const string aFieldDescr = "a_description_of_a_field"; - theField_->setDescription(aFieldDescr); - CPPUNIT_ASSERT_EQUAL(aFieldDescr, theField_->getDescription()); - - // support - theField_->setSupport(theSupport); - CPPUNIT_ASSERT(theField_->getSupport() == theSupport); - - // components information - int aNbComps = 3; - - string aCompsNames[3] = {"Vx", "Vy", "Vz"}; - string aCompsDescs[3] = {"vitesse selon x", "vitesse selon y", "vitesse selon z"}; - string aCompsUnits[3] = {"m.s-1", "m.s-1", "m.s-1"}; - - theField_->setNumberOfComponents(aNbComps); - CPPUNIT_ASSERT_EQUAL(aNbComps, theField_->getNumberOfComponents()); - - theField_->setComponentsNames(aCompsNames); - -#ifdef ENABLE_FAULTS - try { - theField_->setNumberOfComponents(7); - // Segmentation fault here because array of components names is not resized - for (int i = 1; i <= 7; i++) { - theField_->setComponentName(i, "AnyComponent"); - } - } - catch (MEDEXCEPTION& ex) { - // Ok, it is good to have MEDEXCEPTION here - } - catch (...) { - CPPUNIT_FAIL("Unknown exception cought"); - } - // restore components names - theField_->setNumberOfComponents(aNbComps); - theField_->setComponentsNames(aCompsNames); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("FIELD_::_componentsNames bad management"); -#endif - - theField_->setComponentsDescriptions(aCompsDescs); - theField_->setMEDComponentsUnits(aCompsUnits); - - const string * aCompsNamesBack = theField_->getComponentsNames(); - const string * aCompsDescsBack = theField_->getComponentsDescriptions(); - const string * aCompsUnitsBack = theField_->getMEDComponentsUnits(); - for (int i = 1; i <= aNbComps; i++) { - CPPUNIT_ASSERT_EQUAL(aCompsNamesBack[i-1], theField_->getComponentName(i)); - CPPUNIT_ASSERT_EQUAL(aCompsNamesBack[i-1], aCompsNames[i-1]); - - CPPUNIT_ASSERT_EQUAL(aCompsDescsBack[i-1], theField_->getComponentDescription(i)); - CPPUNIT_ASSERT_EQUAL(aCompsDescsBack[i-1], aCompsDescs[i-1]); - - CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack[i-1], theField_->getMEDComponentUnit(i)); - CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack[i-1], aCompsUnits[i-1]); - } - - const string aCompName2 ("Name of second component"); - const string aCompDesc2 ("Description of second component"); - const string aCompUnit2 ("Unit of second MED component"); - - theField_->setComponentName(2, aCompName2); - theField_->setComponentDescription(2, aCompDesc2); - theField_->setMEDComponentUnit(2, aCompUnit2); - - const string * aCompsNamesBack2 = theField_->getComponentsNames(); - const string * aCompsDescsBack2 = theField_->getComponentsDescriptions(); - const string * aCompsUnitsBack2 = theField_->getMEDComponentsUnits(); - - CPPUNIT_ASSERT_EQUAL(aCompsNamesBack2[1], theField_->getComponentName(2)); - CPPUNIT_ASSERT_EQUAL(aCompsNamesBack2[1], aCompName2); - - CPPUNIT_ASSERT_EQUAL(aCompsDescsBack2[1], theField_->getComponentDescription(2)); - CPPUNIT_ASSERT_EQUAL(aCompsDescsBack2[1], aCompDesc2); - - CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack2[1], theField_->getMEDComponentUnit(2)); - CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack2[1], aCompUnit2); - -#ifdef ENABLE_FAULTS - // (BUG) No index checking - CPPUNIT_ASSERT_THROW(theField_->setComponentName(0, "str"), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField_->setComponentName(aNbComps + 1, "str"), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField_->setComponentDescription(0, "str"), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField_->setComponentDescription(aNbComps + 1, "str"), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField_->setMEDComponentUnit(0, "str"), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField_->setMEDComponentUnit(aNbComps + 1, "str"), MEDEXCEPTION); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("FIELD::setComponentXXX() does not check component index"); -#endif - - // iteration information - int anIterNumber = 10; // set value to MED_NOPDT if undefined (default) - theField_->setIterationNumber(anIterNumber); - CPPUNIT_ASSERT_EQUAL(anIterNumber, theField_->getIterationNumber()); - - int anOrderNumber = 1; // set value to MED_NONOR if undefined (default) - theField_->setOrderNumber(anOrderNumber); - CPPUNIT_ASSERT_EQUAL(anOrderNumber, theField_->getOrderNumber()); - - double aTime = 3.435678; // in second - theField_->setTime(aTime); - CPPUNIT_ASSERT_DOUBLES_EQUAL(aTime, theField_->getTime(), 0.0000001); - - // Value - int nbOfValues = 10; - // dangerous method, because it does not reallocate values array - theField_->setNumberOfValues(nbOfValues); - CPPUNIT_ASSERT_EQUAL(nbOfValues, theField_->getNumberOfValues()); - - // Value type and Interlacing type - CPPUNIT_ASSERT_EQUAL(theValueType, theField_->getValueType()); - CPPUNIT_ASSERT_EQUAL(theInterlace, theField_->getInterlacingType()); -} - -template<class T, class INTERLACING_TAG> -void compareField(const FIELD<T, INTERLACING_TAG> * theField_1, - const FIELD<T, INTERLACING_TAG> * theField_2, bool isValue) -{ - // compare FIELD_ part - compareField_(theField_1, theField_2, /*isFIELD = */true, isValue); - - // compare FIELD part - // TO DO -} - -template<class T, class INTERLACING_TAG> -void checkField (FIELD<T, INTERLACING_TAG> * theField, const SUPPORT * theSupport) -{ - // check FIELD_ part - MED_EN::med_type_champ aValueType = SET_VALUE_TYPE<T>::_valueType; - MED_EN::medModeSwitch anInterlace = SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType; - checkField_(theField, theSupport, aValueType, anInterlace); - - // check FIELD part - - // filling by support charackteristics (NOT IMPLEMENTED METHODS!!!): - // value type must be MED_REEL64 (i.e. a FIELD<double>) for these methods, - // nb. of components must be equal 1 (for Volume, Area, Length) or - // space dimension (for Normal, Barycenter, ) - { - MESH* aMesh = theSupport->getMesh(); - int spaceDim = 3; - if (aMesh) spaceDim = aMesh->getSpaceDimension(); - theField->deallocValue(); - theField->allocValue(/*NumberOfComponents = */spaceDim + 1); - - CPPUNIT_ASSERT_THROW(theField->getVolume(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField->getArea(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField->getLength(), MEDEXCEPTION); - if (aMesh) { - CPPUNIT_ASSERT_THROW(theField->getNormal(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField->getBarycenter(), MEDEXCEPTION); - } - - theField->deallocValue(); - theField->allocValue(/*NumberOfComponents = */1); - if (aValueType == MED_EN::MED_REEL64) { - CPPUNIT_ASSERT_NO_THROW(theField->getVolume()); - CPPUNIT_ASSERT_NO_THROW(theField->getArea()); - CPPUNIT_ASSERT_NO_THROW(theField->getLength()); - } - else { - CPPUNIT_ASSERT_THROW(theField->getVolume(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField->getArea(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField->getLength(), MEDEXCEPTION); - } - - if (aMesh) { - theField->deallocValue(); - theField->allocValue(/*NumberOfComponents = */spaceDim); - if (aValueType == MED_EN::MED_REEL64) { - CPPUNIT_ASSERT_NO_THROW(theField->getNormal()); - CPPUNIT_ASSERT_NO_THROW(theField->getBarycenter()); - } - else { - CPPUNIT_ASSERT_THROW(theField->getNormal(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField->getBarycenter(), MEDEXCEPTION); - } - } - } - - // values - theField->deallocValue(); - theField->allocValue(/*NumberOfComponents = */2); - int nbElemSupport = theSupport->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS); - CPPUNIT_ASSERT_EQUAL(nbElemSupport, theField->getNumberOfValues()); - -#ifdef ENABLE_FAULTS - // (BUG) FIELD::deallocValue() does not nullify _value pointer, - // that is why there can be failures in other methods - // (even if simply call deallocValue() two times) - theField->deallocValue(); - theField->getGaussPresence(); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("FIELD::deallocValue() does not nullify _value pointer"); -#endif - - // copy constructor - FIELD<T, INTERLACING_TAG> aField_copy1 (*theField); - //compareField(theField, &aField_copy1, /*isValue = */false); - compareField(theField, &aField_copy1, /*isValue = */true); - - // operator= -#ifdef ENABLE_FAULTS - // (BUG) This fails (Segmentation fault) if not set: - // _componentsNames or _componentsDescriptions, or _componentsUnits, or _MEDComponentsUnits - FIELD<T, INTERLACING_TAG> aField_copy2; - aField_copy2 = *theField; - //compareField(theField, &aField_copy2, /*isValue = */false); - compareField(theField, &aField_copy2, /*isValue = */true); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("FIELD_::operator=() fails if _componentsUnits is not set"); -#endif -} - -template<class T> -FIELD<T> * createFieldOnGroup(MESH* theMesh, const GROUP* theGroup, - const string theName, const string theDescr) -{ - FIELD<T> * aFieldOnGroup = new FIELD<T> (theGroup, /*NumberOfComponents = */2); - - aFieldOnGroup->setName(theName); - aFieldOnGroup->setDescription(theDescr); - - string aCompsNames[2] = {"Pos", "Neg"}; - string aCompsDescs[2] = {"+", "-"}; - string aCompsUnits[2] = {"unit1", "unit2"}; - - aFieldOnGroup->setComponentsNames(aCompsNames); - aFieldOnGroup->setComponentsDescriptions(aCompsDescs); - aFieldOnGroup->setMEDComponentsUnits(aCompsUnits); - - return aFieldOnGroup; -} - -double plus13 (double val) -{ - return val + 13; -} - -// function to calculate field values from coordinates of an element -// typedef void (*myFuncType)(const double * temp, T* output); -// size of temp array = space dim = 3 -// size of output array = nb. comps = 2 -void proj2d (const double * temp, double* output) -{ - // dimetric projection with coefficients: - // 1.0 along Oy and Oz, 0.5 along Ox - // - // ^ z (y_) - // | - // | - // .----> y (x_) - // / - // L x - // - // x_ = y - x * sqrt(2.) / 4. - // y_ = z - x * sqrt(2.) / 4. - - double dx = temp[0] * std::sqrt(2.) / 4.; - output[0] = temp[1] - dx; - output[1] = temp[2] - dx; -} - -void testDrivers() -{ - string data_dir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - if (tmp_dir == "") - tmp_dir = "/tmp"; - - string filename_rd = data_dir + "/MedFiles/pointe.med"; - string filename_wr = tmp_dir + "/myMedFieldfile.med"; - string filename_support_wr = tmp_dir + "/myMedSupportFiledfile.med"; - string filename22_rd = data_dir + "/MedFiles/pointe_import22.med"; - string filenamevtk_wr = tmp_dir + "/myMedFieldfile22.vtk"; - string cp_file = "cp " + filename_rd + " " + filename_wr; - - string fieldname_celldouble_rd = "fieldcelldouble"; - string fieldname_celldouble_wr = fieldname_celldouble_rd + "_cpy"; - string fieldname_nodeint_rd = "fieldnodeint"; - string fieldname_nodeint_wr = fieldname_nodeint_rd + "_cpy"; - string fieldname_nodeint_wr1 = fieldname_nodeint_rd + "_cpy1"; - string meshname = "maa1"; - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filename_wr); - aRemover.Register(filenamevtk_wr); - aRemover.Register(filename_support_wr); - - //Copy file - system(cp_file.c_str()); - - FIELD<int> aInvalidField; - //must throw becase only VTK_DRIVER or MED_DRIVER may be specified as driverType for FIELD - CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(NO_DRIVER, filename_rd, fieldname_nodeint_rd), - MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(GIBI_DRIVER, filename_rd, fieldname_nodeint_rd), - MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(PORFLOW_DRIVER, filename_rd, fieldname_nodeint_rd), - MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(ASCII_DRIVER, filename_rd, fieldname_nodeint_rd), - MEDEXCEPTION); - - ////////////////// - //TestRead Part// - ////////////////// - FIELD<double> *aField_1 = NULL; - CPPUNIT_ASSERT_NO_THROW(aField_1 = new FIELD<double>(MED_DRIVER, filename_rd, fieldname_celldouble_rd)); - - //Test read(int index) method - int IdDriver_rd = aField_1->addDriver(MED_DRIVER,filename_rd,fieldname_celldouble_rd); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Cannot open file, but file exist - CPPUNIT_ASSERT_NO_THROW(aField_1->read(IdDriver_rd)); -#endif - - //Test read(GENDRIVER & genDriver) method - //Creation a Driver - MED_FIELD_RDONLY_DRIVER21<int> *aMedRdFieldDriver21_1 = - new MED_FIELD_RDONLY_DRIVER21<int>(); - //Creation a Field - FIELD<int> *aField_2 = new FIELD<int>(); - aField_2->setName(fieldname_nodeint_rd); - aField_2->addDriver(*aMedRdFieldDriver21_1); - aField_2->read(*aMedRdFieldDriver21_1); - - /////////////////// - //Test Write Part// - /////////////////// - int IdDriver; - MESH *aMesh = new MESH(MED_DRIVER,filename_rd,meshname); - SUPPORT *aSupport = new SUPPORT(aMesh, "aSupport",MED_CELL); - FIELD<int> *aFieldSupport; -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_NO_THROW(aFieldSupport = - new FIELD<int>(aSupport, MED_DRIVER,filename_support_wr,fieldname_nodeint_rd)); - //(BUG) Can not open file - MED_FIELD_WRONLY_DRIVER21<int> * aFieldWrDriver21 = - new MED_FIELD_WRONLY_DRIVER21<int>(filename_support_wr,aFieldSupport); - aFieldWrDriver21->setFieldName(aFieldSupport->getName() + "_copy"); - CPPUNIT_ASSERT_NO_THROW(IdDriver= aFieldSupport->addDriver(*aFieldWrDriver21)); - CPPUNIT_ASSERT_NO_THROW(aFieldSupport->write(IdDriver)); - delete aFieldSupport; - delete aFieldWrDriver21; -#endif - - //Create fileds - FIELD<double> * aField_3 = new FIELD<double>(); - MED_FIELD_RDONLY_DRIVER21<double> *aMedRdFieldDriver21_2 = - new MED_FIELD_RDONLY_DRIVER21<double>(filename_rd, aField_3); - aMedRdFieldDriver21_2->open(); - aMedRdFieldDriver21_2->setFieldName(fieldname_celldouble_rd); - aMedRdFieldDriver21_2->read(); - aMedRdFieldDriver21_2->close(); - - //Test write(int index) method - //Add drivers to FIELDs - int IdDriver1 = -1; - try - { - IdDriver1 = aField_3->addDriver(MED_DRIVER,filename_wr,fieldname_celldouble_wr); - } - catch(MEDEXCEPTION &e) - { - e.what(); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - //Trying call write(int index) method with incorrect index -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_THROW(aField_3->write(IdDriver1+1, fieldname_celldouble_wr),MEDEXCEPTION); - // => Segmentation fault -#endif - - //Write field to file -#ifdef ENABLE_FAULTS - try - { - aField_3->write(IdDriver1, fieldname_celldouble_wr); - // => Segmentation fault - } - catch(MEDEXCEPTION &e) - { - e.what(); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } -#endif - - CPPUNIT_ASSERT_NO_THROW(aField_3->rmDriver(IdDriver1)); - - //Test write(const GENDRIVER &); - //Create a driver - MED_FIELD_WRONLY_DRIVER21<int> *aMedWrFieldDriver21 = - new MED_FIELD_WRONLY_DRIVER21<int>(); - aMedWrFieldDriver21->setFileName(filename_wr); - aField_2->setName(fieldname_nodeint_wr1); - //Add driver to a field - aField_2->addDriver(*aMedWrFieldDriver21); - - try - { - aField_2->write(*aMedWrFieldDriver21); - } - catch(MEDEXCEPTION &e) - { - e.what(); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test writeAppend(int index) method - //Create a vtk file - MESH * aMesh_1 = new MESH(); - MED_MESH_RDONLY_DRIVER22 *aMedMeshRdDriver22 = new MED_MESH_RDONLY_DRIVER22(filename22_rd, aMesh_1); - aMedMeshRdDriver22->open(); - aMedMeshRdDriver22->setMeshName(meshname); - aMedMeshRdDriver22->read(); - aMedMeshRdDriver22->close(); - VTK_MESH_DRIVER *aVtkDriver = new VTK_MESH_DRIVER(filenamevtk_wr, aMesh_1); - aVtkDriver->open(); - aVtkDriver->write(); - aVtkDriver->close(); - - //Create a field - FIELD<int> * aField_4 = new FIELD<int>(); - MED_FIELD_RDONLY_DRIVER22<int> *aMedRdFieldDriver22 = - new MED_FIELD_RDONLY_DRIVER22<int>(filename22_rd, aField_2); - aMedRdFieldDriver22->open(); - aMedRdFieldDriver22->setFieldName(fieldname_nodeint_rd); - aMedRdFieldDriver22->read(); - aMedRdFieldDriver22->close(); - - //Add Driver to a field - int IdDriver2; - try - { - IdDriver2 = aField_4->addDriver(VTK_DRIVER, filenamevtk_wr ,fieldname_nodeint_wr); - } - catch(MEDEXCEPTION &e) - { - e.what(); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } -#ifdef ENABLE_FAULTS - //Trying call writeAppend() method with incorrect index - CPPUNIT_ASSERT_THROW(aField_4->writeAppend(IdDriver2+1,fieldname_nodeint_wr),MEDEXCEPTION); - // => Segmentation fault -#endif - -#ifdef ENABLE_FAULTS - // (BUG) => Segmentation fault - CPPUNIT_ASSERT_NO_THROW(aField_4->writeAppend(IdDriver2, fieldname_nodeint_wr)); -#endif - - //Test writeAppend(const GENDRIVER &) method - aField_4->setName(fieldname_nodeint_wr1); - - //Add driver to a field -#ifdef ENABLE_FAULTS - //Create a driver - VTK_FIELD_DRIVER<int> *aVtkFieldDriver = new VTK_FIELD_DRIVER<int>(filenamevtk_wr, aField_4); - CPPUNIT_ASSERT_NO_THROW(aField_4->addDriver(*aVtkFieldDriver)); - //(BUG) => Segmentation fault after addDriver(const GENDRIVER &) - CPPUNIT_ASSERT_NO_THROW(aField_4->writeAppend(*aVtkFieldDriver)); -#endif - - - //Delete objects - delete aField_1; - delete aMedRdFieldDriver21_1; - delete aField_2; - delete aField_3; - delete aMedRdFieldDriver21_2; - delete aField_4; - delete aMedMeshRdDriver22; - delete aMedWrFieldDriver21; - delete aVtkDriver; - delete aMesh; - delete aMesh_1; - delete aMedRdFieldDriver22; - delete aSupport; -} - -void MEDMEMTest::testField() -{ - SUPPORT anEmptySupport; - //////////////////// - // TEST 1: FIELD_ // - //////////////////// - FIELD_ aField_; - - // check set/get methods - MED_EN::med_type_champ aValueType = MED_EN::MED_UNDEFINED_TYPE; - MED_EN::medModeSwitch anInterlace = MED_EN::MED_UNDEFINED_INTERLACE; - checkField_(&aField_, &anEmptySupport, aValueType, anInterlace); - - // copy constructor - // This fails (Segmentation fault) if not set: - // _componentsNames or _componentsDescriptions, or _MEDComponentsUnits - FIELD_ aField_copy1 (aField_); - compareField_(&aField_, &aField_copy1, /*isFIELD = */false, /*isValue = */false); - - // operator= -#ifdef ENABLE_FAULTS - // (BUG) This fails (Segmentation fault) if not set: - // _componentsNames or _componentsDescriptions, or _componentsUnits, or _MEDComponentsUnits - // (BUG) Code duplication with copyGlobalInfo(), called from copy constructor - FIELD_ aField_copy2; - aField_copy2 = aField_; - compareField_(&aField_, &aField_copy2, /*isFIELD = */false, /*isValue = */false); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("FIELD_::operator=() fails if _componentsUnits is not set"); -#endif - - // construction on a given support - { - anEmptySupport.setTotalNumberOfElements(11); - // CASE1: - FIELD_ aField_case1 (&anEmptySupport, 10); - // CASE2: - FIELD_ aField_case2; - aField_case2.setSupport(&anEmptySupport); - aField_case2.setNumberOfComponents(10); - -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_EQUAL_MESSAGE("No correspondance between CASE1 and CASE2", - aField_case1.getNumberOfValues(), - aField_case2.getNumberOfValues()); -#endif - } - - //////////////////////// - // TEST 2: FIELD<int> // - //////////////////////// - FIELD<int> aFieldInt; - checkField(&aFieldInt, &anEmptySupport); - - //////////////////////////////////////// - // TEST 3: FIELD<double, NoInterlace> // - //////////////////////////////////////// - MESH * aMesh = MEDMEMTest_createTestMesh(); - const GROUP* aGroup = aMesh->getGroup(MED_EN::MED_FACE, 1); - - FIELD<double, NoInterlace> aFieldDouble; - checkField(&aFieldDouble, aGroup); - - ////////////////////////////////////////// - // TEST 4: FIELD<double, FullInterlace> // - ////////////////////////////////////////// - FIELD<double> * aFieldOnGroup1 = createFieldOnGroup<double>(aMesh, aGroup, "Linear", "N"); - FIELD<double> * aFieldOnGroup2 = createFieldOnGroup<double>(aMesh, aGroup, "Quadratic", "N**2"); - - int nbVals = aFieldOnGroup1->getNumberOfValues(); - CPPUNIT_ASSERT(nbVals); - - // numbers of elements in group, - // they are needed in method FIELD::setValueIJ() - const int *anElems = aGroup->getnumber()->getValue(); - double eucl1 = 0., eucl2 = 0.; - - for (int i = 1; i <= nbVals; i++) { - aFieldOnGroup1->setValueIJ(anElems[i-1], 1, (double)i); - aFieldOnGroup1->setValueIJ(anElems[i-1], 2, (double)(-i)); - - aFieldOnGroup2->setValueIJ(anElems[i-1], 1, (double)i*i); - aFieldOnGroup2->setValueIJ(anElems[i-1], 2, (double)(-i*i)); - - eucl1 += 2. * i * i; - eucl2 += 2. * i * i * i * i; - } - - // out of bound (inexisting 33-th component of last element) - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->setValueIJ(anElems[nbVals-1], 33, 10.), MEDEXCEPTION); - - // normMax - CPPUNIT_ASSERT_DOUBLES_EQUAL(nbVals, aFieldOnGroup1->normMax(), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(nbVals*nbVals, aFieldOnGroup2->normMax(), 0.000001); - - // norm2 - CPPUNIT_ASSERT_DOUBLES_EQUAL(std::sqrt(eucl1), aFieldOnGroup1->norm2(), 0.000001); // 10.4881 - CPPUNIT_ASSERT_DOUBLES_EQUAL(std::sqrt(eucl2), aFieldOnGroup2->norm2(), 0.000001); // 44.2493 - - // check getXXX methods - CPPUNIT_ASSERT(!aFieldOnGroup1->getGaussPresence()); - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getArrayGauss(), MEDEXCEPTION); - MEDMEM_ArrayInterface<double, FullInterlace,NoGauss>::Array * anArrayNoGauss = - aFieldOnGroup1->getArrayNoGauss(); - - MEDMEM_Array_ * aMEDMEM_Array_ = aFieldOnGroup1->getArray(); - MEDMEM_ArrayInterface<double, FullInterlace,NoGauss>::Array * aMEDMEM_Array_conv = - static_cast<MEDMEM_ArrayInterface<double, FullInterlace,NoGauss>::Array *>(aMEDMEM_Array_); - - const double * aValues = aFieldOnGroup1->getValue(); - - // out of range - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getColumn(3), MEDEXCEPTION); - // cannot get column in FullInterlace - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getColumn(1), MEDEXCEPTION); - - for (int i = 1; i <= nbVals; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , aFieldOnGroup1->getValueIJK(anElems[i-1], 1, 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), aFieldOnGroup1->getValueIJK(anElems[i-1], 2, 1), 0.000001); - - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , aValues[(i-1)*2 + 0], 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), aValues[(i-1)*2 + 1], 0.000001); - - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , anArrayNoGauss->getIJ(i, 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), anArrayNoGauss->getIJ(i, 2), 0.000001); - - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , aMEDMEM_Array_conv->getIJ(i, 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), aMEDMEM_Array_conv->getIJ(i, 2), 0.000001); - - const double* row_i = aFieldOnGroup1->getRow(anElems[i-1]); - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , row_i[0], 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), row_i[1], 0.000001); - - double vals_i [2]; - aFieldOnGroup1->getValueOnElement(anElems[i-1], vals_i); - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , vals_i[0], 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), vals_i[1], 0.000001); - } - - // modify all values of aFieldOnGroup2 by formula a*x + b (a = 2, b = 3) - aFieldOnGroup2->applyLin(2., 3.); - for (int i = 1; i <= nbVals; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(3. + 2.*i*i, aFieldOnGroup2->getValueIJ(anElems[i-1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3. - 2.*i*i, aFieldOnGroup2->getValueIJ(anElems[i-1], 2), 0.000001); - } - - // apply function plus13() to aFieldOnGroup1 - aFieldOnGroup1->applyFunc<plus13>(); - for (int i = 1; i <= nbVals; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); - } - - // scalarProduct - FIELD<double, FullInterlace> * aScalarProduct = - FIELD<double, FullInterlace>::scalarProduct(*aFieldOnGroup1, *aFieldOnGroup2, /*deepCheck = */true); - CPPUNIT_ASSERT_EQUAL(nbVals, aScalarProduct->getNumberOfValues()); - CPPUNIT_ASSERT_EQUAL(1, aScalarProduct->getNumberOfComponents()); - for (int i = 1; i <= nbVals; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(78. + 4.*i*i*i, //(3. + 2.*i*i)*(13 + i) + (3. - 2.*i*i)*(13 - i) - aScalarProduct->getValueIJ(anElems[i-1], 1), 0.000001); - } - - // fillFromAnalytic - aFieldOnGroup2->fillFromAnalytic(proj2d); - - double bary [3]; - double outp [2]; - const SUPPORT * aSupp = aFieldOnGroup2->getSupport(); - FIELD<double,FullInterlace> * barycenter = aMesh->getBarycenter(aSupp); - for (int i = 1; i <= nbVals; i++) { - bary[0] = barycenter->getValueIJ(anElems[i-1], 1); - bary[1] = barycenter->getValueIJ(anElems[i-1], 2); - bary[2] = barycenter->getValueIJ(anElems[i-1], 3); - - proj2d(bary, outp); - - //cout << "barycenter (" << bary[0] << ", " << bary[1] << ", " << bary[2] << ")" << endl; - //cout << "proj2d (" << outp[0] << ", " << outp[1] << ")" << endl; - - //bary (-0.666667, 0.666667, 0.666667) -> outp ( 0.902369, 0.902369) - //bary ( 0.666667, -0.666667, 0.666667) -> outp (-0.902369, 0.430964) - //bary ( 0. , 0. , 2. ) -> outp ( 0. , 2. ) - //bary ( 0. , 0. , 3. ) -> outp ( 0. , 3. ) - //bary (-1. , 0. , 2.5 ) -> outp ( 0.353553, 2.85355 ) - -#ifdef ENABLE_FORCED_FAILURES - // (BUG) in FIELD::fillFromAnalytic() in case of support, different from nodes: - // barycenterField in FullInterlace, but values extracted like from NoInterlace - CPPUNIT_ASSERT_DOUBLES_EQUAL(outp[0], aFieldOnGroup2->getValueIJ(anElems[i-1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(outp[1], aFieldOnGroup2->getValueIJ(anElems[i-1], 2), 0.000001); -#endif - - // currently it gives values, that are wrong: - //aFieldOnGroup2 row1 ( 0.902369, 0.235702) - //aFieldOnGroup2 row2 (-0.235702, 2.7643 ) - //aFieldOnGroup2 row3 (-0.235702, -1.2357 ) - //aFieldOnGroup2 row4 ( 1.7643 , -0.235702) - //aFieldOnGroup2 row5 ( 0.235702, 2.7357 ) - } - - // info about support (Group1) - CPPUNIT_ASSERT(!aFieldOnGroup1->isOnAllElements()); // because we build Group1 so - int nbTypes = aFieldOnGroup1->getNumberOfGeometricTypes(); - //CPPUNIT_ASSERT(nbTypes); - CPPUNIT_ASSERT_EQUAL(2, nbTypes); - const int * nbElemsInEachType = aFieldOnGroup1->getNumberOfElements(); - const MED_EN::medGeometryElement * aGeomTypes = aFieldOnGroup1->getGeometricTypes(); - - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_TRIA3, aGeomTypes[0]); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_QUAD4, aGeomTypes[1]); - - // GAUSS - - // now we have no gauss localization in aFieldOnGroup1 - CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA3)); - CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_QUAD4)); - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA6), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(), MEDEXCEPTION); - - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalization(MED_EN::MED_TRIA3), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_TRIA3), MEDEXCEPTION); - - CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNbGaussI(anElems[0])); - - // set a gauss localization into aFieldOnGroup1 - double cooRef[6] = {1.,1., 2.,4., 3.,9.}; // xy xy xy - double cooGauss[10] = {7.,7., 6.,6., 5.,5., 4.,3., 2.,1.}; // x1,y1 x2,y2 x3,y3 x4,y4 x5,y5 - double wg[5] = {1., 2., 3., 4., 5.}; - GAUSS_LOCALIZATION<> gl1 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef, cooGauss, wg); - - aFieldOnGroup1->setGaussLocalization(MED_EN::MED_TRIA3, gl1); - - // now we have a gauss localization for MED_TRIA3 type - CPPUNIT_ASSERT_EQUAL(5, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA3)); - CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_QUAD4)); - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA6), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(), MEDEXCEPTION); - - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalization(MED_EN::MED_QUAD4), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_QUAD4), MEDEXCEPTION); - - GAUSS_LOCALIZATION<> gl1Back = aFieldOnGroup1->getGaussLocalization(MED_EN::MED_TRIA3); - const GAUSS_LOCALIZATION<> * gl1BackPtr = aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_TRIA3); - - CPPUNIT_ASSERT(gl1 == gl1Back); - CPPUNIT_ASSERT(gl1 == *gl1BackPtr); - - CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNbGaussI(anElems[0])); - - // sub-support of Group1 on one (first) geometric type - SUPPORT * aSubSupport1 = new SUPPORT(aMesh, "Sub-Support 1 of Group1", MED_EN::MED_FACE); - aSubSupport1->setAll(false); - - int nbTypes1 = 1; - int nbElemsInEachType1[1]; - nbElemsInEachType1[0] = nbElemsInEachType[0]; - int nbElems1 = nbElemsInEachType1[0]; - MED_EN::medGeometryElement aGeomTypes1[1]; - aGeomTypes1[0] = aGeomTypes[0]; - int * anElems1 = new int[nbElems1]; - for (int i = 0; i < nbElems1; i++) { - anElems1[i] = anElems[i]; - } - - aSubSupport1->setpartial("Support for sub-field 1 on one type of elements", - nbTypes1, nbElems1, aGeomTypes1, nbElemsInEachType1, anElems1); - - //cout << "aSubSupport1:" << endl; - //cout << *aSubSupport1 << endl; - - // extract sub-field on aSubSupport1 - FIELD<double, FullInterlace> * aSubField1 = aFieldOnGroup1->extract(aSubSupport1); - CPPUNIT_ASSERT_EQUAL(nbElems1 * /*NumberOfComponents = */2, aSubField1->getValueLength()); - - // aSubField1: - // elt\comp | 1 | 2 - //-------------------- - // 1 | 14 | 12 - // 2 | 15 | 11 - - // check normL2() and normL1() - FIELD<double>* anAreaField = aMesh->getArea(aSubSupport1); - double area1 = anAreaField->getValueIJ(anElems1[0], 1); - double area2 = anAreaField->getValueIJ(anElems1[1], 1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.44949, area1, 0.00001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.44949, area2, 0.00001); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(210.5, aSubField1->normL2(1), 0.00001); // (14*14 + 15*15)/2 -#ifdef ENABLE_FORCED_FAILURES - // (BUG) FIELD::normL2(int component, const FIELD * p_field_volume): - // component is not taken into account - CPPUNIT_ASSERT_DOUBLES_EQUAL(132.5, aSubField1->normL2(2), 0.00001); // (12*12 + 11*11)/2 -#endif - CPPUNIT_ASSERT_DOUBLES_EQUAL(343.0, aSubField1->normL2() , 0.00001); // 210.5 + 132.5 - - CPPUNIT_ASSERT_DOUBLES_EQUAL(14.5, aSubField1->normL1(1), 0.00001); // (14 + 15)/2 - CPPUNIT_ASSERT_DOUBLES_EQUAL(11.5, aSubField1->normL1(2), 0.00001); // (12 + 11)/2 - CPPUNIT_ASSERT_DOUBLES_EQUAL(26.0, aSubField1->normL1() , 0.00001); // 14.5 + 11.5 - - double aNewArea [2] = {1., 0.}; // only first element will be taken into account - anAreaField->setValue(aNewArea); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(196.0, aSubField1->normL2(1, anAreaField), 0.00001); // 14*14/1 -#ifdef ENABLE_FORCED_FAILURES - // (BUG) FIELD::normL2(int component, const FIELD * p_field_volume): - // component is not taken into account - CPPUNIT_ASSERT_DOUBLES_EQUAL(144.0, aSubField1->normL2(2, anAreaField), 0.00001); // 12*12/1 -#endif - CPPUNIT_ASSERT_DOUBLES_EQUAL(340.0, aSubField1->normL2(anAreaField) , 0.00001); // 196 + 144 - - CPPUNIT_ASSERT_DOUBLES_EQUAL(14.0, aSubField1->normL1(1, anAreaField), 0.00001); // 14/1 - CPPUNIT_ASSERT_DOUBLES_EQUAL(12.0, aSubField1->normL1(2, anAreaField), 0.00001); // 12/1 - CPPUNIT_ASSERT_DOUBLES_EQUAL(26.0, aSubField1->normL1(anAreaField) , 0.00001); // 14 + 12 - - // applyPow - aSubField1->applyPow(2.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(196., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); // 14*14 - CPPUNIT_ASSERT_DOUBLES_EQUAL(144., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); // 12*12 - CPPUNIT_ASSERT_DOUBLES_EQUAL(225., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); // 15*15 - CPPUNIT_ASSERT_DOUBLES_EQUAL(121., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); // 11*11 - - // setArray (NoGauss) - MEDMEM_ArrayInterface<double,FullInterlace,NoGauss>::Array * aNewArrayNoGauss = - new MEDMEM_ArrayInterface<double,FullInterlace,NoGauss>::Array(/*dim*/2, /*nbelem*/2); - aNewArrayNoGauss->setIJ(1, 1, 4.); - aNewArrayNoGauss->setIJ(1, 2, 2.); - aNewArrayNoGauss->setIJ(2, 1, 5.); - aNewArrayNoGauss->setIJ(2, 2, 1.); - aSubField1->setArray(aNewArrayNoGauss); - // no need to delete aNewArrayNoGauss, because it will be deleted - // in destructor or in deallocValue() method of aSubField1 - - CPPUNIT_ASSERT_DOUBLES_EQUAL(4., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); - - // setRow - double row[2] = {-1., -3.}; - aSubField1->setRow(anElems1[0], row); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-3., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 5., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); - // out of range - CPPUNIT_ASSERT_THROW(aSubField1->setRow(3, row), MEDEXCEPTION); - - // setColumn - double col[2] = {-7., -9.}; - aSubField1->setColumn(1, col); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-7., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-3., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) in MEDMEM_Array::setColumn() - CPPUNIT_ASSERT_DOUBLES_EQUAL(-9., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); -#endif - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); - // out of range - CPPUNIT_ASSERT_THROW(aSubField1->setColumn(3, col), MEDEXCEPTION); - - // setArray (Gauss) - { - int nbelgeoc[2] = {1, 3}; // 3 - 1 = two elements for the first (and the only) type - int nbgaussgeo[2] = {-1, 1}; // one gauss point per each element - MEDMEM_ArrayInterface<double,FullInterlace,Gauss>::Array * aNewArrayGauss = - new MEDMEM_ArrayInterface<double,FullInterlace,Gauss>::Array - (/*dim*/2, /*nbelem*/2, /*nbtypegeo*/1, /*nbelgeoc*/nbelgeoc, /*nbgaussgeo*/nbgaussgeo); - -#ifdef ENABLE_FAULTS - aNewArrayGauss->setIJ(1, 1, -4.); - aNewArrayGauss->setIJ(1, 2, -2.); - aNewArrayGauss->setIJ(2, 1, -5.); - aNewArrayGauss->setIJ(2, 2, -1.); -#endif -#ifdef ENABLE_FORCED_FAILURES - // ? (BUG) in FullInterlaceGaussPolicy::getIndex(int i,int j) - // FullInterlaceGaussPolicy::getIndex(2,2) returns 4!!! - CPPUNIT_FAIL("? Bug in FullInterlaceGaussPolicy::getIndex(int i,int j) ?"); -#endif - - aNewArrayGauss->setIJK(1, 1, 1, -4.); - aNewArrayGauss->setIJK(1, 2, 1, -2.); - aNewArrayGauss->setIJK(2, 1, 1, -5.); - aNewArrayGauss->setIJK(2, 2, 1, -1.); - - aSubField1->setArray(aNewArrayGauss); - // no need to delete aNewArrayGauss, because it will be deleted - // in destructor or in deallocValue() method of aSubField1 - -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_DOUBLES_EQUAL(-4., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-2., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-5., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); -#endif -#ifdef ENABLE_FORCED_FAILURES - // ? (BUG) in FullInterlaceGaussPolicy::getIndex(int i,int j) - // Must be : return _G[i-1]-1 + (j-1); - // Instead of: return _G[i-1]-1 + (j-1)*_dim; - CPPUNIT_FAIL("? Bug in FullInterlaceGaussPolicy::getIndex(int i,int j) ?"); -#endif - - CPPUNIT_ASSERT_DOUBLES_EQUAL(-4., aSubField1->getValueIJK(anElems1[0], 1, 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-2., aSubField1->getValueIJK(anElems1[0], 2, 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-5., aSubField1->getValueIJK(anElems1[1], 1, 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., aSubField1->getValueIJK(anElems1[1], 2, 1), 0.000001); - } - - // alloc/dealloc; compatibility of new size with support - try { - aSubField1->deallocValue(); - aSubField1->allocValue(/*NumberOfComponents*/2, /*LengthValue*/5); -#ifdef ENABLE_FAULTS - // (BUG) No compatibility between Support and allocated value - aSubField1->normL1(); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("Error: no compatibility between Support and allocated value"); -#endif - } - catch (MEDEXCEPTION & ex) { - // normal behaviour - } - catch (...) { - CPPUNIT_FAIL("Error: no compatibility between Support and allocated value"); - } - - // check that aFieldOnGroup1 is not changed after aSubField1 modifications - for (int i = 1; i <= nbVals; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); - } - - // reset aFieldOnGroup2 values for simple control of operators results - for (int i = 1; i <= nbVals; i++) { - aFieldOnGroup2->setValueIJ(anElems[i-1], 1, i*i); - aFieldOnGroup2->setValueIJ(anElems[i-1], 2, -i*i); - } - - int len = aFieldOnGroup1->getValueLength(); - const double * val1 = aFieldOnGroup1->getValue(); - const double * val2 = aFieldOnGroup2->getValue(); - const double * val_res; - - // operators and add, sub, mul, div - - // + - FIELD<double> aSum = *aFieldOnGroup1 + *aFieldOnGroup2; - aSum.setName(aFieldOnGroup1->getName()); - aSum.setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, &aSum, true, true); - val_res = aSum.getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val2[i], val_res[i], 0.000001); - } - - // - - FIELD<double> aDifference = *aFieldOnGroup1 - *aFieldOnGroup2; - aDifference.setName(aFieldOnGroup1->getName()); - aDifference.setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, &aDifference, true, true); - val_res = aDifference.getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] - val2[i], val_res[i], 0.000001); - } - - // - (unary) - FIELD<double> aNegative = - *aFieldOnGroup1; - aNegative.setName(aFieldOnGroup1->getName()); - aNegative.setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, &aNegative, true, true); - val_res = aNegative.getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(- val1[i], val_res[i], 0.000001); - } - - // * - FIELD<double> aProduct = (*aFieldOnGroup1) * (*aFieldOnGroup2); - aProduct.setName(aFieldOnGroup1->getName()); - aProduct.setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, &aProduct, true, true); - val_res = aProduct.getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] * val2[i], val_res[i], 0.000001); - } - - // / - FIELD<double> aQuotient = *aFieldOnGroup1 / *aFieldOnGroup2; - aQuotient.setName(aFieldOnGroup1->getName()); - aQuotient.setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, &aQuotient, true, true); - val_res = aQuotient.getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] / val2[i], val_res[i], 0.000001); - } - - double val22 = aFieldOnGroup2->getValueIJ(anElems[2], 2); - aFieldOnGroup2->setValueIJ(anElems[2], 2, 0.); - - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 / *aFieldOnGroup2, MEDEXCEPTION); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) is it up to user to control validity of data to avoid division on zero? - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 /= *aFieldOnGroup2, MEDEXCEPTION); -#endif - CPPUNIT_ASSERT_THROW(FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); - - // restore value - aFieldOnGroup2->setValueIJ(anElems[2], 2, val22); - - // restore values - for (int i = 1; i <= nbVals; i++) { - aFieldOnGroup1->setValueIJ(anElems[i-1], 1, 13 + i); - aFieldOnGroup1->setValueIJ(anElems[i-1], 2, 13 - i); - } - - // static methods - FIELD<double> * aPtr; - - // add - aPtr = FIELD<double>::add(*aFieldOnGroup1, *aFieldOnGroup2); - aPtr->setName(aFieldOnGroup1->getName()); - aPtr->setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, aPtr, true, true); - val_res = aPtr->getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val2[i], val_res[i], 0.000001); - } - delete aPtr; - - // sub - aPtr = FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup2); - aPtr->setName(aFieldOnGroup1->getName()); - aPtr->setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, aPtr, true, true); - val_res = aPtr->getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] - val2[i], val_res[i], 0.000001); - } - delete aPtr; - - // mul - aPtr = FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup2); - aPtr->setName(aFieldOnGroup1->getName()); - aPtr->setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, aPtr, true, true); - val_res = aPtr->getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] * val2[i], val_res[i], 0.000001); - } - delete aPtr; - - // div - aPtr = FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2); - aPtr->setName(aFieldOnGroup1->getName()); - aPtr->setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, aPtr, true, true); - val_res = aPtr->getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] / val2[i], val_res[i], 0.000001); - } - delete aPtr; - - // addDeep - aPtr = FIELD<double>::addDeep(*aFieldOnGroup1, *aFieldOnGroup2); - aPtr->setName(aFieldOnGroup1->getName()); - aPtr->setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, aPtr, true, true); - val_res = aPtr->getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val2[i], val_res[i], 0.000001); - } - delete aPtr; - - // subDeep - aPtr = FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup2); - aPtr->setName(aFieldOnGroup1->getName()); - aPtr->setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, aPtr, true, true); - val_res = aPtr->getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] - val2[i], val_res[i], 0.000001); - } - delete aPtr; - - // mulDeep - aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup2); - aPtr->setName(aFieldOnGroup1->getName()); - aPtr->setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, aPtr, true, true); - val_res = aPtr->getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] * val2[i], val_res[i], 0.000001); - } - delete aPtr; - - // divDeep - aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2); - aPtr->setName(aFieldOnGroup1->getName()); - aPtr->setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, aPtr, true, true); - val_res = aPtr->getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] / val2[i], val_res[i], 0.000001); - } - delete aPtr; - - // += - *aFieldOnGroup1 += *aFieldOnGroup2; - for (int i = 1; i <= nbVals; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i + i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i - i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); - } - - // -= - *aFieldOnGroup1 -= *aFieldOnGroup2; - for (int i = 1; i <= nbVals; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); - } - - // *= - *aFieldOnGroup1 *= *aFieldOnGroup2; - for (int i = 1; i <= nbVals; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL( (13 + i)*i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-(13 - i)*i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); - } - - // /= - *aFieldOnGroup1 /= *aFieldOnGroup2; - for (int i = 1; i <= nbVals; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); - } - - // check case of different operands: support - MESH * aMeshOneMore = MEDMEMTest_createTestMesh(); - const GROUP* aGroupOneMore = aMeshOneMore->getGroup(MED_EN::MED_FACE, 1); - FIELD<double> * aFieldOnGroup3 = - createFieldOnGroup<double>(aMeshOneMore, aGroupOneMore, "Test_Diff_Mesh", "test"); - for (int i = 1; i <= nbVals; i++) { - aFieldOnGroup3->setValueIJ(anElems[i-1], 1, 2*i); - aFieldOnGroup3->setValueIJ(anElems[i-1], 2, 3*i); - } - const double * val3 = aFieldOnGroup3->getValue(); - - //CPPUNIT_ASSERT_NO_THROW(); - try { - aPtr = FIELD<double>::addDeep(*aFieldOnGroup1, *aFieldOnGroup3); - aPtr->setName(aFieldOnGroup1->getName()); - aPtr->setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, aPtr, true, true); - val_res = aPtr->getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val3[i], val_res[i], 0.000001); - } - delete aPtr; - - aPtr = FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup3); - delete aPtr; - aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup3); - delete aPtr; - aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup3); - delete aPtr; - } - catch (MEDEXCEPTION & ex) { - CPPUNIT_FAIL(ex.what()); - } - catch (...) { - CPPUNIT_FAIL("Unknown exception in FIELD::xxxDeep()"); - } - - CPPUNIT_ASSERT_THROW(FIELD<double>::add(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION); - - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 + *aFieldOnGroup3, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 - *aFieldOnGroup3, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 * *aFieldOnGroup3, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 / *aFieldOnGroup3, MEDEXCEPTION); - - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 += *aFieldOnGroup3, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 -= *aFieldOnGroup3, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 *= *aFieldOnGroup3, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 /= *aFieldOnGroup3, MEDEXCEPTION); - - // check case of different operands: MEDComponentsUnits - aFieldOnGroup1->setMEDComponentUnit(1, "unit3"); - - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 + *aFieldOnGroup2, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 - *aFieldOnGroup2, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 += *aFieldOnGroup2, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 -= *aFieldOnGroup2, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(FIELD<double>::add(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(FIELD<double>::addDeep(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); - - //CPPUNIT_ASSERT_NO_THROW(); - try { - aPtr = FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup2); - delete aPtr; - aPtr = FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2); - delete aPtr; - aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup2); - delete aPtr; - aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2); - delete aPtr; - - *aFieldOnGroup1 *= *aFieldOnGroup2; - *aFieldOnGroup1 /= *aFieldOnGroup2; - - FIELD<double> aPr = *aFieldOnGroup1 * *aFieldOnGroup2; - FIELD<double> aQu = *aFieldOnGroup1 / *aFieldOnGroup2; - } - catch (MEDEXCEPTION & ex) { - CPPUNIT_FAIL(ex.what()); - } - catch (...) { - CPPUNIT_FAIL("Unknown exception"); - } - - // restore MED units - aFieldOnGroup1->setMEDComponentUnit(1, "unit1"); - - // check case of different operands: valueType - //FIELD<int> * aFieldOnGroup4 = - // createFieldOnGroup<int>(aMeshOneMore, aGroupOneMore, "Test_Diff_Mesh", "test"); - // - //CPPUNIT_ASSERT_THROW(FIELD<double>::add(*aFieldOnGroup4, *aFieldOnGroup3), MEDEXCEPTION); - //CPPUNIT_ASSERT_THROW(*aFieldOnGroup4 - *aFieldOnGroup3, MEDEXCEPTION); - //CPPUNIT_ASSERT_THROW(*aFieldOnGroup4 *= *aFieldOnGroup3, MEDEXCEPTION); - //delete aFieldOnGroup4; - - // check case of different operands: numberOfComponents -#ifdef ENABLE_FAULTS - // (BUG) Cannot allocate value of higher dimension because of _componentsTypes reinitialization - aFieldOnGroup1->deallocValue(); - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->allocValue(/*dim*/5), MEDEXCEPTION); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("Segmentation fault on attempt to allocate value of higher dimension." - " Must be MEDEXCEPTION instead. And on attempt to change nb.components" - " must be the same behaviour."); -#endif - aFieldOnGroup1->setNumberOfComponents(5); - - CPPUNIT_ASSERT_THROW(FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 * *aFieldOnGroup2, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 /= *aFieldOnGroup2, MEDEXCEPTION); - - // check case of different operands: numberOfValues - aFieldOnGroup1->deallocValue(); - aFieldOnGroup1->allocValue(2, nbVals + 1); - // be carefull: aFieldOnGroup1 reallocated and contains random values - - CPPUNIT_ASSERT_THROW(FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 / *aFieldOnGroup2, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 += *aFieldOnGroup2, MEDEXCEPTION); - - // restore aFieldOnGroup1 - aFieldOnGroup1->deallocValue(); - aFieldOnGroup1->allocValue(2, nbVals); - // be carefull: aFieldOnGroup1 reallocated and contains random values - - delete aSubSupport1; - delete [] anElems1; - - delete aScalarProduct; - delete aSubField1; - delete anAreaField; - delete barycenter; - delete aFieldOnGroup1; - delete aFieldOnGroup2; - delete aFieldOnGroup3; - - delete aMesh; - delete aMeshOneMore; - - ///////////////////// - // TEST 5: Drivers // - ///////////////////// - testDrivers(); -} - -/*! - * Check methods (2), defined in MEDMEM_FieldConvert.hxx: - * (+) template <class T> FIELD<T,FullInterlace> * FieldConvert(const FIELD<T,NoInterlace> & field); - * (+) template <class T> FIELD<T,NoInterlace> * FieldConvert(const FIELD<T,FullInterlace> & field); - */ -void MEDMEMTest::testFieldConvert() -{ - // create an empty integer field 2x10 - FIELD<int, FullInterlace> * aField_FING = new FIELD<int, FullInterlace> (); - - aField_FING->setName("Field_FING"); - aField_FING->setDescription("Field full interlace no gauss"); - - aField_FING->setNumberOfComponents(2); - aField_FING->setNumberOfValues(10); - - string aCompsNames[2] = {"Pos", "Neg"}; - string aCompsDescs[2] = {"+", "-"}; - string aMEDCompsUnits[2] = {"unit1", "unit2"}; - UNIT aCompsUnits[2]; - - aCompsUnits[0] = UNIT("u1", "descr1"); - aCompsUnits[1] = UNIT("u2", "descr2"); - - aField_FING->setComponentsNames(aCompsNames); - aField_FING->setComponentsDescriptions(aCompsDescs); - aField_FING->setMEDComponentsUnits(aMEDCompsUnits); - aField_FING->setComponentsUnits(aCompsUnits); - - // check UNITs (for testField()) - const UNIT * aCompsUnitsBack = aField_FING->getComponentsUnits(); - CPPUNIT_ASSERT(aCompsUnits[0].getName() == aCompsUnitsBack[0].getName()); - CPPUNIT_ASSERT(aCompsUnits[1].getName() == aCompsUnitsBack[1].getName()); - - const UNIT * aCompUnitBack1 = aField_FING->getComponentUnit(1); - const UNIT * aCompUnitBack2 = aField_FING->getComponentUnit(2); - CPPUNIT_ASSERT(aCompsUnits[0].getName() == aCompUnitBack1->getName()); - CPPUNIT_ASSERT(aCompsUnits[1].getName() == aCompUnitBack2->getName()); - - // create one more field by copy - FIELD<int, FullInterlace> * aField_FIGG = new FIELD<int, FullInterlace> (*aField_FING); - - // values - int values_FING[20] = { 7,- 7, 14,-14, 21,-21, 28,-28, 35,-35, - 42,-42, 49,-49, 56,-56, 63,-63, 70,-70}; - - ///////////////////// - // TEST 1: NoGauss // - ///////////////////// - - MEDMEM_ArrayInterface<int,FullInterlace,NoGauss>::Array * anArray_FING = - new MEDMEM_ArrayInterface<int,FullInterlace,NoGauss>::Array - (values_FING, /*dim*/2, /*nbelem*/10, /*shallowCopy*/false, /*ownershipOfValues*/false); - aField_FING->setArray(anArray_FING); - // no need to delete anArray_FING, because it will be deleted in destructor of aField_FING - - // 1. FullInterlace -> NoInterlace - FIELD<int, NoInterlace> * aField_NING = FieldConvert(*aField_FING); - const int * values_NING = aField_NING->getValue(); - - for (int i = 0; i < 10; i++) { - for (int j = 0; j < 2; j++) { - CPPUNIT_ASSERT_EQUAL(values_FING[2*i + j], values_NING[10*j + i]); - } - } - - // 2. NoInterlace -> FullInterlace - FIELD<int, FullInterlace> * aField_FING_conv = FieldConvert(*aField_NING); - const int * values_FING_conv = aField_FING_conv->getValue(); - - for (int i = 0; i < 10; i++) { - for (int j = 0; j < 2; j++) { - CPPUNIT_ASSERT_EQUAL(values_FING_conv[2*i + j], values_FING[2*i + j]); - CPPUNIT_ASSERT_EQUAL(values_FING_conv[2*i + j], values_NING[10*j + i]); - } - } - - delete aField_FING; - delete aField_NING; - delete aField_FING_conv; - - /////////////////// - // TEST 2: Gauss // - /////////////////// - int nbelgeoc[2] = {1, 11}; - int nbgaussgeo[2] = {-1, 1}; - MEDMEM_ArrayInterface<int,FullInterlace,Gauss>::Array * anArray_FIGG = - new MEDMEM_ArrayInterface<int,FullInterlace,Gauss>::Array - (values_FING, /*dim*/2, /*nbelem*/10, /*nbtypegeo*/1, /*nbelgeoc*/nbelgeoc, - /*nbgaussgeo*/nbgaussgeo, /*shallowCopy*/false, /*ownershipOfValues*/false); - aField_FIGG->setArray(anArray_FIGG); - // no need to delete anArray_FIGG, because it will be deleted in destructor of aField_FIGG - - // 1. FullInterlace -> NoInterlace - FIELD<int, NoInterlace> * aField_NIGG = FieldConvert(*aField_FIGG); - const int * values_NIGG = aField_NIGG->getValue(); - - for (int i = 0; i < 10; i++) { - for (int j = 0; j < 2; j++) { - CPPUNIT_ASSERT_EQUAL(values_FING[2*i + j], values_NIGG[10*j + i]); - } - } - - // 2. NoInterlace -> FullInterlace - FIELD<int, FullInterlace> * aField_FIGG_conv = FieldConvert(*aField_NIGG); - const int * values_FIGG_conv = aField_FIGG_conv->getValue(); - - for (int i = 0; i < 10; i++) { - for (int j = 0; j < 2; j++) { - CPPUNIT_ASSERT_EQUAL(values_FIGG_conv[2*i + j], values_FING[2*i + j]); - CPPUNIT_ASSERT_EQUAL(values_FIGG_conv[2*i + j], values_NIGG[10*j + i]); - } - } - - delete aField_FIGG; - delete aField_NIGG; - delete aField_FIGG_conv; - -#ifdef ENABLE_FAULTS - // (BUG) in FieldConvert(), concerning FIELD_::operator= - { - // create an empty integer field 2x10 - FIELD<int, FullInterlace> * aField = new FIELD<int, FullInterlace> (); - - aField->setName("aField"); - aField->setDescription("Field full interlace no gauss"); - - aField->setNumberOfComponents(2); - aField->setNumberOfValues(10); - - aField->setComponentsNames(aCompsNames); - aField->setComponentsDescriptions(aCompsDescs); - aField->setMEDComponentsUnits(aMEDCompsUnits); - - MEDMEM_ArrayInterface<int,FullInterlace,NoGauss>::Array * anArray = - new MEDMEM_ArrayInterface<int,FullInterlace,NoGauss>::Array - (values_FING, /*dim*/2, /*nbelem*/10, /*shallowCopy*/false, /*ownershipOfValues*/false); - aField->setArray(anArray); - // no need to delete anArray, because it will be deleted in destructor of aField - - FIELD<int, NoInterlace> * aField_conv = FieldConvert(*aField); - } -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("FieldConvert() fails if _componentsUnits is not set, because it calls FIELD_::operator="); -#endif -} diff --git a/src/MEDMEM/Test/MEDMEMTest_Field_fault.cxx b/src/MEDMEM/Test/MEDMEMTest_Field_fault.cxx deleted file mode 100644 index 59efcfc8d..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Field_fault.cxx +++ /dev/null @@ -1,1543 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "MEDMEM_FieldConvert.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Group.hxx" -#include "MEDMEM_Support.hxx" -#include <MEDMEM_VtkMeshDriver.hxx> -#include <MEDMEM_MedMeshDriver22.hxx> - - -#include <sstream> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -//#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; - -// #14,15: MEDMEMTest_Field.cxx -// Check methods from MEDMEM_Field.hxx, MEDMEM_FieldConvert.hxx - -/*! - * Check methods (48), defined in MEDMEM_Field.hxx: - * class FIELD_ { - * (+) FIELD_(); - * (+) FIELD_(const SUPPORT * Support, const int NumberOfComponents); - * (+) FIELD_(const FIELD_ &m); - * (+) virtual ~FIELD_(); - * (+) FIELD_& operator=(const FIELD_ &m); - * - * (-) virtual void rmDriver(int index=0); - * (-) virtual int addDriver(driverTypes driverType, - * const string & fileName="Default File Name.med", - * const string & driverFieldName="Default Field Nam", - * MED_EN::med_mode_acces access=MED_EN::MED_REMP); - * (-) virtual int addDriver(GENDRIVER & driver); - * - * (-) virtual void read (const GENDRIVER &); - * (-) virtual void read(int index=0); - * (-) virtual void openAppend(void); - * (-) virtual void write(const GENDRIVER &); - * (-) virtual void write(int index=0, const string & driverName=""); - * (-) virtual void writeAppend(const GENDRIVER &); - * (-) virtual void writeAppend(int index=0, const string & driverName=""); - * - * (+) inline void setName(const string Name); - * (+) inline string getName() const; - * (+) inline void setDescription(const string Description); - * (+) inline string getDescription() const; - * (+) inline const SUPPORT * getSupport() const; - * (+) inline void setSupport(const SUPPORT * support); - * (+) inline void setNumberOfComponents(const int NumberOfComponents); - * (+) inline int getNumberOfComponents() const; - * (+) inline void setNumberOfValues(const int NumberOfValues); - * (+) inline int getNumberOfValues() const; - * (+) inline void setComponentsNames(const string * ComponentsNames); - * (+) inline void setComponentName(int i, const string ComponentName); - * (+) inline const string * getComponentsNames() const; - * (+) inline string getComponentName(int i) const; - * (+) inline void setComponentsDescriptions(const string * ComponentsDescriptions); - * (+) inline void setComponentDescription(int i, const string ComponentDescription); - * (+) inline const string * getComponentsDescriptions() const; - * (+) inline string getComponentDescription(int i) const; - * (+) inline void setComponentsUnits(const UNIT * ComponentsUnits); - * (+) inline const UNIT * getComponentsUnits() const; - * (+) inline const UNIT * getComponentUnit(int i) const; - * (+) inline void setMEDComponentsUnits(const string * MEDComponentsUnits); - * (+) inline void setMEDComponentUnit(int i, const string MEDComponentUnit); - * (+) inline const string * getMEDComponentsUnits() const; - * (+) inline string getMEDComponentUnit(int i) const; - * - * (+) inline void setIterationNumber(int IterationNumber); - * (+) inline int getIterationNumber() const; - * (+) inline void setTime(double Time); - * (+) inline double getTime() const; - * (+) inline void setOrderNumber(int OrderNumber); - * (+) inline int getOrderNumber() const; - * - * (+) inline MED_EN::med_type_champ getValueType () const; - * (+) inline MED_EN::medModeSwitch getInterlacingType() const; - * (-) virtual inline bool getGaussPresence() const throw (MEDEXCEPTION); - * } - * - * template <class T, class INTERLACING_TAG> class FIELD : public FIELD_ { - * (+) FIELD(); - * (+) FIELD(const FIELD &m); - * (+) FIELD(const SUPPORT * Support, const int NumberOfComponents) throw (MEDEXCEPTION); - * (+) FIELD(driverTypes driverType, - * const string & fileName, const string & fieldDriverName, - * const int iterationNumber=-1, const int orderNumber=-1) throw (MEDEXCEPTION); - * (+) FIELD(const SUPPORT * Support, driverTypes driverType, - * const string & fileName="", const string & fieldName="", - * const int iterationNumber = -1, const int orderNumber = -1) throw (MEDEXCEPTION); - * (+) ~FIELD(); - * (+) FIELD & operator=(const FIELD &m); - * - * (+) const FIELD operator+(const FIELD& m) const; - * (+) const FIELD operator-(const FIELD& m) const; - * (+) const FIELD operator*(const FIELD& m) const; - * (+) const FIELD operator/(const FIELD& m) const; - * (+) const FIELD operator-() const; - * (+) FIELD& operator+=(const FIELD& m); - * (+) FIELD& operator-=(const FIELD& m); - * (+) FIELD& operator*=(const FIELD& m); - * (+) FIELD& operator/=(const FIELD& m); - * - * (+) static FIELD* add(const FIELD& m, const FIELD& n); - * (+) static FIELD* addDeep(const FIELD& m, const FIELD& n); - * (+) static FIELD* sub(const FIELD& m, const FIELD& n); - * (+) static FIELD* subDeep(const FIELD& m, const FIELD& n); - * (+) static FIELD* mul(const FIELD& m, const FIELD& n); - * (+) static FIELD* mulDeep(const FIELD& m, const FIELD& n); - * (+) static FIELD* div(const FIELD& m, const FIELD& n); - * (+) static FIELD* divDeep(const FIELD& m, const FIELD& n); - * - * (+) double normMax() const throw (MEDEXCEPTION); - * (+) double norm2() const throw (MEDEXCEPTION); - * - * (+) void applyLin(T a, T b); - * (+) template <T T_function(T)> void applyFunc(); - * (+) void applyPow(T scalar); - * - * (+) static FIELD* scalarProduct(const FIELD& m, const FIELD& n, bool deepCheck=false); - * - * (+) double normL2(int component, const FIELD<double,FullInterlace> * p_field_volume=NULL) const; - * (+) double normL2(const FIELD<double,FullInterlace> * p_field_volume=NULL) const; - * (+) double normL1(int component, const FIELD<double,FullInterlace> * p_field_volume=NULL) const; - * (+) double normL1(const FIELD<double,FullInterlace> * p_field_volume=NULL) const; - * - * (+) FIELD* extract(const SUPPORT *subSupport) const throw (MEDEXCEPTION); - * - * (EMPTY COMMENT, EMPTY IMPLEMENTATION!!!) void init (); - * - * (+) void rmDriver(int index=0); - * (+) int addDriver(driverTypes driverType, - * const string & fileName="Default File Name.med", - * const string & driverFieldName="Default Field Name", - * MED_EN::med_mode_acces access=MED_EN::MED_REMP); - * (+) int addDriver(GENDRIVER & driver); - * - * (+) void allocValue(const int NumberOfComponents); - * (+) void allocValue(const int NumberOfComponents, const int LengthValue); - * (+) void deallocValue(); - * - * (+) inline void read(int index=0); - * (+) inline void read(const GENDRIVER & genDriver); - * (+) inline void write(int index=0, const string & driverName = ""); - * (+) inline void write(const GENDRIVER &); - * (+) inline void writeAppend(int index=0, const string & driverName = ""); - * (+) inline void writeAppend(const GENDRIVER &); - * - * (+) inline MEDMEM_Array_ * getArray() const throw (MEDEXCEPTION); - * (+) inline ArrayGauss * getArrayGauss() const throw (MEDEXCEPTION); - * (+) inline ArrayNoGauss * getArrayNoGauss() const throw (MEDEXCEPTION); - * (+) inline bool getGaussPresence() const throw (MEDEXCEPTION); - * - * (+) inline int getValueLength() const throw (MEDEXCEPTION); - * (+) inline const T* getValue() const throw (MEDEXCEPTION); - * (+) inline const T* getRow(int i) const throw (MEDEXCEPTION); - * (+) inline const T* getColumn(int j) const throw (MEDEXCEPTION); - * (+) inline T getValueIJ(int i,int j) const throw (MEDEXCEPTION); - * (+) inline T getValueIJK(int i,int j,int k) const throw (MEDEXCEPTION); - * (+) bool getValueOnElement(int eltIdInSup,T* retValues) const throw (MEDEXCEPTION); - * - * (+) const int getNumberOfGeometricTypes() const throw (MEDEXCEPTION); - * - * (+) const GAUSS_LOCALIZATION<INTERLACING_TAG> & getGaussLocalization - * (MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION); - * (+) const GAUSS_LOCALIZATION<INTERLACING_TAG> * getGaussLocalizationPtr - * (MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION); - * (+) void setGaussLocalization(MED_EN::medGeometryElement geomElement, - * const GAUSS_LOCALIZATION<INTERLACING_TAG> & gaussloc); - * (+) const int * getNumberOfGaussPoints() const throw (MEDEXCEPTION); - * (+) const int getNumberOfGaussPoints - * (MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION); - * (+) const int getNbGaussI(int i) const throw (MEDEXCEPTION); - * - * (+) const int * getNumberOfElements() const throw (MEDEXCEPTION); - * (+) const MED_EN::medGeometryElement * getGeometricTypes() const throw (MEDEXCEPTION); - * (+) bool isOnAllElements() const throw (MEDEXCEPTION); - * - * (+) inline void setArray(MEDMEM_Array_ *value) throw (MEDEXCEPTION); - * (+) inline void setValue(T* value) throw (MEDEXCEPTION); - * (+) inline void setRow(int i, T* value) throw (MEDEXCEPTION); - * (+) inline void setColumn(int i, T* value) throw (MEDEXCEPTION); - * (+) inline void setValueIJ(int i, int j, T value) throw (MEDEXCEPTION); - * - * (NOT IMPLEMENTED!!!) void getVolume() const throw (MEDEXCEPTION); - * (NOT IMPLEMENTED!!!) void getArea() const throw (MEDEXCEPTION); - * (NOT IMPLEMENTED!!!) void getLength() const throw (MEDEXCEPTION); - * (NOT IMPLEMENTED!!!) void getNormal() const throw (MEDEXCEPTION); - * (NOT IMPLEMENTED!!!) void getBarycenter() const throw (MEDEXCEPTION); - * - * (+) void fillFromAnalytic(myFuncType f) throw (MEDEXCEPTION); - * } - * - * Use code of test_operation_fieldint.cxx - * test_operation_fielddouble.cxx - * test_copie_field_.cxx - * test_copie_fieldT.cxx - */ -void compareField_(const FIELD_ * theField_1, const FIELD_ * theField_2, bool isFIELD, bool isValue) -{ - // name, description, support - CPPUNIT_ASSERT_EQUAL(theField_1->getName(), theField_2->getName()); - CPPUNIT_ASSERT_EQUAL(theField_1->getDescription(), theField_2->getDescription()); - CPPUNIT_ASSERT_EQUAL(theField_1->getSupport(), theField_2->getSupport()); - - // components information - int aNbComps = theField_1->getNumberOfComponents(); - CPPUNIT_ASSERT_EQUAL(aNbComps, theField_2->getNumberOfComponents()); - - for (int i = 1; i <= aNbComps; i++) { - CPPUNIT_ASSERT_EQUAL(theField_1->getComponentName(i), theField_2->getComponentName(i)); - CPPUNIT_ASSERT_EQUAL(theField_1->getComponentDescription(i), theField_2->getComponentDescription(i)); - CPPUNIT_ASSERT_EQUAL(theField_1->getMEDComponentUnit(i), theField_2->getMEDComponentUnit(i)); - } - - // iteration information - CPPUNIT_ASSERT_EQUAL(theField_1->getIterationNumber(), theField_2->getIterationNumber()); - CPPUNIT_ASSERT_EQUAL(theField_1->getOrderNumber(), theField_2->getOrderNumber()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(theField_1->getTime(), theField_2->getTime(), 0.0000001); - - // Value - int nbOfValues = theField_1->getNumberOfValues(); - CPPUNIT_ASSERT_EQUAL(nbOfValues, theField_2->getNumberOfValues()); - - if (isFIELD) { - // Value type and Interlacing type - CPPUNIT_ASSERT_EQUAL(theField_1->getValueType(), theField_2->getValueType()); - CPPUNIT_ASSERT_EQUAL(theField_1->getInterlacingType(), theField_2->getInterlacingType()); - - // Gauss Presence - if (isValue) { - CPPUNIT_ASSERT_EQUAL(theField_1->getGaussPresence(), theField_2->getGaussPresence()); - } - else { - CPPUNIT_ASSERT_THROW(theField_1->getGaussPresence(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField_2->getGaussPresence(), MEDEXCEPTION); - } - } - else { - CPPUNIT_ASSERT_THROW(theField_1->getGaussPresence(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField_2->getGaussPresence(), MEDEXCEPTION); - } -} - -void checkField_(FIELD_ * theField_, const SUPPORT * theSupport, - MED_EN::med_type_champ theValueType, - MED_EN::medModeSwitch theInterlace) -{ - // name - const string aFieldName = "a_name_of_a_field"; - theField_->setName(aFieldName); - CPPUNIT_ASSERT_EQUAL(aFieldName, theField_->getName()); - - // description - const string aFieldDescr = "a_description_of_a_field"; - theField_->setDescription(aFieldDescr); - CPPUNIT_ASSERT_EQUAL(aFieldDescr, theField_->getDescription()); - - // support - theField_->setSupport(theSupport); - CPPUNIT_ASSERT(theField_->getSupport() == theSupport); - - // components information - int aNbComps = 3; - - string aCompsNames[3] = {"Vx", "Vy", "Vz"}; - string aCompsDescs[3] = {"vitesse selon x", "vitesse selon y", "vitesse selon z"}; - string aCompsUnits[3] = {"m.s-1", "m.s-1", "m.s-1"}; - - theField_->setNumberOfComponents(aNbComps); - CPPUNIT_ASSERT_EQUAL(aNbComps, theField_->getNumberOfComponents()); - - theField_->setComponentsNames(aCompsNames); - -#ifdef ENABLE_FAULTS - try { - theField_->setNumberOfComponents(7); - // Segmentation fault here because array of components names is not resized - for (int i = 1; i <= 7; i++) { - theField_->setComponentName(i, "AnyComponent"); - } - } - catch (MEDEXCEPTION& ex) { - // Ok, it is good to have MEDEXCEPTION here - } - catch (...) { - CPPUNIT_FAIL("Unknown exception cought"); - } - // restore components names - theField_->setNumberOfComponents(aNbComps); - theField_->setComponentsNames(aCompsNames); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("FIELD_::_componentsNames bad management"); -#endif - - theField_->setComponentsDescriptions(aCompsDescs); - theField_->setMEDComponentsUnits(aCompsUnits); - - const string * aCompsNamesBack = theField_->getComponentsNames(); - const string * aCompsDescsBack = theField_->getComponentsDescriptions(); - const string * aCompsUnitsBack = theField_->getMEDComponentsUnits(); - for (int i = 1; i <= aNbComps; i++) { - CPPUNIT_ASSERT_EQUAL(aCompsNamesBack[i-1], theField_->getComponentName(i)); - CPPUNIT_ASSERT_EQUAL(aCompsNamesBack[i-1], aCompsNames[i-1]); - - CPPUNIT_ASSERT_EQUAL(aCompsDescsBack[i-1], theField_->getComponentDescription(i)); - CPPUNIT_ASSERT_EQUAL(aCompsDescsBack[i-1], aCompsDescs[i-1]); - - CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack[i-1], theField_->getMEDComponentUnit(i)); - CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack[i-1], aCompsUnits[i-1]); - } - - const string aCompName2 ("Name of second component"); - const string aCompDesc2 ("Description of second component"); - const string aCompUnit2 ("Unit of second MED component"); - - theField_->setComponentName(2, aCompName2); - theField_->setComponentDescription(2, aCompDesc2); - theField_->setMEDComponentUnit(2, aCompUnit2); - - const string * aCompsNamesBack2 = theField_->getComponentsNames(); - const string * aCompsDescsBack2 = theField_->getComponentsDescriptions(); - const string * aCompsUnitsBack2 = theField_->getMEDComponentsUnits(); - - CPPUNIT_ASSERT_EQUAL(aCompsNamesBack2[1], theField_->getComponentName(2)); - CPPUNIT_ASSERT_EQUAL(aCompsNamesBack2[1], aCompName2); - - CPPUNIT_ASSERT_EQUAL(aCompsDescsBack2[1], theField_->getComponentDescription(2)); - CPPUNIT_ASSERT_EQUAL(aCompsDescsBack2[1], aCompDesc2); - - CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack2[1], theField_->getMEDComponentUnit(2)); - CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack2[1], aCompUnit2); - -#ifdef ENABLE_FAULTS - // (BUG) No index checking - CPPUNIT_ASSERT_THROW(theField_->setComponentName(0, "str"), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField_->setComponentName(aNbComps + 1, "str"), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField_->setComponentDescription(0, "str"), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField_->setComponentDescription(aNbComps + 1, "str"), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField_->setMEDComponentUnit(0, "str"), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField_->setMEDComponentUnit(aNbComps + 1, "str"), MEDEXCEPTION); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("FIELD::setComponentXXX() does not check component index"); -#endif - - // iteration information - int anIterNumber = 10; // set value to MED_NOPDT if undefined (default) - theField_->setIterationNumber(anIterNumber); - CPPUNIT_ASSERT_EQUAL(anIterNumber, theField_->getIterationNumber()); - - int anOrderNumber = 1; // set value to MED_NONOR if undefined (default) - theField_->setOrderNumber(anOrderNumber); - CPPUNIT_ASSERT_EQUAL(anOrderNumber, theField_->getOrderNumber()); - - double aTime = 3.435678; // in second - theField_->setTime(aTime); - CPPUNIT_ASSERT_DOUBLES_EQUAL(aTime, theField_->getTime(), 0.0000001); - - // Value - int nbOfValues = 10; - // dangerous method, because it does not reallocate values array - theField_->setNumberOfValues(nbOfValues); - CPPUNIT_ASSERT_EQUAL(nbOfValues, theField_->getNumberOfValues()); - - // Value type and Interlacing type - CPPUNIT_ASSERT_EQUAL(theValueType, theField_->getValueType()); - CPPUNIT_ASSERT_EQUAL(theInterlace, theField_->getInterlacingType()); -} - -template<class T, class INTERLACING_TAG> -void compareField(const FIELD<T, INTERLACING_TAG> * theField_1, - const FIELD<T, INTERLACING_TAG> * theField_2, bool isValue) -{ - // compare FIELD_ part - compareField_(theField_1, theField_2, /*isFIELD = */true, isValue); - - // compare FIELD part - // TO DO -} - -template<class T, class INTERLACING_TAG> -void checkField (FIELD<T, INTERLACING_TAG> * theField, const SUPPORT * theSupport) -{ - // check FIELD_ part - MED_EN::med_type_champ aValueType = SET_VALUE_TYPE<T>::_valueType; - MED_EN::medModeSwitch anInterlace = SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType; - checkField_(theField, theSupport, aValueType, anInterlace); - - // check FIELD part - - // filling by support charackteristics (NOT IMPLEMENTED METHODS!!!): - // value type must be MED_REEL64 (i.e. a FIELD<double>) for these methods, - // nb. of components must be equal 1 (for Volume, Area, Length) or - // space dimension (for Normal, Barycenter, ) - { - MESH* aMesh = theSupport->getMesh(); - int spaceDim = 3; - if (aMesh) spaceDim = aMesh->getSpaceDimension(); - theField->deallocValue(); - theField->allocValue(/*NumberOfComponents = */spaceDim + 1); - - CPPUNIT_ASSERT_THROW(theField->getVolume(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField->getArea(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField->getLength(), MEDEXCEPTION); - if (aMesh) { - CPPUNIT_ASSERT_THROW(theField->getNormal(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField->getBarycenter(), MEDEXCEPTION); - } - - theField->deallocValue(); - theField->allocValue(/*NumberOfComponents = */1); - if (aValueType == MED_EN::MED_REEL64) { - CPPUNIT_ASSERT_NO_THROW(theField->getVolume()); - CPPUNIT_ASSERT_NO_THROW(theField->getArea()); - CPPUNIT_ASSERT_NO_THROW(theField->getLength()); - } - else { - CPPUNIT_ASSERT_THROW(theField->getVolume(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField->getArea(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField->getLength(), MEDEXCEPTION); - } - - if (aMesh) { - theField->deallocValue(); - theField->allocValue(/*NumberOfComponents = */spaceDim); - if (aValueType == MED_EN::MED_REEL64) { - CPPUNIT_ASSERT_NO_THROW(theField->getNormal()); - CPPUNIT_ASSERT_NO_THROW(theField->getBarycenter()); - } - else { - CPPUNIT_ASSERT_THROW(theField->getNormal(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(theField->getBarycenter(), MEDEXCEPTION); - } - } - } - - // values - theField->deallocValue(); - theField->allocValue(/*NumberOfComponents = */2); - int nbElemSupport = theSupport->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS); - CPPUNIT_ASSERT_EQUAL(nbElemSupport, theField->getNumberOfValues()); - -#ifdef ENABLE_FAULTS - // (BUG) FIELD::deallocValue() does not nullify _value pointer, - // that is why there can be failures in other methods - // (even if simply call deallocValue() two times) - theField->deallocValue(); - theField->getGaussPresence(); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("FIELD::deallocValue() does not nullify _value pointer"); -#endif - - // copy constructor - FIELD<T, INTERLACING_TAG> aField_copy1 (*theField); - //compareField(theField, &aField_copy1, /*isValue = */false); - compareField(theField, &aField_copy1, /*isValue = */true); - - // operator= -#ifdef ENABLE_FAULTS - // (BUG) This fails (Segmentation fault) if not set: - // _componentsNames or _componentsDescriptions, or _componentsUnits, or _MEDComponentsUnits - FIELD<T, INTERLACING_TAG> aField_copy2; - aField_copy2 = *theField; - //compareField(theField, &aField_copy2, /*isValue = */false); - compareField(theField, &aField_copy2, /*isValue = */true); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("FIELD_::operator=() fails if _componentsUnits is not set"); -#endif -} - -template<class T> -FIELD<T> * createFieldOnGroup(MESH* theMesh, const GROUP* theGroup, - const string theName, const string theDescr) -{ - FIELD<T> * aFieldOnGroup = new FIELD<T> (theGroup, /*NumberOfComponents = */2); - - aFieldOnGroup->setName(theName); - aFieldOnGroup->setDescription(theDescr); - - string aCompsNames[2] = {"Pos", "Neg"}; - string aCompsDescs[2] = {"+", "-"}; - string aCompsUnits[2] = {"unit1", "unit2"}; - - aFieldOnGroup->setComponentsNames(aCompsNames); - aFieldOnGroup->setComponentsDescriptions(aCompsDescs); - aFieldOnGroup->setMEDComponentsUnits(aCompsUnits); - - return aFieldOnGroup; -} - -double plus13 (double val) -{ - return val + 13; -} - -// function to calculate field values from coordinates of an element -// typedef void (*myFuncType)(const double * temp, T* output); -// size of temp array = space dim = 3 -// size of output array = nb. comps = 2 -void proj2d (const double * temp, double* output) -{ - // dimetric projection with coefficients: - // 1.0 along Oy and Oz, 0.5 along Ox - // - // ^ z (y_) - // | - // | - // .----> y (x_) - // / - // L x - // - // x_ = y - x * sqrt(2.) / 4. - // y_ = z - x * sqrt(2.) / 4. - - double dx = temp[0] * std::sqrt(2.) / 4.; - output[0] = temp[1] - dx; - output[1] = temp[2] - dx; -} - -void testDrivers() -{ - string data_dir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - if (tmp_dir == "") - tmp_dir = "/tmp"; - - string filename_rd = data_dir + "/MedFiles/pointe.med"; - string filename_wr = tmp_dir + "/myMedFieldfile.med"; - string filename_support_wr = tmp_dir + "/myMedSupportFiledfile.med"; - string filename22_rd = data_dir + "/MedFiles/pointe_import22.med"; - string filenamevtk_wr = tmp_dir + "/myMedFieldfile22.vtk"; - string cp_file = "cp " + filename_rd + " " + filename_wr; - - string fieldname_celldouble_rd = "fieldcelldouble"; - string fieldname_celldouble_wr = fieldname_celldouble_rd + "_cpy"; - string fieldname_nodeint_rd = "fieldnodeint"; - string fieldname_nodeint_wr = fieldname_nodeint_rd + "_cpy"; - string fieldname_nodeint_wr1 = fieldname_nodeint_rd + "_cpy1"; - string meshname = "maa1"; - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filename_wr); - aRemover.Register(filenamevtk_wr); - aRemover.Register(filename_support_wr); - - //Copy file - system(cp_file.c_str()); - - FIELD<int> aInvalidField; - //must throw becase only VTK_DRIVER or MED_DRIVER may be specified as driverType for FIELD - CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(NO_DRIVER, filename_rd, fieldname_nodeint_rd), - MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(GIBI_DRIVER, filename_rd, fieldname_nodeint_rd), - MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(PORFLOW_DRIVER, filename_rd, fieldname_nodeint_rd), - MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(ASCII_DRIVER, filename_rd, fieldname_nodeint_rd), - MEDEXCEPTION); - - ////////////////// - //TestRead Part// - ////////////////// - FIELD<double> *aField_1 = NULL; - CPPUNIT_ASSERT_NO_THROW(aField_1 = new FIELD<double>(MED_DRIVER, filename_rd, fieldname_celldouble_rd)); - - //Test read(int index) method - int IdDriver_rd = aField_1->addDriver(MED_DRIVER,filename_rd,fieldname_celldouble_rd); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Cannot open file, but file exist - CPPUNIT_ASSERT_NO_THROW(aField_1->read(IdDriver_rd)); -#endif - - //Test read(GENDRIVER & genDriver) method - //Creation a Driver - MED_FIELD_RDONLY_DRIVER21<int> *aMedRdFieldDriver21_1 = - new MED_FIELD_RDONLY_DRIVER21<int>(); - //Creation a Field - FIELD<int> *aField_2 = new FIELD<int>(); - aField_2->setName(fieldname_nodeint_rd); - aField_2->addDriver(*aMedRdFieldDriver21_1); - aField_2->read(*aMedRdFieldDriver21_1); - - /////////////////// - //Test Write Part// - /////////////////// - int IdDriver; - MESH *aMesh = new MESH(MED_DRIVER,filename_rd,meshname); - SUPPORT *aSupport = new SUPPORT(aMesh, "aSupport",MED_CELL); - FIELD<int> *aFieldSupport; -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_NO_THROW(aFieldSupport = - new FIELD<int>(aSupport, MED_DRIVER,filename_support_wr,fieldname_nodeint_rd)); - //(BUG) Can not open file - MED_FIELD_WRONLY_DRIVER21<int> * aFieldWrDriver21 = - new MED_FIELD_WRONLY_DRIVER21<int>(filename_support_wr,aFieldSupport); - aFieldWrDriver21->setFieldName(aFieldSupport->getName() + "_copy"); - CPPUNIT_ASSERT_NO_THROW(IdDriver= aFieldSupport->addDriver(*aFieldWrDriver21)); - CPPUNIT_ASSERT_NO_THROW(aFieldSupport->write(IdDriver)); - delete aFieldSupport; - delete aFieldWrDriver21; -#endif - - //Create fileds - FIELD<double> * aField_3 = new FIELD<double>(); - MED_FIELD_RDONLY_DRIVER21<double> *aMedRdFieldDriver21_2 = - new MED_FIELD_RDONLY_DRIVER21<double>(filename_rd, aField_3); - aMedRdFieldDriver21_2->open(); - aMedRdFieldDriver21_2->setFieldName(fieldname_celldouble_rd); - aMedRdFieldDriver21_2->read(); - aMedRdFieldDriver21_2->close(); - - //Test write(int index) method - //Add drivers to FIELDs - int IdDriver1 = -1; - try - { - IdDriver1 = aField_3->addDriver(MED_DRIVER,filename_wr,fieldname_celldouble_wr); - } - catch(MEDEXCEPTION &e) - { - e.what(); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - //Trying call write(int index) method with incorrect index -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_THROW(aField_3->write(IdDriver1+1, fieldname_celldouble_wr),MEDEXCEPTION); - // => Segmentation fault -#endif - - //Write field to file -#ifdef ENABLE_FAULTS - try - { - aField_3->write(IdDriver1, fieldname_celldouble_wr); - // => Segmentation fault - } - catch(MEDEXCEPTION &e) - { - e.what(); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } -#endif - - CPPUNIT_ASSERT_NO_THROW(aField_3->rmDriver(IdDriver1)); - - //Test write(const GENDRIVER &); - //Create a driver - MED_FIELD_WRONLY_DRIVER21<int> *aMedWrFieldDriver21 = - new MED_FIELD_WRONLY_DRIVER21<int>(); - aMedWrFieldDriver21->setFileName(filename_wr); - aField_2->setName(fieldname_nodeint_wr1); - //Add driver to a field - aField_2->addDriver(*aMedWrFieldDriver21); - - try - { - aField_2->write(*aMedWrFieldDriver21); - } - catch(MEDEXCEPTION &e) - { - e.what(); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test writeAppend(int index) method - //Create a vtk file - MESH * aMesh_1 = new MESH(); - MED_MESH_RDONLY_DRIVER22 *aMedMeshRdDriver22 = new MED_MESH_RDONLY_DRIVER22(filename22_rd, aMesh_1); - aMedMeshRdDriver22->open(); - aMedMeshRdDriver22->setMeshName(meshname); - aMedMeshRdDriver22->read(); - aMedMeshRdDriver22->close(); - VTK_MESH_DRIVER *aVtkDriver = new VTK_MESH_DRIVER(filenamevtk_wr, aMesh_1); - aVtkDriver->open(); - aVtkDriver->write(); - aVtkDriver->close(); - - //Create a field - FIELD<int> * aField_4 = new FIELD<int>(); - MED_FIELD_RDONLY_DRIVER22<int> *aMedRdFieldDriver22 = - new MED_FIELD_RDONLY_DRIVER22<int>(filename22_rd, aField_2); - aMedRdFieldDriver22->open(); - aMedRdFieldDriver22->setFieldName(fieldname_nodeint_rd); - aMedRdFieldDriver22->read(); - aMedRdFieldDriver22->close(); - - //Add Driver to a field - int IdDriver2; - try - { - IdDriver2 = aField_4->addDriver(VTK_DRIVER, filenamevtk_wr ,fieldname_nodeint_wr); - } - catch(MEDEXCEPTION &e) - { - e.what(); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } -#ifdef ENABLE_FAULTS - //Trying call writeAppend() method with incorrect index - CPPUNIT_ASSERT_THROW(aField_4->writeAppend(IdDriver2+1,fieldname_nodeint_wr),MEDEXCEPTION); - // => Segmentation fault -#endif - -#ifdef ENABLE_FAULTS - // (BUG) => Segmentation fault - CPPUNIT_ASSERT_NO_THROW(aField_4->writeAppend(IdDriver2, fieldname_nodeint_wr)); -#endif - - //Test writeAppend(const GENDRIVER &) method - aField_4->setName(fieldname_nodeint_wr1); - - //Add driver to a field -#ifdef ENABLE_FAULTS - //Create a driver - VTK_FIELD_DRIVER<int> *aVtkFieldDriver = new VTK_FIELD_DRIVER<int>(filenamevtk_wr, aField_4); - CPPUNIT_ASSERT_NO_THROW(aField_4->addDriver(*aVtkFieldDriver)); - //(BUG) => Segmentation fault after addDriver(const GENDRIVER &) - CPPUNIT_ASSERT_NO_THROW(aField_4->writeAppend(*aVtkFieldDriver)); -#endif - - - //Delete objects - delete aField_1; - delete aMedRdFieldDriver21_1; - delete aField_2; - delete aField_3; - delete aMedRdFieldDriver21_2; - delete aField_4; - delete aMedMeshRdDriver22; - delete aMedWrFieldDriver21; - delete aVtkDriver; - delete aMesh; - delete aMesh_1; - delete aMedRdFieldDriver22; - delete aSupport; -} - -void MEDMEMTest_testField() -{ - SUPPORT anEmptySupport; - //////////////////// - // TEST 1: FIELD_ // - //////////////////// - FIELD_ aField_; - - // check set/get methods - MED_EN::med_type_champ aValueType = MED_EN::MED_UNDEFINED_TYPE; - MED_EN::medModeSwitch anInterlace = MED_EN::MED_UNDEFINED_INTERLACE; - checkField_(&aField_, &anEmptySupport, aValueType, anInterlace); - - // copy constructor - // This fails (Segmentation fault) if not set: - // _componentsNames or _componentsDescriptions, or _MEDComponentsUnits - FIELD_ aField_copy1 (aField_); - compareField_(&aField_, &aField_copy1, /*isFIELD = */false, /*isValue = */false); - - // operator= -#ifdef ENABLE_FAULTS - // (BUG) This fails (Segmentation fault) if not set: - // _componentsNames or _componentsDescriptions, or _componentsUnits, or _MEDComponentsUnits - // (BUG) Code duplication with copyGlobalInfo(), called from copy constructor - FIELD_ aField_copy2; - aField_copy2 = aField_; - compareField_(&aField_, &aField_copy2, /*isFIELD = */false, /*isValue = */false); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("FIELD_::operator=() fails if _componentsUnits is not set"); -#endif - - // construction on a given support - { - anEmptySupport.setTotalNumberOfElements(11); - // CASE1: - FIELD_ aField_case1 (&anEmptySupport, 10); - // CASE2: - FIELD_ aField_case2; - aField_case2.setSupport(&anEmptySupport); - aField_case2.setNumberOfComponents(10); - -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_EQUAL_MESSAGE("No correspondance between CASE1 and CASE2", - aField_case1.getNumberOfValues(), - aField_case2.getNumberOfValues()); -#endif - } - - //////////////////////// - // TEST 2: FIELD<int> // - //////////////////////// - FIELD<int> aFieldInt; - checkField(&aFieldInt, &anEmptySupport); - - //////////////////////////////////////// - // TEST 3: FIELD<double, NoInterlace> // - //////////////////////////////////////// - MESH * aMesh = MEDMEMTest_createTestMesh(); - const GROUP* aGroup = aMesh->getGroup(MED_EN::MED_FACE, 1); - - FIELD<double, NoInterlace> aFieldDouble; - checkField(&aFieldDouble, aGroup); - - ////////////////////////////////////////// - // TEST 4: FIELD<double, FullInterlace> // - ////////////////////////////////////////// - FIELD<double> * aFieldOnGroup1 = createFieldOnGroup<double>(aMesh, aGroup, "Linear", "N"); - FIELD<double> * aFieldOnGroup2 = createFieldOnGroup<double>(aMesh, aGroup, "Quadratic", "N**2"); - - int nbVals = aFieldOnGroup1->getNumberOfValues(); - CPPUNIT_ASSERT(nbVals); - - // numbers of elements in group, - // they are needed in method FIELD::setValueIJ() - const int *anElems = aGroup->getnumber()->getValue(); - double eucl1 = 0., eucl2 = 0.; - - for (int i = 1; i <= nbVals; i++) { - aFieldOnGroup1->setValueIJ(anElems[i-1], 1, (double)i); - aFieldOnGroup1->setValueIJ(anElems[i-1], 2, (double)(-i)); - - aFieldOnGroup2->setValueIJ(anElems[i-1], 1, (double)i*i); - aFieldOnGroup2->setValueIJ(anElems[i-1], 2, (double)(-i*i)); - - eucl1 += 2. * i * i; - eucl2 += 2. * i * i * i * i; - } - - // out of bound (inexisting 33-th component of last element) - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->setValueIJ(anElems[nbVals-1], 33, 10.), MEDEXCEPTION); - - // normMax - CPPUNIT_ASSERT_DOUBLES_EQUAL(nbVals, aFieldOnGroup1->normMax(), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(nbVals*nbVals, aFieldOnGroup2->normMax(), 0.000001); - - // norm2 - CPPUNIT_ASSERT_DOUBLES_EQUAL(std::sqrt(eucl1), aFieldOnGroup1->norm2(), 0.000001); // 10.4881 - CPPUNIT_ASSERT_DOUBLES_EQUAL(std::sqrt(eucl2), aFieldOnGroup2->norm2(), 0.000001); // 44.2493 - - // check getXXX methods - CPPUNIT_ASSERT(!aFieldOnGroup1->getGaussPresence()); - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getArrayGauss(), MEDEXCEPTION); - MEDMEM_ArrayInterface<double, FullInterlace,NoGauss>::Array * anArrayNoGauss = - aFieldOnGroup1->getArrayNoGauss(); - - MEDMEM_Array_ * aMEDMEM_Array_ = aFieldOnGroup1->getArray(); - MEDMEM_ArrayInterface<double, FullInterlace,NoGauss>::Array * aMEDMEM_Array_conv = - static_cast<MEDMEM_ArrayInterface<double, FullInterlace,NoGauss>::Array *>(aMEDMEM_Array_); - - const double * aValues = aFieldOnGroup1->getValue(); - - // out of range - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getColumn(3), MEDEXCEPTION); - // cannot get column in FullInterlace - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getColumn(1), MEDEXCEPTION); - - for (int i = 1; i <= nbVals; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , aFieldOnGroup1->getValueIJK(anElems[i-1], 1, 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), aFieldOnGroup1->getValueIJK(anElems[i-1], 2, 1), 0.000001); - - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , aValues[(i-1)*2 + 0], 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), aValues[(i-1)*2 + 1], 0.000001); - - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , anArrayNoGauss->getIJ(i, 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), anArrayNoGauss->getIJ(i, 2), 0.000001); - - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , aMEDMEM_Array_conv->getIJ(i, 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), aMEDMEM_Array_conv->getIJ(i, 2), 0.000001); - - const double* row_i = aFieldOnGroup1->getRow(anElems[i-1]); - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , row_i[0], 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), row_i[1], 0.000001); - - double vals_i [2]; - aFieldOnGroup1->getValueOnElement(anElems[i-1], vals_i); - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , vals_i[0], 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), vals_i[1], 0.000001); - } - - // modify all values of aFieldOnGroup2 by formula a*x + b (a = 2, b = 3) - aFieldOnGroup2->applyLin(2., 3.); - for (int i = 1; i <= nbVals; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(3. + 2.*i*i, aFieldOnGroup2->getValueIJ(anElems[i-1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3. - 2.*i*i, aFieldOnGroup2->getValueIJ(anElems[i-1], 2), 0.000001); - } - - // apply function plus13() to aFieldOnGroup1 - aFieldOnGroup1->applyFunc<plus13>(); - for (int i = 1; i <= nbVals; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); - } - - // scalarProduct - FIELD<double, FullInterlace> * aScalarProduct = - FIELD<double, FullInterlace>::scalarProduct(*aFieldOnGroup1, *aFieldOnGroup2, /*deepCheck = */true); - CPPUNIT_ASSERT_EQUAL(nbVals, aScalarProduct->getNumberOfValues()); - CPPUNIT_ASSERT_EQUAL(1, aScalarProduct->getNumberOfComponents()); - for (int i = 1; i <= nbVals; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(78. + 4.*i*i*i, //(3. + 2.*i*i)*(13 + i) + (3. - 2.*i*i)*(13 - i) - aScalarProduct->getValueIJ(anElems[i-1], 1), 0.000001); - } - - // fillFromAnalytic - aFieldOnGroup2->fillFromAnalytic(proj2d); - - double bary [3]; - double outp [2]; - const SUPPORT * aSupp = aFieldOnGroup2->getSupport(); - FIELD<double,FullInterlace> * barycenter = aMesh->getBarycenter(aSupp); - for (int i = 1; i <= nbVals; i++) { - bary[0] = barycenter->getValueIJ(anElems[i-1], 1); - bary[1] = barycenter->getValueIJ(anElems[i-1], 2); - bary[2] = barycenter->getValueIJ(anElems[i-1], 3); - - proj2d(bary, outp); - - //cout << "barycenter (" << bary[0] << ", " << bary[1] << ", " << bary[2] << ")" << endl; - //cout << "proj2d (" << outp[0] << ", " << outp[1] << ")" << endl; - - //bary (-0.666667, 0.666667, 0.666667) -> outp ( 0.902369, 0.902369) - //bary ( 0.666667, -0.666667, 0.666667) -> outp (-0.902369, 0.430964) - //bary ( 0. , 0. , 2. ) -> outp ( 0. , 2. ) - //bary ( 0. , 0. , 3. ) -> outp ( 0. , 3. ) - //bary (-1. , 0. , 2.5 ) -> outp ( 0.353553, 2.85355 ) - -#ifdef ENABLE_FORCED_FAILURES - // (BUG) in FIELD::fillFromAnalytic() in case of support, different from nodes: - // barycenterField in FullInterlace, but values extracted like from NoInterlace - CPPUNIT_ASSERT_DOUBLES_EQUAL(outp[0], aFieldOnGroup2->getValueIJ(anElems[i-1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(outp[1], aFieldOnGroup2->getValueIJ(anElems[i-1], 2), 0.000001); -#endif - - // currently it gives values, that are wrong: - //aFieldOnGroup2 row1 ( 0.902369, 0.235702) - //aFieldOnGroup2 row2 (-0.235702, 2.7643 ) - //aFieldOnGroup2 row3 (-0.235702, -1.2357 ) - //aFieldOnGroup2 row4 ( 1.7643 , -0.235702) - //aFieldOnGroup2 row5 ( 0.235702, 2.7357 ) - } - - // info about support (Group1) - CPPUNIT_ASSERT(!aFieldOnGroup1->isOnAllElements()); // because we build Group1 so - int nbTypes = aFieldOnGroup1->getNumberOfGeometricTypes(); - //CPPUNIT_ASSERT(nbTypes); - CPPUNIT_ASSERT_EQUAL(2, nbTypes); - const int * nbElemsInEachType = aFieldOnGroup1->getNumberOfElements(); - const MED_EN::medGeometryElement * aGeomTypes = aFieldOnGroup1->getGeometricTypes(); - - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_TRIA3, aGeomTypes[0]); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_QUAD4, aGeomTypes[1]); - - // GAUSS - - // now we have no gauss localization in aFieldOnGroup1 - CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA3)); - CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_QUAD4)); - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA6), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(), MEDEXCEPTION); - - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalization(MED_EN::MED_TRIA3), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_TRIA3), MEDEXCEPTION); - - CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNbGaussI(anElems[0])); - - // set a gauss localization into aFieldOnGroup1 - double cooRef[6] = {1.,1., 2.,4., 3.,9.}; // xy xy xy - double cooGauss[10] = {7.,7., 6.,6., 5.,5., 4.,3., 2.,1.}; // x1,y1 x2,y2 x3,y3 x4,y4 x5,y5 - double wg[5] = {1., 2., 3., 4., 5.}; - GAUSS_LOCALIZATION<> gl1 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef, cooGauss, wg); - - aFieldOnGroup1->setGaussLocalization(MED_EN::MED_TRIA3, gl1); - - // now we have a gauss localization for MED_TRIA3 type - CPPUNIT_ASSERT_EQUAL(5, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA3)); - CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_QUAD4)); - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA6), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(), MEDEXCEPTION); - - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalization(MED_EN::MED_QUAD4), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_QUAD4), MEDEXCEPTION); - - GAUSS_LOCALIZATION<> gl1Back = aFieldOnGroup1->getGaussLocalization(MED_EN::MED_TRIA3); - const GAUSS_LOCALIZATION<> * gl1BackPtr = aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_TRIA3); - - CPPUNIT_ASSERT(gl1 == gl1Back); - CPPUNIT_ASSERT(gl1 == *gl1BackPtr); - - CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNbGaussI(anElems[0])); - - // sub-support of Group1 on one (first) geometric type - SUPPORT * aSubSupport1 = new SUPPORT(aMesh, "Sub-Support 1 of Group1", MED_EN::MED_FACE); - aSubSupport1->setAll(false); - - int nbTypes1 = 1; - int nbElemsInEachType1[1]; - nbElemsInEachType1[0] = nbElemsInEachType[0]; - int nbElems1 = nbElemsInEachType1[0]; - MED_EN::medGeometryElement aGeomTypes1[1]; - aGeomTypes1[0] = aGeomTypes[0]; - int * anElems1 = new int[nbElems1]; - for (int i = 0; i < nbElems1; i++) { - anElems1[i] = anElems[i]; - } - - aSubSupport1->setpartial("Support for sub-field 1 on one type of elements", - nbTypes1, nbElems1, aGeomTypes1, nbElemsInEachType1, anElems1); - - //cout << "aSubSupport1:" << endl; - //cout << *aSubSupport1 << endl; - - // extract sub-field on aSubSupport1 - FIELD<double, FullInterlace> * aSubField1 = aFieldOnGroup1->extract(aSubSupport1); - CPPUNIT_ASSERT_EQUAL(nbElems1 * /*NumberOfComponents = */2, aSubField1->getValueLength()); - - // aSubField1: - // elt\comp | 1 | 2 - //-------------------- - // 1 | 14 | 12 - // 2 | 15 | 11 - - // check normL2() and normL1() - FIELD<double>* anAreaField = aMesh->getArea(aSubSupport1); - double area1 = anAreaField->getValueIJ(anElems1[0], 1); - double area2 = anAreaField->getValueIJ(anElems1[1], 1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.44949, area1, 0.00001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.44949, area2, 0.00001); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(210.5, aSubField1->normL2(1), 0.00001); // (14*14 + 15*15)/2 -#ifdef ENABLE_FORCED_FAILURES - // (BUG) FIELD::normL2(int component, const FIELD * p_field_volume): - // component is not taken into account - CPPUNIT_ASSERT_DOUBLES_EQUAL(132.5, aSubField1->normL2(2), 0.00001); // (12*12 + 11*11)/2 -#endif - CPPUNIT_ASSERT_DOUBLES_EQUAL(343.0, aSubField1->normL2() , 0.00001); // 210.5 + 132.5 - - CPPUNIT_ASSERT_DOUBLES_EQUAL(14.5, aSubField1->normL1(1), 0.00001); // (14 + 15)/2 - CPPUNIT_ASSERT_DOUBLES_EQUAL(11.5, aSubField1->normL1(2), 0.00001); // (12 + 11)/2 - CPPUNIT_ASSERT_DOUBLES_EQUAL(26.0, aSubField1->normL1() , 0.00001); // 14.5 + 11.5 - - double aNewArea [2] = {1., 0.}; // only first element will be taken into account - anAreaField->setValue(aNewArea); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(196.0, aSubField1->normL2(1, anAreaField), 0.00001); // 14*14/1 -#ifdef ENABLE_FORCED_FAILURES - // (BUG) FIELD::normL2(int component, const FIELD * p_field_volume): - // component is not taken into account - CPPUNIT_ASSERT_DOUBLES_EQUAL(144.0, aSubField1->normL2(2, anAreaField), 0.00001); // 12*12/1 -#endif - CPPUNIT_ASSERT_DOUBLES_EQUAL(340.0, aSubField1->normL2(anAreaField) , 0.00001); // 196 + 144 - - CPPUNIT_ASSERT_DOUBLES_EQUAL(14.0, aSubField1->normL1(1, anAreaField), 0.00001); // 14/1 - CPPUNIT_ASSERT_DOUBLES_EQUAL(12.0, aSubField1->normL1(2, anAreaField), 0.00001); // 12/1 - CPPUNIT_ASSERT_DOUBLES_EQUAL(26.0, aSubField1->normL1(anAreaField) , 0.00001); // 14 + 12 - - // applyPow - aSubField1->applyPow(2.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(196., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); // 14*14 - CPPUNIT_ASSERT_DOUBLES_EQUAL(144., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); // 12*12 - CPPUNIT_ASSERT_DOUBLES_EQUAL(225., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); // 15*15 - CPPUNIT_ASSERT_DOUBLES_EQUAL(121., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); // 11*11 - - // setArray (NoGauss) - MEDMEM_ArrayInterface<double,FullInterlace,NoGauss>::Array * aNewArrayNoGauss = - new MEDMEM_ArrayInterface<double,FullInterlace,NoGauss>::Array(/*dim*/2, /*nbelem*/2); - aNewArrayNoGauss->setIJ(1, 1, 4.); - aNewArrayNoGauss->setIJ(1, 2, 2.); - aNewArrayNoGauss->setIJ(2, 1, 5.); - aNewArrayNoGauss->setIJ(2, 2, 1.); - aSubField1->setArray(aNewArrayNoGauss); - // no need to delete aNewArrayNoGauss, because it will be deleted - // in destructor or in deallocValue() method of aSubField1 - - CPPUNIT_ASSERT_DOUBLES_EQUAL(4., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); - - // setRow - double row[2] = {-1., -3.}; - aSubField1->setRow(anElems1[0], row); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-3., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 5., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); - // out of range - CPPUNIT_ASSERT_THROW(aSubField1->setRow(3, row), MEDEXCEPTION); - - // setColumn - double col[2] = {-7., -9.}; - aSubField1->setColumn(1, col); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-7., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-3., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) in MEDMEM_Array::setColumn() - CPPUNIT_ASSERT_DOUBLES_EQUAL(-9., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); -#endif - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); - // out of range - CPPUNIT_ASSERT_THROW(aSubField1->setColumn(3, col), MEDEXCEPTION); - - // setArray (Gauss) - { - int nbelgeoc[2] = {1, 3}; // 3 - 1 = two elements for the first (and the only) type - int nbgaussgeo[2] = {-1, 1}; // one gauss point per each element - MEDMEM_ArrayInterface<double,FullInterlace,Gauss>::Array * aNewArrayGauss = - new MEDMEM_ArrayInterface<double,FullInterlace,Gauss>::Array - (/*dim*/2, /*nbelem*/2, /*nbtypegeo*/1, /*nbelgeoc*/nbelgeoc, /*nbgaussgeo*/nbgaussgeo); - -#ifdef ENABLE_FAULTS - aNewArrayGauss->setIJ(1, 1, -4.); - aNewArrayGauss->setIJ(1, 2, -2.); - aNewArrayGauss->setIJ(2, 1, -5.); - aNewArrayGauss->setIJ(2, 2, -1.); -#endif -#ifdef ENABLE_FORCED_FAILURES - // ? (BUG) in FullInterlaceGaussPolicy::getIndex(int i,int j) - // FullInterlaceGaussPolicy::getIndex(2,2) returns 4!!! - CPPUNIT_FAIL("? Bug in FullInterlaceGaussPolicy::getIndex(int i,int j) ?"); -#endif - - aNewArrayGauss->setIJK(1, 1, 1, -4.); - aNewArrayGauss->setIJK(1, 2, 1, -2.); - aNewArrayGauss->setIJK(2, 1, 1, -5.); - aNewArrayGauss->setIJK(2, 2, 1, -1.); - - aSubField1->setArray(aNewArrayGauss); - // no need to delete aNewArrayGauss, because it will be deleted - // in destructor or in deallocValue() method of aSubField1 - -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_DOUBLES_EQUAL(-4., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-2., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-5., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); -#endif -#ifdef ENABLE_FORCED_FAILURES - // ? (BUG) in FullInterlaceGaussPolicy::getIndex(int i,int j) - // Must be : return _G[i-1]-1 + (j-1); - // Instead of: return _G[i-1]-1 + (j-1)*_dim; - CPPUNIT_FAIL("? Bug in FullInterlaceGaussPolicy::getIndex(int i,int j) ?"); -#endif - - CPPUNIT_ASSERT_DOUBLES_EQUAL(-4., aSubField1->getValueIJK(anElems1[0], 1, 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-2., aSubField1->getValueIJK(anElems1[0], 2, 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-5., aSubField1->getValueIJK(anElems1[1], 1, 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., aSubField1->getValueIJK(anElems1[1], 2, 1), 0.000001); - } - - // alloc/dealloc; compatibility of new size with support - try { - aSubField1->deallocValue(); - aSubField1->allocValue(/*NumberOfComponents*/2, /*LengthValue*/5); -#ifdef ENABLE_FAULTS - // (BUG) No compatibility between Support and allocated value - aSubField1->normL1(); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("Error: no compatibility between Support and allocated value"); -#endif - } - catch (MEDEXCEPTION & ex) { - // normal behaviour - } - catch (...) { - CPPUNIT_FAIL("Error: no compatibility between Support and allocated value"); - } - - // check that aFieldOnGroup1 is not changed after aSubField1 modifications - for (int i = 1; i <= nbVals; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); - } - - // reset aFieldOnGroup2 values for simple control of operators results - for (int i = 1; i <= nbVals; i++) { - aFieldOnGroup2->setValueIJ(anElems[i-1], 1, i*i); - aFieldOnGroup2->setValueIJ(anElems[i-1], 2, -i*i); - } - - int len = aFieldOnGroup1->getValueLength(); - const double * val1 = aFieldOnGroup1->getValue(); - const double * val2 = aFieldOnGroup2->getValue(); - const double * val_res; - - // operators and add, sub, mul, div - - // + - FIELD<double> aSum = *aFieldOnGroup1 + *aFieldOnGroup2; - aSum.setName(aFieldOnGroup1->getName()); - aSum.setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, &aSum, true, true); - val_res = aSum.getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val2[i], val_res[i], 0.000001); - } - - // - - FIELD<double> aDifference = *aFieldOnGroup1 - *aFieldOnGroup2; - aDifference.setName(aFieldOnGroup1->getName()); - aDifference.setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, &aDifference, true, true); - val_res = aDifference.getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] - val2[i], val_res[i], 0.000001); - } - - // - (unary) - FIELD<double> aNegative = - *aFieldOnGroup1; - aNegative.setName(aFieldOnGroup1->getName()); - aNegative.setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, &aNegative, true, true); - val_res = aNegative.getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(- val1[i], val_res[i], 0.000001); - } - - // * - FIELD<double> aProduct = (*aFieldOnGroup1) * (*aFieldOnGroup2); - aProduct.setName(aFieldOnGroup1->getName()); - aProduct.setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, &aProduct, true, true); - val_res = aProduct.getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] * val2[i], val_res[i], 0.000001); - } - - // / - FIELD<double> aQuotient = *aFieldOnGroup1 / *aFieldOnGroup2; - aQuotient.setName(aFieldOnGroup1->getName()); - aQuotient.setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, &aQuotient, true, true); - val_res = aQuotient.getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] / val2[i], val_res[i], 0.000001); - } - - double val22 = aFieldOnGroup2->getValueIJ(anElems[2], 2); - aFieldOnGroup2->setValueIJ(anElems[2], 2, 0.); - - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 / *aFieldOnGroup2, MEDEXCEPTION); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) is it up to user to control validity of data to avoid division on zero? - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 /= *aFieldOnGroup2, MEDEXCEPTION); -#endif - CPPUNIT_ASSERT_THROW(FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); - - // restore value - aFieldOnGroup2->setValueIJ(anElems[2], 2, val22); - - // restore values - for (int i = 1; i <= nbVals; i++) { - aFieldOnGroup1->setValueIJ(anElems[i-1], 1, 13 + i); - aFieldOnGroup1->setValueIJ(anElems[i-1], 2, 13 - i); - } - - // static methods - FIELD<double> * aPtr; - - // add - aPtr = FIELD<double>::add(*aFieldOnGroup1, *aFieldOnGroup2); - aPtr->setName(aFieldOnGroup1->getName()); - aPtr->setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, aPtr, true, true); - val_res = aPtr->getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val2[i], val_res[i], 0.000001); - } - delete aPtr; - - // sub - aPtr = FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup2); - aPtr->setName(aFieldOnGroup1->getName()); - aPtr->setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, aPtr, true, true); - val_res = aPtr->getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] - val2[i], val_res[i], 0.000001); - } - delete aPtr; - - // mul - aPtr = FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup2); - aPtr->setName(aFieldOnGroup1->getName()); - aPtr->setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, aPtr, true, true); - val_res = aPtr->getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] * val2[i], val_res[i], 0.000001); - } - delete aPtr; - - // div - aPtr = FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2); - aPtr->setName(aFieldOnGroup1->getName()); - aPtr->setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, aPtr, true, true); - val_res = aPtr->getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] / val2[i], val_res[i], 0.000001); - } - delete aPtr; - - // addDeep - aPtr = FIELD<double>::addDeep(*aFieldOnGroup1, *aFieldOnGroup2); - aPtr->setName(aFieldOnGroup1->getName()); - aPtr->setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, aPtr, true, true); - val_res = aPtr->getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val2[i], val_res[i], 0.000001); - } - delete aPtr; - - // subDeep - aPtr = FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup2); - aPtr->setName(aFieldOnGroup1->getName()); - aPtr->setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, aPtr, true, true); - val_res = aPtr->getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] - val2[i], val_res[i], 0.000001); - } - delete aPtr; - - // mulDeep - aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup2); - aPtr->setName(aFieldOnGroup1->getName()); - aPtr->setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, aPtr, true, true); - val_res = aPtr->getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] * val2[i], val_res[i], 0.000001); - } - delete aPtr; - - // divDeep - aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2); - aPtr->setName(aFieldOnGroup1->getName()); - aPtr->setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, aPtr, true, true); - val_res = aPtr->getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] / val2[i], val_res[i], 0.000001); - } - delete aPtr; - - // += - *aFieldOnGroup1 += *aFieldOnGroup2; - for (int i = 1; i <= nbVals; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i + i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i - i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); - } - - // -= - *aFieldOnGroup1 -= *aFieldOnGroup2; - for (int i = 1; i <= nbVals; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); - } - - // *= - *aFieldOnGroup1 *= *aFieldOnGroup2; - for (int i = 1; i <= nbVals; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL( (13 + i)*i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-(13 - i)*i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); - } - - // /= - *aFieldOnGroup1 /= *aFieldOnGroup2; - for (int i = 1; i <= nbVals; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); - } - - // check case of different operands: support - MESH * aMeshOneMore = MEDMEMTest_createTestMesh(); - const GROUP* aGroupOneMore = aMeshOneMore->getGroup(MED_EN::MED_FACE, 1); - FIELD<double> * aFieldOnGroup3 = - createFieldOnGroup<double>(aMeshOneMore, aGroupOneMore, "Test_Diff_Mesh", "test"); - for (int i = 1; i <= nbVals; i++) { - aFieldOnGroup3->setValueIJ(anElems[i-1], 1, 2*i); - aFieldOnGroup3->setValueIJ(anElems[i-1], 2, 3*i); - } - const double * val3 = aFieldOnGroup3->getValue(); - - //CPPUNIT_ASSERT_NO_THROW(); - try { - aPtr = FIELD<double>::addDeep(*aFieldOnGroup1, *aFieldOnGroup3); - aPtr->setName(aFieldOnGroup1->getName()); - aPtr->setDescription(aFieldOnGroup1->getDescription()); - compareField_(aFieldOnGroup1, aPtr, true, true); - val_res = aPtr->getValue(); - for (int i = 0; i < len; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val3[i], val_res[i], 0.000001); - } - delete aPtr; - - aPtr = FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup3); - delete aPtr; - aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup3); - delete aPtr; - aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup3); - delete aPtr; - } - catch (MEDEXCEPTION & ex) { - CPPUNIT_FAIL(ex.what()); - } - catch (...) { - CPPUNIT_FAIL("Unknown exception in FIELD::xxxDeep()"); - } - - CPPUNIT_ASSERT_THROW(FIELD<double>::add(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION); - - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 + *aFieldOnGroup3, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 - *aFieldOnGroup3, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 * *aFieldOnGroup3, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 / *aFieldOnGroup3, MEDEXCEPTION); - - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 += *aFieldOnGroup3, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 -= *aFieldOnGroup3, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 *= *aFieldOnGroup3, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 /= *aFieldOnGroup3, MEDEXCEPTION); - - // check case of different operands: MEDComponentsUnits - aFieldOnGroup1->setMEDComponentUnit(1, "unit3"); - - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 + *aFieldOnGroup2, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 - *aFieldOnGroup2, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 += *aFieldOnGroup2, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 -= *aFieldOnGroup2, MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(FIELD<double>::add(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(FIELD<double>::addDeep(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); - - //CPPUNIT_ASSERT_NO_THROW(); - try { - aPtr = FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup2); - delete aPtr; - aPtr = FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2); - delete aPtr; - aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup2); - delete aPtr; - aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2); - delete aPtr; - - *aFieldOnGroup1 *= *aFieldOnGroup2; - *aFieldOnGroup1 /= *aFieldOnGroup2; - - FIELD<double> aPr = *aFieldOnGroup1 * *aFieldOnGroup2; - FIELD<double> aQu = *aFieldOnGroup1 / *aFieldOnGroup2; - } - catch (MEDEXCEPTION & ex) { - CPPUNIT_FAIL(ex.what()); - } - catch (...) { - CPPUNIT_FAIL("Unknown exception"); - } - - // restore MED units - aFieldOnGroup1->setMEDComponentUnit(1, "unit1"); - - // check case of different operands: numberOfComponents -#ifdef ENABLE_FAULTS - // (BUG) Cannot allocate value of higher dimension because of _componentsTypes reinitialization - // Must be MEDEXCEPTION instead. And on attempt to change nb.components must be the same behaviour. - aFieldOnGroup1->deallocValue(); - CPPUNIT_ASSERT_THROW(aFieldOnGroup1->allocValue(/*dim*/5), MEDEXCEPTION); -#endif - - delete aSubSupport1; - delete [] anElems1; - - delete aScalarProduct; - delete aSubField1; - delete anAreaField; - delete barycenter; - delete aFieldOnGroup1; - delete aFieldOnGroup2; - delete aFieldOnGroup3; - - delete aMesh; - delete aMeshOneMore; - - ///////////////////// - // TEST 5: Drivers // - ///////////////////// - testDrivers(); -} - -int main (int argc, char** argv) -{ - MEDMEMTest_testField(); -} diff --git a/src/MEDMEM/Test/MEDMEMTest_Formulae.cxx b/src/MEDMEM/Test/MEDMEMTest_Formulae.cxx deleted file mode 100644 index c8e30bada..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Formulae.cxx +++ /dev/null @@ -1,611 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "MEDMEM_Formulae.hxx" -#include "MEDMEM_STRING.hxx" - -#include <iostream> -#include <sstream> -#include <cmath> -#include <cfloat> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; - -// #17: MEDMEM_Formulae.hxx } MEDMEMTest_Formulae.cxx - -/*! - * Check methods (13), defined in MEDMEM_Formulae.hxx: - * - * (+) inline void CalculateBarycenterDyn(const double **pts, int nbPts, int dim, double *bary); - * - * (+) inline double CalculateAreaForPolyg(const double **coords, int nbOfPtsInPolygs, int spaceDim); - * (+) inline double CalculateAreaForTria(const double *p1, const double *p2, - * const double *p3, int spaceDim); - * (+) inline double CalculateAreaForQuad(const double *p1, const double *p2, - * const double *p3, const double *p4, int spaceDim); - * - * (+) inline void CalculateNormalForTria(const double *p1, const double *p2, - * const double *p3, double *normal); - * (+) inline void CalculateNormalForQuad(const double *p1, const double *p2, - * const double *p3, const double *p4, double *normal); - * (+) inline void CalculateNormalForPolyg(const double **coords, int nbOfPtsInPolygs, double *normal); - * - * (+) inline double CalculateVolumeForTetra(const double *p1, const double *p2, - * const double *p3, const double *p4); - * (+) inline double CalculateVolumeForPyra(const double *p1, const double *p2, - * const double *p3, const double *p4, const double *p5); - * (+) inline double CalculateVolumeForPenta(const double *p1, const double *p2, const double *p3, - * const double *p4, const double *p5, const double *p6); - * (+) inline double CalculateVolumeForHexa(const double *pt1, const double *pt2, const double *pt3, - * const double *pt4, const double *pt5, const double *pt6, - * const double *pt7, const double *pt8); - * (+) inline double CalculateVolumeForPolyh(const double ***pts, const int *nbOfNodesPerFaces, - * int nbOfFaces, const double *bary); - * - * (+) template<int N> inline double addComponentsOfVec(const double **pts, int rk); - * (+) template<> inline double addComponentsOfVec<1>(const double **pts, int rk); - * - * (+) template<int N, int DIM> inline void CalculateBarycenter(const double **pts, double *bary); - * (-) template<> inline void CalculateBarycenter<2,0>(const double **pts, double *bary); - * (-) template<> inline void CalculateBarycenter<3,0>(const double **pts, double *bary); - * (-) template<> inline void CalculateBarycenter<4,0>(const double **pts, double *bary); - * (-) template<> inline void CalculateBarycenter<5,0>(const double **pts, double *bary); - * (-) template<> inline void CalculateBarycenter<6,0>(const double **pts, double *bary); - * (-) template<> inline void CalculateBarycenter<7,0>(const double **pts, double *bary); - * (-) template<> inline void CalculateBarycenter<8,0>(const double **pts, double *bary); - */ -void MEDMEMTest::testFormulae() -{ - double val; - - // ^y - // | - // *3 - // 4 | - // .*. . . . . . *6,7 - // | - // . .8* . . . . . - // | 5 2,9 - // . . . .*. * . . - // 1| - // -.-.-*-.-.-.-.-.-->x - // | - - // S_12634 = (3 + (3+4.8)*2 + 4.8 + 1.5*4)/2 = 1.5 + 7.8 + 2.4 + 3 = 14.7 - // S_143652 = S_14362 - S_625 = 14.7 - 2 * 1.5 / 2 = 13.2 - - double xy1[2] = { 0.0, 0.0}; - double xy2[2] = { 3.0, 1.0}; - double xy3[2] = { 0.0, 4.0}; - double xy4[2] = {-1.5, 3.0}; - double xy5[2] = { 1.5, 1.0}; - double xy6[2] = { 4.8, 3.0}; - - double xyz1[3] = { 0.0, 0.0, 0.0}; - double xyz2[3] = { 3.0, 1.0, 4.0}; // cos(alpha) = 3/5 - double xyz3[3] = { 0.0, 4.0, 0.0}; - double xyz4[3] = {-1.5, 3.0, -2.0}; // z4 = z2 * x4 / x2 = - 4 * 1.5 / 3 - double xyz5[3] = { 1.5, 1.0, 2.0}; // z5 = z2 * x5 / x2 = 4 * 1.5 / 3 - double xyz6[3] = { 4.8, 3.0, 6.4}; // z6 = z2 * x6 / x2 = 4 * 4.8 / 3 - double xyz7[3] = { 4.8, 3.0, 0.0}; - double xyz8[3] = { 0.0, 2.0, 0.0}; - double xyz9[3] = { 3.0, 1.0, 0.0}; - - // S_3d = S_2d * 5.0 / 3.0 - - /////////////////////////// - // CalculateAreaForPolyg // - /////////////////////////// - { - // 2D: Convex polygon - const double * poly_2d_cc[5] = {xy1, xy2, xy6, xy3, xy4}; - const double * poly_2d_cw[5] = {xy1, xy4, xy3, xy6, xy2}; - - // counter-clockwise - val = CalculateAreaForPolyg(poly_2d_cc, /*nbOfPtsInPolygs*/5, /*dim*/2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-14.7, val, 0.000001); - - // clockwise - val = CalculateAreaForPolyg(poly_2d_cw, /*nbOfPtsInPolygs*/5, /*dim*/2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(14.7, val, 0.000001); - - // 2D: Non-convex polygon - const double * poly_2d_nc[6] = {xy1, xy4, xy3, xy6, xy5, xy2}; - val = CalculateAreaForPolyg(poly_2d_nc, /*nbOfPtsInPolygs*/6, /*dim*/2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(13.2, val, 0.000001); - - // 3D: Convex polygon - const double * poly_3d_cc[5] = {xyz1, xyz2, xyz6, xyz3, xyz4}; - - val = CalculateAreaForPolyg(poly_3d_cc, /*nbOfPtsInPolygs*/5, /*dim*/3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(24.5, val, 0.000001); - - // 3D: Non-convex polygon - const double * poly_3d_nc[6] = {xyz1, xyz4, xyz3, xyz6, xyz5, xyz2}; - val = CalculateAreaForPolyg(poly_3d_nc, /*nbOfPtsInPolygs*/6, /*dim*/3); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Wrong area calculation for non-convex polygons in 3D space, - // because area of triangle is always positive - CPPUNIT_ASSERT_DOUBLES_EQUAL(22.0, val, 0.000001); -#endif - } - - ////////////////////////// - // CalculateAreaForTria // - ////////////////////////// - { - // 2D: counter-clockwise - val = CalculateAreaForTria(xy1, xy2, xy3, /*dim*/2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.0, val, 0.000001); - - // 2D: clockwise - val = CalculateAreaForTria(xy2, xy1, xy3, /*dim*/2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.0, val, 0.000001); - - // 3D - val = CalculateAreaForTria(xyz1, xyz2, xyz3, /*dim*/3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(10.0, val, 0.000001); - - // Invalid (three points on one line) - val = CalculateAreaForTria(xyz1, xyz8, xyz3, /*dim*/3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, val, 0.000001); - } - - ////////////////////////// - // CalculateAreaForQuad // - ////////////////////////// - { - // 2D: Convex quadrangle - - // counter-clockwise - val = CalculateAreaForQuad(xy1, xy2, xy3, xy4, /*dim*/2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-9.0, val, 0.000001); - - // clockwise - val = CalculateAreaForQuad(xy2, xy1, xy4, xy3, /*dim*/2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0, val, 0.000001); - - // wrong order - CPPUNIT_ASSERT_NO_THROW(CalculateAreaForQuad(xy2, xy1, xy3, xy4, /*dim*/2)); - - // 2D: Non-convex quadrangle - - // counter-clockwise - val = CalculateAreaForQuad(xy1, xy2, xy3, xy5, /*dim*/2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.0, val, 0.000001); - - // clockwise - val = CalculateAreaForQuad(xy1, xy5, xy3, xy2, /*dim*/2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0, val, 0.000001); - - // 3D: Convex quadrangle - - // good order - val = CalculateAreaForQuad(xyz1, xyz2, xyz3, xyz4, /*dim*/3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.0, val, 0.000001); - - // wrong order - CPPUNIT_ASSERT_NO_THROW(CalculateAreaForQuad(xyz1, xyz4, xyz2, xyz3, /*dim*/3)); - - // 3D: Non-convex quadrangle - val = CalculateAreaForQuad(xyz1, xyz2, xyz3, xyz5, /*dim*/3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.0, val, 0.000001); - - // 3D: Non-planar quadrangle - double xyz7[3] = {-1.5, 3.0, 2.0}; - CPPUNIT_ASSERT_NO_THROW(CalculateAreaForQuad(xyz1, xyz2, xyz3, xyz7, /*dim*/3)); - } - - //////////////////////////// - // CalculateNormalForTria // - //////////////////////////// - { - double tria_normal [3]; - - // Triangle in plane XOY, normal is opposit to axis Z - CalculateNormalForTria(xyz1, xyz3, xyz7, tria_normal); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, tria_normal[0], 0.0000001); // Nx - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, tria_normal[1], 0.0000001); // Ny - CPPUNIT_ASSERT(tria_normal[2] < -0.0000001); // Nz - - // Triangle in plane XOY, normal co-directed with axis Z - CalculateNormalForTria(xyz1, xyz7, xyz3, tria_normal); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, tria_normal[0], 0.0000001); // Nx - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, tria_normal[1], 0.0000001); // Ny - CPPUNIT_ASSERT(tria_normal[2] > 0.0000001); // Nz - - // Triangle in 3D - CalculateNormalForTria(xyz1, xyz3, xyz6, tria_normal); - double koeff = tria_normal[0]/12.8; - //CPPUNIT_ASSERT_DOUBLES_EQUAL(12.8, tria_normal[0], 0.0000001); // Nx - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0 , tria_normal[1], 0.0000001); // Ny - CPPUNIT_ASSERT_DOUBLES_EQUAL(-9.6 * koeff, tria_normal[2], 0.0000001); // Nz - - // Invalid Triangle (three points on one line) - CPPUNIT_ASSERT_NO_THROW(CalculateNormalForTria(xyz1, xyz8, xyz3, tria_normal)); - //MEDMEMTest_DumpArray<double>(cout, tria_normal, 3, "Invalid Triangle normal"); - //Invalid Triangle normal: {0, 0, 0} - } - - //////////////////////////// - // CalculateNormalForQuad // - //////////////////////////// - { - double quad_normal [3]; - - // Quadrangle in plane XOY, normal is opposit to axis Z - CalculateNormalForQuad(xyz1, xyz3, xyz7, xyz9, quad_normal); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, quad_normal[0], 0.0000001); // Nx - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, quad_normal[1], 0.0000001); // Ny - CPPUNIT_ASSERT(quad_normal[2] < -0.0000001); // Nz - - // Quadrangle in plane XOY, normal co-directed with axis Z - CalculateNormalForQuad(xyz1, xyz9, xyz7, xyz3, quad_normal); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, quad_normal[0], 0.0000001); // Nx - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, quad_normal[1], 0.0000001); // Ny - CPPUNIT_ASSERT(quad_normal[2] > 0.0000001); // Nz - - // Quadrangle in 3D - CalculateNormalForQuad(xyz1, xyz3, xyz6, xyz2, quad_normal); - //MEDMEMTest_DumpArray<double>(cout, quad_normal, 3, "Quadrangle in 3D normal"); - double koeff = quad_normal[0]/15.6; - //CPPUNIT_ASSERT_DOUBLES_EQUAL(15.6, quad_normal[0], 0.0000001); // Nx - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0 , quad_normal[1], 0.0000001); // Ny - CPPUNIT_ASSERT_DOUBLES_EQUAL(-11.7 * koeff, quad_normal[2], 0.0000001); // Nz - - // Invalid Quadrangle (four points on one line) - CPPUNIT_ASSERT_NO_THROW(CalculateNormalForQuad(xyz1, xyz8, xyz3, xyz3, quad_normal)); - //MEDMEMTest_DumpArray<double>(cout, quad_normal, 3, "Invalid Quadrangle normal"); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) division on zero in CalculateNormalForQuad(), if quadrangle is singular - //Invalid Quadrangle normal: {nan, nan, nan} - CPPUNIT_ASSERT(quad_normal[0] < DBL_MAX); - CPPUNIT_ASSERT(quad_normal[1] < DBL_MAX); - CPPUNIT_ASSERT(quad_normal[2] < DBL_MAX); -#endif - } - - ///////////////////////////// - // CalculateNormalForPolyg // - ///////////////////////////// - { - double poly_normal [3]; - const double * polygon_cc[4] = {xyz1, xyz3, xyz7, xyz9}; - const double * polygon_er[4] = {xyz1, xyz8, xyz3, xyz7}; - const double * polygon_cw[4] = {xyz1, xyz9, xyz7, xyz3}; - const double * polygon_3d[4] = {xyz1, xyz3, xyz6, xyz2}; - const double * polygon_si[4] = {xyz1, xyz8, xyz3, xyz3}; - - // Polygon in plane XOY, normal is opposit to axis Z - CalculateNormalForPolyg(polygon_cc, /*nbOfPtsInPolygs*/4, poly_normal); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, poly_normal[0], 0.0000001); // Nx - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, poly_normal[1], 0.0000001); // Ny -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Normal for polygon is wrong - CPPUNIT_ASSERT(poly_normal[2] < -0.0000001); // Nz -#endif - - // Polygon in plane XOY, normal co-directed with axis Z - CalculateNormalForPolyg(polygon_cw, /*nbOfPtsInPolygs*/4, poly_normal); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, poly_normal[0], 0.0000001); // Nx - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, poly_normal[1], 0.0000001); // Ny -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Normal for polygon is wrong - CPPUNIT_ASSERT(poly_normal[2] > 0.0000001); // Nz -#endif - - // Polygon in plane XOY, normal is opposit to axis Z, first three points lay on one line - CalculateNormalForPolyg(polygon_er, /*nbOfPtsInPolygs*/4, poly_normal); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, poly_normal[0], 0.0000001); // Nx - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, poly_normal[1], 0.0000001); // Ny -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Normal for polygon is wrong if first (three) points are on one line - CPPUNIT_ASSERT(poly_normal[2] < -0.0000001); // Nz -#endif - - // Polygon in 3D - CalculateNormalForPolyg(polygon_3d, /*nbOfPtsInPolygs*/4, poly_normal); - double koeff = poly_normal[0]/15.6; - //CPPUNIT_ASSERT_DOUBLES_EQUAL(15.6, poly_normal[0], 0.0000001); // Nx - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0 , poly_normal[1], 0.0000001); // Ny - CPPUNIT_ASSERT_DOUBLES_EQUAL(-11.7 * koeff, poly_normal[2], 0.0000001); // Nz - - // Invalid Polygon (four points on one line) - CPPUNIT_ASSERT_NO_THROW(CalculateNormalForPolyg(polygon_si, /*nbOfPtsInPolygs*/4, poly_normal)); - //MEDMEMTest_DumpArray<double>(cout, poly_normal, 3, "Invalid Polygon normal"); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) division on zero in CalculateNormalForPolyg(), if polygon is singular - //Invalid Polygon normal: {nan, nan, nan} - CPPUNIT_ASSERT(poly_normal[0] < DBL_MAX); - CPPUNIT_ASSERT(poly_normal[1] < DBL_MAX); - CPPUNIT_ASSERT(poly_normal[2] < DBL_MAX); -#endif - } - - ///////////////////////////// - // CalculateVolumeForTetra // - ///////////////////////////// - { - // good - val = CalculateVolumeForTetra(xyz1, xyz3, xyz7, xyz5); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.4, val, 0.000001); - - // reversed - val = CalculateVolumeForTetra(xyz1, xyz7, xyz3, xyz5); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.4, val, 0.000001); - - // good - val = CalculateVolumeForTetra(xyz1, xyz7, xyz3, xyz4); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.4, val, 0.000001); - - // reversed - val = CalculateVolumeForTetra(xyz1, xyz3, xyz7, xyz4); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.4, val, 0.000001); - - // singular (in plane) - val = CalculateVolumeForTetra(xyz1, xyz3, xyz7, xyz9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, val, 0.000001); - } - - //////////////////////////// - // CalculateVolumeForPyra // - //////////////////////////// - { - // good - val = CalculateVolumeForPyra(xyz1, xyz3, xyz7, xyz9, xyz5); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8, val, 0.000001); - - // reversed - val = CalculateVolumeForPyra(xyz1, xyz9, xyz7, xyz3, xyz5); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-7.8, val, 0.000001); - - // good - val = CalculateVolumeForPyra(xyz1, xyz9, xyz7, xyz3, xyz4); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8, val, 0.000001); - - // reversed - val = CalculateVolumeForPyra(xyz1, xyz3, xyz7, xyz9, xyz4); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-7.8, val, 0.000001); - - // singular (in plane) - val = CalculateVolumeForPyra(xyz1, xyz3, xyz7, xyz9, xyz8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, val, 0.000001); - } - - ///////////////////////////// - // CalculateVolumeForPenta // - ///////////////////////////// - { - double top1[3] = {xyz1[0], xyz1[1], xyz1[2] + 10.0}; - double top3[3] = {xyz3[0], xyz3[1], xyz3[2] + 10.0}; - double top7[3] = {xyz7[0], xyz7[1], xyz7[2] + 10.0}; - - // good - val = CalculateVolumeForPenta(xyz1, xyz3, xyz7, top1, top3, top7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(96.0, val, 0.000001); - - // reversed - val = CalculateVolumeForPenta(xyz1, xyz7, xyz3, top1, top7, top3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-96.0, val, 0.000001); - - // good - top1[0] = top1[0] + 7.0; - top3[0] = top3[0] + 7.0; - top7[0] = top7[0] + 7.0; - - val = CalculateVolumeForPenta(xyz1, xyz3, xyz7, top1, top3, top7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(96.0, val, 0.000001); - - // reversed - val = CalculateVolumeForPenta(xyz1, xyz7, xyz3, top1, top7, top3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-96.0, val, 0.000001); - - // singular (in plane) - top1[2] = top1[2] - 10.0; - top3[2] = top3[2] - 10.0; - top7[2] = top7[2] - 10.0; - - val = CalculateVolumeForPenta(xyz1, xyz3, xyz7, top1, top3, top7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, val, 0.000001); - } - - //////////////////////////// - // CalculateVolumeForHexa // - //////////////////////////// - { - double top1[3] = {xyz1[0], xyz1[1], xyz1[2] + 10.0}; - double top3[3] = {xyz3[0], xyz3[1], xyz3[2] + 10.0}; - double top7[3] = {xyz7[0], xyz7[1], xyz7[2] + 10.0}; - double top9[3] = {xyz9[0], xyz9[1], xyz9[2] + 10.0}; - - // good - val = CalculateVolumeForHexa(xyz1, xyz3, xyz7, xyz9, top1, top3, top7, top9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(117.0, val, 0.000001); - - // reversed - val = CalculateVolumeForHexa(xyz1, xyz9, xyz7, xyz3, top1, top9, top7, top3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-117.0, val, 0.000001); - - // good - top1[0] = top1[0] + 7.0; - top3[0] = top3[0] + 7.0; - top7[0] = top7[0] + 7.0; - top9[0] = top9[0] + 7.0; - - val = CalculateVolumeForHexa(xyz1, xyz3, xyz7, xyz9, top1, top3, top7, top9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(117.0, val, 0.000001); - - // reversed - val = CalculateVolumeForHexa(xyz1, xyz9, xyz7, xyz3, top1, top9, top7, top3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-117.0, val, 0.000001); - - // singular (in plane) - top1[2] = top1[2] - 10.0; - top3[2] = top3[2] - 10.0; - top7[2] = top7[2] - 10.0; - top9[2] = top9[2] - 10.0; - - val = CalculateVolumeForHexa(xyz1, xyz3, xyz7, xyz9, top1, top3, top7, top9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, val, 0.000001); - } - - ///////////////////////////// - // CalculateVolumeForPolyh // - ///////////////////////////// - // inline double CalculateVolumeForPolyh(const double ***pts, const int *nbOfNodesPerFaces, - // int nbOfFaces, const double *bary); - { - int nbFaces = 4; - int nbOfNodesPerFaces[4] = {3,3,3,3}; - - const double * nodes[4] = {xyz1, xyz7, xyz3, xyz5}; - double bary[3]; - CalculateBarycenterDyn(nodes, 4, /*dim*/3, bary); - - // good - const double * fa1[3] = {xyz1, xyz7, xyz3}; - const double * fa2[3] = {xyz1, xyz3, xyz5}; - const double * fa3[3] = {xyz3, xyz7, xyz5}; - const double * fa4[3] = {xyz7, xyz1, xyz5}; - const double ** polyh[4] = {fa1, fa2, fa3, fa4}; - - val = CalculateVolumeForPolyh(polyh, nbOfNodesPerFaces, nbFaces, bary); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.4, val, 0.000001); - - // reversed - //const double * fa1_r[3] = {xyz1, xyz3, xyz7}; - //const double * fa2_r[3] = {xyz3, xyz1, xyz5}; - //const double * fa3_r[3] = {xyz7, xyz3, xyz5}; - //const double * fa4_r[3] = {xyz1, xyz7, xyz5}; - //const double ** polyh_r[4] = {fa1_r, fa2_r, fa3_r, fa4_r}; - // - //val = CalculateVolumeForPolyh(polyh_r, nbOfNodesPerFaces, nbFaces, bary); - //CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.4, val, 0.000001); - - // singular (in plane) - const double * nodes_si[4] = {xyz1, xyz7, xyz3, xyz9}; - double bary_si[3]; - CalculateBarycenterDyn(nodes_si, 4, /*dim*/3, bary_si); - - const double * fa1_si[3] = {xyz1, xyz7, xyz3}; - const double * fa2_si[3] = {xyz1, xyz3, xyz9}; - const double * fa3_si[3] = {xyz3, xyz7, xyz9}; - const double * fa4_si[3] = {xyz7, xyz1, xyz9}; - const double ** polyh_si[4] = {fa1_si, fa2_si, fa3_si, fa4_si}; - - val = CalculateVolumeForPolyh(polyh_si, nbOfNodesPerFaces, nbFaces, bary_si); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, val, 0.000001); - } - - //////////////////////// - // addComponentsOfVec // - //////////////////////// - { - // five points - const double * pts[5] = {xyz2, xyz1, xyz3, xyz4, xyz5}; - - val = addComponentsOfVec<5>(pts, 0); // x - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0, val, 0.000001); - - val = addComponentsOfVec<5>(pts, 1); // y - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0, val, 0.000001); - - val = addComponentsOfVec<5>(pts, 2); // z - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0, val, 0.000001); - - // one point: xyz2 - val = addComponentsOfVec<1>(pts, 0); // x - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0, val, 0.000001); - - val = addComponentsOfVec<1>(pts, 1); // y - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, val, 0.000001); - - val = addComponentsOfVec<1>(pts, 2); // z - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0, val, 0.000001); - } - - //////////////////////////// - // CalculateBarycenterDyn // - //////////////////////////// - { - // five points - const double * pts[5] = {xyz2, xyz1, xyz3, xyz4, xyz5}; - double bary_3d[3]; - double bary_2d[2]; - - CalculateBarycenterDyn(pts, /*nbPts*/5, /*dim*/3, bary_3d); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0/5.0, bary_3d[0], 0.000001); // x - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0/5.0, bary_3d[1], 0.000001); // y - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0/5.0, bary_3d[2], 0.000001); // z - - CalculateBarycenterDyn(pts, /*nbPts*/5, /*dim*/2, bary_2d); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0/5.0, bary_2d[0], 0.000001); // x - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0/5.0, bary_2d[1], 0.000001); // y - - // one point: xyz2 - CalculateBarycenterDyn(pts, /*nbPts*/1, /*dim*/3, bary_3d); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0, bary_3d[0], 0.000001); // x - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, bary_3d[1], 0.000001); // y - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0, bary_3d[2], 0.000001); // z - } - - ///////////////////////// - // CalculateBarycenter // - ///////////////////////// - // template<int N, int DIM> inline void CalculateBarycenter(const double **pts, double *bary); - // template<> inline void CalculateBarycenter<2,0>(const double **pts, double *bary); - // template<> inline void CalculateBarycenter<3,0>(const double **pts, double *bary); - // template<> inline void CalculateBarycenter<4,0>(const double **pts, double *bary); - // template<> inline void CalculateBarycenter<5,0>(const double **pts, double *bary); - // template<> inline void CalculateBarycenter<6,0>(const double **pts, double *bary); - // template<> inline void CalculateBarycenter<7,0>(const double **pts, double *bary); - // template<> inline void CalculateBarycenter<8,0>(const double **pts, double *bary); - { - // five points - const double * pts[5] = {xyz2, xyz1, xyz3, xyz4, xyz5}; - double bary_3d[3]; - double bary_2d[2]; - - CalculateBarycenter<5,3>(pts, bary_3d); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0/5.0, bary_3d[0], 0.000001); // x - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0/5.0, bary_3d[1], 0.000001); // y - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0/5.0, bary_3d[2], 0.000001); // z - - CalculateBarycenter<5,2>(pts, bary_2d); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0/5.0, bary_2d[0], 0.000001); // x - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0/5.0, bary_2d[1], 0.000001); // y - - // one point: xyz2 : NOT IMPLEMENTED!!! - //CalculateBarycenter<1,3>(pts, bary_3d); - //CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0, bary_3d[0], 0.000001); - //CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, bary_3d[1], 0.000001); - //CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0, bary_3d[2], 0.000001); - } -} diff --git a/src/MEDMEM/Test/MEDMEMTest_GaussLocalization.cxx b/src/MEDMEM/Test/MEDMEMTest_GaussLocalization.cxx deleted file mode 100644 index d7b03d67a..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_GaussLocalization.cxx +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "MEDMEM_GaussLocalization.hxx" -#include "MEDMEM_STRING.hxx" - -#include <sstream> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; - -// #18: MEDMEM_GaussLocalization.hxx } MEDMEMTest.cxx - -/*! - * Check methods (13), defined in MEDMEM_GaussLocalization.hxx: - * class GAUSS_LOCALIZATION_ { - * (+) virtual MED_EN::medModeSwitch getInterlacingType() const; - * (+) virtual ~GAUSS_LOCALIZATION_(); - * } - * (+) template <class INTERLACING_TAG=FullInterlace> class GAUSS_LOCALIZATION; - * - * (+) template <class INTERLACING_TAG> ostream & operator<< - * (ostream &os, const GAUSS_LOCALIZATION<INTERLACING_TAG> &loc); - * - * template <class INTERLACING_TAG> class GAUSS_LOCALIZATION : public GAUSS_LOCALIZATION_ { - * (+) GAUSS_LOCALIZATION() throw (MEDEXCEPTION); - * (+) GAUSS_LOCALIZATION(const string & locName, - * const MED_EN::medGeometryElement typeGeo, - * const int nGauss, - * const ArrayNoGauss & cooRef, - * const ArrayNoGauss & cooGauss, - * const vector<double> & wg) throw (MEDEXCEPTION); - * (+) GAUSS_LOCALIZATION(const string & locName, - * const MED_EN::medGeometryElement typeGeo, - * const int nGauss, - * const double * const cooRef, - * const double * const cooGauss, - * const double * const wg) throw (MEDEXCEPTION); - * (+) virtual ~GAUSS_LOCALIZATION(); - * - * (+) GAUSS_LOCALIZATION & operator=(const GAUSS_LOCALIZATION & gaussLoc); - * (+) bool operator == (const GAUSS_LOCALIZATION &loc) const; - * - * (+) string getName() const; - * (+) MED_EN::medGeometryElement getType() const; - * - * (+) int getNbGauss() const; - * (+) ArrayNoGauss getRefCoo () const; - * (+) ArrayNoGauss getGsCoo () const; - * (+) vector <double> getWeight () const; - * - * (+) inline MED_EN::medModeSwitch getInterlacingType() const; - * } - */ -void MEDMEMTest::testGaussLocalization() -{ - // GAUSS_LOCALIZATION_ - GAUSS_LOCALIZATION_ aGL_; - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_UNDEFINED_INTERLACE, aGL_.getInterlacingType()); - - // GAUSS_LOCALIZATION empty constructor and InterlaceType - GAUSS_LOCALIZATION<> anEmptyGL1; - MED_EN::medModeSwitch aDefaultInterlaceType = anEmptyGL1.getInterlacingType(); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FULL_INTERLACE, aDefaultInterlaceType); - - GAUSS_LOCALIZATION<NoInterlace> anEmptyGL2; - MED_EN::medModeSwitch anInterlaceType2 = anEmptyGL2.getInterlacingType(); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_NO_INTERLACE, anInterlaceType2); - - // Construction from C++ arrays - double cooRef[6] = {1.,1., 2.,4., 3.,9.}; // xy xy xy - double cooGauss[10] = {7.,7., 6.,6., 5.,5., 4.,3., 2.,1.}; // x1,y1 x2,y2 x3,y3 x4,y4 x5,y5 - double wg[5] = {1., 2., 3., 4., 5.}; - - GAUSS_LOCALIZATION<> gl1 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef, cooGauss, wg); - GAUSS_LOCALIZATION<> gl2 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef, cooGauss, wg); - - // getXXX - CPPUNIT_ASSERT(gl1.getName() == "GL1"); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_TRIA3, gl1.getType()); - CPPUNIT_ASSERT_EQUAL(5, gl1.getNbGauss()); - - GAUSS_LOCALIZATION<>::ArrayNoGauss cooRefBack = gl1.getRefCoo(); - GAUSS_LOCALIZATION<>::ArrayNoGauss cooGaussBack = gl1.getGsCoo(); - vector<double> wgBack = gl1.getWeight(); - - double * cooRefBack_ptr = cooRefBack.getPtr(); - double * cooGaussBack_ptr = cooGaussBack.getPtr(); - - for (int i = 0; i < 10; i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL(cooRef[i%6], cooRefBack_ptr[i%6], 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(cooGauss[i], cooGaussBack_ptr[i], 0.000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(wg[i%5] , wgBack[i%5] , 0.000001); - } - - // Operators == and = - CPPUNIT_ASSERT(gl1 == gl2); - CPPUNIT_ASSERT_EQUAL(gl1, gl2); - - GAUSS_LOCALIZATION<> gl1_c; - gl1_c = gl1; - -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Badly copyed arrays as a result of operator= usage - CPPUNIT_ASSERT_EQUAL(gl1, gl1_c); - // Invalid read of size 8 - // at 0x342B157A: MEDMEM::MEDMEM_Array<double, MEDMEM::FullInterlaceNoGaussPolicy, MEDMEM::IndexCheckPolicy>::operator==(MEDMEM::MEDMEM_Array<double, MEDMEM::FullInterlaceNoGaussPolicy, MEDMEM::IndexCheckPolicy> const&) const (MEDMEM_nArray.hxx:255) - // by 0x342A1CDA: MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace>::operator==(MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace> const&) const (MEDMEM_GaussLocalization.hxx:175) - // by 0x34315F98: CppUnit::assertion_traits<MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace> >::equal(MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace> const&, MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace> const&) (TestAssert.h:40) - // by 0x34314D35: void CppUnit::assertEquals<MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace> >(MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace> const&, MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace> const&, CppUnit::SourceLine, std::string const&) (TestAssert.h:62) - // by 0x34311D6F: MEDMEMTest::testGaussLocalization() (MEDMEMTest_GaussLocalization.cxx:132) - // Address 0x35B5FC98 is 0 bytes inside a block of size 48 free'd - // at 0x3414CD61: operator delete[](void*) (vg_replace_malloc.c:161) - // by 0x341D88CA: MEDMEM::PointerOf<double>::~PointerOf() (MEDMEM_PointerOf.hxx:141) - // by 0x341D56C7: MEDMEM::MEDMEM_Array<double, MEDMEM::FullInterlaceNoGaussPolicy, MEDMEM::IndexCheckPolicy>::~MEDMEM_Array() (MEDMEM_nArray.hxx:52) - // by 0x34314F58: MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace>::operator=(MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace> const&) (MEDMEM_GaussLocalization.hxx:166) - // by 0x34311CCC: MEDMEMTest::testGaussLocalization() (MEDMEMTest_GaussLocalization.cxx:128) -#endif - - // same name, type and nb.gauss, but different coords or weights - double cooRef_ch[6] = {1.,1., 2.,8., 3.,9.}; - double cooGauss_ch[10] = {7.,8., 6.,6., 5.,5., 4.,3., 2.,1.}; - double wg_ch[5] = {1., 2., 8., 4., 5.}; - - GAUSS_LOCALIZATION<> gl3 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef_ch, cooGauss, wg); - GAUSS_LOCALIZATION<> gl4 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef, cooGauss_ch, wg); - GAUSS_LOCALIZATION<> gl5 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef, cooGauss, wg_ch); - - CPPUNIT_ASSERT(!(gl1 == gl3)); - CPPUNIT_ASSERT(!(gl1 == gl4)); - CPPUNIT_ASSERT(!(gl1 == gl5)); - - // different name or type, or nb.gauss - double cooRef_quad[8] = {1.,1., 2.,4., 3.,9., 4., 16.}; - double cooGauss_4[8] = {7.,8., 6.,6., 5.,5., 4.,3.}; - double wg_4[4] = {1., 2., 8., 4.}; - - GAUSS_LOCALIZATION<> gl6 ("GL6", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef, cooGauss, wg); - GAUSS_LOCALIZATION<> gl7 ("GL1", MED_EN::MED_QUAD4, /*nGauss*/5, cooRef_quad, cooGauss, wg); - GAUSS_LOCALIZATION<> gl8 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/4, cooRef, cooGauss_4, wg_4); - - CPPUNIT_ASSERT(!(gl1 == gl6)); - CPPUNIT_ASSERT(!(gl1 == gl7)); - CPPUNIT_ASSERT(!(gl1 == gl8)); - - // Operator << - ostringstream ostr1; - ostr1 << gl1; - CPPUNIT_ASSERT(ostr1.str() != ""); - - ostringstream ostr2; - ostr2 << gl2; - CPPUNIT_ASSERT_EQUAL(ostr1.str(), ostr2.str()); - - // Construction from ArrayNoGauss and vector<double> - GAUSS_LOCALIZATION<> gl9 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/5, cooRefBack, cooGaussBack, wgBack); - CPPUNIT_ASSERT(gl1 == gl9); - - // NoInterlace - double cooRef_ni[6] = {1.,2.,3., 1.,4.,9.}; // xxx yyy - double cooGauss_ni[10] = {7.,6.,5.,4.,2., 7.,6.,5.,3.,1.}; // x1,x2,x3,x4,x5 y1,y2,y3,y4,y5 - - GAUSS_LOCALIZATION<NoInterlace> gl10 ("GL10", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef_ni, cooGauss_ni, wg); - - GAUSS_LOCALIZATION<NoInterlace>::ArrayNoGauss cooRefBack_ni = gl10.getRefCoo(); - GAUSS_LOCALIZATION<NoInterlace>::ArrayNoGauss cooGaussBack_ni = gl10.getGsCoo(); - - for (int i = 1; i <= 3; i++) { // nb. nodes - for (int j = 1; j <= 2; j++) { // dim - CPPUNIT_ASSERT_DOUBLES_EQUAL(cooRefBack.getIJ(i, j), cooRefBack_ni.getIJ(i, j), 0.000001); - } - } - - for (int i = 1; i <= 5; i++) { // nGauss - for (int j = 1; j <= 2; j++) { // dim - CPPUNIT_ASSERT_DOUBLES_EQUAL(cooGaussBack.getIJ(i, j), cooGaussBack_ni.getIJ(i, j), 0.000001); - } - } -} diff --git a/src/MEDMEM/Test/MEDMEMTest_GibiMeshDriver.cxx b/src/MEDMEM/Test/MEDMEMTest_GibiMeshDriver.cxx deleted file mode 100644 index f5e7dd63b..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_GibiMeshDriver.cxx +++ /dev/null @@ -1,502 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include <MEDMEM_GibiMeshDriver.hxx> -#include <MEDMEM_Mesh.hxx> -#include <MEDMEM_Med.hxx> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -/*! - * Check methods (31), defined in MEDMEM_GibiMeshDriver.hxx: - * class GIBI_MESH_DRIVER : public GENDRIVER { - * (+) GIBI_MESH_DRIVER(); - * (+) GIBI_MESH_DRIVER(const string & fileName, MESH * ptrMesh, MED_EN::med_mode_acces accessMode); - * (+) GIBI_MESH_DRIVER(const GIBI_MESH_DRIVER & driver); - * (+) virtual ~GIBI_MESH_DRIVER(); - * (+) virtual void write(void) const = 0; - * (+) virtual void read (void) = 0; - * (+) void setMeshName(const string & meshName); - * (+) string getMeshName() const; - * (+) static MED_EN::medGeometryElement gibi2medGeom(size_t gibiTypeNb); - * (+) static int med2gibiGeom(MED_EN::medGeometryElement medGeomType); - * } - * class GIBI_MESH_RDONLY_DRIVER : public virtual GIBI_MESH_DRIVER { - * (+) GIBI_MESH_RDONLY_DRIVER(); - * (+) GIBI_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh); - * (+) GIBI_MESH_RDONLY_DRIVER(const GIBI_MESH_RDONLY_DRIVER & driver); - * (+) virtual ~GIBI_MESH_RDONLY_DRIVER(); - * (+) void write(void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void open(); - * (+) void close(); - * } - * class GIBI_MESH_WRONLY_DRIVER : public virtual GIBI_MESH_DRIVER { - * (+) GIBI_MESH_WRONLY_DRIVER(); - * (+) GIBI_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh); - * (+) GIBI_MESH_WRONLY_DRIVER(const GIBI_MESH_WRONLY_DRIVER & driver); - * (+) virtual ~GIBI_MESH_WRONLY_DRIVER(); - * (+) void write(void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void open(); - * (+) void close(); - * } - * class GIBI_MESH_RDWR_DRIVER : public GIBI_MESH_RDONLY_DRIVER, public GIBI_MESH_WRONLY_DRIVER { - * (+) GIBI_MESH_RDWR_DRIVER(); - * (+) GIBI_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh); - * (+) GIBI_MESH_RDWR_DRIVER(const GIBI_MESH_RDWR_DRIVER & driver); - * (+) ~GIBI_MESH_RDWR_DRIVER(); - * (+) void write(void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void open(); - * (+) void close(); - * } - * class GIBI_MED_RDONLY_DRIVER : public GIBI_MESH_RDONLY_DRIVER { - * (+) GIBI_MED_RDONLY_DRIVER(); - * (+) GIBI_MED_RDONLY_DRIVER(const string & fileName, MED * ptrMed); - * (+) GIBI_MED_RDONLY_DRIVER(const GIBI_MED_RDONLY_DRIVER & driver); - * (+) virtual ~GIBI_MED_RDONLY_DRIVER(); - * (+) void read (void) throw (MEDEXCEPTION); - * } - * class GIBI_MED_WRONLY_DRIVER : public GIBI_MESH_WRONLY_DRIVER { - * (+) GIBI_MED_WRONLY_DRIVER(); - * (+) GIBI_MED_WRONLY_DRIVER(const string & fileName, MED * ptrMed, MESH * ptrMesh); - * (+) GIBI_MED_WRONLY_DRIVER(const GIBI_MED_WRONLY_DRIVER & driver); - * (+) virtual ~GIBI_MED_WRONLY_DRIVER(); - * (+) void write(void) const throw (MEDEXCEPTION); - * } - */ - -void MEDMEMTest::testGibiMeshDriver() -{ - MESH *aMesh = new MESH(); - MESH *aMesh_NULL = NULL; - MESH *aMesh_2 = new MESH(); - MED *aMed = new MED(); - MED *aMed_1 = NULL; - - string data_dir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - - string filename_rd = data_dir + "/Sauv/Darcy3_3D_H_10x10x10.sauve"; - string filenamemed_rd = data_dir + "/Sauv/elle_3D_HPr_10x10x10.sauve"; - string filename_wr = tmp_dir + "/myWr_Darcy3_3D_H_10x10x10.sauve"; - string tmpfile = tmp_dir + "/tmp.sauve"; - string tmpfile_rdwr = tmp_dir + "/rdwr_tmp.sauve"; - string filenamemed_wr = tmp_dir + "/myWrMed_elle_3D_HPr_10x10x10.sauve"; - string tmpfilemed = tmp_dir + "/tmpmed.sauve"; - string meshname = "Darcy3_3D_H_10x10x10"; - string newmeshname = "new" + meshname; - string fileNotExistsName_rd = "notExists.sauve"; - string fileNotExistsName_wr = "/path_not_exists/file_not_exists.sauve"; - string filename_rdwr = tmp_dir + "/myRdWr_Darcy3_3D_H_10x10x10.sauve"; - string fcopy = "cp " + filename_rd + " " + filename_rdwr; - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filename_wr); - aRemover.Register(tmpfile); - aRemover.Register(tmpfilemed); - aRemover.Register(filenamemed_wr); - aRemover.Register(tmpfile_rdwr); - aRemover.Register(filename_rdwr); - - //Test gibi2medGeom() and med2gibiGeom() methods - size_t aSize = 17; - CPPUNIT_ASSERT_EQUAL(GIBI_MESH_DRIVER::gibi2medGeom(aSize), MED_PENTA15); - CPPUNIT_ASSERT_EQUAL(GIBI_MESH_DRIVER::med2gibiGeom(MED_PENTA15), 17); - - //---------------------------Test GIBI MESH READ ONLY part--------------------------------// - { - { - //Creation of an incorrect read only driver - GIBI_MESH_RDONLY_DRIVER *aInvalidGibiRdDriver = - new GIBI_MESH_RDONLY_DRIVER(fileNotExistsName_rd, aMesh); - - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidGibiRdDriver->open(), MEDEXCEPTION); - - delete aInvalidGibiRdDriver; - } - - //Creation a correct Gibi read only driver (normal constructor) - GIBI_MESH_RDONLY_DRIVER *aGibiRdDriver = - new GIBI_MESH_RDONLY_DRIVER(filename_rd, aMesh); - - //Check driver - CPPUNIT_ASSERT(aGibiRdDriver); - - //Trying read mesh from file, if file is not open - CPPUNIT_ASSERT_THROW(aGibiRdDriver->read(), MEDEXCEPTION); - - //Test open() method - CPPUNIT_ASSERT_NO_THROW(aGibiRdDriver->open()); - - //Trying open file secondary. -#ifdef ENABLE_FORCED_FAILURES - //This case is not work, seems it BUG - CPPUNIT_ASSERT_THROW(aGibiRdDriver->open(), MEDEXCEPTION); -#endif - - //Test setMeshName() and getMeshName() methods - CPPUNIT_ASSERT_NO_THROW(aGibiRdDriver->setMeshName(meshname)); - CPPUNIT_ASSERT_EQUAL(meshname, aGibiRdDriver->getMeshName()); - - //Test read() method - CPPUNIT_ASSERT_NO_THROW(aGibiRdDriver->read()); - // Source and destination overlap in memcpy(0x35DBF040, 0x35DBF06D, 101) - // at 0x3414D97E: memcpy (mac_replace_strmem.c:113) - // by 0x3492EDE9: MEDMEM::GIBI_MESH_RDONLY_DRIVER::getLine(char*&) (MEDMEM_GibiMeshDriver.cxx:942) - // by 0x349407FD: MEDMEM::GIBI_MESH_RDONLY_DRIVER::getNextLine(char*&, bool) (MEDMEM_GibiMeshDriver.hxx:168) - // by 0x349268B1: MEDMEM::GIBI_MESH_RDONLY_DRIVER::readFile(MEDMEM::_intermediateMED*, bool) (MEDMEM_GibiMeshDriver.cxx:209) - // by 0x3492F58B: MEDMEM::GIBI_MESH_RDONLY_DRIVER::read() (MEDMEM_GibiMeshDriver.cxx:1058) - // by 0x3436DEA6: MEDMEMTest::testGibiMeshDriver() (MEDMEMTest_GibiMeshDriver.cxx:168) - - //Trying fill not empty mesh - CPPUNIT_ASSERT_THROW(aGibiRdDriver->read(), MEDEXCEPTION); - - //Test write() method for GIBI READ ONLY driver - CPPUNIT_ASSERT_THROW(aGibiRdDriver->write(), MEDEXCEPTION); - - //Check Mesh - CPPUNIT_ASSERT(aMesh); - - //Test close method - CPPUNIT_ASSERT_NO_THROW(aGibiRdDriver->close()); - - //Default constructor - { - GIBI_MESH_RDONLY_DRIVER aGibiRdDriverCpy_1; - } - - //Test copy constructor and operator==(), defined in GENDRIVER class - { - GIBI_MESH_RDONLY_DRIVER aGibiRdDriverCpy_2 (*aGibiRdDriver); - CPPUNIT_ASSERT(aGibiRdDriverCpy_2.GENDRIVER::operator==(*aGibiRdDriver)); - - //Test (friend ostream & operator <<) defined GENDRIVER class - ostringstream rostr1, rostr2; - rostr1 << *aGibiRdDriver; - rostr2 << aGibiRdDriverCpy_2; - CPPUNIT_ASSERT(rostr1.str() != ""); - CPPUNIT_ASSERT(rostr1.str() == rostr2.str()); - } - - delete aGibiRdDriver; - } - - //-------------------------------Test GIBI WRITE ONLY part------------------------------// - { - { - //Creation a incorrect gibi write only driver - GIBI_MESH_WRONLY_DRIVER *aInvalidGibiWrDriver = - new GIBI_MESH_WRONLY_DRIVER(fileNotExistsName_wr, aMesh); - - //Trying open non existing file - CPPUNIT_ASSERT_THROW(aInvalidGibiWrDriver->open(), MEDEXCEPTION); - - delete aInvalidGibiWrDriver; - } - - //Trying write empty mesh - { - GIBI_MESH_WRONLY_DRIVER *aTmpGibiWrDriver = - new GIBI_MESH_WRONLY_DRIVER(tmpfile, aMesh_NULL); - aTmpGibiWrDriver->open(); - - CPPUNIT_ASSERT_THROW(aTmpGibiWrDriver->write(),MEDEXCEPTION); - aTmpGibiWrDriver->close(); - - delete aTmpGibiWrDriver; - } - - //Creation a correct gibi write only drivers - GIBI_MESH_WRONLY_DRIVER *aGibiWrDriver = - new GIBI_MESH_WRONLY_DRIVER(filename_wr, aMesh); - - //Check driver - CPPUNIT_ASSERT(aGibiWrDriver); - - //Trying write mesh to file, if file is not open - CPPUNIT_ASSERT_THROW(aGibiWrDriver->write(), MEDEXCEPTION); - - //Test open() method - CPPUNIT_ASSERT_NO_THROW(aGibiWrDriver->open()); - - //Trying open file secondary. -#ifdef ENABLE_FORCED_FAILURES - // (BUG) No exception on attempt to open an opened file for the second time - CPPUNIT_ASSERT_THROW(aGibiWrDriver->open(), MEDEXCEPTION); -#endif - - //Test setMeshName() and getMeshName() methods - CPPUNIT_ASSERT_NO_THROW(aGibiWrDriver->setMeshName(newmeshname)); - CPPUNIT_ASSERT_EQUAL(newmeshname, aGibiWrDriver->getMeshName()); - - //Test write() method - CPPUNIT_ASSERT_NO_THROW(aGibiWrDriver->write()); - - //Test read() method for GIBI WRITE ONLY driver - CPPUNIT_ASSERT_THROW(aGibiWrDriver->read(), MEDEXCEPTION); - - //Test close method - CPPUNIT_ASSERT_NO_THROW(aGibiWrDriver->close()); - - //Default constructor - GIBI_MESH_WRONLY_DRIVER aGibiWrDriverCpy_1; - - //Test copy constructor - GIBI_MESH_WRONLY_DRIVER aGibiWrDriverCpy_2 (*aGibiWrDriver); - - //Test (bool operator ==) defined GENDRIVER class - CPPUNIT_ASSERT(aGibiWrDriverCpy_2.GENDRIVER::operator==(*aGibiWrDriver)); - - //Test (friend ostream & operator <<) defined GENDRIVER class - ostringstream wostr1, wostr2; - wostr1 << *aGibiWrDriver; - wostr2 << aGibiWrDriverCpy_2; - CPPUNIT_ASSERT(wostr1.str() != ""); - CPPUNIT_ASSERT(wostr1.str() == wostr2.str()); - - delete aGibiWrDriver; - } - - //-------------------------------Test GIBI READ/WRITE part---------------------------------// - { - //Copy file - system(fcopy.c_str()); - - { - //Creation a incorrect gibi read/write driver - GIBI_MESH_RDWR_DRIVER *aInvalidGibiRdWrDriver = - new GIBI_MESH_RDWR_DRIVER(fileNotExistsName_wr, aMesh_2); - - //Trying read/write from not existing file - CPPUNIT_ASSERT_THROW(aInvalidGibiRdWrDriver->read(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aInvalidGibiRdWrDriver->write(), MEDEXCEPTION); - - delete aInvalidGibiRdWrDriver; - } - - //Trying write empty mesh - { - GIBI_MESH_RDWR_DRIVER *aTmpGibiRdWrDriver = - new GIBI_MESH_RDWR_DRIVER(tmpfile_rdwr, aMesh_NULL); - CPPUNIT_ASSERT_THROW(aTmpGibiRdWrDriver->write(), MEDEXCEPTION); - delete aTmpGibiRdWrDriver; - } - - //Creation a correct read/write driver - GIBI_MESH_RDWR_DRIVER *aGibiRdWrDriver = - new GIBI_MESH_RDWR_DRIVER(filename_rdwr, aMesh_2); - - //Test open/close methods - CPPUNIT_ASSERT_NO_THROW(aGibiRdWrDriver->open()); - CPPUNIT_ASSERT_NO_THROW(aGibiRdWrDriver->close()); - - //Check driver - CPPUNIT_ASSERT(aGibiRdWrDriver); - - //Test read() method - CPPUNIT_ASSERT_NO_THROW(aGibiRdWrDriver->read()); - - //Check Mesh - CPPUNIT_ASSERT(aMesh); - - //Trying fill not empty mesh - CPPUNIT_ASSERT_THROW(aGibiRdWrDriver->read(),MEDEXCEPTION); - - //Test write() method - aGibiRdWrDriver->setMeshName(newmeshname); - CPPUNIT_ASSERT_NO_THROW(aGibiRdWrDriver->write()); - - //Default constructor - GIBI_MESH_RDWR_DRIVER aGibiRdWrDriverCpy_1; - - //Test copy constructor - GIBI_MESH_RDWR_DRIVER aGibiRdWrDriverCpy_2 (*aGibiRdWrDriver); - - //Test (bool operator ==) - CPPUNIT_ASSERT(aGibiRdWrDriverCpy_2.GENDRIVER::operator==(*aGibiRdWrDriver)); - - //Test (ostream & operator <<) - ostringstream rwostr1, rwostr2; - rwostr1 << *aGibiRdWrDriver; - rwostr2 << aGibiRdWrDriverCpy_2; - CPPUNIT_ASSERT(rwostr1.str() != ""); - CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - delete aGibiRdWrDriver; - } - - //----------------------------Test GIBI_MED_RDONLY_DRIVER---------------------------- - { - { - GIBI_MED_RDONLY_DRIVER *aInvalidMedGibiRdDriver = - new GIBI_MED_RDONLY_DRIVER(fileNotExistsName_rd, aMed); - - //Trying open not exising file - CPPUNIT_ASSERT_THROW(aInvalidMedGibiRdDriver->open(), MEDEXCEPTION); - - delete aInvalidMedGibiRdDriver; - } - - //Creation a correct Gibi read only driver (normal constructor) - GIBI_MED_RDONLY_DRIVER *aGibiMedRdDriver = - new GIBI_MED_RDONLY_DRIVER(filenamemed_rd, aMed); - - //Check driver - CPPUNIT_ASSERT(aGibiMedRdDriver); - - //Trying read mesh from file, if file is not open - CPPUNIT_ASSERT_THROW(aGibiMedRdDriver->read(), MEDEXCEPTION); - - //Test open() method - CPPUNIT_ASSERT_NO_THROW(aGibiMedRdDriver->open()); - -#ifdef ENABLE_FORCED_FAILURES - //Trying open file secondary. - CPPUNIT_ASSERT_THROW(aGibiMedRdDriver->open(), MEDEXCEPTION); - //This case is not work, seems it BUG -#endif - - //Test read() method - CPPUNIT_ASSERT_NO_THROW(aGibiMedRdDriver->read()); - - //Test write() method for GIBI MED READ ONLY driver - CPPUNIT_ASSERT_THROW(aGibiMedRdDriver->write(), MEDEXCEPTION); - - //Check Med - CPPUNIT_ASSERT(aMed); - - //Test close method - CPPUNIT_ASSERT_NO_THROW(aGibiMedRdDriver->close()); - - //Default constructor - GIBI_MED_RDONLY_DRIVER aGibiMedRdDriverCpy_1; - - //Test (bool operator ==) defined in GENDRIVER class - CPPUNIT_ASSERT(! aGibiMedRdDriverCpy_1.GENDRIVER::operator==(*aGibiMedRdDriver)); - - //Test copy constructor - GIBI_MED_RDONLY_DRIVER aGibiMedRdDriverCpy_2 (*aGibiMedRdDriver); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Copy constructor of GIBI_MED_RDONLY_DRIVER is not implemented - CPPUNIT_ASSERT(aGibiMedRdDriverCpy_2.GENDRIVER::operator==(*aGibiMedRdDriver)); -#endif - - //Test (friend ostream & operator <<) defined in GENDRIVER class - ostringstream medrostr1, medrostr2; - medrostr1 << *aGibiMedRdDriver; - medrostr2 << aGibiMedRdDriverCpy_2; - CPPUNIT_ASSERT(medrostr1.str() != ""); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Copy constructor of GIBI_MED_RDONLY_DRIVER is not implemented - CPPUNIT_ASSERT(medrostr1.str() == medrostr2.str()); -#endif - - delete aGibiMedRdDriver; - } - - //----------------------------Test GIBI MED WRITE ONLY part----------------------------------// - { - { - //Creation a incorrect gibi med write only driver - GIBI_MED_WRONLY_DRIVER *aInvalidGibiMedWrDriver = - new GIBI_MED_WRONLY_DRIVER(fileNotExistsName_wr, aMed, aMesh); - - //Trying open non existing file - CPPUNIT_ASSERT_THROW(aInvalidGibiMedWrDriver->open(), MEDEXCEPTION); - - delete aInvalidGibiMedWrDriver; - } - - //Trying create gibi med write only driver with null MED and MESH - CPPUNIT_ASSERT_THROW(new GIBI_MED_WRONLY_DRIVER(tmpfilemed, aMed_1, aMesh_NULL), MEDEXCEPTION); - - //Creation a correct gibi med write only drivers - GIBI_MED_WRONLY_DRIVER *aGibiMedWrDriver = - new GIBI_MED_WRONLY_DRIVER(filenamemed_wr, aMed, aMesh); - - //Check driver - CPPUNIT_ASSERT(aGibiMedWrDriver); - - //Trying write mesh to file, if file is not open - CPPUNIT_ASSERT_THROW(aGibiMedWrDriver->write(), MEDEXCEPTION); - - //Test open() method - CPPUNIT_ASSERT_NO_THROW(aGibiMedWrDriver->open()); - - //Trying open file secondary. -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Exception is generated, but second call to open() function breaks driver - CPPUNIT_ASSERT_THROW(aGibiMedWrDriver->open(), MEDEXCEPTION); -#endif - - //Test write() method - CPPUNIT_ASSERT_NO_THROW(aGibiMedWrDriver->write()); - - //Test read() method for GIBI MED WRITE ONLY driver - CPPUNIT_ASSERT_THROW(aGibiMedWrDriver->read(), MEDEXCEPTION); - - //Test close method - CPPUNIT_ASSERT_NO_THROW(aGibiMedWrDriver->close()); - - //Default constructor - GIBI_MED_WRONLY_DRIVER aGibiMedWrDriverCpy_1; - - //Test copy constructor - { - GIBI_MED_WRONLY_DRIVER aGibiMedWrDriverCpy_2 (*aGibiMedWrDriver); - - //Test (bool operator ==) defined in GENDRIVER class -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Copy constructor of GIBI_MED_WRONLY_DRIVER is not implemented!!! - CPPUNIT_ASSERT(aGibiMedWrDriverCpy_2.GENDRIVER::operator==(*aGibiMedWrDriver)); -#endif - - //Test (friend ostream & operator <<) defined GENDRIVER class - ostringstream medwostr1, medwostr2; - medwostr1 << *aGibiMedWrDriver; - medwostr2 << aGibiMedWrDriverCpy_2; - CPPUNIT_ASSERT(medwostr1.str() != ""); -#ifdef ENABLE_FORCED_FAILURES - // Copy constructor of GIBI_MED_WRONLY_DRIVER is not implemented!!! - CPPUNIT_ASSERT(medwostr1.str() == medwostr2.str()); -#endif - } - - delete aGibiMedWrDriver; - } - - //Delete all objects - delete aMesh; - delete aMesh_2; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_Grid.cxx b/src/MEDMEM/Test/MEDMEMTest_Grid.cxx deleted file mode 100644 index 204b99cfc..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Grid.cxx +++ /dev/null @@ -1,696 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "MEDMEM_define.hxx" -#include "MEDMEM_Grid.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Med.hxx" -#include "MEDMEM_MedMedDriver.hxx" -#include "MEDMEM_MedMeshDriver.hxx" - -#include <sstream> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - - -/*! - * Check methods (44), defined in MEDMEM_Grid.hxx: - * class GRID: public MESH { - * (+) GRID(); - * (+) GRID(const MED_EN::med_grid_type type); - * (BUG:operator=() not implemented but init() not called) GRID(const GRID &m); - * (+) GRID(driverTypes driverType, const string & fileName="",const string & meshName=""); - * (+) GRID(const std::vector<std::vector<double> >& xyz_array, - * const std::vector<std::string>& coord_name, - * const std::vector<std::string>& coord_unit, - * const MED_EN::med_grid_type type=MED_EN::MED_CARTESIAN); - * (NOT IMPLEMENTED) GRID & operator=(const GRID &m); - * (+) virtual ~GRID(); - * (+) virtual void init(); - * (tested together with getCoordinateptr() as it is called - * internally from there first of all. - * Moreover, fillCoordinates should be made private to avoid - * ambiguity druing in GRID class usage.) void fillCoordinates() const; - * (tested together with getConnectivityptr()) void fillConnectivity() const; - * (+) inline void makeUnstructured();//fill coordinates and connectivity of MESH - * (+) void fillMeshAfterRead(); - * (+) void writeUnstructured(int index=0, const string & driverName = ""); - * (+) void read(int index=0); - * (+) inline int getNodeNumber(const int i, const int j=0, const int k=0) const; - * (+) inline int getCellNumber(const int i, const int j=0, const int k=0) const; - * (+) int getEdgeNumber - * (const int Axis, const int i, const int j=0, const int k=0) const throw (MEDEXCEPTION); - * (+) int getFaceNumber - * (const int Axis, const int i, const int j=0, const int k=0) const throw (MEDEXCEPTION); - * (+) void getNodePosition(const int Number, int& i, int& j, int& k) const throw (MEDEXCEPTION); - * (+) void getCellPosition(const int Number, int& i, int& j, int& k) const throw (MEDEXCEPTION); - * (+) void getEdgePosition - * (const int Number, int& Axis, int& i, int& j, int& k) const throw (MEDEXCEPTION); - * (+) void getFacePosition - * (const int Number, int& Axis, int& i, int& j, int& k) const throw (MEDEXCEPTION); - * (+) inline MED_EN::med_grid_type getGridType() const; - * (+) int getArrayLength(const int Axis) const throw (MEDEXCEPTION); - * (+) const double getArrayValue (const int Axis, const int i) const throw (MEDEXCEPTION); - * (+) inline const COORDINATE * getCoordinateptr() const; - * (+) inline const double * getCoordinates(MED_EN::medModeSwitch Mode) const; - * (+) inline const double getCoordinate(int Number,int Axis) const; - * (+) inline int getNumberOfTypes(MED_EN::medEntityMesh Entity) const; - * (+) inline int getNumberOfTypesWithPoly(MED_EN::medEntityMesh Entity) const; - * (+) inline const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const; - * (+) MED_EN::medGeometryElement * getTypesWithPoly(MED_EN::medEntityMesh Entity) const; - * (+) inline const CELLMODEL * getCellsTypes(MED_EN::medEntityMesh Entity) const; - * (+) const int * getGlobalNumberingIndex(MED_EN::medEntityMesh Entity) const; - * (+) inline int getNumberOfElements - * (MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type) const; - * (+) inline int getNumberOfElementsWithPoly - * (MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type) const; - * (+) inline bool existConnectivity - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; - * (+) inline MED_EN::medGeometryElement getElementType - * (MED_EN::medEntityMesh Entity, int Number) const; - * (+) inline MED_EN::medGeometryElement getElementTypeWithPoly - * (MED_EN::medEntityMesh Entity, int Number) const; - * (+) inline void calculateConnectivity(MED_EN::medModeSwitch Mode, - * MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity) const; - * (+) inline const CONNECTIVITY* getConnectivityptr() const; - * (+) inline const int * getConnectivity - * (MED_EN::medModeSwitch Mode, MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type) const; - * (+) inline const int * getConnectivityIndex(MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity) const; - * (+) inline const int * getReverseConnectivity(MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; - * (+) inline const int * getReverseConnectivityIndex(MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; - * (+) inline void setGridType(MED_EN::med_grid_type gridType); - * } - */ -void MEDMEMTest::testGrid() -{ - string datadir = getenv("DATA_DIR"); - string filename = datadir + "/MedFiles/test19.med" ; - string tmp_dir = getenv("TMP"); - if (tmp_dir == "") - tmp_dir = "/tmp"; - string filenameout21 = tmp_dir + "/myGridWrite_grid21.med"; - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filenameout21); - - // Remove file in advance to ensure it does not exist at the moment of writing, - // because files are not removed by the MEDMEMTest_TmpFilesRemover in case of - // Segmentation Fault (in previous tests execution). - { - MEDMEMTest_TmpFilesRemover aRemover1; - aRemover1.Register(filenameout21); - } - - MED * myMed = new MED() ; - MED_MED_RDONLY_DRIVER myMeshDriver (filename, myMed); - myMeshDriver.open(); - myMeshDriver.readFileStruct(); - myMeshDriver.close(); - - int nbMeshes = myMed->getNumberOfMeshes(); - CPPUNIT_ASSERT(nbMeshes); - - deque<string> mesh_names = myMed->getMeshNames(); - CPPUNIT_ASSERT(mesh_names.size() != 0); - - ////////////////////////////// - // test1 "CARTESIAN GRID" // - ////////////////////////////// - { - MESH* myMesh = myMed->getMesh(mesh_names[0]); - myMesh->read(); - - CPPUNIT_ASSERT(myMesh != NULL); - CPPUNIT_ASSERT(myMesh->getIsAGrid()); - - GRID* myGrid = dynamic_cast<GRID*>(myMesh); - CPPUNIT_ASSERT(myGrid); - - CPPUNIT_ASSERT_THROW(myGrid->getArrayLength(0), MEDEXCEPTION); - - int I, J, K; - CPPUNIT_ASSERT_NO_THROW(I = myGrid->getArrayLength(1)); - CPPUNIT_ASSERT_NO_THROW(J = myGrid->getArrayLength(2)); - CPPUNIT_ASSERT_NO_THROW(K = myGrid->getArrayLength(3)); - - CPPUNIT_ASSERT(I); - CPPUNIT_ASSERT(J); - - med_grid_type grid_type = myGrid->getGridType(); - CPPUNIT_ASSERT_MESSAGE("Wrong grid type", grid_type == MED_CARTESIAN); - - const double * coordinates = myGrid->getCoordinates(MED_FULL_INTERLACE); - int SpaceDimension = myGrid->getSpaceDimension(); - for (int axe = 0; axe < SpaceDimension; axe++) { - for (int num = 0; num < myGrid->getNumberOfNodes(); num++) { - double coordinate; - CPPUNIT_ASSERT_NO_THROW(coordinate = myGrid->getCoordinate(num + 1, axe + 1)); - //cout << "coordinate = " << coordinate << endl; - CPPUNIT_ASSERT(fabs(coordinate - coordinates[(num * SpaceDimension)+axe]) < 0.001); - } - } - - int nbTypesCell = myGrid->getNumberOfTypes(MED_CELL); - CPPUNIT_ASSERT(nbTypesCell == 1); - - const medGeometryElement* types; - CPPUNIT_ASSERT_NO_THROW(types = myGrid->getTypes(MED_CELL)); -#ifdef ENABLE_FORCED_FAILURES - // Compilation warning about GRID::getTypes(): - // "inline function - // `virtual const MED_EN::medGeometryElement* MEDMEM::GRID::getTypes(MED_EN::medEntityMesh) const' - // used but never defined". - // In MEDMEM_Grid.hxx: - // inline const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const; - // But implemented in MEDMEM_Grid.cxx: - // const MED_EN::medGeometryElement * GRID::getTypes(MED_EN::medEntityMesh entity) const - CPPUNIT_FAIL("Problem with GRID::getTypes() method implementation."); -#endif - CPPUNIT_ASSERT(types[0] == MED_QUAD4); - - int nbElem = 0; - CPPUNIT_ASSERT_NO_THROW(nbElem = myGrid->getNumberOfElements(MED_CELL,types[0])); - CPPUNIT_ASSERT(nbElem); - - int nbNodes = myGrid->getNumberOfNodes(); - CPPUNIT_ASSERT(nbNodes); - - int ijkNode[3]; - int NodeNumber; - for (int nbNode = 1; nbNode <= nbNodes; nbNode++) { - CPPUNIT_ASSERT_NO_THROW(myGrid->getNodePosition(nbNode, ijkNode[0], ijkNode[1], ijkNode[2])); - CPPUNIT_ASSERT_NO_THROW(NodeNumber = myGrid->getNodeNumber(ijkNode[0], ijkNode[1], ijkNode[2])); - CPPUNIT_ASSERT(NodeNumber == nbNode); - } - - int nbCells = myGrid->getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS); - CPPUNIT_ASSERT(nbCells); - - int ijkCell[3]; - int CellNumber; - for (int nbCell = 1; nbCell <= nbCells; nbCell++) { - CPPUNIT_ASSERT_NO_THROW(myGrid->getCellPosition(nbCell, ijkCell[0], ijkCell[1], ijkCell[2])); - CPPUNIT_ASSERT_NO_THROW(CellNumber = myGrid->getCellNumber(ijkCell[0], ijkCell[1], ijkCell[2])); - CPPUNIT_ASSERT(CellNumber == nbCell); - } - - int nbEdges = myGrid->getNumberOfElements(MED_EDGE, MED_ALL_ELEMENTS); - CPPUNIT_ASSERT(nbEdges); - - int ijkAxisEdge[4]; - int EdgeNumber; - for (int nbEdge = 1; nbEdge <= nbEdges; nbEdge++) { - CPPUNIT_ASSERT_NO_THROW(myGrid->getEdgePosition(nbEdge, ijkAxisEdge[0], ijkAxisEdge[1], - ijkAxisEdge[2], ijkAxisEdge[3])); - CPPUNIT_ASSERT_NO_THROW(EdgeNumber = myGrid->getEdgeNumber(ijkAxisEdge[0], ijkAxisEdge[1], - ijkAxisEdge[2], ijkAxisEdge[3])); - CPPUNIT_ASSERT(EdgeNumber == nbEdge); - } - - int nbFaces = myGrid->getNumberOfElements(MED_FACE, MED_ALL_ELEMENTS); - CPPUNIT_ASSERT(nbFaces == 0); - -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("ERROR: nbFaces == 0, but getFacePosition(AnyNumber, ...) - return position(i,j,k)"); -#endif - int ijkAxisFace[4]; - CPPUNIT_ASSERT_NO_THROW(myGrid->getFacePosition(6, ijkAxisFace[0], ijkAxisFace[1], - ijkAxisFace[2], ijkAxisFace[3])); - CPPUNIT_ASSERT(ijkAxisFace[0]); - CPPUNIT_ASSERT(ijkAxisFace[1]); - CPPUNIT_ASSERT(ijkAxisFace[2]); - - /*int FaceNumber; - for(int nbFace = 1; nbFace <= nbFaces; nbFace++) - { - CPPUNIT_ASSERT_NO_THROW( myGrid->getFacePosition(nbFace, ijkAxisFace[0], ijkAxisFace[1], - ijkAxisFace[2], ijkAxisFace[3])); - CPPUNIT_ASSERT_NO_THROW( EdgeNumber = myGrid->getEdgeNumber(ijkAxisFace[0], ijkAxisFace[1], - ijkAxisFace[2], ijkAxisFace[3])); - CPPUNIT_ASSERT(FaceNumber == nbFace); - }*/ - - bool existConnect = false; - CPPUNIT_ASSERT_NO_THROW(existConnect = myGrid->existConnectivity(MED_NODAL, MED_CELL)); - if (!existConnect) { - CPPUNIT_ASSERT_NO_THROW(myGrid->calculateConnectivity(MED_FULL_INTERLACE, MED_NODAL, MED_CELL)); - CPPUNIT_ASSERT(myGrid->existConnectivity(MED_NODAL, MED_CELL)); - } - - const int* Connectivity; - const int* connectivity_index; - CPPUNIT_ASSERT_NO_THROW(Connectivity = myGrid->getConnectivity(MED_FULL_INTERLACE, MED_NODAL, - MED_CELL, types[0])); - CPPUNIT_ASSERT_NO_THROW(connectivity_index = myGrid->getConnectivityIndex(MED_NODAL, MED_CELL)); - cout << "Nodal connectivity" << endl; - for (int j = 0; j < nbElem; j++) { - cout << "Element "<< j+1 << " : "; - for (int k = connectivity_index[j]; k < connectivity_index[j+1]; k++) - cout << Connectivity[k-1] << " "; - cout << endl; - } - - const int * ReverseNodalConnectivity; - const int * ReverseConnectivityIndex; - CPPUNIT_ASSERT_NO_THROW(ReverseNodalConnectivity = myGrid->getReverseConnectivity(MED_NODAL)); - CPPUNIT_ASSERT_NO_THROW(ReverseConnectivityIndex = myGrid->getReverseConnectivityIndex(MED_NODAL)); - for (int i = 0; i < nbNodes; i++) { - cout << "Node "<< i+1 << " : "; - for (int j = ReverseConnectivityIndex[i]; j < ReverseConnectivityIndex[i+1]; j++) - cout << ReverseNodalConnectivity[j-1] << " "; - cout << endl; - } - - const int* myGlobalNbIdx; - CPPUNIT_ASSERT_NO_THROW(myGlobalNbIdx = myGrid->getGlobalNumberingIndex(MED_CELL)); - for (int i = 0; i <= nbTypesCell; i++) { - if (i == nbTypesCell) { - CPPUNIT_ASSERT_THROW(myGrid->getElementType(MED_CELL, myGlobalNbIdx[i]), MEDEXCEPTION); - break; - } - medGeometryElement aElem, geomPolyElem; - CPPUNIT_ASSERT_NO_THROW(aElem = myGrid->getElementType(MED_CELL, myGlobalNbIdx[i])); - CPPUNIT_ASSERT_NO_THROW(geomPolyElem = myGrid->getElementTypeWithPoly(MED_CELL, myGlobalNbIdx[i])); - CPPUNIT_ASSERT(types[0] == aElem); - CPPUNIT_ASSERT(geomPolyElem == aElem); - } - - CPPUNIT_ASSERT_NO_THROW(existConnect = myGrid->existConnectivity(MED_DESCENDING, MED_CELL)); - if (!existConnect) { - CPPUNIT_ASSERT_NO_THROW(myGrid->calculateConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, MED_CELL)); - CPPUNIT_ASSERT(myGrid->existConnectivity(MED_DESCENDING, MED_CELL)); - } - - const int* ConnectivityDes; - const int* connectivity_index_des; - CPPUNIT_ASSERT_NO_THROW(ConnectivityDes = myGrid->getConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, - MED_CELL, MED_ALL_ELEMENTS)); - CPPUNIT_ASSERT_NO_THROW(connectivity_index_des = - myGrid->getConnectivityIndex(MED_DESCENDING, MED_CELL)); - cout<<"Descending connectivity"<<endl; - for (int j = 0; j < nbElem; j++) { - cout << "Element "<< j+1 << " : "; - for (int k = connectivity_index_des[j]; k < connectivity_index_des[j+1]; k++) - cout << ConnectivityDes[k-1] << " "; - cout << endl; - } - - const int * ReverseDesConnectivity; - const int * ReverseConnectivityIndexDes; - CPPUNIT_ASSERT_NO_THROW(ReverseDesConnectivity = myGrid->getReverseConnectivity(MED_DESCENDING)); - CPPUNIT_ASSERT_NO_THROW(ReverseConnectivityIndexDes = - myGrid->getReverseConnectivityIndex(MED_DESCENDING)); - for (int i = 0; i < nbNodes; i++) { - cout << "Node "<< i+1 << " : "; - for (int j = ReverseConnectivityIndexDes[i]; j < ReverseConnectivityIndexDes[i+1]; j++) - cout << ReverseDesConnectivity[j-1] << " "; - cout << endl; - } - - //TEST POLY - { - int nbPolytypes; - //test getNumberOfTypesWithPoly() - a grid has one type - CPPUNIT_ASSERT_NO_THROW(nbPolytypes = myGrid->getNumberOfTypesWithPoly(MED_CELL)); - CPPUNIT_ASSERT(nbPolytypes == 1 ); - - const MED_EN::medGeometryElement * PolyTypes, *Types; - CPPUNIT_ASSERT_NO_THROW(PolyTypes = myGrid->getTypesWithPoly(MED_CELL)); - CPPUNIT_ASSERT_NO_THROW(Types = myGrid->getTypes(MED_CELL)); - CPPUNIT_ASSERT_EQUAL(PolyTypes[nbPolytypes-1],Types[nbPolytypes-1]); - - for (int t = 0; t < nbPolytypes; t++) { - int nbElPoly, nbEl; - CPPUNIT_ASSERT_NO_THROW(nbElPoly = myGrid->getNumberOfElementsWithPoly(MED_CELL, PolyTypes[t])); - CPPUNIT_ASSERT_NO_THROW(nbEl = myGrid->getNumberOfElements(MED_CELL, PolyTypes[t])); - CPPUNIT_ASSERT(nbElPoly == nbEl); - } - } - } - - ////////////////////////////// - // test2 "MED_BODY_FITTED" // - ////////////////////////////// - { - MESH* myMesh1 = myMed->getMesh(mesh_names[1]); - myMesh1->read(); - - CPPUNIT_ASSERT(myMesh1 != NULL); - CPPUNIT_ASSERT(myMesh1->getIsAGrid()); - - GRID* myGrid1 = dynamic_cast<GRID*>(myMesh1); - CPPUNIT_ASSERT(myGrid1); - - int I, J, K; - CPPUNIT_ASSERT_NO_THROW(I = myGrid1->getArrayLength(1)); - CPPUNIT_ASSERT_NO_THROW(J = myGrid1->getArrayLength(2)); - CPPUNIT_ASSERT_NO_THROW(K = myGrid1->getArrayLength(3)); - - CPPUNIT_ASSERT(I == 2); - CPPUNIT_ASSERT(J == 2); - - med_grid_type grid_type = myGrid1->getGridType(); - CPPUNIT_ASSERT_MESSAGE("Wrong grid type", grid_type == MED_BODY_FITTED); - - int nbTypesCell = myGrid1->getNumberOfTypes(MED_CELL); - CPPUNIT_ASSERT(nbTypesCell == 1); - - const medGeometryElement* types1; - CPPUNIT_ASSERT_NO_THROW( types1 = myGrid1->getTypes(MED_CELL) ); - CPPUNIT_ASSERT( types1[0] == MED_QUAD4); - - int nbElem; - CPPUNIT_ASSERT_NO_THROW(nbElem = myGrid1->getNumberOfElements(MED_CELL, types1[0])); - CPPUNIT_ASSERT(nbElem); - - const int* BodyConnectivity; - const int* body_connectivity_index; - int ijkNodeBody[3]; - CPPUNIT_ASSERT_NO_THROW(BodyConnectivity = myGrid1->getConnectivity(MED_FULL_INTERLACE, MED_NODAL, - MED_CELL, types1[0])); - CPPUNIT_ASSERT_NO_THROW(body_connectivity_index = myGrid1->getConnectivityIndex(MED_NODAL, MED_CELL)); - cout<<"Nodal connectivity"<<endl; - for (int j = 0; j < nbElem; j++) { - cout << "Element "<< j+1 << " : "; - for (int k = body_connectivity_index[j]; k < body_connectivity_index[j+1]; k++){ - CPPUNIT_ASSERT_NO_THROW(myGrid1->getNodePosition(BodyConnectivity[k-1], ijkNodeBody[0], - ijkNodeBody[1], ijkNodeBody[2])); - cout << BodyConnectivity[k-1] << " "; - } - cout << endl; - } - } - - /////////////////////////////////////////////////// - // test3 "maa1" which in fact is not a pure GRID // - /////////////////////////////////////////////////// - { - MESH* myMesh2 = NULL; - - myMesh2 = myMed->getMesh(mesh_names[2]); - myMesh2->read(); - - CPPUNIT_ASSERT(myMesh2 != NULL); - CPPUNIT_ASSERT(!(myMesh2->getIsAGrid())); - } - - delete myMed; - - //////////////////////////// - // test4 create new GRID // - //////////////////////////// - - // Default constructor and destructor - { - GRID* myGrid2 = new GRID(); - CPPUNIT_ASSERT(myGrid2->getIsAGrid()); - CPPUNIT_ASSERT(myGrid2->getGridType() == MED_CARTESIAN); - CPPUNIT_ASSERT(!myGrid2->getArrayLength(1)); - CPPUNIT_ASSERT(!myGrid2->getArrayLength(2)); - CPPUNIT_ASSERT(!myGrid2->getArrayLength(3)); - delete myGrid2; - } - - // Constructor with grid type, setGridType() - { - GRID* myGrid2 = new GRID(MED_POLAR); - CPPUNIT_ASSERT(myGrid2->getGridType() == MED_POLAR); - myGrid2->setGridType(MED_CARTESIAN); - CPPUNIT_ASSERT(myGrid2->getGridType() == MED_CARTESIAN); - delete myGrid2; - } - - // Constructor with coordinate values, getArrayValue(), init() - { - vector<vector<double> > xyz; - const int nbCoords = 3; - xyz.resize(nbCoords); - for ( int i = 0; i < nbCoords; i++ ) - { - xyz[i].resize(i + 2); - for ( int j = 0; j < i + 2; j++ ) - xyz[i][j] = j; - } - vector<string> Coord_Names; - Coord_Names.resize(nbCoords); - Coord_Names[0] = "X"; - Coord_Names[1] = "Y"; - Coord_Names[2] = "Z"; - - vector<string> Coord_Units; - Coord_Units.resize(nbCoords); - for(int i = 0; i < 3; i++) - Coord_Units[i] = "cm"; - - GRID* myGrid2; - - try{ - myGrid2 = new GRID(xyz, Coord_Names, Coord_Units, MED_CARTESIAN); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - // testing getCoordinateptr() and fillCoordinates() - // We fill a map of all possible coordinate triples. - // After iteration through all coordinates, this map should contain only "true" as data. - // "true" in some map element during iteration means duplicated node position. - // "false" in some map element after iteration means empty node position. - map<int, bool> found; - for ( int i1 = 0; i1 < xyz[0].size(); i1++ ) - for ( int i2 = 0; i2 < xyz[1].size(); i2++ ) - for ( int i3 = 0; i3 < xyz[2].size(); i3++ ) - found[int(xyz[0][i1] * 100 + xyz[1][i2] * 10 + xyz[2][i3])] = false; - - COORDINATE* coords = (COORDINATE*)myGrid2->getCoordinateptr(); - CPPUNIT_ASSERT(coords); - for (int num = 0; num < myGrid2->getNumberOfNodes(); num++) { - int x = int(coords->getCoordinate(num + 1, 1)); - int y = int(coords->getCoordinate(num + 1, 2)); - int z = int(coords->getCoordinate(num + 1, 3)); - CPPUNIT_ASSERT(!found[x * 100 + y * 10 + z]); - found[x * 100 + y * 10 + z] = true; - } - - for ( map<int, bool>::iterator it = found.begin(); it != found.end(); it++ ) - CPPUNIT_ASSERT((*it).second); - - // Testing fillConnectivity() and getConnectivityptr() - // Basic testing: presence of connectivity arrays, element types and number of elements - CONNECTIVITY* conn = (CONNECTIVITY*)myGrid2->getConnectivityptr(); - CPPUNIT_ASSERT(conn); - bool hasFaces = myGrid2->getArrayLength(3), hasEdges = myGrid2->getArrayLength(2); - medGeometryElement aCellGeometry; - if (hasFaces) aCellGeometry = MED_HEXA8; - else if (hasEdges) aCellGeometry = MED_QUAD4; - else aCellGeometry = MED_SEG2; - CPPUNIT_ASSERT(conn->getElementType(MED_CELL, 1) == aCellGeometry); - CPPUNIT_ASSERT(conn->existConnectivity(MED_NODAL, MED_CELL)); - CPPUNIT_ASSERT(conn->existConnectivity(MED_DESCENDING, MED_CELL)); - //test getCellsTypes - CELLMODEL* cellmodel = (CELLMODEL*)myGrid2->getCellsTypes(MED_CELL); - CPPUNIT_ASSERT(cellmodel); - - int nbCells, nbFaces, nbEdges; - - int iLen = myGrid2->getArrayLength(1); - int jLen = myGrid2->getArrayLength(2); - int kLen = myGrid2->getArrayLength(3); - int iLenMin1 = myGrid2->getArrayLength(1)-1; - int jLenMin1 = myGrid2->getArrayLength(2)-1; - int kLenMin1 = myGrid2->getArrayLength(3)-1; - const int* aCellCount = conn->getGlobalNumberingIndex(MED_CELL); - nbCells = iLenMin1 * jLenMin1 * kLenMin1; - CPPUNIT_ASSERT(aCellCount[1] - 1 == nbCells); - - if (hasFaces){ - CPPUNIT_ASSERT(conn->getElementType(MED_FACE, 1) == MED_QUAD4); - nbFaces = iLen * jLenMin1 * kLenMin1; - nbFaces += jLen * kLenMin1 * iLenMin1; - nbFaces += kLen * iLenMin1 * jLenMin1; - const int* aFaceCount = conn->getGlobalNumberingIndex(MED_FACE); - CPPUNIT_ASSERT(aFaceCount[1] - 1 == nbFaces); - CPPUNIT_ASSERT(conn->existConnectivity(MED_NODAL, MED_FACE)); - //test getCellsTypes - CELLMODEL* cellmodelF = (CELLMODEL*)myGrid2->getCellsTypes(MED_FACE); - CPPUNIT_ASSERT(cellmodelF); - } - if (hasEdges){ - CPPUNIT_ASSERT(conn->getElementType(MED_EDGE, 1) == MED_SEG2); - if (kLen) { // 3d grid - nbEdges = iLenMin1 * jLen * kLen; - nbEdges += jLenMin1 * kLen * iLen; - nbEdges += kLenMin1 * iLen * jLen; - } - else if (jLen) { // 2d - nbEdges = iLenMin1 * jLen; - nbEdges += jLenMin1 * iLen; - } - const int* anEdgeCount = conn->getGlobalNumberingIndex(MED_EDGE); - CPPUNIT_ASSERT(anEdgeCount[1] - 1 == nbEdges); - CPPUNIT_ASSERT(conn->existConnectivity(MED_NODAL, MED_EDGE)); - //test getCellsTypes - CELLMODEL* cellmodelE = (CELLMODEL*)myGrid2->getCellsTypes(MED_EDGE); - CPPUNIT_ASSERT(cellmodelE); - - } - - // Testing getArrayValue() - for ( int ii = 1; ii <= nbCoords; ii++ ) - for ( int jj = 0; jj < ii + 1; jj++ ) - CPPUNIT_ASSERT(myGrid2->getArrayValue(ii, jj) == xyz[ii - 1][jj]); - - CPPUNIT_ASSERT_THROW(myGrid2->getArrayValue(nbCoords + 1, 0), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(myGrid2->getArrayValue(1, myGrid2->getArrayLength(1) + 1), MEDEXCEPTION); - myGrid2->setGridType(MED_POLAR); - - //testing read/write functions - - // add new driver - int idGridV21; - - try - { - idGridV21 = myGrid2->addDriver(MED_DRIVER,filenameout21); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - // write this driver to file as an unstructured mesh - CPPUNIT_ASSERT_NO_THROW(myGrid2->writeUnstructured(idGridV21)); - - GRID* myGrid3 = new GRID(); - // add new driver for myGrid3 - int driver; - CPPUNIT_ASSERT_NO_THROW(driver = myGrid3->addDriver(MED_DRIVER, filenameout21)); - -#ifdef ENABLE_FORCED_FAILURES - // ? (BUG) ? "The mesh dimension |-1| seems to be incorrect for the mesh : |Default Mesh Name|" - CPPUNIT_ASSERT_NO_THROW(myGrid3->read(driver)); - - // Testing getArrayValue() - for ( int ii = 1; ii <= nbCoords; ii++ ) - for ( int jj = 0; jj < ii + 1; jj++ ) - CPPUNIT_ASSERT(myGrid3->getArrayValue(ii, jj) == xyz[ii - 1][jj]); - - CPPUNIT_ASSERT(myGrid3->getGridType() == MED_POLAR); -#endif - - delete myGrid3; - - //test init() - CPPUNIT_ASSERT_NO_THROW(myGrid2->init()); - CPPUNIT_ASSERT(myGrid2->getGridType() == MED_CARTESIAN); - CPPUNIT_ASSERT(myGrid2->getArrayLength(1) == 0); - CPPUNIT_ASSERT(myGrid2->getArrayLength(2) == 0); - CPPUNIT_ASSERT(myGrid2->getArrayLength(3) == 0); -#ifdef ENABLE_FAULTS - // (BUG) Segmentation Fault - myGrid2->makeUnstructured(); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("ERROR:makeUnstructured() - there is no check if grid is empty or not"); -#endif - - delete myGrid2; - } - -#ifdef ENABLE_FORCED_FAILURES - { - GRID* myGrid2; - // ? (BUG) ? MED Exception in /dn20/salome/jfa/V3/SRC/MED_SRC/src/MEDMEM/MEDMEM_MedM - //eshDriver21.cxx [430] : MED_MESH_RDONLY_DRIVER21::getCOORDINATE() : The number - //of nodes |0| seems to be incorrect for the mesh : |bodyfitted| - CPPUNIT_ASSERT_NO_THROW(myGrid2 = new GRID(MED_DRIVER, filename, mesh_names[1])); - - // Check if something has been read - full mesh data testing is above - CPPUNIT_ASSERT(myGrid2->getSpaceDimension()); - CPPUNIT_ASSERT(myGrid2->getNumberOfNodes()); - CPPUNIT_ASSERT(myGrid2->getNumberOfTypes(MED_CELL) == 1); - const medGeometryElement* types2; - CPPUNIT_ASSERT_NO_THROW(types2 = myGrid2->getTypes(MED_CELL)); - int nbElem; - CPPUNIT_ASSERT_NO_THROW(nbElem = myGrid2->getNumberOfElements(MED_CELL,types2[0])); - CPPUNIT_ASSERT(nbElem); - delete myGrid2; - } -#endif - - { - GRID* myGrid4 = new GRID(); - filename = datadir + "/MedFiles/pointe.med"; - myGrid4->setName("maa1"); - MED_MESH_RDONLY_DRIVER myMeshDriver(filename, myGrid4); - myMeshDriver.setMeshName("maa1"); - - // add new driver for myGrid4 - int driver; - CPPUNIT_ASSERT_NO_THROW(driver = myGrid4->addDriver(myMeshDriver)); - - // ??? ERROR:myGrid4->fillMeshAfterRead()- this method is incomplete: - // currently it only resets _is_coordinates_filled and _is_connectivity_filled - // flags that leads to grid reconstruction - - // MED Exception : MED_MESH_RDONLY_DRIVER21::getGRID() : The number - // of nodes |-1| seems to be incorrect for the mesh : |maa1| - // But this exception seems to be correct reaction on attempt - // to read a grid from a file, which does not contain it. - CPPUNIT_ASSERT_THROW(myGrid4->read(driver), MEDEXCEPTION); - //CPPUNIT_ASSERT_NO_THROW(myGrid4->read(driver)); - /*CPPUNIT_ASSERT(myGrid4->getArrayLength(1) == 0); - CPPUNIT_ASSERT(myGrid4->getArrayLength(2) == 0); - CPPUNIT_ASSERT(myGrid4->getArrayLength(3) == 0); - myGrid4->fillMeshAfterRead(); - CPPUNIT_ASSERT(myGrid4->getArrayLength(1) != 0); - CPPUNIT_ASSERT(myGrid4->getArrayLength(2) != 0); - CPPUNIT_ASSERT(myGrid4->getArrayLength(3) != 0);*/ - - delete myGrid4; - } -} diff --git a/src/MEDMEM/Test/MEDMEMTest_Grid_fault.cxx b/src/MEDMEM/Test/MEDMEMTest_Grid_fault.cxx deleted file mode 100644 index a38538280..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Grid_fault.cxx +++ /dev/null @@ -1,701 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "MEDMEM_define.hxx" -#include "MEDMEM_Grid.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Med.hxx" -#include "MEDMEM_MedMedDriver.hxx" -#include "MEDMEM_MedMeshDriver.hxx" - -#include <sstream> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -//#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - - -/*! - * Check methods (44), defined in MEDMEM_Grid.hxx: - * class GRID: public MESH { - * (+) GRID(); - * (+) GRID(const MED_EN::med_grid_type type); - * (BUG:operator=() not implemented but init() not called) GRID(const GRID &m); - * (+) GRID(driverTypes driverType, const string & fileName="",const string & meshName=""); - * (+) GRID(const std::vector<std::vector<double> >& xyz_array, - * const std::vector<std::string>& coord_name, - * const std::vector<std::string>& coord_unit, - * const MED_EN::med_grid_type type=MED_EN::MED_CARTESIAN); - * (NOT IMPLEMENTED) GRID & operator=(const GRID &m); - * (+) virtual ~GRID(); - * (+) virtual void init(); - * (tested together with getCoordinateptr() as it is called - * internally from there first of all. - * Moreover, fillCoordinates should be made private to avoid - * ambiguity druing in GRID class usage.) void fillCoordinates() const; - * (tested together with getConnectivityptr()) void fillConnectivity() const; - * (+) inline void makeUnstructured();//fill coordinates and connectivity of MESH - * (+) void fillMeshAfterRead(); - * (+) void writeUnstructured(int index=0, const string & driverName = ""); - * (+) void read(int index=0); - * (+) inline int getNodeNumber(const int i, const int j=0, const int k=0) const; - * (+) inline int getCellNumber(const int i, const int j=0, const int k=0) const; - * (+) int getEdgeNumber - * (const int Axis, const int i, const int j=0, const int k=0) const throw (MEDEXCEPTION); - * (+) int getFaceNumber - * (const int Axis, const int i, const int j=0, const int k=0) const throw (MEDEXCEPTION); - * (+) void getNodePosition(const int Number, int& i, int& j, int& k) const throw (MEDEXCEPTION); - * (+) void getCellPosition(const int Number, int& i, int& j, int& k) const throw (MEDEXCEPTION); - * (+) void getEdgePosition - * (const int Number, int& Axis, int& i, int& j, int& k) const throw (MEDEXCEPTION); - * (+) void getFacePosition - * (const int Number, int& Axis, int& i, int& j, int& k) const throw (MEDEXCEPTION); - * (+) inline MED_EN::med_grid_type getGridType() const; - * (+) int getArrayLength(const int Axis) const throw (MEDEXCEPTION); - * (+) const double getArrayValue (const int Axis, const int i) const throw (MEDEXCEPTION); - * (+) inline const COORDINATE * getCoordinateptr() const; - * (+) inline const double * getCoordinates(MED_EN::medModeSwitch Mode) const; - * (+) inline const double getCoordinate(int Number,int Axis) const; - * (+) inline int getNumberOfTypes(MED_EN::medEntityMesh Entity) const; - * (+) inline int getNumberOfTypesWithPoly(MED_EN::medEntityMesh Entity) const; - * (+) inline const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const; - * (+) MED_EN::medGeometryElement * getTypesWithPoly(MED_EN::medEntityMesh Entity) const; - * (+) inline const CELLMODEL * getCellsTypes(MED_EN::medEntityMesh Entity) const; - * (+) const int * getGlobalNumberingIndex(MED_EN::medEntityMesh Entity) const; - * (+) inline int getNumberOfElements - * (MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type) const; - * (+) inline int getNumberOfElementsWithPoly - * (MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type) const; - * (+) inline bool existConnectivity - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; - * (+) inline MED_EN::medGeometryElement getElementType - * (MED_EN::medEntityMesh Entity, int Number) const; - * (+) inline MED_EN::medGeometryElement getElementTypeWithPoly - * (MED_EN::medEntityMesh Entity, int Number) const; - * (+) inline void calculateConnectivity(MED_EN::medModeSwitch Mode, - * MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity) const; - * (+) inline const CONNECTIVITY* getConnectivityptr() const; - * (+) inline const int * getConnectivity - * (MED_EN::medModeSwitch Mode, MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type) const; - * (+) inline const int * getConnectivityIndex(MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity) const; - * (+) inline const int * getReverseConnectivity(MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; - * (+) inline const int * getReverseConnectivityIndex(MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; - * (+) inline void setGridType(MED_EN::med_grid_type gridType); - * } - */ -void MEDMEMTest_testGrid() -{ - string datadir = getenv("DATA_DIR"); - string filename = datadir + "/MedFiles/test19.med" ; - string tmp_dir = getenv("TMP"); - if (tmp_dir == "") - tmp_dir = "/tmp"; - string filenameout21 = tmp_dir + "/myGridWrite_grid21.med"; - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filenameout21); - - // Remove file in advance to ensure it does not exist at the moment of writing, - // because files are not removed by the MEDMEMTest_TmpFilesRemover in case of - // Segmentation Fault (in previous tests execution). - { - MEDMEMTest_TmpFilesRemover aRemover1; - aRemover1.Register(filenameout21); - } - - MED * myMed = new MED() ; - MED_MED_RDONLY_DRIVER myMeshDriver (filename, myMed); - myMeshDriver.open(); - myMeshDriver.readFileStruct(); - myMeshDriver.close(); - - int nbMeshes = myMed->getNumberOfMeshes(); - CPPUNIT_ASSERT(nbMeshes); - - deque<string> mesh_names = myMed->getMeshNames(); - CPPUNIT_ASSERT(mesh_names.size() != 0); - - ////////////////////////////// - // test1 "CARTESIAN GRID" // - ////////////////////////////// - { - MESH* myMesh = myMed->getMesh(mesh_names[0]); - myMesh->read(); - - CPPUNIT_ASSERT(myMesh != NULL); - CPPUNIT_ASSERT(myMesh->getIsAGrid()); - - GRID* myGrid = dynamic_cast<GRID*>(myMesh); - CPPUNIT_ASSERT(myGrid); - - CPPUNIT_ASSERT_THROW(myGrid->getArrayLength(0), MEDEXCEPTION); - - int I, J, K; - CPPUNIT_ASSERT_NO_THROW(I = myGrid->getArrayLength(1)); - CPPUNIT_ASSERT_NO_THROW(J = myGrid->getArrayLength(2)); - CPPUNIT_ASSERT_NO_THROW(K = myGrid->getArrayLength(3)); - - CPPUNIT_ASSERT(I); - CPPUNIT_ASSERT(J); - - med_grid_type grid_type = myGrid->getGridType(); - CPPUNIT_ASSERT_MESSAGE("Wrong grid type", grid_type == MED_CARTESIAN); - - const double * coordinates = myGrid->getCoordinates(MED_FULL_INTERLACE); - int SpaceDimension = myGrid->getSpaceDimension(); - for (int axe = 0; axe < SpaceDimension; axe++) { - for (int num = 0; num < myGrid->getNumberOfNodes(); num++) { - double coordinate; - CPPUNIT_ASSERT_NO_THROW(coordinate = myGrid->getCoordinate(num + 1, axe + 1)); - //cout << "coordinate = " << coordinate << endl; - CPPUNIT_ASSERT(fabs(coordinate - coordinates[(num * SpaceDimension)+axe]) < 0.001); - } - } - - int nbTypesCell = myGrid->getNumberOfTypes(MED_CELL); - CPPUNIT_ASSERT(nbTypesCell == 1); - - const medGeometryElement* types; - CPPUNIT_ASSERT_NO_THROW(types = myGrid->getTypes(MED_CELL)); -#ifdef ENABLE_FORCED_FAILURES - // Compilation warning about GRID::getTypes(): - // "inline function - // `virtual const MED_EN::medGeometryElement* MEDMEM::GRID::getTypes(MED_EN::medEntityMesh) const' - // used but never defined". - // In MEDMEM_Grid.hxx: - // inline const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const; - // But implemented in MEDMEM_Grid.cxx: - // const MED_EN::medGeometryElement * GRID::getTypes(MED_EN::medEntityMesh entity) const - CPPUNIT_FAIL("Problem with GRID::getTypes() method implementation."); -#endif - CPPUNIT_ASSERT(types[0] == MED_QUAD4); - - int nbElem = 0; - CPPUNIT_ASSERT_NO_THROW(nbElem = myGrid->getNumberOfElements(MED_CELL,types[0])); - CPPUNIT_ASSERT(nbElem); - - int nbNodes = myGrid->getNumberOfNodes(); - CPPUNIT_ASSERT(nbNodes); - - int ijkNode[3]; - int NodeNumber; - for (int nbNode = 1; nbNode <= nbNodes; nbNode++) { - CPPUNIT_ASSERT_NO_THROW(myGrid->getNodePosition(nbNode, ijkNode[0], ijkNode[1], ijkNode[2])); - CPPUNIT_ASSERT_NO_THROW(NodeNumber = myGrid->getNodeNumber(ijkNode[0], ijkNode[1], ijkNode[2])); - CPPUNIT_ASSERT(NodeNumber == nbNode); - } - - int nbCells = myGrid->getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS); - CPPUNIT_ASSERT(nbCells); - - int ijkCell[3]; - int CellNumber; - for (int nbCell = 1; nbCell <= nbCells; nbCell++) { - CPPUNIT_ASSERT_NO_THROW(myGrid->getCellPosition(nbCell, ijkCell[0], ijkCell[1], ijkCell[2])); - CPPUNIT_ASSERT_NO_THROW(CellNumber = myGrid->getCellNumber(ijkCell[0], ijkCell[1], ijkCell[2])); - CPPUNIT_ASSERT(CellNumber == nbCell); - } - - int nbEdges = myGrid->getNumberOfElements(MED_EDGE, MED_ALL_ELEMENTS); - CPPUNIT_ASSERT(nbEdges); - - int ijkAxisEdge[4]; - int EdgeNumber; - for (int nbEdge = 1; nbEdge <= nbEdges; nbEdge++) { - CPPUNIT_ASSERT_NO_THROW(myGrid->getEdgePosition(nbEdge, ijkAxisEdge[0], ijkAxisEdge[1], - ijkAxisEdge[2], ijkAxisEdge[3])); - CPPUNIT_ASSERT_NO_THROW(EdgeNumber = myGrid->getEdgeNumber(ijkAxisEdge[0], ijkAxisEdge[1], - ijkAxisEdge[2], ijkAxisEdge[3])); - CPPUNIT_ASSERT(EdgeNumber == nbEdge); - } - - int nbFaces = myGrid->getNumberOfElements(MED_FACE, MED_ALL_ELEMENTS); - CPPUNIT_ASSERT(nbFaces == 0); - -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("ERROR: nbFaces == 0, but getFacePosition(AnyNumber, ...) - return position(i,j,k)"); -#endif - int ijkAxisFace[4]; - CPPUNIT_ASSERT_NO_THROW(myGrid->getFacePosition(6, ijkAxisFace[0], ijkAxisFace[1], - ijkAxisFace[2], ijkAxisFace[3])); - CPPUNIT_ASSERT(ijkAxisFace[0]); - CPPUNIT_ASSERT(ijkAxisFace[1]); - CPPUNIT_ASSERT(ijkAxisFace[2]); - - /*int FaceNumber; - for(int nbFace = 1; nbFace <= nbFaces; nbFace++) - { - CPPUNIT_ASSERT_NO_THROW( myGrid->getFacePosition(nbFace, ijkAxisFace[0], ijkAxisFace[1], - ijkAxisFace[2], ijkAxisFace[3])); - CPPUNIT_ASSERT_NO_THROW( EdgeNumber = myGrid->getEdgeNumber(ijkAxisFace[0], ijkAxisFace[1], - ijkAxisFace[2], ijkAxisFace[3])); - CPPUNIT_ASSERT(FaceNumber == nbFace); - }*/ - - bool existConnect = false; - CPPUNIT_ASSERT_NO_THROW(existConnect = myGrid->existConnectivity(MED_NODAL, MED_CELL)); - if (!existConnect) { - CPPUNIT_ASSERT_NO_THROW(myGrid->calculateConnectivity(MED_FULL_INTERLACE, MED_NODAL, MED_CELL)); - CPPUNIT_ASSERT(myGrid->existConnectivity(MED_NODAL, MED_CELL)); - } - - const int* Connectivity; - const int* connectivity_index; - CPPUNIT_ASSERT_NO_THROW(Connectivity = myGrid->getConnectivity(MED_FULL_INTERLACE, MED_NODAL, - MED_CELL, types[0])); - CPPUNIT_ASSERT_NO_THROW(connectivity_index = myGrid->getConnectivityIndex(MED_NODAL, MED_CELL)); - cout << "Nodal connectivity" << endl; - for (int j = 0; j < nbElem; j++) { - cout << "Element "<< j+1 << " : "; - for (int k = connectivity_index[j]; k < connectivity_index[j+1]; k++) - cout << Connectivity[k-1] << " "; - cout << endl; - } - - const int * ReverseNodalConnectivity; - const int * ReverseConnectivityIndex; - CPPUNIT_ASSERT_NO_THROW(ReverseNodalConnectivity = myGrid->getReverseConnectivity(MED_NODAL)); - CPPUNIT_ASSERT_NO_THROW(ReverseConnectivityIndex = myGrid->getReverseConnectivityIndex(MED_NODAL)); - for (int i = 0; i < nbNodes; i++) { - cout << "Node "<< i+1 << " : "; - for (int j = ReverseConnectivityIndex[i]; j < ReverseConnectivityIndex[i+1]; j++) - cout << ReverseNodalConnectivity[j-1] << " "; - cout << endl; - } - - const int* myGlobalNbIdx; - CPPUNIT_ASSERT_NO_THROW(myGlobalNbIdx = myGrid->getGlobalNumberingIndex(MED_CELL)); - for (int i = 0; i <= nbTypesCell; i++) { - if (i == nbTypesCell) { - CPPUNIT_ASSERT_THROW(myGrid->getElementType(MED_CELL, myGlobalNbIdx[i]), MEDEXCEPTION); - break; - } - medGeometryElement aElem, geomPolyElem; - CPPUNIT_ASSERT_NO_THROW(aElem = myGrid->getElementType(MED_CELL, myGlobalNbIdx[i])); - CPPUNIT_ASSERT_NO_THROW(geomPolyElem = myGrid->getElementTypeWithPoly(MED_CELL, myGlobalNbIdx[i])); - CPPUNIT_ASSERT(types[0] == aElem); - CPPUNIT_ASSERT(geomPolyElem == aElem); - } - - CPPUNIT_ASSERT_NO_THROW(existConnect = myGrid->existConnectivity(MED_DESCENDING, MED_CELL)); - if (!existConnect) { - CPPUNIT_ASSERT_NO_THROW(myGrid->calculateConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, MED_CELL)); - CPPUNIT_ASSERT(myGrid->existConnectivity(MED_DESCENDING, MED_CELL)); - } - - const int* ConnectivityDes; - const int* connectivity_index_des; - CPPUNIT_ASSERT_NO_THROW(ConnectivityDes = myGrid->getConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, - MED_CELL, MED_ALL_ELEMENTS)); - CPPUNIT_ASSERT_NO_THROW(connectivity_index_des = - myGrid->getConnectivityIndex(MED_DESCENDING, MED_CELL)); - cout<<"Descending connectivity"<<endl; - for (int j = 0; j < nbElem; j++) { - cout << "Element "<< j+1 << " : "; - for (int k = connectivity_index_des[j]; k < connectivity_index_des[j+1]; k++) - cout << ConnectivityDes[k-1] << " "; - cout << endl; - } - - const int * ReverseDesConnectivity; - const int * ReverseConnectivityIndexDes; - CPPUNIT_ASSERT_NO_THROW(ReverseDesConnectivity = myGrid->getReverseConnectivity(MED_DESCENDING)); - CPPUNIT_ASSERT_NO_THROW(ReverseConnectivityIndexDes = - myGrid->getReverseConnectivityIndex(MED_DESCENDING)); - for (int i = 0; i < nbNodes; i++) { - cout << "Node "<< i+1 << " : "; - for (int j = ReverseConnectivityIndexDes[i]; j < ReverseConnectivityIndexDes[i+1]; j++) - cout << ReverseDesConnectivity[j-1] << " "; - cout << endl; - } - - //TEST POLY - { - int nbPolytypes; - //test getNumberOfTypesWithPoly() - a grid has one type - CPPUNIT_ASSERT_NO_THROW(nbPolytypes = myGrid->getNumberOfTypesWithPoly(MED_CELL)); - CPPUNIT_ASSERT(nbPolytypes == 1 ); - - const MED_EN::medGeometryElement * PolyTypes, *Types; - CPPUNIT_ASSERT_NO_THROW(PolyTypes = myGrid->getTypesWithPoly(MED_CELL)); - CPPUNIT_ASSERT_NO_THROW(Types = myGrid->getTypes(MED_CELL)); - CPPUNIT_ASSERT_EQUAL(PolyTypes[nbPolytypes-1],Types[nbPolytypes-1]); - - for (int t = 0; t < nbPolytypes; t++) { - int nbElPoly, nbEl; - CPPUNIT_ASSERT_NO_THROW(nbElPoly = myGrid->getNumberOfElementsWithPoly(MED_CELL, PolyTypes[t])); - CPPUNIT_ASSERT_NO_THROW(nbEl = myGrid->getNumberOfElements(MED_CELL, PolyTypes[t])); - CPPUNIT_ASSERT(nbElPoly == nbEl); - } - } - } - - ////////////////////////////// - // test2 "MED_BODY_FITTED" // - ////////////////////////////// - { - MESH* myMesh1 = myMed->getMesh(mesh_names[1]); - myMesh1->read(); - - CPPUNIT_ASSERT(myMesh1 != NULL); - CPPUNIT_ASSERT(myMesh1->getIsAGrid()); - - GRID* myGrid1 = dynamic_cast<GRID*>(myMesh1); - CPPUNIT_ASSERT(myGrid1); - - int I, J, K; - CPPUNIT_ASSERT_NO_THROW(I = myGrid1->getArrayLength(1)); - CPPUNIT_ASSERT_NO_THROW(J = myGrid1->getArrayLength(2)); - CPPUNIT_ASSERT_NO_THROW(K = myGrid1->getArrayLength(3)); - - CPPUNIT_ASSERT(I == 2); - CPPUNIT_ASSERT(J == 2); - - med_grid_type grid_type = myGrid1->getGridType(); - CPPUNIT_ASSERT_MESSAGE("Wrong grid type", grid_type == MED_BODY_FITTED); - - int nbTypesCell = myGrid1->getNumberOfTypes(MED_CELL); - CPPUNIT_ASSERT(nbTypesCell == 1); - - const medGeometryElement* types1; - CPPUNIT_ASSERT_NO_THROW( types1 = myGrid1->getTypes(MED_CELL) ); - CPPUNIT_ASSERT( types1[0] == MED_QUAD4); - - int nbElem; - CPPUNIT_ASSERT_NO_THROW(nbElem = myGrid1->getNumberOfElements(MED_CELL, types1[0])); - CPPUNIT_ASSERT(nbElem); - - const int* BodyConnectivity; - const int* body_connectivity_index; - int ijkNodeBody[3]; - CPPUNIT_ASSERT_NO_THROW(BodyConnectivity = myGrid1->getConnectivity(MED_FULL_INTERLACE, MED_NODAL, - MED_CELL, types1[0])); - CPPUNIT_ASSERT_NO_THROW(body_connectivity_index = myGrid1->getConnectivityIndex(MED_NODAL, MED_CELL)); - cout<<"Nodal connectivity"<<endl; - for (int j = 0; j < nbElem; j++) { - cout << "Element "<< j+1 << " : "; - for (int k = body_connectivity_index[j]; k < body_connectivity_index[j+1]; k++){ - CPPUNIT_ASSERT_NO_THROW(myGrid1->getNodePosition(BodyConnectivity[k-1], ijkNodeBody[0], - ijkNodeBody[1], ijkNodeBody[2])); - cout << BodyConnectivity[k-1] << " "; - } - cout << endl; - } - } - - /////////////////////////////////////////////////// - // test3 "maa1" which in fact is not a pure GRID // - /////////////////////////////////////////////////// - { - MESH* myMesh2 = NULL; - - myMesh2 = myMed->getMesh(mesh_names[2]); - myMesh2->read(); - - CPPUNIT_ASSERT(myMesh2 != NULL); - CPPUNIT_ASSERT(!(myMesh2->getIsAGrid())); - } - - delete myMed; - - //////////////////////////// - // test4 create new GRID // - //////////////////////////// - - // Default constructor and destructor - { - GRID* myGrid2 = new GRID(); - CPPUNIT_ASSERT(myGrid2->getIsAGrid()); - CPPUNIT_ASSERT(myGrid2->getGridType() == MED_CARTESIAN); - CPPUNIT_ASSERT(!myGrid2->getArrayLength(1)); - CPPUNIT_ASSERT(!myGrid2->getArrayLength(2)); - CPPUNIT_ASSERT(!myGrid2->getArrayLength(3)); - delete myGrid2; - } - - // Constructor with grid type, setGridType() - { - GRID* myGrid2 = new GRID(MED_POLAR); - CPPUNIT_ASSERT(myGrid2->getGridType() == MED_POLAR); - myGrid2->setGridType(MED_CARTESIAN); - CPPUNIT_ASSERT(myGrid2->getGridType() == MED_CARTESIAN); - delete myGrid2; - } - - // Constructor with coordinate values, getArrayValue(), init() - { - vector<vector<double> > xyz; - const int nbCoords = 3; - xyz.resize(nbCoords); - for ( int i = 0; i < nbCoords; i++ ) - { - xyz[i].resize(i + 2); - for ( int j = 0; j < i + 2; j++ ) - xyz[i][j] = j; - } - vector<string> Coord_Names; - Coord_Names.resize(nbCoords); - Coord_Names[0] = "X"; - Coord_Names[1] = "Y"; - Coord_Names[2] = "Z"; - - vector<string> Coord_Units; - Coord_Units.resize(nbCoords); - for(int i = 0; i < 3; i++) - Coord_Units[i] = "cm"; - - GRID* myGrid2; - - try{ - myGrid2 = new GRID(xyz, Coord_Names, Coord_Units, MED_CARTESIAN); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - // testing getCoordinateptr() and fillCoordinates() - // We fill a map of all possible coordinate triples. - // After iteration through all coordinates, this map should contain only "true" as data. - // "true" in some map element during iteration means duplicated node position. - // "false" in some map element after iteration means empty node position. - map<int, bool> found; - for ( int i1 = 0; i1 < xyz[0].size(); i1++ ) - for ( int i2 = 0; i2 < xyz[1].size(); i2++ ) - for ( int i3 = 0; i3 < xyz[2].size(); i3++ ) - found[int(xyz[0][i1] * 100 + xyz[1][i2] * 10 + xyz[2][i3])] = false; - - COORDINATE* coords = (COORDINATE*)myGrid2->getCoordinateptr(); - CPPUNIT_ASSERT(coords); - for (int num = 0; num < myGrid2->getNumberOfNodes(); num++) { - int x = int(coords->getCoordinate(num + 1, 1)); - int y = int(coords->getCoordinate(num + 1, 2)); - int z = int(coords->getCoordinate(num + 1, 3)); - CPPUNIT_ASSERT(!found[x * 100 + y * 10 + z]); - found[x * 100 + y * 10 + z] = true; - } - - for ( map<int, bool>::iterator it = found.begin(); it != found.end(); it++ ) - CPPUNIT_ASSERT((*it).second); - - // Testing fillConnectivity() and getConnectivityptr() - // Basic testing: presence of connectivity arrays, element types and number of elements - CONNECTIVITY* conn = (CONNECTIVITY*)myGrid2->getConnectivityptr(); - CPPUNIT_ASSERT(conn); - bool hasFaces = myGrid2->getArrayLength(3), hasEdges = myGrid2->getArrayLength(2); - medGeometryElement aCellGeometry; - if (hasFaces) aCellGeometry = MED_HEXA8; - else if (hasEdges) aCellGeometry = MED_QUAD4; - else aCellGeometry = MED_SEG2; - CPPUNIT_ASSERT(conn->getElementType(MED_CELL, 1) == aCellGeometry); - CPPUNIT_ASSERT(conn->existConnectivity(MED_NODAL, MED_CELL)); - CPPUNIT_ASSERT(conn->existConnectivity(MED_DESCENDING, MED_CELL)); - //test getCellsTypes - CELLMODEL* cellmodel = (CELLMODEL*)myGrid2->getCellsTypes(MED_CELL); - CPPUNIT_ASSERT(cellmodel); - - int nbCells, nbFaces, nbEdges; - - int iLen = myGrid2->getArrayLength(1); - int jLen = myGrid2->getArrayLength(2); - int kLen = myGrid2->getArrayLength(3); - int iLenMin1 = myGrid2->getArrayLength(1)-1; - int jLenMin1 = myGrid2->getArrayLength(2)-1; - int kLenMin1 = myGrid2->getArrayLength(3)-1; - const int* aCellCount = conn->getGlobalNumberingIndex(MED_CELL); - nbCells = iLenMin1 * jLenMin1 * kLenMin1; - CPPUNIT_ASSERT(aCellCount[1] - 1 == nbCells); - - if (hasFaces){ - CPPUNIT_ASSERT(conn->getElementType(MED_FACE, 1) == MED_QUAD4); - nbFaces = iLen * jLenMin1 * kLenMin1; - nbFaces += jLen * kLenMin1 * iLenMin1; - nbFaces += kLen * iLenMin1 * jLenMin1; - const int* aFaceCount = conn->getGlobalNumberingIndex(MED_FACE); - CPPUNIT_ASSERT(aFaceCount[1] - 1 == nbFaces); - CPPUNIT_ASSERT(conn->existConnectivity(MED_NODAL, MED_FACE)); - //test getCellsTypes - CELLMODEL* cellmodelF = (CELLMODEL*)myGrid2->getCellsTypes(MED_FACE); - CPPUNIT_ASSERT(cellmodelF); - } - if (hasEdges){ - CPPUNIT_ASSERT(conn->getElementType(MED_EDGE, 1) == MED_SEG2); - if (kLen) { // 3d grid - nbEdges = iLenMin1 * jLen * kLen; - nbEdges += jLenMin1 * kLen * iLen; - nbEdges += kLenMin1 * iLen * jLen; - } - else if (jLen) { // 2d - nbEdges = iLenMin1 * jLen; - nbEdges += jLenMin1 * iLen; - } - const int* anEdgeCount = conn->getGlobalNumberingIndex(MED_EDGE); - CPPUNIT_ASSERT(anEdgeCount[1] - 1 == nbEdges); - CPPUNIT_ASSERT(conn->existConnectivity(MED_NODAL, MED_EDGE)); - //test getCellsTypes - CELLMODEL* cellmodelE = (CELLMODEL*)myGrid2->getCellsTypes(MED_EDGE); - CPPUNIT_ASSERT(cellmodelE); - - } - - // Testing getArrayValue() - for ( int ii = 1; ii <= nbCoords; ii++ ) - for ( int jj = 0; jj < ii + 1; jj++ ) - CPPUNIT_ASSERT(myGrid2->getArrayValue(ii, jj) == xyz[ii - 1][jj]); - - CPPUNIT_ASSERT_THROW(myGrid2->getArrayValue(nbCoords + 1, 0), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(myGrid2->getArrayValue(1, myGrid2->getArrayLength(1) + 1), MEDEXCEPTION); - myGrid2->setGridType(MED_POLAR); - - //testing read/write functions - - // add new driver - int idGridV21; - - try - { - idGridV21 = myGrid2->addDriver(MED_DRIVER,filenameout21); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - // write this driver to file as an unstructured mesh - CPPUNIT_ASSERT_NO_THROW(myGrid2->writeUnstructured(idGridV21)); - - GRID* myGrid3 = new GRID(); - // add new driver for myGrid3 - int driver; - CPPUNIT_ASSERT_NO_THROW(driver = myGrid3->addDriver(MED_DRIVER, filenameout21)); - -#ifdef ENABLE_FORCED_FAILURES - // ? (BUG) ? "The mesh dimension |-1| seems to be incorrect for the mesh : |Default Mesh Name|" - CPPUNIT_ASSERT_NO_THROW(myGrid3->read(driver)); - - // Testing getArrayValue() - for ( int ii = 1; ii <= nbCoords; ii++ ) - for ( int jj = 0; jj < ii + 1; jj++ ) - CPPUNIT_ASSERT(myGrid3->getArrayValue(ii, jj) == xyz[ii - 1][jj]); - - CPPUNIT_ASSERT(myGrid3->getGridType() == MED_POLAR); -#endif - - delete myGrid3; - - //test init() - CPPUNIT_ASSERT_NO_THROW(myGrid2->init()); - CPPUNIT_ASSERT(myGrid2->getGridType() == MED_CARTESIAN); - CPPUNIT_ASSERT(myGrid2->getArrayLength(1) == 0); - CPPUNIT_ASSERT(myGrid2->getArrayLength(2) == 0); - CPPUNIT_ASSERT(myGrid2->getArrayLength(3) == 0); -#ifdef ENABLE_FAULTS - // (BUG) Segmentation Fault - myGrid2->makeUnstructured(); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("ERROR:makeUnstructured() - there is no check if grid is empty or not"); -#endif - - delete myGrid2; - } - -#ifdef ENABLE_FORCED_FAILURES - { - GRID* myGrid2; - // ? (BUG) ? MED Exception in /dn20/salome/jfa/V3/SRC/MED_SRC/src/MEDMEM/MEDMEM_MedM - //eshDriver21.cxx [430] : MED_MESH_RDONLY_DRIVER21::getCOORDINATE() : The number - //of nodes |0| seems to be incorrect for the mesh : |bodyfitted| - CPPUNIT_ASSERT_NO_THROW(myGrid2 = new GRID(MED_DRIVER, filename, mesh_names[1])); - - // Check if something has been read - full mesh data testing is above - CPPUNIT_ASSERT(myGrid2->getSpaceDimension()); - CPPUNIT_ASSERT(myGrid2->getNumberOfNodes()); - CPPUNIT_ASSERT(myGrid2->getNumberOfTypes(MED_CELL) == 1); - const medGeometryElement* types2; - CPPUNIT_ASSERT_NO_THROW(types2 = myGrid2->getTypes(MED_CELL)); - int nbElem; - CPPUNIT_ASSERT_NO_THROW(nbElem = myGrid2->getNumberOfElements(MED_CELL,types2[0])); - CPPUNIT_ASSERT(nbElem); - delete myGrid2; - } -#endif - - { - GRID* myGrid4 = new GRID(); - filename = datadir + "/MedFiles/pointe.med"; - myGrid4->setName("maa1"); - MED_MESH_RDONLY_DRIVER myMeshDriver(filename, myGrid4); - myMeshDriver.setMeshName("maa1"); - - // add new driver for myGrid4 - int driver; - CPPUNIT_ASSERT_NO_THROW(driver = myGrid4->addDriver(myMeshDriver)); - - // ??? ERROR:myGrid4->fillMeshAfterRead()- this method is incomplete: - // currently it only resets _is_coordinates_filled and _is_connectivity_filled - // flags that leads to grid reconstruction - - // MED Exception : MED_MESH_RDONLY_DRIVER21::getGRID() : The number - // of nodes |-1| seems to be incorrect for the mesh : |maa1| - // But this exception seems to be correct reaction on attempt - // to read a grid from a file, which does not contain it. - CPPUNIT_ASSERT_THROW(myGrid4->read(driver), MEDEXCEPTION); - //CPPUNIT_ASSERT_NO_THROW(myGrid4->read(driver)); - /*CPPUNIT_ASSERT(myGrid4->getArrayLength(1) == 0); - CPPUNIT_ASSERT(myGrid4->getArrayLength(2) == 0); - CPPUNIT_ASSERT(myGrid4->getArrayLength(3) == 0); - myGrid4->fillMeshAfterRead(); - CPPUNIT_ASSERT(myGrid4->getArrayLength(1) != 0); - CPPUNIT_ASSERT(myGrid4->getArrayLength(2) != 0); - CPPUNIT_ASSERT(myGrid4->getArrayLength(3) != 0);*/ - - delete myGrid4; - } -} - -int main (int argc, char** argv) -{ - MEDMEMTest_testGrid(); -} diff --git a/src/MEDMEM/Test/MEDMEMTest_Group.cxx b/src/MEDMEM/Test/MEDMEMTest_Group.cxx deleted file mode 100644 index 1680f692e..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Group.cxx +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/Message.h> -#include <cppunit/TestAssert.h> - -#include "MEDMEM_Group.hxx" -#include "MEDMEM_define.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_MedMeshDriver.hxx" - -#include <sstream> -#include <cmath> - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -/*! - * Check methods (10), defined in MEDMEM_Group.hxx: - * class GROUP : virtual public SUPPORT { - * (+) GROUP(); - * (+) GROUP(const string & name, const list<FAMILY*> & family) throw (MEDEXCEPTION); - * (+) GROUP(const GROUP & m); - * (+) virtual ~GROUP(); - * (+) GROUP & operator=(const GROUP &group); - * (+) friend ostream & operator<<(ostream &os, GROUP &my); - * (+) inline void setNumberOfFamilies(int numberOfFamilies); - * (+) inline void setFamilies(vector<FAMILY*> Family); - * (+) inline int getNumberOfFamilies() const; - * (+) inline vector<FAMILY*> getFamilies() const; - * (+) inline FAMILY * getFamily(int i) const; - * } - */ -void MEDMEMTest::testGroup() -{ - string datadir = getenv("DATA_DIR"); - string filename = datadir + "/MedFiles/pointe.med" ; - string meshname = "maa1"; - - MESH * myMesh= new MESH() ; - myMesh->setName(meshname); - MED_MESH_RDONLY_DRIVER myMeshDriver(filename,myMesh); - myMeshDriver.setMeshName(meshname); - myMeshDriver.open(); - myMeshDriver.read(); - myMeshDriver.close(); - - const GROUP * myGroup = myMesh->getGroup(MED_NODE,1); - CPPUNIT_ASSERT(myGroup != NULL); - - int NumberOfFamillies = myGroup->getNumberOfFamilies(); - CPPUNIT_ASSERT(NumberOfFamillies != 0); - - vector<FAMILY*> aFamilies = myGroup->getFamilies(); - CPPUNIT_ASSERT(NumberOfFamillies == aFamilies.size()); - list<FAMILY*> aList; - - for (int j=1;j<=NumberOfFamillies;j++) - { - try{ - aList.push_back(myGroup->getFamily(j)); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT_EQUAL(myGroup->getFamily(j)->getName(), aFamilies[j-1]->getName()); - } - - GROUP* myGroup2 = new GROUP(*myGroup); - - cout<<*myGroup2<<endl; - ostringstream os; - os << *myGroup2; - CPPUNIT_ASSERT(os.str() != ""); - - GROUP myGroup3; - try{ - myGroup3 = *myGroup2; - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_EQUAL(myGroup3, *myGroup2); - - GROUP myGroup4; - const GROUP * Group = myMesh->getGroup(MED_NODE,2); - CPPUNIT_ASSERT(Group != NULL); - - int NumberOfFamillies1 = Group->getNumberOfFamilies(); - CPPUNIT_ASSERT(NumberOfFamillies1 != 0); - if(NumberOfFamillies1) - { - myGroup4.setNumberOfFamilies(NumberOfFamillies1); - myGroup4.setFamilies(Group->getFamilies()); - for(int i = 1; i <= myGroup4.getNumberOfFamilies(); i++ ) - { - CPPUNIT_ASSERT_EQUAL(myGroup4.getFamily(i), Group->getFamily(i)); - } - } - - if(aList.size()) - { - try{ - GROUP myGroup5("newFamily", aList); - cout<< myGroup5 <<endl; - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - } - - delete myGroup2; - delete myMesh ; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_Med.cxx b/src/MEDMEM/Test/MEDMEMTest_Med.cxx deleted file mode 100644 index 3b040101d..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Med.cxx +++ /dev/null @@ -1,437 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "MEDMEM_Med.hxx" - -#include <sstream> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -// #30: MEDMEM_Med.hxx } MEDMEMTest_Med.cxx - -/*! - * Check methods (26), defined in MEDMEM_Med.hxx: - * class MED { - * (+) MED(); - * (+) MED (driverTypes driverType, const string & fileName); - * (+) ~MED(); - * (+) void addField (FIELD_ * const ptrField) throw (MED_EXCEPTION); - * (+) void addMesh (MESH * const ptrMesh) throw (MED_EXCEPTION); - * (+) int addDriver (driverTypes driverType, const string & fileName, - * MED_EN::med_mode_acces access=MED_EN::MED_REMP); - * (+) int addDriver (GENDRIVER & driver); - * (+) void rmDriver (int index=0) throw (MEDEXCEPTION); - * (+) void readFileStruct(int index=0) throw (MEDEXCEPTION); - * (+) void read (int index=0) throw (MEDEXCEPTION); - * (+) void writeFrom (int index=0) throw (MEDEXCEPTION); - * (+) void write (int index=0) throw (MEDEXCEPTION); - * (+) int getNumberOfMeshes (void) const; - * (+) int getNumberOfFields (void) const; - * (+) void getMeshNames (string * meshNames) const throw (MEDEXCEPTION); - * (+) deque<string> getMeshNames () const; - * (+) MESH * getMesh (const string & meshName) const throw (MEDEXCEPTION); - * (+) MESH * getMesh (const FIELD_ * const field) const throw (MEDEXCEPTION); - * (+) void getFieldNames (string * fieldNames) const throw (MEDEXCEPTION); - * (+) deque<string> getFieldNames () const; - * (+) deque<DT_IT_> getFieldIteration (const string & fieldName) const throw (MEDEXCEPTION); - * (+) FIELD_ * getField (const string & fieldName, const int dt, - * const int it) const throw (MEDEXCEPTION); - * (NOT COMPILABLE!!!) template<class T> FIELD<T> * getFieldT - * (const string & fieldName, const int dt, const int it) const throw (MEDEXCEPTION); - * (+) FIELD_ * getField2 (const string & fieldName, double time, int it=0) const throw (MEDEXCEPTION); - * (+) const map<MED_EN::medEntityMesh,SUPPORT *> & getSupports - * (const string & meshName) const throw (MEDEXCEPTION); - * (+) SUPPORT * getSupport (const string & meshName, - * MED_EN::medEntityMesh entity) const throw (MEDEXCEPTION); - * (-, as it is temporary and called from driver after Med object reading from file) void updateSupport (); - * } - */ -void MEDMEMTest::testMed() -{ - string datadir = getenv("DATA_DIR"); - string filename = datadir + "/MedFiles/pointe.med"; - - string tmp_dir = getenv("TMP"); - if (tmp_dir == "") - tmp_dir = "/tmp"; - - string filenameout21 = tmp_dir + "/myMedWrite_pointe21.med"; - string filenameout21_from = tmp_dir + "/myMedWrite_pointe21_from.med"; - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filenameout21); - aRemover.Register(filenameout21_from); - - MED* myMed = new MED(MED_DRIVER, filename); - //read all objects in the file - CPPUNIT_ASSERT_NO_THROW(myMed->read()); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Memory problem in MED::updateSupport()! - // Invalid read of size 4 - // at 0x34548AD6: std::_Rb_tree_decrement(std::_Rb_tree_node_base*) (in /usr/lib/libstdc++.so.6.0.1) - // by 0x34876722: std::_Rb_tree_iterator<std::pair<long const, MEDMEM::SUPPORT*> >::operator--(int) (stl_tree.h:203) - // by 0x348733BE: MEDMEM::MED::updateSupport() (MEDMEM_Med.cxx:805) - // Address 0x35C67598 is 0 bytes inside a block of size 24 free'd - // at 0x3414CBD5: operator delete(void*) (vg_replace_malloc.c:155) - // ... - // by 0x348766EB: std::map<long, MEDMEM::SUPPORT*, std::less<long>, std::allocator<std::pair<long const, MEDMEM::SUPPORT*> > >::erase(std::_Rb_tree_iterator<std::pair<long const, MEDMEM::SUPPORT*> >) (stl_map.h:410) - // by 0x348733A3: MEDMEM::MED::updateSupport() (MEDMEM_Med.cxx:804) - CPPUNIT_FAIL("Memory problem in MED::updateSupport(): removing map item while iterating on this map."); -#endif - - //getNumberOfMeshes - int nbMeshes, nbFields; - try{ - nbMeshes = myMed->getNumberOfMeshes(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT(nbMeshes); - - //getMeshNames - deque<string> mesh_names, field_names; - try{ - mesh_names = myMed->getMeshNames(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT(mesh_names.size() != 0); - - //getNumberOfFields - try{ - nbFields = myMed->getNumberOfFields(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT(nbFields); - - //getFieldNames - try{ - field_names = myMed->getFieldNames(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT(field_names.size() != 0); - - string field_names_1[nbFields]; - string mesh_names_1[nbMeshes]; - //get field and mesh names - try{ - myMed->getMeshNames(mesh_names_1); - myMed->getFieldNames(field_names_1); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - // Ensure what it's impossible to get mesh object by empty or non-existent name - CPPUNIT_ASSERT_THROW(myMed->getMesh(""), MEDEXCEPTION); - - //compare mesh names, produced by two different methods - for(int nb = 0; nb < nbMeshes; nb++ ) - { - MESH* myMesh; - CPPUNIT_ASSERT(mesh_names_1[nb] == mesh_names[nb]); - CPPUNIT_ASSERT_NO_THROW(myMesh = myMed->getMesh(mesh_names[nb])); - //ensure mesh is not empty - CPPUNIT_ASSERT(myMesh->getSpaceDimension() != MED_INVALID); - CPPUNIT_ASSERT(myMesh->getNumberOfNodes() != MED_INVALID); - CPPUNIT_ASSERT(myMesh->getCoordinateptr() != NULL); - } - - // Ensure what it's impossible to get field object by empty or non-existent name - CPPUNIT_ASSERT_THROW(myMed->getField("", 0, 0),MEDEXCEPTION); - - // Cycle by amount of fields - // Compare field names produced by two different methods - // Get field object with help of getField(...) and getField2(...) - for(int nb = 0; nb < nbFields; nb++ ) - { - CPPUNIT_ASSERT(field_names_1[nb] == field_names[nb]); - deque<DT_IT_> myFIter; - CPPUNIT_ASSERT_NO_THROW(myFIter = myMed->getFieldIteration(field_names[nb])); - CPPUNIT_ASSERT(myFIter.size()); - for(int nbIter = 0; nbIter < myFIter.size(); nbIter++) - { - FIELD_ *myField, *myField2; - CPPUNIT_ASSERT_NO_THROW(myField = myMed->getField (field_names[nb], myFIter[nbIter].dt, myFIter[nbIter].it)); - CPPUNIT_ASSERT_NO_THROW(myField2 = myMed->getField2(field_names[nb], myField->getTime())); - CPPUNIT_ASSERT(myField==myField2); - //compare two fields - CPPUNIT_ASSERT(myField->getNumberOfComponents() == myField2->getNumberOfComponents()); - CPPUNIT_ASSERT(myField->getNumberOfValues() == myField2->getNumberOfValues()); - CPPUNIT_ASSERT(myField->getSupport() == myField2->getSupport()); - CPPUNIT_ASSERT(myField->getValueType() == myField2->getValueType()); - CPPUNIT_ASSERT(myField->getDescription() == myField2->getDescription()); - - med_type_champ type = myField->getValueType(); - switch (type) - { - case MED_INT32: - { -#ifdef ENABLE_FORCED_FAILURES - // (BUG) ERROR in MEDMEM_Med.hxx line 153: FIELD_ retUp=getField(fieldName,dt,it); - // But getField returns FIELD_* - CPPUNIT_FAIL("Error in MED::getFieldT(const string & fieldName, const int dt, const int it)"); -#endif - // not compilable - //FIELD<int> *myFieldT; - //CPPUNIT_ASSERT_NO_THROW(myFieldT = myMed->getFieldT<int>(field_names[nb], myFIter[nbIter].dt, myFIter[nbIter].it)) - } - break; - case MED_REEL64: - { - // not compilable - //FIELD<double> *myFieldT; - //CPPUNIT_ASSERT_NO_THROW(myFieldT = myMed->getFieldT<double>(field_names[nb], myFIter[nbIter].dt, myFIter[nbIter].it)) - } - break; - } - } - } - - // For each mesh get a map - for(int nb = 0; nb < nbMeshes; nb++ ) - { - map<MED_EN::medEntityMesh,SUPPORT *> myMapSupports; - CPPUNIT_ASSERT_NO_THROW(myMapSupports = myMed->getSupports(mesh_names[nb])); - map<MED_EN::medEntityMesh,SUPPORT *>::const_iterator myMapSupportsIter = myMapSupports.begin(); - for( ; myMapSupportsIter != myMapSupports.end(); myMapSupportsIter++ ) - { - SUPPORT* mySupport; - CPPUNIT_ASSERT_NO_THROW(mySupport = myMed->getSupport(mesh_names[nb], (*myMapSupportsIter).first)); - CPPUNIT_ASSERT_EQUAL(mySupport, (*myMapSupportsIter).second); - CPPUNIT_ASSERT(mySupport->deepCompare(*(*myMapSupportsIter).second)); - } - } - - // add new driver - int idMedV21; - - try - { - idMedV21 = myMed->addDriver(MED_DRIVER,filenameout21); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - // write to file - CPPUNIT_ASSERT_NO_THROW(myMed->write(idMedV21)); - // check, that the file is created on disk - CPPUNIT_ASSERT(access(filenameout21.data(), F_OK) == 0); - - // writeFrom - CPPUNIT_ASSERT_THROW(myMed->writeFrom(idMedV21 + 1000), MEDEXCEPTION); // invalid driver index - int idMedV21_from = myMed->addDriver(MED_DRIVER, filenameout21_from); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) MED::writeFrom(int) always throws MEDEXCEPTION. - // ? missed 'else' clause before throw ? - CPPUNIT_ASSERT_NO_THROW(myMed->writeFrom(idMedV21_from)); -#endif - // check, that the file is created on disk -#ifdef ENABLE_FORCED_FAILURES - // ? (BUG) The file is not created. - CPPUNIT_ASSERT(access(filenameout21_from.data(), F_OK) == 0); -#endif - - // remove driver from med - CPPUNIT_ASSERT_NO_THROW(myMed->rmDriver(idMedV21)); -#ifdef ENABLE_FORCED_FAILURES - //ERROR: driver with index idMedV21 has not been removed - // Why driver removal is commented out? - // ensure exception is raised on second attempt to remove driver - CPPUNIT_ASSERT_THROW(myMed->rmDriver(idMedV21),MEDEXCEPTION); -#endif - - //create empty MED object - MED* myEmptyMed = new MED(); - // create new driver for med object - // and add driver to med - int idDriver; - GENDRIVER *driver = DRIVERFACTORY::buildDriverForMed(MED_DRIVER,filename,myEmptyMed,MED_LECT); - try{ - idDriver = myEmptyMed->addDriver(*driver); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT(idDriver == 0); - - // trying to read file with non-existent index of driver - // read file and create empty object - CPPUNIT_ASSERT_NO_THROW(myEmptyMed->readFileStruct()); - - //getNumberOfMeshes - int nbEmptyMeshes, nbEmptyFields; - try{ - nbEmptyMeshes = myEmptyMed->getNumberOfMeshes(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT(nbEmptyMeshes == nbMeshes); - - //getMeshNames - deque<string> empty_mesh_names, empty_field_names; - try{ - empty_mesh_names = myEmptyMed->getMeshNames(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT(empty_mesh_names.size() != 0); - - //getNumberOfFields - try{ - nbEmptyFields = myEmptyMed->getNumberOfFields(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT(nbFields == nbEmptyFields); - - //getFieldNames - try{ - empty_field_names = myEmptyMed->getFieldNames(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT(empty_field_names.size() != 0); - - //compare mesh names, produced by two different methods - for(int nb = 0; nb < nbMeshes; nb++ ) - { - MESH* myMesh; - CPPUNIT_ASSERT(empty_mesh_names[nb] == mesh_names[nb]); - CPPUNIT_ASSERT_NO_THROW(myMesh = myEmptyMed->getMesh(empty_mesh_names[nb])); - //MESH* myMesh1 = myMed->getMesh(mesh_names[nb]); - CPPUNIT_ASSERT(!myMesh->deepCompare(*(myMed->getMesh(mesh_names[nb])))); - //ensure mesh is empty - CPPUNIT_ASSERT(myMesh->getSpaceDimension() == MED_INVALID); - CPPUNIT_ASSERT(myMesh->getNumberOfNodes() == MED_INVALID); - CPPUNIT_ASSERT(myMesh->getCoordinateptr() == NULL); - } - - // trying to add null mesh pointer - CPPUNIT_ASSERT_THROW(myEmptyMed->addMesh(NULL), MEDEXCEPTION); - - //create a mesh - MESH * aMesh = MEDMEMTest_createTestMesh(); - // and add it - CPPUNIT_ASSERT_NO_THROW(myEmptyMed->addMesh(aMesh)); - - //compare two meshes - CPPUNIT_ASSERT(aMesh->deepCompare(*(myEmptyMed->getMesh("meshing")))); - - // add null field, exception should be raised - CPPUNIT_ASSERT_THROW(myEmptyMed->addField(NULL), MEDEXCEPTION); - // - FIELD_* myEmptyField = new FIELD_(); - // add empty field, ensure exception is raised - CPPUNIT_ASSERT_THROW(myEmptyMed->addField(myEmptyField), MEDEXCEPTION); - //set field name - myEmptyField->setName("myField"); - - // set support - SUPPORT* aSupport = new SUPPORT(myEmptyMed->getMesh("meshing"), "Support On Cells"); - myEmptyField->setSupport(aSupport); - - CPPUNIT_ASSERT_NO_THROW(myEmptyMed->addField(myEmptyField)); - - CPPUNIT_ASSERT(aSupport->deepCompare(*(myEmptyMed->getSupport("meshing",MED_CELL)))); - CPPUNIT_ASSERT(aMesh->deepCompare(*(myEmptyMed->getMesh("meshing")))); - - delete myMed; - delete myEmptyMed; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_MedFieldDriver21.cxx b/src/MEDMEM/Test/MEDMEMTest_MedFieldDriver21.cxx deleted file mode 100644 index 262bfabe6..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_MedFieldDriver21.cxx +++ /dev/null @@ -1,625 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include <MEDMEM_Field.hxx> -#include <MEDMEM_MedFieldDriver21.hxx> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -/*! - * Check methods (17), defined in MEDMEM_MedFieldDriver21.hxx: - * template <class T> class MED_FIELD_DRIVER21 : public virtual MED_FIELD_DRIVER<T> { - * (+) MED_FIELD_DRIVER21(); - * (+) template <class INTERLACING_TAG> MED_FIELD_DRIVER21(const string & fileName, - * FIELD<T, INTERLACING_TAG> * ptrField, MED_EN::med_mode_acces accessMode); - * (+) MED_FIELD_DRIVER21(const MED_FIELD_DRIVER21 & fieldDriver); - * (+) virtual ~MED_FIELD_DRIVER21(); - * (+) void open() throw (MEDEXCEPTION); - * (+) void close(); - * } - * template <class T> class MED_FIELD_RDONLY_DRIVER21 : public virtual MED_FIELD_DRIVER21<T>, - * public virtual IMED_FIELD_RDONLY_DRIVER<T> { - * (+) MED_FIELD_RDONLY_DRIVER21(); - * (+) template <class INTERLACING_TAG> MED_FIELD_RDONLY_DRIVER21 - * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField); - * (+) MED_FIELD_RDONLY_DRIVER21(const MED_FIELD_RDONLY_DRIVER21 & fieldDriver); - * (+) virtual ~MED_FIELD_RDONLY_DRIVER21(); - * (+) void write(void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * } - * template <class T> class MED_FIELD_WRONLY_DRIVER21 : public virtual MED_FIELD_DRIVER21<T>, - * public virtual IMED_FIELD_WRONLY_DRIVER<T> { - * (+) MED_FIELD_WRONLY_DRIVER21(); - * (+) template <class INTERLACING_TAG> MED_FIELD_WRONLY_DRIVER21 - * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField); - * (+) MED_FIELD_WRONLY_DRIVER21(const MED_FIELD_WRONLY_DRIVER21 & fieldDriver); - * (+) virtual ~MED_FIELD_WRONLY_DRIVER21(); - * (+) void write(void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * } - * template <class T> class MED_FIELD_RDWR_DRIVER21 : public MED_FIELD_RDONLY_DRIVER21<T>, - * public MED_FIELD_WRONLY_DRIVER21<T>, public IMED_FIELD_RDWR_DRIVER<T> { - * (+) MED_FIELD_RDWR_DRIVER21(); - * (+) template <class INTERLACING_TAG> MED_FIELD_RDWR_DRIVER21 - * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField); - * (+) MED_FIELD_RDWR_DRIVER21(const MED_FIELD_RDWR_DRIVER21 & fieldDriver); - * (+) ~MED_FIELD_RDWR_DRIVER21(); - * (+) void write(void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * } - */ -void MEDMEMTest::testMedFieldDriver21() -{ - FIELD<int> *aField = new FIELD<int> (); - FIELD<int> *aField_1 = new FIELD<int> (); - FIELD<double> *aField_2 = new FIELD<double> (); - string data_dir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - if (tmp_dir == "") - tmp_dir = "/tmp"; - string filename_rd = data_dir + "/MedFiles/pointe.med"; - string filenameWithOutFileds = data_dir + "/MedFiles/Mistrat.med"; - string fileldnotexist = "anyfield"; - string fieldname = "fieldnodeint"; - string fieldname_cpy = fieldname + "_cpy"; - string fileNotExist_rd = "notExist.med"; - string emptyfilename = ""; - - string filename_wr = tmp_dir + "/myWrField_pointe21.med"; - string cp_file_wr = "cp " + filename_rd + " " + filename_wr; - string fileNotExist_wr = "/path_not_exist/file_not_exist.med"; - string emptyfile_wr = tmp_dir + "/myWrField_pointe_empty21.med"; - string other_file = data_dir + "/MedFiles/fra.med"; - string other_file_wr = tmp_dir + "/myWRfra.med"; - string cp_other_file = "cp " + other_file + " " + other_file_wr; - - string filename_rdwr = tmp_dir + "/myRdWrField_pointe21.med"; - string cp_file_rdwr = "cp " + filename_rd + " " + filename_rdwr; - string emptyfile_rdwr = tmp_dir + "/myRdWrField_pointe_empty21.med"; - string fieldnameDouble = "fieldnodedouble"; - string fieldnameDouble_cpy = fieldnameDouble + "_cpy"; - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filename_wr); - aRemover.Register(emptyfile_wr); - aRemover.Register(other_file_wr); - aRemover.Register(filename_rdwr); - aRemover.Register(emptyfile_rdwr); - - //--------------------------Test READ ONLY part------------------------------// - - ///////////////////////////////////// - // TEST1: Open not existing file // - ///////////////////////////////////// - - //Creation Invalid Read Only MedFieldDriver21 (file not exist) - MED_FIELD_RDONLY_DRIVER21<int> *aInvalidMedRdFieldDriver21_1 = - new MED_FIELD_RDONLY_DRIVER21<int>(fileNotExist_rd, aField); - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedRdFieldDriver21_1->open(), MEDEXCEPTION); - - ////////////////////////////////////////////// - // TEST2: Open file with empty file name /// - ////////////////////////////////////////////// - - //Creation Invalid Read Only MedFieldDriver21 (empty file name) - MED_FIELD_RDONLY_DRIVER21<int> *aInvalidMedRdFieldDriver21_2 = - new MED_FIELD_RDONLY_DRIVER21<int>(emptyfilename, aField); - //Trying file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedRdFieldDriver21_2->open(), MEDEXCEPTION); - - ///////////////////////////////////////////////////// - // TEST3: Reading field from file without fields // - ///////////////////////////////////////////////////// - MED_FIELD_RDONLY_DRIVER21<int> *aInvalidMedRdFieldDriver21_3 = - new MED_FIELD_RDONLY_DRIVER21<int>(filenameWithOutFileds, aField); - aInvalidMedRdFieldDriver21_3->open(); - aInvalidMedRdFieldDriver21_3->setFieldName(fieldname); - //Trying read field from file - CPPUNIT_ASSERT_THROW(aInvalidMedRdFieldDriver21_3->read(), MEDEXCEPTION); - aInvalidMedRdFieldDriver21_3->close(); - - //////////////////////// - // TEST4: Main test // - //////////////////////// - //Creation correct Read Only MedFieldDriver21 - MED_FIELD_RDONLY_DRIVER21<int> *aMedRdFieldDriver21 = - new MED_FIELD_RDONLY_DRIVER21<int>(filename_rd, aField); - - //Check driver - CPPUNIT_ASSERT(aMedRdFieldDriver21); - - //Trying read field before open file - CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->read(),MEDEXCEPTION); - - //Test open() method - try - { - aMedRdFieldDriver21->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FORCED_FAILURES - //Trying open file secondary. - CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->open(), MEDEXCEPTION); - // (BUG) No exception in this case -#endif - - //Trying read field form file if it name is empty - CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->read(), MEDEXCEPTION); - - //Test setFieldName() and getFieldName() - try - { - aMedRdFieldDriver21->setFieldName(fileldnotexist); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT_EQUAL(fileldnotexist, aMedRdFieldDriver21->getFieldName()); - - //Trying read not existing field from file - CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->read(), MEDEXCEPTION); - - //Test read() method - aMedRdFieldDriver21->setFieldName(fieldname); - try - { - aMedRdFieldDriver21->read(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test write() method for READ ONLY driver - CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->write(), MEDEXCEPTION); - - //Test close() method - try - { - aMedRdFieldDriver21->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_FIELD_RDONLY_DRIVER21<int> aMedRdFieldDriver21Cpy_1; - - //Test (void operator =) defined in GENDRIVER class in MEDMEM_GenDriver.hxx - aMedRdFieldDriver21Cpy_1 = *aMedRdFieldDriver21; - - //Test (bool operator ==) defined GENDRIVER class in MEDMEM_GenDriver.hxx - CPPUNIT_ASSERT(aMedRdFieldDriver21Cpy_1 == *aMedRdFieldDriver21); - - //Test copy constructor - MED_FIELD_RDONLY_DRIVER21<int> aMedRdFieldDriver21Cpy_2 (*aMedRdFieldDriver21); - CPPUNIT_ASSERT_EQUAL(aMedRdFieldDriver21Cpy_2, *aMedRdFieldDriver21); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream rostr1, rostr2; - rostr1<<aMedRdFieldDriver21Cpy_1; - rostr2<<aMedRdFieldDriver21Cpy_2; - CPPUNIT_ASSERT(rostr1.str() != ""); - CPPUNIT_ASSERT(rostr1.str() == rostr2.str()); - - - //--------------------------Test WRITE ONLY part------------------------------// - - //Copy file - system(cp_other_file.c_str()); - system(cp_file_wr.c_str()); - - ///////////////////////////////////// - // TEST1: Open not existing file // - ///////////////////////////////////// - - //Creation Invalid Write Only MedFieldDriver21 (file not exist) - MED_FIELD_WRONLY_DRIVER21<int> *aInvalidMedWrFieldDriver21_1 = - new MED_FIELD_WRONLY_DRIVER21<int>(fileNotExist_wr, aField_1); - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver21_1->open(), MEDEXCEPTION); - - ///////////////////////////////////////////// - // TEST2: Open file with empty file name // - ///////////////////////////////////////////// - //Creation Invalid Write Only MedFieldDriver21 (empty file name) - MED_FIELD_WRONLY_DRIVER21<int> *aInvalidMedWrFieldDriver21_2 = - new MED_FIELD_WRONLY_DRIVER21<int>(emptyfilename, aField_1); - //Trying open not existing file and file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver21_2->open(), MEDEXCEPTION); - - /////////////////////////////////////////////////////// - // TEST3: Writing field in empty file without mesh // - /////////////////////////////////////////////////////// - //Creation Invalid Write Only MedFieldDriver21 - MED_FIELD_WRONLY_DRIVER21<int> *aInvalidMedWrFieldDriver21_3 = - new MED_FIELD_WRONLY_DRIVER21<int>(emptyfile_wr, aField); - - aInvalidMedWrFieldDriver21_3->open(); -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver21_3->write(), MEDEXCEPTION); - //=>Segmentation fault in this case -#endif - - ////////////////////////////////////////////// - // TEST4: Writing field in the other file // - ////////////////////////////////////////////// - - //Creation Invalid Write Only MedFieldDriver21 - MED_FIELD_WRONLY_DRIVER21<int> *aInvalidMedWrFieldDriver21_4 = - new MED_FIELD_WRONLY_DRIVER21<int>(other_file_wr, aField); - aInvalidMedWrFieldDriver21_4->open(); -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver21_4->write(), MEDEXCEPTION); - //=>Segmentation fault in this case -#endif - - //////////////////////// - // TEST5: Main test // - //////////////////////// - - //Creation correct Write Only MedFieldDriver21 - MED_FIELD_WRONLY_DRIVER21<int> *aMedWrFieldDriver21 = - new MED_FIELD_WRONLY_DRIVER21<int>(filename_wr, aField); - - //Check driver - CPPUNIT_ASSERT(aMedWrFieldDriver21); - - //Trying write field before open file -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedWrFieldDriver21->write(),MEDEXCEPTION); - // (BUG) No exception in this case -#endif - - //Test open() method - try - { - aMedWrFieldDriver21->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FORCED_FAILURES - //Trying open file secondary. - CPPUNIT_ASSERT_THROW(aMedWrFieldDriver21->open(), MEDEXCEPTION); - // (BUG) No exception in this case -#endif - - //Test setFieldName() and getFieldName - aField->setName(fieldname_cpy); - try - { - aMedWrFieldDriver21->setFieldName(fieldname_cpy); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT_EQUAL(fieldname_cpy, aMedWrFieldDriver21->getFieldName()); - -#ifdef ENABLE_FAULTS - //Test write() method - try - { - aMedWrFieldDriver21->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - //=>Segmentation fault in this case -#endif - - //Test read() method for Write only part - CPPUNIT_ASSERT_THROW(aMedWrFieldDriver21->read(),MEDEXCEPTION); - - //Test close() method - try - { - aMedWrFieldDriver21->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_FIELD_WRONLY_DRIVER21<int> aMedWrFieldDriver21Cpy_1; - - //Test (void operator =) defined in GENDRIVER class - //aMedWrFieldDriver21Cpy_1 = *aMedWrFieldDriver21; - - //Test (bool operator ==) defined in GENDRIVER class - CPPUNIT_ASSERT(aMedWrFieldDriver21Cpy_1.GENDRIVER::operator==(*aMedWrFieldDriver21)); - - //Test copy constructor - MED_FIELD_WRONLY_DRIVER21<int> aMedWrFieldDriver21Cpy_2 (*aMedWrFieldDriver21); - CPPUNIT_ASSERT_EQUAL(aMedWrFieldDriver21Cpy_2, *aMedWrFieldDriver21); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream wostr1, wostr2; - wostr1 << aMedWrFieldDriver21Cpy_1; - wostr2 << aMedWrFieldDriver21Cpy_2; - CPPUNIT_ASSERT(wostr1.str() != ""); - CPPUNIT_ASSERT(wostr1.str() == wostr2.str()); - - - //--------------------------Test READ/WRITE part------------------------------// - - //Copy files - system(cp_file_rdwr.c_str()); - ///////////////////////////////////// - // TEST1: Open not existing file // - ///////////////////////////////////// - - //Creation Invalid Read/Write MedFieldDriver21 (file not exist) - MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_1 = - new MED_FIELD_RDWR_DRIVER21<int>(fileNotExist_wr, aField_1); - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_1->open(), MEDEXCEPTION); - - ///////////////////////////////////////////// - // TEST2: Open file with empty file name // - ///////////////////////////////////////////// - //Creation Invalid Read/Write MedFieldDriver21 (empty file name) - MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_2 = - new MED_FIELD_RDWR_DRIVER21<int>(emptyfilename, aField_1); - //Trying open not existing file and file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_2->open(), MEDEXCEPTION); - - ///////////////////////////////////////////////////// - // TEST3: Reading field from file without fields // - ///////////////////////////////////////////////////// - MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_3 = - new MED_FIELD_RDWR_DRIVER21<int>(filenameWithOutFileds, aField_1); - aInvalidMedRdWrFieldDriver21_3->open(); - aInvalidMedRdWrFieldDriver21_3->setFieldName(fieldname); - //Trying read field from file - CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_3->read(), MEDEXCEPTION); - aInvalidMedRdWrFieldDriver21_3->close(); - - /////////////////////////////////////////////////////// - // TEST4: Writing field in empty file without mesh // - /////////////////////////////////////////////////////// - //Creation Invalid Read/Write MedFieldDriver21 - MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_4 = - new MED_FIELD_RDWR_DRIVER21<int>(emptyfile_rdwr, aField); - - aInvalidMedRdWrFieldDriver21_4->open(); -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_4->write(), MEDEXCEPTION); - //=>Segmentation fault in this case -#endif - - ////////////////////////////////////////////// - // TEST6: Writing field in the other file // - ////////////////////////////////////////////// - //Creation Invalid Read/Write MedFieldDriver21 - MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_5 = - new MED_FIELD_RDWR_DRIVER21<int>(other_file_wr, aField); - aInvalidMedRdWrFieldDriver21_5->open(); -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_5->write(), MEDEXCEPTION); - //=>Segmentation fault in this case -#endif - - //////////////////////// - // TEST7: Main test // - //////////////////////// - - //Creation correct Read/Write MedFieldDriver21 - MED_FIELD_RDWR_DRIVER21<double> *aMedRdWrFieldDriver21 = - new MED_FIELD_RDWR_DRIVER21<double>(filename_rdwr, aField_2); - - //Check driver - CPPUNIT_ASSERT(aMedRdWrFieldDriver21); - - //Trying read/write field before open file - CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->read(),MEDEXCEPTION); -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->write(),MEDEXCEPTION); - //(BUG) No exception in this case -#endif - - //Test open() method - try - { - aMedRdWrFieldDriver21->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FORCED_FAILURES - //Trying open file secondary. - CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->open(), MEDEXCEPTION); - // (BUG) No exception in this case -#endif - - //Trying read field from file if field name is empty - CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->read(), MEDEXCEPTION); - - //Test setFieldName() and getFieldName - try - { - aMedRdWrFieldDriver21->setFieldName(fileldnotexist); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT_EQUAL(fileldnotexist, aMedRdWrFieldDriver21->getFieldName()); - - //Trying read not existing field from file - CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->read(), MEDEXCEPTION); - - //Test read() method - aMedRdWrFieldDriver21->setFieldName(fieldnameDouble); - try - { - aMedRdWrFieldDriver21->read(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying write field in the file with empty name - aField_2->setName(emptyfilename); - aMedRdWrFieldDriver21->setFieldName(emptyfilename); - CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->write(), MEDEXCEPTION); - - //Test write() method - aField_2->setName(fieldnameDouble_cpy); - aMedRdWrFieldDriver21->setFieldName(fieldnameDouble_cpy); -#ifdef ENABLE_FAULTS - try - { - aMedRdWrFieldDriver21->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - //=>Segmentation fault in this case -#endif - - //Test close() method - try - { - aMedRdWrFieldDriver21->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_FIELD_RDWR_DRIVER21<double> aMedRdWrFieldDriver21Cpy_1; - - //Test (void operator =) defined in GENDRIVER class - //aMedRdWrFieldDriver21Cpy_1 = *aMedRdWrFieldDriver21; - - //Test (bool operator ==) defined in GENDRIVER class - CPPUNIT_ASSERT(aMedRdWrFieldDriver21Cpy_1.GENDRIVER::operator==(*aMedRdWrFieldDriver21)); - - //Test copy constructor - MED_FIELD_RDWR_DRIVER21<double> aMedRdWrFieldDriver21Cpy_2 (*aMedRdWrFieldDriver21); - CPPUNIT_ASSERT_EQUAL(aMedRdWrFieldDriver21Cpy_2, *aMedRdWrFieldDriver21); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream rwostr1, rwostr2; - rwostr1 << aMedRdWrFieldDriver21Cpy_1; - rwostr2 << aMedRdWrFieldDriver21Cpy_2; - CPPUNIT_ASSERT(rwostr1.str() != ""); - CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - //Delete all objects - delete aField; - delete aField_1; - delete aField_2; - - delete aInvalidMedRdFieldDriver21_1; - delete aInvalidMedRdFieldDriver21_2; - delete aInvalidMedRdFieldDriver21_3; - delete aMedRdFieldDriver21; - - delete aInvalidMedWrFieldDriver21_1; - delete aInvalidMedWrFieldDriver21_2; - delete aInvalidMedWrFieldDriver21_3; - delete aInvalidMedWrFieldDriver21_4; - delete aMedWrFieldDriver21; - - delete aInvalidMedRdWrFieldDriver21_1; - delete aInvalidMedRdWrFieldDriver21_2; - delete aInvalidMedRdWrFieldDriver21_3; - delete aInvalidMedRdWrFieldDriver21_4; - delete aInvalidMedRdWrFieldDriver21_5; - delete aMedRdWrFieldDriver21; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_MedFieldDriver21_fault.cxx b/src/MEDMEM/Test/MEDMEMTest_MedFieldDriver21_fault.cxx deleted file mode 100644 index 1011762a1..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_MedFieldDriver21_fault.cxx +++ /dev/null @@ -1,630 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include <MEDMEM_Field.hxx> -#include <MEDMEM_MedFieldDriver21.hxx> - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -//#define ENABLE_FORCED_FAILURES - -/*! - * Check methods (17), defined in MEDMEM_MedFieldDriver21.hxx: - * template <class T> class MED_FIELD_DRIVER21 : public virtual MED_FIELD_DRIVER<T> { - * (+) MED_FIELD_DRIVER21(); - * (+) template <class INTERLACING_TAG> MED_FIELD_DRIVER21(const string & fileName, - * FIELD<T, INTERLACING_TAG> * ptrField, MED_EN::med_mode_acces accessMode); - * (+) MED_FIELD_DRIVER21(const MED_FIELD_DRIVER21 & fieldDriver); - * (+) virtual ~MED_FIELD_DRIVER21(); - * (+) void open() throw (MEDEXCEPTION); - * (+) void close(); - * } - * template <class T> class MED_FIELD_RDONLY_DRIVER21 : public virtual MED_FIELD_DRIVER21<T>, - * public virtual IMED_FIELD_RDONLY_DRIVER<T> { - * (+) MED_FIELD_RDONLY_DRIVER21(); - * (+) template <class INTERLACING_TAG> MED_FIELD_RDONLY_DRIVER21 - * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField); - * (+) MED_FIELD_RDONLY_DRIVER21(const MED_FIELD_RDONLY_DRIVER21 & fieldDriver); - * (+) virtual ~MED_FIELD_RDONLY_DRIVER21(); - * (+) void write(void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * } - * template <class T> class MED_FIELD_WRONLY_DRIVER21 : public virtual MED_FIELD_DRIVER21<T>, - * public virtual IMED_FIELD_WRONLY_DRIVER<T> { - * (+) MED_FIELD_WRONLY_DRIVER21(); - * (+) template <class INTERLACING_TAG> MED_FIELD_WRONLY_DRIVER21 - * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField); - * (+) MED_FIELD_WRONLY_DRIVER21(const MED_FIELD_WRONLY_DRIVER21 & fieldDriver); - * (+) virtual ~MED_FIELD_WRONLY_DRIVER21(); - * (+) void write(void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * } - * template <class T> class MED_FIELD_RDWR_DRIVER21 : public MED_FIELD_RDONLY_DRIVER21<T>, - * public MED_FIELD_WRONLY_DRIVER21<T>, public IMED_FIELD_RDWR_DRIVER<T> { - * (+) MED_FIELD_RDWR_DRIVER21(); - * (+) template <class INTERLACING_TAG> MED_FIELD_RDWR_DRIVER21 - * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField); - * (+) MED_FIELD_RDWR_DRIVER21(const MED_FIELD_RDWR_DRIVER21 & fieldDriver); - * (+) ~MED_FIELD_RDWR_DRIVER21(); - * (+) void write(void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * } - */ -void MEDMEMTest_testMedFieldDriver21() -{ - FIELD<int> *aField = new FIELD<int> (); - FIELD<int> *aField_1 = new FIELD<int> (); - FIELD<double> *aField_2 = new FIELD<double> (); - string data_dir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - if (tmp_dir == "") - tmp_dir = "/tmp"; - string filename_rd = data_dir + "/MedFiles/pointe.med"; - string filenameWithOutFileds = data_dir + "/MedFiles/Mistrat.med"; - string fileldnotexist = "anyfield"; - string fieldname = "fieldnodeint"; - string fieldname_cpy = fieldname + "_cpy"; - string fileNotExist_rd = "notExist.med"; - string emptyfilename = ""; - - string filename_wr = tmp_dir + "/myWrField_pointe21.med"; - string cp_file_wr = "cp " + filename_rd + " " + filename_wr; - string fileNotExist_wr = "/path_not_exist/file_not_exist.med"; - string emptyfile_wr = tmp_dir + "/myWrField_pointe_empty21.med"; - string other_file = data_dir + "/MedFiles/fra.med"; - string other_file_wr = tmp_dir + "/myWRfra.med"; - string cp_other_file = "cp " + other_file + " " + other_file_wr; - - string filename_rdwr = tmp_dir + "/myRdWrField_pointe21.med"; - string cp_file_rdwr = "cp " + filename_rd + " " + filename_rdwr; - string emptyfile_rdwr = tmp_dir + "/myRdWrField_pointe_empty21.med"; - string fieldnameDouble = "fieldnodedouble"; - string fieldnameDouble_cpy = fieldnameDouble + "_cpy"; - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filename_wr); - aRemover.Register(emptyfile_wr); - aRemover.Register(other_file_wr); - aRemover.Register(filename_rdwr); - aRemover.Register(emptyfile_rdwr); - - //--------------------------Test READ ONLY part------------------------------// - - ///////////////////////////////////// - // TEST1: Open not existing file // - ///////////////////////////////////// - - //Creation Invalid Read Only MedFieldDriver21 (file not exist) - MED_FIELD_RDONLY_DRIVER21<int> *aInvalidMedRdFieldDriver21_1 = - new MED_FIELD_RDONLY_DRIVER21<int>(fileNotExist_rd, aField); - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedRdFieldDriver21_1->open(), MEDEXCEPTION); - - ////////////////////////////////////////////// - // TEST2: Open file with empty file name /// - ////////////////////////////////////////////// - - //Creation Invalid Read Only MedFieldDriver21 (empty file name) - MED_FIELD_RDONLY_DRIVER21<int> *aInvalidMedRdFieldDriver21_2 = - new MED_FIELD_RDONLY_DRIVER21<int>(emptyfilename, aField); - //Trying file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedRdFieldDriver21_2->open(), MEDEXCEPTION); - - ///////////////////////////////////////////////////// - // TEST3: Reading field from file without fields // - ///////////////////////////////////////////////////// - MED_FIELD_RDONLY_DRIVER21<int> *aInvalidMedRdFieldDriver21_3 = - new MED_FIELD_RDONLY_DRIVER21<int>(filenameWithOutFileds, aField); - aInvalidMedRdFieldDriver21_3->open(); - aInvalidMedRdFieldDriver21_3->setFieldName(fieldname); - //Trying read field from file - CPPUNIT_ASSERT_THROW(aInvalidMedRdFieldDriver21_3->read(), MEDEXCEPTION); - aInvalidMedRdFieldDriver21_3->close(); - - //////////////////////// - // TEST4: Main test // - //////////////////////// - //Creation correct Read Only MedFieldDriver21 - MED_FIELD_RDONLY_DRIVER21<int> *aMedRdFieldDriver21 = - new MED_FIELD_RDONLY_DRIVER21<int>(filename_rd, aField); - - //Check driver - CPPUNIT_ASSERT(aMedRdFieldDriver21); - - //Trying read field before open file - CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->read(),MEDEXCEPTION); - - //Test open() method - try - { - aMedRdFieldDriver21->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FORCED_FAILURES - //Trying open file secondary. - CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->open(), MEDEXCEPTION); - // (BUG) No exception in this case -#endif - - //Trying read field form file if it name is empty - CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->read(), MEDEXCEPTION); - - //Test setFieldName() and getFieldName() - try - { - aMedRdFieldDriver21->setFieldName(fileldnotexist); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT_EQUAL(fileldnotexist, aMedRdFieldDriver21->getFieldName()); - - //Trying read not existing field from file - CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->read(), MEDEXCEPTION); - - //Test read() method - aMedRdFieldDriver21->setFieldName(fieldname); - try - { - aMedRdFieldDriver21->read(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test write() method for READ ONLY driver - CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->write(), MEDEXCEPTION); - - //Test close() method - try - { - aMedRdFieldDriver21->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_FIELD_RDONLY_DRIVER21<int> aMedRdFieldDriver21Cpy_1; - - //Test (void operator =) defined in GENDRIVER class in MEDMEM_GenDriver.hxx - aMedRdFieldDriver21Cpy_1 = *aMedRdFieldDriver21; - - //Test (bool operator ==) defined GENDRIVER class in MEDMEM_GenDriver.hxx - CPPUNIT_ASSERT(aMedRdFieldDriver21Cpy_1 == *aMedRdFieldDriver21); - - //Test copy constructor - MED_FIELD_RDONLY_DRIVER21<int> aMedRdFieldDriver21Cpy_2 (*aMedRdFieldDriver21); - CPPUNIT_ASSERT_EQUAL(aMedRdFieldDriver21Cpy_2, *aMedRdFieldDriver21); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream rostr1, rostr2; - rostr1<<aMedRdFieldDriver21Cpy_1; - rostr2<<aMedRdFieldDriver21Cpy_2; - CPPUNIT_ASSERT(rostr1.str() != ""); - CPPUNIT_ASSERT(rostr1.str() == rostr2.str()); - - - //--------------------------Test WRITE ONLY part------------------------------// - - //Copy file - system(cp_other_file.c_str()); - system(cp_file_wr.c_str()); - - ///////////////////////////////////// - // TEST1: Open not existing file // - ///////////////////////////////////// - - //Creation Invalid Write Only MedFieldDriver21 (file not exist) - MED_FIELD_WRONLY_DRIVER21<int> *aInvalidMedWrFieldDriver21_1 = - new MED_FIELD_WRONLY_DRIVER21<int>(fileNotExist_wr, aField_1); - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver21_1->open(), MEDEXCEPTION); - - ///////////////////////////////////////////// - // TEST2: Open file with empty file name // - ///////////////////////////////////////////// - //Creation Invalid Write Only MedFieldDriver21 (empty file name) - MED_FIELD_WRONLY_DRIVER21<int> *aInvalidMedWrFieldDriver21_2 = - new MED_FIELD_WRONLY_DRIVER21<int>(emptyfilename, aField_1); - //Trying open not existing file and file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver21_2->open(), MEDEXCEPTION); - - /////////////////////////////////////////////////////// - // TEST3: Writing field in empty file without mesh // - /////////////////////////////////////////////////////// - //Creation Invalid Write Only MedFieldDriver21 - MED_FIELD_WRONLY_DRIVER21<int> *aInvalidMedWrFieldDriver21_3 = - new MED_FIELD_WRONLY_DRIVER21<int>(emptyfile_wr, aField); - - aInvalidMedWrFieldDriver21_3->open(); -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver21_3->write(), MEDEXCEPTION); - //=>Segmentation fault in this case -#endif - - ////////////////////////////////////////////// - // TEST4: Writing field in the other file // - ////////////////////////////////////////////// - - //Creation Invalid Write Only MedFieldDriver21 - MED_FIELD_WRONLY_DRIVER21<int> *aInvalidMedWrFieldDriver21_4 = - new MED_FIELD_WRONLY_DRIVER21<int>(other_file_wr, aField); - aInvalidMedWrFieldDriver21_4->open(); -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver21_4->write(), MEDEXCEPTION); - //=>Segmentation fault in this case -#endif - - //////////////////////// - // TEST5: Main test // - //////////////////////// - - //Creation correct Write Only MedFieldDriver21 - MED_FIELD_WRONLY_DRIVER21<int> *aMedWrFieldDriver21 = - new MED_FIELD_WRONLY_DRIVER21<int>(filename_wr, aField); - - //Check driver - CPPUNIT_ASSERT(aMedWrFieldDriver21); - - //Trying write field before open file -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedWrFieldDriver21->write(),MEDEXCEPTION); - // (BUG) No exception in this case -#endif - - //Test open() method - try - { - aMedWrFieldDriver21->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FORCED_FAILURES - //Trying open file secondary. - CPPUNIT_ASSERT_THROW(aMedWrFieldDriver21->open(), MEDEXCEPTION); - // (BUG) No exception in this case -#endif - - //Test setFieldName() and getFieldName - aField->setName(fieldname_cpy); - try - { - aMedWrFieldDriver21->setFieldName(fieldname_cpy); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT_EQUAL(fieldname_cpy, aMedWrFieldDriver21->getFieldName()); - -#ifdef ENABLE_FAULTS - //Test write() method - try - { - aMedWrFieldDriver21->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - //=>Segmentation fault in this case -#endif - - //Test read() method for Write only part - CPPUNIT_ASSERT_THROW(aMedWrFieldDriver21->read(),MEDEXCEPTION); - - //Test close() method - try - { - aMedWrFieldDriver21->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_FIELD_WRONLY_DRIVER21<int> aMedWrFieldDriver21Cpy_1; - - //Test (void operator =) defined in GENDRIVER class - //aMedWrFieldDriver21Cpy_1 = *aMedWrFieldDriver21; - - //Test (bool operator ==) defined in GENDRIVER class - CPPUNIT_ASSERT(aMedWrFieldDriver21Cpy_1.GENDRIVER::operator==(*aMedWrFieldDriver21)); - - //Test copy constructor - MED_FIELD_WRONLY_DRIVER21<int> aMedWrFieldDriver21Cpy_2 (*aMedWrFieldDriver21); - CPPUNIT_ASSERT_EQUAL(aMedWrFieldDriver21Cpy_2, *aMedWrFieldDriver21); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream wostr1, wostr2; - wostr1 << aMedWrFieldDriver21Cpy_1; - wostr2 << aMedWrFieldDriver21Cpy_2; - CPPUNIT_ASSERT(wostr1.str() != ""); - CPPUNIT_ASSERT(wostr1.str() == wostr2.str()); - - - //--------------------------Test READ/WRITE part------------------------------// - - //Copy files - system(cp_file_rdwr.c_str()); - ///////////////////////////////////// - // TEST1: Open not existing file // - ///////////////////////////////////// - - //Creation Invalid Read/Write MedFieldDriver21 (file not exist) - MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_1 = - new MED_FIELD_RDWR_DRIVER21<int>(fileNotExist_wr, aField_1); - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_1->open(), MEDEXCEPTION); - - ///////////////////////////////////////////// - // TEST2: Open file with empty file name // - ///////////////////////////////////////////// - //Creation Invalid Read/Write MedFieldDriver21 (empty file name) - MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_2 = - new MED_FIELD_RDWR_DRIVER21<int>(emptyfilename, aField_1); - //Trying open not existing file and file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_2->open(), MEDEXCEPTION); - - ///////////////////////////////////////////////////// - // TEST3: Reading field from file without fields // - ///////////////////////////////////////////////////// - MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_3 = - new MED_FIELD_RDWR_DRIVER21<int>(filenameWithOutFileds, aField_1); - aInvalidMedRdWrFieldDriver21_3->open(); - aInvalidMedRdWrFieldDriver21_3->setFieldName(fieldname); - //Trying read field from file - CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_3->read(), MEDEXCEPTION); - aInvalidMedRdWrFieldDriver21_3->close(); - - /////////////////////////////////////////////////////// - // TEST4: Writing field in empty file without mesh // - /////////////////////////////////////////////////////// - //Creation Invalid Read/Write MedFieldDriver21 - MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_4 = - new MED_FIELD_RDWR_DRIVER21<int>(emptyfile_rdwr, aField); - - aInvalidMedRdWrFieldDriver21_4->open(); -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_4->write(), MEDEXCEPTION); - //=>Segmentation fault in this case -#endif - - ////////////////////////////////////////////// - // TEST6: Writing field in the other file // - ////////////////////////////////////////////// - //Creation Invalid Read/Write MedFieldDriver21 - MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_5 = - new MED_FIELD_RDWR_DRIVER21<int>(other_file_wr, aField); - aInvalidMedRdWrFieldDriver21_5->open(); -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_5->write(), MEDEXCEPTION); - //=>Segmentation fault in this case -#endif - - //////////////////////// - // TEST7: Main test // - //////////////////////// - - //Creation correct Read/Write MedFieldDriver21 - MED_FIELD_RDWR_DRIVER21<double> *aMedRdWrFieldDriver21 = - new MED_FIELD_RDWR_DRIVER21<double>(filename_rdwr, aField_2); - - //Check driver - CPPUNIT_ASSERT(aMedRdWrFieldDriver21); - - //Trying read/write field before open file - CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->read(),MEDEXCEPTION); -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->write(),MEDEXCEPTION); - //(BUG) No exception in this case -#endif - - //Test open() method - try - { - aMedRdWrFieldDriver21->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FORCED_FAILURES - //Trying open file secondary. - CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->open(), MEDEXCEPTION); - // (BUG) No exception in this case -#endif - - //Trying read field from file if field name is empty - CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->read(), MEDEXCEPTION); - - //Test setFieldName() and getFieldName - try - { - aMedRdWrFieldDriver21->setFieldName(fileldnotexist); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT_EQUAL(fileldnotexist, aMedRdWrFieldDriver21->getFieldName()); - - //Trying read not existing field from file - CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->read(), MEDEXCEPTION); - - //Test read() method - aMedRdWrFieldDriver21->setFieldName(fieldnameDouble); - try - { - aMedRdWrFieldDriver21->read(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying write field in the file with empty name - aField_2->setName(emptyfilename); - aMedRdWrFieldDriver21->setFieldName(emptyfilename); - CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->write(), MEDEXCEPTION); - - //Test write() method - aField_2->setName(fieldnameDouble_cpy); - aMedRdWrFieldDriver21->setFieldName(fieldnameDouble_cpy); -#ifdef ENABLE_FAULTS - try - { - aMedRdWrFieldDriver21->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - //=>Segmentation fault in this case -#endif - - //Test close() method - try - { - aMedRdWrFieldDriver21->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_FIELD_RDWR_DRIVER21<double> aMedRdWrFieldDriver21Cpy_1; - - //Test (void operator =) defined in GENDRIVER class - //aMedRdWrFieldDriver21Cpy_1 = *aMedRdWrFieldDriver21; - - //Test (bool operator ==) defined in GENDRIVER class - CPPUNIT_ASSERT(aMedRdWrFieldDriver21Cpy_1.GENDRIVER::operator==(*aMedRdWrFieldDriver21)); - - //Test copy constructor - MED_FIELD_RDWR_DRIVER21<double> aMedRdWrFieldDriver21Cpy_2 (*aMedRdWrFieldDriver21); - CPPUNIT_ASSERT_EQUAL(aMedRdWrFieldDriver21Cpy_2, *aMedRdWrFieldDriver21); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream rwostr1, rwostr2; - rwostr1 << aMedRdWrFieldDriver21Cpy_1; - rwostr2 << aMedRdWrFieldDriver21Cpy_2; - CPPUNIT_ASSERT(rwostr1.str() != ""); - CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - //Delete all objects - delete aField; - delete aField_1; - delete aField_2; - - delete aInvalidMedRdFieldDriver21_1; - delete aInvalidMedRdFieldDriver21_2; - delete aInvalidMedRdFieldDriver21_3; - delete aMedRdFieldDriver21; - - delete aInvalidMedWrFieldDriver21_1; - delete aInvalidMedWrFieldDriver21_2; - delete aInvalidMedWrFieldDriver21_3; - delete aInvalidMedWrFieldDriver21_4; - delete aMedWrFieldDriver21; - - delete aInvalidMedRdWrFieldDriver21_1; - delete aInvalidMedRdWrFieldDriver21_2; - delete aInvalidMedRdWrFieldDriver21_3; - delete aInvalidMedRdWrFieldDriver21_4; - delete aInvalidMedRdWrFieldDriver21_5; - delete aMedRdWrFieldDriver21; -} - -int main (int argc, char** argv) -{ - MEDMEMTest_testMedFieldDriver21(); -} diff --git a/src/MEDMEM/Test/MEDMEMTest_MedFieldDriver22.cxx b/src/MEDMEM/Test/MEDMEMTest_MedFieldDriver22.cxx deleted file mode 100644 index f3bf94d98..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_MedFieldDriver22.cxx +++ /dev/null @@ -1,619 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include <MEDMEM_Field.hxx> -#include <MEDMEM_MedFieldDriver22.hxx> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -/*! - * Check methods (17), defined in MEDMEM_MedFieldDriver22.hxx: - * template <class T> class MED_FIELD_DRIVER22 : public virtual MED_FIELD_DRIVER<T> { - * (+) MED_FIELD_DRIVER22(); - * (+) template <class INTERLACING_TAG> MED_FIELD_DRIVER22(const string & fileName, - * FIELD<T, INTERLACING_TAG> * ptrField, MED_EN::med_mode_acces accessMode); - * (+) MED_FIELD_DRIVER22(const MED_FIELD_DRIVER22 & fieldDriver); - * (+) virtual ~MED_FIELD_DRIVER22(); - * (+) void open() throw (MEDEXCEPTION); - * (+) void close(); - * } - * template <class T> class MED_FIELD_RDONLY_DRIVER22 : public virtual MED_FIELD_DRIVER22<T>, - * public virtual IMED_FIELD_RDONLY_DRIVER<T> { - * (+) MED_FIELD_RDONLY_DRIVER22(); - * (+) template <class INTERLACING_TAG> MED_FIELD_RDONLY_DRIVER22 - * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField); - * (+) MED_FIELD_RDONLY_DRIVER22(const MED_FIELD_RDONLY_DRIVER22 & fieldDriver); - * (+) virtual ~MED_FIELD_RDONLY_DRIVER22(); - * (+) void write(void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * } - * template <class T> class MED_FIELD_WRONLY_DRIVER22 : public virtual MED_FIELD_DRIVER22<T>, - * public virtual IMED_FIELD_WRONLY_DRIVER<T> { - * (+) MED_FIELD_WRONLY_DRIVER22(); - * (+) template <class INTERLACING_TAG> MED_FIELD_WRONLY_DRIVER22 - * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField); - * (+) MED_FIELD_WRONLY_DRIVER22(const MED_FIELD_WRONLY_DRIVER22 & fieldDriver); - * (+) virtual ~MED_FIELD_WRONLY_DRIVER22(); - * (+) void write(void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * } - * template <class T> class MED_FIELD_RDWR_DRIVER22 : public MED_FIELD_RDONLY_DRIVER22<T>, - * public MED_FIELD_WRONLY_DRIVER22<T>, public IMED_FIELD_RDWR_DRIVER<T> { - * (+) MED_FIELD_RDWR_DRIVER22(); - * (+) template <class INTERLACING_TAG> MED_FIELD_RDWR_DRIVER22 - * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField); - * (+) MED_FIELD_RDWR_DRIVER22(const MED_FIELD_RDWR_DRIVER22 & fieldDriver); - * (+) ~MED_FIELD_RDWR_DRIVER22(); - * (+) void write(void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * } - */ -void MEDMEMTest::testMedFieldDriver22() -{ - FIELD<int> *aField = new FIELD<int> (); - FIELD<int> *aField_1 = new FIELD<int> (); - FIELD<double> *aField_2 = new FIELD<double> (); - string data_dir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - if (tmp_dir == "") - tmp_dir = "/tmp"; - string filename_rd = data_dir + "/MedFiles/pointe_import22.med"; - string filenameWithOutFileds = data_dir + "/MedFiles/Mistrat_import22.med"; - string fileldnotexist = "anyfield"; - string fieldname = "fieldnodeint"; - string fieldname_cpy = fieldname + "_cpy"; - string fileNotExist_rd = "notExist22.med"; - string emptyfilename = ""; - - string filename_wr = tmp_dir + "/myWrField_pointe22.med"; - string cp_file_wr = "cp " + filename_rd + " " + filename_wr; - string fileNotExist_wr = "/path_not_exist/file_not_exist.med"; - string emptyfile_wr = tmp_dir + "/myWrField_pointe_empty22.med"; - string other_file = data_dir + "/MedFiles/cube_hexa8_import22.med"; - string other_file_wr = tmp_dir + "/myWRcube_hexa8_import22.med"; - string cp_other_file = "cp " + other_file + " " + other_file_wr; - - string filename_rdwr = tmp_dir + "/myRdWrField_pointe22.med"; - string cp_file_rdwr = "cp " + filename_rd + " " + filename_rdwr; - string emptyfile_rdwr = tmp_dir + "/myRdWrField_pointe_empty22.med"; - string fieldnameDouble = "fieldnodedouble"; - string fieldnameDouble_cpy = fieldnameDouble + "_cpy"; - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filename_wr); - aRemover.Register(emptyfile_wr); - aRemover.Register(other_file_wr); - aRemover.Register(filename_rdwr); - aRemover.Register(emptyfile_rdwr); - - //--------------------------Test READ ONLY part------------------------------// - - ///////////////////////////////////// - // TEST1: Open not existing file // - ///////////////////////////////////// - - //Creation Invalid Read Only MedFieldDriver22 (file not exist) - MED_FIELD_RDONLY_DRIVER22<int> *aInvalidMedRdFieldDriver22_1 = - new MED_FIELD_RDONLY_DRIVER22<int>(fileNotExist_rd, aField); - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedRdFieldDriver22_1->open(), MEDEXCEPTION); - - ////////////////////////////////////////////// - // TEST2: Open file with empty file name /// - ////////////////////////////////////////////// - - //Creation Invalid Read Only MedFieldDriver22 (empty file name) - MED_FIELD_RDONLY_DRIVER22<int> *aInvalidMedRdFieldDriver22_2 = - new MED_FIELD_RDONLY_DRIVER22<int>(emptyfilename, aField); - //Trying file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedRdFieldDriver22_2->open(), MEDEXCEPTION); - - ///////////////////////////////////////////////////// - // TEST3: Reading field from file without fields // - ///////////////////////////////////////////////////// - MED_FIELD_RDONLY_DRIVER22<int> *aInvalidMedRdFieldDriver22_3 = - new MED_FIELD_RDONLY_DRIVER22<int>(filenameWithOutFileds, aField); - aInvalidMedRdFieldDriver22_3->open(); - aInvalidMedRdFieldDriver22_3->setFieldName(fieldname); - //Trying read field from file - CPPUNIT_ASSERT_THROW(aInvalidMedRdFieldDriver22_3->read(), MEDEXCEPTION); - aInvalidMedRdFieldDriver22_3->close(); - - //////////////////////// - // TEST4: Main test // - //////////////////////// - //Creation correct Read Only MedFieldDriver22 - MED_FIELD_RDONLY_DRIVER22<int> *aMedRdFieldDriver22 = - new MED_FIELD_RDONLY_DRIVER22<int>(filename_rd, aField); - - //Check driver - CPPUNIT_ASSERT(aMedRdFieldDriver22); - - //Trying read field before open file - CPPUNIT_ASSERT_THROW(aMedRdFieldDriver22->read(),MEDEXCEPTION); - - //Test open() method - try - { - aMedRdFieldDriver22->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FORCED_FAILURES - //Trying open file secondary. - CPPUNIT_ASSERT_THROW(aMedRdFieldDriver22->open(), MEDEXCEPTION); - // (BUG) No exception in this case -#endif - - //Trying read field form file if it name is empty - CPPUNIT_ASSERT_THROW(aMedRdFieldDriver22->read(), MEDEXCEPTION); - - //Test setFieldName() and getFieldName() - try - { - aMedRdFieldDriver22->setFieldName(fileldnotexist); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT_EQUAL(fileldnotexist, aMedRdFieldDriver22->getFieldName()); - - //Trying read not existing field from file - CPPUNIT_ASSERT_THROW(aMedRdFieldDriver22->read(), MEDEXCEPTION); - - //Test read() method - aMedRdFieldDriver22->setFieldName(fieldname); - try - { - aMedRdFieldDriver22->read(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test write() method for READ ONLY driver - CPPUNIT_ASSERT_THROW(aMedRdFieldDriver22->write(), MEDEXCEPTION); - - //Test close() method - try - { - aMedRdFieldDriver22->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_FIELD_RDONLY_DRIVER22<int> aMedRdFieldDriver22Cpy_1; - - //Test (void operator =) defined in GENDRIVER class in MEDMEM_GenDriver.hxx - aMedRdFieldDriver22Cpy_1 = *aMedRdFieldDriver22; - - //Test (bool operator ==) defined GENDRIVER class in MEDMEM_GenDriver.hxx - CPPUNIT_ASSERT(aMedRdFieldDriver22Cpy_1 == *aMedRdFieldDriver22); - - //Test copy constructor - MED_FIELD_RDONLY_DRIVER22<int> aMedRdFieldDriver22Cpy_2 (*aMedRdFieldDriver22); - CPPUNIT_ASSERT_EQUAL(aMedRdFieldDriver22Cpy_2, *aMedRdFieldDriver22); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream rostr1, rostr2; - rostr1<<aMedRdFieldDriver22Cpy_1; - rostr2<<aMedRdFieldDriver22Cpy_2; - CPPUNIT_ASSERT(rostr1.str() != ""); - CPPUNIT_ASSERT(rostr1.str() == rostr2.str()); - - - //--------------------------Test WRITE ONLY part------------------------------// - - //Copy file - system(cp_other_file.c_str()); - system(cp_file_wr.c_str()); - - ///////////////////////////////////// - // TEST1: Open not existing file // - ///////////////////////////////////// - - //Creation Invalid Write Only MedFieldDriver22 (file not exist) - MED_FIELD_WRONLY_DRIVER22<int> *aInvalidMedWrFieldDriver22_1 = - new MED_FIELD_WRONLY_DRIVER22<int>(fileNotExist_wr, aField_1); - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver22_1->open(), MEDEXCEPTION); - - ///////////////////////////////////////////// - // TEST2: Open file with empty file name // - ///////////////////////////////////////////// - //Creation Invalid Write Only MedFieldDriver22 (empty file name) - MED_FIELD_WRONLY_DRIVER22<int> *aInvalidMedWrFieldDriver22_2 = - new MED_FIELD_WRONLY_DRIVER22<int>(emptyfilename, aField_1); - //Trying open not existing file and file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver22_2->open(), MEDEXCEPTION); - - /////////////////////////////////////////////////////// - // TEST3: Writing field in empty file without mesh // - /////////////////////////////////////////////////////// - //Creation Invalid Write Only MedFieldDriver22 - MED_FIELD_WRONLY_DRIVER22<int> *aInvalidMedWrFieldDriver22_3 = - new MED_FIELD_WRONLY_DRIVER22<int>(emptyfile_wr, aField); - - aInvalidMedWrFieldDriver22_3->open(); -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver22_3->write(), MEDEXCEPTION); - //(Bug) No Exception in this case - aInvalidMedWrFieldDriver22_3->close(); -#endif - - ////////////////////////////////////////////// - // TEST4: Writing field in the other file // - ////////////////////////////////////////////// - - //Creation Invalid Write Only MedFieldDriver22 - MED_FIELD_WRONLY_DRIVER22<int> *aInvalidMedWrFieldDriver22_4 = - new MED_FIELD_WRONLY_DRIVER22<int>(other_file_wr, aField); - aInvalidMedWrFieldDriver22_4->open(); -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver22_4->write(), MEDEXCEPTION); - //(Bug) No Exception in this case -#endif - - //////////////////////// - // TEST5: Main test // - //////////////////////// - - //Creation correct Write Only MedFieldDriver22 - MED_FIELD_WRONLY_DRIVER22<int> *aMedWrFieldDriver22 = - new MED_FIELD_WRONLY_DRIVER22<int>(filename_wr, aField); - - //Check driver - CPPUNIT_ASSERT(aMedWrFieldDriver22); - - //Trying write field before open file -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedWrFieldDriver22->write(),MEDEXCEPTION); - // (BUG) No exception in this case -#endif - - //Test open() method - try - { - aMedWrFieldDriver22->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FORCED_FAILURES - //Trying open file secondary. - CPPUNIT_ASSERT_THROW(aMedWrFieldDriver22->open(), MEDEXCEPTION); - // (BUG) No exception in this case -#endif - - //Test setFieldName() and getFieldName - aField->setName(fieldname_cpy); - try - { - aMedWrFieldDriver22->setFieldName(fieldname_cpy); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT_EQUAL(fieldname_cpy, aMedWrFieldDriver22->getFieldName()); - - //Test write() method - try - { - aMedWrFieldDriver22->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test read() method for Write only part - CPPUNIT_ASSERT_THROW(aMedWrFieldDriver22->read(),MEDEXCEPTION); - - //Test close() method - try - { - aMedWrFieldDriver22->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_FIELD_WRONLY_DRIVER22<int> aMedWrFieldDriver22Cpy_1; - - //Test (void operator =) defined in GENDRIVER class - //aMedWrFieldDriver22Cpy_1 = *aMedWrFieldDriver22; - - //Test (bool operator ==) defined in GENDRIVER class - CPPUNIT_ASSERT(aMedWrFieldDriver22Cpy_1.GENDRIVER::operator==(*aMedWrFieldDriver22)); - - //Test copy constructor - MED_FIELD_WRONLY_DRIVER22<int> aMedWrFieldDriver22Cpy_2 (*aMedWrFieldDriver22); - CPPUNIT_ASSERT_EQUAL(aMedWrFieldDriver22Cpy_2, *aMedWrFieldDriver22); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream wostr1, wostr2; - wostr1 << aMedWrFieldDriver22Cpy_1; - wostr2 << aMedWrFieldDriver22Cpy_2; - CPPUNIT_ASSERT(wostr1.str() != ""); - CPPUNIT_ASSERT(wostr1.str() == wostr2.str()); - - - //--------------------------Test READ/WRITE part------------------------------// - - //Copy files - system(cp_file_rdwr.c_str()); - ///////////////////////////////////// - // TEST1: Open not existing file // - ///////////////////////////////////// - - //Creation Invalid Read/Write MedFieldDriver22 (file not exist) - MED_FIELD_RDWR_DRIVER22<int> *aInvalidMedRdWrFieldDriver22_1 = - new MED_FIELD_RDWR_DRIVER22<int>(fileNotExist_wr, aField_1); - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver22_1->open(), MEDEXCEPTION); - - ///////////////////////////////////////////// - // TEST2: Open file with empty file name // - ///////////////////////////////////////////// - //Creation Invalid Read/Write MedFieldDriver22 (empty file name) - MED_FIELD_RDWR_DRIVER22<int> *aInvalidMedRdWrFieldDriver22_2 = - new MED_FIELD_RDWR_DRIVER22<int>(emptyfilename, aField_1); - //Trying open not existing file and file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver22_2->open(), MEDEXCEPTION); - - ///////////////////////////////////////////////////// - // TEST3: Reading field from file without fields // - ///////////////////////////////////////////////////// - MED_FIELD_RDWR_DRIVER22<int> *aInvalidMedRdWrFieldDriver22_3 = - new MED_FIELD_RDWR_DRIVER22<int>(filenameWithOutFileds, aField_1); - aInvalidMedRdWrFieldDriver22_3->open(); - aInvalidMedRdWrFieldDriver22_3->setFieldName(fieldname); - //Trying read field from file - CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver22_3->read(), MEDEXCEPTION); - aInvalidMedRdWrFieldDriver22_3->close(); - - /////////////////////////////////////////////////////// - // TEST4: Writing field in empty file without mesh // - /////////////////////////////////////////////////////// - - //Creation Invalid Read/Write MedFieldDriver22 - MED_FIELD_RDWR_DRIVER22<int> *aInvalidMedRdWrFieldDriver22_4 = - new MED_FIELD_RDWR_DRIVER22<int>(emptyfile_rdwr, aField); - - aInvalidMedRdWrFieldDriver22_4->open(); -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver22_4->write(), MEDEXCEPTION); - // (BUG) No exception in this case -#endif - - ////////////////////////////////////////////// - // TEST6: Writing field in the other file // - ////////////////////////////////////////////// - - //Creation Invalid Read/Write MedFieldDriver22 - MED_FIELD_RDWR_DRIVER22<int> *aInvalidMedRdWrFieldDriver22_5 = - new MED_FIELD_RDWR_DRIVER22<int>(other_file_wr, aField); - aInvalidMedRdWrFieldDriver22_5->open(); -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver22_5->write(), MEDEXCEPTION); - // (BUG) No exception in this case -#endif - - //////////////////////// - // TEST7: Main test // - //////////////////////// - - //Creation correct Read/Write MedFieldDriver22 - MED_FIELD_RDWR_DRIVER22<double> *aMedRdWrFieldDriver22 = - new MED_FIELD_RDWR_DRIVER22<double>(filename_rdwr, aField_2); - - //Check driver - CPPUNIT_ASSERT(aMedRdWrFieldDriver22); - - //Trying read/write field before open file - CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver22->read(),MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver22->write(),MEDEXCEPTION); - - //Test open() method - try - { - aMedRdWrFieldDriver22->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FORCED_FAILURES - //Trying open file secondary. - CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver22->open(), MEDEXCEPTION); - // (BUG) No exception in this case -#endif - - //Trying read field from file if field name is empty - CPPUNIT_ASSERT_THROW(aMedRdFieldDriver22->read(), MEDEXCEPTION); - - //Test setFieldName() and getFieldName - try - { - aMedRdWrFieldDriver22->setFieldName(fileldnotexist); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT_EQUAL(fileldnotexist, aMedRdWrFieldDriver22->getFieldName()); - - //Trying read not existing field from file - CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver22->read(), MEDEXCEPTION); - - //Test read() method - aMedRdWrFieldDriver22->setFieldName(fieldnameDouble); - try - { - aMedRdWrFieldDriver22->read(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying write field in the file with empty name - aField_2->setName(emptyfilename); - aMedRdWrFieldDriver22->setFieldName(emptyfilename); - CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver22->write(), MEDEXCEPTION); - - //Test write() method - aField_2->setName(fieldnameDouble_cpy); - aMedRdWrFieldDriver22->setFieldName(fieldnameDouble_cpy); - try - { - aMedRdWrFieldDriver22->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test close() method - try - { - aMedRdWrFieldDriver22->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_FIELD_RDWR_DRIVER22<double> aMedRdWrFieldDriver22Cpy_1; - - //Test (void operator =) defined in GENDRIVER class - //aMedRdWrFieldDriver22Cpy_1 = *aMedRdWrFieldDriver22; - - //Test (bool operator ==) defined in GENDRIVER class - CPPUNIT_ASSERT(aMedRdWrFieldDriver22Cpy_1.GENDRIVER::operator==(*aMedRdWrFieldDriver22)); - - //Test copy constructor - MED_FIELD_RDWR_DRIVER22<double> aMedRdWrFieldDriver22Cpy_2 (*aMedRdWrFieldDriver22); - CPPUNIT_ASSERT_EQUAL(aMedRdWrFieldDriver22Cpy_2, *aMedRdWrFieldDriver22); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream rwostr1, rwostr2; - rwostr1 << aMedRdWrFieldDriver22Cpy_1; - rwostr2 << aMedRdWrFieldDriver22Cpy_2; - CPPUNIT_ASSERT(rwostr1.str() != ""); - CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - //Delete all objects - delete aField; - delete aField_1; - delete aField_2; - - delete aInvalidMedRdFieldDriver22_1; - delete aInvalidMedRdFieldDriver22_2; - delete aInvalidMedRdFieldDriver22_3; - delete aMedRdFieldDriver22; - - delete aInvalidMedWrFieldDriver22_1; - delete aInvalidMedWrFieldDriver22_2; - delete aInvalidMedWrFieldDriver22_3; - delete aInvalidMedWrFieldDriver22_4; - delete aMedWrFieldDriver22; - - delete aInvalidMedRdWrFieldDriver22_1; - delete aInvalidMedRdWrFieldDriver22_2; - delete aInvalidMedRdWrFieldDriver22_3; - delete aInvalidMedRdWrFieldDriver22_4; - delete aInvalidMedRdWrFieldDriver22_5; - delete aMedRdWrFieldDriver22; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_MedMedDriver21.cxx b/src/MEDMEM/Test/MEDMEMTest_MedMedDriver21.cxx deleted file mode 100644 index 53bccf034..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_MedMedDriver21.cxx +++ /dev/null @@ -1,523 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include <MEDMEM_Compatibility21_22.hxx> -#include <MEDMEM_MedMedDriver21.hxx> -#include <MEDMEM_Med.hxx> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -/*! - * Check methods (21), defined in MEDMEM_MedMedDriver21.hxx: - * class MED_MED_DRIVER21 : public virtual MED_MED_DRIVER { - * (+) MED_MED_DRIVER21(); - * (+) MED_MED_DRIVER21(const string & fileName, MED * const ptrMed); - * (+) MED_MED_DRIVER21(const string & fileName, MED * const ptrMed, - * MED_EN::med_mode_acces accessMode); - * (+) MED_MED_DRIVER21(const MED_MED_DRIVER21 & driver); - * (+) virtual ~MED_MED_DRIVER21(); - * (+) void open() throw (MEDEXCEPTION); - * (+) void close(); - * (+) virtual void write (void) const; - * (+) virtual void writeFrom (void) const; - * (+) virtual void read (void); - * (+) virtual void readFileStruct (void); - * } - * class MED_MED_RDONLY_DRIVER21 : public virtual IMED_MED_RDONLY_DRIVER, - * public virtual MED_MED_DRIVER21 { - * (+) MED_MED_RDONLY_DRIVER21(); - * (+) MED_MED_RDONLY_DRIVER21(const string & fileName, MED * const ptrMed); - * (+) MED_MED_RDONLY_DRIVER21(const MED_MED_RDONLY_DRIVER21 & driver); - * (+) virtual ~MED_MED_RDONLY_DRIVER21(); - * (+) void write (void) const throw (MEDEXCEPTION); - * (+) void writeFrom (void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void readFileStruct (void) throw (MEDEXCEPTION); - * } - * class MED_MED_WRONLY_DRIVER21 : public virtual IMED_MED_WRONLY_DRIVER, - * public virtual MED_MED_DRIVER21 { - * (+) MED_MED_WRONLY_DRIVER21(); - * (+) MED_MED_WRONLY_DRIVER21(const string & fileName, MED * const ptrMed); - * (+) MED_MED_WRONLY_DRIVER21(const MED_MED_WRONLY_DRIVER21 & driver); - * (+) virtual ~MED_MED_WRONLY_DRIVER21(); - * (+) void write (void) const throw (MEDEXCEPTION); - * (+) void writeFrom (void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void readFileStruct (void) throw (MEDEXCEPTION); - * } - * class MED_MED_RDWR_DRIVER21 : public MED_MED_RDONLY_DRIVER21, - * public MED_MED_WRONLY_DRIVER21, - * public IMED_MED_RDWR_DRIVER { - * (+) MED_MED_RDWR_DRIVER21(); - * (+) MED_MED_RDWR_DRIVER21(const string & fileName, MED * const ptrMed); - * (+) MED_MED_RDWR_DRIVER21(const MED_MED_RDWR_DRIVER21 & driver); - * (+) ~MED_MED_RDWR_DRIVER21(); - * (+) void write (void) const throw (MEDEXCEPTION); - * (+) void writeFrom (void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void readFileStruct (void) throw (MEDEXCEPTION); - * } - */ -void MEDMEMTest::testMedMedDriver21() { - MED *aMed = new MED(); - string data_dir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - if(tmp_dir == "") - tmp_dir = "/tmp"; - - string filename_rd = data_dir + "/MedFiles/pointe.med"; - string emptyfilename = ""; - string filename_wr = tmp_dir + "/myMedWr_pointe21.med"; - string fileNotExistsName_rd = "notExists.med"; - string fileNotExistsName_wr = "/path_not_exists/file_not_exists.med"; - string filename_rdwr = tmp_dir + "/myMedRdWr_pointe21.med"; - string fcopy = "cp " + filename_rd + " " + filename_rdwr; - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filename_wr); - aRemover.Register(filename_rdwr); - - //Copy file in the TMP dir for testing READ/WRITE case - system(fcopy.data()); - - //-------------------------------Test READ_ONLY part------------------------------------------------------- - //Creation incorrect Med_Med read only driver (file is not exist) - MED_MED_RDONLY_DRIVER21 *aInvalidMedMedRdDriver21 = new MED_MED_RDONLY_DRIVER21(fileNotExistsName_rd, aMed); - - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedMedRdDriver21->open(),MEDEXCEPTION); - - //Creation incorrect Med_Med read only driver (with empty file name) - MED_MED_RDONLY_DRIVER21 *aInvalidMedMedRdDriver21_1 = new MED_MED_RDONLY_DRIVER21(emptyfilename, aMed); - - //Trying open file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedMedRdDriver21_1->open(),MEDEXCEPTION); - - - //Creation a correct Med_Med read only driver (normal constructor) - MED_MED_RDONLY_DRIVER21 *aMedMedRdDriver21 = new MED_MED_RDONLY_DRIVER21(filename_rd, aMed); - - //Check driver - CPPUNIT_ASSERT(aMedMedRdDriver21); - - //Trying read mesh from file, if file is not open -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->read(), MEDEXCEPTION); - // (BUG) No exception in this case. -#endif - - CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->readFileStruct(),MEDEXCEPTION); - - //Test open() method - try - { - aMedMedRdDriver21->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying open() file twice -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->open(),MEDEXCEPTION); - //(BUG) No exception in this case. -#endif - - //Test read() method - try - { - aMedMedRdDriver21->read(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test read() method - try - { - aMedMedRdDriver21->readFileStruct(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test write() and WriteFrom() methods for READ_ONLY part - CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->write(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->writeFrom(), MEDEXCEPTION); - - //Check MED - CPPUNIT_ASSERT(aMed); - - //Test close() method - try - { - aMedMedRdDriver21->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_MED_RDONLY_DRIVER21 aMedMedRdDriver21Cpy_1; - - //Test (void operator =) defined in GENDRIVER class - //aMedMedRdDriver21Cpy_1 = *aMedMedRdDriver21; - - //Test copy constructor -#ifdef ENABLE_FAULTS - MED_MED_RDONLY_DRIVER21 aMedMedRdDriver21Cpy_2 (*aMedMedRdDriver21); - // (BUG) => Segmentation fault, because _concreteMedDrv is NULL - // Process terminating with default action of signal 11 (SIGSEGV) - // Access not within mapped region at address 0x0 - // at 0x34881A7A: MEDMEM::MED_MED_DRIVER::MED_MED_DRIVER(MEDMEM::MED_MED_DRIVER const&) (MEDMEM_MedMedDriver.cxx:56) - // by 0x34A07786: MEDMEM::MED_MED_RDONLY_DRIVER21::MED_MED_RDONLY_DRIVER21(MEDMEM::MED_MED_RDONLY_DRIVER21 const&) (MEDMEM_MedMedDriver21.cxx:179) - // by 0x343A02AD: MEDMEMTest::testMedMedDriver21() (MEDMEMTest_MedMedDriver21.cxx:219) -#endif - - //CPPUNIT_ASSERT_EQUAL(aMedMedRdDriver21Cpy_2, *aMedMedRdDriver21); - - //Test (bool operator ==) defined in GENDRIVER class in MEDMEM_GenDriver.hxx - //CPPUNIT_ASSERT(aMedMedRdDriver21Cpy_2.GENDRIVER::operator==(*aMedMedRdDriver21)); - - //Test (friend ostream & operator <<) defined GENDRIVER class - //ostringstream rwostr1, rwostr2; - //rwostr1<<aMedMedRdDriver21Cpy_1; - //rwostr2<<aMedMedRdDriver21Cpy_2; - //CPPUNIT_ASSERT(rwostr1.str() != ""); - //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - //-------------------------------Test WRITE_ONLY part------------------------------------------------------- - //Creation incorrect Med_Med write only driver (file is not exist) - MED_MED_WRONLY_DRIVER21 *aInvalidMedMedWrDriver21 = new MED_MED_WRONLY_DRIVER21(fileNotExistsName_wr, aMed); - - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedMedWrDriver21->open(),MEDEXCEPTION); - - //Creation incorrect Med_Med write only driver (with empty file name) - MED_MED_WRONLY_DRIVER21 *aInvalidMedMedWrDriver21_1 = new MED_MED_WRONLY_DRIVER21(emptyfilename, aMed); - - //Trying open file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedMedWrDriver21_1->open(),MEDEXCEPTION); - - - //Creation a correct Med_Med write only driver (normal constructor) - MED_MED_WRONLY_DRIVER21 *aMedMedWrDriver21 = new MED_MED_WRONLY_DRIVER21(filename_wr, aMed); - - //Check driver - CPPUNIT_ASSERT(aMedMedWrDriver21); - - - //Trying write mesh to file, if file is not open -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedWrDriver21->writeFrom(),MEDEXCEPTION); - // (BUG) No exception in this case -#endif - -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_THROW(aMedMedWrDriver21->write(), MEDEXCEPTION); - //(BUG) => Segmentation fault -#endif - - //Test open() method - try - { - aMedMedWrDriver21->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying open() file twice -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedWrDriver21->open(),MEDEXCEPTION); - //(BUG) No exception in this case. -#endif - - //Test writeFrom() method - try - { - aMedMedWrDriver21->writeFrom(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FAULTS - //Test write() method - try - { - aMedMedWrDriver21->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - // (BUG) => terminate called after throwing an instance of 'std::length_error' - // what(): basic_string::_S_create -#endif - - //Test close method - try - { - aMedMedWrDriver21->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_MED_WRONLY_DRIVER21 aMedMedWrDriver21Cpy_1; - - //Test (void operator =) defined in GENDRIVER class - //aMedMedWrDriver21Cpy_1 = *aMedMedWrDriver21; - - //Test copy constructor -#ifdef ENABLE_FAULTS - MED_MED_WRONLY_DRIVER21 aMedMedWrDriver21Cpy_2 (*aMedMedWrDriver21); - // (BUG) => Segmentation fault -#endif - //CPPUNIT_ASSERT_EQUAL(aMedMedWrDriver21Cpy_2, *aMedMedWrDriver21); - - //Test (bool operator ==) defined in GENDRIVER class - //CPPUNIT_ASSERT(aMedMedWrDriver21Cpy_2.GENDRIVER::operator==(*aMedMedWrDriver21)); - - //Test (friend ostream & operator <<) defined GENDRIVER class - //ostringstream rwostr1, rwostr2; - //rwostr1<<aMedMedWrDriver21Cpy_1; - //rwostr2<<aMedMedWrDriver21Cpy_2; - //CPPUNIT_ASSERT(rwostr1.str() != ""); - //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - -//-------------------------------Test READ/WRITE part------------------------------------------------------- - //Creation incorrect Med_Med read/write driver (file is not exist) - MED_MED_RDWR_DRIVER21 *aInvalidMedMedRdWrDriver21 = new MED_MED_RDWR_DRIVER21(fileNotExistsName_wr, aMed); - - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedMedRdWrDriver21->open(),MEDEXCEPTION); - - //Creation incorrect Med_Med read/write driver (with empty file name) - MED_MED_RDWR_DRIVER21 *aInvalidMedMedRdWrDriver21_1 = new MED_MED_RDWR_DRIVER21(emptyfilename, aMed); - - //Trying open file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedMedRdWrDriver21_1->open(),MEDEXCEPTION); - - - //Creation a correct Med_Med read/write driver (normal constructor) - MED_MED_RDWR_DRIVER21 *aMedMedRdWrDriver21 = new MED_MED_RDWR_DRIVER21(filename_rdwr, aMed); - - //Check driver - CPPUNIT_ASSERT(aMedMedRdWrDriver21); - - //Trying read MED from file if it is not open -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->read(), MEDEXCEPTION); - // (BUG) No exception in this case. -#endif - - CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->readFileStruct(),MEDEXCEPTION); - - //Trying write mesh to file, if file is not open -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver21->writeFrom(),MEDEXCEPTION); - // (BUG) => No exception in this case -#endif - -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver21->write(), MEDEXCEPTION); - //(BUG) => Crash -#endif - - //Test open() method - try - { - aMedMedRdWrDriver21->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying open() file twice -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver21->open(),MEDEXCEPTION); - //(BUG) No exception in this case. -#endif - - //Test readFileStruct() method - try - { - aMedMedRdWrDriver21->readFileStruct(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test read() method - try - { - aMedMedRdWrDriver21->read(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test writeFrom() method - try - { - aMedMedRdWrDriver21->writeFrom(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FAULTS - //Test write() method - try - { - aMedMedRdWrDriver21->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } -#endif - - //Test close() method - try - { - aMedMedRdWrDriver21->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_MED_RDWR_DRIVER21 aMedMedRdWrDriver21Cpy_1; - - //Test copy constructor -#ifdef ENABLE_FAULTS - MED_MED_RDWR_DRIVER21 aMedMedRdWrDriver21Cpy_2 (*aMedMedRdWrDriver21); - // (BUG) => Segmentation fault -#endif - //CPPUNIT_ASSERT_EQUAL(aMedMedRdWrDriver21Cpy_2, *aMedMedRdWrDriver21); - - //Test (bool operator ==) defined in GENDRIVER class - //CPPUNIT_ASSERT(aMedMedRdWrDriver21Cpy_2.GENDRIVER::operator==(*aMedMedRdWrDriver21)); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - //ostringstream rwostr1, rwostr2; - //rwostr1<<aMedMedRdWrDriver21Cpy_1; - //rwostr2<<aMedMedRdWrDriver21Cpy_2; - //CPPUNIT_ASSERT(rwostr1.str() != ""); - //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - //Delete all objects - delete aMed; - delete aInvalidMedMedRdDriver21; - delete aInvalidMedMedRdDriver21_1; - delete aMedMedRdDriver21; - - delete aInvalidMedMedWrDriver21; - delete aInvalidMedMedWrDriver21_1; - delete aMedMedWrDriver21; - - delete aInvalidMedMedRdWrDriver21; - delete aInvalidMedMedRdWrDriver21_1; - delete aMedMedRdWrDriver21; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_MedMedDriver21_fault.cxx b/src/MEDMEM/Test/MEDMEMTest_MedMedDriver21_fault.cxx deleted file mode 100644 index fb5872052..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_MedMedDriver21_fault.cxx +++ /dev/null @@ -1,528 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include <MEDMEM_Compatibility21_22.hxx> -#include <MEDMEM_MedMedDriver21.hxx> -#include <MEDMEM_Med.hxx> - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -//#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -/*! - * Check methods (21), defined in MEDMEM_MedMedDriver21.hxx: - * class MED_MED_DRIVER21 : public virtual MED_MED_DRIVER { - * (+) MED_MED_DRIVER21(); - * (+) MED_MED_DRIVER21(const string & fileName, MED * const ptrMed); - * (+) MED_MED_DRIVER21(const string & fileName, MED * const ptrMed, - * MED_EN::med_mode_acces accessMode); - * (+) MED_MED_DRIVER21(const MED_MED_DRIVER21 & driver); - * (+) virtual ~MED_MED_DRIVER21(); - * (+) void open() throw (MEDEXCEPTION); - * (+) void close(); - * (+) virtual void write (void) const; - * (+) virtual void writeFrom (void) const; - * (+) virtual void read (void); - * (+) virtual void readFileStruct (void); - * } - * class MED_MED_RDONLY_DRIVER21 : public virtual IMED_MED_RDONLY_DRIVER, - * public virtual MED_MED_DRIVER21 { - * (+) MED_MED_RDONLY_DRIVER21(); - * (+) MED_MED_RDONLY_DRIVER21(const string & fileName, MED * const ptrMed); - * (+) MED_MED_RDONLY_DRIVER21(const MED_MED_RDONLY_DRIVER21 & driver); - * (+) virtual ~MED_MED_RDONLY_DRIVER21(); - * (+) void write (void) const throw (MEDEXCEPTION); - * (+) void writeFrom (void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void readFileStruct (void) throw (MEDEXCEPTION); - * } - * class MED_MED_WRONLY_DRIVER21 : public virtual IMED_MED_WRONLY_DRIVER, - * public virtual MED_MED_DRIVER21 { - * (+) MED_MED_WRONLY_DRIVER21(); - * (+) MED_MED_WRONLY_DRIVER21(const string & fileName, MED * const ptrMed); - * (+) MED_MED_WRONLY_DRIVER21(const MED_MED_WRONLY_DRIVER21 & driver); - * (+) virtual ~MED_MED_WRONLY_DRIVER21(); - * (+) void write (void) const throw (MEDEXCEPTION); - * (+) void writeFrom (void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void readFileStruct (void) throw (MEDEXCEPTION); - * } - * class MED_MED_RDWR_DRIVER21 : public MED_MED_RDONLY_DRIVER21, - * public MED_MED_WRONLY_DRIVER21, - * public IMED_MED_RDWR_DRIVER { - * (+) MED_MED_RDWR_DRIVER21(); - * (+) MED_MED_RDWR_DRIVER21(const string & fileName, MED * const ptrMed); - * (+) MED_MED_RDWR_DRIVER21(const MED_MED_RDWR_DRIVER21 & driver); - * (+) ~MED_MED_RDWR_DRIVER21(); - * (+) void write (void) const throw (MEDEXCEPTION); - * (+) void writeFrom (void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void readFileStruct (void) throw (MEDEXCEPTION); - * } - */ -void MEDMEMTest_testMedMedDriver21() { - MED *aMed = new MED(); - string data_dir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - if(tmp_dir == "") - tmp_dir = "/tmp"; - - string filename_rd = data_dir + "/MedFiles/pointe.med"; - string emptyfilename = ""; - string filename_wr = tmp_dir + "/myMedWr_pointe21.med"; - string fileNotExistsName_rd = "notExists.med"; - string fileNotExistsName_wr = "/path_not_exists/file_not_exists.med"; - string filename_rdwr = tmp_dir + "/myMedRdWr_pointe21.med"; - string fcopy = "cp " + filename_rd + " " + filename_rdwr; - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filename_wr); - aRemover.Register(filename_rdwr); - - //Copy file in the TMP dir for testing READ/WRITE case - system(fcopy.data()); - - //-------------------------------Test READ_ONLY part------------------------------------------------------- - //Creation incorrect Med_Med read only driver (file is not exist) - MED_MED_RDONLY_DRIVER21 *aInvalidMedMedRdDriver21 = new MED_MED_RDONLY_DRIVER21(fileNotExistsName_rd, aMed); - - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedMedRdDriver21->open(),MEDEXCEPTION); - - //Creation incorrect Med_Med read only driver (with empty file name) - MED_MED_RDONLY_DRIVER21 *aInvalidMedMedRdDriver21_1 = new MED_MED_RDONLY_DRIVER21(emptyfilename, aMed); - - //Trying open file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedMedRdDriver21_1->open(),MEDEXCEPTION); - - - //Creation a correct Med_Med read only driver (normal constructor) - MED_MED_RDONLY_DRIVER21 *aMedMedRdDriver21 = new MED_MED_RDONLY_DRIVER21(filename_rd, aMed); - - //Check driver - CPPUNIT_ASSERT(aMedMedRdDriver21); - - //Trying read mesh from file, if file is not open -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->read(), MEDEXCEPTION); - // (BUG) No exception in this case. -#endif - - CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->readFileStruct(),MEDEXCEPTION); - - //Test open() method - try - { - aMedMedRdDriver21->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying open() file twice -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->open(),MEDEXCEPTION); - //(BUG) No exception in this case. -#endif - - //Test read() method - try - { - aMedMedRdDriver21->read(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test read() method - try - { - aMedMedRdDriver21->readFileStruct(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test write() and WriteFrom() methods for READ_ONLY part - CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->write(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->writeFrom(), MEDEXCEPTION); - - //Check MED - CPPUNIT_ASSERT(aMed); - - //Test close() method - try - { - aMedMedRdDriver21->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_MED_RDONLY_DRIVER21 aMedMedRdDriver21Cpy_1; - - //Test (void operator =) defined in GENDRIVER class - //aMedMedRdDriver21Cpy_1 = *aMedMedRdDriver21; - - //Test copy constructor -#ifdef ENABLE_FAULTS - MED_MED_RDONLY_DRIVER21 aMedMedRdDriver21Cpy_2 (*aMedMedRdDriver21); - // (BUG) => Segmentation fault, because _concreteMedDrv is NULL - // Process terminating with default action of signal 11 (SIGSEGV) - // Access not within mapped region at address 0x0 - // at 0x34881A7A: MEDMEM::MED_MED_DRIVER::MED_MED_DRIVER(MEDMEM::MED_MED_DRIVER const&) (MEDMEM_MedMedDriver.cxx:56) - // by 0x34A07786: MEDMEM::MED_MED_RDONLY_DRIVER21::MED_MED_RDONLY_DRIVER21(MEDMEM::MED_MED_RDONLY_DRIVER21 const&) (MEDMEM_MedMedDriver21.cxx:179) - // by 0x343A02AD: MEDMEMTest::testMedMedDriver21() (MEDMEMTest_MedMedDriver21.cxx:219) -#endif - - //CPPUNIT_ASSERT_EQUAL(aMedMedRdDriver21Cpy_2, *aMedMedRdDriver21); - - //Test (bool operator ==) defined in GENDRIVER class in MEDMEM_GenDriver.hxx - //CPPUNIT_ASSERT(aMedMedRdDriver21Cpy_2.GENDRIVER::operator==(*aMedMedRdDriver21)); - - //Test (friend ostream & operator <<) defined GENDRIVER class - //ostringstream rwostr1, rwostr2; - //rwostr1<<aMedMedRdDriver21Cpy_1; - //rwostr2<<aMedMedRdDriver21Cpy_2; - //CPPUNIT_ASSERT(rwostr1.str() != ""); - //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - //-------------------------------Test WRITE_ONLY part------------------------------------------------------- - //Creation incorrect Med_Med write only driver (file is not exist) - MED_MED_WRONLY_DRIVER21 *aInvalidMedMedWrDriver21 = new MED_MED_WRONLY_DRIVER21(fileNotExistsName_wr, aMed); - - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedMedWrDriver21->open(),MEDEXCEPTION); - - //Creation incorrect Med_Med write only driver (with empty file name) - MED_MED_WRONLY_DRIVER21 *aInvalidMedMedWrDriver21_1 = new MED_MED_WRONLY_DRIVER21(emptyfilename, aMed); - - //Trying open file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedMedWrDriver21_1->open(),MEDEXCEPTION); - - - //Creation a correct Med_Med write only driver (normal constructor) - MED_MED_WRONLY_DRIVER21 *aMedMedWrDriver21 = new MED_MED_WRONLY_DRIVER21(filename_wr, aMed); - - //Check driver - CPPUNIT_ASSERT(aMedMedWrDriver21); - - - //Trying write mesh to file, if file is not open -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedWrDriver21->writeFrom(),MEDEXCEPTION); - // (BUG) No exception in this case -#endif - -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_THROW(aMedMedWrDriver21->write(), MEDEXCEPTION); - //(BUG) => Segmentation fault -#endif - - //Test open() method - try - { - aMedMedWrDriver21->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying open() file twice -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedWrDriver21->open(),MEDEXCEPTION); - //(BUG) No exception in this case. -#endif - - //Test writeFrom() method - try - { - aMedMedWrDriver21->writeFrom(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FAULTS - //Test write() method - try - { - aMedMedWrDriver21->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - // (BUG) => terminate called after throwing an instance of 'std::length_error' - // what(): basic_string::_S_create -#endif - - //Test close method - try - { - aMedMedWrDriver21->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_MED_WRONLY_DRIVER21 aMedMedWrDriver21Cpy_1; - - //Test (void operator =) defined in GENDRIVER class - //aMedMedWrDriver21Cpy_1 = *aMedMedWrDriver21; - - //Test copy constructor -#ifdef ENABLE_FAULTS - MED_MED_WRONLY_DRIVER21 aMedMedWrDriver21Cpy_2 (*aMedMedWrDriver21); - // (BUG) => Segmentation fault -#endif - //CPPUNIT_ASSERT_EQUAL(aMedMedWrDriver21Cpy_2, *aMedMedWrDriver21); - - //Test (bool operator ==) defined in GENDRIVER class - //CPPUNIT_ASSERT(aMedMedWrDriver21Cpy_2.GENDRIVER::operator==(*aMedMedWrDriver21)); - - //Test (friend ostream & operator <<) defined GENDRIVER class - //ostringstream rwostr1, rwostr2; - //rwostr1<<aMedMedWrDriver21Cpy_1; - //rwostr2<<aMedMedWrDriver21Cpy_2; - //CPPUNIT_ASSERT(rwostr1.str() != ""); - //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - -//-------------------------------Test READ/WRITE part------------------------------------------------------- - //Creation incorrect Med_Med read/write driver (file is not exist) - MED_MED_RDWR_DRIVER21 *aInvalidMedMedRdWrDriver21 = new MED_MED_RDWR_DRIVER21(fileNotExistsName_wr, aMed); - - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedMedRdWrDriver21->open(),MEDEXCEPTION); - - //Creation incorrect Med_Med read/write driver (with empty file name) - MED_MED_RDWR_DRIVER21 *aInvalidMedMedRdWrDriver21_1 = new MED_MED_RDWR_DRIVER21(emptyfilename, aMed); - - //Trying open file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedMedRdWrDriver21_1->open(),MEDEXCEPTION); - - - //Creation a correct Med_Med read/write driver (normal constructor) - MED_MED_RDWR_DRIVER21 *aMedMedRdWrDriver21 = new MED_MED_RDWR_DRIVER21(filename_rdwr, aMed); - - //Check driver - CPPUNIT_ASSERT(aMedMedRdWrDriver21); - - //Trying read MED from file if it is not open -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->read(), MEDEXCEPTION); - // (BUG) No exception in this case. -#endif - - CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->readFileStruct(),MEDEXCEPTION); - - //Trying write mesh to file, if file is not open -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver21->writeFrom(),MEDEXCEPTION); - // (BUG) => No exception in this case -#endif - -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver21->write(), MEDEXCEPTION); - //(BUG) => Crash -#endif - - //Test open() method - try - { - aMedMedRdWrDriver21->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying open() file twice -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver21->open(),MEDEXCEPTION); - //(BUG) No exception in this case. -#endif - - //Test readFileStruct() method - try - { - aMedMedRdWrDriver21->readFileStruct(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test read() method - try - { - aMedMedRdWrDriver21->read(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test writeFrom() method - try - { - aMedMedRdWrDriver21->writeFrom(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FAULTS - //Test write() method - try - { - aMedMedRdWrDriver21->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } -#endif - - //Test close() method - try - { - aMedMedRdWrDriver21->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_MED_RDWR_DRIVER21 aMedMedRdWrDriver21Cpy_1; - - //Test copy constructor -#ifdef ENABLE_FAULTS - MED_MED_RDWR_DRIVER21 aMedMedRdWrDriver21Cpy_2 (*aMedMedRdWrDriver21); - // (BUG) => Segmentation fault -#endif - //CPPUNIT_ASSERT_EQUAL(aMedMedRdWrDriver21Cpy_2, *aMedMedRdWrDriver21); - - //Test (bool operator ==) defined in GENDRIVER class - //CPPUNIT_ASSERT(aMedMedRdWrDriver21Cpy_2.GENDRIVER::operator==(*aMedMedRdWrDriver21)); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - //ostringstream rwostr1, rwostr2; - //rwostr1<<aMedMedRdWrDriver21Cpy_1; - //rwostr2<<aMedMedRdWrDriver21Cpy_2; - //CPPUNIT_ASSERT(rwostr1.str() != ""); - //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - //Delete all objects - delete aMed; - delete aInvalidMedMedRdDriver21; - delete aInvalidMedMedRdDriver21_1; - delete aMedMedRdDriver21; - - delete aInvalidMedMedWrDriver21; - delete aInvalidMedMedWrDriver21_1; - delete aMedMedWrDriver21; - - delete aInvalidMedMedRdWrDriver21; - delete aInvalidMedMedRdWrDriver21_1; - delete aMedMedRdWrDriver21; -} - -int main (int argc, char** argv) -{ - MEDMEMTest_testMedMedDriver21(); -} diff --git a/src/MEDMEM/Test/MEDMEMTest_MedMedDriver22.cxx b/src/MEDMEM/Test/MEDMEMTest_MedMedDriver22.cxx deleted file mode 100644 index dc09f5e03..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_MedMedDriver22.cxx +++ /dev/null @@ -1,517 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include <MEDMEM_Compatibility21_22.hxx> -#include <MEDMEM_MedMedDriver22.hxx> -#include <MEDMEM_Med.hxx> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -/*! - * Check methods (21), defined in MEDMEM_MedMedDriver22.hxx: - * class MED_MED_DRIVER22 : public virtual MED_MED_DRIVER { - * (+) MED_MED_DRIVER22(); - * (+) MED_MED_DRIVER22(const string & fileName, MED * const ptrMed); - * (+) MED_MED_DRIVER22(const string & fileName, MED * const ptrMed, - * MED_EN::med_mode_acces accessMode); - * (+) MED_MED_DRIVER22(const MED_MED_DRIVER22 & driver); - * (+) virtual ~MED_MED_DRIVER22(); - * (+) void open() throw (MEDEXCEPTION); - * (+) void close(); - * (+) virtual void write (void) const; - * (+) virtual void writeFrom (void) const; - * (+) virtual void read (void); - * (+) virtual void readFileStruct (void); - * } - * class MED_MED_RDONLY_DRIVER22 : public virtual IMED_MED_RDONLY_DRIVER, - * public virtual MED_MED_DRIVER22 { - * (+) MED_MED_RDONLY_DRIVER22(); - * (+) MED_MED_RDONLY_DRIVER22(const string & fileName, MED * const ptrMed); - * (+) MED_MED_RDONLY_DRIVER22(const MED_MED_RDONLY_DRIVER22 & driver); - * (+) virtual ~MED_MED_RDONLY_DRIVER22(); - * (+) void write (void) const throw (MEDEXCEPTION); - * (+) void writeFrom (void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void readFileStruct (void) throw (MEDEXCEPTION); - * } - * class MED_MED_WRONLY_DRIVER22 : public virtual IMED_MED_WRONLY_DRIVER, - * public virtual MED_MED_DRIVER22 { - * (+) MED_MED_WRONLY_DRIVER22(); - * (+) MED_MED_WRONLY_DRIVER22(const string & fileName, MED * const ptrMed); - * (+) MED_MED_WRONLY_DRIVER22(const MED_MED_WRONLY_DRIVER22 & driver); - * (+) virtual ~MED_MED_WRONLY_DRIVER22(); - * (+) void write (void) const throw (MEDEXCEPTION); - * (+) void writeFrom (void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void readFileStruct (void) throw (MEDEXCEPTION); - * } - * class MED_MED_RDWR_DRIVER22 : public virtual MED_MED_RDONLY_DRIVER22, - * public virtual MED_MED_WRONLY_DRIVER22, - * public virtual IMED_MED_RDWR_DRIVER { - * (+) MED_MED_RDWR_DRIVER22(); - * (+) MED_MED_RDWR_DRIVER22(const string & fileName, MED * const ptrMed); - * (+) MED_MED_RDWR_DRIVER22(const MED_MED_RDWR_DRIVER22 & driver); - * (+) ~MED_MED_RDWR_DRIVER22(); - * (+) void write (void) const throw (MEDEXCEPTION); - * (+) void writeFrom (void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void readFileStruct (void) throw (MEDEXCEPTION); - * } - */ -void MEDMEMTest::testMedMedDriver22() { - MED *aMed = new MED(); - string data_dir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - if(tmp_dir == "") - tmp_dir = "/tmp"; - - string filename_rd = data_dir + "/MedFiles/pointe_import22.med"; - string emptyfilename = ""; - string filename_wr = tmp_dir + "/myMedWr_pointe22.med"; - string fileNotExistsName_rd = "notExists.med"; - string fileNotExistsName_wr = "/path_not_exists/file_not_exists.med"; - string filename_rdwr = tmp_dir + "/myMedRdWr_pointe22.med"; - string fcopy = "cp " + filename_rd + " " + filename_rdwr; - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filename_wr); - aRemover.Register(filename_rdwr); - - //Copy file in the TMP dir for testing READ/WRITE case - system(fcopy.data()); - - //-------------------------------Test READ_ONLY part------------------------------------------------------- - //Creation incorrect Med_Med read only driver (file is not exist) - MED_MED_RDONLY_DRIVER22 *aInvalidMedMedRdDriver22 = new MED_MED_RDONLY_DRIVER22(fileNotExistsName_rd, aMed); - - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedMedRdDriver22->open(),MEDEXCEPTION); - - //Creation incorrect Med_Med read only driver (with empty file name) - MED_MED_RDONLY_DRIVER22 *aInvalidMedMedRdDriver22_1 = new MED_MED_RDONLY_DRIVER22(emptyfilename, aMed); - - //Trying open file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedMedRdDriver22_1->open(),MEDEXCEPTION); - - - //Creation a correct Med_Med read only driver (normal constructor) - MED_MED_RDONLY_DRIVER22 *aMedMedRdDriver22 = new MED_MED_RDONLY_DRIVER22(filename_rd, aMed); - - //Check driver - CPPUNIT_ASSERT(aMedMedRdDriver22); - - //Trying read mesh from file, if file is not open -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->read(), MEDEXCEPTION); - // (BUG) No exception in this case. -#endif - - CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->readFileStruct(),MEDEXCEPTION); - - //Test open() method - try - { - aMedMedRdDriver22->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying open() file twice -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->open(),MEDEXCEPTION); - //(BUG) No exception in this case. -#endif - - //Test read() method - try - { - aMedMedRdDriver22->read(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test read() method - try - { - aMedMedRdDriver22->readFileStruct(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test write() and WriteFrom() methods for READ_ONLY part - CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->write(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->writeFrom(), MEDEXCEPTION); - - //Check MED - CPPUNIT_ASSERT(aMed); - - //Test close() method - try - { - aMedMedRdDriver22->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_MED_RDONLY_DRIVER22 aMedMedRdDriver22Cpy_1; - - //Test (void operator =) defined in GENDRIVER class - //aMedMedRdDriver22Cpy_1 = *aMedMedRdDriver22; - - //Test copy constructor -#ifdef ENABLE_FAULTS - MED_MED_RDONLY_DRIVER22 aMedMedRdDriver22Cpy_2 (*aMedMedRdDriver22); - // (BUG) => Segmentation fault, because _concreteMedDrv is NULL -#endif - //CPPUNIT_ASSERT_EQUAL(aMedMedRdDriver22Cpy_2, *aMedMedRdDriver22); - - //Test (bool operator ==) defined in GENDRIVER class in MEDMEM_GenDriver.hxx - //CPPUNIT_ASSERT(aMedMedRdDriver22Cpy_2.GENDRIVER::operator==(*aMedMedRdDriver22)); - - //Test (friend ostream & operator <<) defined GENDRIVER class - //ostringstream rwostr1, rwostr2; - //rwostr1<<aMedMedRdDriver22Cpy_1; - //rwostr2<<aMedMedRdDriver22Cpy_2; - //CPPUNIT_ASSERT(rwostr1.str() != ""); - //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - //-------------------------------Test WRITE_ONLY part------------------------------------------------------- - //Creation incorrect Med_Med write only driver (file is not exist) - MED_MED_WRONLY_DRIVER22 *aInvalidMedMedWrDriver22 = new MED_MED_WRONLY_DRIVER22(fileNotExistsName_wr, aMed); - - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedMedWrDriver22->open(),MEDEXCEPTION); - - //Creation incorrect Med_Med write only driver (with empty file name) - MED_MED_WRONLY_DRIVER22 *aInvalidMedMedWrDriver22_1 = new MED_MED_WRONLY_DRIVER22(emptyfilename, aMed); - - //Trying open file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedMedWrDriver22_1->open(),MEDEXCEPTION); - - - //Creation a correct Med_Med write only driver (normal constructor) - MED_MED_WRONLY_DRIVER22 *aMedMedWrDriver22 = new MED_MED_WRONLY_DRIVER22(filename_wr, aMed); - - //Check driver - CPPUNIT_ASSERT(aMedMedWrDriver22); - - - //Trying write mesh to file, if file is not open -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedWrDriver22->writeFrom(),MEDEXCEPTION); - // (BUG) No exception in this case -#endif - -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_THROW(aMedMedWrDriver22->write(), MEDEXCEPTION); - //(BUG) => Segmentation fault -#endif - - //Test open() method - try - { - aMedMedWrDriver22->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying open() file twice -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedWrDriver22->open(),MEDEXCEPTION); - //(BUG) No exception in this case. -#endif - - //Test writeFrom() method - try - { - aMedMedWrDriver22->writeFrom(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FAULTS - //Test write() method - try - { - aMedMedWrDriver22->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - // (BUG) => terminate called after throwing an instance of 'std::length_error' - // what(): basic_string::_S_create -#endif - - //Test close method - try - { - aMedMedWrDriver22->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_MED_WRONLY_DRIVER22 aMedMedWrDriver22Cpy_1; - - //Test (void operator =) defined in GENDRIVER class - //aMedMedWrDriver22Cpy_1 = *aMedMedWrDriver22; - - //Test copy constructor -#ifdef ENABLE_FAULTS - MED_MED_WRONLY_DRIVER22 aMedMedWrDriver22Cpy_2 (*aMedMedWrDriver22); - // (BUG) => Segmentation fault -#endif - //CPPUNIT_ASSERT_EQUAL(aMedMedWrDriver22Cpy_2, *aMedMedWrDriver22); - - //Test (bool operator ==) defined in GENDRIVER class - //CPPUNIT_ASSERT(aMedMedWrDriver22Cpy_2.GENDRIVER::operator==(*aMedMedWrDriver22)); - - //Test (friend ostream & operator <<) defined GENDRIVER class - //ostringstream rwostr1, rwostr2; - //rwostr1<<aMedMedWrDriver22Cpy_1; - //rwostr2<<aMedMedWrDriver22Cpy_2; - //CPPUNIT_ASSERT(rwostr1.str() != ""); - //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - -//-------------------------------Test READ/WRITE part------------------------------------------------------- - //Creation incorrect Med_Med read/write driver (file is not exist) - MED_MED_RDWR_DRIVER22 *aInvalidMedMedRdWrDriver22 = new MED_MED_RDWR_DRIVER22(fileNotExistsName_wr, aMed); - - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedMedRdWrDriver22->open(),MEDEXCEPTION); - - //Creation incorrect Med_Med read/write driver (with empty file name) - MED_MED_RDWR_DRIVER22 *aInvalidMedMedRdWrDriver22_1 = new MED_MED_RDWR_DRIVER22(emptyfilename, aMed); - - //Trying open file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedMedRdWrDriver22_1->open(),MEDEXCEPTION); - - - //Creation a correct Med_Med read/write driver (normal constructor) - MED_MED_RDWR_DRIVER22 *aMedMedRdWrDriver22 = new MED_MED_RDWR_DRIVER22(filename_rdwr, aMed); - - //Check driver - CPPUNIT_ASSERT(aMedMedRdWrDriver22); - - //Trying read MED from file if it is not open -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->read(), MEDEXCEPTION); - // (BUG) No exception in this case. -#endif - - CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->readFileStruct(),MEDEXCEPTION); - - //Trying write mesh to file, if file is not open -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver22->writeFrom(),MEDEXCEPTION); - // (BUG) => No exception in this case -#endif - -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver22->write(), MEDEXCEPTION); - //(BUG) => Crash -#endif - - //Test open() method - try - { - aMedMedRdWrDriver22->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying open() file twice -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver22->open(),MEDEXCEPTION); - //(BUG) No exception in this case. -#endif - - //Test readFileStruct() method - try - { - aMedMedRdWrDriver22->readFileStruct(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test read() method - try - { - aMedMedRdWrDriver22->read(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test writeFrom() method - try - { - aMedMedRdWrDriver22->writeFrom(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FAULTS - //Test write() method - try - { - aMedMedRdWrDriver22->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } -#endif - - //Test close() method - try - { - aMedMedRdWrDriver22->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_MED_RDWR_DRIVER22 aMedMedRdWrDriver22Cpy_1; - - //Test copy constructor -#ifdef ENABLE_FAULTS - MED_MED_RDWR_DRIVER22 aMedMedRdWrDriver22Cpy_2 (*aMedMedRdWrDriver22); - // (BUG) => Segmentation fault -#endif - //CPPUNIT_ASSERT_EQUAL(aMedMedRdWrDriver22Cpy_2, *aMedMedRdWrDriver22); - - //Test (bool operator ==) defined in GENDRIVER class - //CPPUNIT_ASSERT(aMedMedRdWrDriver22Cpy_2.GENDRIVER::operator==(*aMedMedRdWrDriver22)); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - //ostringstream rwostr1, rwostr2; - //rwostr1<<aMedMedRdWrDriver22Cpy_1; - //rwostr2<<aMedMedRdWrDriver22Cpy_2; - //CPPUNIT_ASSERT(rwostr1.str() != ""); - //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - //Delete all objects - delete aMed; - delete aInvalidMedMedRdDriver22; - delete aInvalidMedMedRdDriver22_1; - delete aMedMedRdDriver22; - - delete aInvalidMedMedWrDriver22; - delete aInvalidMedMedWrDriver22_1; - delete aMedMedWrDriver22; - - delete aInvalidMedMedRdWrDriver22; - delete aInvalidMedMedRdWrDriver22_1; - delete aMedMedRdWrDriver22; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_MedMedDriver22_fault.cxx b/src/MEDMEM/Test/MEDMEMTest_MedMedDriver22_fault.cxx deleted file mode 100644 index 4c3806c3a..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_MedMedDriver22_fault.cxx +++ /dev/null @@ -1,522 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include <MEDMEM_Compatibility21_22.hxx> -#include <MEDMEM_MedMedDriver22.hxx> -#include <MEDMEM_Med.hxx> - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -//#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -/*! - * Check methods (21), defined in MEDMEM_MedMedDriver22.hxx: - * class MED_MED_DRIVER22 : public virtual MED_MED_DRIVER { - * (+) MED_MED_DRIVER22(); - * (+) MED_MED_DRIVER22(const string & fileName, MED * const ptrMed); - * (+) MED_MED_DRIVER22(const string & fileName, MED * const ptrMed, - * MED_EN::med_mode_acces accessMode); - * (+) MED_MED_DRIVER22(const MED_MED_DRIVER22 & driver); - * (+) virtual ~MED_MED_DRIVER22(); - * (+) void open() throw (MEDEXCEPTION); - * (+) void close(); - * (+) virtual void write (void) const; - * (+) virtual void writeFrom (void) const; - * (+) virtual void read (void); - * (+) virtual void readFileStruct (void); - * } - * class MED_MED_RDONLY_DRIVER22 : public virtual IMED_MED_RDONLY_DRIVER, - * public virtual MED_MED_DRIVER22 { - * (+) MED_MED_RDONLY_DRIVER22(); - * (+) MED_MED_RDONLY_DRIVER22(const string & fileName, MED * const ptrMed); - * (+) MED_MED_RDONLY_DRIVER22(const MED_MED_RDONLY_DRIVER22 & driver); - * (+) virtual ~MED_MED_RDONLY_DRIVER22(); - * (+) void write (void) const throw (MEDEXCEPTION); - * (+) void writeFrom (void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void readFileStruct (void) throw (MEDEXCEPTION); - * } - * class MED_MED_WRONLY_DRIVER22 : public virtual IMED_MED_WRONLY_DRIVER, - * public virtual MED_MED_DRIVER22 { - * (+) MED_MED_WRONLY_DRIVER22(); - * (+) MED_MED_WRONLY_DRIVER22(const string & fileName, MED * const ptrMed); - * (+) MED_MED_WRONLY_DRIVER22(const MED_MED_WRONLY_DRIVER22 & driver); - * (+) virtual ~MED_MED_WRONLY_DRIVER22(); - * (+) void write (void) const throw (MEDEXCEPTION); - * (+) void writeFrom (void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void readFileStruct (void) throw (MEDEXCEPTION); - * } - * class MED_MED_RDWR_DRIVER22 : public virtual MED_MED_RDONLY_DRIVER22, - * public virtual MED_MED_WRONLY_DRIVER22, - * public virtual IMED_MED_RDWR_DRIVER { - * (+) MED_MED_RDWR_DRIVER22(); - * (+) MED_MED_RDWR_DRIVER22(const string & fileName, MED * const ptrMed); - * (+) MED_MED_RDWR_DRIVER22(const MED_MED_RDWR_DRIVER22 & driver); - * (+) ~MED_MED_RDWR_DRIVER22(); - * (+) void write (void) const throw (MEDEXCEPTION); - * (+) void writeFrom (void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void readFileStruct (void) throw (MEDEXCEPTION); - * } - */ -void MEDMEMTest_testMedMedDriver22() { - MED *aMed = new MED(); - string data_dir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - if(tmp_dir == "") - tmp_dir = "/tmp"; - - string filename_rd = data_dir + "/MedFiles/pointe_import22.med"; - string emptyfilename = ""; - string filename_wr = tmp_dir + "/myMedWr_pointe22.med"; - string fileNotExistsName_rd = "notExists.med"; - string fileNotExistsName_wr = "/path_not_exists/file_not_exists.med"; - string filename_rdwr = tmp_dir + "/myMedRdWr_pointe22.med"; - string fcopy = "cp " + filename_rd + " " + filename_rdwr; - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filename_wr); - aRemover.Register(filename_rdwr); - - //Copy file in the TMP dir for testing READ/WRITE case - system(fcopy.data()); - - //-------------------------------Test READ_ONLY part------------------------------------------------------- - //Creation incorrect Med_Med read only driver (file is not exist) - MED_MED_RDONLY_DRIVER22 *aInvalidMedMedRdDriver22 = new MED_MED_RDONLY_DRIVER22(fileNotExistsName_rd, aMed); - - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedMedRdDriver22->open(),MEDEXCEPTION); - - //Creation incorrect Med_Med read only driver (with empty file name) - MED_MED_RDONLY_DRIVER22 *aInvalidMedMedRdDriver22_1 = new MED_MED_RDONLY_DRIVER22(emptyfilename, aMed); - - //Trying open file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedMedRdDriver22_1->open(),MEDEXCEPTION); - - - //Creation a correct Med_Med read only driver (normal constructor) - MED_MED_RDONLY_DRIVER22 *aMedMedRdDriver22 = new MED_MED_RDONLY_DRIVER22(filename_rd, aMed); - - //Check driver - CPPUNIT_ASSERT(aMedMedRdDriver22); - - //Trying read mesh from file, if file is not open -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->read(), MEDEXCEPTION); - // (BUG) No exception in this case. -#endif - - CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->readFileStruct(),MEDEXCEPTION); - - //Test open() method - try - { - aMedMedRdDriver22->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying open() file twice -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->open(),MEDEXCEPTION); - //(BUG) No exception in this case. -#endif - - //Test read() method - try - { - aMedMedRdDriver22->read(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test read() method - try - { - aMedMedRdDriver22->readFileStruct(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test write() and WriteFrom() methods for READ_ONLY part - CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->write(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->writeFrom(), MEDEXCEPTION); - - //Check MED - CPPUNIT_ASSERT(aMed); - - //Test close() method - try - { - aMedMedRdDriver22->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_MED_RDONLY_DRIVER22 aMedMedRdDriver22Cpy_1; - - //Test (void operator =) defined in GENDRIVER class - //aMedMedRdDriver22Cpy_1 = *aMedMedRdDriver22; - - //Test copy constructor -#ifdef ENABLE_FAULTS - MED_MED_RDONLY_DRIVER22 aMedMedRdDriver22Cpy_2 (*aMedMedRdDriver22); - // (BUG) => Segmentation fault, because _concreteMedDrv is NULL -#endif - //CPPUNIT_ASSERT_EQUAL(aMedMedRdDriver22Cpy_2, *aMedMedRdDriver22); - - //Test (bool operator ==) defined in GENDRIVER class in MEDMEM_GenDriver.hxx - //CPPUNIT_ASSERT(aMedMedRdDriver22Cpy_2.GENDRIVER::operator==(*aMedMedRdDriver22)); - - //Test (friend ostream & operator <<) defined GENDRIVER class - //ostringstream rwostr1, rwostr2; - //rwostr1<<aMedMedRdDriver22Cpy_1; - //rwostr2<<aMedMedRdDriver22Cpy_2; - //CPPUNIT_ASSERT(rwostr1.str() != ""); - //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - //-------------------------------Test WRITE_ONLY part------------------------------------------------------- - //Creation incorrect Med_Med write only driver (file is not exist) - MED_MED_WRONLY_DRIVER22 *aInvalidMedMedWrDriver22 = new MED_MED_WRONLY_DRIVER22(fileNotExistsName_wr, aMed); - - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedMedWrDriver22->open(),MEDEXCEPTION); - - //Creation incorrect Med_Med write only driver (with empty file name) - MED_MED_WRONLY_DRIVER22 *aInvalidMedMedWrDriver22_1 = new MED_MED_WRONLY_DRIVER22(emptyfilename, aMed); - - //Trying open file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedMedWrDriver22_1->open(),MEDEXCEPTION); - - - //Creation a correct Med_Med write only driver (normal constructor) - MED_MED_WRONLY_DRIVER22 *aMedMedWrDriver22 = new MED_MED_WRONLY_DRIVER22(filename_wr, aMed); - - //Check driver - CPPUNIT_ASSERT(aMedMedWrDriver22); - - - //Trying write mesh to file, if file is not open -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedWrDriver22->writeFrom(),MEDEXCEPTION); - // (BUG) No exception in this case -#endif - -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_THROW(aMedMedWrDriver22->write(), MEDEXCEPTION); - //(BUG) => Segmentation fault -#endif - - //Test open() method - try - { - aMedMedWrDriver22->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying open() file twice -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedWrDriver22->open(),MEDEXCEPTION); - //(BUG) No exception in this case. -#endif - - //Test writeFrom() method - try - { - aMedMedWrDriver22->writeFrom(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FAULTS - //Test write() method - try - { - aMedMedWrDriver22->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - // (BUG) => terminate called after throwing an instance of 'std::length_error' - // what(): basic_string::_S_create -#endif - - //Test close method - try - { - aMedMedWrDriver22->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_MED_WRONLY_DRIVER22 aMedMedWrDriver22Cpy_1; - - //Test (void operator =) defined in GENDRIVER class - //aMedMedWrDriver22Cpy_1 = *aMedMedWrDriver22; - - //Test copy constructor -#ifdef ENABLE_FAULTS - MED_MED_WRONLY_DRIVER22 aMedMedWrDriver22Cpy_2 (*aMedMedWrDriver22); - // (BUG) => Segmentation fault -#endif - //CPPUNIT_ASSERT_EQUAL(aMedMedWrDriver22Cpy_2, *aMedMedWrDriver22); - - //Test (bool operator ==) defined in GENDRIVER class - //CPPUNIT_ASSERT(aMedMedWrDriver22Cpy_2.GENDRIVER::operator==(*aMedMedWrDriver22)); - - //Test (friend ostream & operator <<) defined GENDRIVER class - //ostringstream rwostr1, rwostr2; - //rwostr1<<aMedMedWrDriver22Cpy_1; - //rwostr2<<aMedMedWrDriver22Cpy_2; - //CPPUNIT_ASSERT(rwostr1.str() != ""); - //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - -//-------------------------------Test READ/WRITE part------------------------------------------------------- - //Creation incorrect Med_Med read/write driver (file is not exist) - MED_MED_RDWR_DRIVER22 *aInvalidMedMedRdWrDriver22 = new MED_MED_RDWR_DRIVER22(fileNotExistsName_wr, aMed); - - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidMedMedRdWrDriver22->open(),MEDEXCEPTION); - - //Creation incorrect Med_Med read/write driver (with empty file name) - MED_MED_RDWR_DRIVER22 *aInvalidMedMedRdWrDriver22_1 = new MED_MED_RDWR_DRIVER22(emptyfilename, aMed); - - //Trying open file with empty name - CPPUNIT_ASSERT_THROW(aInvalidMedMedRdWrDriver22_1->open(),MEDEXCEPTION); - - - //Creation a correct Med_Med read/write driver (normal constructor) - MED_MED_RDWR_DRIVER22 *aMedMedRdWrDriver22 = new MED_MED_RDWR_DRIVER22(filename_rdwr, aMed); - - //Check driver - CPPUNIT_ASSERT(aMedMedRdWrDriver22); - - //Trying read MED from file if it is not open -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->read(), MEDEXCEPTION); - // (BUG) No exception in this case. -#endif - - CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->readFileStruct(),MEDEXCEPTION); - - //Trying write mesh to file, if file is not open -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver22->writeFrom(),MEDEXCEPTION); - // (BUG) => No exception in this case -#endif - -#ifdef ENABLE_FAULTS - CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver22->write(), MEDEXCEPTION); - //(BUG) => Crash -#endif - - //Test open() method - try - { - aMedMedRdWrDriver22->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying open() file twice -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver22->open(),MEDEXCEPTION); - //(BUG) No exception in this case. -#endif - - //Test readFileStruct() method - try - { - aMedMedRdWrDriver22->readFileStruct(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test read() method - try - { - aMedMedRdWrDriver22->read(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test writeFrom() method - try - { - aMedMedRdWrDriver22->writeFrom(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FAULTS - //Test write() method - try - { - aMedMedRdWrDriver22->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } -#endif - - //Test close() method - try - { - aMedMedRdWrDriver22->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Default constructor - MED_MED_RDWR_DRIVER22 aMedMedRdWrDriver22Cpy_1; - - //Test copy constructor -#ifdef ENABLE_FAULTS - MED_MED_RDWR_DRIVER22 aMedMedRdWrDriver22Cpy_2 (*aMedMedRdWrDriver22); - // (BUG) => Segmentation fault -#endif - //CPPUNIT_ASSERT_EQUAL(aMedMedRdWrDriver22Cpy_2, *aMedMedRdWrDriver22); - - //Test (bool operator ==) defined in GENDRIVER class - //CPPUNIT_ASSERT(aMedMedRdWrDriver22Cpy_2.GENDRIVER::operator==(*aMedMedRdWrDriver22)); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - //ostringstream rwostr1, rwostr2; - //rwostr1<<aMedMedRdWrDriver22Cpy_1; - //rwostr2<<aMedMedRdWrDriver22Cpy_2; - //CPPUNIT_ASSERT(rwostr1.str() != ""); - //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - //Delete all objects - delete aMed; - delete aInvalidMedMedRdDriver22; - delete aInvalidMedMedRdDriver22_1; - delete aMedMedRdDriver22; - - delete aInvalidMedMedWrDriver22; - delete aInvalidMedMedWrDriver22_1; - delete aMedMedWrDriver22; - - delete aInvalidMedMedRdWrDriver22; - delete aInvalidMedMedRdWrDriver22_1; - delete aMedMedRdWrDriver22; -} - -int main (int argc, char** argv) -{ - MEDMEMTest_testMedMedDriver22(); -} diff --git a/src/MEDMEM/Test/MEDMEMTest_MedMeshDriver21.cxx b/src/MEDMEM/Test/MEDMEMTest_MedMeshDriver21.cxx deleted file mode 100644 index d73c9ec6e..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_MedMeshDriver21.cxx +++ /dev/null @@ -1,535 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include <MEDMEM_MedMeshDriver21.hxx> -#include <MEDMEM_Mesh.hxx> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; - -/*! - * Check methods (13), defined in MEDMEM_MedMeshDriver21.hxx: - * class MED_MESH_DRIVER21 : public virtual MED_MESH_DRIVER { - * (+) MED_MESH_DRIVER21(); - * (+) MED_MESH_DRIVER21(const string & fileName, MESH * ptrMesh, MED_EN::med_mode_acces accessMode); - * (+) MED_MESH_DRIVER21(const MED_MESH_DRIVER21 & driver); - * (+) virtual ~MED_MESH_DRIVER21(); - * (+) void open(); - * (+) void close(); - * } - * class MED_MESH_RDONLY_DRIVER21 : public virtual IMED_MESH_RDONLY_DRIVER, - * public virtual MED_MESH_DRIVER21 { - * (+) MED_MESH_RDONLY_DRIVER21(); - * (+) MED_MESH_RDONLY_DRIVER21(const string & fileName, MESH * ptrMesh); - * (+) MED_MESH_RDONLY_DRIVER21(const MED_MESH_RDONLY_DRIVER21 & driver); - * (+) virtual ~MED_MESH_RDONLY_DRIVER21(); - * (+) void read (void); - * } - * class MED_MESH_WRONLY_DRIVER21 : public virtual IMED_MESH_WRONLY_DRIVER, - * public virtual MED_MESH_DRIVER21 { - * (+) MED_MESH_WRONLY_DRIVER21(); - * (+) MED_MESH_WRONLY_DRIVER21(const string & fileName, MESH * ptrMesh); - * (+) MED_MESH_WRONLY_DRIVER21(const MED_MESH_WRONLY_DRIVER21 & driver); - * (+) virtual ~MED_MESH_WRONLY_DRIVER21(); - * (+) void write(void) const; - * } - * class MED_MESH_RDWR_DRIVER21 : public IMED_MESH_RDWR_DRIVER, - * public MED_MESH_RDONLY_DRIVER21, public MED_MESH_WRONLY_DRIVER21 { - * (+) MED_MESH_RDWR_DRIVER21(); - * (+) MED_MESH_RDWR_DRIVER21(const string & fileName, MESH * ptrMesh); - * (+) MED_MESH_RDWR_DRIVER21(const MED_MESH_RDWR_DRIVER21 & driver); - * (+) ~MED_MESH_RDWR_DRIVER21(); - * (+) void write(void) const; - * (+) void read (void); - * } - */ -void MEDMEMTest::testMedMeshDriver21() -{ - MESH *aMesh = new MESH(); - MESH *aMesh_1 = new MESH(); - - string data_dir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - if (tmp_dir == "") tmp_dir = "/tmp"; - - string filename_rd = data_dir + "/MedFiles/pointe.med"; - string filename_wr = tmp_dir + "/myWr_pointe21.med"; - string tmpfile = tmp_dir + "/tmp.med"; - string meshname = "maa1"; - string newmeshname = "new" + meshname; - string fileNotExistsName_rd = "notExists.med"; - string fileNotExistsName_wr = "/path_not_exists/file_not_exists.med"; - string filename_rdwr = tmp_dir + "/myRdWr_pointe22.med"; - char* longmeshname = new char[MED_TAILLE_NOM+2]; - string fcopy = "cp " + filename_rd + " " + filename_rdwr; - for (int i = 0; i<MED_TAILLE_NOM+2; ++i) - longmeshname[i] = 'a'; - - //Copy file in the TMP dir for testing READ/WRITE case - system(fcopy.data()); - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filename_wr); - aRemover.Register(filename_rdwr); - aRemover.Register(tmpfile); - - //----------------------------------Test READ ONLY part---------------------------------------------------// - - //Creation a incorrect read only driver - MED_MESH_RDONLY_DRIVER21 *aInvalidRdDriver21 = new MED_MESH_RDONLY_DRIVER21(fileNotExistsName_rd, aMesh); - - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidRdDriver21->open(), MEDEXCEPTION); - - //Creation a correct read only driver (normal constructor) - MED_MESH_RDONLY_DRIVER21 *aRdDriver21 = new MED_MESH_RDONLY_DRIVER21(filename_rd, aMesh); - - //Check driver - CPPUNIT_ASSERT(aRdDriver21); - - //Trying read mesh from file, if file is not open - CPPUNIT_ASSERT_THROW(aRdDriver21->read(), MEDEXCEPTION); - - //Test open() method - try - { - aRdDriver21->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } -#ifdef ENABLE_FORCED_FAILURES - //Trying open file secondary. - CPPUNIT_ASSERT_THROW(aRdDriver21->open(), MEDEXCEPTION); - //This case is not work, seems it BUG - - //Trying read mesh from file, if mesh name is not set, i.e. empty - CPPUNIT_ASSERT_THROW(aRdDriver21->read(), MEDEXCEPTION); - //No correct exception in this case - - //Trying read mesh from file with very long name - //aRdDriver21->setMeshName(longmeshname); - CPPUNIT_ASSERT_THROW(aRdDriver21->read(), MEDEXCEPTION); - //No correct exception in this case -#endif - - //Set correct Mesh name - //Test setMeshName() and getMeshName() methods - try - { - aRdDriver21->setMeshName(meshname); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_EQUAL(meshname, aRdDriver21->getMeshName()); - - - //Test read() method - try - { - aRdDriver21->read(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test write() method for READ ONLY driver - CPPUNIT_ASSERT_THROW(aRdDriver21->write(), MEDEXCEPTION); - - //Check Mesh - CPPUNIT_ASSERT(aMesh); - - //Default constructor - MED_MESH_RDONLY_DRIVER21 aRdDriver21Cpy_1; - - //Test (void operator =) defined in GENDRIVER class in MEDMEM_GenDriver.hxx - //aRdDriver21Cpy_1 = *aRdDriver21; - - //Test (bool operator ==) defined GENDRIVER class in MEDMEM_GenDriver.hxx - CPPUNIT_ASSERT(aRdDriver21Cpy_1.GENDRIVER::operator==(*aRdDriver21)); - - //Test copy constructor - MED_MESH_RDONLY_DRIVER21 aRdDriver21Cpy_2 (aRdDriver21Cpy_1); - CPPUNIT_ASSERT_EQUAL(aRdDriver21Cpy_2, *aRdDriver21); - - //Test close() method - try - { - aRdDriver21->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying read mesh from copy closed driver - CPPUNIT_ASSERT_THROW(aRdDriver21Cpy_1.read(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aRdDriver21Cpy_2.read(), MEDEXCEPTION); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream rostr1, rostr2; - rostr1<<aRdDriver21Cpy_1; - rostr2<<aRdDriver21Cpy_2; - CPPUNIT_ASSERT(rostr1.str() != ""); - CPPUNIT_ASSERT(rostr1.str() == rostr2.str()); - - - //----------------------------------Test WRITE ONLY part------------------------------------------// - - //Creation a incorrect write only driver - MED_MESH_WRONLY_DRIVER21 *aInvalidWrDriver21 = new MED_MESH_WRONLY_DRIVER21(fileNotExistsName_wr, aMesh); - - //Trying open non existing file - CPPUNIT_ASSERT_THROW(aInvalidWrDriver21->open(), MEDEXCEPTION); - - //Trying write empty mesh - MED_MESH_WRONLY_DRIVER21 *aTmpWrDriver21 = new MED_MESH_WRONLY_DRIVER21(tmpfile, aMesh_1); - -#ifdef ENABLE_FORCED_FAILURES - aTmpWrDriver21->open(); - aTmpWrDriver21->setMeshName("EmptyMesh"); - CPPUNIT_ASSERT_THROW(aTmpWrDriver21->write(),MEDEXCEPTION); - aTmpWrDriver21->close(); - //Unknown exception in this case -#endif - - //Creation a correct write only driver - MED_MESH_WRONLY_DRIVER21 *aWrDriver21 = new MED_MESH_WRONLY_DRIVER21(filename_wr, aMesh); - - //Check driver - CPPUNIT_ASSERT(aWrDriver21); - - //Trying write mesh to file, if file is not open - CPPUNIT_ASSERT_THROW(aWrDriver21->write(), MEDEXCEPTION); - - //Test open() method - try - { - aWrDriver21->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FORCED_FAILURES - //Trying open file secondary. - CPPUNIT_ASSERT_THROW(aWrDriver21->open(), MEDEXCEPTION); - //This case is not work, seems it BUG -#endif - -#ifdef ENABLE_FORCED_FAILURES - //Test case: trying write mesh to file, if mesh name is not set, i.e empty - aMesh->setName(""); - aWrDriver21->setMeshName(""); - CPPUNIT_ASSERT_THROW(aWrDriver21->write(), MEDEXCEPTION); - //No exception in this case - - //Trying write mesh to file with very long name - aWrDriver21->setMeshName(longmeshname); - CPPUNIT_ASSERT_THROW(aWrDriver21->write(), MEDEXCEPTION); - //No exception in this case -#endif - - //Set initialy mesh name - aMesh->setName(meshname); - //Test setMeshName() and getMeshName() methods - try - { - aWrDriver21->setMeshName(meshname); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_EQUAL(meshname, aWrDriver21->getMeshName()); - - //Test write() method - try - { - aWrDriver21->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test read() method for WRITE ONLY driver - CPPUNIT_ASSERT_THROW(aWrDriver21->read(), MEDEXCEPTION); - - //Default constructor - MED_MESH_WRONLY_DRIVER21 aWrDriver21Cpy_1; - - //Test (void operator =) defined in GENDRIVER class - //aWrDriver21Cpy_1 = *aWrDriver21; - - //Test (bool operator ==) defined GENDRIVER class - CPPUNIT_ASSERT(aWrDriver21Cpy_1.GENDRIVER::operator==(*aWrDriver21)); - - //Test copy constructor - MED_MESH_WRONLY_DRIVER21 aWrDriver21Cpy_2 (aWrDriver21Cpy_1); - CPPUNIT_ASSERT_EQUAL(aWrDriver21Cpy_2 , *aWrDriver21); - - try - { - aWrDriver21->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test case: Trying write mesh using copy closed driver - CPPUNIT_ASSERT_THROW(aWrDriver21Cpy_1.write(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aWrDriver21Cpy_2.write(), MEDEXCEPTION); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream wostr1, wostr2; - wostr1<<aWrDriver21Cpy_1; - wostr2<<aWrDriver21Cpy_2; - CPPUNIT_ASSERT(wostr1.str() != ""); - CPPUNIT_ASSERT(wostr1.str() == wostr2.str()); - - - //----------------------------------Test READ / WRITE part------------------------------------------// - - //Creation a incorrect read/write driver - MED_MESH_RDWR_DRIVER21 *aInvalidRdWrDriver21 = new MED_MESH_RDWR_DRIVER21(fileNotExistsName_wr, aMesh_1); - - //Test case: trying open non existing file - CPPUNIT_ASSERT_THROW(aInvalidRdWrDriver21->open(), MEDEXCEPTION); - - //Creation a correct read/write driver - MED_MESH_RDWR_DRIVER21 *aRdWrDriver21 = new MED_MESH_RDWR_DRIVER21(filename_rdwr, aMesh_1); - - //Check driver - CPPUNIT_ASSERT(aRdWrDriver21); - - //Test case: trying write mesh to file, if file is not open - CPPUNIT_ASSERT_THROW(aRdWrDriver21->write(), MEDEXCEPTION); - - //Test case: trying read mesh from file, if file is not open - CPPUNIT_ASSERT_THROW(aRdWrDriver21->read(), MEDEXCEPTION); - - //Test open() method - try - { - aRdWrDriver21->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FORCED_FAILURES - //Test case: trying open file secondary. - CPPUNIT_ASSERT_THROW(aRdWrDriver21->open(), MEDEXCEPTION); - //This case is not work, seems it BUG -#endif - -#ifdef ENABLE_FORCED_FAILURES - //Set mesh name - aMesh_1->setName("EmptyMesh"); - aRdWrDriver21->setMeshName("EmptyMesh"); - - //Trying write in file empty mesh - CPPUNIT_ASSERT_THROW(aRdWrDriver21->write(),MEDEXCEPTION); - //No exception in this case, seems it BUG -#endif - - //Set initialy mesh name - aMesh_1->setName(meshname); - //Test setMeshName() and getMeshName() methods - try - { - aRdWrDriver21->setMeshName(meshname); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_EQUAL(meshname, aRdWrDriver21->getMeshName()); - - //Test read() method - try - { - aRdWrDriver21->read(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying read mesh from file, if mesh name is not set, i.e. empty -#ifdef ENABLE_FORCED_FAILURES - aRdWrDriver21->setMeshName(""); - aMesh_1->setName(""); - CPPUNIT_ASSERT_THROW(aRdWrDriver21->read(), MEDEXCEPTION); - //No correct exception in this case - - //Trying write mesh to file, if mesh name is not set, i.e empty - CPPUNIT_ASSERT_THROW(aRdWrDriver21->write(), MEDEXCEPTION); - //No correct exception in this case - - //Trying read mesh from file with very long name - aRdWrDriver21->setMeshName(longmeshname); - aMesh_1->setName(longmeshname); - CPPUNIT_ASSERT_THROW(aRdWrDriver21->read(), MEDEXCEPTION); - //No correct exception in this case - - //Trying write mesh to file with very long name - CPPUNIT_ASSERT_THROW(aRdWrDriver21->write(), MEDEXCEPTION); - //No correct exception in this case -#endif - - //Test write() method - aRdWrDriver21->setMeshName(newmeshname); - aMesh_1->setName(newmeshname); - try - { - aRdWrDriver21->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Check Mesh - CPPUNIT_ASSERT(aMesh_1); - - //Default constructor - MED_MESH_RDWR_DRIVER21 aRdWrDriver21Cpy_1; - - //Test (void operator =) defined in GENDRIVER class - //aRdWrDriver21Cpy_1 = *aRdWrDriver21; - - //Test (bool operator ==) defined GENDRIVER class - CPPUNIT_ASSERT(aRdWrDriver21Cpy_1.GENDRIVER::operator==(*aRdWrDriver21)); - - //Test copy constructor - MED_MESH_RDWR_DRIVER21 aRdWrDriver21Cpy_2 (aRdWrDriver21Cpy_1); - CPPUNIT_ASSERT_EQUAL(aRdWrDriver21Cpy_2, *aRdWrDriver21); - - try - { - aRdWrDriver21->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test case: trying read/write mesh using copy closed driver - CPPUNIT_ASSERT_THROW(aRdWrDriver21Cpy_1.read(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aRdWrDriver21Cpy_2.read(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aRdWrDriver21Cpy_1.write(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aRdWrDriver21Cpy_2.write(), MEDEXCEPTION); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream rwostr1, rwostr2; - rwostr1<<aRdWrDriver21Cpy_1; - rwostr2<<aRdWrDriver21Cpy_2; - CPPUNIT_ASSERT(rwostr1.str() != ""); - CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - //Delete all objects - delete longmeshname; - - delete aInvalidRdDriver21; - delete aRdDriver21; - - delete aInvalidWrDriver21; - delete aWrDriver21; - delete aTmpWrDriver21; - - delete aInvalidRdWrDriver21; - delete aRdWrDriver21; - - delete aMesh; - delete aMesh_1; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_MedMeshDriver22.cxx b/src/MEDMEM/Test/MEDMEMTest_MedMeshDriver22.cxx deleted file mode 100644 index 043e26253..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_MedMeshDriver22.cxx +++ /dev/null @@ -1,523 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include <MEDMEM_MedMeshDriver22.hxx> -#include <MEDMEM_Mesh.hxx> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; - -/*! - * Check methods (13), defined in MEDMEM_MedMeshDriver22.hxx: - * class MED_MESH_DRIVER22 : public virtual MED_MESH_DRIVER { - * (+) MED_MESH_DRIVER22(); - * (+) MED_MESH_DRIVER22(const string & fileName, MESH * ptrMesh, MED_EN::med_mode_acces accessMode); - * (+) MED_MESH_DRIVER22(const MED_MESH_DRIVER22 & driver); - * (+) virtual ~MED_MESH_DRIVER22(); - * (+) void open(); - * (+) void close(); - * } - * class MED_MESH_RDONLY_DRIVER22 : public virtual IMED_MESH_RDONLY_DRIVER, - * public virtual MED_MESH_DRIVER22 { - * (+) MED_MESH_RDONLY_DRIVER22(); - * (+) MED_MESH_RDONLY_DRIVER22(const string & fileName, MESH * ptrMesh); - * (+) MED_MESH_RDONLY_DRIVER22(const MED_MESH_RDONLY_DRIVER22 & driver); - * (+) virtual ~MED_MESH_RDONLY_DRIVER22(); - * (+) void read (void); - * } - * class MED_MESH_WRONLY_DRIVER22 : public virtual IMED_MESH_WRONLY_DRIVER, - * public virtual MED_MESH_DRIVER22 { - * (+) MED_MESH_WRONLY_DRIVER22(); - * (+) MED_MESH_WRONLY_DRIVER22(const string & fileName, MESH * ptrMesh); - * (+) MED_MESH_WRONLY_DRIVER22(const MED_MESH_WRONLY_DRIVER22 & driver); - * (+) virtual ~MED_MESH_WRONLY_DRIVER22(); - * (+) void write(void) const; - * } - * class MED_MESH_RDWR_DRIVER22 : public IMED_MESH_RDWR_DRIVER, - * public MED_MESH_RDONLY_DRIVER22, public MED_MESH_WRONLY_DRIVER22 { - * (+) MED_MESH_RDWR_DRIVER22(); - * (+) MED_MESH_RDWR_DRIVER22(const string & fileName, MESH * ptrMesh); - * (+) MED_MESH_RDWR_DRIVER22(const MED_MESH_RDWR_DRIVER22 & driver); - * (+) ~MED_MESH_RDWR_DRIVER22(); - * (+) void write(void) const; - * (+) void read (void); - * } - */ -void MEDMEMTest::testMedMeshDriver22() -{ - MESH *aMesh = new MESH(); - MESH *aMesh_1 = new MESH(); - - string data_dir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - if (tmp_dir == "") tmp_dir = "/tmp"; - - string filename_rd = data_dir + "/MedFiles/pointe_import22.med"; - string filename_wr = tmp_dir + "/myWr_pointe22.med"; - string tmpfile = tmp_dir + "/tmp.med"; - string meshname = "maa1"; - string newmeshname = "new" + meshname; - string fileNotExistsName_rd = "notExists.med"; - string fileNotExistsName_wr = "/path_not_exists/file_not_exists.med"; - string filename_rdwr = tmp_dir + "/myRdWr_pointe22.med"; - char* longmeshname = new char[MED_TAILLE_NOM+2]; - string fcopy = "cp " + filename_rd + " " + filename_rdwr; - for (int i = 0; i<MED_TAILLE_NOM+2; ++i) - longmeshname[i] = 'a'; - - //Copy file in the TMP dir for testing READ/WRITE case - system(fcopy.data()); - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filename_wr); - aRemover.Register(filename_rdwr); - aRemover.Register(tmpfile); - - //----------------------------------Test READ ONLY part---------------------------------------------------// - - //Creation a incorrect read only driver - MED_MESH_RDONLY_DRIVER22 *aInvalidRdDriver22 = new MED_MESH_RDONLY_DRIVER22(fileNotExistsName_rd, aMesh); - - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidRdDriver22->open(), MEDEXCEPTION); - - //Creation a correct read only driver (normal constructor) - MED_MESH_RDONLY_DRIVER22 *aRdDriver22 = new MED_MESH_RDONLY_DRIVER22(filename_rd, aMesh); - - //Check driver - CPPUNIT_ASSERT(aRdDriver22); - - //Trying read mesh from file, if file is not open - CPPUNIT_ASSERT_THROW(aRdDriver22->read(), MEDEXCEPTION); - - //Test open() method - try - { - aRdDriver22->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FORCED_FAILURES - //Trying open file secondary. - CPPUNIT_ASSERT_THROW(aRdDriver22->open(), MEDEXCEPTION); - //This case is not work, seems it BUG -#endif - - //Trying read mesh from file, if mesh name is not set, i.e. empty - CPPUNIT_ASSERT_THROW(aRdDriver22->read(), MEDEXCEPTION); - - //Trying read mesh from file with very long name - aRdDriver22->setMeshName(longmeshname); - CPPUNIT_ASSERT_THROW(aRdDriver22->read(), MEDEXCEPTION); - - //Set correct Mesh name - //Test setMeshName() and getMeshName() methods - try - { - aRdDriver22->setMeshName(meshname); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_EQUAL(meshname, aRdDriver22->getMeshName()); - - - //Test read() method - try - { - aRdDriver22->read(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test write() method for READ ONLY driver - CPPUNIT_ASSERT_THROW(aRdDriver22->write(), MEDEXCEPTION); - - //Check Mesh - CPPUNIT_ASSERT(aMesh); - - //Default constructor - MED_MESH_RDONLY_DRIVER22 aRdDriver22Cpy_1; - - //Test (void operator =) defined in GENDRIVER class in MEDMEM_GenDriver.hxx - //aRdDriver22Cpy_1 = *aRdDriver22; - - //Test (bool operator ==) defined GENDRIVER class in MEDMEM_GenDriver.hxx - CPPUNIT_ASSERT(aRdDriver22Cpy_1.GENDRIVER::operator==(*aRdDriver22)); - - //Test copy constructor - MED_MESH_RDONLY_DRIVER22 aRdDriver22Cpy_2 (aRdDriver22Cpy_1); - CPPUNIT_ASSERT_EQUAL(aRdDriver22Cpy_2, *aRdDriver22); - - //Test close() method - try - { - aRdDriver22->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying read mesh from copy closed driver - CPPUNIT_ASSERT_THROW(aRdDriver22Cpy_1.read(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aRdDriver22Cpy_2.read(), MEDEXCEPTION); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream rostr1, rostr2; - rostr1<<aRdDriver22Cpy_1; - rostr2<<aRdDriver22Cpy_2; - CPPUNIT_ASSERT(rostr1.str() != ""); - CPPUNIT_ASSERT(rostr1.str() == rostr2.str()); - - - //----------------------------------Test WRITE ONLY part------------------------------------------// - - //Creation a incorrect write only driver - MED_MESH_WRONLY_DRIVER22 *aInvalidWrDriver22 = new MED_MESH_WRONLY_DRIVER22(fileNotExistsName_wr, aMesh); - - //Trying open non existing file - CPPUNIT_ASSERT_THROW(aInvalidWrDriver22->open(), MEDEXCEPTION); - - //Trying write empty mesh - MED_MESH_WRONLY_DRIVER22 *aTmpWrDriver22 = new MED_MESH_WRONLY_DRIVER22(tmpfile, aMesh_1); - -#ifdef ENABLE_FORCED_FAILURES - aTmpWrDriver22->open(); - aTmpWrDriver22->setMeshName("EmptyMesh"); - CPPUNIT_ASSERT_THROW(aTmpWrDriver22->write(),MEDEXCEPTION); - aTmpWrDriver22->close(); - //Unknown exception in this case -#endif - - //Creation a correct write only driver - MED_MESH_WRONLY_DRIVER22 *aWrDriver22 = new MED_MESH_WRONLY_DRIVER22(filename_wr, aMesh); - - //Check driver - CPPUNIT_ASSERT(aWrDriver22); - - //Trying write mesh to file, if file is not open - CPPUNIT_ASSERT_THROW(aWrDriver22->write(), MEDEXCEPTION); - - //Test open() method - try - { - aWrDriver22->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FORCED_FAILURES - //Trying open file secondary. - CPPUNIT_ASSERT_THROW(aWrDriver22->open(), MEDEXCEPTION); - //This case is not work, seems it BUG -#endif - - //Test case: trying write mesh to file, if mesh name is not set, i.e empty - aMesh->setName(""); - aWrDriver22->setMeshName(""); - CPPUNIT_ASSERT_THROW(aWrDriver22->write(), MEDEXCEPTION); - - //Trying write mesh to file with very long name - aWrDriver22->setMeshName(longmeshname); - CPPUNIT_ASSERT_THROW(aWrDriver22->write(), MEDEXCEPTION); - - //Set initialy mesh name - aMesh->setName(meshname); - //Test setMeshName() and getMeshName() methods - try - { - aWrDriver22->setMeshName(meshname); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_EQUAL(meshname, aWrDriver22->getMeshName()); - - //Test write() method - try - { - aWrDriver22->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test read() method for WRITE ONLY driver - CPPUNIT_ASSERT_THROW(aWrDriver22->read(), MEDEXCEPTION); - - //Default constructor - MED_MESH_WRONLY_DRIVER22 aWrDriver22Cpy_1; - - //Test (void operator =) defined in GENDRIVER class - //aWrDriver22Cpy_1 = *aWrDriver22; - - //Test (bool operator ==) defined GENDRIVER class - CPPUNIT_ASSERT(aWrDriver22Cpy_1.GENDRIVER::operator==(*aWrDriver22)); - - //Test copy constructor - MED_MESH_WRONLY_DRIVER22 aWrDriver22Cpy_2 (aWrDriver22Cpy_1); - CPPUNIT_ASSERT_EQUAL(aWrDriver22Cpy_2 , *aWrDriver22); - - try - { - aWrDriver22->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test case: Trying write mesh using copy closed driver - CPPUNIT_ASSERT_THROW(aWrDriver22Cpy_1.write(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aWrDriver22Cpy_2.write(), MEDEXCEPTION); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream wostr1, wostr2; - wostr1<<aWrDriver22Cpy_1; - wostr2<<aWrDriver22Cpy_2; - CPPUNIT_ASSERT(wostr1.str() != ""); - CPPUNIT_ASSERT(wostr1.str() == wostr2.str()); - - - //----------------------------------Test READ / WRITE part------------------------------------------// - - //Creation a incorrect read/write driver - MED_MESH_RDWR_DRIVER22 *aInvalidRdWrDriver22 = new MED_MESH_RDWR_DRIVER22(fileNotExistsName_wr, aMesh_1); - - //Test case: trying open non existing file - CPPUNIT_ASSERT_THROW(aInvalidRdWrDriver22->open(), MEDEXCEPTION); - - //Creation a correct read/write driver - MED_MESH_RDWR_DRIVER22 *aRdWrDriver22 = new MED_MESH_RDWR_DRIVER22(filename_rdwr, aMesh_1); - - //Check driver - CPPUNIT_ASSERT(aRdWrDriver22); - - //Test case: trying write mesh to file, if file is not open - CPPUNIT_ASSERT_THROW(aRdWrDriver22->write(), MEDEXCEPTION); - - //Test case: trying read mesh from file, if file is not open - CPPUNIT_ASSERT_THROW(aRdWrDriver22->read(), MEDEXCEPTION); - - //Test open() method - try - { - aRdWrDriver22->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FORCED_FAILURES - //Test case: trying open file secondary. - CPPUNIT_ASSERT_THROW(aRdWrDriver22->open(), MEDEXCEPTION); - //This case is not work, seems it BUG -#endif - -#ifdef ENABLE_FORCED_FAILURES - //Set mesh name - aMesh_1->setName("EmptyMesh"); - aRdWrDriver22->setMeshName("EmptyMesh"); - //Trying write in file empty mesh - CPPUNIT_ASSERT_THROW(aRdWrDriver22->write(),MEDEXCEPTION); - //No exception in this case, seems it BUG -#endif - - //Set initialy mesh name - aMesh_1->setName(meshname); - //Test setMeshName() and getMeshName() methods - try - { - aRdWrDriver22->setMeshName(meshname); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_EQUAL(meshname, aRdWrDriver22->getMeshName()); - - //Test read() method - try - { - aRdWrDriver22->read(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Trying read mesh from file, if mesh name is not set, i.e. empty - aRdWrDriver22->setMeshName(""); - aMesh_1->setName(""); - CPPUNIT_ASSERT_THROW(aRdWrDriver22->read(), MEDEXCEPTION); - - //Trying write mesh to file, if mesh name is not set, i.e empty - CPPUNIT_ASSERT_THROW(aRdWrDriver22->write(), MEDEXCEPTION); - - //Trying read mesh from file with very long name - aRdWrDriver22->setMeshName(longmeshname); - aMesh_1->setName(longmeshname); - CPPUNIT_ASSERT_THROW(aRdWrDriver22->read(), MEDEXCEPTION); - - //Trying write mesh to file with very long name - CPPUNIT_ASSERT_THROW(aRdWrDriver22->write(), MEDEXCEPTION); - - //Test write() method - aRdWrDriver22->setMeshName(newmeshname); - aMesh_1->setName(newmeshname); - try - { - aRdWrDriver22->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Check Mesh - CPPUNIT_ASSERT(aMesh_1); - - //Default constructor - MED_MESH_RDWR_DRIVER22 aRdWrDriver22Cpy_1; - - //Test (void operator =) defined in GENDRIVER class - //aRdWrDriver22Cpy_1 = *aRdWrDriver22; - - //Test (bool operator ==) defined GENDRIVER class - CPPUNIT_ASSERT(aRdWrDriver22Cpy_1.GENDRIVER::operator==(*aRdWrDriver22)); - - //Test copy constructor - MED_MESH_RDWR_DRIVER22 aRdWrDriver22Cpy_2 (aRdWrDriver22Cpy_1); - CPPUNIT_ASSERT_EQUAL(aRdWrDriver22Cpy_2, *aRdWrDriver22); - - try - { - aRdWrDriver22->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test case: trying read/write mesh using copy closed driver - CPPUNIT_ASSERT_THROW(aRdWrDriver22Cpy_1.read(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aRdWrDriver22Cpy_2.read(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aRdWrDriver22Cpy_1.write(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aRdWrDriver22Cpy_2.write(), MEDEXCEPTION); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream rwostr1, rwostr2; - rwostr1<<aRdWrDriver22Cpy_1; - rwostr2<<aRdWrDriver22Cpy_2; - CPPUNIT_ASSERT(rwostr1.str() != ""); - CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - //Delete all objects - delete longmeshname; - - delete aInvalidRdDriver22; - delete aRdDriver22; - - delete aInvalidWrDriver22; - delete aWrDriver22; - - delete aInvalidRdWrDriver22; - delete aRdWrDriver22; - delete aTmpWrDriver22; - - delete aMesh; - delete aMesh_1; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_MedVersion.cxx b/src/MEDMEM/Test/MEDMEMTest_MedVersion.cxx deleted file mode 100644 index fecc5a8ed..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_MedVersion.cxx +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include <cstdlib> -#include <exception> - -#include <MEDMEM_MedVersion.hxx> -#include "MEDMEM_Compatibility21_22.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -/*! - * Check methods (not in spec), defined in MEDMEM_MedVersion.hxx: - * (+) MED_EN::medFileVersion getMedFileVersion(const string & fileName) throw (MEDEXCEPTION); - * (+) int getMedAccessMode(MED_EN::med_mode_acces mode, - * MED_EN::medFileVersion medVersion) throw (MEDEXCEPTION); - */ - -void MEDMEMTest::testMedVersion() -{ - string filename = getenv("DATA_DIR"); - filename += "/MedFiles/pointe.med"; - string notExistFileName = "anyfile"; - medFileVersion myFileVersion; - medFileVersion myEmptyFileVersion; - - // Test - getMedFileVersion - CPPUNIT_ASSERT_THROW(getMedFileVersion(notExistFileName),MEDEXCEPTION); - - try - { - myFileVersion = getMedFileVersion(filename); - CPPUNIT_ASSERT(myFileVersion == V21); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch(...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test - getMedAccessMode - CPPUNIT_ASSERT_THROW(getMedAccessMode(MED_REMP,myEmptyFileVersion),MEDEXCEPTION); - - try - { - CPPUNIT_ASSERT_EQUAL(med_2_1::MED_ECRI, - (med_2_1::med_mode_acces)getMedAccessMode(MED_REMP,myFileVersion)); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch(...) - { - CPPUNIT_FAIL("Unknown exception"); - } -} diff --git a/src/MEDMEM/Test/MEDMEMTest_MeshAndMeshing.cxx b/src/MEDMEM/Test/MEDMEMTest_MeshAndMeshing.cxx deleted file mode 100644 index fb63b63eb..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_MeshAndMeshing.cxx +++ /dev/null @@ -1,1844 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/Message.h> -#include <cppunit/TestAssert.h> -#include "MEDMEM_Meshing.hxx" -#include "MEDMEM_Group.hxx" -#include "MEDMEM_define.hxx" -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_Grid.hxx" - -#include "MEDMEM_Med.hxx" -#include "MEDMEM_MedMeshDriver22.hxx" - -#include <sstream> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -double dmax(double x, double y) { return (x>y)?x:y;} - -double dmin(double x, double y) { return (x>y)?y:x;} - -void addMedFacesGroup (MESHING& meshing, int nFaces, const int *groupValue, - string groupName, const MED_EN::medGeometryElement *mytypes, - const int *index, const int *myNumberOfElements, int nbOfGeomTypes) -{ - GROUP faces; - faces.setName(groupName); - faces.setMesh(&meshing); - faces.setEntity(MED_EN::MED_FACE); - faces.setNumberOfGeometricType(nbOfGeomTypes); - faces.setGeometricType(mytypes); - faces.setNumberOfElements(myNumberOfElements); - faces.setNumber(index, groupValue); - meshing.addGroup(faces); -} - -void addMedFacesGroupAll (MESHING& meshing, string groupName) -{ - GROUP faces; - faces.setName(groupName); - faces.setMesh(&meshing); - faces.setEntity(MED_EN::MED_FACE); - meshing.addGroup(faces); -} - -/*! - * Check methods (18), defined in MEDMEM_Meshing.hxx: - * class MESHING: public MESH { - * (+) MESHING(); - * (+) ~MESHING(); - * (+) void setSpaceDimension (const int SpaceDimension); - * (+) void setMeshDimension (const int MeshDimension); - * (+) void setNumberOfNodes (const int NumberOfNodes); - * (+) void setCoordinates (const int SpaceDimension, const int NumberOfNodes, - * const double * Coordinates, - * const string System, const MED_EN::medModeSwitch Mode); - * (+) void setCoordinatesSystem(const string System) throw (MEDEXCEPTION); - * (+) void setCoordinatesNames (const string * names); - * (+) void setCoordinateName (const string name, const int i); - * (+) void setCoordinatesUnits (const string * units); - * (+) void setCoordinateUnit (const string unit, const int i); - * (+) void setNumberOfTypes (const int NumberOfTypes, - * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); - * (+) void setTypes (const MED_EN::medGeometryElement * Types, - * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); - * (+) void setNumberOfElements (const int * NumberOfElements, - * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); - * (+) void setConnectivity (const int * Connectivity, const MED_EN::medEntityMesh Entity, - * const MED_EN::medGeometryElement Type) throw (MEDEXCEPTION); - * (+) void setPolygonsConnectivity (const int * ConnectivityIndex, const int * ConnectivityValue, - * int nbOfPolygons, - * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); - * (+) void setPolyhedraConnectivity (const int * PolyhedronIndex, const int * FacesIndex, - * const int * Nodes, int nbOfPolyhedra, - * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); - * (NOT YET IMPLEMENTED!!!) void setConnectivities (const int * ConnectivityIndex, - * const int * ConnectivityValue, - * const MED_EN::medConnectivity ConnectivityType, - * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); - * (+) void addGroup (const GROUP & Group) throw (MEDEXCEPTION); - * } - */ - -/*! - * Check methods (87), defined in MEDMEM_Mesh.hxx: - * class MESH : public RCBASE { - * (+) void init(); - * (+) MESH(); - * (+) MESH(MESH &m); - * (+) MESH & operator=(const MESH &m); - * (+) virtual bool operator==(const MESH& other) const; - * (+) virtual bool deepCompare(const MESH& other) const; - * (+) MESH(driverTypes driverType, const string & fileName="", - * const string & meshName="") throw (MEDEXCEPTION); - * (+) virtual ~MESH(); - * (+) friend ostream & operator<<(ostream &os, const MESH &my); - * (+) int addDriver(driverTypes driverType, - * const string & fileName="Default File Name.med", - * const string & driverName="Default Mesh Name", - * MED_EN::med_mode_acces access=MED_EN::MED_REMP); - * (+) int addDriver(GENDRIVER & driver); - * (+) void rmDriver(int index=0); - * (+) virtual void read(int index=0); - * (must be private) inline void read(const GENDRIVER & genDriver); - * (+) inline void write(int index=0, const string & driverName = ""); - * (must be private) inline void write(const GENDRIVER & genDriver); - * (+) inline void setName(string name); - * (+) inline void setDescription(string description); - * (+) inline string getName() const; - * (+) inline string getDescription() const; - * (+) inline int getSpaceDimension() const; - * (+) inline int getMeshDimension() const; - * (+) inline bool getIsAGrid(); - * (+) inline int getNumberOfNodes() const; - * (+) virtual inline const COORDINATE * getCoordinateptr() const; - * (+) inline string getCoordinatesSystem() const; - * (+) virtual inline const double * getCoordinates(MED_EN::medModeSwitch Mode) const; - * (+) virtual inline const double getCoordinate(int Number,int Axis) const; - * (+) inline const string * getCoordinatesNames() const; - * (+) inline const string * getCoordinatesUnits() const; - * (+) virtual inline int getNumberOfTypes(MED_EN::medEntityMesh Entity) const; - * (+) virtual int getNumberOfTypesWithPoly(MED_EN::medEntityMesh Entity) const; - * (+) virtual inline const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const; - * (+) virtual MED_EN::medGeometryElement * getTypesWithPoly(MED_EN::medEntityMesh Entity) const; - * (+) virtual inline const CELLMODEL * getCellsTypes(MED_EN::medEntityMesh Entity) const; - * (+) virtual inline string * getCellTypeNames(MED_EN::medEntityMesh Entity) const; - * (+) virtual const int * getGlobalNumberingIndex(MED_EN::medEntityMesh Entity) const; - * (+) virtual inline int getNumberOfElements(MED_EN::medEntityMesh Entity, - * MED_EN::medGeometryElement Type) const; - * (+) virtual int getNumberOfElementsWithPoly(MED_EN::medEntityMesh Entity, - * MED_EN::medGeometryElement Type) const; - * (+) virtual inline bool existConnectivity(MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity) const; - * (+) inline bool existPolygonsConnectivity(MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity) const; - * (+) inline bool existPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity) const; - * (+) virtual inline MED_EN::medGeometryElement getElementType - * (MED_EN::medEntityMesh Entity, int Number) const; - * (+) virtual inline MED_EN::medGeometryElement getElementTypeWithPoly - * (MED_EN::medEntityMesh Entity, int Number) const; - * (+) virtual inline void calculateConnectivity(MED_EN::medModeSwitch Mode, - * MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity) const; - * (+) virtual inline int getConnectivityLength(MED_EN::medModeSwitch Mode, - * MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity, - * MED_EN::medGeometryElement Type) const; - * (+) virtual inline const int * getConnectivity(MED_EN::medModeSwitch Mode, - * MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity, - * MED_EN::medGeometryElement Type) const; - * (+) virtual inline const int * getConnectivityIndex - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; - * (+) inline int getPolygonsConnectivityLength - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; - * (+) inline const int * getPolygonsConnectivity - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; - * (+) inline const int * getPolygonsConnectivityIndex - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; - * (+) inline int getNumberOfPolygons(MED_EN::medEntityMesh Entity=MED_EN::MED_ALL_ENTITIES) const; - * (+) inline int getPolyhedronConnectivityLength(MED_EN::medConnectivity ConnectivityType) const; - * (+) inline const int * getPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType) const; - * (+) inline const int * getPolyhedronFacesIndex() const; - * (+) inline const int * getPolyhedronIndex(MED_EN::medConnectivity ConnectivityType) const; - * (+) inline int getNumberOfPolyhedronFaces() const; - * (+) inline int getNumberOfPolyhedron() const; - * (+) virtual int getElementNumber(MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type, - * int * connectivity) const; - * (+) virtual inline int getReverseConnectivityLength - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; - * (+) virtual inline const int * getReverseConnectivity - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; - * (+) virtual inline int getReverseConnectivityIndexLength - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; - * (+) virtual inline const int * getReverseConnectivityIndex - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; - * (+) virtual int getNumberOfFamilies(MED_EN::medEntityMesh Entity) const; - * (+) virtual inline const vector<FAMILY*> getFamilies(MED_EN::medEntityMesh Entity) const; - * (+) virtual inline const FAMILY* getFamily(MED_EN::medEntityMesh Entity,int i) const; - * (+) virtual int getNumberOfGroups(MED_EN::medEntityMesh Entity) const; - * (+) virtual inline const vector<GROUP*> getGroups(MED_EN::medEntityMesh Entity) const; - * (+) virtual inline const GROUP* getGroup(MED_EN::medEntityMesh Entity,int i) const; - * (+) virtual inline const CONNECTIVITY* getConnectivityptr() const; - * (+) virtual SUPPORT * getBoundaryElements(MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); - * (+) SUPPORT * getSkin(const SUPPORT * Support3D) throw (MEDEXCEPTION); - * (+) virtual FIELD<double>* getVolume (const SUPPORT * Support) const throw (MEDEXCEPTION); - * (+) virtual FIELD<double>* getArea (const SUPPORT * Support) const throw (MEDEXCEPTION); - * (+) virtual FIELD<double>* getLength (const SUPPORT * Support) const throw (MEDEXCEPTION); - * (+) virtual FIELD<double>* getNormal (const SUPPORT * Support) const throw (MEDEXCEPTION); - * (+) virtual FIELD<double>* getBarycenter (const SUPPORT * Support) const throw (MEDEXCEPTION); - * (+) static SUPPORT * mergeSupports(const vector<SUPPORT *> Supports) throw (MEDEXCEPTION); - * (+) static SUPPORT * intersectSupports(const vector<SUPPORT *> Supports) throw (MEDEXCEPTION); - * (+) void createFamilies(); - * (+) SUPPORT *buildSupportOnNodeFromElementList - * (const list<int>& listOfElt, MED_EN::medEntityMesh entity) const throw (MEDEXCEPTION); - * (do the same thing as buildSupportOnNodeFromElementList except that a SUPPORT is not created) void fillSupportOnNodeFromElementList - * (const list<int>& listOfElt, SUPPORT *supportToFill) const throw (MEDEXCEPTION); - * (+) SUPPORT *buildSupportOnElementsFromElementList - * (const list<int>& listOfElt, MED_EN::medEntityMesh entity) const throw (MEDEXCEPTION); - * (+) int getElementContainingPoint(const double *coord); - * (+) vector< vector<double> > getBoundingBox() const; - * (+) template<class T> static - * FIELD<T> * mergeFields(const vector< FIELD<T> * > & others, bool meshCompare=false); - * (Presently disconnected in C++) virtual void addReference() const; - * (Presently disconnected in C++) virtual void removeReference() const; - * } - */ -void MEDMEMTest::testMeshAndMeshing() -{ - string datadir = getenv("DATA_DIR"); - string filename = datadir + "/MedFiles/pointe.med"; - string meshname = "maa1"; - string tmp_dir = getenv("TMP"); - if (tmp_dir == "") - tmp_dir = "/tmp"; - string filenameout21 = tmp_dir + "/myMeshWrite4_pointe21.med"; - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filenameout21); - - //////////// - // TEST 1 // - //////////// - - MESH * myMesh= new MESH(); - myMesh->setName("FIRST_MESH"); - CPPUNIT_ASSERT(myMesh != NULL); - - //test operator << - //#ifdef ENABLE_FAULTS - //CPPUNIT_ASSERT_NO_THROW(cout << *myMesh << endl); - //#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("ERROR: operator << : if mesh is empty then attempt" - " to get values from null object causes error"); -#endif - - //test operator = - MESH myMesh1 = *myMesh; - - //deepCompare -#ifdef ENABLE_FAULTS - bool isEqual = false; - CPPUNIT_ASSERT_NO_THROW(isEqual = myMesh1.deepCompare(*myMesh)); - CPPUNIT_ASSERT(isEqual); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("ERROR: deepCompare(...) fails if mesh is empty"); -#endif - - //ensure it imposible to compare meshes - MESH *myMeshPointer = myMesh; - //test operator == - CPPUNIT_ASSERT(*myMeshPointer == *myMesh); - - delete myMesh; - - //set a MESH object - MESHING myMeshing; - myMeshing.setName("meshing"); - // define coordinates - - int SpaceDimension = 3; - int NumberOfNodes = 19; - double Coordinates[57] = { - 0.0, 0.0, 0.0, - 0.0, 0.0, 1.0, - 2.0, 0.0, 1.0, - 0.0, 2.0, 1.0, - -2.0, 0.0, 1.0, - 0.0, -2.0, 1.0, - 1.0, 1.0, 2.0, - -1.0, 1.0, 2.0, - -1.0, -1.0, 2.0, - 1.0, -1.0, 2.0, - 1.0, 1.0, 3.0, - -1.0, 1.0, 3.0, - -1.0, -1.0, 3.0, - 1.0, -1.0, 3.0, - 1.0, 1.0, 4.0, - -1.0, 1.0, 4.0, - -1.0, -1.0, 4.0, - 1.0, -1.0, 4.0, - 0.0, 0.0, 5.0 - }; - try - { - myMeshing.setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,"CARTESIAN",MED_FULL_INTERLACE); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - string Names[3] = { "X","Y","Z" }; - try - { - myMeshing.setCoordinatesNames(Names); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - string Units[3] = { "cm","cm","cm" }; - try - { - myMeshing.setCoordinatesUnits(Units); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - // define conectivities - - // cell part - - const int NumberOfTypes = 3; - medGeometryElement Types[NumberOfTypes] = {MED_TETRA4,MED_PYRA5,MED_HEXA8}; - const int NumberOfElements[NumberOfTypes] = {12,2,2}; - - CPPUNIT_ASSERT_NO_THROW(myMeshing.setNumberOfTypes(NumberOfTypes,MED_CELL)); - - CPPUNIT_ASSERT_NO_THROW(myMeshing.setTypes(Types,MED_CELL)); - - CPPUNIT_ASSERT_NO_THROW(myMeshing.setNumberOfElements(NumberOfElements,MED_CELL)); - - const int sizeTetra = 12*4; - int ConnectivityTetra[sizeTetra]= - { - 1,2,3,6, - 1,2,4,3, - 1,2,5,4, - 1,2,6,5, - 2,7,4,3, - 2,8,5,4, - 2,9,6,5, - 2,10,3,6, - 2,7,3,10, - 2,8,4,7, - 2,9,5,8, - 2,10,6,9 - }; - - CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityTetra,MED_CELL,MED_TETRA4)); - - int ConnectivityPyra[2*5]= - { - 7,8,9,10,2, - 15,18,17,16,19 - }; - - CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityPyra,MED_CELL,MED_PYRA5)); - - int ConnectivityHexa[2*8]= - { - 11,12,13,14,7,8,9,10, - 15,16,17,18,11,12,13,14 - }; - - CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityHexa,MED_CELL,MED_HEXA8)); - - // face part - const int NumberOfFacesTypes = 2; - medGeometryElement FacesTypes[NumberOfFacesTypes] = {MED_TRIA3,MED_QUAD4}; - const int NumberOfFacesElements[NumberOfFacesTypes] = {4,4}; - - CPPUNIT_ASSERT_NO_THROW(myMeshing.setNumberOfTypes(NumberOfFacesTypes,MED_FACE)); - CPPUNIT_ASSERT_NO_THROW(myMeshing.setTypes(FacesTypes,MED_FACE)); - CPPUNIT_ASSERT_NO_THROW(myMeshing.setNumberOfElements(NumberOfFacesElements,MED_FACE)); - const int nbTria = 4; - const int sizeTria = nbTria*3; - int ConnectivityTria[sizeTria]= - { - 1,4,3, - 1,5,4, - 1,6,5, - 1,3,6 - }; - - CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityTria,MED_FACE,MED_TRIA3)); - const int nbQua = 4; - int ConnectivityQua[nbQua*4]= - { - 7,8,9,10, - 11,12,13,14, - 11,7,8,12, - 12,8,9,13 - }; - - CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityQua,MED_FACE,MED_QUAD4)); - - int meshDimension = SpaceDimension; // because there 3D cells in the mesh - try - { - myMeshing.setMeshDimension(meshDimension); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - // edge part - - // not yet implemented : if set, results are unpredictable. - - // Some groups : - - // Node : - { - GROUP myGroup; - myGroup.setName("SomeNodes"); - myGroup.setMesh(&myMeshing); - myGroup.setEntity(MED_NODE); - myGroup.setNumberOfGeometricType(1); - medGeometryElement myTypes[1] = {MED_NONE}; - myGroup.setGeometricType(myTypes); - const int myNumberOfElements[1] = {4}; - myGroup.setNumberOfElements(myNumberOfElements); - const int index[1+1] = {1,5}; - const int value[4]= { 1,4,5,7}; - myGroup.setNumber(index,value); - CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); - } - { - GROUP myGroup; - myGroup.setName("OtherNodes"); - myGroup.setMesh(&myMeshing); - myGroup.setEntity(MED_NODE); - myGroup.setNumberOfGeometricType(1); - medGeometryElement myTypes[1] = {MED_NONE}; - myGroup.setGeometricType(myTypes); - const int myNumberOfElements[1] = {3}; - myGroup.setNumberOfElements(myNumberOfElements); - const int index[1+1] = {1,4}; - const int value[3]= { 2,3,6}; - myGroup.setNumber(index,value); - CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); - } - - // Cell : - { - GROUP myGroup; - myGroup.setName("SomeCells"); - myGroup.setMesh(&myMeshing); - myGroup.setEntity(MED_CELL); - myGroup.setNumberOfGeometricType(3); - medGeometryElement myTypes[3] = {MED_TETRA4,MED_PYRA5,MED_HEXA8}; - myGroup.setGeometricType(myTypes); - const int myNumberOfElements[3] = {4,1,2}; - myGroup.setNumberOfElements(myNumberOfElements); - const int index[3+1] = {1,5,6,8}; - const int value[4+1+2]= - { - 2,7,8,12, - 13, - 15,16 - }; - myGroup.setNumber(index,value); - CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); - } - { - GROUP myGroup; - myGroup.setName("OtherCells"); - myGroup.setMesh(&myMeshing); - myGroup.setEntity(MED_CELL); - myGroup.setNumberOfGeometricType(2); - medGeometryElement myTypes[] = {MED_TETRA4,MED_PYRA5}; - myGroup.setGeometricType(myTypes); - const int myNumberOfElements[] = {4,1}; - myGroup.setNumberOfElements(myNumberOfElements); - const int index[2+1] = {1,5,6}; - const int value[4+1]= - { - 3,4,5,9, - 14 - }; - myGroup.setNumber(index,value); - CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); - } - - // Face : - { - GROUP myGroup; - myGroup.setName("SomeFaces"); - myGroup.setMesh(&myMeshing); - myGroup.setEntity(MED_FACE); - myGroup.setNumberOfGeometricType(2); - medGeometryElement myTypes[2] = {MED_TRIA3,MED_QUAD4}; - myGroup.setGeometricType(myTypes); - const int myNumberOfElements[2] = {2,3}; - myGroup.setNumberOfElements(myNumberOfElements); - const int index[2+1] = {1,3,6}; - const int value[2+3]= - { - 2,4, - 5,6,8 - }; - myGroup.setNumber(index,value); - CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); - } - { - GROUP myGroup; - myGroup.setName("OtherFaces"); - myGroup.setMesh(&myMeshing); - myGroup.setEntity(MED_FACE); - myGroup.setNumberOfGeometricType(1); - medGeometryElement myTypes[1] = {MED_TRIA3}; - myGroup.setGeometricType(myTypes); - const int myNumberOfElements[1] = {2}; - myGroup.setNumberOfElements(myNumberOfElements); - const int index[1+1] = {1,3}; - const int value[2]= - { - 1,3 - }; - myGroup.setNumber(index,value); - CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); - } - - //test Mesh(MESH &m) - { - MESH * myMesh2 = new MESH( myMeshing ); - CPPUNIT_ASSERT(myMesh2->deepCompare(myMeshing)); - - cout<<*myMesh2<<endl; - ostringstream os; - os << * myMesh2; - CPPUNIT_ASSERT(os.str() != ""); - - CPPUNIT_ASSERT_EQUAL(myMesh2->getName(),(string)"meshing"); - CPPUNIT_ASSERT((myMesh2->getDescription()).size() == 0); - myMesh2->setDescription("This class contains all information related to a 'meshing' mesh "); - CPPUNIT_ASSERT((myMesh2->getDescription()).size() != 0); - - CPPUNIT_ASSERT(myMesh2->getSpaceDimension() == SpaceDimension); - CPPUNIT_ASSERT(myMesh2->getMeshDimension() == meshDimension); - CPPUNIT_ASSERT(myMesh2->getNumberOfNodes() == NumberOfNodes); - - const COORDINATE* coord = myMesh2->getCoordinateptr(); - try - { - CPPUNIT_ASSERT(myMesh2->getCoordinatesSystem() != "catresian"); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - const string * units; - try - { - units = myMesh2->getCoordinatesUnits(); - for (int axe = 0; axe < SpaceDimension; axe++) { - string verif = coord->getCoordinateUnit(axe+1); - CPPUNIT_ASSERT(verif == units[axe]); - } - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - const string * noms; - try - { - noms = myMesh2->getCoordinatesNames(); - for (int axe = 0; axe < SpaceDimension; axe++) { - string verif = coord->getCoordinateName(axe+1); - CPPUNIT_ASSERT(verif == noms[axe]); - } - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - const double * coor2 = myMesh2->getCoordinates(MED_FULL_INTERLACE); - - for (int axe = 0; axe < SpaceDimension; axe++) { - try - { - for (int num = 0; num < NumberOfNodes; num++) { - try - { - const double d = myMesh2->getCoordinate(num + 1, axe + 1); - CPPUNIT_ASSERT(fabs(d - coor2[(num * SpaceDimension)+axe]) < 0.001); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - } - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - } - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - const CONNECTIVITY * myConnectivity = myMesh2->getConnectivityptr(); - - // MED_EN::MED_CELL - MED_EN::medEntityMesh entity = myConnectivity->getEntity(); - CPPUNIT_ASSERT_EQUAL(MED_CELL, entity); - - int typesNb; - CPPUNIT_ASSERT_NO_THROW(typesNb= myConnectivity->getNumberOfTypes(entity)); - CPPUNIT_ASSERT_EQUAL(NumberOfTypes, typesNb); - - const MED_EN::medGeometryElement * Types1; - CPPUNIT_ASSERT_NO_THROW(Types1 = myMesh2->getTypes(entity)); - - medConnectivity myMedConnect; - bool existConnect = false; - if (myMesh2->existConnectivity(MED_NODAL, entity)) - { - existConnect = true; - myMedConnect = MED_NODAL; - } - else if(myMesh2->existConnectivity(MED_DESCENDING, entity)) - { - existConnect = true; - myMedConnect = MED_DESCENDING; - } - - for(int t = 0; t < NumberOfTypes; t++ ) - { - CPPUNIT_ASSERT_EQUAL(Types1[t], Types[t]); - int NumberOfElements1 = 0; - CPPUNIT_ASSERT_NO_THROW(NumberOfElements1 = myMesh2->getNumberOfElements(entity, Types1[t])); - CPPUNIT_ASSERT_EQUAL(NumberOfElements1, NumberOfElements[t]); - if(existConnect) - { - const int * connectivity; - const int * connectivity_index; - CPPUNIT_ASSERT_NO_THROW(connectivity = myMesh2->getConnectivity - (MED_FULL_INTERLACE, myMedConnect, entity, Types1[t])); - connectivity_index = myMesh2->getConnectivityIndex(myMedConnect, entity); - for (int j = 0; j < NumberOfElements1; j++) { - cout<<"!!!!!!!!!!!!!!!"<<endl; - for (int k = connectivity_index[j]; k < connectivity_index[j+1]; k++) - cout << connectivity[k-1] << " "; - cout << endl; - } - } - } - - const CELLMODEL* myCellModel = myMesh2->getCellsTypes(entity); - string* TypeNames; - CPPUNIT_ASSERT_NO_THROW(TypeNames = myMesh2->getCellTypeNames(entity)); - - for(int k = 0; k < NumberOfTypes; k++ ) - { - CPPUNIT_ASSERT_EQUAL(TypeNames[k], myCellModel[k].getName()); - } - delete [] TypeNames; - - const int* myGlobalNbIdx; - CPPUNIT_ASSERT_NO_THROW(myGlobalNbIdx = myMesh2->getGlobalNumberingIndex(MED_FACE)); - for(int i = 0; i <= NumberOfFacesTypes; i++) - { - if(i == NumberOfFacesTypes) - { - CPPUNIT_ASSERT_EQUAL(myGlobalNbIdx[i],nbTria+nbQua+1); - CPPUNIT_ASSERT_THROW(myMesh2->getElementType(MED_FACE, myGlobalNbIdx[i]), MEDEXCEPTION); - break; - } - cout<<"Global number of first element of each geom type : "<<myGlobalNbIdx[i]<<endl; - } - - { - const int * ReverseNodalConnectivity; - - // Show Reverse Nodal Connectivity -#ifndef ENABLE_FAULTS - // (BUG) CONNECTIVITY::_numberOfNodes is not set - ((CONNECTIVITY*)myConnectivity)->setNumberOfNodes(NumberOfNodes); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("ERROR in CONNECTIVITY::calculateReverseNodalConnectivity()" - " because myMesh2->_connectivity->_numberOfNodes is not set"); -#endif - - CPPUNIT_ASSERT_NO_THROW(ReverseNodalConnectivity = myMesh2->getReverseConnectivity(MED_NODAL, entity)); - CPPUNIT_ASSERT_NO_THROW(myMesh2->getReverseConnectivityLength(MED_NODAL, entity)); - const int * ReverseNodalConnectivityIndex = myMesh2->getReverseConnectivityIndex(MED_NODAL, entity); - const int ReverseIdxLength = myMesh2->getReverseConnectivityIndexLength(MED_NODAL, entity); - CPPUNIT_ASSERT(ReverseIdxLength == NumberOfNodes+1); - for (int i = 0; i < NumberOfNodes; i++) { - cout << "Node "<< i+1 << " : "; - for (int j = ReverseNodalConnectivityIndex[i]; j < ReverseNodalConnectivityIndex[i+1]; j++) - cout << ReverseNodalConnectivity[j-1] << " "; - cout << endl; - } - - // Show Descending Connectivity - int NumberOfElements1; - const int * connectivity; - const int * connectivity_index; - myMesh2->calculateConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, entity); - try { - NumberOfElements1 = myMesh2->getNumberOfElements(entity, MED_ALL_ELEMENTS); - connectivity = myMesh2->getConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, entity, MED_ALL_ELEMENTS); - connectivity_index = myMesh2->getConnectivityIndex(MED_DESCENDING, entity); - } - catch (MEDEXCEPTION m) { - CPPUNIT_FAIL(m.what()); - } - - for (int j = 0; j < NumberOfElements1; j++) { - cout << "Element " << j+1 << " : "; - for (int k = connectivity_index[j]; k < connectivity_index[j+1]; k++) - cout << connectivity[k-1] << " "; - cout << endl; - } - - // getElementNumber - if (myMesh2->existConnectivity(MED_NODAL, MED_FACE)) { - int myTr[3] = {1,5,4}; - CPPUNIT_ASSERT_NO_THROW(myMesh2->getElementNumber(MED_NODAL,MED_FACE,MED_TRIA3,myTr)); - } - } - - //test family and group - int NumberOfGroups; - CPPUNIT_ASSERT_THROW(myMesh2->getNumberOfGroups(MED_ALL_ENTITIES), MEDEXCEPTION); - CPPUNIT_ASSERT_NO_THROW(NumberOfGroups = myMesh2->getNumberOfGroups(MED_CELL)); - CPPUNIT_ASSERT_EQUAL(NumberOfGroups, 2); - vector<GROUP*> groups; - CPPUNIT_ASSERT_NO_THROW(groups = myMesh2->getGroups(MED_CELL)); - CPPUNIT_ASSERT(groups.size() != 0); - for(int nb = 1; nb <= NumberOfGroups; nb++ ) - { - const GROUP* group; - CPPUNIT_ASSERT_NO_THROW(group = myMesh2->getGroup(MED_CELL, nb)); - CPPUNIT_ASSERT_EQUAL(group->getName(), groups[nb-1]->getName()); - } - - int NumberOfFamilies; - CPPUNIT_ASSERT_NO_THROW(NumberOfFamilies = myMesh2->getNumberOfFamilies(MED_CELL)); - CPPUNIT_ASSERT_MESSAGE("Current mesh hasn't Families", NumberOfFamilies == 0); - - //create families - it's not possible to create, becase not all entities are defined - CPPUNIT_ASSERT_THROW( myMesh2->createFamilies(),MEDEXCEPTION); - - /*CPPUNIT_ASSERT_NO_THROW(NumberOfFamilies = myMesh2->getNumberOfFamilies(MED_CELL)); - CPPUNIT_ASSERT( NumberOfFamilies != 0);*/ - - delete myMesh2; - } - - ////////////////////////////////////////////////////////////// - // TEST 2: Polygon and Polyhedron(only NODAL connectivity) // - ///////////////////////////////////////////////////////////// - - double CoordinatesPoly[57] = { - 2.0, 3.0, 2.0, - 3.0, 2.0, 2.0, - 4.0, 1.0, 2.0, - 2.0, 0.0, 2.0, - 0.0, 1.0, 2.0, - 1.0, 2.0, 2.0, - 2.0, 3.0, 1.0, - 3.0, 2.0, 0.0, - 4.0, 1.0, 0.0, - 2.0, 0.0, 0.0, - 0.0, 1.0, 0.0, - 1.0, 2.0, 0.0, - 5.0, 3.0, 2.0, - 7.0, 2.0, 2.0, - 6.0, 0.0, 2.0, - 6.0, 3.0, 0.0, - 7.0, 2.0, 0.0, - 6.0, 0.0, -1.0, - 5.0, 1.0, -3.0}; - - const int REFnodalConnOfFaces[74] = { - 1, 2, 3, 4, 5, 6, // Polyhedron 1 - 1, 7, 8, 2, - 2, 8, 9, 3, - 4, 3, 9, 10, - 5, 4, 10, 11, - 6, 5, 11, 12, - 1, 6, 12, 7, - 7, 12, 8, - 10, 9, 8, 12, 11, - - 13, 14, 15, 3, 2, // Polyhedron 2 - 13, 2, 8, 16, - 14, 13, 16, 17, - 15, 14, 17, - 15, 17, 18, - 15, 18, 9, - 3, 15, 9, - 2, 3, 9, 8, - 8, 9, 17, 16, - 9, 18, 17}; - const int NumberOfFaces = 19; - const int NumberOfPolyhedron = 2; - const int nbOfPolygons = 2; - const int REFfacesIndex[NumberOfFaces+1] = { - 1, 7, 11, 15, 19, 23, 27, 31, 34, - 39, 44, 48, 52, 55, 58, 61, 64, 68, 72, 75}; - - const int REFpolyIndex[NumberOfPolyhedron+1] = {1, 10, 20}; - - double PolygonCoordinates[27] = { - 2.0, 3.0, 12.0, - 3.0, 2.0, 12.0, - 4.0, 1.0, 12.0, - 2.0, 0.0, 12.0, - 0.0, 1.0, 12.0, - 1.0, 2.0, 12.0, - 5.0, 3.0, 12.0, - 7.0, 2.0, 12.0, - 6.0, 0.0, 12.0}; - - const int REFpolygonFaces[11] = { - 1, 2, 3, 4, 5, 6, // Polygon 1 - 7, 8, 9, 3, 2}; // Polygon 2 - - const int REFpolygonIndex[nbOfPolygons+1] = {1, 7, 12}; - - MESHING myMeshingPoly; - myMeshingPoly.setName("meshingpoly"); - - int MeshDimension = 3; - - const int NbOfTypes = 1; - medGeometryElement TypesPoly[NbOfTypes] = {MED_TETRA4}; - const int NbOfElements[NbOfTypes] = {1}; - - CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setNumberOfTypes(NbOfTypes, MED_CELL)); - - try - { - myMeshingPoly.setCoordinates(SpaceDimension, NumberOfNodes, CoordinatesPoly, - "CARTESIAN", MED_FULL_INTERLACE); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - myMeshingPoly.setSpaceDimension(SpaceDimension); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - myMeshingPoly.setMeshDimension(MeshDimension); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setTypes(TypesPoly, MED_CELL)); - CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setNumberOfElements(NbOfElements, MED_CELL)); - - string Unit ="cm"; - for(int i = 0; i < SpaceDimension; i++ ) - { - try - { - myMeshingPoly.setCoordinateName(Names[i],i); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - try - { - myMeshingPoly.setCoordinateUnit(Unit, i); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - } - - int ConnectivityTetraPoly[4*1]= - { - 17, 9, 18, 19 - }; - - CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setConnectivity(ConnectivityTetraPoly, MED_CELL, MED_TETRA4)); - - CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setPolyhedraConnectivity(REFpolyIndex, REFfacesIndex, - REFnodalConnOfFaces, NumberOfPolyhedron, MED_CELL)); - - bool PolyConn = false; - CPPUNIT_ASSERT_NO_THROW(PolyConn = myMeshingPoly.existPolyhedronConnectivity(MED_NODAL, MED_CELL)); - if(PolyConn) - { - CPPUNIT_ASSERT_EQUAL(myMeshingPoly.getNumberOfPolyhedron(),NumberOfPolyhedron); - CPPUNIT_ASSERT_EQUAL(myMeshingPoly.getNumberOfPolyhedronFaces(),NumberOfFaces); - CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.getPolyhedronConnectivityLength(MED_NODAL)); - const int * PolyConn; - const int * PolyFaceIdx; - const int * PolyIdx; - CPPUNIT_ASSERT_NO_THROW(PolyConn = myMeshingPoly.getPolyhedronConnectivity(MED_NODAL)); - CPPUNIT_ASSERT_NO_THROW(PolyFaceIdx = myMeshingPoly.getPolyhedronFacesIndex()); - CPPUNIT_ASSERT_NO_THROW(PolyIdx = myMeshingPoly.getPolyhedronIndex(MED_NODAL)); - for(int i = 0; i<NumberOfPolyhedron; i++) - { - int FaceIdxBegin = PolyIdx[i]; - int FaceIdxEnd = PolyIdx[i+1]; - for(int k = FaceIdxBegin; k < FaceIdxEnd; k++) - { - int IdxBegin = PolyFaceIdx[k-1]; - int IdxEnd = PolyFaceIdx[k]; - for(int j = IdxBegin; j < IdxEnd; j++ ) - CPPUNIT_ASSERT_EQUAL(PolyConn[j-1],REFnodalConnOfFaces[j-1]); - } - } - } - - MESHING myPolygonMeshing; - myPolygonMeshing.setName("PolygonMeshing"); - - medGeometryElement PolygonTypes[NbOfTypes] = {MED_TRIA3}; - const int PolygonNumberOfElements[NbOfTypes] = {2}; - - CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setNumberOfTypes(NbOfTypes, MED_CELL)); - - try - { - myPolygonMeshing.setCoordinates(SpaceDimension, NumberOfNodes, PolygonCoordinates, - "CARTESIAN", MED_FULL_INTERLACE); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - NumberOfNodes = 9; - SpaceDimension = 3; - MeshDimension = 2; - - myPolygonMeshing.setSpaceDimension(SpaceDimension); - CPPUNIT_ASSERT(myPolygonMeshing.getSpaceDimension() == 3); - myPolygonMeshing.setMeshDimension(MeshDimension); - CPPUNIT_ASSERT(myPolygonMeshing.getMeshDimension() == 2); - myPolygonMeshing.setNumberOfNodes(NumberOfNodes); - CPPUNIT_ASSERT(myPolygonMeshing.getNumberOfNodes() == 9); - CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setTypes(PolygonTypes, MED_CELL)); - CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setNumberOfElements(PolygonNumberOfElements, MED_CELL)); - CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setCoordinatesSystem("CARTESIAN")); - - try - { - myPolygonMeshing.setCoordinatesNames(Names); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - myPolygonMeshing.setCoordinatesUnits(Units); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - const int sizeTri = 3*2; - int ConnectivityTri[sizeTri]= - { - 1, 7, 2, 3, 9, 4 - }; - - CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setConnectivity(ConnectivityTri, MED_CELL, MED_TRIA3)); - CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setPolygonsConnectivity - (REFpolygonIndex, REFpolygonFaces, nbOfPolygons, MED_CELL)); - - bool PolygonConn = false; - CPPUNIT_ASSERT_NO_THROW(PolygonConn = myPolygonMeshing.existPolygonsConnectivity(MED_NODAL, MED_CELL)); - if(PolygonConn) - { - int Polytypes; - CPPUNIT_ASSERT_NO_THROW(Polytypes = myPolygonMeshing.getNumberOfTypesWithPoly(MED_CELL)); - CPPUNIT_ASSERT(NbOfTypes != Polytypes); - - const MED_EN::medGeometryElement * PolyTypes; - CPPUNIT_ASSERT_NO_THROW(PolyTypes = myPolygonMeshing.getTypesWithPoly(MED_CELL)); - CPPUNIT_ASSERT_EQUAL(PolyTypes[NbOfTypes],MED_POLYGON); - - for(int t = 0; t < Polytypes; t++) - { - CPPUNIT_ASSERT_NO_THROW( myPolygonMeshing.getNumberOfElementsWithPoly(MED_CELL, PolyTypes[t])); - } - - medGeometryElement geomPolyElem; - CPPUNIT_ASSERT_NO_THROW(geomPolyElem = myPolygonMeshing.getElementTypeWithPoly(MED_CELL, 1)); - CPPUNIT_ASSERT_EQUAL(geomPolyElem, MED_TRIA3); - - CPPUNIT_ASSERT_EQUAL(myPolygonMeshing.getNumberOfPolygons(),nbOfPolygons); - CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.getPolygonsConnectivityLength(MED_NODAL,MED_CELL)); - const int * PolygonConn; - const int * PolygonIdx; - CPPUNIT_ASSERT_THROW(PolygonConn = myMeshingPoly.getPolygonsConnectivity(MED_NODAL,MED_CELL),MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(PolygonIdx = myMeshingPoly.getPolygonsConnectivityIndex(MED_NODAL,MED_CELL),MEDEXCEPTION); - } - - ///////////////////////////////////////////////////// - // TEST : SUPPORT* sup = new SUPPORT(myMeshPointe) // - ///////////////////////////////////////////////////// - -#ifdef ENABLE_FAULTS - { - MESH * myMeshPointe = new MESH(); - myMeshPointe->setName(meshname); - MED_MESH_RDONLY_DRIVER myMeshDriver (filename, myMeshPointe); - myMeshDriver.setMeshName(meshname); - myMeshDriver.open(); - myMeshDriver.read(); - myMeshDriver.close(); - - SUPPORT* sup = new SUPPORT(myMeshPointe); - delete sup; - delete myMeshPointe; - } -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("ERROR: can not create SUPPORT on mesh, read from pointe.med"); -#endif - - //////////////////////////////////////////////////////// - // TEST 3: test MESH on MEDMEMTest::createTestMesh()// - /////////////////////////////////////////////////////// - - MESH* myMesh3 = MEDMEMTest_createTestMesh(); - - int MeshDim = myMesh3->getMeshDimension(); - medEntityMesh constituentEntity; - if (MeshDim==3) { - constituentEntity = MED_CELL; - } - if (MeshDim==2) { - constituentEntity = MED_FACE; - } - if (MeshDim==1) { - constituentEntity = MED_EDGE; - } - - int SpaceDim = myMesh3->getSpaceDimension(); - - // Show Reverse Nodal Connectivity - const int* ReverseNodalConnectivity; - const int* ReverseNodalConnectivityIndex; - int ReverseLength; - int ReverseIdxLength; - - CONNECTIVITY* myConnectivity3 = (CONNECTIVITY*)myMesh3->getConnectivityptr(); - myConnectivity3->setNumberOfNodes(myMesh3->getNumberOfNodes()); - - CPPUNIT_ASSERT_NO_THROW(ReverseNodalConnectivity= myMesh3->getReverseConnectivity(MED_NODAL, MED_CELL)); - CPPUNIT_ASSERT_NO_THROW(ReverseLength = myMesh3->getReverseConnectivityLength(MED_NODAL, MED_CELL)); - CPPUNIT_ASSERT_NO_THROW(ReverseNodalConnectivityIndex = myMesh3->getReverseConnectivityIndex(MED_NODAL, MED_CELL)); - CPPUNIT_ASSERT_NO_THROW(ReverseIdxLength = myMesh3->getReverseConnectivityIndexLength(MED_NODAL, MED_CELL)); - CPPUNIT_ASSERT(ReverseIdxLength == myMesh3->getNumberOfNodes()+1); - - for (int i = 0; i < myMesh3->getNumberOfNodes(); i++) { - cout << "Node "<< i+1 << " : "; - for (int j = ReverseNodalConnectivityIndex[i]; j < ReverseNodalConnectivityIndex[i+1]; j++) - cout << ReverseNodalConnectivity[j-1] << " "; - cout << endl; - } - - // Show Descending Connectivity - int NumberOfElements1; - const int * connectivity; - const int * connectivity_index; - myMesh3->calculateConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, MED_EN::MED_CELL); - try { - NumberOfElements1 = myMesh3->getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS); - connectivity = myMesh3->getConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, MED_CELL, MED_ALL_ELEMENTS); - connectivity_index = myMesh3->getConnectivityIndex(MED_DESCENDING, MED_CELL); - } - catch (MEDEXCEPTION m) { - CPPUNIT_FAIL(m.what()); - } - - for (int j = 0; j < NumberOfElements1; j++) { - cout << "Element " << j+1 << " : "; - for (int k = connectivity_index[j]; k < connectivity_index[j+1]; k++) - cout << connectivity[k-1] << " "; - cout << endl; - } - - //test 3D mesh - for(int ind = SpaceDim; ind > 1; ind-- ) - { - int NumberOfElem = myMesh3->getNumberOfElements (constituentEntity,MED_ALL_ELEMENTS); - if(NumberOfElem < 1) continue; - - SUPPORT * sup = (SUPPORT*) NULL; - sup = new SUPPORT(myMesh3,"",constituentEntity); - - if (ind == 2) - { - // test of normal(for 1d or 2d elements) - FIELD<double>* normal; - CPPUNIT_ASSERT_NO_THROW(normal = myMesh3->getNormal(sup)); - - double normal_square, norm; - double maxnorm=0.; - double minnorm=0.; - double tmp_value; - for (int i = 1; i<=NumberOfElem; i++) { - normal_square = 0.; - cout << "Normal " << i << " "; - for (int j=1; j<=SpaceDim; j++) { - tmp_value = normal->getValueIJ(i,j); - normal_square += tmp_value*tmp_value; - cout << tmp_value << " "; - } - norm = sqrt(normal_square); - maxnorm = dmax(maxnorm,norm); - minnorm = dmin(minnorm,norm); - cout << ", Norm = " << norm << endl; - } - cout << "Max Norm " << maxnorm << " Min Norm " << minnorm << endl; - delete normal; - - // test of area(for 2d elements) - FIELD<double>* area; - CPPUNIT_ASSERT_NO_THROW(area = myMesh3->getArea(sup)); - - double maxarea,minarea,areatot; - maxarea = 0.; - minarea = 0.; - areatot = 0.0; - for (int i = 1; i<=NumberOfElem;i++) - { - cout << "Area " << i << " " << area->getValueIJ(i,1) << endl; - maxarea = dmax(maxarea,area->getValueIJ(i,1)); - minarea = dmin(minarea,area->getValueIJ(i,1)); - areatot = areatot + area->getValueIJ(i,1); - } - - cout << "Max Area " << maxarea << " Min Area " << minarea << endl; - cout << "Support Area " << areatot << endl; - - delete area; - } - - // test of barycenter(for 3d and 2d elements) - FIELD<double>* barycenter; - CPPUNIT_ASSERT_NO_THROW(barycenter = myMesh3->getBarycenter(sup)); - - CPPUNIT_ASSERT_NO_THROW(NumberOfElem = myMesh3->getNumberOfElements(constituentEntity,MED_ALL_ELEMENTS)); - - for (int i = 1; i<=NumberOfElem;i++) - { - if (ind == 3) - cout << "Barycenter " << i << " " << barycenter->getValueIJ(i,1) << " " << barycenter->getValueIJ(i,2) << " " << barycenter->getValueIJ(i,3) << endl; - - if (ind == 2) - cout << "Barycenter " << i << " " << barycenter->getValueIJ(i,1) << " " << barycenter->getValueIJ(i,2) << endl; - } - delete barycenter; - - // test of volume(for 3d elements) - if (ind == 3) - { - FIELD<double>* volume; - CPPUNIT_ASSERT_NO_THROW(volume= myMesh3->getVolume(sup)); - - double maxvol,minvol,voltot; - maxvol = 0.; - minvol = 0.; - voltot = 0.0; - for (int i = 1; i<=NumberOfElem;i++) - { - cout << "Volume " << i << " " << volume->getValueIJ(i,1) << endl; - maxvol = dmax(maxvol,volume->getValueIJ(i,1)); - minvol = dmin(minvol,volume->getValueIJ(i,1)); - voltot = voltot + volume->getValueIJ(i,1); - } - - cout << "Max Volume " << maxvol << " Min Volume " << minvol << endl; - cout << "Support Volume " << voltot << endl; - - delete volume; - - // test of skin - SUPPORT *skin; - CPPUNIT_ASSERT_NO_THROW(skin = myMesh3->getSkin(sup)); - - //test mergeSupports and intersectSupports. vactor contains only 1 elements - vector<SUPPORT *> myVectSup; - myVectSup.push_back(skin); - - //method return a copy of skin object - SUPPORT *copyMergeSkin; - CPPUNIT_ASSERT_NO_THROW(copyMergeSkin = myMesh3->mergeSupports(myVectSup)); - try{ - CPPUNIT_ASSERT(copyMergeSkin->deepCompare(*skin)); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //method return a copy of skin object - SUPPORT *copyIntersectSkin; - CPPUNIT_ASSERT_NO_THROW(copyIntersectSkin = myMesh3->intersectSupports(myVectSup)); - try{ - CPPUNIT_ASSERT(copyIntersectSkin->deepCompare(*skin)); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - delete skin; - delete copyMergeSkin; - delete copyIntersectSkin; - } - - constituentEntity++; - } - - - // Testing length and normal vectors on 1d elements - { - // coordinates - int NumberOfNodes3 = 4; - - string Names3[3] = { "X","Y","Z" }; - string Units3[3] = { "cm","cm","cm" }; - - double Coordinates3[4*2] = {0.0, 0.0, // n1 - 1.0, 1.0, // n2 - 0.0, 1.0, // n3 - 1.0, 0.0}; // n4 - - const int NumberOfEdgeTypes = 1; - MED_EN::medGeometryElement EdgeTypes[NumberOfEdgeTypes] = {MED_SEG2}; - const int NumberOfEdges[NumberOfEdgeTypes] = {4}; - int ConnectivityEdge[4*2] = {1,2, 2,3, 3,4, 4,1}; - - // CREATE THE MESH - MEDMEM::MESHING* myMeshing3 = new MEDMEM::MESHING; - myMeshing3->setName("meshing3"); - myMeshing3->setCoordinates(/*SpaceDimension*/2, NumberOfNodes3, Coordinates3, - "CARTESIAN", MED_EN::MED_FULL_INTERLACE); - myMeshing3->setCoordinatesNames(Names3); - myMeshing3->setCoordinatesUnits(Units3); - - // define connectivities - // cell part - const int NumberOfTypes3 = 1; - medGeometryElement Types3[NumberOfTypes3] = {MED_QUAD4}; - const int NumberOfElements3[NumberOfTypes3] = {1}; - - myMeshing3->setNumberOfTypes(NumberOfTypes3,MED_CELL); - myMeshing3->setTypes(Types3,MED_CELL); - myMeshing3->setNumberOfElements(NumberOfElements3,MED_CELL); - - int Connectivityquad[1*4] = {1,2,3,4}; - - myMeshing3->setConnectivity(Connectivityquad,MED_CELL,MED_QUAD4); - - myMeshing3->setNumberOfTypes(NumberOfEdgeTypes, MED_EDGE); - myMeshing3->setTypes(EdgeTypes, MED_EDGE); - myMeshing3->setNumberOfElements(NumberOfEdges, MED_EDGE); - - myMeshing3->setConnectivity(ConnectivityEdge, MED_EDGE, MED_SEG2); - - // mesh dimension - myMeshing3->setMeshDimension(2); - - //test 2D mesh - int NumberOfElem = myMeshing3->getNumberOfElements (MED_EDGE, MED_ALL_ELEMENTS); - - SUPPORT * sup = new SUPPORT (myMeshing3, "", MED_EDGE); - - // test of normal(for 1d or 2d elements) - FIELD<double>* normal; - CPPUNIT_ASSERT_NO_THROW(normal = myMeshing3->getNormal(sup)); - - double normal_square, norm; - double maxnorm=0.; - double minnorm=0.; - double tmp_value; - for (int i = 1; i<=NumberOfElem; i++) { - normal_square = 0.; - cout << "Normal " << i << " "; - for (int j=1; j<=/*SpaceDimension*/2; j++) { - tmp_value = normal->getValueIJ(i,j); - normal_square += tmp_value*tmp_value; - cout << tmp_value << " "; - } - norm = sqrt(normal_square); - maxnorm = dmax(maxnorm,norm); - minnorm = dmin(minnorm,norm); - cout << ", Norm = " << norm << endl; - } - cout << "Max Norm " << maxnorm << " Min Norm " << minnorm << endl; - - // test of length(for 1d elements) - FIELD<double>* length; - CPPUNIT_ASSERT_NO_THROW(length = myMeshing3->getLength(sup)); - - double length_value,maxlength,minlength; - maxlength = 0; - minlength = 0; - for (int i = 1; i<=NumberOfElem;i++) { - length_value = length->getValueIJ(i,1); - cout << "Length " << i << " " << length_value << endl; - maxlength = dmax(maxlength,length_value); - minlength = dmin(minlength,length_value); - } - cout << "Max Length " << maxlength << " Min Length " << minlength << endl; - - vector< FIELD<double> *> myVectField1; - myVectField1.push_back(normal); - myVectField1.push_back(length); - CPPUNIT_ASSERT_NO_THROW(myMeshing3->mergeFields(myVectField1)); - - delete normal; - delete length; - delete sup; - -#ifdef ENABLE_FAULTS - { - // (BUG) Segmentation fault if vector is empty - vector<SUPPORT *> myVectSupEmpty; - CPPUNIT_ASSERT_THROW(myMesh3->mergeSupports(myVectSupEmpty), MEDEXCEPTION); - } -#endif - - // test mergeFields method: Fields have the same value type - //intersectSupports and mergeSupports methods - { - SUPPORT * sup1 = new SUPPORT (myMeshing3, "", MED_EDGE); - SUPPORT * sup2 = new SUPPORT (myMeshing3, "", MED_EDGE); - MED_EN::medGeometryElement gtEdges[1] = {MED_SEG2}; - int nbEdges1[1] = {1}; - int edges1[1] = {1}; - int nbEdges2[1] = {2}; - int edges2[2] = {2,3}; - sup1->setpartial("description 1", 1, 1, gtEdges, nbEdges1, edges1); - sup2->setpartial("description 1", 1, 2, gtEdges, nbEdges2, edges2); - - vector<SUPPORT *> myVectSup3; - myVectSup3.push_back(sup1); - myVectSup3.push_back(sup2); - //method return a MergeSup on the union of all SUPPORTs in Supports. - SUPPORT *MergeSup; - CPPUNIT_ASSERT_NO_THROW(MergeSup = myMesh3->mergeSupports(myVectSup3)); - cout << *MergeSup << endl; - delete MergeSup; - - //method return a intersection of all SUPPORTs in IntersectSup - SUPPORT *IntersectSup; - CPPUNIT_ASSERT_NO_THROW(IntersectSup = myMesh3->intersectSupports(myVectSup3)); - if (IntersectSup != NULL) cout<< *IntersectSup <<endl; - delete IntersectSup; - - FIELD<double> * length1 = myMeshing3->getLength(sup1); - FIELD<double> * length2 = myMeshing3->getLength(sup2); - - vector< FIELD<double> *> myVect12; - myVect12.push_back(length1); - myVect12.push_back(length2); - - FIELD<double> * length12; - CPPUNIT_ASSERT_NO_THROW(length12 = myMeshing3->mergeFields(myVect12)); - delete length12; - - delete sup1; - delete sup2; - delete length1; - delete length2; - } - } - - ///////////////////////////////////////////////////////// - // TEST 4: test MESH constructed from file pointe.med // - //////////////////////////////////////////////////////// - MESH * myMesh4 = new MESH(); - myMesh4->setName(meshname); - MED_MESH_RDONLY_DRIVER myMeshDriver (filename, myMesh4); - myMeshDriver.setMeshName(meshname); - - //Mesh has no driver->segmentation violation - //CPPUNIT_ASSERT_THROW(myMesh4->read(), MEDEXCEPTION); - - //Add an existing MESH driver. - int myDriver4; - CPPUNIT_ASSERT_NO_THROW(myDriver4 = myMesh4->addDriver(myMeshDriver)); - - //read all objects in the file - CPPUNIT_ASSERT_NO_THROW(myMesh4->read(myDriver4)); - - if (myMesh4->getIsAGrid()) { - GRID* myGrid = dynamic_cast<GRID*>(myMesh4); - CPPUNIT_ASSERT(myGrid); - } - - //myDriver4->DRONLY->can't write - CPPUNIT_ASSERT_THROW(myMesh4->write(myDriver4), MEDEXCEPTION); - - // add new driver - int idMeshV21; - CPPUNIT_ASSERT_NO_THROW(idMeshV21 = myMesh4->addDriver(MED_DRIVER,filenameout21)); - - //Write all the content of the MESH using driver referenced by the integer handler index. - CPPUNIT_ASSERT_NO_THROW(myMesh4->write(idMeshV21)); - - // remove driver from mesh - CPPUNIT_ASSERT_NO_THROW(myMesh4->rmDriver(myDriver4)); -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("ERROR: driver with index idMedV21 has not been removed"); -#endif - // ensure exception is raised on second attempt to remove driver - //CPPUNIT_ASSERT_THROW(myMesh4->rmDriver(myDriver4),MEDEXCEPTION); - - // Create a MESH object using a MESH driver of type MED_DRIVER associated with file fileName. - MESH* myMesh5; - CPPUNIT_ASSERT_NO_THROW(myMesh5 = new MESH(MED_DRIVER, filename, meshname)); - if(myMesh5->getIsAGrid()){ - GRID* myGrid = dynamic_cast<GRID*>(myMesh4); - CPPUNIT_ASSERT(myGrid); - } - - //ensure two meshes constracted from one file in two different ways are equal - CPPUNIT_ASSERT(myMesh5->deepCompare(*myMesh4)); - - int myDriver6; - MESH* myMesh6 = new MESH(); - try{ - myDriver6 = myMesh6->addDriver(MED_DRIVER, filename, meshname, MED_LECT); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try{ - myMesh6->read(myDriver6); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //ensure two meshes constracted from one file in two different ways are equal - CPPUNIT_ASSERT(myMesh6->deepCompare(*myMesh4)); - - //test FAMILY - int NumberOfFamilies4; - CPPUNIT_ASSERT_NO_THROW(NumberOfFamilies4 = myMesh6->getNumberOfFamilies(MED_CELL)); - CPPUNIT_ASSERT_MESSAGE("Current mesh hasn't Families", NumberOfFamilies4 != 0); - - vector<FAMILY*> families4; - CPPUNIT_ASSERT_NO_THROW(families4 = myMesh6->getFamilies(MED_CELL)); - CPPUNIT_ASSERT(families4.size() == NumberOfFamilies4); - for(int nb = 1; nb <= NumberOfFamilies4; nb++ ) - { - const FAMILY* family; - CPPUNIT_ASSERT_NO_THROW(family = myMesh6->getFamily(MED_CELL, nb)); - CPPUNIT_ASSERT_EQUAL(family->getName(), families4[nb-1]->getName()); - } - - //get support which reference all elements on the boundary of mesh. - SUPPORT*myBndSup; - CPPUNIT_ASSERT_THROW(myMesh6->getBoundaryElements(MED_CELL), MEDEXCEPTION); - //get only face in 3D. - CPPUNIT_ASSERT_NO_THROW(myBndSup = myMesh6->getBoundaryElements(MED_FACE)); - - //test buildSupportOnElementsFromElementList and buildSupportOnNodeFromElementList - const int * myConnectivityValue6; - CPPUNIT_ASSERT_NO_THROW(myConnectivityValue6 = myMesh6->getReverseConnectivity(MED_DESCENDING)); - const int * myConnectivityIndex6; - CPPUNIT_ASSERT_NO_THROW(myConnectivityIndex6 = myMesh6->getReverseConnectivityIndex(MED_DESCENDING)); - int numberOfElem6; - CPPUNIT_ASSERT_NO_THROW(numberOfElem6 = myMesh6->getNumberOfElementsWithPoly(MED_FACE,MED_ALL_ELEMENTS)); - list<int> myElementsList6; - - for (int i=0; i<numberOfElem6; i++) - if (myConnectivityValue6[myConnectivityIndex6[i]] == 0) { - myElementsList6.push_back(i+1); - } - - SUPPORT * mySupportOnNode; - SUPPORT * mySupportOnElem; - CPPUNIT_ASSERT_NO_THROW(mySupportOnElem = myMesh6->buildSupportOnElementsFromElementList(myElementsList6,MED_FACE)); - CPPUNIT_ASSERT(mySupportOnElem->deepCompare(*myBndSup)); - CPPUNIT_ASSERT_EQUAL(MED_FACE, mySupportOnElem->getEntity()); - - list<int>::const_iterator iteronelem = myElementsList6.begin(); - for (int i = 1; i <= 3; i++, iteronelem++) { - CPPUNIT_ASSERT_EQUAL(i, mySupportOnElem->getValIndFromGlobalNumber(*iteronelem)); - } - - CPPUNIT_ASSERT_NO_THROW(mySupportOnNode = myMesh6->buildSupportOnNodeFromElementList(myElementsList6,MED_FACE)); - CPPUNIT_ASSERT(mySupportOnNode->deepCompare( *(myMesh6->getBoundaryElements(MED_NODE)))); - - //sets mesh fields to initial values - try{ - myMesh6->init(); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //ensure two meshes constracted from one file in two different ways are equal - CPPUNIT_ASSERT(!myMesh6->deepCompare(*myMesh4)); - - //ensure mesh is empty - CPPUNIT_ASSERT(myMesh6->getSpaceDimension() == MED_INVALID); - CPPUNIT_ASSERT(myMesh6->getNumberOfNodes() == MED_INVALID); - CPPUNIT_ASSERT(myMesh6->getCoordinateptr() == NULL); - - delete myMesh4; - delete myMesh5; - delete myMesh6; - - MESH* myMesh7 = MEDMEMTest_createTestMesh(); - vector< vector<double> > myBndBox; - try{ - myBndBox = myMesh7->getBoundingBox(); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - cout<<"Bounding box for createTestMesh()"<<endl; - for(int i = 0; i < myBndBox.size(); i++) - { - for(int j = 0; j < myBndBox[i].size(); j++) - cout<<" "<< myBndBox[i][j]<<" "; - cout<<endl; - } - - double CoorPoint[3] = {0.0, 0.0, 1.0}; //n2 - int idxElem; - try{ - idxElem = myMesh7->getElementContainingPoint(CoorPoint); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT(idxElem != -1); - - double CoorNoPoint[3] = {5.0, 0.0, -5.0}; //there is no such point - int idxNoElem; - try{ - idxNoElem = myMesh7->getElementContainingPoint(CoorNoPoint); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT(idxNoElem == -1); - - /////////////////////////////////////////////////////// - // TEST 5: test desactivateFacesComputation() method // - // of driver: NPAL17670 // - /////////////////////////////////////////////////////// - double coords[54] = { - -0.215040, -0.107520, +0.000000, - +0.000000, -0.107520, +0.000000, - +0.000000, +0.107520, +0.000000, - -0.215040, +0.107520, +0.000000, - +0.215040, -0.107520, +0.000000, - +0.215040, +0.107520, +0.000000, - -0.215040, -0.107520, +1.500000, - -0.215040, -0.107520, +4.080623, - +0.000000, -0.107520, +1.500000, - +0.000000, -0.107520, +4.080623, - +0.000000, +0.107520, +1.500000, - +0.000000, +0.107520, +4.080623, - -0.215040, +0.107520, +1.500000, - -0.215040, +0.107520, +4.080623, - +0.215040, -0.107520, +1.500000, - +0.215040, -0.107520, +4.080623, - +0.215040, +0.107520, +1.500000, - +0.215040, +0.107520, +4.080623 - }; - - int connQuad4[] = { - 2 , 5 , 15 , 9 , - 10, 16 , 18 , 12, - 11 , 13 , 14 , 12, - 7 , 9 , 11 , 13, - 3 , 4 , 13 , 11, - 1 , 2 , 9 , 7, - 1 , 2 , 3 , 4, - 15 , 17 , 18 , 16 , - 5 , 6 , 17 , 15, - 9 , 15 , 17 , 11 , - 13 , 7 , 8 , 14, - 4 , 1 , 7 , 13, - 9 , 11 , 12 , 10, - 8 , 10 , 12 , 14, - 2 , 5 , 6 , 3, - 17 , 11, 12 , 18 , - 2 , 3 , 11 , 9, - 6 , 3 , 11 , 17, - 7 , 9 , 10 , 8, - 9 , 15 , 16 , 10 - }; - - int connHexa8[] = { - 3 , 2 , 1 , 4 , 11 , 9 , 7 , 13, - 17 , 15 , 9 , 11 , 18 , 16 , 10 , 12, - 11 , 9 , 7 , 13 , 12 , 10 , 8 , 14 , - 6 , 5 , 2 , 3 , 17 , 15 , 9 , 11 - }; - - int bottom[2] = {7,15}; - MED_EN::medGeometryElement bottomTypes[1] = {MED_EN::MED_QUAD4}; - int bottomIndex[2] = {1,3}; - int bottomNbOfElts[1] = {2}; - - MESHING* meshing = new MESHING(); - meshing->setName( "TESTMESH" ); - meshing->setSpaceDimension(3); - const int nFaces=20; - const int nNodes=18; - meshing->setNumberOfNodes(nNodes); - meshing->setCoordinates(3, nNodes, coords, "CARTESIAN", - MED_EN::MED_FULL_INTERLACE); - string coordname[3] = { "x", "y", "z" }; - meshing->setCoordinatesNames(coordname); - string coordunit[3] = { "m", "m", "m" }; - meshing->setCoordinatesUnits(coordunit); - //Cell connectivity info for classical elts - const MED_EN::medGeometryElement classicalTypesCell[1]={MED_EN::MED_HEXA8}; - const int nbOfCellElts[1]={4}; - meshing->setNumberOfTypes(1,MED_EN::MED_CELL); - meshing->setTypes(classicalTypesCell,MED_EN::MED_CELL); - meshing->setNumberOfElements(nbOfCellElts,MED_EN::MED_CELL); - meshing->setMeshDimension(3); - //Face connectivity info for classical elts - const MED_EN::medGeometryElement classicalTypesFace[1]={MED_EN::MED_QUAD4}; - const int nbOfFaceElts[1]={nFaces}; - meshing->setNumberOfTypes(1,MED_EN::MED_FACE); - meshing->setTypes(classicalTypesFace,MED_EN::MED_FACE); - meshing->setNumberOfElements(nbOfFaceElts,MED_EN::MED_FACE); - //All cell conn - meshing->setConnectivity(connHexa8,MED_EN::MED_CELL,MED_EN::MED_HEXA8); - //All face conn - meshing->setConnectivity(connQuad4,MED_EN::MED_FACE,MED_EN::MED_QUAD4); - //Adding some groups on faces - addMedFacesGroup( *meshing, 4, bottom, "BottomFaces",bottomTypes,bottomIndex,bottomNbOfElts,1) ; - //addMedFacesGroupAll( *meshing, "AllFaces"); - //writing... - int id=meshing->addDriver(MED_DRIVER,"out.med",meshing->getName()); - meshing->write(id); - // Field writing - SUPPORT *sup=new SUPPORT(meshing,"AllFaces",MED_FACE); - FIELD<double> * field = new FIELD<double>(sup, 1); - field->setName("temperature"); - field->setComponentName(1,"T"); field->setMEDComponentUnit(1,"K"); - double *tab=(double *)field->getValue(); - for(int i=0;i<nFaces;i++) - tab[i]=i*(1.22); - //field->setIterationNumber(-1); - field->setTime(12.); - id=field->addDriver(MED_DRIVER,"out.med",field->getName()); - field->write(id); - delete field; - delete meshing; - // - MED medObj(MED_DRIVER,"out.med"); - MESH *mesh=medObj.getMesh("TESTMESH"); - MED_MESH_RDONLY_DRIVER22 *drv=new MED_MESH_RDONLY_DRIVER22("out.med",mesh); - drv->desactivateFacesComputation(); - int newDrv=mesh->addDriver(*drv); - delete drv; - mesh->read(newDrv); - FIELD<double> *f=(FIELD<double> *)medObj.getField("temperature",-1,-1); - f->read(); - const int *conn=mesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_FACE,MED_ALL_ELEMENTS); - for (int j = 0; j < nFaces; j++) { - for (int k = 0; k < 4; k++) { - cout << conn[4*j+k] << " "; - CPPUNIT_ASSERT_EQUAL(conn[4*j+k], connQuad4[4*j+k]); - } - cout << endl; - } -} diff --git a/src/MEDMEM/Test/MEDMEMTest_MeshAndMeshing_fault.cxx b/src/MEDMEM/Test/MEDMEMTest_MeshAndMeshing_fault.cxx deleted file mode 100644 index c8aabee89..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_MeshAndMeshing_fault.cxx +++ /dev/null @@ -1,1694 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/Message.h> -#include <cppunit/TestAssert.h> -#include "MEDMEM_Meshing.hxx" -#include "MEDMEM_Group.hxx" -#include "MEDMEM_define.hxx" -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_Grid.hxx" - -#include <sstream> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -//#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -double dmax(double x, double y) { return (x>y)?x:y;} - -double dmin(double x, double y) { return (x>y)?y:x;} - -/*! - * Check methods (18), defined in MEDMEM_Meshing.hxx: - * class MESHING: public MESH { - * (+) MESHING(); - * (+) ~MESHING(); - * (+) void setSpaceDimension (const int SpaceDimension); - * (+) void setMeshDimension (const int MeshDimension); - * (+) void setNumberOfNodes (const int NumberOfNodes); - * (+) void setCoordinates (const int SpaceDimension, const int NumberOfNodes, - * const double * Coordinates, - * const string System, const MED_EN::medModeSwitch Mode); - * (+) void setCoordinatesSystem(const string System) throw (MEDEXCEPTION); - * (+) void setCoordinatesNames (const string * names); - * (+) void setCoordinateName (const string name, const int i); - * (+) void setCoordinatesUnits (const string * units); - * (+) void setCoordinateUnit (const string unit, const int i); - * (+) void setNumberOfTypes (const int NumberOfTypes, - * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); - * (+) void setTypes (const MED_EN::medGeometryElement * Types, - * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); - * (+) void setNumberOfElements (const int * NumberOfElements, - * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); - * (+) void setConnectivity (const int * Connectivity, const MED_EN::medEntityMesh Entity, - * const MED_EN::medGeometryElement Type) throw (MEDEXCEPTION); - * (+) void setPolygonsConnectivity (const int * ConnectivityIndex, const int * ConnectivityValue, - * int nbOfPolygons, - * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); - * (+) void setPolyhedraConnectivity (const int * PolyhedronIndex, const int * FacesIndex, - * const int * Nodes, int nbOfPolyhedra, - * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); - * (NOT YET IMPLEMENTED!!!) void setConnectivities (const int * ConnectivityIndex, - * const int * ConnectivityValue, - * const MED_EN::medConnectivity ConnectivityType, - * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); - * (+) void addGroup (const GROUP & Group) throw (MEDEXCEPTION); - * } - */ - -/*! - * Check methods (87), defined in MEDMEM_Mesh.hxx: - * class MESH : public RCBASE { - * (+) void init(); - * (+) MESH(); - * (+) MESH(MESH &m); - * (+) MESH & operator=(const MESH &m); - * (+) virtual bool operator==(const MESH& other) const; - * (+) virtual bool deepCompare(const MESH& other) const; - * (+) MESH(driverTypes driverType, const string & fileName="", - * const string & meshName="") throw (MEDEXCEPTION); - * (+) virtual ~MESH(); - * (+) friend ostream & operator<<(ostream &os, const MESH &my); - * (+) int addDriver(driverTypes driverType, - * const string & fileName="Default File Name.med", - * const string & driverName="Default Mesh Name", - * MED_EN::med_mode_acces access=MED_EN::MED_REMP); - * (+) int addDriver(GENDRIVER & driver); - * (+) void rmDriver(int index=0); - * (+) virtual void read(int index=0); - * (must be private) inline void read(const GENDRIVER & genDriver); - * (+) inline void write(int index=0, const string & driverName = ""); - * (must be private) inline void write(const GENDRIVER & genDriver); - * (+) inline void setName(string name); - * (+) inline void setDescription(string description); - * (+) inline string getName() const; - * (+) inline string getDescription() const; - * (+) inline int getSpaceDimension() const; - * (+) inline int getMeshDimension() const; - * (+) inline bool getIsAGrid(); - * (+) inline int getNumberOfNodes() const; - * (+) virtual inline const COORDINATE * getCoordinateptr() const; - * (+) inline string getCoordinatesSystem() const; - * (+) virtual inline const double * getCoordinates(MED_EN::medModeSwitch Mode) const; - * (+) virtual inline const double getCoordinate(int Number,int Axis) const; - * (+) inline const string * getCoordinatesNames() const; - * (+) inline const string * getCoordinatesUnits() const; - * (+) virtual inline int getNumberOfTypes(MED_EN::medEntityMesh Entity) const; - * (+) virtual int getNumberOfTypesWithPoly(MED_EN::medEntityMesh Entity) const; - * (+) virtual inline const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const; - * (+) virtual MED_EN::medGeometryElement * getTypesWithPoly(MED_EN::medEntityMesh Entity) const; - * (+) virtual inline const CELLMODEL * getCellsTypes(MED_EN::medEntityMesh Entity) const; - * (+) virtual inline string * getCellTypeNames(MED_EN::medEntityMesh Entity) const; - * (+) virtual const int * getGlobalNumberingIndex(MED_EN::medEntityMesh Entity) const; - * (+) virtual inline int getNumberOfElements(MED_EN::medEntityMesh Entity, - * MED_EN::medGeometryElement Type) const; - * (+) virtual int getNumberOfElementsWithPoly(MED_EN::medEntityMesh Entity, - * MED_EN::medGeometryElement Type) const; - * (+) virtual inline bool existConnectivity(MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity) const; - * (+) inline bool existPolygonsConnectivity(MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity) const; - * (+) inline bool existPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity) const; - * (+) virtual inline MED_EN::medGeometryElement getElementType - * (MED_EN::medEntityMesh Entity, int Number) const; - * (+) virtual inline MED_EN::medGeometryElement getElementTypeWithPoly - * (MED_EN::medEntityMesh Entity, int Number) const; - * (+) virtual inline void calculateConnectivity(MED_EN::medModeSwitch Mode, - * MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity) const; - * (+) virtual inline int getConnectivityLength(MED_EN::medModeSwitch Mode, - * MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity, - * MED_EN::medGeometryElement Type) const; - * (+) virtual inline const int * getConnectivity(MED_EN::medModeSwitch Mode, - * MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity, - * MED_EN::medGeometryElement Type) const; - * (+) virtual inline const int * getConnectivityIndex - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; - * (+) inline int getPolygonsConnectivityLength - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; - * (+) inline const int * getPolygonsConnectivity - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; - * (+) inline const int * getPolygonsConnectivityIndex - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; - * (+) inline int getNumberOfPolygons(MED_EN::medEntityMesh Entity=MED_EN::MED_ALL_ENTITIES) const; - * (+) inline int getPolyhedronConnectivityLength(MED_EN::medConnectivity ConnectivityType) const; - * (+) inline const int * getPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType) const; - * (+) inline const int * getPolyhedronFacesIndex() const; - * (+) inline const int * getPolyhedronIndex(MED_EN::medConnectivity ConnectivityType) const; - * (+) inline int getNumberOfPolyhedronFaces() const; - * (+) inline int getNumberOfPolyhedron() const; - * (+) virtual int getElementNumber(MED_EN::medConnectivity ConnectivityType, - * MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type, - * int * connectivity) const; - * (+) virtual inline int getReverseConnectivityLength - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; - * (+) virtual inline const int * getReverseConnectivity - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; - * (+) virtual inline int getReverseConnectivityIndexLength - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; - * (+) virtual inline const int * getReverseConnectivityIndex - * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; - * (+) virtual int getNumberOfFamilies(MED_EN::medEntityMesh Entity) const; - * (+) virtual inline const vector<FAMILY*> getFamilies(MED_EN::medEntityMesh Entity) const; - * (+) virtual inline const FAMILY* getFamily(MED_EN::medEntityMesh Entity,int i) const; - * (+) virtual int getNumberOfGroups(MED_EN::medEntityMesh Entity) const; - * (+) virtual inline const vector<GROUP*> getGroups(MED_EN::medEntityMesh Entity) const; - * (+) virtual inline const GROUP* getGroup(MED_EN::medEntityMesh Entity,int i) const; - * (+) virtual inline const CONNECTIVITY* getConnectivityptr() const; - * (+) virtual SUPPORT * getBoundaryElements(MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); - * (+) SUPPORT * getSkin(const SUPPORT * Support3D) throw (MEDEXCEPTION); - * (+) virtual FIELD<double>* getVolume (const SUPPORT * Support) const throw (MEDEXCEPTION); - * (+) virtual FIELD<double>* getArea (const SUPPORT * Support) const throw (MEDEXCEPTION); - * (+) virtual FIELD<double>* getLength (const SUPPORT * Support) const throw (MEDEXCEPTION); - * (+) virtual FIELD<double>* getNormal (const SUPPORT * Support) const throw (MEDEXCEPTION); - * (+) virtual FIELD<double>* getBarycenter (const SUPPORT * Support) const throw (MEDEXCEPTION); - * (+) static SUPPORT * mergeSupports(const vector<SUPPORT *> Supports) throw (MEDEXCEPTION); - * (+) static SUPPORT * intersectSupports(const vector<SUPPORT *> Supports) throw (MEDEXCEPTION); - * (+) void createFamilies(); - * (+) SUPPORT *buildSupportOnNodeFromElementList - * (const list<int>& listOfElt, MED_EN::medEntityMesh entity) const throw (MEDEXCEPTION); - * (do the same thing as buildSupportOnNodeFromElementList except that a SUPPORT is not created) void fillSupportOnNodeFromElementList - * (const list<int>& listOfElt, SUPPORT *supportToFill) const throw (MEDEXCEPTION); - * (+) SUPPORT *buildSupportOnElementsFromElementList - * (const list<int>& listOfElt, MED_EN::medEntityMesh entity) const throw (MEDEXCEPTION); - * (+) int getElementContainingPoint(const double *coord); - * (+) vector< vector<double> > getBoundingBox() const; - * (+) template<class T> static - * FIELD<T> * mergeFields(const vector< FIELD<T> * > & others, bool meshCompare=false); - * (Presently disconnected in C++) virtual void addReference() const; - * (Presently disconnected in C++) virtual void removeReference() const; - * } - */ -void MEDMEMTest_testMeshAndMeshing() -{ - string datadir = getenv("DATA_DIR"); - string filename = datadir + "/MedFiles/pointe.med"; - string meshname = "maa1"; - string tmp_dir = getenv("TMP"); - if (tmp_dir == "") - tmp_dir = "/tmp"; - string filenameout21 = tmp_dir + "/myMeshWrite4_pointe21.med"; - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filenameout21); - - //////////// - // TEST 1 // - //////////// - - MESH * myMesh= new MESH(); - myMesh->setName("FIRST_MESH"); - CPPUNIT_ASSERT(myMesh != NULL); - - //test operator << - //#ifdef ENABLE_FAULTS - //CPPUNIT_ASSERT_NO_THROW(cout << *myMesh << endl); - //#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("ERROR: operator << : if mesh is empty then attempt" - " to get values from null object causes error"); -#endif - - //test operator = - MESH myMesh1 = *myMesh; - - //deepCompare -#ifdef ENABLE_FAULTS - bool isEqual = false; - CPPUNIT_ASSERT_NO_THROW(isEqual = myMesh1.deepCompare(*myMesh)); - CPPUNIT_ASSERT(isEqual); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("ERROR: deepCompare(...) fails if mesh is empty"); -#endif - - //ensure it imposible to compare meshes - MESH *myMeshPointer = myMesh; - //test operator == - CPPUNIT_ASSERT(*myMeshPointer == *myMesh); - - delete myMesh; - - //set a MESH object - MESHING myMeshing; - myMeshing.setName("meshing"); - // define coordinates - - int SpaceDimension = 3; - int NumberOfNodes = 19; - double Coordinates[57] = { - 0.0, 0.0, 0.0, - 0.0, 0.0, 1.0, - 2.0, 0.0, 1.0, - 0.0, 2.0, 1.0, - -2.0, 0.0, 1.0, - 0.0, -2.0, 1.0, - 1.0, 1.0, 2.0, - -1.0, 1.0, 2.0, - -1.0, -1.0, 2.0, - 1.0, -1.0, 2.0, - 1.0, 1.0, 3.0, - -1.0, 1.0, 3.0, - -1.0, -1.0, 3.0, - 1.0, -1.0, 3.0, - 1.0, 1.0, 4.0, - -1.0, 1.0, 4.0, - -1.0, -1.0, 4.0, - 1.0, -1.0, 4.0, - 0.0, 0.0, 5.0 - }; - try - { - myMeshing.setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,"CARTESIAN",MED_FULL_INTERLACE); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - string Names[3] = { "X","Y","Z" }; - try - { - myMeshing.setCoordinatesNames(Names); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - string Units[3] = { "cm","cm","cm" }; - try - { - myMeshing.setCoordinatesUnits(Units); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - // define conectivities - - // cell part - - const int NumberOfTypes = 3; - medGeometryElement Types[NumberOfTypes] = {MED_TETRA4,MED_PYRA5,MED_HEXA8}; - const int NumberOfElements[NumberOfTypes] = {12,2,2}; - - CPPUNIT_ASSERT_NO_THROW(myMeshing.setNumberOfTypes(NumberOfTypes,MED_CELL)); - - CPPUNIT_ASSERT_NO_THROW(myMeshing.setTypes(Types,MED_CELL)); - - CPPUNIT_ASSERT_NO_THROW(myMeshing.setNumberOfElements(NumberOfElements,MED_CELL)); - - const int sizeTetra = 12*4; - int ConnectivityTetra[sizeTetra]= - { - 1,2,3,6, - 1,2,4,3, - 1,2,5,4, - 1,2,6,5, - 2,7,4,3, - 2,8,5,4, - 2,9,6,5, - 2,10,3,6, - 2,7,3,10, - 2,8,4,7, - 2,9,5,8, - 2,10,6,9 - }; - - CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityTetra,MED_CELL,MED_TETRA4)); - - int ConnectivityPyra[2*5]= - { - 7,8,9,10,2, - 15,18,17,16,19 - }; - - CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityPyra,MED_CELL,MED_PYRA5)); - - int ConnectivityHexa[2*8]= - { - 11,12,13,14,7,8,9,10, - 15,16,17,18,11,12,13,14 - }; - - CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityHexa,MED_CELL,MED_HEXA8)); - - // face part - const int NumberOfFacesTypes = 2; - medGeometryElement FacesTypes[NumberOfFacesTypes] = {MED_TRIA3,MED_QUAD4}; - const int NumberOfFacesElements[NumberOfFacesTypes] = {4,4}; - - CPPUNIT_ASSERT_NO_THROW(myMeshing.setNumberOfTypes(NumberOfFacesTypes,MED_FACE)); - CPPUNIT_ASSERT_NO_THROW(myMeshing.setTypes(FacesTypes,MED_FACE)); - CPPUNIT_ASSERT_NO_THROW(myMeshing.setNumberOfElements(NumberOfFacesElements,MED_FACE)); - const int nbTria = 4; - const int sizeTria = nbTria*3; - int ConnectivityTria[sizeTria]= - { - 1,4,3, - 1,5,4, - 1,6,5, - 1,3,6 - }; - - CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityTria,MED_FACE,MED_TRIA3)); - const int nbQua = 4; - int ConnectivityQua[nbQua*4]= - { - 7,8,9,10, - 11,12,13,14, - 11,7,8,12, - 12,8,9,13 - }; - - CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityQua,MED_FACE,MED_QUAD4)); - - int meshDimension = SpaceDimension; // because there 3D cells in the mesh - try - { - myMeshing.setMeshDimension(meshDimension); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - // edge part - - // not yet implemented : if set, results are unpredictable. - - // Some groups : - - // Node : - { - GROUP myGroup; - myGroup.setName("SomeNodes"); - myGroup.setMesh(&myMeshing); - myGroup.setEntity(MED_NODE); - myGroup.setNumberOfGeometricType(1); - medGeometryElement myTypes[1] = {MED_NONE}; - myGroup.setGeometricType(myTypes); - const int myNumberOfElements[1] = {4}; - myGroup.setNumberOfElements(myNumberOfElements); - const int index[1+1] = {1,5}; - const int value[4]= { 1,4,5,7}; - myGroup.setNumber(index,value); - CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); - } - { - GROUP myGroup; - myGroup.setName("OtherNodes"); - myGroup.setMesh(&myMeshing); - myGroup.setEntity(MED_NODE); - myGroup.setNumberOfGeometricType(1); - medGeometryElement myTypes[1] = {MED_NONE}; - myGroup.setGeometricType(myTypes); - const int myNumberOfElements[1] = {3}; - myGroup.setNumberOfElements(myNumberOfElements); - const int index[1+1] = {1,4}; - const int value[3]= { 2,3,6}; - myGroup.setNumber(index,value); - CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); - } - - // Cell : - { - GROUP myGroup; - myGroup.setName("SomeCells"); - myGroup.setMesh(&myMeshing); - myGroup.setEntity(MED_CELL); - myGroup.setNumberOfGeometricType(3); - medGeometryElement myTypes[3] = {MED_TETRA4,MED_PYRA5,MED_HEXA8}; - myGroup.setGeometricType(myTypes); - const int myNumberOfElements[3] = {4,1,2}; - myGroup.setNumberOfElements(myNumberOfElements); - const int index[3+1] = {1,5,6,8}; - const int value[4+1+2]= - { - 2,7,8,12, - 13, - 15,16 - }; - myGroup.setNumber(index,value); - CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); - } - { - GROUP myGroup; - myGroup.setName("OtherCells"); - myGroup.setMesh(&myMeshing); - myGroup.setEntity(MED_CELL); - myGroup.setNumberOfGeometricType(2); - medGeometryElement myTypes[] = {MED_TETRA4,MED_PYRA5}; - myGroup.setGeometricType(myTypes); - const int myNumberOfElements[] = {4,1}; - myGroup.setNumberOfElements(myNumberOfElements); - const int index[2+1] = {1,5,6}; - const int value[4+1]= - { - 3,4,5,9, - 14 - }; - myGroup.setNumber(index,value); - CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); - } - - // Face : - { - GROUP myGroup; - myGroup.setName("SomeFaces"); - myGroup.setMesh(&myMeshing); - myGroup.setEntity(MED_FACE); - myGroup.setNumberOfGeometricType(2); - medGeometryElement myTypes[2] = {MED_TRIA3,MED_QUAD4}; - myGroup.setGeometricType(myTypes); - const int myNumberOfElements[2] = {2,3}; - myGroup.setNumberOfElements(myNumberOfElements); - const int index[2+1] = {1,3,6}; - const int value[2+3]= - { - 2,4, - 5,6,8 - }; - myGroup.setNumber(index,value); - CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); - } - { - GROUP myGroup; - myGroup.setName("OtherFaces"); - myGroup.setMesh(&myMeshing); - myGroup.setEntity(MED_FACE); - myGroup.setNumberOfGeometricType(1); - medGeometryElement myTypes[1] = {MED_TRIA3}; - myGroup.setGeometricType(myTypes); - const int myNumberOfElements[1] = {2}; - myGroup.setNumberOfElements(myNumberOfElements); - const int index[1+1] = {1,3}; - const int value[2]= - { - 1,3 - }; - myGroup.setNumber(index,value); - CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); - } - - //test Mesh(MESH &m) - { - MESH * myMesh2 = new MESH( myMeshing ); - CPPUNIT_ASSERT(myMesh2->deepCompare(myMeshing)); - - cout<<*myMesh2<<endl; - ostringstream os; - os << * myMesh2; - CPPUNIT_ASSERT(os.str() != ""); - - CPPUNIT_ASSERT_EQUAL(myMesh2->getName(),(string)"meshing"); - CPPUNIT_ASSERT((myMesh2->getDescription()).size() == 0); - myMesh2->setDescription("This class contains all information related to a 'meshing' mesh "); - CPPUNIT_ASSERT((myMesh2->getDescription()).size() != 0); - - CPPUNIT_ASSERT(myMesh2->getSpaceDimension() == SpaceDimension); - CPPUNIT_ASSERT(myMesh2->getMeshDimension() == meshDimension); - CPPUNIT_ASSERT(myMesh2->getNumberOfNodes() == NumberOfNodes); - - const COORDINATE* coord = myMesh2->getCoordinateptr(); - try - { - CPPUNIT_ASSERT(myMesh2->getCoordinatesSystem() != "catresian"); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - const string * units; - try - { - units = myMesh2->getCoordinatesUnits(); - for (int axe = 0; axe < SpaceDimension; axe++) { - string verif = coord->getCoordinateUnit(axe+1); - CPPUNIT_ASSERT(verif == units[axe]); - } - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - const string * noms; - try - { - noms = myMesh2->getCoordinatesNames(); - for (int axe = 0; axe < SpaceDimension; axe++) { - string verif = coord->getCoordinateName(axe+1); - CPPUNIT_ASSERT(verif == noms[axe]); - } - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - const double * coor2 = myMesh2->getCoordinates(MED_FULL_INTERLACE); - - for (int axe = 0; axe < SpaceDimension; axe++) { - try - { - for (int num = 0; num < NumberOfNodes; num++) { - try - { - const double d = myMesh2->getCoordinate(num + 1, axe + 1); - CPPUNIT_ASSERT(fabs(d - coor2[(num * SpaceDimension)+axe]) < 0.001); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - } - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - } - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - const CONNECTIVITY * myConnectivity = myMesh2->getConnectivityptr(); - - // MED_EN::MED_CELL - MED_EN::medEntityMesh entity = myConnectivity->getEntity(); - CPPUNIT_ASSERT_EQUAL(MED_CELL, entity); - - int typesNb; - CPPUNIT_ASSERT_NO_THROW(typesNb= myConnectivity->getNumberOfTypes(entity)); - CPPUNIT_ASSERT_EQUAL(NumberOfTypes, typesNb); - - const MED_EN::medGeometryElement * Types1; - CPPUNIT_ASSERT_NO_THROW(Types1 = myMesh2->getTypes(entity)); - - medConnectivity myMedConnect; - bool existConnect = false; - if (myMesh2->existConnectivity(MED_NODAL, entity)) - { - existConnect = true; - myMedConnect = MED_NODAL; - } - else if(myMesh2->existConnectivity(MED_DESCENDING, entity)) - { - existConnect = true; - myMedConnect = MED_DESCENDING; - } - - for(int t = 0; t < NumberOfTypes; t++ ) - { - CPPUNIT_ASSERT_EQUAL(Types1[t], Types[t]); - int NumberOfElements1 = 0; - CPPUNIT_ASSERT_NO_THROW(NumberOfElements1 = myMesh2->getNumberOfElements(entity, Types1[t])); - CPPUNIT_ASSERT_EQUAL(NumberOfElements1, NumberOfElements[t]); - if(existConnect) - { - const int * connectivity; - const int * connectivity_index; - CPPUNIT_ASSERT_NO_THROW(connectivity = myMesh2->getConnectivity - (MED_FULL_INTERLACE, myMedConnect, entity, Types1[t])); - connectivity_index = myMesh2->getConnectivityIndex(myMedConnect, entity); - for (int j = 0; j < NumberOfElements1; j++) { - cout<<"!!!!!!!!!!!!!!!"<<endl; - for (int k = connectivity_index[j]; k < connectivity_index[j+1]; k++) - cout << connectivity[k-1] << " "; - cout << endl; - } - } - } - - const CELLMODEL* myCellModel = myMesh2->getCellsTypes(entity); - string* TypeNames; - CPPUNIT_ASSERT_NO_THROW(TypeNames = myMesh2->getCellTypeNames(entity)); - - for(int k = 0; k < NumberOfTypes; k++ ) - { - CPPUNIT_ASSERT_EQUAL(TypeNames[k], myCellModel[k].getName()); - } - delete [] TypeNames; - - const int* myGlobalNbIdx; - CPPUNIT_ASSERT_NO_THROW(myGlobalNbIdx = myMesh2->getGlobalNumberingIndex(MED_FACE)); - for(int i = 0; i <= NumberOfFacesTypes; i++) - { - if(i == NumberOfFacesTypes) - { - CPPUNIT_ASSERT_EQUAL(myGlobalNbIdx[i],nbTria+nbQua+1); - CPPUNIT_ASSERT_THROW(myMesh2->getElementType(MED_FACE, myGlobalNbIdx[i]), MEDEXCEPTION); - break; - } - cout<<"Global number of first element of each geom type : "<<myGlobalNbIdx[i]<<endl; - } - - { - const int * ReverseNodalConnectivity; - - // Show Reverse Nodal Connectivity -#ifndef ENABLE_FAULTS - // (BUG) CONNECTIVITY::_numberOfNodes is not set - ((CONNECTIVITY*)myConnectivity)->setNumberOfNodes(NumberOfNodes); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("ERROR in CONNECTIVITY::calculateReverseNodalConnectivity()" - " because myMesh2->_connectivity->_numberOfNodes is not set"); -#endif - - CPPUNIT_ASSERT_NO_THROW(ReverseNodalConnectivity = myMesh2->getReverseConnectivity(MED_NODAL, entity)); - CPPUNIT_ASSERT_NO_THROW(myMesh2->getReverseConnectivityLength(MED_NODAL, entity)); - const int * ReverseNodalConnectivityIndex = myMesh2->getReverseConnectivityIndex(MED_NODAL, entity); - const int ReverseIdxLength = myMesh2->getReverseConnectivityIndexLength(MED_NODAL, entity); - CPPUNIT_ASSERT(ReverseIdxLength == NumberOfNodes+1); - for (int i = 0; i < NumberOfNodes; i++) { - cout << "Node "<< i+1 << " : "; - for (int j = ReverseNodalConnectivityIndex[i]; j < ReverseNodalConnectivityIndex[i+1]; j++) - cout << ReverseNodalConnectivity[j-1] << " "; - cout << endl; - } - - // Show Descending Connectivity - int NumberOfElements1; - const int * connectivity; - const int * connectivity_index; - myMesh2->calculateConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, entity); - try { - NumberOfElements1 = myMesh2->getNumberOfElements(entity, MED_ALL_ELEMENTS); - connectivity = myMesh2->getConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, entity, MED_ALL_ELEMENTS); - connectivity_index = myMesh2->getConnectivityIndex(MED_DESCENDING, entity); - } - catch (MEDEXCEPTION m) { - CPPUNIT_FAIL(m.what()); - } - - for (int j = 0; j < NumberOfElements1; j++) { - cout << "Element " << j+1 << " : "; - for (int k = connectivity_index[j]; k < connectivity_index[j+1]; k++) - cout << connectivity[k-1] << " "; - cout << endl; - } - - // getElementNumber - if (myMesh2->existConnectivity(MED_NODAL, MED_FACE)) { - int myTr[3] = {1,5,4}; - CPPUNIT_ASSERT_NO_THROW(myMesh2->getElementNumber(MED_NODAL,MED_FACE,MED_TRIA3,myTr)); - } - } - - //test family and group - int NumberOfGroups; - CPPUNIT_ASSERT_THROW(myMesh2->getNumberOfGroups(MED_ALL_ENTITIES), MEDEXCEPTION); - CPPUNIT_ASSERT_NO_THROW(NumberOfGroups = myMesh2->getNumberOfGroups(MED_CELL)); - CPPUNIT_ASSERT_EQUAL(NumberOfGroups, 2); - vector<GROUP*> groups; - CPPUNIT_ASSERT_NO_THROW(groups = myMesh2->getGroups(MED_CELL)); - CPPUNIT_ASSERT(groups.size() != 0); - for(int nb = 1; nb <= NumberOfGroups; nb++ ) - { - const GROUP* group; - CPPUNIT_ASSERT_NO_THROW(group = myMesh2->getGroup(MED_CELL, nb)); - CPPUNIT_ASSERT_EQUAL(group->getName(), groups[nb-1]->getName()); - } - - int NumberOfFamilies; - CPPUNIT_ASSERT_NO_THROW(NumberOfFamilies = myMesh2->getNumberOfFamilies(MED_CELL)); - CPPUNIT_ASSERT_MESSAGE("Current mesh hasn't Families", NumberOfFamilies == 0); - - //create families - it's not possible to create, becase not all entities are defined - CPPUNIT_ASSERT_THROW( myMesh2->createFamilies(),MEDEXCEPTION); - - /*CPPUNIT_ASSERT_NO_THROW(NumberOfFamilies = myMesh2->getNumberOfFamilies(MED_CELL)); - CPPUNIT_ASSERT( NumberOfFamilies != 0);*/ - - delete myMesh2; - } - - ////////////////////////////////////////////////////////////// - // TEST 2: Polygon and Polyhedron(only NODAL connectivity) // - ///////////////////////////////////////////////////////////// - - double CoordinatesPoly[57] = { - 2.0, 3.0, 2.0, - 3.0, 2.0, 2.0, - 4.0, 1.0, 2.0, - 2.0, 0.0, 2.0, - 0.0, 1.0, 2.0, - 1.0, 2.0, 2.0, - 2.0, 3.0, 1.0, - 3.0, 2.0, 0.0, - 4.0, 1.0, 0.0, - 2.0, 0.0, 0.0, - 0.0, 1.0, 0.0, - 1.0, 2.0, 0.0, - 5.0, 3.0, 2.0, - 7.0, 2.0, 2.0, - 6.0, 0.0, 2.0, - 6.0, 3.0, 0.0, - 7.0, 2.0, 0.0, - 6.0, 0.0, -1.0, - 5.0, 1.0, -3.0}; - - const int REFnodalConnOfFaces[74] = { - 1, 2, 3, 4, 5, 6, // Polyhedron 1 - 1, 7, 8, 2, - 2, 8, 9, 3, - 4, 3, 9, 10, - 5, 4, 10, 11, - 6, 5, 11, 12, - 1, 6, 12, 7, - 7, 12, 8, - 10, 9, 8, 12, 11, - - 13, 14, 15, 3, 2, // Polyhedron 2 - 13, 2, 8, 16, - 14, 13, 16, 17, - 15, 14, 17, - 15, 17, 18, - 15, 18, 9, - 3, 15, 9, - 2, 3, 9, 8, - 8, 9, 17, 16, - 9, 18, 17}; - const int NumberOfFaces = 19; - const int NumberOfPolyhedron = 2; - const int nbOfPolygons = 2; - const int REFfacesIndex[NumberOfFaces+1] = { - 1, 7, 11, 15, 19, 23, 27, 31, 34, - 39, 44, 48, 52, 55, 58, 61, 64, 68, 72, 75}; - - const int REFpolyIndex[NumberOfPolyhedron+1] = {1, 10, 20}; - - double PolygonCoordinates[27] = { - 2.0, 3.0, 12.0, - 3.0, 2.0, 12.0, - 4.0, 1.0, 12.0, - 2.0, 0.0, 12.0, - 0.0, 1.0, 12.0, - 1.0, 2.0, 12.0, - 5.0, 3.0, 12.0, - 7.0, 2.0, 12.0, - 6.0, 0.0, 12.0}; - - const int REFpolygonFaces[11] = { - 1, 2, 3, 4, 5, 6, // Polygon 1 - 7, 8, 9, 3, 2}; // Polygon 2 - - const int REFpolygonIndex[nbOfPolygons+1] = {1, 7, 12}; - - MESHING myMeshingPoly; - myMeshingPoly.setName("meshingpoly"); - - int MeshDimension = 3; - - const int NbOfTypes = 1; - medGeometryElement TypesPoly[NbOfTypes] = {MED_TETRA4}; - const int NbOfElements[NbOfTypes] = {1}; - - CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setNumberOfTypes(NbOfTypes, MED_CELL)); - - try - { - myMeshingPoly.setCoordinates(SpaceDimension, NumberOfNodes, CoordinatesPoly, - "CARTESIAN", MED_FULL_INTERLACE); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - myMeshingPoly.setSpaceDimension(SpaceDimension); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - myMeshingPoly.setMeshDimension(MeshDimension); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setTypes(TypesPoly, MED_CELL)); - CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setNumberOfElements(NbOfElements, MED_CELL)); - - string Unit ="cm"; - for(int i = 0; i < SpaceDimension; i++ ) - { - try - { - myMeshingPoly.setCoordinateName(Names[i],i); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - try - { - myMeshingPoly.setCoordinateUnit(Unit, i); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - } - - int ConnectivityTetraPoly[4*1]= - { - 17, 9, 18, 19 - }; - - CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setConnectivity(ConnectivityTetraPoly, MED_CELL, MED_TETRA4)); - - CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setPolyhedraConnectivity(REFpolyIndex, REFfacesIndex, - REFnodalConnOfFaces, NumberOfPolyhedron, MED_CELL)); - - bool PolyConn = false; - CPPUNIT_ASSERT_NO_THROW(PolyConn = myMeshingPoly.existPolyhedronConnectivity(MED_NODAL, MED_CELL)); - if(PolyConn) - { - CPPUNIT_ASSERT_EQUAL(myMeshingPoly.getNumberOfPolyhedron(),NumberOfPolyhedron); - CPPUNIT_ASSERT_EQUAL(myMeshingPoly.getNumberOfPolyhedronFaces(),NumberOfFaces); - CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.getPolyhedronConnectivityLength(MED_NODAL)); - const int * PolyConn; - const int * PolyFaceIdx; - const int * PolyIdx; - CPPUNIT_ASSERT_NO_THROW(PolyConn = myMeshingPoly.getPolyhedronConnectivity(MED_NODAL)); - CPPUNIT_ASSERT_NO_THROW(PolyFaceIdx = myMeshingPoly.getPolyhedronFacesIndex()); - CPPUNIT_ASSERT_NO_THROW(PolyIdx = myMeshingPoly.getPolyhedronIndex(MED_NODAL)); - for(int i = 0; i<NumberOfPolyhedron; i++) - { - int FaceIdxBegin = PolyIdx[i]; - int FaceIdxEnd = PolyIdx[i+1]; - for(int k = FaceIdxBegin; k < FaceIdxEnd; k++) - { - int IdxBegin = PolyFaceIdx[k-1]; - int IdxEnd = PolyFaceIdx[k]; - for(int j = IdxBegin; j < IdxEnd; j++ ) - CPPUNIT_ASSERT_EQUAL(PolyConn[j-1],REFnodalConnOfFaces[j-1]); - } - } - } - - MESHING myPolygonMeshing; - myPolygonMeshing.setName("PolygonMeshing"); - - medGeometryElement PolygonTypes[NbOfTypes] = {MED_TRIA3}; - const int PolygonNumberOfElements[NbOfTypes] = {2}; - - CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setNumberOfTypes(NbOfTypes, MED_CELL)); - - try - { - myPolygonMeshing.setCoordinates(SpaceDimension, NumberOfNodes, PolygonCoordinates, - "CARTESIAN", MED_FULL_INTERLACE); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - NumberOfNodes = 9; - SpaceDimension = 3; - MeshDimension = 2; - - myPolygonMeshing.setSpaceDimension(SpaceDimension); - CPPUNIT_ASSERT(myPolygonMeshing.getSpaceDimension() == 3); - myPolygonMeshing.setMeshDimension(MeshDimension); - CPPUNIT_ASSERT(myPolygonMeshing.getMeshDimension() == 2); - myPolygonMeshing.setNumberOfNodes(NumberOfNodes); - CPPUNIT_ASSERT(myPolygonMeshing.getNumberOfNodes() == 9); - CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setTypes(PolygonTypes, MED_CELL)); - CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setNumberOfElements(PolygonNumberOfElements, MED_CELL)); - CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setCoordinatesSystem("CARTESIAN")); - - try - { - myPolygonMeshing.setCoordinatesNames(Names); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - myPolygonMeshing.setCoordinatesUnits(Units); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - const int sizeTri = 3*2; - int ConnectivityTri[sizeTri]= - { - 1, 7, 2, 3, 9, 4 - }; - - CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setConnectivity(ConnectivityTri, MED_CELL, MED_TRIA3)); - CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setPolygonsConnectivity - (REFpolygonIndex, REFpolygonFaces, nbOfPolygons, MED_CELL)); - - bool PolygonConn = false; - CPPUNIT_ASSERT_NO_THROW(PolygonConn = myPolygonMeshing.existPolygonsConnectivity(MED_NODAL, MED_CELL)); - if(PolygonConn) - { - int Polytypes; - CPPUNIT_ASSERT_NO_THROW(Polytypes = myPolygonMeshing.getNumberOfTypesWithPoly(MED_CELL)); - CPPUNIT_ASSERT(NbOfTypes != Polytypes); - - const MED_EN::medGeometryElement * PolyTypes; - CPPUNIT_ASSERT_NO_THROW(PolyTypes = myPolygonMeshing.getTypesWithPoly(MED_CELL)); - CPPUNIT_ASSERT_EQUAL(PolyTypes[NbOfTypes],MED_POLYGON); - - for(int t = 0; t < Polytypes; t++) - { - CPPUNIT_ASSERT_NO_THROW( myPolygonMeshing.getNumberOfElementsWithPoly(MED_CELL, PolyTypes[t])); - } - - medGeometryElement geomPolyElem; - CPPUNIT_ASSERT_NO_THROW(geomPolyElem = myPolygonMeshing.getElementTypeWithPoly(MED_CELL, 1)); - CPPUNIT_ASSERT_EQUAL(geomPolyElem, MED_TRIA3); - - CPPUNIT_ASSERT_EQUAL(myPolygonMeshing.getNumberOfPolygons(),nbOfPolygons); - CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.getPolygonsConnectivityLength(MED_NODAL,MED_CELL)); - const int * PolygonConn; - const int * PolygonIdx; - CPPUNIT_ASSERT_THROW(PolygonConn = myMeshingPoly.getPolygonsConnectivity(MED_NODAL,MED_CELL),MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(PolygonIdx = myMeshingPoly.getPolygonsConnectivityIndex(MED_NODAL,MED_CELL),MEDEXCEPTION); - } - - ///////////////////////////////////////////////////// - // TEST : SUPPORT* sup = new SUPPORT(myMeshPointe) // - ///////////////////////////////////////////////////// - -#ifdef ENABLE_FAULTS - { - MESH * myMeshPointe = new MESH(); - myMeshPointe->setName(meshname); - MED_MESH_RDONLY_DRIVER myMeshDriver (filename, myMeshPointe); - myMeshDriver.setMeshName(meshname); - myMeshDriver.open(); - myMeshDriver.read(); - myMeshDriver.close(); - - SUPPORT* sup = new SUPPORT(myMeshPointe); - delete sup; - delete myMeshPointe; - } -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("ERROR: can not create SUPPORT on mesh, read from pointe.med"); -#endif - - //////////////////////////////////////////////////////// - // TEST 3: test MESH on MEDMEMTest::createTestMesh()// - /////////////////////////////////////////////////////// - - MESH* myMesh3 = MEDMEMTest_createTestMesh(); - - int MeshDim = myMesh3->getMeshDimension(); - medEntityMesh constituentEntity; - if (MeshDim==3) { - constituentEntity = MED_CELL; - } - if (MeshDim==2) { - constituentEntity = MED_FACE; - } - if (MeshDim==1) { - constituentEntity = MED_EDGE; - } - - int SpaceDim = myMesh3->getSpaceDimension(); - - // Show Reverse Nodal Connectivity - const int* ReverseNodalConnectivity; - const int* ReverseNodalConnectivityIndex; - int ReverseLength; - int ReverseIdxLength; - - CONNECTIVITY* myConnectivity3 = (CONNECTIVITY*)myMesh3->getConnectivityptr(); - myConnectivity3->setNumberOfNodes(myMesh3->getNumberOfNodes()); - - CPPUNIT_ASSERT_NO_THROW(ReverseNodalConnectivity= myMesh3->getReverseConnectivity(MED_NODAL, MED_CELL)); - CPPUNIT_ASSERT_NO_THROW(ReverseLength = myMesh3->getReverseConnectivityLength(MED_NODAL, MED_CELL)); - CPPUNIT_ASSERT_NO_THROW(ReverseNodalConnectivityIndex = myMesh3->getReverseConnectivityIndex(MED_NODAL, MED_CELL)); - CPPUNIT_ASSERT_NO_THROW(ReverseIdxLength = myMesh3->getReverseConnectivityIndexLength(MED_NODAL, MED_CELL)); - CPPUNIT_ASSERT(ReverseIdxLength == myMesh3->getNumberOfNodes()+1); - - for (int i = 0; i < myMesh3->getNumberOfNodes(); i++) { - cout << "Node "<< i+1 << " : "; - for (int j = ReverseNodalConnectivityIndex[i]; j < ReverseNodalConnectivityIndex[i+1]; j++) - cout << ReverseNodalConnectivity[j-1] << " "; - cout << endl; - } - - // Show Descending Connectivity - int NumberOfElements1; - const int * connectivity; - const int * connectivity_index; - myMesh3->calculateConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, MED_EN::MED_CELL); - try { - NumberOfElements1 = myMesh3->getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS); - connectivity = myMesh3->getConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, MED_CELL, MED_ALL_ELEMENTS); - connectivity_index = myMesh3->getConnectivityIndex(MED_DESCENDING, MED_CELL); - } - catch (MEDEXCEPTION m) { - CPPUNIT_FAIL(m.what()); - } - - for (int j = 0; j < NumberOfElements1; j++) { - cout << "Element " << j+1 << " : "; - for (int k = connectivity_index[j]; k < connectivity_index[j+1]; k++) - cout << connectivity[k-1] << " "; - cout << endl; - } - - //test 3D mesh - for(int ind = SpaceDim; ind > 1; ind-- ) - { - int NumberOfElem = myMesh3->getNumberOfElements (constituentEntity,MED_ALL_ELEMENTS); - if(NumberOfElem < 1) continue; - - SUPPORT * sup = (SUPPORT*) NULL; - sup = new SUPPORT(myMesh3,"",constituentEntity); - - if (ind == 2) - { - // test of normal(for 1d or 2d elements) - FIELD<double>* normal; - CPPUNIT_ASSERT_NO_THROW(normal = myMesh3->getNormal(sup)); - - double normal_square, norm; - double maxnorm=0.; - double minnorm=0.; - double tmp_value; - for (int i = 1; i<=NumberOfElem; i++) { - normal_square = 0.; - cout << "Normal " << i << " "; - for (int j=1; j<=SpaceDim; j++) { - tmp_value = normal->getValueIJ(i,j); - normal_square += tmp_value*tmp_value; - cout << tmp_value << " "; - } - norm = sqrt(normal_square); - maxnorm = dmax(maxnorm,norm); - minnorm = dmin(minnorm,norm); - cout << ", Norm = " << norm << endl; - } - cout << "Max Norm " << maxnorm << " Min Norm " << minnorm << endl; - delete normal; - - // test of area(for 2d elements) - FIELD<double>* area; - CPPUNIT_ASSERT_NO_THROW(area = myMesh3->getArea(sup)); - - double maxarea,minarea,areatot; - maxarea = 0.; - minarea = 0.; - areatot = 0.0; - for (int i = 1; i<=NumberOfElem;i++) - { - cout << "Area " << i << " " << area->getValueIJ(i,1) << endl; - maxarea = dmax(maxarea,area->getValueIJ(i,1)); - minarea = dmin(minarea,area->getValueIJ(i,1)); - areatot = areatot + area->getValueIJ(i,1); - } - - cout << "Max Area " << maxarea << " Min Area " << minarea << endl; - cout << "Support Area " << areatot << endl; - - delete area; - } - - // test of barycenter(for 3d and 2d elements) - FIELD<double>* barycenter; - CPPUNIT_ASSERT_NO_THROW(barycenter = myMesh3->getBarycenter(sup)); - - CPPUNIT_ASSERT_NO_THROW(NumberOfElem = myMesh3->getNumberOfElements(constituentEntity,MED_ALL_ELEMENTS)); - - for (int i = 1; i<=NumberOfElem;i++) - { - if (ind == 3) - cout << "Barycenter " << i << " " << barycenter->getValueIJ(i,1) << " " << barycenter->getValueIJ(i,2) << " " << barycenter->getValueIJ(i,3) << endl; - - if (ind == 2) - cout << "Barycenter " << i << " " << barycenter->getValueIJ(i,1) << " " << barycenter->getValueIJ(i,2) << endl; - } - delete barycenter; - - // test of volume(for 3d elements) - if (ind == 3) - { - FIELD<double>* volume; - CPPUNIT_ASSERT_NO_THROW(volume= myMesh3->getVolume(sup)); - - double maxvol,minvol,voltot; - maxvol = 0.; - minvol = 0.; - voltot = 0.0; - for (int i = 1; i<=NumberOfElem;i++) - { - cout << "Volume " << i << " " << volume->getValueIJ(i,1) << endl; - maxvol = dmax(maxvol,volume->getValueIJ(i,1)); - minvol = dmin(minvol,volume->getValueIJ(i,1)); - voltot = voltot + volume->getValueIJ(i,1); - } - - cout << "Max Volume " << maxvol << " Min Volume " << minvol << endl; - cout << "Support Volume " << voltot << endl; - - delete volume; - - // test of skin - SUPPORT *skin; - CPPUNIT_ASSERT_NO_THROW(skin = myMesh3->getSkin(sup)); - - //test mergeSupports and intersectSupports. vactor contains only 1 elements - vector<SUPPORT *> myVectSup; - myVectSup.push_back(skin); - - //method return a copy of skin object - SUPPORT *copyMergeSkin; - CPPUNIT_ASSERT_NO_THROW(copyMergeSkin = myMesh3->mergeSupports(myVectSup)); - try{ - CPPUNIT_ASSERT(copyMergeSkin->deepCompare(*skin)); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //method return a copy of skin object - SUPPORT *copyIntersectSkin; - CPPUNIT_ASSERT_NO_THROW(copyIntersectSkin = myMesh3->intersectSupports(myVectSup)); - try{ - CPPUNIT_ASSERT(copyIntersectSkin->deepCompare(*skin)); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - delete skin; - delete copyMergeSkin; - delete copyIntersectSkin; - } - - constituentEntity++; - } - - - // Testing length and normal vectors on 1d elements - { - // coordinates - int NumberOfNodes3 = 4; - - string Names3[3] = { "X","Y","Z" }; - string Units3[3] = { "cm","cm","cm" }; - - double Coordinates3[4*2] = {0.0, 0.0, // n1 - 1.0, 1.0, // n2 - 0.0, 1.0, // n3 - 1.0, 0.0}; // n4 - - const int NumberOfEdgeTypes = 1; - MED_EN::medGeometryElement EdgeTypes[NumberOfEdgeTypes] = {MED_SEG2}; - const int NumberOfEdges[NumberOfEdgeTypes] = {4}; - int ConnectivityEdge[4*2] = {1,2, 2,3, 3,4, 4,1}; - - // CREATE THE MESH - MEDMEM::MESHING* myMeshing3 = new MEDMEM::MESHING; - myMeshing3->setName("meshing3"); - myMeshing3->setCoordinates(/*SpaceDimension*/2, NumberOfNodes3, Coordinates3, - "CARTESIAN", MED_EN::MED_FULL_INTERLACE); - myMeshing3->setCoordinatesNames(Names3); - myMeshing3->setCoordinatesUnits(Units3); - - // define connectivities - // cell part - const int NumberOfTypes3 = 1; - medGeometryElement Types3[NumberOfTypes3] = {MED_QUAD4}; - const int NumberOfElements3[NumberOfTypes3] = {1}; - - myMeshing3->setNumberOfTypes(NumberOfTypes3,MED_CELL); - myMeshing3->setTypes(Types3,MED_CELL); - myMeshing3->setNumberOfElements(NumberOfElements3,MED_CELL); - - int Connectivityquad[1*4] = {1,2,3,4}; - - myMeshing3->setConnectivity(Connectivityquad,MED_CELL,MED_QUAD4); - - myMeshing3->setNumberOfTypes(NumberOfEdgeTypes, MED_EDGE); - myMeshing3->setTypes(EdgeTypes, MED_EDGE); - myMeshing3->setNumberOfElements(NumberOfEdges, MED_EDGE); - - myMeshing3->setConnectivity(ConnectivityEdge, MED_EDGE, MED_SEG2); - - // mesh dimension - myMeshing3->setMeshDimension(2); - - //test 2D mesh - int NumberOfElem = myMeshing3->getNumberOfElements (MED_EDGE, MED_ALL_ELEMENTS); - - SUPPORT * sup = new SUPPORT (myMeshing3, "", MED_EDGE); - - // test of normal(for 1d or 2d elements) - FIELD<double>* normal; - CPPUNIT_ASSERT_NO_THROW(normal = myMeshing3->getNormal(sup)); - - double normal_square, norm; - double maxnorm=0.; - double minnorm=0.; - double tmp_value; - for (int i = 1; i<=NumberOfElem; i++) { - normal_square = 0.; - cout << "Normal " << i << " "; - for (int j=1; j<=/*SpaceDimension*/2; j++) { - tmp_value = normal->getValueIJ(i,j); - normal_square += tmp_value*tmp_value; - cout << tmp_value << " "; - } - norm = sqrt(normal_square); - maxnorm = dmax(maxnorm,norm); - minnorm = dmin(minnorm,norm); - cout << ", Norm = " << norm << endl; - } - cout << "Max Norm " << maxnorm << " Min Norm " << minnorm << endl; - - // test of length(for 1d elements) - FIELD<double>* length; - CPPUNIT_ASSERT_NO_THROW(length = myMeshing3->getLength(sup)); - - double length_value,maxlength,minlength; - maxlength = 0; - minlength = 0; - for (int i = 1; i<=NumberOfElem;i++) { - length_value = length->getValueIJ(i,1); - cout << "Length " << i << " " << length_value << endl; - maxlength = dmax(maxlength,length_value); - minlength = dmin(minlength,length_value); - } - cout << "Max Length " << maxlength << " Min Length " << minlength << endl; - - vector< FIELD<double> *> myVectField1; - myVectField1.push_back(normal); - myVectField1.push_back(length); - CPPUNIT_ASSERT_NO_THROW(myMeshing3->mergeFields(myVectField1)); - - delete normal; - delete length; - delete sup; - -#ifdef ENABLE_FAULTS - { - // (BUG) Segmentation fault if vector is empty - vector<SUPPORT *> myVectSupEmpty; - CPPUNIT_ASSERT_THROW(myMesh3->mergeSupports(myVectSupEmpty), MEDEXCEPTION); - } -#endif - - // test mergeFields method: Fields have the same value type - //intersectSupports and mergeSupports methods - { - SUPPORT * sup1 = new SUPPORT (myMeshing3, "", MED_EDGE); - SUPPORT * sup2 = new SUPPORT (myMeshing3, "", MED_EDGE); - MED_EN::medGeometryElement gtEdges[1] = {MED_SEG2}; - int nbEdges1[1] = {1}; - int edges1[1] = {1}; - int nbEdges2[1] = {2}; - int edges2[2] = {2,3}; - sup1->setpartial("description 1", 1, 1, gtEdges, nbEdges1, edges1); - sup2->setpartial("description 1", 1, 2, gtEdges, nbEdges2, edges2); - - vector<SUPPORT *> myVectSup3; - myVectSup3.push_back(sup1); - myVectSup3.push_back(sup2); - //method return a MergeSup on the union of all SUPPORTs in Supports. - SUPPORT *MergeSup; - CPPUNIT_ASSERT_NO_THROW(MergeSup = myMesh3->mergeSupports(myVectSup3)); - cout << *MergeSup << endl; - delete MergeSup; - - //method return a intersection of all SUPPORTs in IntersectSup - SUPPORT *IntersectSup; - CPPUNIT_ASSERT_NO_THROW(IntersectSup = myMesh3->intersectSupports(myVectSup3)); - if (IntersectSup != NULL) cout<< *IntersectSup <<endl; - delete IntersectSup; - - FIELD<double> * length1 = myMeshing3->getLength(sup1); - FIELD<double> * length2 = myMeshing3->getLength(sup2); - - vector< FIELD<double> *> myVect12; - myVect12.push_back(length1); - myVect12.push_back(length2); - - FIELD<double> * length12; - CPPUNIT_ASSERT_NO_THROW(length12 = myMeshing3->mergeFields(myVect12)); - delete length12; - - delete sup1; - delete sup2; - delete length1; - delete length2; - } - } - - ///////////////////////////////////////////////////////// - // TEST 4: test MESH constructed from file pointe.med // - //////////////////////////////////////////////////////// - MESH * myMesh4 = new MESH(); - myMesh4->setName(meshname); - MED_MESH_RDONLY_DRIVER myMeshDriver (filename, myMesh4); - myMeshDriver.setMeshName(meshname); - - //Mesh has no driver->segmentation violation - //CPPUNIT_ASSERT_THROW(myMesh4->read(), MEDEXCEPTION); - - //Add an existing MESH driver. - int myDriver4; - CPPUNIT_ASSERT_NO_THROW(myDriver4 = myMesh4->addDriver(myMeshDriver)); - - //read all objects in the file - CPPUNIT_ASSERT_NO_THROW(myMesh4->read(myDriver4)); - - if (myMesh4->getIsAGrid()) { - GRID* myGrid = dynamic_cast<GRID*>(myMesh4); - CPPUNIT_ASSERT(myGrid); - } - - //myDriver4->DRONLY->can't write - CPPUNIT_ASSERT_THROW(myMesh4->write(myDriver4), MEDEXCEPTION); - - // add new driver - int idMeshV21; - CPPUNIT_ASSERT_NO_THROW(idMeshV21 = myMesh4->addDriver(MED_DRIVER,filenameout21)); - - //Write all the content of the MESH using driver referenced by the integer handler index. - CPPUNIT_ASSERT_NO_THROW(myMesh4->write(idMeshV21)); - - // remove driver from mesh - CPPUNIT_ASSERT_NO_THROW(myMesh4->rmDriver(myDriver4)); -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("ERROR: driver with index idMedV21 has not been removed"); -#endif - // ensure exception is raised on second attempt to remove driver - //CPPUNIT_ASSERT_THROW(myMesh4->rmDriver(myDriver4),MEDEXCEPTION); - - // Create a MESH object using a MESH driver of type MED_DRIVER associated with file fileName. - MESH* myMesh5; - CPPUNIT_ASSERT_NO_THROW(myMesh5 = new MESH(MED_DRIVER, filename, meshname)); - if(myMesh5->getIsAGrid()){ - GRID* myGrid = dynamic_cast<GRID*>(myMesh4); - CPPUNIT_ASSERT(myGrid); - } - - //ensure two meshes constracted from one file in two different ways are equal - CPPUNIT_ASSERT(myMesh5->deepCompare(*myMesh4)); - - int myDriver6; - MESH* myMesh6 = new MESH(); - try{ - myDriver6 = myMesh6->addDriver(MED_DRIVER, filename, meshname, MED_LECT); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try{ - myMesh6->read(myDriver6); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //ensure two meshes constracted from one file in two different ways are equal - CPPUNIT_ASSERT(myMesh6->deepCompare(*myMesh4)); - - //test FAMILY - int NumberOfFamilies4; - CPPUNIT_ASSERT_NO_THROW(NumberOfFamilies4 = myMesh6->getNumberOfFamilies(MED_CELL)); - CPPUNIT_ASSERT_MESSAGE("Current mesh hasn't Families", NumberOfFamilies4 != 0); - - vector<FAMILY*> families4; - CPPUNIT_ASSERT_NO_THROW(families4 = myMesh6->getFamilies(MED_CELL)); - CPPUNIT_ASSERT(families4.size() == NumberOfFamilies4); - for(int nb = 1; nb <= NumberOfFamilies4; nb++ ) - { - const FAMILY* family; - CPPUNIT_ASSERT_NO_THROW(family = myMesh6->getFamily(MED_CELL, nb)); - CPPUNIT_ASSERT_EQUAL(family->getName(), families4[nb-1]->getName()); - } - - //get support which reference all elements on the boundary of mesh. - SUPPORT*myBndSup; - CPPUNIT_ASSERT_THROW(myMesh6->getBoundaryElements(MED_CELL), MEDEXCEPTION); - //get only face in 3D. - CPPUNIT_ASSERT_NO_THROW(myBndSup = myMesh6->getBoundaryElements(MED_FACE)); - - //test buildSupportOnElementsFromElementList and buildSupportOnNodeFromElementList - const int * myConnectivityValue6; - CPPUNIT_ASSERT_NO_THROW(myConnectivityValue6 = myMesh6->getReverseConnectivity(MED_DESCENDING)); - const int * myConnectivityIndex6; - CPPUNIT_ASSERT_NO_THROW(myConnectivityIndex6 = myMesh6->getReverseConnectivityIndex(MED_DESCENDING)); - int numberOfElem6; - CPPUNIT_ASSERT_NO_THROW(numberOfElem6 = myMesh6->getNumberOfElementsWithPoly(MED_FACE,MED_ALL_ELEMENTS)); - list<int> myElementsList6; - - for (int i=0; i<numberOfElem6; i++) - if (myConnectivityValue6[myConnectivityIndex6[i]] == 0) { - myElementsList6.push_back(i+1); - } - - SUPPORT * mySupportOnNode; - SUPPORT * mySupportOnElem; - CPPUNIT_ASSERT_NO_THROW(mySupportOnElem = myMesh6->buildSupportOnElementsFromElementList(myElementsList6,MED_FACE)); - CPPUNIT_ASSERT(mySupportOnElem->deepCompare(*myBndSup)); - CPPUNIT_ASSERT_EQUAL(MED_FACE, mySupportOnElem->getEntity()); - - list<int>::const_iterator iteronelem = myElementsList6.begin(); - for (int i = 1; i <= 3; i++, iteronelem++) { - CPPUNIT_ASSERT_EQUAL(i, mySupportOnElem->getValIndFromGlobalNumber(*iteronelem)); - } - - CPPUNIT_ASSERT_NO_THROW(mySupportOnNode = myMesh6->buildSupportOnNodeFromElementList(myElementsList6,MED_FACE)); - CPPUNIT_ASSERT(mySupportOnNode->deepCompare( *(myMesh6->getBoundaryElements(MED_NODE)))); - - //sets mesh fields to initial values - try{ - myMesh6->init(); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //ensure two meshes constracted from one file in two different ways are equal - CPPUNIT_ASSERT(!myMesh6->deepCompare(*myMesh4)); - - //ensure mesh is empty - CPPUNIT_ASSERT(myMesh6->getSpaceDimension() == MED_INVALID); - CPPUNIT_ASSERT(myMesh6->getNumberOfNodes() == MED_INVALID); - CPPUNIT_ASSERT(myMesh6->getCoordinateptr() == NULL); - - delete myMesh4; - delete myMesh5; - delete myMesh6; - - MESH* myMesh7 = MEDMEMTest_createTestMesh(); - vector< vector<double> > myBndBox; - try{ - myBndBox = myMesh7->getBoundingBox(); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - cout<<"Bounding box for createTestMesh()"<<endl; - for(int i = 0; i < myBndBox.size(); i++) - { - for(int j = 0; j < myBndBox[i].size(); j++) - cout<<" "<< myBndBox[i][j]<<" "; - cout<<endl; - } - - double CoorPoint[3] = {0.0, 0.0, 1.0}; //n2 - int idxElem; - try{ - idxElem = myMesh7->getElementContainingPoint(CoorPoint); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT(idxElem != -1); - - double CoorNoPoint[3] = {5.0, 0.0, -5.0}; //there is no such point - int idxNoElem; - try{ - idxNoElem = myMesh7->getElementContainingPoint(CoorNoPoint); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT(idxNoElem == -1); -} - -int main (int argc, char** argv) -{ - MEDMEMTest_testMeshAndMeshing(); -} diff --git a/src/MEDMEM/Test/MEDMEMTest_ModulusArray.cxx b/src/MEDMEM/Test/MEDMEMTest_ModulusArray.cxx deleted file mode 100644 index a912b9c05..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_ModulusArray.cxx +++ /dev/null @@ -1,288 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/Message.h> -#include <cppunit/TestAssert.h> - -#include "MEDMEM_ModulusArray.hxx" -#include "MEDMEM_define.hxx" - -#include <sstream> -#include <cmath> - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -/*! - * Check methods (4), defined in MEDMEM_ModulusArray.hxx: - * class MEDMODULUSARRAY { - * (+) MEDMODULUSARRAY(int length, const int * array); - * (+) MEDMODULUSARRAY(int vertexLength, int totalLength, const int * array); - * (+) ~MEDMODULUSARRAY(); - * (+) const int operator[](const int &i) const; - * (+) int compare(const MEDMODULUSARRAY &modulusArray) const; - * } - */ -void MEDMEMTest::testModulusArray() -{ - - int array[5]={0,1,2,1,4} ; - MEDMODULUSARRAY modulusArray(5,array); - - cout <<"ModulusArray"<<endl; - for(int i=-10;i<15;i++) - cout <<" - A["<<i<<"]="<<modulusArray[i]<<endl; - cout <<endl; - - // test compare - int ret ; - - int array2[5]={1,4,0,1,2} ; - MEDMODULUSARRAY modulusArray2(5,array2); - - try{ - ret=modulusArray2.compare(modulusArray); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - cout<<"!!!!!!ret"<<ret<<endl; - CPPUNIT_ASSERT_MESSAGE("Two identical arrays - KO", ret == 1); - - int array3[5]={1,2,1,0,4} ; - MEDMODULUSARRAY modulusArray3(5,array3) ; - try{ - ret=modulusArray3.compare(modulusArray); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_MESSAGE("Two arrays are in reverse order - KO",ret == -1); - - int array4[6]={1,2,1,0} ; - MEDMODULUSARRAY modulusArray4(4,array4) ; - try{ - ret=modulusArray4.compare(modulusArray); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_MESSAGE("Two arrays are have different size - KO",ret == 0); - - int array5[5]={1,2,1,0,1} ; - MEDMODULUSARRAY modulusArray5(5,array5) ; - - try{ - ret=modulusArray5.compare(modulusArray); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_MESSAGE("Two different arrays, same size - KO",ret == 0); - - // test small array : - - // 1 - int array6[1]={1} ; - MEDMODULUSARRAY modulusArray6(1,array6); - - cout <<"Test small array"<<endl; - for(int i=-10;i<15;i++) - cout <<" - A["<<i<<"]="<<modulusArray6[i]<<endl; - - - int array7[1]={1} ; - MEDMODULUSARRAY modulusArray7(1,array7); - try{ - ret=modulusArray6.compare(modulusArray7); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_MESSAGE("Two identical arrays - KO", ret == 1); - - int array8[1]={2} ; - MEDMODULUSARRAY modulusArray8(1,array8); - try{ - ret=modulusArray6.compare(modulusArray8); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_MESSAGE("Two different arrays - KO",ret == 0); - - // 2 - int array60[2]={1,2} ; - MEDMODULUSARRAY modulusArray60(2,array60); - - cout<<"ModulusArray 2 :"<<endl; - for(int i=-10;i<15;i++) - cout <<" - A["<<i<<"]="<<modulusArray60[i]<<endl; - cout <<endl; - - int array70[2]={1,2} ; - MEDMODULUSARRAY modulusArray70(2,array70); - - try{ - ret=modulusArray60.compare(modulusArray70); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_MESSAGE("Same arrays, same order - KO",ret == 1); - - int array80[2]={2,2} ; - MEDMODULUSARRAY modulusArray80(2,array80); - try{ - ret=modulusArray60.compare(modulusArray80); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_MESSAGE("Different arrays - KO",ret == 0); - - int array90[2]={2,1} ; - MEDMODULUSARRAY modulusArray90(2,array90); - - try{ - ret=modulusArray60.compare(modulusArray90); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_MESSAGE("Two arrays are in reverse order - KO",ret == -1); - - //test not vertex nodes - int array100[2]={1,2} ; - MEDMODULUSARRAY modulusArray100(2,2,array100); // == MEDMODULUSARRAY(2,array100); - - try{ - ret = modulusArray60.compare(modulusArray100); - } - catch (const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_MESSAGE("Same arrays, same order - KO", ret == 1); - - // check comparison of equal arrays, containing non-vertex nodes - - int array110[4] = {1,2,4,3}; - MEDMODULUSARRAY modulusArray110(2,4,array110); - - int array120[4] = {1,2,4,3}; - MEDMODULUSARRAY modulusArray120(2,4,array120); - - int array130[4] = {1,2,3,4}; - MEDMODULUSARRAY modulusArray130(2,4,array130); - - // same order of non-vertex nodes - CPPUNIT_ASSERT_NO_THROW(ret = modulusArray120.compare(modulusArray110)); - CPPUNIT_ASSERT_MESSAGE("Same arrays, same order - KO", ret == 1); - - // different order of non-vertex nodes - CPPUNIT_ASSERT_NO_THROW(ret = modulusArray130.compare(modulusArray110)); - CPPUNIT_ASSERT_MESSAGE("Same arrays, same order - KO", ret == 1); - - // check comparison of different arrays, containing non-vertex nodes - - // difference is in vertex nodes - int array140[4] = {1,5,4,3}; - MEDMODULUSARRAY modulusArray140 (2,4,array140); - - CPPUNIT_ASSERT_NO_THROW(ret = modulusArray120.compare(modulusArray140)); - CPPUNIT_ASSERT_MESSAGE("Different arrays - KO", ret == 0); - - // difference is in non-vertex nodes - int array150[4] = {1,2,4,5}; - MEDMODULUSARRAY modulusArray150 (2,4,array150); - - CPPUNIT_ASSERT_NO_THROW(ret = modulusArray120.compare(modulusArray150)); - CPPUNIT_ASSERT_MESSAGE("Different arrays - KO", ret == 0); - - // check that operator[] returns only vertex nodes - CPPUNIT_ASSERT_EQUAL(1, modulusArray120[0]); - CPPUNIT_ASSERT_EQUAL(2, modulusArray120[1]); - CPPUNIT_ASSERT_EQUAL(1, modulusArray120[2]); - CPPUNIT_ASSERT_EQUAL(2, modulusArray120[3]); - CPPUNIT_ASSERT_EQUAL(1, modulusArray120[4]); - CPPUNIT_ASSERT_EQUAL(2, modulusArray120[5]); -} diff --git a/src/MEDMEM/Test/MEDMEMTest_PointerOf.cxx b/src/MEDMEM/Test/MEDMEMTest_PointerOf.cxx deleted file mode 100644 index 6e5f47e0f..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_PointerOf.cxx +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include "MEDMEM_PointerOf.hxx" -#include "MEDMEM_define.hxx" - -#include <cppunit/TestAssert.h> - -#include <sstream> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; - -/*! - * Check methods (12), defined in MEDMEM_PointerOf.hxx: - * template <typename T> class PointerOf { - * (+) PointerOf(); - * (+) ~PointerOf(); - * (+) PointerOf(const int &size); - * (+) PointerOf(const T *pointer); - * (+) PointerOf(const int &size, const T *pointer); - * (+) PointerOf(const PointerOf<T> & pointerOf); - * (NOT COMPILABLE!!!) PointerOf(const int &size, const PointerOf<T> & pointerOf); - * (+) operator T*(); - * (+) operator const T*() const; - * (+) void set(const int &size); - * (+) void set(const T *pointer); - * (+) void set(const int &size, const T *pointer); - * (+) void setShallowAndOwnership(const T *pointer); - * (+) PointerOf<T>& operator=(const PointerOf<T> &pointer); - * } - * - */ -void MEDMEMTest::testPointerOf() -{ - const int size=10; - PointerOf<int> P; - - try - { - P.set(0); - CPPUNIT_ASSERT((int *)P == NULL); - } - catch ( const std::exception &e ) - { - CPPUNIT_FAIL(e.what()); - } - - try - { - P.set(-1 * size); - CPPUNIT_ASSERT((int *)P == NULL); - } - catch ( const std::exception &e ) - { - CPPUNIT_FAIL(e.what()); - } - - try - { - P.set(size); - CPPUNIT_ASSERT((int *)P != NULL); - } - catch ( const std::exception &e ) - { - CPPUNIT_FAIL(e.what()); - } - - for (int i=0; i < size; i++) - { - P[i]=i; - } - - PointerOf<int> P2(10); - - P2=P; - for (int i=0; i < size; i++) - { - SCRUTE(P2[i]); - } - - int * p=new int [size]; - for (int i=0; i < size; i++) - { - p[i]=i*10; - } - - P2.set(p); - PointerOf<int> P3(p); - - for (int i=0; i < size; i++) - { - CPPUNIT_ASSERT_EQUAL(P2[i],P3[i]); - } - - const PointerOf<int> P4(p); - for (int i=0; i < size; i++) - { - CPPUNIT_ASSERT_EQUAL(P4[i],p[i]); - } - - const PointerOf<int> P5(P4); - CPPUNIT_ASSERT((const int*)P5 != NULL); - - const PointerOf<int> P7(10, p); - - { -#ifdef ENABLE_COMPILATION_ERRORS - PointerOf<int> PP1 (10, p); - PointerOf<int> PP2 (10, PP1); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("Can not create: PointerOf(const int &size, const PointerOf<T> & pointerOf)"); -#endif - } - - CPPUNIT_ASSERT_THROW(P3.set(0, p),MEDEXCEPTION); - - P.setShallowAndOwnership( p ); - for (int i=0; i < size; i++) - { - CPPUNIT_ASSERT_EQUAL(P[i],p[i]); - } - - //delete [] p; not needed - P already owns p and will delete it when the scope is over -} diff --git a/src/MEDMEM/Test/MEDMEMTest_PolyhedronArray.cxx b/src/MEDMEM/Test/MEDMEMTest_PolyhedronArray.cxx deleted file mode 100644 index 5a1261ab5..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_PolyhedronArray.cxx +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/Message.h> -#include <cppunit/TestAssert.h> - -#include "MEDMEM_PolyhedronArray.hxx" -#include "MEDMEM_define.hxx" - -#include <sstream> -#include <cmath> - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -/*! - * Check methods (12), defined in MEDMEM_PolyhedronArray.hxx: - * class POLYHEDRONARRAY { - * (+) POLYHEDRONARRAY(); - * (+) POLYHEDRONARRAY(MED_EN::med_int numberofpolyhedron, - * MED_EN::med_int numberoffaces, MED_EN::med_int numberofnodes); - * (+) POLYHEDRONARRAY(const POLYHEDRONARRAY& m); - * - * (+) inline MED_EN::med_int getNumberOfPolyhedron() const; - * (+) inline MED_EN::med_int getNumberOfFaces() const; - * (+) inline MED_EN::med_int getNumberOfNodes() const; - * - * (+) inline const MED_EN::med_int* getPolyhedronIndex() const; - * (+) inline const MED_EN::med_int* getFacesIndex() const; - * (+) inline const MED_EN::med_int* getNodes() const; - * - * (+) inline void setPolyhedronIndex(const MED_EN::med_int* polyhedronindex); - * (+) inline void setFacesIndex(const MED_EN::med_int* facesindex); - * (+) inline void setNodes(const MED_EN::med_int* nodes); - * } - */ -void MEDMEMTest::testPolyhedronArray() -{ - const med_int nbPolyhedrons = 2; - const med_int nbFaces = 11; - const med_int nbNodes = 40; - - med_int polyhedronindex[nbPolyhedrons] = {1,7}; - med_int facesindex[nbFaces] = {1,5,9,13,17,21,25,28,31,34,37}; - med_int nodes[nbNodes] = {1,2,6,5,2,3,7,6,4,3,7,8,1,4,8,5,1,2,3,4,5,6,7,8,5,6,9,6,7,9,7,8,9,8,5,9,5,6,7,8}; - - // construction with parameters - POLYHEDRONARRAY myPArray (nbPolyhedrons, nbFaces, nbNodes); - - CPPUNIT_ASSERT_NO_THROW(myPArray.setPolyhedronIndex(polyhedronindex)); - CPPUNIT_ASSERT_NO_THROW(myPArray.setFacesIndex(facesindex)); - CPPUNIT_ASSERT_NO_THROW(myPArray.setNodes(nodes)); - - // copy constructor - POLYHEDRONARRAY myPArray2 (myPArray); - - const med_int* __polyhedronindex = myPArray2.getPolyhedronIndex(); - const med_int* __facesindex = myPArray2.getFacesIndex(); - const med_int* __nodes = myPArray2.getNodes(); - - CPPUNIT_ASSERT_EQUAL(myPArray2.getNumberOfPolyhedron(), nbPolyhedrons); - CPPUNIT_ASSERT_EQUAL(myPArray2.getNumberOfFaces(), nbFaces); - CPPUNIT_ASSERT_EQUAL(myPArray2.getNumberOfNodes(), nbNodes); - - for (int i = 0; i < nbPolyhedrons; i++) - CPPUNIT_ASSERT_EQUAL(__polyhedronindex[i], polyhedronindex[i]); - - for (int i = 0; i < nbFaces; i++) - CPPUNIT_ASSERT_EQUAL(__facesindex[i], facesindex[i]); - - for (int i = 0; i < nbNodes; i++) - CPPUNIT_ASSERT_EQUAL(__nodes[i], nodes[i]); - - // default constructor (has no sense, must be private) - POLYHEDRONARRAY myPArray3; - - CPPUNIT_ASSERT_EQUAL(0, int(myPArray3.getNumberOfPolyhedron())); - CPPUNIT_ASSERT_EQUAL(0, int(myPArray3.getNumberOfFaces())); - CPPUNIT_ASSERT_EQUAL(0, int(myPArray3.getNumberOfNodes())); - - CPPUNIT_ASSERT(myPArray3.getPolyhedronIndex() == NULL); - CPPUNIT_ASSERT(myPArray3.getFacesIndex() == NULL); - CPPUNIT_ASSERT(myPArray3.getNodes() == NULL); -} diff --git a/src/MEDMEM/Test/MEDMEMTest_PorflowMeshDriver.cxx b/src/MEDMEM/Test/MEDMEMTest_PorflowMeshDriver.cxx deleted file mode 100644 index 1174e1ef7..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_PorflowMeshDriver.cxx +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include <MEDMEM_PorflowMeshDriver.hxx> -#include <MEDMEM_Mesh.hxx> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; - -/*! - * Check methods (18), defined in MEDMEM_PorflowMeshDriver.hxx: - * class PORFLOW_MESH_DRIVER : public GENDRIVER { - * (+) PORFLOW_MESH_DRIVER(); - * (+) PORFLOW_MESH_DRIVER(const string & fileName, MESH * ptrMesh, MED_EN::med_mode_acces accessMode); - * (+) PORFLOW_MESH_DRIVER(const PORFLOW_MESH_DRIVER & driver); - * (+) virtual ~PORFLOW_MESH_DRIVER(); - * (+) void open() throw (MEDEXCEPTION); - * (+) void close() throw (MEDEXCEPTION); - * (-) virtual void write(void) const = 0; - * (+) virtual void read (void) = 0; - * (+) void setMeshName(const string & meshName); - * (+) string getMeshName() const; - * } - * class PORFLOW_MESH_RDONLY_DRIVER : public virtual PORFLOW_MESH_DRIVER { - * (+) PORFLOW_MESH_RDONLY_DRIVER(); - * (+) PORFLOW_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh); - * (+) PORFLOW_MESH_RDONLY_DRIVER(const PORFLOW_MESH_RDONLY_DRIVER & driver); - * (+) virtual ~PORFLOW_MESH_RDONLY_DRIVER(); - * (+) void write(void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * } - * class PORFLOW_MESH_WRONLY_DRIVER : public virtual PORFLOW_MESH_DRIVER { - * (+) PORFLOW_MESH_WRONLY_DRIVER(); - * (+) PORFLOW_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh); - * (+) PORFLOW_MESH_WRONLY_DRIVER(const PORFLOW_MESH_WRONLY_DRIVER & driver); - * (+) virtual ~PORFLOW_MESH_WRONLY_DRIVER(); - * (NOT IMPLEMENTED!!!) void write(void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * } - * class PORFLOW_MESH_RDWR_DRIVER : public PORFLOW_MESH_RDONLY_DRIVER, public PORFLOW_MESH_WRONLY_DRIVER { - * (+) PORFLOW_MESH_RDWR_DRIVER(); - * (+) PORFLOW_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh); - * (+) PORFLOW_MESH_RDWR_DRIVER(const PORFLOW_MESH_RDWR_DRIVER & driver); - * (+) ~PORFLOW_MESH_RDWR_DRIVER(); - * (CALLS PORFLOW_MESH_WRONLY_DRIVER::write()) void write(void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * } - */ -void MEDMEMTest::testPorflowMeshDriver() -{ - MESH *aMesh = new MESH(); - MESH *aMesh_1 = new MESH(); - - string data_dir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - - string filename_rd = data_dir + "/inp_xyz/Case1.inp"; - string filename_wr = tmp_dir + "/myWr_Case1.inp"; - string meshname = "Case1"; - string newmeshname = "new" + meshname; - string fileNotExistsName_rd = "notExists.inp"; - string fileNotExistsName_wr = "/path_not_exists/file_not_exists.inp"; - string filename_rdwr = tmp_dir + "/myRdWr_Case1.inp"; - string fcopy = "cp " + filename_rd + " " + filename_rdwr; - string fcopy1 = "cp " + data_dir + "/inp_xyz/Case1.xyz" + " " + tmp_dir + "/Case1.xyz"; - string fcopy2 = "cp " + data_dir + "/inp_xyz/Case1.cnc" + " " + tmp_dir + "/Case1.cnc"; - - //Copy files in the TMP dir for testing READ/WRITE case - system(fcopy.data()); - system(fcopy1.data()); - system(fcopy2.data()); - - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filename_wr); - aRemover.Register(filename_rdwr); - aRemover.Register(tmp_dir + "/Case1.xyz"); - aRemover.Register(tmp_dir + "/Case1.cnc"); - - //-----------------------------Test READ ONLY part---------------------------------------// - { - { - //Creation a incorrect Porflow read only driver - PORFLOW_MESH_RDONLY_DRIVER *aInvalidPorflowRdDriver = - new PORFLOW_MESH_RDONLY_DRIVER(fileNotExistsName_rd, aMesh); - - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidPorflowRdDriver->open(), MEDEXCEPTION); - - delete aInvalidPorflowRdDriver; - } - - //Creation a correct Porflow read only driver (normal constructor) - PORFLOW_MESH_RDONLY_DRIVER *aPorflowRdDriver = new PORFLOW_MESH_RDONLY_DRIVER(filename_rd, aMesh); - - //Check driver - CPPUNIT_ASSERT(aPorflowRdDriver); - - //Trying read mesh from file, if file is not open - CPPUNIT_ASSERT_THROW(aPorflowRdDriver->read(), MEDEXCEPTION); - - //Test open() method - CPPUNIT_ASSERT_NO_THROW(aPorflowRdDriver->open()); - -#ifdef ENABLE_FORCED_FAILURES - //Trying open file secondary - CPPUNIT_ASSERT_THROW(aPorflowRdDriver->open(), MEDEXCEPTION); - //This case work, but it corrypt driver -#endif - - //Test read() method - CPPUNIT_ASSERT_NO_THROW(aPorflowRdDriver->read()); - - //Check Mesh - CPPUNIT_ASSERT(aMesh); - - //Trying fill not empty mesh - CPPUNIT_ASSERT_THROW(aPorflowRdDriver->read(), MEDEXCEPTION); - - //Test write() method for Porflow RDONLY Driver - CPPUNIT_ASSERT_THROW(aPorflowRdDriver->write(), MEDEXCEPTION); - - //Test setMeshName() and getMeshName() - CPPUNIT_ASSERT_NO_THROW(aPorflowRdDriver->setMeshName(meshname)); - CPPUNIT_ASSERT_EQUAL(meshname, aPorflowRdDriver->getMeshName()); - - //Test close() method - CPPUNIT_ASSERT_NO_THROW(aPorflowRdDriver->close()); - - //Default constructor - PORFLOW_MESH_RDONLY_DRIVER aPorflowRdDriverCpy_1; - // TO DO - - //Test copy constructor - PORFLOW_MESH_RDONLY_DRIVER aPorflowRdDriverCpy_2 (*aPorflowRdDriver); - - //Test (bool operator ==) defined GENDRIVER class in MEDMEM_GenDriver.hxx - CPPUNIT_ASSERT(aPorflowRdDriverCpy_2.GENDRIVER::operator==(*aPorflowRdDriver)); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream rostr1, rostr2; - rostr1 << *aPorflowRdDriver; - rostr2 << aPorflowRdDriverCpy_2; - CPPUNIT_ASSERT(rostr1.str() != ""); - CPPUNIT_ASSERT_EQUAL(rostr1.str() , rostr2.str()); - - delete aPorflowRdDriver; - } - - //---------------------------Test WRITE ONLY part-------------------------------------// - { - { - //Creation a incorrect Porflow write only driver - PORFLOW_MESH_WRONLY_DRIVER *aInvalidPorflowWrDriver = - new PORFLOW_MESH_WRONLY_DRIVER(fileNotExistsName_wr, aMesh); - - //Test case: trying open non existing file - CPPUNIT_ASSERT_THROW(aInvalidPorflowWrDriver->open(), MEDEXCEPTION); - - delete aInvalidPorflowWrDriver; - } - - //Creation a correct write only driver - PORFLOW_MESH_WRONLY_DRIVER *aPorflowWrDriver = new PORFLOW_MESH_WRONLY_DRIVER(filename_wr, aMesh); - - //Check driver - CPPUNIT_ASSERT(aPorflowWrDriver); - - //Test case: trying write mesh to file, if file is not open - CPPUNIT_ASSERT_THROW(aPorflowWrDriver->write(), MEDEXCEPTION); - - //Test open() method -#ifndef ENABLE_FORCED_FAILURES - FILE *tmpFile = fopen(filename_wr.data(), "w"); - fclose(tmpFile); -#endif - CPPUNIT_ASSERT_NO_THROW(aPorflowWrDriver->open()); - - //Test case: trying open file secondary. - CPPUNIT_ASSERT_THROW(aPorflowWrDriver->open(), MEDEXCEPTION); - - //Test write() method -#ifdef ENABLE_FORCED_FAILURES - //Write method is not implemented - CPPUNIT_ASSERT_NO_THROW(aPorflowWrDriver->write()); -#endif - - //Test read() method for WRITE ONLY driver - CPPUNIT_ASSERT_THROW(aPorflowWrDriver->read(), MEDEXCEPTION); - - //Test setMeshName() and getMeshName() - CPPUNIT_ASSERT_NO_THROW(aPorflowWrDriver->setMeshName(newmeshname)); - CPPUNIT_ASSERT_EQUAL(newmeshname, aPorflowWrDriver->getMeshName()); - - CPPUNIT_ASSERT_NO_THROW(aPorflowWrDriver->close()); - - //Default constructor - PORFLOW_MESH_WRONLY_DRIVER aPorflowWrDriverCpy_1; - - //Test copy constructor - PORFLOW_MESH_WRONLY_DRIVER aPorflowWrDriverCpy_2 (*aPorflowWrDriver); - - //Test (bool operator ==) defined in GENDRIVER class - CPPUNIT_ASSERT(aPorflowWrDriverCpy_2.GENDRIVER::operator==(*aPorflowWrDriver)); - - //Test (friend ostream & operator <<) defined in GENDRIVER class - ostringstream wostr1, wostr2; - wostr1 << *aPorflowWrDriver; - wostr2 << aPorflowWrDriverCpy_2; - CPPUNIT_ASSERT(wostr1.str() != ""); - CPPUNIT_ASSERT(wostr1.str() == wostr2.str()); - - delete aPorflowWrDriver; - } - - //------------------------Test READ / WRITE part------------------------------------// - { - { - //Creation a incorrect read/write driver - PORFLOW_MESH_RDWR_DRIVER *aInvalidPorflowRdWrDriver = - new PORFLOW_MESH_RDWR_DRIVER(fileNotExistsName_wr, aMesh_1); - - //Test case: trying open non existing file - CPPUNIT_ASSERT_THROW(aInvalidPorflowRdWrDriver->open(), MEDEXCEPTION); - - delete aInvalidPorflowRdWrDriver; - } - - //Creation a correct read/write driver - PORFLOW_MESH_RDWR_DRIVER *aPorflowRdWrDriver = new PORFLOW_MESH_RDWR_DRIVER(filename_rdwr, aMesh_1); - - //Check driver - CPPUNIT_ASSERT(aPorflowRdWrDriver); - - //Test case: trying write mesh to file, if file is not open - CPPUNIT_ASSERT_THROW(aPorflowRdWrDriver->write(), MEDEXCEPTION); - - //Test case: trying read mesh from file, if file is not open - CPPUNIT_ASSERT_THROW(aPorflowRdWrDriver->read(), MEDEXCEPTION); - - //Test open() method - CPPUNIT_ASSERT_NO_THROW(aPorflowRdWrDriver->open()); - - //Test case: trying open file secondary. -#ifdef ENABLE_FORCED_FAILURES - // (BUG) This case work, but corrupt driver - CPPUNIT_ASSERT_THROW(aPorflowRdWrDriver->open(), MEDEXCEPTION); -#endif - - //Test read() method - CPPUNIT_ASSERT_NO_THROW(); - CPPUNIT_ASSERT_NO_THROW(aPorflowRdWrDriver->read()); - - //Test write() method - //aPorflowRdWrDriver->setMeshName(newmeshname); - //aMesh->setName(newmeshname); - //CPPUNIT_ASSERT_NO_THROW(aPorflowRdWrDriver->write()); - //Write method is not implemented -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("PORFLOW_MESH_RDWR_DRIVER::write() method not implemented"); -#endif - - //Check Mesh - CPPUNIT_ASSERT(aMesh); - - CPPUNIT_ASSERT_NO_THROW(aPorflowRdWrDriver->close()); - - //Default constructor - PORFLOW_MESH_RDWR_DRIVER aPorflowRdWrDriverCpy_1; - // TO DO - - //Test copy constructor - PORFLOW_MESH_RDWR_DRIVER aPorflowRdWrDriverCpy_2 (*aPorflowRdWrDriver); - - //Test (bool operator ==) defined in GENDRIVER class - CPPUNIT_ASSERT(aPorflowRdWrDriverCpy_2.GENDRIVER::operator==(*aPorflowRdWrDriver)); - - //Test (friend ostream & operator <<) defined in GENDRIVER class - ostringstream rwostr1, rwostr2; - rwostr1 << *aPorflowRdWrDriver; - rwostr2 << aPorflowRdWrDriverCpy_2; - CPPUNIT_ASSERT(rwostr1.str() != ""); - CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); - - delete aPorflowRdWrDriver; - } - - //Delete all objects - delete aMesh; - delete aMesh_1; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_SkyLineArray.cxx b/src/MEDMEM/Test/MEDMEMTest_SkyLineArray.cxx deleted file mode 100644 index d71050d99..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_SkyLineArray.cxx +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> -#include "MEDMEM_SkyLineArray.hxx" -#include "MEDMEM_define.hxx" - -#include <sstream> -#include <cmath> - -using namespace std; -using namespace MEDMEM; - -/*! - * Check methods (17), defined in MEDMEM_SkyLineArray.hxx: - * class MEDSKYLINEARRAY { - * (+) MEDSKYLINEARRAY(); - * (+) MEDSKYLINEARRAY(const MEDSKYLINEARRAY &myArray); - * (+) MEDSKYLINEARRAY(const int count, const int length); - * (+) MEDSKYLINEARRAY(const int count, const int length, - * const int* index, const int* value, bool shallowCopy=false); - * (+) ~MEDSKYLINEARRAY(); - * (+) inline int getNumberOf() const; - * (+) inline int getLength() const; - * (+) inline const int* getIndex() const; - * (+) inline const int* getValue() const; - * (+) inline int getNumberOfI(int i) const throw (MEDEXCEPTION); - * (+) inline const int* getI(int i) const throw (MEDEXCEPTION); - * (+) inline int getIJ(int i, int j) const throw (MEDEXCEPTION); - * (+) inline int getIndexValue(int i) const throw (MEDEXCEPTION); - * (+) inline void setIndex(const int* index); - * (+) inline void setI(const int i, const int* values) throw (MEDEXCEPTION); - * (+) inline void setIJ(int i, int j, int value) throw (MEDEXCEPTION); - * (+) inline void setIndexValue(int i, int value) throw (MEDEXCEPTION); - * (+) friend ostream& operator<<(ostream &os, const MEDSKYLINEARRAY &sky); - * } - * - */ -void MEDMEMTest::testSkyLineArray() -{ - int NumberOfCell = 3 ; // 1 triangle,1 quadrangle,1 triangle - int Size = 10 ; // 10 nodes - - int * index = new int[NumberOfCell+1] ; - index[0]=1; - index[1]=4; - index[2]=8; - index[3]=11; - int * value = new int[Size] ; - value[0]=1; // first - value[1]=2; - value[2]=5; - value[3]=2; // second - value[4]=3; - value[5]=5; - value[6]=6; - value[7]=3; // thirst - value[8]=4; - value[9]=6; - // value[]=; // forth - - MEDSKYLINEARRAY * myArray = new MEDSKYLINEARRAY(NumberOfCell,Size,index,value) ; - const int * ArrayIndex ; - try - { - ArrayIndex = myArray->getIndex() ; - } - catch ( const std::exception &e ) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - const int * ArrayValue ; - try - { - ArrayValue = myArray->getValue() ; - } - catch ( const std::exception &e ) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - - try - { - CPPUNIT_ASSERT(myArray->getNumberOf()==NumberOfCell); - - } - catch ( const std::exception &e ) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - CPPUNIT_ASSERT(myArray->getLength()==Size); - } - catch ( const std::exception &e ) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - for (int i=1; i< NumberOfCell+1 ; i++) - { - const int * cell; - CPPUNIT_ASSERT_NO_THROW(cell = myArray->getI(i)); - int numberof; - CPPUNIT_ASSERT_NO_THROW(numberof= myArray->getNumberOfI(i)); - CPPUNIT_ASSERT(numberof==index[i]-index[i-1]); - int verif; - for (int j=0;j<numberof;j++) - { - CPPUNIT_ASSERT_NO_THROW(verif=myArray->getIJ(i,j+1)); - CPPUNIT_ASSERT(verif == cell[j]); - } - } - - MEDSKYLINEARRAY * myArray2 = new MEDSKYLINEARRAY(*myArray) ; - delete myArray ; - - const int * index2 = myArray2->getIndex() ; - for (int i=1; i<=NumberOfCell ; i++) { - for (int j=index2[i-1];j<index2[i];j++) - CPPUNIT_ASSERT_NO_THROW(myArray2->getIndexValue(j)); - } - - delete myArray2 ; - - MEDSKYLINEARRAY myArray3(NumberOfCell,Size); - try - { - myArray3.setIndex(index); - } - catch ( const std::exception &e ) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - CPPUNIT_ASSERT_THROW(myArray3.setI(0, 0),MEDEXCEPTION); - - for (int i=1; i<NumberOfCell+1 ; i++) { - CPPUNIT_ASSERT_NO_THROW(myArray3.setI(i, &value[index[i-1]-1])); - } - - for (int i=1; i<NumberOfCell+1 ; i++) { - int numberof; - CPPUNIT_ASSERT_NO_THROW(numberof = myArray3.getNumberOfI(i)); - for (int j=1;j<numberof+1;j++) - CPPUNIT_ASSERT_NO_THROW(myArray3.setIJ(i,j,myArray3.getIJ(i,j))) ; - } - - for (int i=1; i<=NumberOfCell ; i++) { - for (int j=index[i-1];j<index[i];j++) - CPPUNIT_ASSERT_NO_THROW(myArray3.setIndexValue(j,value[j-1])); - } - - delete[] index ; - delete[] value ; - MEDSKYLINEARRAY myEmptyArray; - cout<<myEmptyArray<<endl; -} - diff --git a/src/MEDMEM/Test/MEDMEMTest_Support.cxx b/src/MEDMEM/Test/MEDMEMTest_Support.cxx deleted file mode 100644 index 6e83298ae..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Support.cxx +++ /dev/null @@ -1,686 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_STRING.hxx" -#include "MEDMEM_Support.hxx" - -#include <sstream> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; - -// #52: MEDMEM_Support.hxx } MEDMEMTest_Support.cxx - -/*! - * Check methods (48), defined in MEDMEM_Support.hxx: - * class SUPPORT : public RCBASE { - * (+) SUPPORT(); - * (+) SUPPORT(MESH* Mesh, string Name="", MED_EN::medEntityMesh Entity=MED_EN::MED_CELL); - * (+) SUPPORT(const SUPPORT & m); - * (+) virtual ~SUPPORT(); - * - * (+) friend ostream & operator<<(ostream &os,const SUPPORT &my); - * (+) SUPPORT& operator=(const SUPPORT &support); - * (+) bool operator == (const SUPPORT &support) const; - * (+) bool deepCompare(const SUPPORT &support) const; - * - * (+) void update(); - * - * (+) inline void setName(string Name); - * (+) inline void setDescription(string Description); - * (+) void setMesh(MESH *Mesh) const; - * (+) inline void setMeshName(const string & meshName); - * (+) inline void setAll(bool All); - * (+) inline void setEntity(MED_EN::medEntityMesh Entity); - * - * (+) inline void setNumberOfGeometricType(int NumberOfGeometricType); - * (+) inline void setGeometricType(const MED_EN::medGeometryElement *GeometricType); - * (+) inline void setNumberOfElements(const int *NumberOfElements); - * (+) inline void setTotalNumberOfElements(int TotalNumberOfElements); - * (+) inline void setNumber(MEDSKYLINEARRAY * Number); - * (+) inline void setNumber(const int * index, const int* value, bool shallowCopy=false); - * - * (+) inline string getName() const; - * (+) inline string getDescription() const; - * (+) virtual inline MESH * getMesh() const; - * (+) string getMeshName() const; - * (+) inline MED_EN::medEntityMesh getEntity() const; - * (+) inline bool isOnAllElements() const; - * - * (+) inline int getNumberOfTypes() const; - * (+) inline const MED_EN::medGeometryElement* getTypes() const; - * (+) inline int getNumberOfElements - * (MED_EN::medGeometryElement GeometricType) const throw (MEDEXCEPTION); - * (+) inline const int * getNumberOfElements() const throw (MEDEXCEPTION); - * (+) virtual inline MEDSKYLINEARRAY * getnumber() const throw (MEDEXCEPTION); - * (NO METHOD IN THIS BRANCH) virtual inline MEDSKYLINEARRAY * getnumberFromFile() const throw (MEDEXCEPTION); - * (+) virtual inline const int * getNumber - * (MED_EN::medGeometryElement GeometricType) const throw (MEDEXCEPTION); - * (NO METHOD IN THIS BRANCH) virtual inline const int * getNumberFromFile - * (MED_EN::medGeometryElement GeometricType) const throw (MEDEXCEPTION); - * (+) virtual inline const int * getNumberIndex() const throw (MEDEXCEPTION); - * (+) virtual int getValIndFromGlobalNumber(const int number) const throw (MEDEXCEPTION); - * - * (+) void blending(SUPPORT * mySupport) throw (MEDEXCEPTION); - * - * (+) void setpartial(string Description, int NumberOfGeometricType, - * int TotalNumberOfEntity, MED_EN::medGeometryElement *GeometricType, - * int *NumberOfEntity, int *NumberValue); - * (+) void setpartial(MEDSKYLINEARRAY * number, bool shallowCopy=false) throw (MEDEXCEPTION); - * (NO METHOD IN THIS BRANCH) void setpartial_fromfile(MEDSKYLINEARRAY * number, bool shallowCopy=false) throw (MEDEXCEPTION); - * - * (+) void setProfilNames(vector<string> profilNames) throw (MEDEXCEPTION); - * (+) vector<string> getProfilNames() const throw (MEDEXCEPTION); - * - * (+) void getBoundaryElements() throw (MEDEXCEPTION); - * - * (+) void changeElementsNbs(MED_EN::medEntityMesh entity, const int *renumberingFromOldToNew, - * int limitNbClassicPoly, const int *renumberingFromOldToNewPoly=0); - * (+) void intersecting(SUPPORT * mySupport) throw (MEDEXCEPTION); - * (+) bool belongsTo(const SUPPORT& other, bool deepCompare=false) const; - * - * (+) SUPPORT *getComplement() const; - * (+) SUPPORT *substract(const SUPPORT& other) const throw (MEDEXCEPTION); - * - * (+) SUPPORT *getBoundaryElements(MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION); - * - * (+) void fillFromNodeList(const list<int>& listOfNode) throw (MEDEXCEPTION); - * (+) void fillFromElementList(const list<int>& listOfElt) throw (MEDEXCEPTION); - * - * (+) void clearDataOnNumbers(); - * - * (reference counter presently disconnected in C++) virtual void addReference() const; - * (reference counter presently disconnected in C++) virtual void removeReference() const; - * } - */ -void MEDMEMTest::testSupport() -{ - // cells connectivities - //const int NumberOfCellTypes = 3; - //MED_EN::medGeometryElement CellTypes[NumberOfCellTypes] = - // {MED_EN::MED_TETRA4, MED_EN::MED_PYRA5, MED_EN::MED_HEXA8}; - //const int NumberOfCells[NumberOfCellTypes] = {12, 2, 2}; - - // faces connectivities - //const int NumberOfFaceTypes = 2; - //MED_EN::medGeometryElement FaceTypes[NumberOfFaceTypes] = {MED_EN::MED_TRIA3, MED_EN::MED_QUAD4}; - //const int NumberOfFaces[NumberOfFaceTypes] = {4, 4}; - - MESH * aMesh = MEDMEMTest_createTestMesh(); - MESH * aMeshOneMore = MEDMEMTest_createTestMesh(); - - //////////// - // TEST 1 // - //////////// - - SUPPORT aSupportOnFaces1 (aMesh, "Support On Faces 1", MED_EN::MED_FACE); - SUPPORT aSupportOnCells1 (aMesh, "Support On Cells 1"/*, MED_EN::MED_CELL*/); - - SUPPORT aSupportOnFaces2; - SUPPORT aSupportOnCells2; - - SUPPORT aSupportOnFaces3 (aMeshOneMore, "Support On Faces 3", MED_EN::MED_FACE); - - // entity - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aSupportOnFaces1.getEntity()); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_CELL, aSupportOnCells1.getEntity()); - - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_CELL, aSupportOnFaces2.getEntity()); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_CELL, aSupportOnCells2.getEntity()); - - aSupportOnFaces2.setEntity(MED_EN::MED_FACE); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aSupportOnFaces2.getEntity()); - - // isOnAllElements - CPPUNIT_ASSERT(aSupportOnFaces1.isOnAllElements()); - CPPUNIT_ASSERT(aSupportOnCells1.isOnAllElements()); - - CPPUNIT_ASSERT(!aSupportOnFaces2.isOnAllElements()); - CPPUNIT_ASSERT(!aSupportOnCells2.isOnAllElements()); - - // mesh and mesh name - CPPUNIT_ASSERT_THROW(aSupportOnFaces1.setMeshName("Mesh 1"), MEDEXCEPTION); - - aSupportOnFaces2.setMeshName("Mesh 1"); - aSupportOnCells2.setMeshName("Mesh 1"); - CPPUNIT_ASSERT(aSupportOnFaces2.getMeshName() == "Mesh 1"); - CPPUNIT_ASSERT(aSupportOnCells2.getMeshName() == "Mesh 1"); - - aSupportOnFaces2.setMesh(aMesh); - CPPUNIT_ASSERT_THROW(aSupportOnFaces2.setMeshName("Mesh 1"), MEDEXCEPTION); - - aSupportOnCells1.setMesh(NULL); - aSupportOnCells1.setMeshName("Mesh 1"); - - CPPUNIT_ASSERT(aSupportOnFaces1.getMeshName() == "meshing"); - CPPUNIT_ASSERT(aSupportOnFaces2.getMeshName() == "meshing"); - CPPUNIT_ASSERT(aSupportOnCells1.getMeshName() == "Mesh 1"); - CPPUNIT_ASSERT(aSupportOnCells2.getMeshName() == "Mesh 1"); - - CPPUNIT_ASSERT(aSupportOnFaces1.getMesh() == aMesh); - CPPUNIT_ASSERT(aSupportOnFaces2.getMesh() == aMesh); - CPPUNIT_ASSERT(aSupportOnCells1.getMesh() == NULL); - CPPUNIT_ASSERT(aSupportOnCells2.getMesh() == NULL); - - // operator == - aSupportOnFaces2.setName("Support On Faces 2"); - aSupportOnCells2.setName("Support On Cells 2"); - - // because aSupportOnFaces1 is on all elements, but aSupportOnFaces2 not - CPPUNIT_ASSERT(!(aSupportOnFaces1 == aSupportOnFaces2)); - - aSupportOnCells1.setAll(false); - CPPUNIT_ASSERT(!aSupportOnCells1.isOnAllElements()); - // this is only sets flag _isOnAllElts to false, but not clear elements and types - // information, so aSupportOnCells1 is not equal to aSupportOnCells2 at this moment - -#ifdef ENABLE_FAULTS - // (BUG) SUPPORT::operator= gives "Segmentation Fault" on supports with NULL meshes!!! - CPPUNIT_ASSERT(!(aSupportOnCells1 == aSupportOnCells2)); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("SUPPORT::operator= gives Segmentation Fault on supports with NULL meshes!!!"); -#endif - - aSupportOnFaces2.setAll(true); - CPPUNIT_ASSERT(aSupportOnFaces2.isOnAllElements()); - // flag _isOnAllElts now is set to true, but we need also to call update() - // to set elements and types information from mesh to this support - CPPUNIT_ASSERT(!(aSupportOnFaces1 == aSupportOnFaces2)); - aSupportOnFaces2.update(); - CPPUNIT_ASSERT(aSupportOnFaces1 == aSupportOnFaces2); - - // deep compare - CPPUNIT_ASSERT(aSupportOnFaces1.deepCompare(aSupportOnFaces2)); - - CPPUNIT_ASSERT(!(aSupportOnFaces1 == aSupportOnFaces3)); // different mesh pointers - CPPUNIT_ASSERT(aSupportOnFaces1.deepCompare(aSupportOnFaces3)); // meshes are really equal - - // description - aSupportOnFaces1.setDescription("Support on all faces with mesh pointer"); - aSupportOnFaces2.setDescription("Support on all faces with mesh pointer"); - - aSupportOnCells1.setDescription("Support on a part of cells with mesh name"); - aSupportOnCells2.setDescription("Support on a part of cells with mesh name"); - - CPPUNIT_ASSERT(aSupportOnFaces1.getDescription() == "Support on all faces with mesh pointer"); - CPPUNIT_ASSERT(aSupportOnFaces2.getDescription() == "Support on all faces with mesh pointer"); - CPPUNIT_ASSERT(aSupportOnCells1.getDescription() == "Support on a part of cells with mesh name"); - CPPUNIT_ASSERT(aSupportOnCells2.getDescription() == "Support on a part of cells with mesh name"); - - // operator<< - ostringstream ostr1; - ostr1 << aSupportOnFaces1; - CPPUNIT_ASSERT(ostr1.str() != ""); - - ostringstream ostr2; - ostr2 << aSupportOnCells2; - CPPUNIT_ASSERT(ostr2.str() != ""); - - // set/get elements and types information - - // 1. aSupportOnCells1 is not on all elements, but now it contains information - // about all cells of aMesh, because it was created on mesh and with parameters. - CPPUNIT_ASSERT_EQUAL(3, aSupportOnCells1.getNumberOfTypes()); - CPPUNIT_ASSERT(aSupportOnCells1.getTypes() != NULL); - - //const int * nbEltsSC_old = aSupportOnCells1.getNumberOfElements(); // {12, 2, 2} - - aSupportOnCells1.setNumberOfGeometricType(0); - CPPUNIT_ASSERT_EQUAL(0, aSupportOnCells1.getNumberOfTypes()); - CPPUNIT_ASSERT(aSupportOnCells1.getTypes() == NULL); - - MED_EN::medGeometryElement aSCTypes[2] = {MED_EN::MED_PYRA5, MED_EN::MED_PENTA15}; - aSupportOnCells1.setNumberOfGeometricType(2); - aSupportOnCells1.setGeometricType(aSCTypes); - - CPPUNIT_ASSERT_EQUAL(2, aSupportOnCells1.getNumberOfTypes()); - CPPUNIT_ASSERT(aSupportOnCells1.getTypes() != NULL); - CPPUNIT_ASSERT(aSupportOnCells1.getNumberOfElements() == NULL); // reset by setNumberOfGeometricType - - int nbEltsSC[2] = {2, 1}; - aSupportOnCells1.setNumberOfElements(nbEltsSC); - - const int * nbEltsSCBack = aSupportOnCells1.getNumberOfElements(); - CPPUNIT_ASSERT_EQUAL(2, aSupportOnCells1.getNumberOfElements(MED_EN::MED_PYRA5)); - CPPUNIT_ASSERT_EQUAL(2, nbEltsSCBack[0]); - CPPUNIT_ASSERT_EQUAL(1, aSupportOnCells1.getNumberOfElements(MED_EN::MED_PENTA15)); - CPPUNIT_ASSERT_EQUAL(1, nbEltsSCBack[1]); - CPPUNIT_ASSERT_EQUAL(3, aSupportOnCells1.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - - // old types - CPPUNIT_ASSERT_THROW(aSupportOnCells1.getNumberOfElements(MED_EN::MED_TETRA4), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSupportOnCells1.getNumberOfElements(MED_EN::MED_HEXA8), MEDEXCEPTION); - - //_number= new MEDSKYLINEARRAY(_numberOfGeometricType,_totalNumberOfElements,index,value,shallowCopy); - int indexSC[3] = {1,3,4}; // length = nb.types + 1 - int valueSC[3] = {21,22,47}; // length = total nb. of elements - aSupportOnCells1.setNumber(indexSC, valueSC); - - // check number - MEDSKYLINEARRAY * aNumberSCBack = aSupportOnCells1.getnumber(); - - CPPUNIT_ASSERT_EQUAL(2, aNumberSCBack->getNumberOf()); - CPPUNIT_ASSERT_EQUAL(3, aNumberSCBack->getLength()); - const int * ind = aNumberSCBack->getIndex(); - const int * val = aNumberSCBack->getValue(); - CPPUNIT_ASSERT_EQUAL(1, ind[0]); - CPPUNIT_ASSERT_EQUAL(3, ind[1]); - CPPUNIT_ASSERT_EQUAL(4, ind[2]); - CPPUNIT_ASSERT_EQUAL(21, val[0]); - CPPUNIT_ASSERT_EQUAL(22, val[1]); - CPPUNIT_ASSERT_EQUAL(47, val[2]); - - // 2. aSupportOnCells2 is not on all elements, and now it contains - // no information about elements of a mesh - CPPUNIT_ASSERT_EQUAL(0, aSupportOnCells2.getNumberOfTypes()); - CPPUNIT_ASSERT(aSupportOnCells2.getTypes() == NULL); - - aSupportOnCells2.setNumberOfGeometricType(2); - aSupportOnCells2.setGeometricType(aSCTypes); - - CPPUNIT_ASSERT_EQUAL(2, aSupportOnCells2.getNumberOfTypes()); - CPPUNIT_ASSERT(aSupportOnCells2.getTypes() != NULL); - - aSupportOnCells2.setNumberOfElements(nbEltsSC); - - // we create MEDSKYLINEARRAY as pointer, because aSupportOnCells2 will - // become an owner of it, and we must not delete it. - MEDSKYLINEARRAY * aNumberSC = new MEDSKYLINEARRAY(2, 3, indexSC, valueSC); - aSupportOnCells2.setNumber(aNumberSC); - - // check number - const int * aNumberIndexSC = aSupportOnCells2.getNumberIndex(); - CPPUNIT_ASSERT_EQUAL(1, aNumberIndexSC[0]); - CPPUNIT_ASSERT_EQUAL(3, aNumberIndexSC[1]); - CPPUNIT_ASSERT_EQUAL(4, aNumberIndexSC[2]); - - const int * aNbPYRA5 = aSupportOnCells2.getNumber(MED_EN::MED_PYRA5); - const int * aNbPENTA15 = aSupportOnCells2.getNumber(MED_EN::MED_PENTA15); - CPPUNIT_ASSERT_THROW(aSupportOnCells2.getNumber(MED_EN::MED_TETRA4), MEDEXCEPTION); - - const int * aNbC = aSupportOnCells2.getNumber(MED_EN::MED_ALL_ELEMENTS); - - CPPUNIT_ASSERT_EQUAL(21, aNbPYRA5[0]); - CPPUNIT_ASSERT_EQUAL(22, aNbPYRA5[1]); - CPPUNIT_ASSERT_EQUAL(47, aNbPENTA15[0]); - - CPPUNIT_ASSERT_EQUAL(21, aNbC[0]); - CPPUNIT_ASSERT_EQUAL(22, aNbC[1]); - CPPUNIT_ASSERT_EQUAL(47, aNbC[2]); - - // getValIndFromGlobalNumber - CPPUNIT_ASSERT_EQUAL(1, aSupportOnCells2.getValIndFromGlobalNumber(21)); - CPPUNIT_ASSERT_EQUAL(2, aSupportOnCells2.getValIndFromGlobalNumber(22)); - CPPUNIT_ASSERT_EQUAL(3, aSupportOnCells2.getValIndFromGlobalNumber(47)); - // not existing element - CPPUNIT_ASSERT_THROW(aSupportOnCells2.getValIndFromGlobalNumber(10), MEDEXCEPTION); - - // compare aSupportOnCells1 and aSupportOnCells2 - - // temporary set mesh (because of bug with operator==) - aSupportOnCells1.setMesh(aMesh); - aSupportOnCells2.setMesh(aMesh); - - CPPUNIT_ASSERT_EQUAL(aSupportOnCells1, aSupportOnCells2); - - // restore mesh name - aSupportOnCells1.setMesh(NULL); - aSupportOnCells2.setMesh(NULL); - aSupportOnCells1.setMeshName("Mesh 1"); - aSupportOnCells2.setMeshName("Mesh 1"); - - // 3. aSupportOnFacesN is on all elements, and it contains - // information about all faces of aMesh - CPPUNIT_ASSERT_EQUAL(2, aSupportOnFaces1.getNumberOfTypes()); - const MED_EN::medGeometryElement* aSF1Types = aSupportOnFaces1.getTypes(); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_TRIA3, aSF1Types[0]); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_QUAD4, aSF1Types[1]); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Comment to method SUPPORT::getTypes() says: - // "If isOnAllElements is false, returns an array of %medGeometryElement types used by the support." - // But in fact it returns types in any case (comment to SUPPORT::setAll() gives more information). - CPPUNIT_FAIL("Comment and implementation does not match for SUPPORT::getTypes()"); - // This concerns also method SUPPORT::update(), being called from constructor, - // which fills internal SUPPORT structures with information about mesh elements - // in case of isOnAllElements == true. - // Also comments and implementation does not match for SUPPORT::getNumberOfElements(). - // It seems that in case "isOnAllElements == true" calls like getNumberOfElements() - // must be redirected to mesh, but what if mesh is not set (mesh name used instead)?. -#endif - const int * nbEltsSF1 = aSupportOnFaces1.getNumberOfElements(); - CPPUNIT_ASSERT_EQUAL(4, aSupportOnFaces1.getNumberOfElements(MED_EN::MED_TRIA3)); - CPPUNIT_ASSERT_EQUAL(4, nbEltsSF1[0]); - CPPUNIT_ASSERT_EQUAL(4, aSupportOnFaces1.getNumberOfElements(MED_EN::MED_QUAD4)); - CPPUNIT_ASSERT_EQUAL(4, nbEltsSF1[1]); - CPPUNIT_ASSERT_EQUAL(8, aSupportOnFaces1.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumberOfElements(MED_EN::MED_TRIA6), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumberOfElements(MED_EN::MED_QUAD8), MEDEXCEPTION); - - // check number - CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumberIndex(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumber(MED_EN::MED_TRIA3), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumber(MED_EN::MED_QUAD4), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumber(MED_EN::MED_ALL_ELEMENTS), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getnumber(), MEDEXCEPTION); - - // getValIndFromGlobalNumber - CPPUNIT_ASSERT_EQUAL(8, aMesh->getNumberOfElements(MED_EN::MED_FACE, MED_EN::MED_ALL_ELEMENTS)); - for (int i = 1; i <= 8; i++) { - CPPUNIT_ASSERT_EQUAL(i, aSupportOnFaces1.getValIndFromGlobalNumber(i)); - } - -#ifdef ENABLE_FORCED_FAILURES - // Why methods setNumber do not throw exception in case "isOnAllElements == true", - // like methods getNumber do? - //CPPUNIT_ASSERT_THROW(aSupportOnFaces1.setNumber(indexSF1, valueSF1)); -#endif - -#ifdef ENABLE_FORCED_FAILURES - // It seems to be dangerous and useless to have method SUPPORT::setTotalNumberOfElements() - //CPPUNIT_FAIL("It seems to be dangerous and useless to have method SUPPORT::setTotalNumberOfElements()"); -#endif - // setTotalNumberOfElements - aSupportOnFaces1.setTotalNumberOfElements(1000); - CPPUNIT_ASSERT_EQUAL(1000, aSupportOnFaces1.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - - // clearDataOnNumbers - aSupportOnCells1.clearDataOnNumbers(); - CPPUNIT_ASSERT_EQUAL(0, aSupportOnCells1.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - CPPUNIT_ASSERT_EQUAL(0, aSupportOnCells1.getNumberOfTypes()); - CPPUNIT_ASSERT_THROW(aSupportOnCells1.getnumber(), MEDEXCEPTION); - - //////////// - // TEST 2 // - //////////// - - list<int> nodes137; - nodes137.push_back(1); - nodes137.push_back(3); - nodes137.push_back(7); - - list<int> nodes248; - nodes248.push_back(2); - nodes248.push_back(4); - nodes248.push_back(8); - - list<int> nodes27; - nodes27.push_back(2); - nodes27.push_back(7); - - SUPPORT aNodes137 (aMesh, "Support On Nodes 1,3,7", MED_EN::MED_CELL); - SUPPORT aNodes248 (aMesh, "Support On Nodes 2,4,8", MED_EN::MED_CELL); - SUPPORT aNodes27 (aMesh, "Support On Nodes 2,7" , MED_EN::MED_CELL); - - aNodes137.fillFromNodeList(nodes137); - aNodes248.fillFromNodeList(nodes248); - aNodes27.fillFromNodeList(nodes27); - - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_NODE, aNodes137.getEntity()); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_NODE, aNodes248.getEntity()); - - list<int>::const_iterator iter137 = nodes137.begin(); - list<int>::const_iterator iter248 = nodes248.begin(); - for (int i = 1; i <= 3; i++, iter137++, iter248++) { - CPPUNIT_ASSERT_EQUAL(i, aNodes137.getValIndFromGlobalNumber(*iter137)); - CPPUNIT_ASSERT_EQUAL(i, aNodes248.getValIndFromGlobalNumber(*iter248)); - } - - //////////// - - list<int> faces123; - faces123.push_back(1); - faces123.push_back(2); - faces123.push_back(3); - - list<int> faces135; - faces135.push_back(1); - faces135.push_back(3); - faces135.push_back(5); - - SUPPORT aFaces123 (aMesh, "Support On Faces 1,2,3", MED_EN::MED_FACE); - SUPPORT aFaces135 (aMesh, "Support On Faces 1,3,5", MED_EN::MED_FACE); - - aFaces123.fillFromElementList(faces123); - aFaces135.fillFromElementList(faces135); - - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces123.getEntity()); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces135.getEntity()); - - list<int>::const_iterator iter123 = faces123.begin(); - list<int>::const_iterator iter135 = faces135.begin(); - for (int i = 1; i <= 3; i++, iter123++, iter135++) { - CPPUNIT_ASSERT_EQUAL(i, aFaces123.getValIndFromGlobalNumber(*iter123)); - CPPUNIT_ASSERT_EQUAL(i, aFaces135.getValIndFromGlobalNumber(*iter135)); - } - - // substract - SUPPORT * aFaces2 = aFaces123.substract(aFaces135); // => 2 - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces2->getEntity()); - CPPUNIT_ASSERT_EQUAL(1, aFaces2->getValIndFromGlobalNumber(2)); - CPPUNIT_ASSERT_EQUAL(1, aFaces2->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - - CPPUNIT_ASSERT_THROW(aFaces123.substract(aNodes137), MEDEXCEPTION); - -#ifdef ENABLE_FORCED_FAILURES - // (BUG) SUPPORT::substract() does not work with supports on nodes, - // because it uses method MESH::buildSupportOnNodeFromElementList(), - // which does not work if entity = MED_NODE - //SUPPORT * aNodes137mesh = aMesh->buildSupportOnNodeFromElementList(nodes137, MED_EN::MED_NODE); - //delete aNodes137mesh; - SUPPORT * aNodes137sub = aNodes137.substract(aNodes248); // => 1,3,7 - CPPUNIT_ASSERT_EQUAL(*aNodes137sub, aNodes137); - delete aNodes137sub; -#endif - - // belongsTo - CPPUNIT_ASSERT(aFaces2->belongsTo(aFaces123)); - CPPUNIT_ASSERT(!aFaces2->belongsTo(aFaces135)); - - CPPUNIT_ASSERT(!aFaces2->belongsTo(aSupportOnFaces3)); - CPPUNIT_ASSERT(aFaces2->belongsTo(aSupportOnFaces3, /*deepCompare*/true)); - - delete aFaces2; - - // getComplement - SUPPORT * aFaces_135 = aFaces135.getComplement(); // => 2,4,6,7,8 - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces_135->getEntity()); - CPPUNIT_ASSERT_EQUAL(5, aFaces_135->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Memory problem in SUPPORT::sub() - // Invalid read of size 4 - // at 0x34902492: MEDMEM::SUPPORT::sub(int, int, int const*, int) (MEDMEM_Support.cxx:852) - // by 0x3490296B: MEDMEM::SUPPORT::getComplement() const (MEDMEM_Support.cxx:916) - // by 0x34398F1E: MEDMEMTest::testSupport() (MEDMEMTest_Support.cxx:514) - // Address 0x352DB91C is 0 bytes after a block of size 12 alloc'd - // at 0x3414C8E2: operator new[](unsigned) (vg_replace_malloc.c:138) - // by 0x3490243A: MEDMEM::SUPPORT::sub(int, int, int const*, int) (MEDMEM_Support.cxx:847) - // by 0x3490296B: MEDMEM::SUPPORT::getComplement() const (MEDMEM_Support.cxx:916) - // by 0x34398F1E: MEDMEMTest::testSupport() (MEDMEMTest_Support.cxx:514) - CPPUNIT_FAIL("Memory problem in SUPPORT::sub(): Invalid read of size 4 from array <temp>"); -#endif - -#ifdef ENABLE_FORCED_FAILURES - // (BUG) SUPPORT::getComplement() does not work with support on nodes, - // because it uses method MESH::buildSupportOnNodeFromElementList(), - // which does not work if entity = MED_NODE - SUPPORT * aNodes_137 = aNodes137.getComplement(); // => 2,4,5,6,8,9,10-19 - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_NODE, aNodes_137->getEntity()); - CPPUNIT_ASSERT_EQUAL(16, aNodes_137->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); -#endif - - // intersecting - aFaces_135->intersecting(&aFaces123); // => 2 - CPPUNIT_ASSERT_EQUAL(1, aFaces_135->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - CPPUNIT_ASSERT_EQUAL(1, aFaces_135->getValIndFromGlobalNumber(2)); - - //aNodes_137->intersecting(&aNodes248); // => 2,4,8 - //CPPUNIT_ASSERT_EQUAL(3, aNodes_137->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - //CPPUNIT_ASSERT_EQUAL(*aNodes_137, aNodes248); - aNodes137.intersecting(&aNodes248); // => {} - CPPUNIT_ASSERT_EQUAL(0, aNodes137.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - - // blending - aFaces_135->blending(&aFaces135); // => 1,2,3,5 - CPPUNIT_ASSERT_EQUAL(4, aFaces_135->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - - aNodes248.blending(&aNodes27); // => 2,4,7,8 - CPPUNIT_ASSERT_EQUAL(4, aNodes248.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - - // operator= - SUPPORT aCopy1; - aCopy1 = aNodes248; - CPPUNIT_ASSERT_EQUAL(aNodes248, aCopy1); - - // copy constructor - SUPPORT aCopy2 (aFaces135); - CPPUNIT_ASSERT_EQUAL(aFaces135, aCopy2); - - delete aFaces_135; -#ifdef ENABLE_FORCED_FAILURES - delete aNodes_137; -#endif - - // profil names - vector<string> aPrN2 (2); // nb. types - aPrN2[0] = "Profil 1"; - aPrN2[1] = "Profil 2"; - aFaces135.setProfilNames(aPrN2); - - // because on all elements - CPPUNIT_ASSERT_THROW(aSupportOnFaces3.setProfilNames(aPrN2), MEDEXCEPTION); - - // because length of vector is not equal to nb.types - vector<string> aPrN3 (3); - CPPUNIT_ASSERT_THROW(aFaces135.setProfilNames(aPrN3), MEDEXCEPTION); - - vector<string> aPrN2Back = aFaces135.getProfilNames(); - CPPUNIT_ASSERT_EQUAL(aPrN2[0], aPrN2Back[0]); - CPPUNIT_ASSERT_EQUAL(aPrN2[1], aPrN2Back[1]); - -#ifdef ENABLE_FORCED_FAILURES - // (BUG) profil names are not copied by copy constructor and operator=, - // not compared by operator==, not dumped in stream by operator<< - //CPPUNIT_FAIL("Not complete implementation for Profil Names"); -#endif - - //////////// - // TEST 3 // - //////////// - - SUPPORT aPartialCells (aMesh, "Support On Cells 2,3,4", MED_EN::MED_CELL); - SUPPORT aPartialNodes (aMesh, "Support On Nodes 2,3,4", MED_EN::MED_NODE); - - // setpartial - MED_EN::medGeometryElement gtCells[1] = {MED_EN::MED_TETRA4}; - int nbCells[1] = {3}; - int cells[3] = {2,3,4}; - aPartialCells.setpartial("with description", 1, 3, gtCells, nbCells, cells); - CPPUNIT_ASSERT_EQUAL(1, aPartialCells.getValIndFromGlobalNumber(2)); - CPPUNIT_ASSERT_EQUAL(2, aPartialCells.getValIndFromGlobalNumber(3)); - CPPUNIT_ASSERT_EQUAL(3, aPartialCells.getValIndFromGlobalNumber(4)); - - MED_EN::medGeometryElement gtNodes[1] = {MED_EN::MED_NONE}; - aPartialNodes.setNumberOfGeometricType(1); - aPartialNodes.setGeometricType(gtNodes); - int indexSN[2] = {1,4}; - int valueSN[3] = {2,3,4}; - MEDSKYLINEARRAY * aNumberSN = new MEDSKYLINEARRAY(1, 3, indexSN, valueSN); - aPartialNodes.setpartial(aNumberSN, /*shallowCopy*/false); - delete aNumberSN; - CPPUNIT_ASSERT_EQUAL(1, aPartialNodes.getValIndFromGlobalNumber(2)); - CPPUNIT_ASSERT_EQUAL(2, aPartialNodes.getValIndFromGlobalNumber(3)); - CPPUNIT_ASSERT_EQUAL(3, aPartialNodes.getValIndFromGlobalNumber(4)); - - // changeElementsNbs - - // {1,2,3,4,5,6,7,8,9,10} -> {10,9,8,7,6,5,4,3,2,1} - int renumberingFromOldToNew[10] = {10,9,8,7,6,5,4,3,2,1}; - - CPPUNIT_ASSERT_THROW(aPartialCells.changeElementsNbs - (MED_EN::MED_NODE, renumberingFromOldToNew, 10), MEDEXCEPTION); - - aPartialCells.changeElementsNbs(MED_EN::MED_CELL, renumberingFromOldToNew, 10); - CPPUNIT_ASSERT_EQUAL(3, aPartialCells.getValIndFromGlobalNumber(9)); - CPPUNIT_ASSERT_EQUAL(2, aPartialCells.getValIndFromGlobalNumber(8)); - CPPUNIT_ASSERT_EQUAL(1, aPartialCells.getValIndFromGlobalNumber(7)); - - // {1,2,3,4,5,6,7} -> {1,3,5,7,2,4,6}, {8,9,10,11} -> {8,10,9,11} - int renumberingFromOldToNewP[7] = {1,3,5,7,2,4,6}; - int renumberingFromOldToNewPolyP[4] = {8,10,9,11}; - aPartialCells.changeElementsNbs(MED_EN::MED_CELL, renumberingFromOldToNewP, - 7, renumberingFromOldToNewPolyP); - CPPUNIT_ASSERT_EQUAL(3, aPartialCells.getValIndFromGlobalNumber(10)); - CPPUNIT_ASSERT_EQUAL(2, aPartialCells.getValIndFromGlobalNumber(8)); - CPPUNIT_ASSERT_EQUAL(1, aPartialCells.getValIndFromGlobalNumber(6)); - - // this method does not suit for nodes renumbering! - // {1,2,3} -> {3,2,1}, {4,5,6,7} -> {5,6,7,4} - //int renumberingFromOldToNewN[3] = {3,2,1}; - //int renumberingFromOldToNewPolyN[4] = {5,6,7,4}; - //aPartialNodes.changeElementsNbs(MED_EN::MED_NODE, renumberingFromOldToNewN, - // 3, renumberingFromOldToNewPolyN); - - // getBoundaryElements -#ifdef ENABLE_FAULTS - // (BUG) Segmentation Fault during SUPPORT::getBoundaryElements() - // ??? May be mesh is not complete ??? - SUPPORT aBoundaryFaces (aMesh, "meshing boundary faces", MED_EN::MED_FACE); - aBoundaryFaces.getBoundaryElements(); - //cout << "aBoundaryFaces:" << endl; - //cout << aBoundaryFaces << endl; - - SUPPORT * aBoundaryNodes = aSupportOnFaces3.getBoundaryElements(MED_EN::MED_NODE); - //cout << "aSupportOnFaces3:" << endl; - //cout << aSupportOnFaces3 << endl; - //cout << "aBoundaryNodes:" << endl; - //cout << aBoundaryNodes << endl; - delete aBoundaryNodes; -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("Segmentation Fault during SUPPORT::getBoundaryElements()"); - // Invalid write of size 4 - // at 0x3439DFCE: void std::_Construct<int, int>(int*, int const&) (stl_construct.h:81) - // by 0x3476E4D1: std::vector<int, std::allocator<int> >::push_back(int const&) (stl_vector.h:560) - // by 0x34763DDB: MEDMEM::CONNECTIVITY::calculateReverseNodalConnectivity() (MEDMEM_Connectivity.cxx:1155) - // by 0x347655FF: MEDMEM::CONNECTIVITY::calculateDescendingConnectivity() (MEDMEM_Connectivity.cxx:1333) - // by 0x3476363E: MEDMEM::CONNECTIVITY::getReverseDescendingConnectivity() (MEDMEM_Connectivity.cxx:1090) - // by 0x34772AB6: MEDMEM::CONNECTIVITY::getReverseConnectivity(long, long) (MEDMEM_Connectivity.hxx:503) - // by 0x348F4F4B: MEDMEM::MESH::getReverseConnectivity(long, long) const (MEDMEM_Mesh.hxx:848) - // by 0x348FF559: MEDMEM::SUPPORT::getBoundaryElements() (MEDMEM_Support.cxx:483) - // by 0x3439C8E5: MEDMEMTest::testSupport() (MEDMEMTest_Support.cxx:641) - // Address 0x61666A2F is not stack'd, malloc'd or (recently) free'd -#endif - - delete aMesh; - delete aMeshOneMore; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_Support_fault.cxx b/src/MEDMEM/Test/MEDMEMTest_Support_fault.cxx deleted file mode 100644 index 7b6dfbe59..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Support_fault.cxx +++ /dev/null @@ -1,691 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_STRING.hxx" -#include "MEDMEM_Support.hxx" - -#include <sstream> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -//#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; - -// #52: MEDMEM_Support.hxx } MEDMEMTest_Support.cxx - -/*! - * Check methods (48), defined in MEDMEM_Support.hxx: - * class SUPPORT : public RCBASE { - * (+) SUPPORT(); - * (+) SUPPORT(MESH* Mesh, string Name="", MED_EN::medEntityMesh Entity=MED_EN::MED_CELL); - * (+) SUPPORT(const SUPPORT & m); - * (+) virtual ~SUPPORT(); - * - * (+) friend ostream & operator<<(ostream &os,const SUPPORT &my); - * (+) SUPPORT& operator=(const SUPPORT &support); - * (+) bool operator == (const SUPPORT &support) const; - * (+) bool deepCompare(const SUPPORT &support) const; - * - * (+) void update(); - * - * (+) inline void setName(string Name); - * (+) inline void setDescription(string Description); - * (+) void setMesh(MESH *Mesh) const; - * (+) inline void setMeshName(const string & meshName); - * (+) inline void setAll(bool All); - * (+) inline void setEntity(MED_EN::medEntityMesh Entity); - * - * (+) inline void setNumberOfGeometricType(int NumberOfGeometricType); - * (+) inline void setGeometricType(const MED_EN::medGeometryElement *GeometricType); - * (+) inline void setNumberOfElements(const int *NumberOfElements); - * (+) inline void setTotalNumberOfElements(int TotalNumberOfElements); - * (+) inline void setNumber(MEDSKYLINEARRAY * Number); - * (+) inline void setNumber(const int * index, const int* value, bool shallowCopy=false); - * - * (+) inline string getName() const; - * (+) inline string getDescription() const; - * (+) virtual inline MESH * getMesh() const; - * (+) string getMeshName() const; - * (+) inline MED_EN::medEntityMesh getEntity() const; - * (+) inline bool isOnAllElements() const; - * - * (+) inline int getNumberOfTypes() const; - * (+) inline const MED_EN::medGeometryElement* getTypes() const; - * (+) inline int getNumberOfElements - * (MED_EN::medGeometryElement GeometricType) const throw (MEDEXCEPTION); - * (+) inline const int * getNumberOfElements() const throw (MEDEXCEPTION); - * (+) virtual inline MEDSKYLINEARRAY * getnumber() const throw (MEDEXCEPTION); - * (NO METHOD IN THIS BRANCH) virtual inline MEDSKYLINEARRAY * getnumberFromFile() const throw (MEDEXCEPTION); - * (+) virtual inline const int * getNumber - * (MED_EN::medGeometryElement GeometricType) const throw (MEDEXCEPTION); - * (NO METHOD IN THIS BRANCH) virtual inline const int * getNumberFromFile - * (MED_EN::medGeometryElement GeometricType) const throw (MEDEXCEPTION); - * (+) virtual inline const int * getNumberIndex() const throw (MEDEXCEPTION); - * (+) virtual int getValIndFromGlobalNumber(const int number) const throw (MEDEXCEPTION); - * - * (+) void blending(SUPPORT * mySupport) throw (MEDEXCEPTION); - * - * (+) void setpartial(string Description, int NumberOfGeometricType, - * int TotalNumberOfEntity, MED_EN::medGeometryElement *GeometricType, - * int *NumberOfEntity, int *NumberValue); - * (+) void setpartial(MEDSKYLINEARRAY * number, bool shallowCopy=false) throw (MEDEXCEPTION); - * (NO METHOD IN THIS BRANCH) void setpartial_fromfile(MEDSKYLINEARRAY * number, bool shallowCopy=false) throw (MEDEXCEPTION); - * - * (+) void setProfilNames(vector<string> profilNames) throw (MEDEXCEPTION); - * (+) vector<string> getProfilNames() const throw (MEDEXCEPTION); - * - * (+) void getBoundaryElements() throw (MEDEXCEPTION); - * - * (+) void changeElementsNbs(MED_EN::medEntityMesh entity, const int *renumberingFromOldToNew, - * int limitNbClassicPoly, const int *renumberingFromOldToNewPoly=0); - * (+) void intersecting(SUPPORT * mySupport) throw (MEDEXCEPTION); - * (+) bool belongsTo(const SUPPORT& other, bool deepCompare=false) const; - * - * (+) SUPPORT *getComplement() const; - * (+) SUPPORT *substract(const SUPPORT& other) const throw (MEDEXCEPTION); - * - * (+) SUPPORT *getBoundaryElements(MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION); - * - * (+) void fillFromNodeList(const list<int>& listOfNode) throw (MEDEXCEPTION); - * (+) void fillFromElementList(const list<int>& listOfElt) throw (MEDEXCEPTION); - * - * (+) void clearDataOnNumbers(); - * - * (reference counter presently disconnected in C++) virtual void addReference() const; - * (reference counter presently disconnected in C++) virtual void removeReference() const; - * } - */ -void MEDMEMTest_testSupport() -{ - // cells connectivities - //const int NumberOfCellTypes = 3; - //MED_EN::medGeometryElement CellTypes[NumberOfCellTypes] = - // {MED_EN::MED_TETRA4, MED_EN::MED_PYRA5, MED_EN::MED_HEXA8}; - //const int NumberOfCells[NumberOfCellTypes] = {12, 2, 2}; - - // faces connectivities - //const int NumberOfFaceTypes = 2; - //MED_EN::medGeometryElement FaceTypes[NumberOfFaceTypes] = {MED_EN::MED_TRIA3, MED_EN::MED_QUAD4}; - //const int NumberOfFaces[NumberOfFaceTypes] = {4, 4}; - - MESH * aMesh = MEDMEMTest_createTestMesh(); - MESH * aMeshOneMore = MEDMEMTest_createTestMesh(); - - //////////// - // TEST 1 // - //////////// - - SUPPORT aSupportOnFaces1 (aMesh, "Support On Faces 1", MED_EN::MED_FACE); - SUPPORT aSupportOnCells1 (aMesh, "Support On Cells 1"/*, MED_EN::MED_CELL*/); - - SUPPORT aSupportOnFaces2; - SUPPORT aSupportOnCells2; - - SUPPORT aSupportOnFaces3 (aMeshOneMore, "Support On Faces 3", MED_EN::MED_FACE); - - // entity - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aSupportOnFaces1.getEntity()); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_CELL, aSupportOnCells1.getEntity()); - - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_CELL, aSupportOnFaces2.getEntity()); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_CELL, aSupportOnCells2.getEntity()); - - aSupportOnFaces2.setEntity(MED_EN::MED_FACE); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aSupportOnFaces2.getEntity()); - - // isOnAllElements - CPPUNIT_ASSERT(aSupportOnFaces1.isOnAllElements()); - CPPUNIT_ASSERT(aSupportOnCells1.isOnAllElements()); - - CPPUNIT_ASSERT(!aSupportOnFaces2.isOnAllElements()); - CPPUNIT_ASSERT(!aSupportOnCells2.isOnAllElements()); - - // mesh and mesh name - CPPUNIT_ASSERT_THROW(aSupportOnFaces1.setMeshName("Mesh 1"), MEDEXCEPTION); - - aSupportOnFaces2.setMeshName("Mesh 1"); - aSupportOnCells2.setMeshName("Mesh 1"); - CPPUNIT_ASSERT(aSupportOnFaces2.getMeshName() == "Mesh 1"); - CPPUNIT_ASSERT(aSupportOnCells2.getMeshName() == "Mesh 1"); - - aSupportOnFaces2.setMesh(aMesh); - CPPUNIT_ASSERT_THROW(aSupportOnFaces2.setMeshName("Mesh 1"), MEDEXCEPTION); - - aSupportOnCells1.setMesh(NULL); - aSupportOnCells1.setMeshName("Mesh 1"); - - CPPUNIT_ASSERT(aSupportOnFaces1.getMeshName() == "meshing"); - CPPUNIT_ASSERT(aSupportOnFaces2.getMeshName() == "meshing"); - CPPUNIT_ASSERT(aSupportOnCells1.getMeshName() == "Mesh 1"); - CPPUNIT_ASSERT(aSupportOnCells2.getMeshName() == "Mesh 1"); - - CPPUNIT_ASSERT(aSupportOnFaces1.getMesh() == aMesh); - CPPUNIT_ASSERT(aSupportOnFaces2.getMesh() == aMesh); - CPPUNIT_ASSERT(aSupportOnCells1.getMesh() == NULL); - CPPUNIT_ASSERT(aSupportOnCells2.getMesh() == NULL); - - // operator == - aSupportOnFaces2.setName("Support On Faces 2"); - aSupportOnCells2.setName("Support On Cells 2"); - - // because aSupportOnFaces1 is on all elements, but aSupportOnFaces2 not - CPPUNIT_ASSERT(!(aSupportOnFaces1 == aSupportOnFaces2)); - - aSupportOnCells1.setAll(false); - CPPUNIT_ASSERT(!aSupportOnCells1.isOnAllElements()); - // this is only sets flag _isOnAllElts to false, but not clear elements and types - // information, so aSupportOnCells1 is not equal to aSupportOnCells2 at this moment - -#ifdef ENABLE_FAULTS - // (BUG) SUPPORT::operator= gives "Segmentation Fault" on supports with NULL meshes!!! - CPPUNIT_ASSERT(!(aSupportOnCells1 == aSupportOnCells2)); -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("SUPPORT::operator= gives Segmentation Fault on supports with NULL meshes!!!"); -#endif - - aSupportOnFaces2.setAll(true); - CPPUNIT_ASSERT(aSupportOnFaces2.isOnAllElements()); - // flag _isOnAllElts now is set to true, but we need also to call update() - // to set elements and types information from mesh to this support - CPPUNIT_ASSERT(!(aSupportOnFaces1 == aSupportOnFaces2)); - aSupportOnFaces2.update(); - CPPUNIT_ASSERT(aSupportOnFaces1 == aSupportOnFaces2); - - // deep compare - CPPUNIT_ASSERT(aSupportOnFaces1.deepCompare(aSupportOnFaces2)); - - CPPUNIT_ASSERT(!(aSupportOnFaces1 == aSupportOnFaces3)); // different mesh pointers - CPPUNIT_ASSERT(aSupportOnFaces1.deepCompare(aSupportOnFaces3)); // meshes are really equal - - // description - aSupportOnFaces1.setDescription("Support on all faces with mesh pointer"); - aSupportOnFaces2.setDescription("Support on all faces with mesh pointer"); - - aSupportOnCells1.setDescription("Support on a part of cells with mesh name"); - aSupportOnCells2.setDescription("Support on a part of cells with mesh name"); - - CPPUNIT_ASSERT(aSupportOnFaces1.getDescription() == "Support on all faces with mesh pointer"); - CPPUNIT_ASSERT(aSupportOnFaces2.getDescription() == "Support on all faces with mesh pointer"); - CPPUNIT_ASSERT(aSupportOnCells1.getDescription() == "Support on a part of cells with mesh name"); - CPPUNIT_ASSERT(aSupportOnCells2.getDescription() == "Support on a part of cells with mesh name"); - - // operator<< - ostringstream ostr1; - ostr1 << aSupportOnFaces1; - CPPUNIT_ASSERT(ostr1.str() != ""); - - ostringstream ostr2; - ostr2 << aSupportOnCells2; - CPPUNIT_ASSERT(ostr2.str() != ""); - - // set/get elements and types information - - // 1. aSupportOnCells1 is not on all elements, but now it contains information - // about all cells of aMesh, because it was created on mesh and with parameters. - CPPUNIT_ASSERT_EQUAL(3, aSupportOnCells1.getNumberOfTypes()); - CPPUNIT_ASSERT(aSupportOnCells1.getTypes() != NULL); - - //const int * nbEltsSC_old = aSupportOnCells1.getNumberOfElements(); // {12, 2, 2} - - aSupportOnCells1.setNumberOfGeometricType(0); - CPPUNIT_ASSERT_EQUAL(0, aSupportOnCells1.getNumberOfTypes()); - CPPUNIT_ASSERT(aSupportOnCells1.getTypes() == NULL); - - MED_EN::medGeometryElement aSCTypes[2] = {MED_EN::MED_PYRA5, MED_EN::MED_PENTA15}; - aSupportOnCells1.setNumberOfGeometricType(2); - aSupportOnCells1.setGeometricType(aSCTypes); - - CPPUNIT_ASSERT_EQUAL(2, aSupportOnCells1.getNumberOfTypes()); - CPPUNIT_ASSERT(aSupportOnCells1.getTypes() != NULL); - CPPUNIT_ASSERT(aSupportOnCells1.getNumberOfElements() == NULL); // reset by setNumberOfGeometricType - - int nbEltsSC[2] = {2, 1}; - aSupportOnCells1.setNumberOfElements(nbEltsSC); - - const int * nbEltsSCBack = aSupportOnCells1.getNumberOfElements(); - CPPUNIT_ASSERT_EQUAL(2, aSupportOnCells1.getNumberOfElements(MED_EN::MED_PYRA5)); - CPPUNIT_ASSERT_EQUAL(2, nbEltsSCBack[0]); - CPPUNIT_ASSERT_EQUAL(1, aSupportOnCells1.getNumberOfElements(MED_EN::MED_PENTA15)); - CPPUNIT_ASSERT_EQUAL(1, nbEltsSCBack[1]); - CPPUNIT_ASSERT_EQUAL(3, aSupportOnCells1.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - - // old types - CPPUNIT_ASSERT_THROW(aSupportOnCells1.getNumberOfElements(MED_EN::MED_TETRA4), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSupportOnCells1.getNumberOfElements(MED_EN::MED_HEXA8), MEDEXCEPTION); - - //_number= new MEDSKYLINEARRAY(_numberOfGeometricType,_totalNumberOfElements,index,value,shallowCopy); - int indexSC[3] = {1,3,4}; // length = nb.types + 1 - int valueSC[3] = {21,22,47}; // length = total nb. of elements - aSupportOnCells1.setNumber(indexSC, valueSC); - - // check number - MEDSKYLINEARRAY * aNumberSCBack = aSupportOnCells1.getnumber(); - - CPPUNIT_ASSERT_EQUAL(2, aNumberSCBack->getNumberOf()); - CPPUNIT_ASSERT_EQUAL(3, aNumberSCBack->getLength()); - const int * ind = aNumberSCBack->getIndex(); - const int * val = aNumberSCBack->getValue(); - CPPUNIT_ASSERT_EQUAL(1, ind[0]); - CPPUNIT_ASSERT_EQUAL(3, ind[1]); - CPPUNIT_ASSERT_EQUAL(4, ind[2]); - CPPUNIT_ASSERT_EQUAL(21, val[0]); - CPPUNIT_ASSERT_EQUAL(22, val[1]); - CPPUNIT_ASSERT_EQUAL(47, val[2]); - - // 2. aSupportOnCells2 is not on all elements, and now it contains - // no information about elements of a mesh - CPPUNIT_ASSERT_EQUAL(0, aSupportOnCells2.getNumberOfTypes()); - CPPUNIT_ASSERT(aSupportOnCells2.getTypes() == NULL); - - aSupportOnCells2.setNumberOfGeometricType(2); - aSupportOnCells2.setGeometricType(aSCTypes); - - CPPUNIT_ASSERT_EQUAL(2, aSupportOnCells2.getNumberOfTypes()); - CPPUNIT_ASSERT(aSupportOnCells2.getTypes() != NULL); - - aSupportOnCells2.setNumberOfElements(nbEltsSC); - - // we create MEDSKYLINEARRAY as pointer, because aSupportOnCells2 will - // become an owner of it, and we must not delete it. - MEDSKYLINEARRAY * aNumberSC = new MEDSKYLINEARRAY(2, 3, indexSC, valueSC); - aSupportOnCells2.setNumber(aNumberSC); - - // check number - const int * aNumberIndexSC = aSupportOnCells2.getNumberIndex(); - CPPUNIT_ASSERT_EQUAL(1, aNumberIndexSC[0]); - CPPUNIT_ASSERT_EQUAL(3, aNumberIndexSC[1]); - CPPUNIT_ASSERT_EQUAL(4, aNumberIndexSC[2]); - - const int * aNbPYRA5 = aSupportOnCells2.getNumber(MED_EN::MED_PYRA5); - const int * aNbPENTA15 = aSupportOnCells2.getNumber(MED_EN::MED_PENTA15); - CPPUNIT_ASSERT_THROW(aSupportOnCells2.getNumber(MED_EN::MED_TETRA4), MEDEXCEPTION); - - const int * aNbC = aSupportOnCells2.getNumber(MED_EN::MED_ALL_ELEMENTS); - - CPPUNIT_ASSERT_EQUAL(21, aNbPYRA5[0]); - CPPUNIT_ASSERT_EQUAL(22, aNbPYRA5[1]); - CPPUNIT_ASSERT_EQUAL(47, aNbPENTA15[0]); - - CPPUNIT_ASSERT_EQUAL(21, aNbC[0]); - CPPUNIT_ASSERT_EQUAL(22, aNbC[1]); - CPPUNIT_ASSERT_EQUAL(47, aNbC[2]); - - // getValIndFromGlobalNumber - CPPUNIT_ASSERT_EQUAL(1, aSupportOnCells2.getValIndFromGlobalNumber(21)); - CPPUNIT_ASSERT_EQUAL(2, aSupportOnCells2.getValIndFromGlobalNumber(22)); - CPPUNIT_ASSERT_EQUAL(3, aSupportOnCells2.getValIndFromGlobalNumber(47)); - // not existing element - CPPUNIT_ASSERT_THROW(aSupportOnCells2.getValIndFromGlobalNumber(10), MEDEXCEPTION); - - // compare aSupportOnCells1 and aSupportOnCells2 - - // temporary set mesh (because of bug with operator==) - aSupportOnCells1.setMesh(aMesh); - aSupportOnCells2.setMesh(aMesh); - - CPPUNIT_ASSERT_EQUAL(aSupportOnCells1, aSupportOnCells2); - - // restore mesh name - aSupportOnCells1.setMesh(NULL); - aSupportOnCells2.setMesh(NULL); - aSupportOnCells1.setMeshName("Mesh 1"); - aSupportOnCells2.setMeshName("Mesh 1"); - - // 3. aSupportOnFacesN is on all elements, and it contains - // information about all faces of aMesh - CPPUNIT_ASSERT_EQUAL(2, aSupportOnFaces1.getNumberOfTypes()); - const MED_EN::medGeometryElement* aSF1Types = aSupportOnFaces1.getTypes(); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_TRIA3, aSF1Types[0]); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_QUAD4, aSF1Types[1]); -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Comment to method SUPPORT::getTypes() says: - // "If isOnAllElements is false, returns an array of %medGeometryElement types used by the support." - // But in fact it returns types in any case (comment to SUPPORT::setAll() gives more information). - CPPUNIT_FAIL("Comment and implementation does not match for SUPPORT::getTypes()"); - // This concerns also method SUPPORT::update(), being called from constructor, - // which fills internal SUPPORT structures with information about mesh elements - // in case of isOnAllElements == true. - // Also comments and implementation does not match for SUPPORT::getNumberOfElements(). - // It seems that in case "isOnAllElements == true" calls like getNumberOfElements() - // must be redirected to mesh, but what if mesh is not set (mesh name used instead)?. -#endif - const int * nbEltsSF1 = aSupportOnFaces1.getNumberOfElements(); - CPPUNIT_ASSERT_EQUAL(4, aSupportOnFaces1.getNumberOfElements(MED_EN::MED_TRIA3)); - CPPUNIT_ASSERT_EQUAL(4, nbEltsSF1[0]); - CPPUNIT_ASSERT_EQUAL(4, aSupportOnFaces1.getNumberOfElements(MED_EN::MED_QUAD4)); - CPPUNIT_ASSERT_EQUAL(4, nbEltsSF1[1]); - CPPUNIT_ASSERT_EQUAL(8, aSupportOnFaces1.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumberOfElements(MED_EN::MED_TRIA6), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumberOfElements(MED_EN::MED_QUAD8), MEDEXCEPTION); - - // check number - CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumberIndex(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumber(MED_EN::MED_TRIA3), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumber(MED_EN::MED_QUAD4), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumber(MED_EN::MED_ALL_ELEMENTS), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getnumber(), MEDEXCEPTION); - - // getValIndFromGlobalNumber - CPPUNIT_ASSERT_EQUAL(8, aMesh->getNumberOfElements(MED_EN::MED_FACE, MED_EN::MED_ALL_ELEMENTS)); - for (int i = 1; i <= 8; i++) { - CPPUNIT_ASSERT_EQUAL(i, aSupportOnFaces1.getValIndFromGlobalNumber(i)); - } - -#ifdef ENABLE_FORCED_FAILURES - // Why methods setNumber do not throw exception in case "isOnAllElements == true", - // like methods getNumber do? - //CPPUNIT_ASSERT_THROW(aSupportOnFaces1.setNumber(indexSF1, valueSF1)); -#endif - -#ifdef ENABLE_FORCED_FAILURES - // It seems to be dangerous and useless to have method SUPPORT::setTotalNumberOfElements() - //CPPUNIT_FAIL("It seems to be dangerous and useless to have method SUPPORT::setTotalNumberOfElements()"); -#endif - // setTotalNumberOfElements - aSupportOnFaces1.setTotalNumberOfElements(1000); - CPPUNIT_ASSERT_EQUAL(1000, aSupportOnFaces1.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - - // clearDataOnNumbers - aSupportOnCells1.clearDataOnNumbers(); - CPPUNIT_ASSERT_EQUAL(0, aSupportOnCells1.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - CPPUNIT_ASSERT_EQUAL(0, aSupportOnCells1.getNumberOfTypes()); - CPPUNIT_ASSERT_THROW(aSupportOnCells1.getnumber(), MEDEXCEPTION); - - //////////// - // TEST 2 // - //////////// - - list<int> nodes137; - nodes137.push_back(1); - nodes137.push_back(3); - nodes137.push_back(7); - - list<int> nodes248; - nodes248.push_back(2); - nodes248.push_back(4); - nodes248.push_back(8); - - list<int> nodes27; - nodes27.push_back(2); - nodes27.push_back(7); - - SUPPORT aNodes137 (aMesh, "Support On Nodes 1,3,7", MED_EN::MED_CELL); - SUPPORT aNodes248 (aMesh, "Support On Nodes 2,4,8", MED_EN::MED_CELL); - SUPPORT aNodes27 (aMesh, "Support On Nodes 2,7" , MED_EN::MED_CELL); - - aNodes137.fillFromNodeList(nodes137); - aNodes248.fillFromNodeList(nodes248); - aNodes27.fillFromNodeList(nodes27); - - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_NODE, aNodes137.getEntity()); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_NODE, aNodes248.getEntity()); - - list<int>::const_iterator iter137 = nodes137.begin(); - list<int>::const_iterator iter248 = nodes248.begin(); - for (int i = 1; i <= 3; i++, iter137++, iter248++) { - CPPUNIT_ASSERT_EQUAL(i, aNodes137.getValIndFromGlobalNumber(*iter137)); - CPPUNIT_ASSERT_EQUAL(i, aNodes248.getValIndFromGlobalNumber(*iter248)); - } - - //////////// - - list<int> faces123; - faces123.push_back(1); - faces123.push_back(2); - faces123.push_back(3); - - list<int> faces135; - faces135.push_back(1); - faces135.push_back(3); - faces135.push_back(5); - - SUPPORT aFaces123 (aMesh, "Support On Faces 1,2,3", MED_EN::MED_FACE); - SUPPORT aFaces135 (aMesh, "Support On Faces 1,3,5", MED_EN::MED_FACE); - - aFaces123.fillFromElementList(faces123); - aFaces135.fillFromElementList(faces135); - - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces123.getEntity()); - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces135.getEntity()); - - list<int>::const_iterator iter123 = faces123.begin(); - list<int>::const_iterator iter135 = faces135.begin(); - for (int i = 1; i <= 3; i++, iter123++, iter135++) { - CPPUNIT_ASSERT_EQUAL(i, aFaces123.getValIndFromGlobalNumber(*iter123)); - CPPUNIT_ASSERT_EQUAL(i, aFaces135.getValIndFromGlobalNumber(*iter135)); - } - - // substract - SUPPORT * aFaces2 = aFaces123.substract(aFaces135); // => 2 - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces2->getEntity()); - CPPUNIT_ASSERT_EQUAL(1, aFaces2->getValIndFromGlobalNumber(2)); - CPPUNIT_ASSERT_EQUAL(1, aFaces2->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - - CPPUNIT_ASSERT_THROW(aFaces123.substract(aNodes137), MEDEXCEPTION); - -#ifdef ENABLE_FORCED_FAILURES - // (BUG) SUPPORT::substract() does not work with supports on nodes, - // because it uses method MESH::buildSupportOnNodeFromElementList(), - // which does not work if entity = MED_NODE - //SUPPORT * aNodes137mesh = aMesh->buildSupportOnNodeFromElementList(nodes137, MED_EN::MED_NODE); - //delete aNodes137mesh; - SUPPORT * aNodes137sub = aNodes137.substract(aNodes248); // => 1,3,7 - CPPUNIT_ASSERT_EQUAL(*aNodes137sub, aNodes137); - delete aNodes137sub; -#endif - - // belongsTo - CPPUNIT_ASSERT(aFaces2->belongsTo(aFaces123)); - CPPUNIT_ASSERT(!aFaces2->belongsTo(aFaces135)); - - CPPUNIT_ASSERT(!aFaces2->belongsTo(aSupportOnFaces3)); - CPPUNIT_ASSERT(aFaces2->belongsTo(aSupportOnFaces3, /*deepCompare*/true)); - - delete aFaces2; - - // getComplement - SUPPORT * aFaces_135 = aFaces135.getComplement(); // => 2,4,6,7,8 - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces_135->getEntity()); - CPPUNIT_ASSERT_EQUAL(5, aFaces_135->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Memory problem in SUPPORT::sub() - // Invalid read of size 4 - // at 0x34902492: MEDMEM::SUPPORT::sub(int, int, int const*, int) (MEDMEM_Support.cxx:852) - // by 0x3490296B: MEDMEM::SUPPORT::getComplement() const (MEDMEM_Support.cxx:916) - // by 0x34398F1E: MEDMEMTest::testSupport() (MEDMEMTest_Support.cxx:514) - // Address 0x352DB91C is 0 bytes after a block of size 12 alloc'd - // at 0x3414C8E2: operator new[](unsigned) (vg_replace_malloc.c:138) - // by 0x3490243A: MEDMEM::SUPPORT::sub(int, int, int const*, int) (MEDMEM_Support.cxx:847) - // by 0x3490296B: MEDMEM::SUPPORT::getComplement() const (MEDMEM_Support.cxx:916) - // by 0x34398F1E: MEDMEMTest::testSupport() (MEDMEMTest_Support.cxx:514) - CPPUNIT_FAIL("Memory problem in SUPPORT::sub(): Invalid read of size 4 from array <temp>"); -#endif - -#ifdef ENABLE_FORCED_FAILURES - // (BUG) SUPPORT::getComplement() does not work with support on nodes, - // because it uses method MESH::buildSupportOnNodeFromElementList(), - // which does not work if entity = MED_NODE - SUPPORT * aNodes_137 = aNodes137.getComplement(); // => 2,4,5,6,8,9,10-19 - CPPUNIT_ASSERT_EQUAL(MED_EN::MED_NODE, aNodes_137->getEntity()); - CPPUNIT_ASSERT_EQUAL(16, aNodes_137->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); -#endif - - // intersecting - aFaces_135->intersecting(&aFaces123); // => 2 - CPPUNIT_ASSERT_EQUAL(1, aFaces_135->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - CPPUNIT_ASSERT_EQUAL(1, aFaces_135->getValIndFromGlobalNumber(2)); - - //aNodes_137->intersecting(&aNodes248); // => 2,4,8 - //CPPUNIT_ASSERT_EQUAL(3, aNodes_137->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - //CPPUNIT_ASSERT_EQUAL(*aNodes_137, aNodes248); - aNodes137.intersecting(&aNodes248); // => {} - CPPUNIT_ASSERT_EQUAL(0, aNodes137.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - - // blending - aFaces_135->blending(&aFaces135); // => 1,2,3,5 - CPPUNIT_ASSERT_EQUAL(4, aFaces_135->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - - aNodes248.blending(&aNodes27); // => 2,4,7,8 - CPPUNIT_ASSERT_EQUAL(4, aNodes248.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); - - // operator= - SUPPORT aCopy1; - aCopy1 = aNodes248; - CPPUNIT_ASSERT_EQUAL(aNodes248, aCopy1); - - // copy constructor - SUPPORT aCopy2 (aFaces135); - CPPUNIT_ASSERT_EQUAL(aFaces135, aCopy2); - - delete aFaces_135; -#ifdef ENABLE_FORCED_FAILURES - delete aNodes_137; -#endif - - // profil names - vector<string> aPrN2 (2); // nb. types - aPrN2[0] = "Profil 1"; - aPrN2[1] = "Profil 2"; - aFaces135.setProfilNames(aPrN2); - - // because on all elements - CPPUNIT_ASSERT_THROW(aSupportOnFaces3.setProfilNames(aPrN2), MEDEXCEPTION); - - // because length of vector is not equal to nb.types - vector<string> aPrN3 (3); - CPPUNIT_ASSERT_THROW(aFaces135.setProfilNames(aPrN3), MEDEXCEPTION); - - vector<string> aPrN2Back = aFaces135.getProfilNames(); - CPPUNIT_ASSERT_EQUAL(aPrN2[0], aPrN2Back[0]); - CPPUNIT_ASSERT_EQUAL(aPrN2[1], aPrN2Back[1]); - -#ifdef ENABLE_FORCED_FAILURES - // (BUG) profil names are not copied by copy constructor and operator=, - // not compared by operator==, not dumped in stream by operator<< - //CPPUNIT_FAIL("Not complete implementation for Profil Names"); -#endif - - //////////// - // TEST 3 // - //////////// - - SUPPORT aPartialCells (aMesh, "Support On Cells 2,3,4", MED_EN::MED_CELL); - SUPPORT aPartialNodes (aMesh, "Support On Nodes 2,3,4", MED_EN::MED_NODE); - - // setpartial - MED_EN::medGeometryElement gtCells[1] = {MED_EN::MED_TETRA4}; - int nbCells[1] = {3}; - int cells[3] = {2,3,4}; - aPartialCells.setpartial("with description", 1, 3, gtCells, nbCells, cells); - CPPUNIT_ASSERT_EQUAL(1, aPartialCells.getValIndFromGlobalNumber(2)); - CPPUNIT_ASSERT_EQUAL(2, aPartialCells.getValIndFromGlobalNumber(3)); - CPPUNIT_ASSERT_EQUAL(3, aPartialCells.getValIndFromGlobalNumber(4)); - - MED_EN::medGeometryElement gtNodes[1] = {MED_EN::MED_NONE}; - aPartialNodes.setNumberOfGeometricType(1); - aPartialNodes.setGeometricType(gtNodes); - int indexSN[2] = {1,4}; - int valueSN[3] = {2,3,4}; - MEDSKYLINEARRAY * aNumberSN = new MEDSKYLINEARRAY(1, 3, indexSN, valueSN); - aPartialNodes.setpartial(aNumberSN, /*shallowCopy*/false); - delete aNumberSN; - CPPUNIT_ASSERT_EQUAL(1, aPartialNodes.getValIndFromGlobalNumber(2)); - CPPUNIT_ASSERT_EQUAL(2, aPartialNodes.getValIndFromGlobalNumber(3)); - CPPUNIT_ASSERT_EQUAL(3, aPartialNodes.getValIndFromGlobalNumber(4)); - - // changeElementsNbs - - // {1,2,3,4,5,6,7,8,9,10} -> {10,9,8,7,6,5,4,3,2,1} - int renumberingFromOldToNew[10] = {10,9,8,7,6,5,4,3,2,1}; - - CPPUNIT_ASSERT_THROW(aPartialCells.changeElementsNbs - (MED_EN::MED_NODE, renumberingFromOldToNew, 10), MEDEXCEPTION); - - aPartialCells.changeElementsNbs(MED_EN::MED_CELL, renumberingFromOldToNew, 10); - CPPUNIT_ASSERT_EQUAL(3, aPartialCells.getValIndFromGlobalNumber(9)); - CPPUNIT_ASSERT_EQUAL(2, aPartialCells.getValIndFromGlobalNumber(8)); - CPPUNIT_ASSERT_EQUAL(1, aPartialCells.getValIndFromGlobalNumber(7)); - - // {1,2,3,4,5,6,7} -> {1,3,5,7,2,4,6}, {8,9,10,11} -> {8,10,9,11} - int renumberingFromOldToNewP[7] = {1,3,5,7,2,4,6}; - int renumberingFromOldToNewPolyP[4] = {8,10,9,11}; - aPartialCells.changeElementsNbs(MED_EN::MED_CELL, renumberingFromOldToNewP, - 7, renumberingFromOldToNewPolyP); - CPPUNIT_ASSERT_EQUAL(3, aPartialCells.getValIndFromGlobalNumber(10)); - CPPUNIT_ASSERT_EQUAL(2, aPartialCells.getValIndFromGlobalNumber(8)); - CPPUNIT_ASSERT_EQUAL(1, aPartialCells.getValIndFromGlobalNumber(6)); - - // this method does not suit for nodes renumbering! - // {1,2,3} -> {3,2,1}, {4,5,6,7} -> {5,6,7,4} - //int renumberingFromOldToNewN[3] = {3,2,1}; - //int renumberingFromOldToNewPolyN[4] = {5,6,7,4}; - //aPartialNodes.changeElementsNbs(MED_EN::MED_NODE, renumberingFromOldToNewN, - // 3, renumberingFromOldToNewPolyN); - - // getBoundaryElements -#ifdef ENABLE_FAULTS - // (BUG) Segmentation Fault during SUPPORT::getBoundaryElements() - // ??? May be mesh is not complete ??? - SUPPORT aBoundaryFaces (aMesh, "meshing boundary faces", MED_EN::MED_FACE); - aBoundaryFaces.getBoundaryElements(); - //cout << "aBoundaryFaces:" << endl; - //cout << aBoundaryFaces << endl; - - SUPPORT * aBoundaryNodes = aSupportOnFaces3.getBoundaryElements(MED_EN::MED_NODE); - //cout << "aSupportOnFaces3:" << endl; - //cout << aSupportOnFaces3 << endl; - //cout << "aBoundaryNodes:" << endl; - //cout << aBoundaryNodes << endl; - delete aBoundaryNodes; -#endif -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_FAIL("Segmentation Fault during SUPPORT::getBoundaryElements()"); - // Invalid write of size 4 - // at 0x3439DFCE: void std::_Construct<int, int>(int*, int const&) (stl_construct.h:81) - // by 0x3476E4D1: std::vector<int, std::allocator<int> >::push_back(int const&) (stl_vector.h:560) - // by 0x34763DDB: MEDMEM::CONNECTIVITY::calculateReverseNodalConnectivity() (MEDMEM_Connectivity.cxx:1155) - // by 0x347655FF: MEDMEM::CONNECTIVITY::calculateDescendingConnectivity() (MEDMEM_Connectivity.cxx:1333) - // by 0x3476363E: MEDMEM::CONNECTIVITY::getReverseDescendingConnectivity() (MEDMEM_Connectivity.cxx:1090) - // by 0x34772AB6: MEDMEM::CONNECTIVITY::getReverseConnectivity(long, long) (MEDMEM_Connectivity.hxx:503) - // by 0x348F4F4B: MEDMEM::MESH::getReverseConnectivity(long, long) const (MEDMEM_Mesh.hxx:848) - // by 0x348FF559: MEDMEM::SUPPORT::getBoundaryElements() (MEDMEM_Support.cxx:483) - // by 0x3439C8E5: MEDMEMTest::testSupport() (MEDMEMTest_Support.cxx:641) - // Address 0x61666A2F is not stack'd, malloc'd or (recently) free'd -#endif - - delete aMesh; - delete aMeshOneMore; -} - -int main (int argc, char** argv) -{ - MEDMEMTest_testSupport(); -} diff --git a/src/MEDMEM/Test/MEDMEMTest_TopLevel.cxx b/src/MEDMEM/Test/MEDMEMTest_TopLevel.cxx deleted file mode 100644 index 8f81511a4..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_TopLevel.cxx +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include <MEDMEM_TopLevel.hxx> -#include <MEDMEM_MedFieldDriver22.hxx> -#include <MEDMEM_Field.hxx> -#include <MEDMEM_Med.hxx> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -/*! - * Check methods (6), defined in MEDMEM_TopLevel.hxx: - * (+) MED *readMedInFile(const std::string& fileName) throw(MEDEXCEPTION); - * (+) MESH *readMeshInFile(const std::string& fileName, const std::string& meshName); - * (+) template<class T> FIELD<T> *readFieldInFile - * (const std::string& fileName, const std::string& fieldName); - * (+) void writeMedToFile(const MED *medObj, const std::string& fileName); - * (+) void writeMeshToFile(const MESH *meshObj, const std::string& fileName); - * (-) template<class T> void writeFieldToFile(const FIELD<T> *fieldObj, const std::string& fileName); - */ -void MEDMEMTest::testTopLevel() -{ - MED * aMed = NULL; - - string data_dir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - if (tmp_dir == "") - tmp_dir = "/tmp"; - - string filename_rd = data_dir + "/MedFiles/pointe.med"; - string filename22_rd = data_dir + "/MedFiles/pointe_import22.med"; - string filenameMesh_wr = tmp_dir + "/myMesh.med"; - string filenameMed_wr = tmp_dir + "/myMed.med"; - string filenameField_wr = tmp_dir + "/myField.med"; - string fileNotExist_rd = "/notExist.med"; - string fileNotExist_wr = "/path_not_exist/file_not_exist.med"; - string meshname = "maa1"; - string meshname_not_exist = "anymesh"; - string fieldname_not_exist = "anyfield"; - string fieldname = "fieldnodedouble"; - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filenameMesh_wr); - aRemover.Register(filenameMed_wr); - aRemover.Register(filenameField_wr); - - /////////////////// - //Test Read Part // - /////////////////// - { - //Trying read from not existing file -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_THROW(readMedInFile(fileNotExist_rd), MEDEXCEPTION); - // (BUG) No exception in this case -#endif - CPPUNIT_ASSERT_THROW(readMeshInFile(fileNotExist_rd, meshname), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(readFieldInFile<double>(fileNotExist_rd, fieldname), MEDEXCEPTION); - - //Trying read not existing mesh from file - CPPUNIT_ASSERT_THROW(readMeshInFile(filename_rd, meshname_not_exist), MEDEXCEPTION); - - //Trying read not existing field from file - CPPUNIT_ASSERT_THROW(readFieldInFile<double>(filename22_rd, fieldname_not_exist), MEDEXCEPTION); - - //Test readMeshInFile() method -#ifdef ENABLE_FORCED_FAILURES - { - MESH * aMesh = NULL; - //MEDEXCEPTION: can not open file, but file exist - CPPUNIT_ASSERT_NO_THROW(aMesh = readMeshInFile(filename_rd, meshname)); - CPPUNIT_ASSERT(aMesh); - delete aMesh; - } -#endif - - //Test readMedInFile() method - { - CPPUNIT_ASSERT_NO_THROW(aMed = readMedInFile(filename_rd)); - CPPUNIT_ASSERT(aMed); - } - - //Test readFieldInFile() method -#ifdef ENABLE_FORCED_FAILURES - { - FIELD<double> * aField = NULL; - //MEDEXCEPTION: can not open file, but file exist - CPPUNIT_ASSERT_NO_THROW(aField = readFieldInFile<double>(filename22_rd, fieldname)); - CPPUNIT_ASSERT(aField); - delete aField; - } -#endif - } - - //////////////////// - //Test Write Part // - //////////////////// - { - //Create a FIELD - FIELD<double> *aField_1 = new FIELD<double> (); - - MED_FIELD_RDONLY_DRIVER22<double> *aMedRdFieldDriver22 = - new MED_FIELD_RDONLY_DRIVER22<double>(filename22_rd, aField_1); - aMedRdFieldDriver22->setFieldName(fieldname); - aMedRdFieldDriver22->open(); - aMedRdFieldDriver22->read(); - aMedRdFieldDriver22->close(); - - //Trying write objects in the not existing file -#ifdef ENABLE_FORCED_FAILURES - // (BUG) No exception in this case - CPPUNIT_ASSERT_THROW(writeMedToFile(aMed, fileNotExist_wr), MEDEXCEPTION); -#endif - - //Create a MESH - MESH * aMesh = MEDMEMTest_createTestMesh(); - CPPUNIT_ASSERT_THROW(writeMeshToFile(aMesh, fileNotExist_wr), MEDEXCEPTION); - -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Error during compilation - //MED_SRC/src/MEDMEM/MEDMEM_TopLevel.hxx:66: error: passing `const MEDMEM::FIELD<double, MEDMEM::FullInterlace>' as `this' argument of `int MEDMEM::FIELD<T, INTERLACING_TAG>::addDriver(MEDMEM::driverTypes, const std::string&, const std::string&, MED_EN::med_mode_acces) [with T = double, INTERLACING_TAG = MEDMEM::FullInterlace]' discards qualifiers CPPUNIT_ASSERT_THROW(writeFieldToFile<double>(aField_1, fileNotExist_wr),MEDEXCEPTION); - CPPUNIT_FAIL("writeFieldToFile(): compilation error"); -#endif - - //Trying write mesh in the file with empty name - aMesh->setName(""); - CPPUNIT_ASSERT_THROW(writeMeshToFile(aMesh, filenameField_wr), MEDEXCEPTION); - - //Test writeMedToFile() and writeMeshToFile() methods - aMesh->setName(meshname); - CPPUNIT_ASSERT_NO_THROW(writeMeshToFile(aMesh, filenameMesh_wr)); - CPPUNIT_ASSERT_NO_THROW(writeMedToFile(aMed, filenameMed_wr)); - - delete aField_1; - delete aMesh; - delete aMed; - } -} diff --git a/src/MEDMEM/Test/MEDMEMTest_Unit.cxx b/src/MEDMEM/Test/MEDMEMTest_Unit.cxx deleted file mode 100644 index 1d83ea282..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_Unit.cxx +++ /dev/null @@ -1,353 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" -#include <cppunit/Message.h> -#include <cppunit/TestAssert.h> - -#include <cstdlib> -#include <exception> - -#include <MEDMEM_Unit.hxx> - -using namespace std; -using namespace MEDMEM; - - -/*! - * Check methods (18), defined in MEDMEM_Unit.hxx: - * class UNIT { - * (+) UNIT(); - * (+) UNIT(string Name, string Description); - * (+) ~UNIT(); - * (+) UNIT & operator=(const UNIT &unit); - * (+) inline void setName(string Name); - * (+) inline void setDescription(string Description); - * (+) inline void setMasse(int Masse); - * (+) inline void setLength(int Length); - * (+) inline void setTime(int Time); - * (+) inline void setTemperature(int Temperature); - * (+) inline void setMatterQuantity(int MatterQuantity); - * (+) void setCurrentStrength(int CurrentStrength); - * (+) inline void setLightIntensity(int LightIntensity); - * - * (+) inline string getName() const; - * (+) inline string getDescription() const; - * (+) inline int getMasse() const; - * (+) inline int getLength() const; - * (+) inline int getTime() const; - * (+) inline int getTemperature() const; - * (+) inline int getMatterQuantity() const; - * (+) inline int getCurrentStrength() const; - * (+) inline int getLightIntensity() const; - * } - * - * Used code of MEDMEM/tests/testUUnit.cxx - */ - -void MEDMEMTest::testUnit() -{ - string myName = "NameForTesting"; - string myDescription = "all values are setted 10"; - int myMasse = 10; - int myLength = 10; - int myTime = 10; - int myTemperature = 10; - int myMatterQuantity = 10; - int myCurrentStrength = 10; - int myLightIntensity = 10; - - //Default constructor - UNIT myUNIT; - - //Normal constructor - UNIT *myUNIT1 = new UNIT(myName,myDescription); - CPPUNIT_ASSERT(myUNIT1); - - //--------------------------------------------------------------------// - // Tests des methodes // - // // - // - setName // - // - setDescription // - // - setMasse // - // - setLength // - // - setTime // - // - setTemperature // - // - setMatterQuantity // - // - setCurrentStrength // - // - setLightIntensity // - //--------------------------------------------------------------------// - - try - { - myUNIT.setName(myName); - } - catch(const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch(...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - myUNIT.setDescription(myDescription); - } - catch(const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch(...) - { - CPPUNIT_FAIL("MEDMEM_UNIT::setDescription(): Unknown exception"); - } - - try - { - myUNIT.setMasse(myMasse); - } - catch(const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch(...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - myUNIT.setLength(myLength); - } - catch(const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch(...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - myUNIT.setTime(myTime); - } - catch(const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch(...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - myUNIT.setTemperature(myTemperature); - } - catch(const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch(...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - myUNIT.setMatterQuantity(myMatterQuantity); - } - catch(const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch(...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - myUNIT.setCurrentStrength(myCurrentStrength); - } - catch(const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch(...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - myUNIT.setLightIntensity(myLightIntensity); - } - catch(const std::exception &e) - { - CPPUNIT_FAIL(e.what()); - } - catch(...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //--------------------------------------------------------------------// - // Tests des methodes // - // // - // - getName // - // - getDescription // - // - getMasse // - // - getLength // - // - getTime // - // - getTemperature // - // - getMatterQuantity // - // - getCurrentStrength // - // - getLightIntensity // - //--------------------------------------------------------------------// - - try - { - CPPUNIT_ASSERT( myUNIT.getName() == myName ); - } - catch( const std::exception &e ) - { - CPPUNIT_FAIL(e.what()); - } - catch ( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - CPPUNIT_ASSERT( myUNIT.getDescription() == myDescription ); - } - catch( const std::exception &e ) - { - CPPUNIT_FAIL(e.what()); - } - catch ( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - CPPUNIT_ASSERT( myUNIT.getMasse() == myMasse ); - } - catch( const std::exception &e ) - { - CPPUNIT_FAIL(e.what()); - } - catch ( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - CPPUNIT_ASSERT( myUNIT.getLength() == myLength ); - } - catch( const std::exception &e ) - { - CPPUNIT_FAIL(e.what()); - } - catch ( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - CPPUNIT_ASSERT( myUNIT.getTime() == myTime ); - } - catch( const std::exception &e ) - { - CPPUNIT_FAIL(e.what()); - } - catch ( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - CPPUNIT_ASSERT( myUNIT.getTemperature() == myTemperature ); - } - catch( const std::exception &e ) - { - CPPUNIT_FAIL(e.what()); - } - catch ( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - CPPUNIT_ASSERT( myUNIT.getMatterQuantity() == myMatterQuantity ); - } - catch( const std::exception &e ) - { - CPPUNIT_FAIL(e.what()); - } - catch ( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - CPPUNIT_ASSERT( myUNIT.getCurrentStrength() == myCurrentStrength ); - } - catch( const std::exception &e ) - { - CPPUNIT_FAIL(e.what()); - } - catch ( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - try - { - CPPUNIT_ASSERT( myUNIT.getLightIntensity() == myLightIntensity ); - } - catch( const std::exception &e ) - { - CPPUNIT_FAIL(e.what()); - } - catch ( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //--------------------------------------------------------------------// - // Tests des method // - // - operator= // - //--------------------------------------------------------------------// - - UNIT myUNITCpy; - myUNITCpy = myUNIT; - CPPUNIT_ASSERT_EQUAL( myUNITCpy.getTemperature(), myUNITCpy.getTemperature()); -} diff --git a/src/MEDMEM/Test/MEDMEMTest_VtkFieldDriver.cxx b/src/MEDMEM/Test/MEDMEMTest_VtkFieldDriver.cxx deleted file mode 100644 index 1610348f5..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_VtkFieldDriver.cxx +++ /dev/null @@ -1,299 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include <MEDMEM_VtkFieldDriver.hxx> -#include <MEDMEM_Med.hxx> -#include <MEDMEM_Field.hxx> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -/*! - * Check methods (14), defined in MEDMEM_VtkFieldDriver.hxx: - * template <class T> class VTK_FIELD_DRIVER : public GENDRIVER { - * //MUST BE PRIVATE, because it is impossible to set _ptrField after this constructor. - * //AND cannot compile, so maybe it is specially implemented to prevent usage of it. - * (!) template <class INTERLACING_TAG> VTK_FIELD_DRIVER(); - * (+) template <class INTERLACING_TAG> VTK_FIELD_DRIVER - * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField) - * (+) VTK_FIELD_DRIVER(const VTK_FIELD_DRIVER & fieldDriver) - * (+) ~VTK_FIELD_DRIVER() - * (+) void openConst() const throw (MEDEXCEPTION) - * (+) void openConstAppend() const throw (MEDEXCEPTION) - * (+) void open() throw (MEDEXCEPTION) - * (+) void openAppend() throw (MEDEXCEPTION) - * (+) void closeConst() const throw (MEDEXCEPTION) - * (+) void close() - * (+) void setFieldName(const string & fieldName); - * (+) string getFieldName() const; - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void write(void) const throw (MEDEXCEPTION); - * (+) void writeAppend(void) const throw (MEDEXCEPTION); - * } - */ -void MEDMEMTest::testVtkFieldDriver() -{ - FIELD<int> *aField = new FIELD<int> (); - FIELD<double> *aField_1 = new FIELD<double> (); - - string data_dir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - if (tmp_dir == "") - tmp_dir = "/tmp"; - - string filename_rd = data_dir + "/MedFiles/pointe.med"; - string emptyfilename = ""; - string fileNotExistsName = "/path_not_exists/file_not_exists.vtk"; - string filename_wr = tmp_dir + "/myField_pointe.vtk"; - - string fieldname_rd_int = "fieldnodeint"; - string fieldname_wr_int = "myintfield"; - string fieldname_rd_double = "fieldnodedouble"; - string fieldname_wr_double = "mydoublefield"; - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filename_wr); - - ///////////////////////////////////// - // TEST1: Open not existing file // - ///////////////////////////////////// - //Creation Invalid VtkFieldDriver (file not exist) - VTK_FIELD_DRIVER<int> *aInvalidVtkFieldDriver_1 = new VTK_FIELD_DRIVER<int>(fileNotExistsName, aField); - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_1->open(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_1->openConst(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_1->openConstAppend(), MEDEXCEPTION); - - ///////////////////////////////////////////// - // TEST2: Open file with empty file name // - ///////////////////////////////////////////// - //Creation Invalid VtkFieldDriver (empty file name) - VTK_FIELD_DRIVER<int> *aInvalidVtkFieldDriver_2 = new VTK_FIELD_DRIVER<int>(emptyfilename, aField); - - //Trying file with empty name - CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_2->open(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_2->openConst(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_2->openConstAppend(), MEDEXCEPTION); - - //////////////////////// - // TEST2: Main test // - //////////////////////// - //Read Fields from file - MED_FIELD_RDONLY_DRIVER21<int> *aMedRdFieldDriver21_int = new MED_FIELD_RDONLY_DRIVER21<int>(filename_rd, aField); - aMedRdFieldDriver21_int->open(); - aMedRdFieldDriver21_int->setFieldName(fieldname_rd_int); - aMedRdFieldDriver21_int->read(); - aMedRdFieldDriver21_int->close(); - - MED_FIELD_RDONLY_DRIVER21<double> *aMedRdFieldDriver21_double = new MED_FIELD_RDONLY_DRIVER21<double>(filename_rd, aField_1); - aMedRdFieldDriver21_double->open(); - aMedRdFieldDriver21_double->setFieldName(fieldname_rd_double); - aMedRdFieldDriver21_double->read(); - aMedRdFieldDriver21_double->close(); - //Check fields - CPPUNIT_ASSERT(aField); - - //Creation correct VtkFieldDriver - VTK_FIELD_DRIVER<int> *aVtkFieldDriver_int = new VTK_FIELD_DRIVER<int>(filename_wr, aField); - - //Check driver - CPPUNIT_ASSERT(aVtkFieldDriver_int); - - //Test setFieldName() and getFieldName() methods - try - { - aVtkFieldDriver_int->setFieldName(fieldname_wr_int); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT_EQUAL(fieldname_wr_int, aVtkFieldDriver_int->getFieldName()); - - //Test open() method - try - { - aVtkFieldDriver_int->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FAULTS - //Test write() method - try - { - aVtkFieldDriver_int->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - // => Segmentation fault -#endif - - //Test read() method for Vtk Field Driver - CPPUNIT_ASSERT_THROW(aVtkFieldDriver_int->read(),MEDEXCEPTION); - - //Test close() method - try - { - aVtkFieldDriver_int->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test openAppend() method - try - { - aVtkFieldDriver_int->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - - ///////////////////////////////////////////////////////// - // TEST? Test openAppend() and writeAppend() methods // - ///////////////////////////////////////////////////////// - - //Creation correct VtkFieldDriver - VTK_FIELD_DRIVER<double> *aVtkFieldDriver_double = new VTK_FIELD_DRIVER<double>(filename_wr, aField_1); - - //Check driver - CPPUNIT_ASSERT(aVtkFieldDriver_double); - - //Test openAppend() method - try - { - aVtkFieldDriver_double->openAppend(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - aVtkFieldDriver_double->setFieldName(fieldname_wr_double); - -#ifdef ENABLE_FAULTS - //Test writeAppend() method - try - { - aVtkFieldDriver_double->writeAppend(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - // => Segmentation fault -#endif - - try - { - aVtkFieldDriver_double->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //#ifdef ENABLE_FORCED_FAILURES - //VTK_FIELD_DRIVER<int> aVtkFieldDriver_intCpy_1; - //VTK_FIELD_DRIVER<int>.template VTK_FIELD_DRIVER<FullInterlace> aVtkFieldDriver_intCpy_1; - //CPPUNIT_FAIL("Compilation error: no matching function for call to 'MEDMEM::VTK_FIELD_DRIVER<int>::VTK_FIELD_DRIVER()"); - //#endif - -#ifdef ENABLE_FAULTS - //Test copy constructor - VTK_FIELD_DRIVER<int> aVtkFieldDriver_intCpy_2 (*aVtkFieldDriver_int); - // => Segmentation fault after call Copy Constructor - - CPPUNIT_ASSERT_EQUAL(aVtkFieldDriver_intCpy_2, *aVtkFieldDriver_int); - //Test (bool operator ==) defined in GENDRIVER class in MEDMEM_GenDriver.hxx - CPPUNIT_ASSERT(aVtkFieldDriver_intCpy_2.GENDRIVER::operator== (*aVtkFieldDriver_int)); - - //Test (friend ostream & operator <<) defined in GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream ostr1, ostr2; - ostr1<<*aVtkFieldDriver_int; - ostr2<<aVtkFieldDriver_intCpy_2; - - CPPUNIT_ASSERT(ostr1.str() != ""); - CPPUNIT_ASSERT(ostr1.str() == ostr2.str()); -#endif - - //Delete all objects - delete aField; - delete aField_1; -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Exception in the destructor after trying close not existing file. - delete aInvalidVtkFieldDriver_1; -#endif - delete aInvalidVtkFieldDriver_2; - delete aMedRdFieldDriver21_int; - delete aMedRdFieldDriver21_double; - delete aVtkFieldDriver_int; - delete aVtkFieldDriver_double; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_VtkFieldDriver_fault.cxx b/src/MEDMEM/Test/MEDMEMTest_VtkFieldDriver_fault.cxx deleted file mode 100644 index 0fecaafc7..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_VtkFieldDriver_fault.cxx +++ /dev/null @@ -1,304 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include <MEDMEM_VtkFieldDriver.hxx> -#include <MEDMEM_Med.hxx> -#include <MEDMEM_Field.hxx> - -// use this define to enable lines, execution of which leads to Segmentation Fault -#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -//#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -/*! - * Check methods (14), defined in MEDMEM_VtkFieldDriver.hxx: - * template <class T> class VTK_FIELD_DRIVER : public GENDRIVER { - * //MUST BE PRIVATE, because it is impossible to set _ptrField after this constructor. - * //AND cannot compile, so maybe it is specially implemented to prevent usage of it. - * (!) template <class INTERLACING_TAG> VTK_FIELD_DRIVER(); - * (+) template <class INTERLACING_TAG> VTK_FIELD_DRIVER - * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField) - * (+) VTK_FIELD_DRIVER(const VTK_FIELD_DRIVER & fieldDriver) - * (+) ~VTK_FIELD_DRIVER() - * (+) void openConst() const throw (MEDEXCEPTION) - * (+) void openConstAppend() const throw (MEDEXCEPTION) - * (+) void open() throw (MEDEXCEPTION) - * (+) void openAppend() throw (MEDEXCEPTION) - * (+) void closeConst() const throw (MEDEXCEPTION) - * (+) void close() - * (+) void setFieldName(const string & fieldName); - * (+) string getFieldName() const; - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void write(void) const throw (MEDEXCEPTION); - * (+) void writeAppend(void) const throw (MEDEXCEPTION); - * } - */ -void MEDMEMTest_testVtkFieldDriver() -{ - FIELD<int> *aField = new FIELD<int> (); - FIELD<double> *aField_1 = new FIELD<double> (); - - string data_dir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - if (tmp_dir == "") - tmp_dir = "/tmp"; - - string filename_rd = data_dir + "/MedFiles/pointe.med"; - string emptyfilename = ""; - string fileNotExistsName = "/path_not_exists/file_not_exists.vtk"; - string filename_wr = tmp_dir + "/myField_pointe.vtk"; - - string fieldname_rd_int = "fieldnodeint"; - string fieldname_wr_int = "myintfield"; - string fieldname_rd_double = "fieldnodedouble"; - string fieldname_wr_double = "mydoublefield"; - - // To remove tmp files from disk - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filename_wr); - - ///////////////////////////////////// - // TEST1: Open not existing file // - ///////////////////////////////////// - //Creation Invalid VtkFieldDriver (file not exist) - VTK_FIELD_DRIVER<int> *aInvalidVtkFieldDriver_1 = new VTK_FIELD_DRIVER<int>(fileNotExistsName, aField); - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_1->open(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_1->openConst(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_1->openConstAppend(), MEDEXCEPTION); - - ///////////////////////////////////////////// - // TEST2: Open file with empty file name // - ///////////////////////////////////////////// - //Creation Invalid VtkFieldDriver (empty file name) - VTK_FIELD_DRIVER<int> *aInvalidVtkFieldDriver_2 = new VTK_FIELD_DRIVER<int>(emptyfilename, aField); - - //Trying file with empty name - CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_2->open(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_2->openConst(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_2->openConstAppend(), MEDEXCEPTION); - - //////////////////////// - // TEST2: Main test // - //////////////////////// - //Read Fields from file - MED_FIELD_RDONLY_DRIVER21<int> *aMedRdFieldDriver21_int = new MED_FIELD_RDONLY_DRIVER21<int>(filename_rd, aField); - aMedRdFieldDriver21_int->open(); - aMedRdFieldDriver21_int->setFieldName(fieldname_rd_int); - aMedRdFieldDriver21_int->read(); - aMedRdFieldDriver21_int->close(); - - MED_FIELD_RDONLY_DRIVER21<double> *aMedRdFieldDriver21_double = new MED_FIELD_RDONLY_DRIVER21<double>(filename_rd, aField_1); - aMedRdFieldDriver21_double->open(); - aMedRdFieldDriver21_double->setFieldName(fieldname_rd_double); - aMedRdFieldDriver21_double->read(); - aMedRdFieldDriver21_double->close(); - //Check fields - CPPUNIT_ASSERT(aField); - - //Creation correct VtkFieldDriver - VTK_FIELD_DRIVER<int> *aVtkFieldDriver_int = new VTK_FIELD_DRIVER<int>(filename_wr, aField); - - //Check driver - CPPUNIT_ASSERT(aVtkFieldDriver_int); - - //Test setFieldName() and getFieldName() methods - try - { - aVtkFieldDriver_int->setFieldName(fieldname_wr_int); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - CPPUNIT_ASSERT_EQUAL(fieldname_wr_int, aVtkFieldDriver_int->getFieldName()); - - //Test open() method - try - { - aVtkFieldDriver_int->open(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - -#ifdef ENABLE_FAULTS - //Test write() method - try - { - aVtkFieldDriver_int->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - // => Segmentation fault -#endif - - //Test read() method for Vtk Field Driver - CPPUNIT_ASSERT_THROW(aVtkFieldDriver_int->read(),MEDEXCEPTION); - - //Test close() method - try - { - aVtkFieldDriver_int->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test openAppend() method - try - { - aVtkFieldDriver_int->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - - ///////////////////////////////////////////////////////// - // TEST? Test openAppend() and writeAppend() methods // - ///////////////////////////////////////////////////////// - - //Creation correct VtkFieldDriver - VTK_FIELD_DRIVER<double> *aVtkFieldDriver_double = new VTK_FIELD_DRIVER<double>(filename_wr, aField_1); - - //Check driver - CPPUNIT_ASSERT(aVtkFieldDriver_double); - - //Test openAppend() method - try - { - aVtkFieldDriver_double->openAppend(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - aVtkFieldDriver_double->setFieldName(fieldname_wr_double); - -#ifdef ENABLE_FAULTS - //Test writeAppend() method - try - { - aVtkFieldDriver_double->writeAppend(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - // => Segmentation fault -#endif - - try - { - aVtkFieldDriver_double->close(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //#ifdef ENABLE_FORCED_FAILURES - //VTK_FIELD_DRIVER<int> aVtkFieldDriver_intCpy_1; - //VTK_FIELD_DRIVER<int>.template VTK_FIELD_DRIVER<FullInterlace> aVtkFieldDriver_intCpy_1; - //CPPUNIT_FAIL("Compilation error: no matching function for call to 'MEDMEM::VTK_FIELD_DRIVER<int>::VTK_FIELD_DRIVER()"); - //#endif - -#ifdef ENABLE_FAULTS - //Test copy constructor - VTK_FIELD_DRIVER<int> aVtkFieldDriver_intCpy_2 (*aVtkFieldDriver_int); - // => Segmentation fault after call Copy Constructor - - CPPUNIT_ASSERT_EQUAL(aVtkFieldDriver_intCpy_2, *aVtkFieldDriver_int); - //Test (bool operator ==) defined in GENDRIVER class in MEDMEM_GenDriver.hxx - CPPUNIT_ASSERT(aVtkFieldDriver_intCpy_2.GENDRIVER::operator== (*aVtkFieldDriver_int)); - - //Test (friend ostream & operator <<) defined in GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream ostr1, ostr2; - ostr1<<*aVtkFieldDriver_int; - ostr2<<aVtkFieldDriver_intCpy_2; - - CPPUNIT_ASSERT(ostr1.str() != ""); - CPPUNIT_ASSERT(ostr1.str() == ostr2.str()); -#endif - - //Delete all objects - delete aField; - delete aField_1; -#ifdef ENABLE_FORCED_FAILURES - // (BUG) Exception in the destructor after trying close not existing file. - delete aInvalidVtkFieldDriver_1; -#endif - delete aInvalidVtkFieldDriver_2; - delete aMedRdFieldDriver21_int; - delete aMedRdFieldDriver21_double; - delete aVtkFieldDriver_int; - delete aVtkFieldDriver_double; -} - -int main (int argc, char** argv) -{ - MEDMEMTest_testVtkFieldDriver(); -} diff --git a/src/MEDMEM/Test/MEDMEMTest_VtkMedDriver.cxx b/src/MEDMEM/Test/MEDMEMTest_VtkMedDriver.cxx deleted file mode 100644 index ad8b0a222..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_VtkMedDriver.cxx +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include <MEDMEM_Compatibility21_22.hxx> -#include <MEDMEM_VtkMedDriver.hxx> -#include <MEDMEM_MedMedDriver21.hxx> -#include <MEDMEM_Med.hxx> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -/*! - * Check methods (5), defined in MEDMEM_VtkMedDriver.hxx: - * class VTK_MED_DRIVER : public GENDRIVER { - * (+) VTK_MED_DRIVER(const string & fileName, MED * const ptrMed); - * (+) VTK_MED_DRIVER(const VTK_MED_DRIVER & driver); - * (+) ~VTK_MED_DRIVER(); - * (+) void write (void) const; - * (-) virtual void read (void) {}; - * (+) GENDRIVER * copy (void) const; - * } - */ -void MEDMEMTest::testVtkMedDriver() -{ - MED *aMed = new MED(); - string data_dir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - if (tmp_dir == "") - tmp_dir = "/tmp"; - string filename_rd = data_dir + "/MedFiles/pointe.med"; - string emptyfilename = ""; - string fileNotExistsName = "/path_not_exists/file_not_exists.vtk"; - string filename_wr = tmp_dir + "/myMED_pointe.vtk"; - - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filename_wr); - - //Read MED structure from file - MED_MED_RDONLY_DRIVER21 *aMedMedRdDriver21 = new MED_MED_RDONLY_DRIVER21(filename_rd, aMed); - aMedMedRdDriver21->open(); - aMedMedRdDriver21->read(); - aMedMedRdDriver21->close(); - //Check Med - CPPUNIT_ASSERT(aMed); - - //Creation incorrect Vtk Med Driver (file is not exists) - VTK_MED_DRIVER *aInvalidVtkMedDriver = new VTK_MED_DRIVER(fileNotExistsName,aMed); - - //Trying write data in the not existing file - CPPUNIT_ASSERT_THROW(aInvalidVtkMedDriver->write(),MEDEXCEPTION); - - //Creation correct Vtk Med Driver - VTK_MED_DRIVER *aVtkMedDriver = new VTK_MED_DRIVER(filename_wr ,aMed); - - //Check driver - CPPUNIT_ASSERT(aVtkMedDriver); - - //Test write() method - - try - { - aVtkMedDriver->write(); - } - catch(MEDEXCEPTION &e) - { - CPPUNIT_FAIL(e.what()); - } - catch( ... ) - { - CPPUNIT_FAIL("Unknown exception"); - } - - //Test copy constructor - VTK_MED_DRIVER *aVtkMedDriverCpy = new VTK_MED_DRIVER(*aVtkMedDriver); -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_EQUAL(*aVtkMedDriverCpy, *aVtkMedDriver); -#endif - - //Test (operator ==) defined in GENDRIVER class in MEDMEM_GenDriver.hxx -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT(*aVtkMedDriverCpy == *aVtkMedDriver); -#endif - - //Test copy() function - VTK_MED_DRIVER *aVtkMedDriverCpy_1 = (VTK_MED_DRIVER*)aVtkMedDriver->copy(); -#ifdef ENABLE_FORCED_FAILURES - CPPUNIT_ASSERT_EQUAL(*aVtkMedDriverCpy_1, *aVtkMedDriver); -#endif - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - ostringstream ostr1, ostr2; - ostr1<<*aVtkMedDriverCpy; - ostr2<<*aVtkMedDriverCpy_1; - CPPUNIT_ASSERT(ostr1.str() != ""); - CPPUNIT_ASSERT(ostr1.str() == ostr2.str()); - - - //Delete objects - delete aMedMedRdDriver21; -#ifdef ENABLE_FORCED_FAILURES - delete aInvalidVtkMedDriver; - delete aVtkMedDriver; - delete aVtkMedDriverCpy; - delete aVtkMedDriverCpy_1; - //MEDEXCEPTION in the destructor (after trying close file) -#endif -} diff --git a/src/MEDMEM/Test/MEDMEMTest_VtkMeshDriver.cxx b/src/MEDMEM/Test/MEDMEMTest_VtkMeshDriver.cxx deleted file mode 100644 index 95e56e181..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_VtkMeshDriver.cxx +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" -#include <cppunit/TestAssert.h> - -#include <MEDMEM_VtkMeshDriver.hxx> -#include <MEDMEM_MedMeshDriver21.hxx> -#include <MEDMEM_Mesh.hxx> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; - -/*! - * Check methods (11), defined in MEDMEM_VtkMeshDriver.hxx: - * class VTK_MESH_DRIVER : public GENDRIVER { - * (+) VTK_MESH_DRIVER(); - * (+) VTK_MESH_DRIVER(const string & fileName, MESH * ptrMesh); - * (+) VTK_MESH_DRIVER(const VTK_MESH_DRIVER & driver); - * (+) ~VTK_MESH_DRIVER(); - * (+) void open(); - * (+) void close(); - * (+) void openConst() const throw (MEDEXCEPTION); - * (+) void closeConst() const throw (MEDEXCEPTION); - * (+) void write(void) const throw (MEDEXCEPTION); - * (+) void read (void) throw (MEDEXCEPTION); - * (+) void setMeshName(const string & meshName); - * (+) string getMeshName() const; - * } - */ -void MEDMEMTest::testVtkMeshDriver() -{ - MESH * aMesh = new MESH(); - - string data_dir = getenv("DATA_DIR"); - string tmp_dir = getenv("TMP"); - string filename_rd = data_dir + "/MedFiles/pointe.med"; - string emptyfilename = ""; - string meshname_rd = "maa1"; - string meshname = "MyMesh"; - string fileNotExistsName = "/path_not_exists/file_not_exists.vtk"; - string filename = tmp_dir + "/my_pointe.vtk"; - - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filename); - - { - //Creation a invalid Vtk driver - VTK_MESH_DRIVER *aInvalidVtkDriver = new VTK_MESH_DRIVER(fileNotExistsName, aMesh); - - //Trying open not existing file - CPPUNIT_ASSERT_THROW(aInvalidVtkDriver->open(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aInvalidVtkDriver->openConst(), MEDEXCEPTION); - -#ifdef ENABLE_FORCED_FAILURES - // (BUG) In destructor of VTK_MESH_DRIVER: Exception after trying close not existing file - CPPUNIT_ASSERT_NO_THROW(delete aInvalidVtkDriver); -#endif - } - - { - //Create Vtk driver with empty file name - VTK_MESH_DRIVER *aEmptyVtkDriver = new VTK_MESH_DRIVER(emptyfilename, aMesh); - - //Test open() and openConst() methods with empty file name - CPPUNIT_ASSERT_THROW(aEmptyVtkDriver->open(), MEDEXCEPTION); - CPPUNIT_ASSERT_THROW(aEmptyVtkDriver->openConst(), MEDEXCEPTION); - - delete aEmptyVtkDriver; - } - - //Creation corect driver - VTK_MESH_DRIVER *aVtkDriver = new VTK_MESH_DRIVER(filename, aMesh); - CPPUNIT_ASSERT(aVtkDriver); - - //Create a Mesh - MED_MESH_RDONLY_DRIVER21 *aMedMeshRdDriver21 = new MED_MESH_RDONLY_DRIVER21(filename_rd, aMesh); - aMedMeshRdDriver21->open(); - aMedMeshRdDriver21->setMeshName(meshname_rd); - - //Test openConst() and closeConst() methods - CPPUNIT_ASSERT_NO_THROW(aVtkDriver->openConst()); - CPPUNIT_ASSERT_NO_THROW(aVtkDriver->closeConst()); - - //Test open() method - CPPUNIT_ASSERT_NO_THROW(aVtkDriver->open()); - - //Trying open file secondary -#ifdef ENABLE_FORCED_FAILURES - // (BUG) No exception on attempt to open a file for the second time - CPPUNIT_ASSERT_THROW(aVtkDriver->open(), MEDEXCEPTION); -#endif - - //Test read method - CPPUNIT_ASSERT_THROW(aVtkDriver->read(), MEDEXCEPTION); - - //Trying write empty mesh -#ifdef ENABLE_FAULTS - // ? (BUG) ? In VTK_MESH_DRIVER::write() => Segmentation fault on attempt to write an empty mesh - CPPUNIT_ASSERT_THROW(aVtkDriver->write(), MEDEXCEPTION); -#endif - - //Read mesh from Med file - aMedMeshRdDriver21->read(); - - //Check mesh - CPPUNIT_ASSERT(aMesh); - - //Test SetMeshName and getMeshName methods - CPPUNIT_ASSERT_NO_THROW(aVtkDriver->setMeshName(meshname)); - CPPUNIT_ASSERT_EQUAL(meshname, aVtkDriver->getMeshName()); - - //Test write method - CPPUNIT_ASSERT_NO_THROW(aVtkDriver->write()); - - //Test close method - CPPUNIT_ASSERT_NO_THROW(aVtkDriver->close()); - - //Test Default constructor - VTK_MESH_DRIVER aVtkDriverCpy_1; - - //Test copy constructor -#ifdef ENABLE_FAULTS - // (BUG) In copy constructor of VTK_MESH_DRIVER: Segmentation fault - VTK_MESH_DRIVER aVtkDriverCpy_2 (*aVtkDriver); -#endif - - //Test (bool operator ==) defined in GENDRIVER class - //CPPUNIT_ASSERT(aVtkDriverCpy_2.GENDRIVER::operator==(aVtkDriver)); - - //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx - //ostringstream ostr1, ostr2; - //ostr1 << aVtkDriverCpy_2; - //ostr2 << aVtkDriver; - //CPPUNIT_ASSERT(ostr1.str() != ""); - //CPPUNIT_ASSERT_EQUAL(ostr1.str(), ostr2.str()); - - //Delete objects - delete aVtkDriver; - delete aMedMeshRdDriver21; - delete aMesh; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_VtkMeshDriver_fault.cxx b/src/MEDMEM/Test/MEDMEMTest_VtkMeshDriver_fault.cxx deleted file mode 100644 index ac5122689..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_VtkMeshDriver_fault.cxx +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 - -#include "MEDMEMTest.hxx" - -#include <MEDMEM_VtkMeshDriver.hxx> -#include <MEDMEM_MedMeshDriver21.hxx> -#include <MEDMEM_Mesh.hxx> - -using namespace std; -using namespace MEDMEM; - -int main (int argc, char** argv) -{ - string tmp_dir = getenv("TMP"); - string meshname = "MyMesh"; - string filename = tmp_dir + "/my_pointe.vtk"; - - MEDMEMTest_TmpFilesRemover aRemover; - aRemover.Register(filename); - - //Create an empty Mesh - MESH * aMesh = new MESH(); - - //Creation corect driver - VTK_MESH_DRIVER *aVtkDriver = new VTK_MESH_DRIVER(filename, aMesh); - aVtkDriver->setMeshName(meshname); - aVtkDriver->open(); - - // ? (BUG) ? In VTK_MESH_DRIVER::write() => Segmentation fault on attempt to write an empty mesh - try - { - //Trying write an empty mesh - aVtkDriver->write(); - } - catch (MEDEXCEPTION & ex) - { - // good behaviour - } - catch (...) - { - } - - aVtkDriver->close(); - - // (BUG) In copy constructor of VTK_MESH_DRIVER: Segmentation fault or Infinite loop - VTK_MESH_DRIVER aVtkDriverCpy_2 (*aVtkDriver); - - delete aVtkDriver; - delete aMesh; -} diff --git a/src/MEDMEM/Test/MEDMEMTest_nArray.cxx b/src/MEDMEM/Test/MEDMEMTest_nArray.cxx deleted file mode 100644 index 0e2fe4ce4..000000000 --- a/src/MEDMEM/Test/MEDMEMTest_nArray.cxx +++ /dev/null @@ -1,529 +0,0 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -#include "MEDMEMTest.hxx" -#include <cppunit/Message.h> -#include <cppunit/TestAssert.h> - -#include "MEDMEM_nArray.hxx" -#include "MEDMEM_define.hxx" -#include "MEDMEM_ArrayConvert.hxx" - -#include <sstream> -#include <cmath> - -// use this define to enable lines, execution of which leads to Segmentation Fault -//#define ENABLE_FAULTS - -// use this define to enable CPPUNIT asserts and fails, showing bugs -#define ENABLE_FORCED_FAILURES - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -/*! - * Check methods (21), defined in MEDMEM_nArray.hxx: - * class MEDMEM_Array_ { - * (-) virtual bool getGaussPresence() const { return false; } - * (-) virtual MED_EN::medModeSwitch getInterlacingType() const {return MED_EN::MED_UNDEFINED_INTERLACE;} - * (+) ~MEDMEM_Array_() {}; - * } - * template<class ARRAY_ELEMENT_TYPE, - * class INTERLACING_POLICY=FullInterlaceNoGaussPolicy, - * class CHECKING_POLICY=IndexCheckPolicy> - * class MEDMEM_Array : public INTERLACING_POLICY, public CHECKING_POLICY, public MEDMEM_Array_ { - * (+) MEDMEM_Array(); - * (+) ~MEDMEM_Array(); - * (+) inline MEDMEM_Array(int dim, int nbelem); - * (+) inline MEDMEM_Array(ElementType * values, int dim, int nbelem, - * bool shallowCopy=false, bool ownershipOfValues=false); - * (+) inline MEDMEM_Array(int dim, int nbelem, int nbtypegeo, - * const int * const nbelgeoc, const int * const nbgaussgeo); - * (+) inline MEDMEM_Array(ElementType * values, int dim, int nbelem, int nbtypegeo, - * const int * const nbelgeoc, const int * const nbgaussgeo, - * bool shallowCopy=false, bool ownershipOfValues=false); - * (+) inline MEDMEM_Array(const MEDMEM_Array & array, bool shallowCopy=false); - * (+) inline MEDMEM_Array<ElementType,InterlacingPolicy,CheckingPolicy> & - * operator=(const MEDMEM_Array & array); - * (+) MED_EN::medModeSwitch getInterlacingType() const; - * (+) bool getGaussPresence() const; - * (+) ElementType * getPtr(); - * (+) void setPtr(ElementType * values, bool shallowCopy=false, bool ownershipOfValues=false); - * (+) inline const ElementType * getRow(int i) const; - * (+) void setRow(int i,const ElementType * const value); - * (+) inline const ElementType * getColumn(int j) const; - * (+) void setColumn(int j, const ElementType * const value); - * (+) inline const ElementType & getIJ(int i, int j) const; - * (+) inline const ElementType & getIJK(int i, int j, int k) const; - * (+) inline void setIJ(int i, int j, const ElementType & value); - * (+) inline void setIJK(int i, int j, int k, const ElementType & value); - * (+) bool operator == (const MEDMEM_Array & array) const; - * (+) friend ostream & operator<<(ostream & os, const MEDMEM_Array & array); - * } - */ -void MEDMEMTest::testnArray() -{ - const int mdim = 2; - const int nbelem1 = 20; - const double EPS = 0.00001; - - ///////////////////////////////////////// - // TEST 1 FullInterlace et NoGauss // - //////////////////////////////////////// - const double * myArray1Ptr = 0; - const double array1Ref[] = { 11 , 12 , 21 , 22 , 31 , 32 , 41 , 42 , 51 , 52 , - 61 , 62 , 71 , 72 , 81 , 82 , 91 , 92 , 101 , 102 , - 111 , 112 , 121 , 122 , 131 , 132 , 141 , 142 , - 151 , 152 , 161 , 162 , 171 , 172 , 181 , 182 , - 191 , 192 , 201 , 202 }; - - const double array2Ref[] = { 11 , 21 , 31 , 41 , 51 , 61 , 71 , 81 , 91 , 101 - , 111 , 121 , 131 , 141 , 151 , 161 , 171 , 181 - , 191 , 201 , - 12 , 22 , 32 , 42 , 52 , 62 , 72 , 82 , 92 , 102 - , 112 , 122 , 132 , 142 , 152 , 162 , 172 , 182 - , 192 , 202 }; - - //test MEDMEM_Array(int dim, int nbelem) - MEDMEM_Array<double> myArray1(mdim,nbelem1); - //test getGaussPresence - CPPUNIT_ASSERT( !myArray1.getGaussPresence()); - - //test setIJ. Fill array - for (int i =1; i <= nbelem1; i++) - for (int j =1; j <= mdim; j++) - { - CPPUNIT_ASSERT_NO_THROW(myArray1.setIJ(i,j,i*10+j)); - } - - //test getPtr - myArray1Ptr = myArray1.getPtr(); - for (int i = 0; i < mdim*nbelem1; i++) - CPPUNIT_ASSERT( myArray1Ptr[i] == array1Ref[i] ); - - { - //test MEDMEM_Array(ElementType * values, int dim, int nbelem, bool shallowCopy=false, bool ownershipOfValues=false) - MEDMEM_Array<double> myArray1val ((double*)array1Ref, mdim, nbelem1); - myArray1Ptr = myArray1val.getPtr(); - for (int i = 0; i < mdim*nbelem1; i++) - CPPUNIT_ASSERT( myArray1Ptr[i] == array1Ref[i] ); - - //test MEDMEM_Array(ElementType * values, int dim, int nbelem, bool shallowCopy=true, bool ownershipOfValues=false); - MEDMEM_Array<double> myArray1valsh ((double*)array1Ref, mdim, nbelem1, true); - myArray1Ptr = myArray1valsh.getPtr(); - for (int i = 0; i < mdim*nbelem1; i++) - CPPUNIT_ASSERT( myArray1Ptr[i] == array1Ref[i] ); - - //test setPtr - double myPtr[] = {-1, -2, -3, -4, -5, -6, -7, -8, -9, 0}; - CPPUNIT_ASSERT_NO_THROW(myArray1valsh.setPtr(myPtr)); - //size the array stays the same, only first 10 element are being overwritten - myArray1Ptr = myArray1valsh.getPtr(); - for (int i = 0; i < 11; i++) - CPPUNIT_ASSERT_EQUAL(myArray1Ptr[i], myPtr[i]); - } - - //test MEDMEM_Array(ElementType * values, int dim, int nbelem, bool shallowCopy=true, bool ownershipOfValues=true); - { - double * array1Ref_do_not_delete = new double[40]; - for (int i = 0; i < 40; i = i + 2) { - array1Ref_do_not_delete[i ] = 10.0 * (i+1) + 1; - array1Ref_do_not_delete[i+1] = 10.0 * (i+1) + 2; - } - MEDMEM_Array<double> myArray1valow (array1Ref_do_not_delete, mdim, nbelem1, true, true); - } - - //test MEDMEM_Array(const MEDMEM_Array & array, bool shallowCopy=false) - MEDMEM_Array<double> myArray1bis (myArray1, false); - CPPUNIT_ASSERT(myArray1 == myArray1bis); - - myArray1Ptr = myArray1bis.getPtr(); - for (int i =0; i < mdim*nbelem1; i++) - CPPUNIT_ASSERT( myArray1Ptr[i] == array1Ref[i] ); - - //test MEDMEM_Array() - MEDMEM_Array<double> myArray1ter; - try - { - myArray1ter = myArray1; - myArray1Ptr = myArray1ter.getPtr(); - } - catch ( const std::exception &e ) - { - CPPUNIT_FAIL(e.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - - for (int i =0; i < mdim*nbelem1; i++) - CPPUNIT_ASSERT( myArray1Ptr[i] == array1Ref[i] ); - - MEDMEM_Array<double> myArray1qua(mdim,nbelem1); - myArray1Ptr = myArray1qua.getPtr(); - - for (int i =1; i <= nbelem1; i++) - { - try { - //test setRow(int i,const ElementType * const value) - myArray1qua.setRow(i,&array1Ref[(i-1)*mdim]); - } - catch (MEDMEM::MEDEXCEPTION &m) { - CPPUNIT_FAIL(m.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - } - - for (int i =0; i < mdim*nbelem1; i++) - CPPUNIT_ASSERT( myArray1Ptr[i] == array1Ref[i] ); - - //test getColumn(int j) - CPPUNIT_ASSERT_THROW(myArray1qua.getColumn(1), MEDEXCEPTION); - - MEDMEM_Array<double,NoInterlaceNoGaussPolicy> * myArray1cin = ArrayConvert(myArray1); - myArray1Ptr = myArray1cin->getPtr(); - int elemno = 0; - for (int j=1; j <= mdim; j++) - for (int i=1; i <= nbelem1 ; i++ ) { - CPPUNIT_ASSERT( myArray1cin->getIJ(i,j) == array2Ref[elemno] ); - CPPUNIT_ASSERT( myArray1Ptr[elemno] == array2Ref[elemno] ); - elemno++; - } - - ///////////////////////////////////// - // TEST 2 NoInterlace et NoGauss // - ///////////////////////////////////// - { - const double * myArray2Ptr = 0; - //MEDMEM_Array(int dim, int nbelem) - MEDMEM_Array<double,NoInterlaceNoGaussPolicy> myArray2(mdim,nbelem1); - - for (int i =1; i <= nbelem1; i++) { - for (int j =1; j <= mdim; j++) { - //test setIJ(int i, int j, const ElementType & value) - CPPUNIT_ASSERT_NO_THROW(myArray2.setIJ(i,j,i*10+j)); - } - } - - //test getPtr() - myArray2Ptr = myArray2.getPtr(); - for (int i =0; i < mdim*nbelem1; i++) - CPPUNIT_ASSERT( myArray2Ptr[i] == array2Ref[i] ); - - //test MEDMEM_Array(const MEDMEM_Array & array, bool shallowCopy=false) - MEDMEM_Array<double,NoInterlaceNoGaussPolicy> myArray2bis(myArray2, false); - myArray2Ptr = myArray2bis.getPtr(); - for (int i =0; i < mdim*nbelem1; i++) - CPPUNIT_ASSERT( myArray2Ptr[i] == array2Ref[i] ); - - //test MEDMEM_Array() - MEDMEM_Array<double,NoInterlaceNoGaussPolicy> myArray2ter; - //test operator=(const MEDMEM_Array & array) - myArray2ter = myArray2; - //test getPtr - myArray2Ptr = myArray2ter.getPtr(); - for (int i =0; i < mdim*nbelem1; i++) - CPPUNIT_ASSERT( myArray2Ptr[i] == array2Ref[i] ); - - MEDMEM_Array<double,NoInterlaceNoGaussPolicy> myArray2qua(mdim,nbelem1); - myArray2Ptr = myArray2qua.getPtr(); - - for (int j = 1; j <= mdim; j++) { - //test setColumn(int j, const ElementType * const value) - CPPUNIT_ASSERT_NO_THROW(myArray2qua.setColumn(j,&array2Ref[nbelem1*(j-1)])); - } - - for (int i =0; i < mdim*nbelem1; i++) - CPPUNIT_ASSERT( myArray2Ptr[i] == array2Ref[i] ); - - //test getRow(int i) - CPPUNIT_ASSERT_THROW(myArray2qua.getRow(1), MEDEXCEPTION); - - MEDMEM_Array<double,FullInterlaceNoGaussPolicy> * myArray2cin = ArrayConvert(myArray2); - myArray2Ptr = myArray2cin->getPtr(); - elemno = 0; - for (int i=1; i <= nbelem1 ; i++) { - for (int j=1; j <= mdim; j++) { - CPPUNIT_ASSERT( myArray2cin->getIJ(i,j) == array1Ref[elemno] ); - CPPUNIT_ASSERT( myArray2Ptr[elemno] == array1Ref[elemno] ); - elemno++; - } - } - } - - /////////////////////////////////////// - // TEST 3 FullInterlace et Gauss // - ////////////////////////////////////// - const int nbelem2 = 5; - const int nbtypegeo = 2; - const int nbelgeoc[nbtypegeo+1] = {1,3,6}; - const int nbgaussgeo[nbtypegeo+1] = {-1,2,3}; - - const double * myArray3Ptr = 0; - const double array3Ref[] = {1.11 , 1.12 , 1.21 , 1.22 , - 2.11 , 2.12 , 2.21 , 2.22 , - 13.11 , 13.12 , 13.21 , 13.22 , 13.31 , 13.32 , - 14.11 , 14.12 , 14.21 , 14.22 , 14.31 , 14.32 , - 15.11 , 15.12 , 15.21 , 15.22 , 15.31 , 15.32 }; - - const double array4Ref[] = { 1.11 , 1.21 , 2.11 , 2.21, - 13.11 , 13.21 , 13.31 , 14.11 , 14.21 , 14.31 , - 15.11 , 15.21 , 15.31 , - 1.12 , 1.22 , 2.12 , 2.22 , - 13.12 , 13.22 , 13.32 , 14.12 , 14.22 , 14.32 , - 15.12 , 15.22 , 15.32 }; - - const int array5Ref[] = { 1 , 1 , 2 , 2, - 13 , 13 , 13 , 14 , 14 , 14 , - 15 , 15 , 15 , - 1 , 1 , 2 , 2 , - 13 , 13 , 13 , 14 , 14 , 14 , - 15 , 15 , 15 }; - - //test MEDMEM_Array(int dim, int nbelem, int nbtypegeo, const int * const nbelgeoc, const int * const nbgaussgeo) - MEDMEM_Array<double,FullInterlaceGaussPolicy> myArray3(mdim,nbelem2,nbtypegeo,nbelgeoc,nbgaussgeo); - - elemno = 1; - for (int ntyp=1; ntyp <= nbtypegeo; ntyp++ ) { - for (int i=0; i < (nbelgeoc[ntyp]-nbelgeoc[ntyp-1]) ; i++ ) { - for (int k=1; k <= nbgaussgeo[ntyp]; k++) - for (int j=1; j <= mdim; j++) { - try{ - //test setIJK(int i, int j, int k, const ElementType & value) - myArray3.setIJK(elemno,j,k,elemno+(ntyp-1)*10+0.1*k+0.01*j); - } - catch (MEDMEM::MEDEXCEPTION &m) { - CPPUNIT_FAIL(m.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - } - elemno++; - } - } - - myArray3Ptr = myArray3.getPtr(); - for (int i =0; i < myArray3.getArraySize(); i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(myArray3Ptr[i], array3Ref[i], EPS); - - MEDMEM_Array<double,FullInterlaceGaussPolicy> myArray3bis(myArray3, false); - myArray3Ptr = myArray3bis.getPtr(); - - elemno = 0; - for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) - for (int k=1; k <= myArray3bis.getNbGauss(i); k++) - for (int j=1; j <= mdim; j++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray3bis.getIJK(i,j,k), array3Ref[elemno], EPS ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray3Ptr[elemno], array3Ref[elemno], EPS ); - elemno++; - } - - //test MEDMEM_Array() - MEDMEM_Array<double,FullInterlaceGaussPolicy> myArray3ter; - //test operator=(const MEDMEM_Array & array) - myArray3ter = myArray3; - myArray3Ptr = myArray3ter.getPtr(); - - elemno = 0; - for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) - for (int k=1; k <= myArray3ter.getNbGauss(i); k++) - for (int j=1; j <= mdim; j++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray3ter.getIJK(i,j,k), array3Ref[elemno], EPS ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray3Ptr[elemno], array3Ref[elemno], EPS ); - elemno++; - } - - MEDMEM_Array<double,FullInterlaceGaussPolicy> myArray3qua(mdim,nbelem2, - nbtypegeo,nbelgeoc,nbgaussgeo); - myArray3Ptr = myArray3qua.getPtr(); - - int cumul = 0; - for (int i =1; i <= nbelem2; i++){ - try{ - myArray3qua.setRow(i,&array3Ref[cumul]); - cumul+=myArray3qua.getNbGauss(i)*mdim; - } - catch (MEDMEM::MEDEXCEPTION &m) { - CPPUNIT_FAIL(m.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - }; - - for (int i =0; i < myArray3qua.getArraySize(); i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray3Ptr[i], array3Ref[i], EPS ); - - MEDMEM_Array<double,NoInterlaceGaussPolicy> * myArray3cin = ArrayConvert(myArray3); - myArray3Ptr = myArray3cin->getPtr(); - elemno = 0; - for (int j=1; j <= mdim; j++) - for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) - for (int k=1; k <= myArray3cin->getNbGauss(i); k++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray3cin->getIJK(i,j,k), array4Ref[elemno], EPS ); - CPPUNIT_ASSERT_DOUBLES_EQUAL(myArray3Ptr[elemno], array4Ref[elemno], EPS ); - elemno++; - } - - //////////////////////////////////// - // TEST 4 NoInterlace et Gauss // - //////////////////////////////////// - const double * myArray4Ptr = 0; - //test MEDMEM_Array(int dim, int nbelem, int nbtypegeo, const int * const nbelgeoc, const int * const nbgaussgeo) - MEDMEM_Array<double,NoInterlaceGaussPolicy> myArray4(mdim,nbelem2,nbtypegeo,nbelgeoc,nbgaussgeo); - - elemno = 1; - for (int ntyp=1; ntyp <= nbtypegeo; ntyp++ ) { - for (int i=0; i < (nbelgeoc[ntyp]-nbelgeoc[ntyp-1]) ; i++ ) { - for (int k=1; k <= nbgaussgeo[ntyp]; k++) - for (int j=1; j <= mdim; j++) { - try{ - //test setIJK(int i, int j, int k, const ElementType & value) - myArray4.setIJK(elemno,j,k,elemno+(ntyp-1)*10+0.1*k+0.01*j); - } - catch (MEDMEM::MEDEXCEPTION &m) { - CPPUNIT_FAIL(m.what()); - } - catch (...) - { - CPPUNIT_FAIL("Unknown exception"); - } - } - elemno++; - } - } - - //test getPtr() - myArray4Ptr = myArray4.getPtr(); - for (int i =0; i < myArray4.getArraySize(); i++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray4Ptr[i], array4Ref[i], EPS ); - } - - //test MEDMEM_Array(const MEDMEM_Array & array, bool shallowCopy=false) - MEDMEM_Array<double,NoInterlaceGaussPolicy> myArray4bis(myArray4, false); - myArray4Ptr = myArray4bis.getPtr(); - - elemno = 0; - for (int j=1; j <= mdim; j++) - for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) - for (int k=1; k <= myArray4bis.getNbGauss(i); k++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray4bis.getIJK(i,j,k), array4Ref[elemno], EPS ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray4Ptr[elemno], array4Ref[elemno], EPS ); - elemno++; - } - - //test MEDMEM_Array() - MEDMEM_Array<double,NoInterlaceGaussPolicy> myArray4ter; - //test operator=(const MEDMEM_Array & array) - myArray4ter = myArray4; - myArray4Ptr = myArray4ter.getPtr(); - - elemno = 0; - for (int j=1; j <= mdim; j++) - for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) - for (int k=1; k <= myArray4ter.getNbGauss(i); k++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray4ter.getIJK(i,j,k), array4Ref[elemno], EPS ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray4Ptr[elemno], array4Ref[elemno], EPS ); - elemno++; - } - - { - MEDMEM_Array<double,NoInterlaceGaussPolicy> myArray4qua (mdim,nbelem2,nbtypegeo,nbelgeoc,nbgaussgeo); - myArray4Ptr = myArray4qua.getPtr(); - - for (int j = 1; j <= mdim; j++) { - int k = (myArray4qua.getArraySize() / mdim) * (j - 1); - CPPUNIT_ASSERT_NO_THROW(myArray4qua.setColumn(j, &array4Ref[k])); - } - - for (int i =0; i < myArray4qua.getArraySize(); i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray4Ptr[i], array4Ref[i], EPS ); - } - - { - MEDMEM_Array<double,FullInterlaceGaussPolicy> * myArray4cin = ArrayConvert(myArray4); - myArray4Ptr = myArray4cin->getPtr(); - elemno = 0; - for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) - for (int k=1; k <= myArray4cin->getNbGauss(i); k++) - for (int j=1; j <= mdim; j++) { - CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray4cin->getIJK(i,j,k), array3Ref[elemno], EPS ); - CPPUNIT_ASSERT( myArray4cin->getIJK(i,j,k) == myArray3.getIJK(i,j,k) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray4Ptr[elemno], array3Ref[elemno], EPS ); - elemno++; - } - delete myArray4cin; - } - - CPPUNIT_ASSERT(myArray4bis.getInterlacingType() != MED_UNDEFINED_INTERLACE); - - CPPUNIT_ASSERT_THROW(myArray4.getIJ(0,2), MEDEXCEPTION); - - ostringstream os; - //test operator<<(ostream & os, const MEDMEM_Array & array) - os << myArray4; - CPPUNIT_ASSERT(os.str() != ""); - - const int * myArray5Ptr = 0; - //test MEDMEM_Array(ElementType * values, int dim, int nbelem, int nbtypegeo, - // const int * const nbelgeoc, const int * const nbgaussgeo, - // bool shallowCopy=false, bool ownershipOfValues=false) - MEDMEM_Array<int, NoInterlaceGaussPolicy> myArray5 ((int*)array5Ref, mdim, nbelem2, - nbtypegeo, nbelgeoc, nbgaussgeo); - //test getGaussPresence - CPPUNIT_ASSERT( myArray5.getGaussPresence()); - - myArray5Ptr = myArray5.getPtr(); - for (int i =0; i < myArray5.getArraySize(); i++) { - CPPUNIT_ASSERT_EQUAL( myArray5Ptr[i], array5Ref[i]); - } - - //test MEDMEM_Array(const MEDMEM_Array & array, bool shallowCopy=false) - MEDMEM_Array<int,NoInterlaceGaussPolicy> myArray5bis(myArray5, false); - myArray5Ptr = myArray5bis.getPtr(); - - elemno = 0; - for (int j=1; j <= mdim; j++) - for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) - for (int k=1; k <= myArray5bis.getNbGauss(i); k++) { - CPPUNIT_ASSERT_EQUAL( myArray5bis.getIJK(i,j,k), array5Ref[elemno] ); - CPPUNIT_ASSERT_EQUAL( myArray5Ptr[elemno], array5Ref[elemno] ); - elemno++; - } - - //MEDMEM_Array() - MEDMEM_Array<int,NoInterlaceGaussPolicy> myArray5ter; - //test setPtr(ElementType * values, bool shallowCopy=false, bool ownershipOfValues=false) - CPPUNIT_ASSERT_NO_THROW(myArray5.setPtr((int*)array5Ref)); - - //test getPtr() - myArray5Ptr = myArray5ter.getPtr(); - for (int i =0; i < myArray5ter.getArraySize(); i++) { - CPPUNIT_ASSERT_EQUAL( myArray5Ptr[i], array5Ref[i]); - } -} diff --git a/src/MEDMEM/Test/Makefile.am b/src/MEDMEM/Test/Makefile.am deleted file mode 100644 index f8da5981f..000000000 --- a/src/MEDMEM/Test/Makefile.am +++ /dev/null @@ -1,116 +0,0 @@ -# SALOMELocalTrace : log on local machine -# -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 -# - -include $(top_srcdir)/adm_local/unix/make_common_starter.am - -lib_LTLIBRARIES = libMEDMEMTest.la - -salomeinclude_HEADERS = MEDMEMTest.hxx - -EXTRA_DIST += BasicMainTest.hxx - -dist_libMEDMEMTest_la_SOURCES= \ - MEDMEMTest.cxx \ - MEDMEMTest_Array.cxx \ - MEDMEMTest_AsciiFieldDriver.cxx \ - MEDMEMTest_Connectivity.cxx \ - MEDMEMTest_Coordinate.cxx \ - MEDMEMTest_DriverFactory.cxx \ - MEDMEMTest_Exception.cxx \ - MEDMEMTest_Family.cxx \ - MEDMEMTest_Field.cxx \ - MEDMEMTest_Formulae.cxx \ - MEDMEMTest_GaussLocalization.cxx \ - MEDMEMTest_GibiMeshDriver.cxx \ - MEDMEMTest_Grid.cxx \ - MEDMEMTest_Group.cxx \ - MEDMEMTest_Med.cxx \ - MEDMEMTest_MedFieldDriver21.cxx \ - MEDMEMTest_MedFieldDriver22.cxx \ - MEDMEMTest_MedMedDriver21.cxx \ - MEDMEMTest_MedMedDriver22.cxx \ - MEDMEMTest_MedMeshDriver21.cxx \ - MEDMEMTest_MedMeshDriver22.cxx \ - MEDMEMTest_MedVersion.cxx \ - MEDMEMTest_MeshAndMeshing.cxx \ - MEDMEMTest_ModulusArray.cxx \ - MEDMEMTest_nArray.cxx \ - MEDMEMTest_PointerOf.cxx \ - MEDMEMTest_PolyhedronArray.cxx \ - MEDMEMTest_PorflowMeshDriver.cxx \ - MEDMEMTest_SkyLineArray.cxx \ - MEDMEMTest_Support.cxx \ - MEDMEMTest_TopLevel.cxx \ - MEDMEMTest_Unit.cxx \ - MEDMEMTest_VtkFieldDriver.cxx \ - MEDMEMTest_VtkMedDriver.cxx \ - MEDMEMTest_VtkMeshDriver.cxx - -libMEDMEMTest_la_CPPFLAGS= @CPPUNIT_INCLUDES@ $(MED2_INCLUDES) $(HDF5_INCLUDES) \ - -I$(srcdir)/../../MEDMEM -I$(srcdir)/../../MEDWrapper/V2_1/Core -libMEDMEMTest_la_LDFLAGS= $(MED2_LIBS) @CPPUNIT_LIBS@ - -if MED_ENABLE_KERNEL - libMEDMEMTest_la_CPPFLAGS+= ${KERNEL_CXXFLAGS} - libMEDMEMTest_la_LDFLAGS+= ${KERNEL_LDFLAGS} -lSALOMELocalTrace -endif - -# Executables targets -bin_PROGRAMS = TestMEDMEM \ - MEDMEMTest_Array_fault \ - MEDMEMTest_Connectivity_fault \ - MEDMEMTest_Coordinate_fault \ - MEDMEMTest_Family_fault \ - MEDMEMTest_Field_fault \ - MEDMEMTest_Grid_fault \ - MEDMEMTest_MedFieldDriver21_fault \ - MEDMEMTest_MedMedDriver21_fault \ - MEDMEMTest_MedMedDriver22_fault \ - MEDMEMTest_MeshAndMeshing_fault \ - MEDMEMTest_Support_fault \ - MEDMEMTest_VtkFieldDriver_fault \ - MEDMEMTest_VtkMeshDriver_fault - -dist_TestMEDMEM_SOURCES= TestMEDMEM.cxx -dist_MEDMEMTest_Array_fault_SOURCES= MEDMEMTest_Array_fault.cxx -dist_MEDMEMTest_Connectivity_fault_SOURCES= MEDMEMTest_Connectivity_fault.cxx -dist_MEDMEMTest_Coordinate_fault_SOURCES= MEDMEMTest_Coordinate_fault.cxx -dist_MEDMEMTest_Family_fault_SOURCES= MEDMEMTest_Family_fault.cxx -dist_MEDMEMTest_Field_fault_SOURCES= MEDMEMTest_Field_fault.cxx -dist_MEDMEMTest_Grid_fault_SOURCES= MEDMEMTest_Grid_fault.cxx -dist_MEDMEMTest_MedFieldDriver21_fault_SOURCES= MEDMEMTest_MedFieldDriver21_fault.cxx -dist_MEDMEMTest_MedMedDriver21_fault_SOURCES= MEDMEMTest_MedMedDriver21_fault.cxx -dist_MEDMEMTest_MedMedDriver22_fault_SOURCES= MEDMEMTest_MedMedDriver22_fault.cxx -dist_MEDMEMTest_MeshAndMeshing_fault_SOURCES= MEDMEMTest_MeshAndMeshing_fault.cxx -dist_MEDMEMTest_Support_fault_SOURCES= MEDMEMTest_Support_fault.cxx -dist_MEDMEMTest_VtkFieldDriver_fault_SOURCES= MEDMEMTest_VtkFieldDriver_fault.cxx -dist_MEDMEMTest_VtkMeshDriver_fault_SOURCES= MEDMEMTest_VtkMeshDriver_fault.cxx - -LDADD= $(MED2_LIBS) $(libMEDMEMTest_la_LDFLAGS) -lm \ - ../../MEDWrapper/V2_1/Core/libmed_V2_1.la ../libmedmem.la libMEDMEMTest.la -if MED_ENABLE_KERNEL - LDADD+= -lSALOMEBasics -endif -AM_CPPFLAGS= $(libMEDMEMTest_la_CPPFLAGS) - -salomescript_DATA = testMEDMEM.py -UNIT_TEST_PROG = TestMEDMEM diff --git a/src/MEDMEM/Test/TestMEDMEM.cxx b/src/MEDMEM/Test/TestMEDMEM.cxx deleted file mode 100644 index 43c056ece..000000000 --- a/src/MEDMEM/Test/TestMEDMEM.cxx +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -// --- include all MEDMEM Test - -#include "MEDMEMTest.hxx" - -// --- Registers the fixture into the 'registry' - -CPPUNIT_TEST_SUITE_REGISTRATION( MEDMEMTest ); - -// --- generic Main program from KERNEL_SRC/src/Basics/Test - -#include "BasicMainTest.hxx" diff --git a/src/MEDMEM/Test/testMEDMEM.py b/src/MEDMEM/Test/testMEDMEM.py deleted file mode 100644 index c576cf3d3..000000000 --- a/src/MEDMEM/Test/testMEDMEM.py +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright (C) 2005 CEA/DEN, EDF R&D, OPEN CASCADE, PRINCIPIA 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. -# -# 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 -# - -import sys, os,signal,string,commands -###import runSalome -###import orbmodule -###import TestKiller - -# get SALOME environment : - -###args, modules_list, modules_root_dir = runSalome.get_config() -###runSalome.set_env(args, modules_list, modules_root_dir) - -# launch CORBA naming server - -###clt=orbmodule.client() - -# launch CORBA logger server - -###myServer=runSalome.LoggerServer(args) -###myServer.run() -###clt.waitLogger("Logger") - -# execute Unit Test - -command = ['TestMEDMEM'] -ret = os.spawnvp(os.P_WAIT, command[0], command) - -print "MEDMEM General testing done." -print "Run cases, which leads to Segmentation Fault ..." - -command = ['MEDMEMTest_Array_fault'] -ret = os.spawnvp(os.P_WAIT, command[0], command) - -command = ['MEDMEMTest_Connectivity_fault'] -ret = os.spawnvp(os.P_WAIT, command[0], command) - -command = ['MEDMEMTest_Coordinate_fault'] -ret = os.spawnvp(os.P_WAIT, command[0], command) - -command = ['MEDMEMTest_Family_fault'] -ret = os.spawnvp(os.P_WAIT, command[0], command) - -command = ['MEDMEMTest_Field_fault'] -ret = os.spawnvp(os.P_WAIT, command[0], command) - -command = ['MEDMEMTest_Grid_fault'] -ret = os.spawnvp(os.P_WAIT, command[0], command) - -command = ['MEDMEMTest_MedFieldDriver21_fault'] -ret = os.spawnvp(os.P_WAIT, command[0], command) - -command = ['MEDMEMTest_MedMedDriver21_fault'] -ret = os.spawnvp(os.P_WAIT, command[0], command) - -command = ['MEDMEMTest_MedMedDriver22_fault'] -ret = os.spawnvp(os.P_WAIT, command[0], command) - -command = ['MEDMEMTest_MeshAndMeshing_fault'] -ret = os.spawnvp(os.P_WAIT, command[0], command) - -command = ['MEDMEMTest_Support_fault'] -ret = os.spawnvp(os.P_WAIT, command[0], command) - -command = ['MEDMEMTest_VtkFieldDriver_fault'] -ret = os.spawnvp(os.P_WAIT, command[0], command) - -command = ['MEDMEMTest_VtkMeshDriver_fault'] -ret = os.spawnvp(os.P_WAIT, command[0], command) - -# kill Test process - -###TestKiller.killProcess(runSalome.process_id) diff --git a/src/MEDMEM/create_grid.c b/src/MEDMEM/create_grid.c deleted file mode 100644 index b24a4cf2d..000000000 --- a/src/MEDMEM/create_grid.c +++ /dev/null @@ -1,436 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// -/*---------------------------------------------------------------------------- - MED MEDMEM : MED files in memory - - File : create_grid.c - Module : MED -----------------------------------------------------------------------------*/ - -/****************************************************************************** - * - Nom du fichier : test19.c - * - * - Description : ecriture des objets MED relatifs aux grilles - * MED V2.0 - * - *****************************************************************************/ - -#include <med.h> -#include <string.h> - -/****************************************************************************** - * - creation d'un fichier MED - * - ecriture des noeuds : coordonnees en mode MED_FULL_INTERLACE, - * noms,numeros,numeros de familles - * - ecriture des familles d'un maillage MED - * 2.0 via les routines de bas niveau - * - fermeture du fichier - *****************************************************************************/ - -int main (int argc, char **argv) -{ - - /* Ecriture d'un premier maillage non structure (test14 + test8) - ************************************************************** */ - - med_err ret; - med_idt fid; - /* la dimension du maillage */ - med_int mdim = 2; - /* nom du maillage de longueur maxi MED_TAILLE_NOM */ - char maa[MED_TAILLE_NOM+1] = "maa1"; - /* description du maillage de longueur maxi MED_TAIIL_DESC */ - char maadesc[MED_TAILLE_DESC+1] = "Example de maillage structure 2D"; - /* le nombre de noeuds */ - med_int nnoe = 4; - /* table des coordonnees - profil : (dimension * nombre de noeuds) */ - med_float coo[8] = {0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0}; - med_int nbr[2] = {2, 2}; - /* tables des noms et des unites des coordonnees - profil : (dimension*MED_TAILLE_PNOM+1) */ - char nomcoo[2*MED_TAILLE_PNOM+1] = "x y "; - char unicoo[2*MED_TAILLE_PNOM+1] = "cm cm "; - - char nomcooi[MED_TAILLE_PNOM+1] = "x "; - char unicooi[MED_TAILLE_PNOM+1] = "cm "; - /* tables des noms, numeros, numeros de familles des noeuds - autant d'elements que de noeuds - les noms ont pout longueur - MED_TAILLE_PNOM */ - char nomnoe[4*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4 "; - med_int numnoe[4] = {1,2,3,4}; - med_int nufano[4] = {0,1,2,2}; - char nomfam[MED_TAILLE_NOM+1]; - med_int numfam; - char attdes[MED_TAILLE_DESC+1]; - med_int natt; - med_int attide; - med_int attval; - med_int ngro; - char gro[MED_TAILLE_LNOM+1]; - int i, ip1; - int nfame = 1; - int nfamn = 2; - med_int famNodeStd[4]; - med_int famElmtStd[1]; - med_int famFaceStd[4]; - med_int famNodeCart[16]; - med_int famElmtCart[9]; - med_int famFaceCart[24]; - /* - les elements: - */ - med_int nquad4 = 1; - med_int quad4[4] = { - 1, 2, 4, 3 - }; - char nomquad4[MED_TAILLE_PNOM*1+1] = "quad1 "; - med_int numquad4[1] = {1}; - med_int nufaquad4[1] = {-1}; - - fid = MEDouvrir("test19.med",MED_LECTURE_ECRITURE); - if (fid < 0) - ret = -1; - else - ret = 0; - printf("MEDouvrir : %d\n",ret); - - /* creation du maillage maa de dimension 2 */ - if (ret == 0) - ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); - printf("MEDmaaCr : %d\n",ret); - - /* ecriture des noeuds d'un maillage MED : - - des coo en mode MED_FULL_INTERLACE : (X1,Y1,X2,Y2,X3,Y3,...) - dans un repere cartesien - - des noms (optionnel dans un fichier MED) - - des numeros (optionnel dans un fichier MED) - - des numeros de familles des noeuds */ - if (ret == 0) - ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, - nomcoo,unicoo,nomnoe,MED_VRAI,numnoe,MED_VRAI, - nufano,nnoe); - printf("MEDnoeudsEcr : %d\n",ret); - - /* ecriture des mailles MED_QUAD4 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,quad4,MED_FULL_INTERLACE, - nomquad4,MED_FAUX,numquad4,MED_VRAI,nufaquad4,nquad4, - MED_MAILLE,MED_QUAD4,MED_NOD); - printf("MEDelementsEcr : %d\n",ret); - - /* ecriture des familles */ - /* Conventions : - - toujours creer une famille de numero 0 ne comportant aucun attribut - ni groupe (famille de reference pour les noeuds ou les elements - qui ne sont rattaches a aucun groupe ni attribut) - - les numeros de familles de noeuds sont > 0 - - les numeros de familles des elements sont < 0 - - rien d'imposer sur les noms de familles - */ - - /* la famille 0 */ - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_0"); - numfam = 0; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, - gro,0); - } - printf("MEDfamCr : %d \n",ret); - - /* on cree pour correspondre aux cas tests precedents, 3 familles - d'elements (-1,-2,-3) et deux familles de noeuds (1,2) */ - if (ret == 0) - { - nfame = 1; - for (i=0;i<nfame;i++) - { - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_ELEMENT_"); - numfam = -(i+1); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe1"); - ngro = 1; - printf("%s - %d - %d - %d - %d \n",nomfam,numfam,attide,attval, - ngro); - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr (elements) : %d\n",ret); - } - } - } - - if (ret == 0) - { - nfamn = 2; - for (i=0;i<nfamn;i++) - { - if(ret == 0) - { - strcpy(nomfam,"FAMILLE_NOEUD_"); - numfam = i+1; - sprintf(nomfam,"%s%d",nomfam,numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe1"); - ngro = 1; - printf("%s - %d - %d - %d - %d \n",nomfam,numfam,attide,attval, - ngro); - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr (nodes) : %d\n",ret); - } - } - } - - - /* fermeture du fichier */ - ret = MEDfermer(fid); - printf("MEDfermer : %d\n",ret); - - /* Ecriture d'un deuxieme maillage structure : grille standard - ************************************************************* */ - - fid = MEDouvrir("test19.med", MED_LECTURE_ECRITURE); - if (fid < 0) - ret = -1; - else - ret = 0; - printf("MEDouvrir : %d\n",ret); - - strcpy(maa, "Grille Standard"); - strcpy(maadesc, "Example de maillage structure grille standard 2D"); - /* creation du maillage grille standard maa de dimension 2 */ - if (ret == 0) - ret = MEDmaaCr(fid, maa, mdim, MED_STRUCTURE, maadesc); - printf("MEDmaaCr : %d\n",ret); - - if (ret == 0) - ret = MEDnatureGrilleEcr(fid, maa, MED_GRILLE_STANDARD); - printf("MEDnatureGrilleEcr : %d\n",ret); - - /* ecriture des noeuds d'un maillage MED : - - des coo en mode MED_FULL_INTERLACE : (X1,Y1,X2,Y2,X3,Y3,...) - dans un repere cartesien - - des noms (optionnel dans un fichier MED) - - des numeros (optionnel dans un fichier MED) - - des numeros de familles des noeuds */ -/* if (ret == 0) */ -/* ret = MEDstructureCoordEcr(fid,maa,mdim,nbr); */ -/* printf("MEDstructureCoordEcr : %d\n",ret); */ - - if (ret == 0) - ret = MEDcoordEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,nnoe,MED_CART, - nomcoo,unicoo); - printf("MEDcoordEcr : %d\n",ret); - - if (ret == 0) - ret = MEDstructureCoordEcr(fid,maa,mdim,nbr); - printf("MEDstructureCoordEcr : %d\n",ret); - - /* Ecriture des familles de la grille standard */ - - /* les noeuds */ - - if (ret == 0) { - famNodeStd[ 0]=1; famNodeStd[ 1]=1; - famNodeStd[ 2]=2; famNodeStd[ 3]=2; - - ret = MEDfamEcr(fid, maa, famNodeStd, 4, MED_NOEUD, 0); - }; - printf("MEDfamEcr for Nodes : %d\n",ret); - - /* les elements */ - - if (ret == 0) { - famElmtStd[ 0]=0; - - ret = MEDfamEcr(fid, maa, famElmtStd, 1, MED_MAILLE, MED_QUAD4); - }; - printf("MEDfamEcr for Elements : %d\n",ret); - - /* les faces/edges */ - - if (ret == 0) { - for (i=0; i<4; i++) famFaceStd[i]=0; - - ret = MEDfamEcr(fid, maa, famFaceStd, 4, MED_ARETE, MED_SEG2); - }; - printf("MEDfamEcr for Elements : %d\n",ret); - - /* la famille 0 */ - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_0"); - numfam = 0; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, - gro,0); - } - printf("MEDfamCr : %d\n",ret); - - if (ret == 0) - { - nfamn = 2; - for (i=0;i<nfamn;i++) - { - if(ret == 0) - { - strcpy(nomfam,"FAMILLE_NOEUD_"); - numfam = i+1; - sprintf(nomfam,"%s%d",nomfam,numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe1"); - ngro = 1; - printf("%s - %d - %d - %d - %d \n",nomfam,numfam,attide,attval, - ngro); - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr (nodes) : %d\n",ret); - } - } - } - - /* fermeture du fichier */ - ret = MEDfermer(fid); - printf("MEDfermer : %d\n",ret); - - /* Ecriture d'un troisieme maillage structure : grille cartesienne - *************************************************************** */ - - fid = MEDouvrir("test19.med", MED_LECTURE_ECRITURE); - if (fid < 0) - ret = -1; - else - ret = 0; - printf("MEDouvrir : %d\n",ret); - - strcpy(maa, "Grille Cartesienne"); - strcpy(maadesc, "Example de maillage structure grille cartesienne 2D"); - /* creation d'une grille cartesienne maa de dimension 2 */ - if (ret == 0) - ret = MEDmaaCr(fid, maa, mdim, MED_STRUCTURE, maadesc); - printf("MEDmaaCr : %d\n",ret); - - if (ret == 0) - ret = MEDnatureGrilleEcr(fid, maa, MED_GRILLE_CARTESIENNE); - printf("MEDnatureGrilleEcr : %d\n",ret); - - /* Ecriture des indices de la grille cartesienne : - - des coo en mode MED_FULL_INTERLACE : (X1,Y1,X2,Y2,X3,Y3,...) */ - for (i=0; i<mdim; i++) { - ip1 = i + 1; - coo[0] = 1.1+i; - coo[1] = 1.2+i; - coo[2] = 1.3+i; - coo[3] = 1.4+i; - if (ret == 0) { - ret = MEDindicesCoordEcr(fid, maa, mdim, coo, nnoe, ip1, - nomcooi, unicooi); - }; - }; - printf("MEDindicesCoordEcr : %d\n",ret); - - /* Ecriture des familles de la grille cartesienne */ - - /* les noeuds */ - - if (ret == 0) { - famNodeCart[ 0]=3; famNodeCart[ 1]=3; famNodeCart[ 2]=2; famNodeCart[ 3]=1; - famNodeCart[ 4]=7; famNodeCart[ 5]=8; famNodeCart[ 6]=2; famNodeCart[ 7]=4; - famNodeCart[ 8]=2; famNodeCart[ 9]=9; famNodeCart[10]=0; famNodeCart[11]=2; - famNodeCart[12]=5; famNodeCart[13]=5; famNodeCart[14]=6; famNodeCart[15]=7; - - ret = MEDfamEcr(fid, maa, famNodeCart, 16, MED_NOEUD, 0); - }; - printf("MEDfamEcr for Nodes : %d\n",ret); - - /* les elements */ - - if (ret == 0) { - for(i=0; i<9; i++) famElmtCart[i]=0; - - ret = MEDfamEcr(fid, maa, famElmtCart, 9, MED_MAILLE, MED_QUAD4); - }; - printf("MEDfamEcr for Elements : %d\n",ret); - - /* les faces/edges */ - - if (ret == 0) { - for(i=0; i<24; i++) famFaceCart[i]=0; - - ret = MEDfamEcr(fid, maa, famFaceCart, 24, MED_ARETE, MED_SEG2); - }; - printf("MEDfamEcr for Elements : %d\n",ret); - - /* la famille 0 */ - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_0"); - numfam = 0; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, - gro,0); - } - printf("MEDfamCr : %d \n",ret); - - if (ret == 0) - { - nfamn = 9; - for (i=0;i<nfamn;i++) - { - if(ret == 0) - { - strcpy(nomfam,"FAMILLE_NOEUD_"); - numfam = i+1; - sprintf(nomfam,"%s%d",nomfam,numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe1"); - ngro = 1; - printf("%s - %d - %d - %d - %d \n",nomfam,numfam,attide,attval, - ngro); - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr (nodes) : %d\n",ret); - } - } - } - - /* fermeture du fichier */ - ret = MEDfermer(fid); - printf("MEDfermer : %d\n",ret); - - return 0; -} diff --git a/src/MEDMEM/create_mesh.c b/src/MEDMEM/create_mesh.c deleted file mode 100644 index 542df04c5..000000000 --- a/src/MEDMEM/create_mesh.c +++ /dev/null @@ -1,407 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// -#include <med.h> -#include <string.h> - -int main (int argc, char **argv) -{ - med_err ret; - med_idt fid; - char maa[MED_TAILLE_NOM+1] = "maa1"; - char maadesc[MED_TAILLE_DESC+1] = "Example de maillage non structure 3D"; - med_int mdim = 3; - med_int nnoe = 19; - med_float coo[57] = { - 0.0, 0.0, 0.0, - 0.0, 0.0, 1.0, - 2.0, 0.0, 1.0, - 0.0, 2.0, 1.0, - -2.0, 0.0, 1.0, - 0.0, -2.0, 1.0, - 1.0, 1.0, 2.0, - -1.0, 1.0, 2.0, - -1.0, -1.0, 2.0, - 1.0, -1.0, 2.0, - 1.0, 1.0, 3.0, - -1.0, 1.0, 3.0, - -1.0, -1.0, 3.0, - 1.0, -1.0, 3.0, - 1.0, 1.0, 4.0, - -1.0, 1.0, 4.0, - -1.0, -1.0, 4.0, - 1.0, -1.0, 4.0, - 0.0, 0.0, 5.0 - }; - char nomcoo[3*MED_TAILLE_PNOM+1] = "x y z "; - char unicoo[3*MED_TAILLE_PNOM+1] = "cm cm cm "; - /* char nomnoe[19*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4";*/ - char *nomnoe ; - med_int numnoe[19] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; - med_int nufano[19] = {1,1,3,3,0,0,2,0,4,0,4,2,4,2,4,2,4,1,3}; - - med_int ntet4 = 12; - med_int tet4[12*4] = { - 1,2,3,6, - 1,2,4,3, - 1,2,5,4, - 1,2,6,5, - 2,7,4,3, - 2,8,5,4, - 2,9,6,5, - 2,10,3,6, - 2,7,3,10, - 2,8,4,7, - 2,9,5,8, - 2,10,6,9 - }; - char * nomtet4 ; - med_int numtet4[12] = {1,2,3,4,5,6,7,8,9,10,11,12}; - med_int nufatet4[12] = {-1,-1,-1,-1,0,0,0,0,0,0,-2,-3}; - - med_int npyra5 = 2; - med_int pyra5[5*2] = { - 7,8,9,10,2, - 15,18,17,16,19 - }; - char nompyra5[MED_TAILLE_PNOM*2+1] = "pyra1 pyra2 "; - med_int numpyra5[2] = {13,16}; - med_int nufapyra5[2] = {0,-3}; - - med_int nhexa8 = 2; - med_int hexa8[8*2] = { - 11,12,13,14,7,8,9,10, - 15,16,17,18,11,12,13,14 - }; - char nomhexa8[MED_TAILLE_PNOM*2+1] = "hexa1 hexa2 "; - med_int numhexa8[2] = {14,15}; - med_int nufahexa8[2] = {0,0}; - - char nomfam[MED_TAILLE_NOM+1]; - med_int numfam; - char attdes[MED_TAILLE_DESC+1]; - med_int natt; - med_int attide; - med_int attval; - med_int ngro; - char gro[MED_TAILLE_LNOM+1]; - char gro2[MED_TAILLE_LNOM*2+1]; - char gro3[MED_TAILLE_LNOM*3+1]; - int i; - int nfame = 3; - int nfamn = 2; - - - /* - Some fields : 2 on nodes : one int and one double , one on cells : double - */ - char champ1[MED_TAILLE_NOM+1]="fieldnodeint" ; - char champ1_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ1_unit[MED_TAILLE_PNOM+1]="M " ; - med_int fieldnodeint[19] = {1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7}; - - char champ2[MED_TAILLE_NOM+1]="fieldnodedouble" ; - char champ2_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ2_unit[MED_TAILLE_PNOM+1]="J " ; - med_float fieldnodedouble1[19] = {1.,1.,1.,2.,2.,2.,3.,3.,3.,4.,4.,4.,5.,5.,5.,6.,6.,6.,7.}; - med_float fieldnodedouble2[19] = {1.,2.,2.,2.,3.,3.,3.,4.,4.,4.,5.,5.,5.,6.,6.,6.,7.,7.,7.}; - - char champ3[MED_TAILLE_NOM+1]="fieldcelldoublevector" ; - char champ3_comp[MED_TAILLE_PNOM*3+1]="comp1 comp2 comp3 " ; - char champ3_unit[MED_TAILLE_PNOM*3+1]="m/s m/s m/s " ; - med_float fieldcelldouble1[12*3] = {1.,1.,1.,2.,2.,2.,3.,3.,3.,4.,4.,4.,0.,0.,0.,1.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,0.,0.,0.,1.,1.,1.,0.,0.,0.}; - med_float fieldcelldouble2[2*3] = {5.,5.,0.,1.,0.,1.}; - med_float fieldcelldouble3[2*3] = {6.,6.,1.,0.,1.,0.}; - - char champ4[MED_TAILLE_NOM+1]="fieldcelldoublescalar" ; - char champ4_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ4_unit[MED_TAILLE_PNOM+1]="m/s " ; - med_float fieldcelldouble4[12] = {1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.}; - med_float fieldcelldouble5[2] = {2.,2.}; - med_float fieldcelldouble6[2] = {3.,3.}; - - /***************************************************************************/ - fid = MEDouvrir("pointe.med",MED_LECTURE_ECRITURE); - if (fid < 0) - ret = -1; - else - ret = 0; - printf("MEDouvrir : %d\n",ret); - - /***************************************************************************/ - if (ret == 0) - ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); - printf("MEDmaaCr : %d\n",ret); - if (ret == 0) - ret = MEDunvCr(fid,maa); - printf("MEDunvCr : %d\n",ret); - - /***************************************************************************/ - if (ret == 0) - ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, - nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, - nufano,nnoe); - printf("MEDnoeudsEcr : %d\n",ret); - - - /***************************************************************************/ - /* ecriture des mailles MED_TETRA4 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,tet4,MED_FULL_INTERLACE, - nomtet4,MED_FAUX,numtet4,MED_VRAI,nufatet4,ntet4, - MED_MAILLE,MED_TETRA4,MED_NOD); - printf("MEDelementsEcr : %d \n",ret); - - /* ecriture des mailles MED_PYRA5 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,pyra5,MED_FULL_INTERLACE, - nompyra5,MED_VRAI,numpyra5,MED_VRAI,nufapyra5,npyra5, - MED_MAILLE,MED_PYRA5,MED_NOD); - printf("MEDelementsEcr : %d \n",ret); - - /* ecriture des mailles MED_HEXA8 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,hexa8,MED_FULL_INTERLACE, - nomhexa8,MED_FAUX,numhexa8,MED_VRAI,nufahexa8,nhexa8, - MED_MAILLE,MED_HEXA8,MED_NOD); - printf("MEDelementsEcr : %d \n",ret); - - /***************************************************************************/ - /* ecriture des familles */ - /* Conventions : - - toujours creer une famille de numero 0 ne comportant aucun attribut - ni groupe (famille de reference pour les noeuds ou les elements - qui ne sont rattaches a aucun groupe ni attribut) - - les numeros de familles de noeuds sont > 0 - - les numeros de familles des elements sont < 0 - - rien d'imposer sur les noms de familles - */ - - /* la famille 0 */ - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_0"); - numfam = 0; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, - gro,0); - } - printf("MEDfamCr : %d \n",ret); - - /* on cree : - - 3 familles d'elements (-1,-2,-3) et - - 2 familles de noeuds (1,2) - */ - if (ret == 0) - { - nfame = 3; - for (i=0;i<nfame;i++) - { - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_ELEMENT_"); - numfam = -(i+1); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe1"); - ngro = 1; - /*printf("nomfam : %s - numfam : %d - attide : %d - attval : %d - ngro : %d \n",nomfam,numfam,attide,attval,ngro);*/ - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - } - } - - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_NOEUD_1"); - numfam = 1; - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro2,"groupe2"); - strcpy(gro2+MED_TAILLE_LNOM,"groupe3"); - ngro = 2; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro2,ngro); - printf("MEDfamCr : %d\n",ret); - } - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_NOEUD_2"); - numfam = 2; - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro2,"groupe3"); - strcpy(gro2+MED_TAILLE_LNOM,"groupe4"); - ngro = 2; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro2,ngro); - printf("MEDfamCr : %d\n",ret); - } - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_NOEUD_3"); - numfam = 3; - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro2,"groupe2"); - strcpy(gro2+MED_TAILLE_LNOM,"groupe4"); - ngro = 2; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro2,ngro); - printf("MEDfamCr : %d\n",ret); - } - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_NOEUD_4"); - numfam = 4; - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe5"); - ngro = 1; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - - /***************************************************************************/ - /* - Les champs - */ - if (ret == 0) - { - ret = MEDchampCr(fid,champ1,MED_INT32,champ1_comp,champ1_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ1, (unsigned char *)fieldnodeint, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - MED_NOPDT," ", 0., MED_NONOR); - - printf("MEDchampEcr : %d \n",ret); - } - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ2,MED_FLOAT64,champ2_comp,champ2_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - 1,"S ", 1.1 , MED_NONOR); - printf("MEDchampEcr1 : %d \n",ret); - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble2, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - 2,"S ", 1.2 , MED_NONOR); - printf("MEDchampEcr2 : %d \n",ret); - } - } - - /* on met champ2 sans pas de temps pour pouvoir le lire aussi par defaut !*/ - if (ret == 0) - { -/* ret = MEDchampCr(fid,champ2,MED_REEL64,champ2_comp,champ2_unit,1); */ -/* printf("MEDchampCr : %d \n",ret); */ - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - MED_NOPDT," ", 0. , MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ3,MED_FLOAT64,champ3_comp,champ3_unit,3); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble1, - MED_NO_INTERLACE, ntet4, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_TETRA4, - MED_NOPDT," ", 0., MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble3, - MED_NO_INTERLACE, nhexa8, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_HEXA8, - MED_NOPDT," ", 0., MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble2, - MED_NO_INTERLACE, npyra5, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_PYRA5, - MED_NOPDT," ", 0., MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ4,MED_FLOAT64,champ4_comp,champ4_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ4, (unsigned char *)fieldcelldouble4, - MED_NO_INTERLACE, ntet4, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_TETRA4, - MED_NOPDT," ", 0., MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - ret = MEDchampEcr(fid, maa, champ4, (unsigned char *)fieldcelldouble6, - MED_NO_INTERLACE, nhexa8, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_HEXA8, - MED_NOPDT," ", 0., MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - ret = MEDchampEcr(fid, maa, champ4, (unsigned char *)fieldcelldouble5, - MED_NO_INTERLACE, npyra5, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_PYRA5, - MED_NOPDT," ", 0., MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - } - - /***************************************************************************/ - ret = MEDfermer(fid); - printf("MEDfermer : %d\n",ret); - - return 0; -} - diff --git a/src/MEDMEM/create_mesh_c2q4.c b/src/MEDMEM/create_mesh_c2q4.c deleted file mode 100644 index da36f83b7..000000000 --- a/src/MEDMEM/create_mesh_c2q4.c +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// -/* - creation d'une geometrie 2d : un cube [0,1]^2 - maillé uniformement en quadrangle reguliers; - avec en plus une partie des aretes (une partie - des arretes de la frontiere) du maillage. - ATTENTION : 3 noeuds dans chaque direction -*/ - -#include <med.h> -#include <string.h> - -int main (int argc, char **argv) -{ - med_err ret; - med_idt fid; - char maa[MED_TAILLE_NOM+1] = "carre_en_quad4"; - char maadesc[MED_TAILLE_DESC+1] = "Example de maillage non structure 2D"; - med_int mdim = 2; - med_int nnoe = 9; - /* - les noeuds: - */ - med_float coo[18] = { - 0.0, 0.0, - 0.5, 0.0, - 1.0, 0.0, - 0.0, 0.5, - 0.5, 0.5, - 1.0, 0.5, - 0.0, 1.0, - 0.5, 1.0, - 1.0, 1.0 - }; - char nomcoo[2*MED_TAILLE_PNOM+1] = "x y "; - char unicoo[2*MED_TAILLE_PNOM+1] = "cm cm "; - /* char nomnoe[19*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4";*/ - char *nomnoe ; - med_int numnoe[9] = {1,2,3,4,5,6,7,8,9}; - med_int nufano[9] = {0,0,0,0,0,0,0,0,0}; - /* - les elements: - */ - med_int nquad4 = 4; - med_int quad4[16] = { - 4, 5, 2, 1, - 5, 6, 3, 2, - 7, 8, 5, 4, - 8, 9, 6, 5 - }; - char nomquad4[MED_TAILLE_PNOM*4+1] = "quad1 quad2 quad3 quad4 "; - med_int numquad4[4] = {1,2,3,4}; - med_int nufaquad4[4] = {-1,-1,0,0}; - - char nomfam[MED_TAILLE_NOM+1]; - med_int numfam; - char attdes[MED_TAILLE_DESC+1]; - med_int natt; - med_int attide; - med_int attval; - med_int ngro; - char gro[MED_TAILLE_LNOM+1]; - int i; - int nfame = 1; - int nfamn = 1; - - /* - Some fields : 2 on nodes : one int and one double , one on cells : double - */ - char champ1[MED_TAILLE_NOM+1]="fieldnodeint" ; - char champ1_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ1_unit[MED_TAILLE_PNOM+1]="M " ; - med_int fieldnodeint[9] = {1,1,3,2,2,3,4,4,5}; - - char champ2[MED_TAILLE_NOM+1]="fieldnodedouble" ; - char champ2_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ2_unit[MED_TAILLE_PNOM+1]="J " ; - med_float fieldnodedouble1[9] = {1.,3.,4.,1.,3.,4.,3.,2.,5.}; - med_float fieldnodedouble2[9] = {1.,2.,2.,3.,3.,3.,4.,4.,5.}; - - char champ3[MED_TAILLE_NOM+1]="fieldcelldouble" ; - char champ3_comp[MED_TAILLE_PNOM*2+1]="comp1 comp2 " ; - char champ3_unit[MED_TAILLE_PNOM*2+1]="M/S m/s " ; - med_float fieldcelldouble[4*2] = {0.,1.,1.,1.,1.,2.,2.,3.}; - - /***************************************************************************/ - fid = MEDouvrir("carre_en_quad4.med",MED_LECTURE_ECRITURE); - if (fid < 0) - ret = -1; - else - ret = 0; - printf("MEDouvrir : %d\n",ret); - - /***************************************************************************/ - if (ret == 0) - ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); - printf("MEDmaaCr : %d\n",ret); - if (ret == 0) - ret = MEDunvCr(fid,maa); - printf("MEDunvCr : %d\n",ret); - - /***************************************************************************/ - if (ret == 0) - ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, - nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, - nufano,nnoe); - printf("MEDnoeudsEcr : %d\n",ret); - - /* ecriture des mailles MED_QUAD4 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,quad4,MED_FULL_INTERLACE, - nomquad4,MED_FAUX,numquad4,MED_VRAI,nufaquad4,nquad4, - MED_MAILLE,MED_QUAD4,MED_NOD); - printf("MEDelementsEcr : %d \n",ret); - - /***************************************************************************/ - /* ecriture des familles */ - /* Conventions : - - toujours creer une famille de numero 0 ne comportant aucun attribut - ni groupe (famille de reference pour les noeuds ou les elements - qui ne sont rattaches a aucun groupe ni attribut) - - les numeros de familles de noeuds sont > 0 - - les numeros de familles des elements sont < 0 - - rien d'imposer sur les noms de familles - */ - - /* la famille 0 */ - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_0"); - numfam = 0; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, - gro,0); - } - printf("MEDfamCr : %d \n",ret); - - /* on cree : - - 1 familles d'elements de dimension (d) - en fait de face (-10) - */ - - if (ret == 0) - { - numfam = -1; - strcpy(nomfam,"FAMILLE_CELL_"); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe0"); - ngro = 1; - - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - /***************************************************************************/ - /* - Les champs - */ - if (ret == 0) - { - ret = MEDchampCr(fid,champ1,MED_INT32,champ1_comp,champ1_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ1, (unsigned char *)fieldnodeint, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - MED_NOPDT," ", 0., MED_NONOR); - - printf("MEDchampEcr : %d \n",ret); - } - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ2,MED_FLOAT64,champ2_comp,champ2_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - 1,"S ", 1.1 , MED_NONOR); - printf("MEDchampEcr1 : %d \n",ret); - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble2, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - 2,"S ", 1.2 , MED_NONOR); - printf("MEDchampEcr2 : %d \n",ret); - } - } - - /* on met champ2 sans pas de temps pour pouvoir le lire aussi par defaut ! */ - if (ret == 0) - { - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - MED_NOPDT," ", 0. , MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ3,MED_FLOAT64,champ3_comp,champ3_unit,2); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble, - MED_NO_INTERLACE, nquad4, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_QUAD4, - MED_NOPDT," ", 0., MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - } - - /***************************************************************************/ - - ret = MEDfermer(fid); - printf("MEDfermer : %d\n",ret); - - return 0; -} diff --git a/src/MEDMEM/create_mesh_c2q4s2.c b/src/MEDMEM/create_mesh_c2q4s2.c deleted file mode 100644 index 4befc6523..000000000 --- a/src/MEDMEM/create_mesh_c2q4s2.c +++ /dev/null @@ -1,308 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// -/* - creation d'une geometrie 2d : un cube [0,1]^2 - maillé uniformement en quadrangle reguliers; - avec en plus une partie des aretes (une partie - des arretes de la frontiere) du maillage. - ATTENTION : 3 noeuds dans chaque direction -*/ - -#include <med.h> -#include <string.h> - -int main (int argc, char **argv) -{ - med_err ret; - med_idt fid; - char maa[MED_TAILLE_NOM+1] = "carre_en_quad4_seg2"; - char maadesc[MED_TAILLE_DESC+1] = "Example de maillage non structure 2D"; - med_int mdim = 2; - med_int nnoe = 9; - /* - les noeuds: - */ - med_float coo[18] = { - 0.0, 0.0, - 0.5, 0.0, - 1.0, 0.0, - 0.0, 0.5, - 0.5, 0.5, - 1.0, 0.5, - 0.0, 1.0, - 0.5, 1.0, - 1.0, 1.0 - }; - char nomcoo[2*MED_TAILLE_PNOM+1] = "x y "; - char unicoo[2*MED_TAILLE_PNOM+1] = "cm cm "; - /* char nomnoe[19*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4";*/ - char *nomnoe ; - med_int numnoe[9] = {1,2,3,4,5,6,7,8,9}; - med_int nufano[9] = {0,0,0,0,0,0,0,0,0}; - /* - les elements: - */ - med_int nquad4 = 4; - med_int quad4[16] = { - 4, 5, 2, 1, - 5, 6, 3, 2, - 7, 8, 5, 4, - 8, 9, 6, 5 - }; - char nomquad4[MED_TAILLE_PNOM*4+1] = "quad1 quad2 quad3 quad4 "; - med_int numquad4[4] = {1,2,3,4}; - med_int nufaquad4[4] = {-10,-10,0,0}; - - /* - Les Faces qui dans ce cas (2D) sont des arretes - */ - - med_int nseg2 = 6; - med_int seg2[18] = { - 6, 3, 0, - 8, 9, 0, - 3, 2, 0, - 9, 6, 0, - 2, 5, 0, - 5, 8, 0 - }; - char nomseg2[MED_TAILLE_PNOM*6+1] = "seg1 seg2 seg3 seg4 seg5 seg6 "; - med_int numseg2[6] = {1,2,3,4,5,6}; - med_int nufaseg2[6] = {-1,-2,-1,-1,-2,-2}; - - char nomfam[MED_TAILLE_NOM+1]; - med_int numfam; - char attdes[MED_TAILLE_DESC+1]; - med_int natt; - med_int attide; - med_int attval; - med_int ngro; - char gro[MED_TAILLE_LNOM+1]; - int i; - int nfame = 1; - int nfamn = 1; - - /* - Some fields : 2 on nodes : one int and one double , one on cells : double - */ - char champ1[MED_TAILLE_NOM+1]="fieldnodeint" ; - char champ1_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ1_unit[MED_TAILLE_PNOM+1]="M " ; - med_int fieldnodeint[9] = {1,1,3,2,2,3,4,4,5}; - - char champ2[MED_TAILLE_NOM+1]="fieldnodedouble" ; - char champ2_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ2_unit[MED_TAILLE_PNOM+1]="J " ; - med_float fieldnodedouble1[9] = {1.,3.,4.,1.,3.,4.,3.,2.,5.}; - med_float fieldnodedouble2[9] = {1.,2.,2.,3.,3.,3.,4.,4.,5.}; - - char champ3[MED_TAILLE_NOM+1]="fieldcelldouble" ; - char champ3_comp[MED_TAILLE_PNOM*2+1]="comp1 comp2 " ; - char champ3_unit[MED_TAILLE_PNOM*2+1]="M/S m/s " ; - med_float fieldcelldouble[4*2] = {0.,1.,1.,1.,1.,2.,2.,3.}; - - /***************************************************************************/ - fid = MEDouvrir("carre_en_quad4_seg2.med",MED_LECTURE_ECRITURE); - if (fid < 0) - ret = -1; - else - ret = 0; - printf("MEDouvrir : %d\n",ret); - - /***************************************************************************/ - if (ret == 0) - ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); - printf("MEDmaaCr : %d\n",ret); - if (ret == 0) - ret = MEDunvCr(fid,maa); - printf("MEDunvCr : %d\n",ret); - - /***************************************************************************/ - if (ret == 0) - ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, - nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, - nufano,nnoe); - printf("MEDnoeudsEcr : %d\n",ret); - - /* ecriture des mailles MED_QUAD4 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,quad4,MED_FULL_INTERLACE, - nomquad4,MED_FAUX,numquad4,MED_VRAI,nufaquad4,nquad4, - MED_MAILLE,MED_QUAD4,MED_NOD); - printf("MEDelementsEcr : %d \n",ret); - - /* ecriture des mailles MED_SEG2 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,seg2,MED_FULL_INTERLACE, - nomseg2,MED_FAUX,numseg2,MED_VRAI,nufaseg2,nseg2, - MED_MAILLE,MED_SEG2,MED_NOD); - printf("%d \n",ret); - - /***************************************************************************/ - /* ecriture des familles */ - /* Conventions : - - toujours creer une famille de numero 0 ne comportant aucun attribut - ni groupe (famille de reference pour les noeuds ou les elements - qui ne sont rattaches a aucun groupe ni attribut) - - les numeros de familles de noeuds sont > 0 - - les numeros de familles des elements sont < 0 - - rien d'imposer sur les noms de familles - */ - - /* la famille 0 */ - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_0"); - numfam = 0; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, - gro,0); - } - printf("%d \n",ret); - - /* on cree : - - 1 familles d'elements de dimension (d-1) - en fait de edge (-1) - - 1 familles d'elements de dimension (d-1) - en fait de edge (-2) - - 1 familles d'elements de dimension (d) - en fait de face (-10) - */ - - if (ret == 0) - { - numfam = -1; - strcpy(nomfam,"FAMILLE_EDGE_"); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe1"); - ngro = 1; - - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - if (ret == 0) - { - numfam = -2; - strcpy(nomfam,"FAMILLE_EDGE_"); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe1"); - ngro = 1; - - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - if (ret == 0) - { - numfam = -10; - strcpy(nomfam,"FAMILLE_CELL_"); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe0"); - ngro = 1; - - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - /***************************************************************************/ - /* - Les champs - */ - if (ret == 0) - { - ret = MEDchampCr(fid,champ1,MED_INT32,champ1_comp,champ1_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ1, (unsigned char *)fieldnodeint, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - MED_NOPDT," ", 0., MED_NONOR); - - printf("MEDchampEcr : %d \n",ret); - } - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ2,MED_FLOAT64,champ2_comp,champ2_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - 1,"S ", 1.1 , MED_NONOR); - printf("MEDchampEcr1 : %d \n",ret); - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble2, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - 2,"S ", 1.2 , MED_NONOR); - printf("MEDchampEcr2 : %d \n",ret); - } - } - - /* on met champ2 sans pas de temps pour pouvoir le lire aussi par defaut !*/ - if (ret == 0) - { - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - MED_NOPDT," ", 0. , MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ3,MED_FLOAT64,champ3_comp,champ3_unit,2); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble, - MED_NO_INTERLACE, nquad4, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_QUAD4, - MED_NOPDT," ", 0., MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - } - - /***************************************************************************/ - - ret = MEDfermer(fid); - printf("%d\n",ret); - - return 0; -} diff --git a/src/MEDMEM/create_mesh_c2q4s2_wrong.c b/src/MEDMEM/create_mesh_c2q4s2_wrong.c deleted file mode 100644 index e32a41881..000000000 --- a/src/MEDMEM/create_mesh_c2q4s2_wrong.c +++ /dev/null @@ -1,312 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// -/* - creation d'une geometrie 2d : un cube [0,1]^2 - maillé uniformement en quadrangle reguliers; - avec en plus une partie des aretes (une partie - des arretes de la frontiere) du maillage. - ATTENTION : 3 noeuds dans chaque direction -*/ - -#include <med.h> -#include <string.h> - -int main (int argc, char **argv) -{ - med_err ret; - med_idt fid; - char maa[MED_TAILLE_NOM+1] = "carre_en_quad4_seg2_wrong"; - char maadesc[MED_TAILLE_DESC+1] = "Example de maillage non structure 2D"; - med_int mdim = 2; - med_int nnoe = 9; - /* - les noeuds: - */ - med_float coo[18] = { - 0.0, 0.0, - 0.5, 0.0, - 1.0, 0.0, - 0.0, 0.5, - 0.5, 0.5, - 1.0, 0.5, - 0.0, 1.0, - 0.5, 1.0, - 1.0, 1.0 - }; - char nomcoo[2*MED_TAILLE_PNOM+1] = "x y "; - char unicoo[2*MED_TAILLE_PNOM+1] = "cm cm "; - /* char nomnoe[19*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4";*/ - char *nomnoe ; - med_int numnoe[9] = {1,2,3,4,5,6,7,8,9}; - med_int nufano[9] = {0,0,0,0,0,0,0,0,0}; - /* - les elements: - */ - med_int nquad4 = 4; - med_int quad4[16] = { - 4, 5, 2, 1, - 5, 6, 3, 2, - 7, 8, 5, 4, - 8, 9, 6, 5 - }; - char nomquad4[MED_TAILLE_PNOM*4+1] = "quad1 quad2 quad3 quad4 "; - med_int numquad4[4] = {1,2,3,4}; - med_int nufaquad4[4] = {-10,-10,0,0}; - - /* - Les Faces qui dans ce cas (2D) sont des arretes - - a face is wrongly oriented, it is just to test the applidation - duplicateMEDMESH - */ - - med_int nseg2 = 6; - med_int seg2[12] = { - 6, 3, - 8, 9, - 3, 2, - /*9, 6,*/ - 6, 9, - 2, 5, - 5, 8 - }; - char nomseg2[MED_TAILLE_PNOM*6+1] = "seg1 seg2 seg3 seg4 seg5 seg6 "; - med_int numseg2[6] = {1,2,3,4,5,6}; - med_int nufaseg2[6] = {-1,-2,-1,-1,-2,-2}; - - char nomfam[MED_TAILLE_NOM+1]; - med_int numfam; - char attdes[MED_TAILLE_DESC+1]; - med_int natt; - med_int attide; - med_int attval; - med_int ngro; - char gro[MED_TAILLE_LNOM+1]; - int i; - int nfame = 1; - int nfamn = 1; - - /* - Some fields : 2 on nodes : one int and one double , one on cells : double - */ - char champ1[MED_TAILLE_NOM+1]="fieldnodeint" ; - char champ1_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ1_unit[MED_TAILLE_PNOM+1]="M " ; - med_int fieldnodeint[9] = {1,1,3,2,2,3,4,4,5}; - - char champ2[MED_TAILLE_NOM+1]="fieldnodedouble" ; - char champ2_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ2_unit[MED_TAILLE_PNOM+1]="J " ; - med_float fieldnodedouble1[9] = {1.,3.,4.,1.,3.,4.,3.,2.,5.}; - med_float fieldnodedouble2[9] = {1.,2.,2.,3.,3.,3.,4.,4.,5.}; - - char champ3[MED_TAILLE_NOM+1]="fieldcelldouble" ; - char champ3_comp[MED_TAILLE_PNOM*2+1]="comp1 comp2 " ; - char champ3_unit[MED_TAILLE_PNOM*2+1]="M/S m/s " ; - med_float fieldcelldouble[4*2] = {0.,1.,1.,1.,1.,2.,2.,3.}; - - /***************************************************************************/ - fid = MEDouvrir("carre_en_quad4_seg2_wrong.med",MED_LECTURE_ECRITURE); - if (fid < 0) - ret = -1; - else - ret = 0; - printf("MEDouvrir : %d\n",ret); - - /***************************************************************************/ - if (ret == 0) - ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); - printf("MEDmaaCr : %d\n",ret); - if (ret == 0) - ret = MEDunvCr(fid,maa); - printf("MEDunvCr : %d\n",ret); - - /***************************************************************************/ - if (ret == 0) - ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, - nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, - nufano,nnoe); - printf("MEDnoeudsEcr : %d\n",ret); - - /* ecriture des mailles MED_QUAD4 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,quad4,MED_FULL_INTERLACE, - nomquad4,MED_FAUX,numquad4,MED_VRAI,nufaquad4,nquad4, - MED_MAILLE,MED_QUAD4,MED_NOD); - printf("MEDelementsEcr : %d \n",ret); - - /* ecriture des mailles MED_SEG2 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,seg2,MED_FULL_INTERLACE, - nomseg2,MED_FAUX,numseg2,MED_VRAI,nufaseg2,nseg2, - MED_ARETE,MED_SEG2,MED_NOD); - printf("MEDelementsEcr : %d \n",ret); - - /***************************************************************************/ - /* ecriture des familles */ - /* Conventions : - - toujours creer une famille de numero 0 ne comportant aucun attribut - ni groupe (famille de reference pour les noeuds ou les elements - qui ne sont rattaches a aucun groupe ni attribut) - - les numeros de familles de noeuds sont > 0 - - les numeros de familles des elements sont < 0 - - rien d'imposer sur les noms de familles - */ - - /* la famille 0 */ - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_0"); - numfam = 0; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, - gro,0); - } - printf("%d \n",ret); - - /* on cree : - - 1 familles d'elements de dimension (d-1) - en fait de edge (-1) - - 1 familles d'elements de dimension (d-1) - en fait de edge (-2) - - 1 familles d'elements de dimension (d) - en fait de face (-10) - */ - - if (ret == 0) - { - numfam = -1; - strcpy(nomfam,"FAMILLE_EDGE_"); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe1"); - ngro = 1; - - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - if (ret == 0) - { - numfam = -2; - strcpy(nomfam,"FAMILLE_EDGE_"); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe1"); - ngro = 1; - - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - if (ret == 0) - { - numfam = -10; - strcpy(nomfam,"FAMILLE_CELL_"); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe0"); - ngro = 1; - - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - /***************************************************************************/ - /* - Les champs - */ - if (ret == 0) - { - ret = MEDchampCr(fid,champ1,MED_INT32,champ1_comp,champ1_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ1, (unsigned char *)fieldnodeint, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - MED_NOPDT," ", 0., MED_NONOR); - - printf("MEDchampEcr : %d \n",ret); - } - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ2,MED_FLOAT64,champ2_comp,champ2_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - 1,"S ", 1.1 , MED_NONOR); - printf("MEDchampEcr1 : %d \n",ret); - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble2, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - 2,"S ", 1.2 , MED_NONOR); - printf("MEDchampEcr2 : %d \n",ret); - } - } - - /* on met champ2 sans pas de temps pour pouvoir le lire aussi par defaut !*/ - if (ret == 0) - { - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - MED_NOPDT," ", 0. , MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ3,MED_FLOAT64,champ3_comp,champ3_unit,2); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble, - MED_NO_INTERLACE, nquad4, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_QUAD4, - MED_NOPDT," ", 0., MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - } - - /***************************************************************************/ - - ret = MEDfermer(fid); - printf("%d\n",ret); - - return 0; -} diff --git a/src/MEDMEM/create_mesh_c3h8.c b/src/MEDMEM/create_mesh_c3h8.c deleted file mode 100644 index 7555cc25c..000000000 --- a/src/MEDMEM/create_mesh_c3h8.c +++ /dev/null @@ -1,301 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// -/* - creation d'une geometrie 3d : un cube [0,1]^3 - maillé uniformement en hexahedres reguliers; - avec en plus une partie des faces (une partie - des faces de la frontiere) du maillage. - ATTENTION : 3 noeuds dans chaque direction -*/ - -#include <med.h> -#include <string.h> - -int main (int argc, char **argv) -{ - med_err ret; - med_idt fid; - char maa[MED_TAILLE_NOM+1] = "CUBE_EN_HEXA8"; - char maadesc[MED_TAILLE_DESC+1] = "Example de maillage non structure 3D"; - med_int mdim = 3; - med_int nnoe = 27; - /* - les noeuds: - */ - med_float coo[81] = { - 0.0, 0.0, 0.0, - 0.5, 0.0, 0.0, - 1.0, 0.0, 0.0, - 0.0, 0.5, 0.0, - 0.5, 0.5, 0.0, - 1.0, 0.5, 0.0, - 0.0, 1.0, 0.0, - 0.5, 1.0, 0.0, - 1.0, 1.0, 0.0, - 0.0, 0.0, 0.5, - 0.5, 0.0, 0.5, - 1.0, 0.0, 0.5, - 0.0, 0.5, 0.5, - 0.5, 0.5, 0.5, - 1.0, 0.5, 0.5, - 0.0, 1.0, 0.5, - 0.5, 1.0, 0.5, - 1.0, 1.0, 0.5, - 0.0, 0.0, 1.0, - 0.5, 0.0, 1.0, - 1.0, 0.0, 1.0, - 0.0, 0.5, 1.0, - 0.5, 0.5, 1.0, - 1.0, 0.5, 1.0, - 0.0, 1.0, 1.0, - 0.5, 1.0, 1.0, - 1.0, 1.0, 1.0 - }; - char nomcoo[3*MED_TAILLE_PNOM+1] = "x y z "; - char unicoo[3*MED_TAILLE_PNOM+1] = "cm cm cm "; - /* char nomnoe[19*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4";*/ - char *nomnoe ; - med_int numnoe[27] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27}; - med_int nufano[27] = {1,1,1,1,1,1,1,1,1,3,3,3,3,0,3,3,3,3,2,2,2,2,2,2,2,2,2}; - /* - les elements: - */ - med_int nhexa8 = 8; - med_int hexa8[64] = { - 4, 13, 14, 5, 1, 10, 11, 2, - 5, 14, 15, 6, 2, 11, 12, 3, - 7, 16, 17, 8, 4, 13, 14, 5, - 8, 17, 18, 9, 5, 14, 15, 6, - 13, 22, 23, 14, 10, 19, 20, 11, - 14, 23, 24, 15, 11, 20, 21, 12, - 16, 25, 26, 17, 13, 22, 23, 14, - 17, 26, 27, 18, 14, 23, 24, 15 - }; - char nomhexa8[MED_TAILLE_PNOM*8+1] = "hexa1 hexa2 hexa3 hexa4 hexa5 hexa6 hexa7 hexa8 "; - med_int numhexa8[8] = {1,2,3,4,5,6,7,8}; - med_int nufahexa8[8] = {-1,-1,-1,-1,-2,-2,-2,-2}; - - char nomfam[MED_TAILLE_NOM+1]; - med_int numfam; - char attdes[MED_TAILLE_DESC+1]; - med_int natt; - med_int attide; - med_int attval; - med_int ngro; - char gro[MED_TAILLE_LNOM+1]; - int i; - int nfame = 1; - int nfamn = 1; - int nfamf = 1; - - /* - Some fields : 2 on nodes : one int and one double , one on cells : double - */ - - char champ1[MED_TAILLE_NOM+1]="fieldnodeint" ; - char champ1_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ1_unit[MED_TAILLE_PNOM+1]="M " ; - med_int fieldnodeint[27] = {1,1,3,2,2,3,4,4,5,1,1,3,2,2,3,4,4,5,1,1,3,2,2,3,4,4,5}; - - char champ2[MED_TAILLE_NOM+1]="fieldnodedouble" ; - char champ2_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ2_unit[MED_TAILLE_PNOM+1]="J " ; - med_float fieldnodedouble1[27] = {1.,3.,4.,1.,3.,4.,3.,2.,5.,1.,3.,4.,1.,3.,4.,3.,2.,5.,1.,3.,4.,1.,3.,4.,3.,2.,5.}; - med_float fieldnodedouble2[27] = {1.,2.,2.,3.,3.,3.,4.,4.,5.,1.,2.,2.,3.,3.,3.,4.,4.,5.,1.,2.,2.,3.,3.,3.,4.,4.,5.}; - - char champ3[MED_TAILLE_NOM+1]="fieldcelldouble" ; - char champ3_comp[MED_TAILLE_PNOM*3+1]="comp1 comp2 comp3 " ; - char champ3_unit[MED_TAILLE_PNOM*3+1]="M/S m/s m/s " ; - med_float fieldcelldouble[8*3] = {0.,1.,1.,1.,1.,2.,2.,3.,0.,1.,1.,1.,1.,2.,2.,3.,0.,1.,1.,1.,1.,2.,2.,3.}; - - /***************************************************************************/ - fid = MEDouvrir("cube_hexa8.med",MED_LECTURE_ECRITURE); - if (fid < 0) - ret = -1; - else - ret = 0; - printf("MEDouvrir : %d\n",ret); - - /***************************************************************************/ - if (ret == 0) - ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); - printf("MEDmaaCr : %d\n",ret); - if (ret == 0) - ret = MEDunvCr(fid,maa); - printf("MEDunvCr : %d\n",ret); - - /***************************************************************************/ - if (ret == 0) - ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, - nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, - nufano,nnoe); - printf("MEDnoeudsEcr : %d\n",ret); - - /* ecriture des mailles MED_HEXA8 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,hexa8,MED_FULL_INTERLACE, - nomhexa8,MED_FAUX,numhexa8,MED_VRAI,nufahexa8,nhexa8, - MED_MAILLE,MED_HEXA8,MED_NOD); - printf("MEDelementsEcr : %d \n",ret); - - /***************************************************************************/ - /* ecriture des familles */ - /* Conventions : - - toujours creer une famille de numero 0 ne comportant aucun attribut - ni groupe (famille de reference pour les noeuds ou les elements - qui ne sont rattaches a aucun groupe ni attribut) - - les numeros de familles de noeuds sont > 0 - - les numeros de familles des elements sont < 0 - - rien d'imposer sur les noms de familles - */ - - /* la famille 0 */ - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_0"); - numfam = 0; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, - gro,0); - } - printf("%d \n",ret); - - /* on cree : - - 2 familles d'elements (-1,-2) et - - 3 familles de noeuds (1,2,3) - */ - - if (ret == 0) - { - nfame = 2; - for (i=0;i<nfame;i++) - { - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_ELEMENT_"); - numfam = -(i+1); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe1"); - ngro = 1; - - /*printf("nomfam : %s - numfam : %d - attide : %d - attval : %d - ngro : %d \n",nomfam,numfam,attide,attval,ngro);*/ - - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - } - } - - if (ret == 0) - { - nfamn = 3; - for (i=0;i<nfamn;i++) - { - if(ret == 0) - { - strcpy(nomfam,"FAMILLE_NOEUD_"); - numfam = i+1; - sprintf(nomfam,"%s%d",nomfam,numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe2"); - ngro = 1; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - } - } - - /***************************************************************************/ - /* - Les champs - */ - if (ret == 0) - { - ret = MEDchampCr(fid,champ1,MED_INT32,champ1_comp,champ1_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ1, (unsigned char *)fieldnodeint, - MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - MED_NOPDT," ", 0., MED_NONOR); - - printf("MEDchampEcr : %d \n",ret); - } - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ2,MED_FLOAT64,champ2_comp,champ2_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, - MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - 1,"S ", 1.1 , MED_NONOR); - printf("MEDchampEcr1 : %d \n",ret); - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble2, - MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - 2,"S ", 1.2 , MED_NONOR); - printf("MEDchampEcr2 : %d \n",ret); - } - } - - /* on met champ2 sans pas de temps pour pouvoir le lire aussi par defaut !*/ - if (ret == 0) - { - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, - MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - MED_NOPDT," ", 0. , MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ3,MED_FLOAT64,champ3_comp,champ3_unit,3); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble, - MED_FULL_INTERLACE, nhexa8, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_HEXA8, - MED_NOPDT," ", 0., MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - } - - /***************************************************************************/ - - ret = MEDfermer(fid); - printf("%d\n",ret); - - return 0; -} diff --git a/src/MEDMEM/create_mesh_c3h8q4.c b/src/MEDMEM/create_mesh_c3h8q4.c deleted file mode 100644 index ee7705cac..000000000 --- a/src/MEDMEM/create_mesh_c3h8q4.c +++ /dev/null @@ -1,358 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// -/* - creation d'une geometrie 3d : un cube [0,1]^3 - maillé uniformement en hexahedres reguliers; - avec en plus une partie des faces (une partie - des faces de la frontiere) du maillage. - ATTENTION : 3 noeuds dans chaque direction -*/ - -#include <med.h> -#include <string.h> - -int main (int argc, char **argv) -{ - med_err ret; - med_idt fid; - char maa[MED_TAILLE_NOM+1] = "CUBE_EN_HEXA8_QUAD4"; - char maadesc[MED_TAILLE_DESC+1] = "Example de maillage non structure 3D"; - med_int mdim = 3; - med_int nnoe = 27; - /* - les noeuds: - */ - med_float coo[81] = { - 0.0, 0.0, 0.0, - 0.5, 0.0, 0.0, - 1.0, 0.0, 0.0, - 0.0, 0.5, 0.0, - 0.5, 0.5, 0.0, - 1.0, 0.5, 0.0, - 0.0, 1.0, 0.0, - 0.5, 1.0, 0.0, - 1.0, 1.0, 0.0, - 0.0, 0.0, 0.5, - 0.5, 0.0, 0.5, - 1.0, 0.0, 0.5, - 0.0, 0.5, 0.5, - 0.5, 0.5, 0.5, - 1.0, 0.5, 0.5, - 0.0, 1.0, 0.5, - 0.5, 1.0, 0.5, - 1.0, 1.0, 0.5, - 0.0, 0.0, 1.0, - 0.5, 0.0, 1.0, - 1.0, 0.0, 1.0, - 0.0, 0.5, 1.0, - 0.5, 0.5, 1.0, - 1.0, 0.5, 1.0, - 0.0, 1.0, 1.0, - 0.5, 1.0, 1.0, - 1.0, 1.0, 1.0 - }; - char nomcoo[3*MED_TAILLE_PNOM+1] = "x y z "; - char unicoo[3*MED_TAILLE_PNOM+1] = "cm cm cm "; - /* char nomnoe[19*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4";*/ - char *nomnoe ; - med_int numnoe[27] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27}; - med_int nufano[27] = {1,1,1,1,1,1,1,1,1,3,3,3,3,0,3,3,3,3,2,2,2,2,2,2,2,2,2}; - /* - les elements: - */ - med_int nhexa8 = 8; - med_int hexa8[64] = { - 4, 13, 14, 5, 1, 10, 11, 2, - 5, 14, 15, 6, 2, 11, 12, 3, - 7, 16, 17, 8, 4, 13, 14, 5, - 8, 17, 18, 9, 5, 14, 15, 6, - 13, 22, 23, 14, 10, 19, 20, 11, - 14, 23, 24, 15, 11, 20, 21, 12, - 16, 25, 26, 17, 13, 22, 23, 14, - 17, 26, 27, 18, 14, 23, 24, 15 - }; - char nomhexa8[MED_TAILLE_PNOM*8+1] = "hexa1 hexa2 hexa3 hexa4 hexa5 hexa6 hexa7 hexa8 "; - med_int numhexa8[8] = {1,2,3,4,5,6,7,8}; - med_int nufahexa8[8] = {-1,-1,-1,-1,-2,-2,-2,-2}; - - /* - Les Faces qui dans ce cas (2D) sont des arretes - */ - - med_int nquad4 = 8; - med_int quad4[40] = { - 20, 21, 24, 23, 0, - 22, 23, 26, 25, 0, - 19, 20, 23, 22, 0, - 23, 24, 27, 26, 0, - 1 , 4, 5, 2, 0, - 5, 8, 9, 6, 0, - 2, 5, 6, 3, 0, - 7, 8, 5, 4, 0 - }; - - char nomquad4[MED_TAILLE_PNOM*8+1] = "quad1 quad2 quad3 quad4 quad5 quad6 quad7 quad8 "; - med_int numquad4[8] = {1,2,3,4,5,6,7,8}; - med_int nufaquad4[8] = {-3,-3,-3,-3,-4, -4, -4 , -4}; - - char nomfam[MED_TAILLE_NOM+1]; - med_int numfam; - char attdes[MED_TAILLE_DESC+1]; - med_int natt; - med_int attide; - med_int attval; - med_int ngro; - char gro[MED_TAILLE_LNOM+1]; - int i; - int nfame = 1; - int nfamn = 1; - int nfamf = 1; - - /* - Some fields : 2 on nodes : one int and one double , one on cells : double - */ - - char champ1[MED_TAILLE_NOM+1]="fieldnodeint" ; - char champ1_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ1_unit[MED_TAILLE_PNOM+1]="M " ; - med_int fieldnodeint[27] = {1,1,3,2,2,3,4,4,5,1,1,3,2,2,3,4,4,5,1,1,3,2,2,3,4,4,5}; - - char champ2[MED_TAILLE_NOM+1]="fieldnodedouble" ; - char champ2_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ2_unit[MED_TAILLE_PNOM+1]="J " ; - med_float fieldnodedouble1[27] = {1.,3.,4.,1.,3.,4.,3.,2.,5.,1.,3.,4.,1.,3.,4.,3.,2.,5.,1.,3.,4.,1.,3.,4.,3.,2.,5.}; - med_float fieldnodedouble2[27] = {1.,2.,2.,3.,3.,3.,4.,4.,5.,1.,2.,2.,3.,3.,3.,4.,4.,5.,1.,2.,2.,3.,3.,3.,4.,4.,5.}; - - char champ3[MED_TAILLE_NOM+1]="fieldcelldouble" ; - char champ3_comp[MED_TAILLE_PNOM*3+1]="comp1 comp2 comp3 " ; - char champ3_unit[MED_TAILLE_PNOM*3+1]="M/S m/s m/s " ; - med_float fieldcelldouble[8*3] = {0.,1.,1.,1.,1.,2.,2.,3.,0.,1.,1.,1.,1.,2.,2.,3.,0.,1.,1.,1.,1.,2.,2.,3.}; - - /***************************************************************************/ - fid = MEDouvrir("cube_hexa8_quad4.med",MED_LECTURE_ECRITURE); - if (fid < 0) - ret = -1; - else - ret = 0; - printf("MEDouvrir : %d\n",ret); - - /***************************************************************************/ - if (ret == 0) - ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); - printf("MEDmaaCr : %d\n",ret); - if (ret == 0) - ret = MEDunvCr(fid,maa); - printf("MEDunvCr : %d\n",ret); - - /***************************************************************************/ - if (ret == 0) - ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, - nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, - nufano,nnoe); - printf("MEDnoeudsEcr : %d\n",ret); - - /* ecriture des mailles MED_HEXA8 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,hexa8,MED_FULL_INTERLACE, - nomhexa8,MED_FAUX,numhexa8,MED_VRAI,nufahexa8,nhexa8, - MED_MAILLE,MED_HEXA8,MED_NOD); - printf("MEDelementsEcr : %d \n",ret); - - /* ecriture des mailles MED_QUAD4 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,quad4,MED_FULL_INTERLACE, - nomquad4,MED_FAUX,numquad4,MED_VRAI,nufaquad4,nquad4, - MED_MAILLE,MED_QUAD4,MED_NOD); - printf("%d \n",ret); - - /***************************************************************************/ - /* ecriture des familles */ - /* Conventions : - - toujours creer une famille de numero 0 ne comportant aucun attribut - ni groupe (famille de reference pour les noeuds ou les elements - qui ne sont rattaches a aucun groupe ni attribut) - - les numeros de familles de noeuds sont > 0 - - les numeros de familles des elements sont < 0 - - rien d'imposer sur les noms de familles - */ - - /* la famille 0 */ - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_0"); - numfam = 0; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, - gro,0); - } - printf("%d \n",ret); - - /* on cree : - - 2 familles d'elements (-1,-2) et - - 3 familles de noeuds (1,2,3) - - 1 famille(s) d'elements de dimension (d-1) - en fait de face (-3) - */ - - if (ret == 0) - { - nfame = 2; - for (i=0;i<nfame;i++) - { - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_ELEMENT_"); - numfam = -(i+1); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe1"); - ngro = 1; - - /*printf("nomfam : %s - numfam : %d - attide : %d - attval : %d - ngro : %d \n",nomfam,numfam,attide,attval,ngro);*/ - - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - } - } - - if (ret == 0) - { - nfamn = 3; - for (i=0;i<nfamn;i++) - { - if(ret == 0) - { - strcpy(nomfam,"FAMILLE_NOEUD_"); - numfam = i+1; - sprintf(nomfam,"%s%d",nomfam,numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe2"); - ngro = 1; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - } - } - - if (ret == 0) - { - nfamf = 2; - for (i=0;i<nfamf;i++) - { - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_FACE_"); - numfam = -(i+3); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe3"); - ngro = 1; - /*printf("nomfam : %s - numfam : %d - attide : %d - attval : %d - ngro : %d \n",nomfam,numfam,attide,attval,ngro);*/ - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - } - } - - /***************************************************************************/ - /* - Les champs - */ - if (ret == 0) - { - ret = MEDchampCr(fid,champ1,MED_INT32,champ1_comp,champ1_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ1, (unsigned char *)fieldnodeint, - MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - MED_NOPDT," ", 0., MED_NONOR); - - printf("MEDchampEcr : %d \n",ret); - } - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ2,MED_FLOAT64,champ2_comp,champ2_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, - MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - 1,"S ", 1.1 , MED_NONOR); - printf("MEDchampEcr1 : %d \n",ret); - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble2, - MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - 2,"S ", 1.2 , MED_NONOR); - printf("MEDchampEcr2 : %d \n",ret); - } - } - - /* on met champ2 sans pas de temps pour pouvoir le lire aussi par defaut !*/ - if (ret == 0) - { - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, - MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - MED_NOPDT," ", 0. , MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ3,MED_FLOAT64,champ3_comp,champ3_unit,3); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble, - MED_FULL_INTERLACE, nhexa8, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_HEXA8, - MED_NOPDT," ", 0., MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - } - - /***************************************************************************/ - - ret = MEDfermer(fid); - printf("%d\n",ret); - - return 0; -} diff --git a/src/MEDMEM/create_mesh_c3h8q4_wrong.c b/src/MEDMEM/create_mesh_c3h8q4_wrong.c deleted file mode 100644 index 62a1d2060..000000000 --- a/src/MEDMEM/create_mesh_c3h8q4_wrong.c +++ /dev/null @@ -1,362 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// -/* - creation d'une geometrie 3d : un cube [0,1]^3 - maillé uniformement en hexahedres reguliers; - avec en plus une partie des faces (une partie - des faces de la frontiere) du maillage. - ATTENTION : 3 noeuds dans chaque direction -*/ - -#include <med.h> -#include <string.h> - -int main (int argc, char **argv) -{ - med_err ret; - med_idt fid; - char maa[MED_TAILLE_NOM+1] = "CUBE_EN_HEXA8_QUAD4_WRONG"; - char maadesc[MED_TAILLE_DESC+1] = "Example de maillage non structure 3D"; - med_int mdim = 3; - med_int nnoe = 27; - /* - les noeuds: - */ - med_float coo[81] = { - 0.0, 0.0, 0.0, - 0.5, 0.0, 0.0, - 1.0, 0.0, 0.0, - 0.0, 0.5, 0.0, - 0.5, 0.5, 0.0, - 1.0, 0.5, 0.0, - 0.0, 1.0, 0.0, - 0.5, 1.0, 0.0, - 1.0, 1.0, 0.0, - 0.0, 0.0, 0.5, - 0.5, 0.0, 0.5, - 1.0, 0.0, 0.5, - 0.0, 0.5, 0.5, - 0.5, 0.5, 0.5, - 1.0, 0.5, 0.5, - 0.0, 1.0, 0.5, - 0.5, 1.0, 0.5, - 1.0, 1.0, 0.5, - 0.0, 0.0, 1.0, - 0.5, 0.0, 1.0, - 1.0, 0.0, 1.0, - 0.0, 0.5, 1.0, - 0.5, 0.5, 1.0, - 1.0, 0.5, 1.0, - 0.0, 1.0, 1.0, - 0.5, 1.0, 1.0, - 1.0, 1.0, 1.0 - }; - char nomcoo[3*MED_TAILLE_PNOM+1] = "x y z "; - char unicoo[3*MED_TAILLE_PNOM+1] = "cm cm cm "; - /* char nomnoe[19*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4";*/ - char *nomnoe ; - med_int numnoe[27] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27}; - med_int nufano[27] = {1,1,1,1,1,1,1,1,1,3,3,3,3,0,3,3,3,3,2,2,2,2,2,2,2,2,2}; - /* - les elements: - */ - med_int nhexa8 = 8; - med_int hexa8[64] = { - 4, 13, 14, 5, 1, 10, 11, 2, - 5, 14, 15, 6, 2, 11, 12, 3, - 7, 16, 17, 8, 4, 13, 14, 5, - 8, 17, 18, 9, 5, 14, 15, 6, - 13, 22, 23, 14, 10, 19, 20, 11, - 14, 23, 24, 15, 11, 20, 21, 12, - 16, 25, 26, 17, 13, 22, 23, 14, - 17, 26, 27, 18, 14, 23, 24, 15 - }; - char nomhexa8[MED_TAILLE_PNOM*8+1] = "hexa1 hexa2 hexa3 hexa4 hexa5 hexa6 hexa7 hexa8 "; - med_int numhexa8[8] = {1,2,3,4,5,6,7,8}; - med_int nufahexa8[8] = {-1,-1,-1,-1,-2,-2,-2,-2}; - - /* - Les Faces qui dans ce cas (2D) sont des arretes - - a face is wrongly oriented, it is just to test the applidation - duplicateMEDMESH - */ - - med_int nquad4 = 8; - med_int quad4[32] = { - 20, 21, 24, 23, - 22, 23, 26, 25, - 19, 20, 23, 22, - 23, 24, 27, 26, - /*1 , 4, 5, 2,*/ - 1 , 2, 5, 4, - 5, 8, 9, 6, - 2, 5, 6, 3, - 7, 8, 5, 4 - }; - - char nomquad4[MED_TAILLE_PNOM*8+1] = "quad1 quad2 quad3 quad4 quad5 quad6 quad7 quad8 "; - med_int numquad4[8] = {1,2,3,4,5,6,7,8}; - med_int nufaquad4[8] = {-3,-3,-3,-3,-4, -4, -4 , -4}; - - char nomfam[MED_TAILLE_NOM+1]; - med_int numfam; - char attdes[MED_TAILLE_DESC+1]; - med_int natt; - med_int attide; - med_int attval; - med_int ngro; - char gro[MED_TAILLE_LNOM+1]; - int i; - int nfame = 1; - int nfamn = 1; - int nfamf = 1; - - /* - Some fields : 2 on nodes : one int and one double , one on cells : double - */ - - char champ1[MED_TAILLE_NOM+1]="fieldnodeint" ; - char champ1_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ1_unit[MED_TAILLE_PNOM+1]="M " ; - med_int fieldnodeint[27] = {1,1,3,2,2,3,4,4,5,1,1,3,2,2,3,4,4,5,1,1,3,2,2,3,4,4,5}; - - char champ2[MED_TAILLE_NOM+1]="fieldnodedouble" ; - char champ2_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ2_unit[MED_TAILLE_PNOM+1]="J " ; - med_float fieldnodedouble1[27] = {1.,3.,4.,1.,3.,4.,3.,2.,5.,1.,3.,4.,1.,3.,4.,3.,2.,5.,1.,3.,4.,1.,3.,4.,3.,2.,5.}; - med_float fieldnodedouble2[27] = {1.,2.,2.,3.,3.,3.,4.,4.,5.,1.,2.,2.,3.,3.,3.,4.,4.,5.,1.,2.,2.,3.,3.,3.,4.,4.,5.}; - - char champ3[MED_TAILLE_NOM+1]="fieldcelldouble" ; - char champ3_comp[MED_TAILLE_PNOM*3+1]="comp1 comp2 comp3 " ; - char champ3_unit[MED_TAILLE_PNOM*3+1]="M/S m/s m/s " ; - med_float fieldcelldouble[8*3] = {0.,1.,1.,1.,1.,2.,2.,3.,0.,1.,1.,1.,1.,2.,2.,3.,0.,1.,1.,1.,1.,2.,2.,3.}; - - /***************************************************************************/ - fid = MEDouvrir("cube_hexa8_quad4_wrong.med",MED_LECTURE_ECRITURE); - if (fid < 0) - ret = -1; - else - ret = 0; - printf("MEDouvrir : %d\n",ret); - - /***************************************************************************/ - if (ret == 0) - ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); - printf("MEDmaaCr : %d\n",ret); - if (ret == 0) - ret = MEDunvCr(fid,maa); - printf("MEDunvCr : %d\n",ret); - - /***************************************************************************/ - if (ret == 0) - ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, - nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, - nufano,nnoe); - printf("MEDnoeudsEcr : %d\n",ret); - - /* ecriture des mailles MED_HEXA8 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,hexa8,MED_FULL_INTERLACE, - nomhexa8,MED_FAUX,numhexa8,MED_VRAI,nufahexa8,nhexa8, - MED_MAILLE,MED_HEXA8,MED_NOD); - printf("MEDelementsEcr : %d \n",ret); - - /* ecriture des mailles MED_QUAD4 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,quad4,MED_FULL_INTERLACE, - nomquad4,MED_FAUX,numquad4,MED_VRAI,nufaquad4,nquad4, - MED_FACE,MED_QUAD4,MED_NOD); - printf("MEDelementsEcr : %d \n",ret); - - /***************************************************************************/ - /* ecriture des familles */ - /* Conventions : - - toujours creer une famille de numero 0 ne comportant aucun attribut - ni groupe (famille de reference pour les noeuds ou les elements - qui ne sont rattaches a aucun groupe ni attribut) - - les numeros de familles de noeuds sont > 0 - - les numeros de familles des elements sont < 0 - - rien d'imposer sur les noms de familles - */ - - /* la famille 0 */ - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_0"); - numfam = 0; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, - gro,0); - } - printf("%d \n",ret); - - /* on cree : - - 2 familles d'elements (-1,-2) et - - 3 familles de noeuds (1,2,3) - - 1 famille(s) d'elements de dimension (d-1) - en fait de face (-3) - */ - - if (ret == 0) - { - nfame = 2; - for (i=0;i<nfame;i++) - { - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_ELEMENT_"); - numfam = -(i+1); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe1"); - ngro = 1; - - /*printf("nomfam : %s - numfam : %d - attide : %d - attval : %d - ngro : %d \n",nomfam,numfam,attide,attval,ngro);*/ - - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - } - } - - if (ret == 0) - { - nfamn = 3; - for (i=0;i<nfamn;i++) - { - if(ret == 0) - { - strcpy(nomfam,"FAMILLE_NOEUD_"); - numfam = i+1; - sprintf(nomfam,"%s%d",nomfam,numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe2"); - ngro = 1; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - } - } - - if (ret == 0) - { - nfamf = 2; - for (i=0;i<nfamf;i++) - { - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_FACE_"); - numfam = -(i+3); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe3"); - ngro = 1; - /*printf("nomfam : %s - numfam : %d - attide : %d - attval : %d - ngro : %d \n",nomfam,numfam,attide,attval,ngro);*/ - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - } - } - - /***************************************************************************/ - /* - Les champs - */ - if (ret == 0) - { - ret = MEDchampCr(fid,champ1,MED_INT32,champ1_comp,champ1_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ1, (unsigned char *)fieldnodeint, - MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - MED_NOPDT," ", 0., MED_NONOR); - - printf("MEDchampEcr : %d \n",ret); - } - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ2,MED_FLOAT64,champ2_comp,champ2_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, - MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - 1,"S ", 1.1 , MED_NONOR); - printf("MEDchampEcr1 : %d \n",ret); - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble2, - MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - 2,"S ", 1.2 , MED_NONOR); - printf("MEDchampEcr2 : %d \n",ret); - } - } - - /* on met champ2 sans pas de temps pour pouvoir le lire aussi par defaut !*/ - if (ret == 0) - { - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, - MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - MED_NOPDT," ", 0. , MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ3,MED_FLOAT64,champ3_comp,champ3_unit,3); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble, - MED_FULL_INTERLACE, nhexa8, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_HEXA8, - MED_NOPDT," ", 0., MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - } - - /***************************************************************************/ - - ret = MEDfermer(fid); - printf("%d\n",ret); - - return 0; -} diff --git a/src/MEDMEM/create_poly2D.c b/src/MEDMEM/create_poly2D.c deleted file mode 100644 index 5fcf4f3a1..000000000 --- a/src/MEDMEM/create_poly2D.c +++ /dev/null @@ -1,331 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// -/* - creation d'une geometrie 2d : - maillé en 4 quadrangles reguliers - 1 triangle et 1 polygone. - -*/ - -#include <med.h> -#include <string.h> - -int main (int argc, char **argv) -{ - med_err ret; - med_idt fid; - char maa[MED_TAILLE_NOM+1] = "poly2D"; - char maadesc[MED_TAILLE_DESC+1] = "Example de maillage non structure 2D avec 1 polygone"; - med_int mdim = 2; - med_int nnoe = 11; - /* - les noeuds: - */ - med_float coo[22] = { - 0.0, 0.0, - 0.5, 0.0, - 1.0, 0.0, - 0.25, 0.5, - 0.5, 0.5, - 0.75, 0.5, - 0.0, 1.0, - 0.5, 1.0, - 1.0, 1.0, - 1.5, 0.0, - 1.5, 1.0 - }; - char nomcoo[2*MED_TAILLE_PNOM+1] = "x y "; - char unicoo[2*MED_TAILLE_PNOM+1] = "cm cm "; - /* char nomnoe[19*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4";*/ - char *nomnoe ; - med_int numnoe[11] = {1,2,3,4,5,6,7,8,9,10,11}; - med_int nufano[11] = {0,0,0,0,0,0,0,0,0,0,0}; - /* - les elements: - */ - med_int nquad4 = 4; - med_int quad4[16] = { - 4, 5, 2, 1, - 5, 6, 3, 2, - 7, 8, 5, 4, - 8, 9, 6, 5 - }; - char nomquad4[MED_TAILLE_PNOM*4+1] = "quad1 quad2 quad3 quad4 "; - med_int numquad4[4] = {1,2,3,4}; - med_int nufaquad4[4] = {-1,-1,0,0}; - - med_int ntria3 = 1; - med_int tria3[3] = { - 7, 4, 1 - }; - char nomtria3[MED_TAILLE_PNOM+1] = "tria1 "; - med_int numtria3[1] = {1}; - med_int nufatria3[1] = {-2}; - - med_int npoly = 1; - med_int nindexpoly = 2; - med_int indexpoly [2] = { - 1,6 - }; - med_int poly[5] = { - 9,11,10,3,6 - }; - char nompoly[MED_TAILLE_PNOM+1] = "poly "; - med_int numpoly[1] = {1}; - med_int nufapoly[1] = {-3}; - - char nomfam[MED_TAILLE_NOM+1]; - med_int numfam; - char attdes[MED_TAILLE_DESC+1]; - med_int natt; - med_int attide; - med_int attval; - med_int ngro; - char gro[MED_TAILLE_LNOM+1]; - int i; - int nfame = 2; - int nfamn = 1; - - /* - Some fields : 2 on nodes : one int and one double , one on cells : double - */ - char champ1[MED_TAILLE_NOM+1]="fieldnodeint" ; - char champ1_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ1_unit[MED_TAILLE_PNOM+1]="M " ; - med_int fieldnodeint[9] = {1,1,3,2,2,3,4,4,5}; - - char champ2[MED_TAILLE_NOM+1]="fieldnodedouble" ; - char champ2_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ2_unit[MED_TAILLE_PNOM+1]="J " ; - med_float fieldnodedouble1[9] = {1.,3.,4.,1.,3.,4.,3.,2.,5.}; - med_float fieldnodedouble2[9] = {1.,2.,2.,3.,3.,3.,4.,4.,5.}; - - char champ3[MED_TAILLE_NOM+1]="fieldcelldouble" ; - char champ3_comp[MED_TAILLE_PNOM*2+1]="comp1 comp2 " ; - char champ3_unit[MED_TAILLE_PNOM*2+1]="M/S m/s " ; - med_float fieldcelldouble[4*2] = {0.,1.,1.,1.,1.,2.,2.,3.}; - - /***************************************************************************/ - fid = MEDouvrir("poly2D.med",MED_LECTURE_ECRITURE); - if (fid < 0) - ret = -1; - else - ret = 0; - printf("MEDouvrir : %d\n",ret); - - /***************************************************************************/ - if (ret == 0) - ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); - printf("MEDmaaCr : %d\n",ret); - if (ret == 0) - ret = MEDunvCr(fid,maa); - printf("MEDunvCr : %d\n",ret); - - /***************************************************************************/ - if (ret == 0) - ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, - nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, - nufano,nnoe); - printf("MEDnoeudsEcr : %d\n",ret); - - /* ecriture des mailles MED_QUAD4 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,quad4,MED_FULL_INTERLACE, - nomquad4,MED_FAUX,numquad4,MED_VRAI,nufaquad4,nquad4, - MED_MAILLE,MED_QUAD4,MED_NOD); - printf("MEDelementsEcr for quad : %d \n",ret); - - /* ecriture des mailles MED_TRIA3 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,tria3,MED_FULL_INTERLACE, - nomtria3,MED_FAUX,numtria3,MED_VRAI,nufatria3,ntria3, - MED_MAILLE,MED_TRIA3,MED_NOD); - printf("MEDelementsEcr for tria : %d \n",ret); - - /* ecriture des mailles MED_POLYGONE: - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles - Dans ce cas il n existe pas de routine globale (Warning !!) - */ - - if (ret == 0) - ret = MEDpolygoneConnEcr(fid,maa,indexpoly,nindexpoly,poly, - MED_MAILLE,MED_NOD); - printf("MEDpolygoneConnEcr: %d \n",ret); - - if (ret == 0) - MEDnomEcr(fid,maa,nompoly,npoly,MED_MAILLE,MED_POLYGONE); - printf("MEDnomEcr for poly : %d \n",ret); - - if (ret == 0) - MEDnumEcr(fid,maa,numpoly,npoly,MED_MAILLE,MED_POLYGONE); - printf("MEDnumEcr for poly : %d \n",ret); - - if (ret == 0) - MEDfamEcr(fid,maa,nufapoly,npoly,MED_MAILLE,MED_POLYGONE); - printf("MEDfamEcr for poly : %d \n",ret); - - - /***************************************************************************/ - /* ecriture des familles */ - /* Conventions : - - toujours creer une famille de numero 0 ne comportant aucun attribut - ni groupe (famille de reference pour les noeuds ou les elements - qui ne sont rattaches a aucun groupe ni attribut) - - les numeros de familles de noeuds sont > 0 - - les numeros de familles des elements sont < 0 - - rien d'imposer sur les noms de familles - */ - - /* la famille 0 */ - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_0"); - numfam = 0; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, - gro,0); - } - printf("MEDfamCr : %d \n",ret); - - /* on cree : - - 2 familles d'elements de dimension (d) - en fait de face (-10) - */ - if (ret == 0) - { - numfam = -1; - strcpy(nomfam,"FAMILLE_CELL_"); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe0"); - ngro = 1; - - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - - numfam = -2; - strcpy(nomfam,"FAMILLE_CELL_"); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe0"); - ngro = 1; - - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - - numfam = -3; - strcpy(nomfam,"FAMILLE_CELL_"); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe0"); - ngro = 1; - - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - - /***************************************************************************/ - /* - Les champs - */ - if (ret == 0) - { - ret = MEDchampCr(fid,champ1,MED_INT32,champ1_comp,champ1_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ1, (unsigned char *)fieldnodeint, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - MED_NOPDT," ", 0., MED_NONOR); - - printf("MEDchampEcr : %d \n",ret); - } - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ2,MED_FLOAT64,champ2_comp,champ2_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - 1,"S ", 1.1 , MED_NONOR); - printf("MEDchampEcr1 : %d \n",ret); - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble2, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - 2,"S ", 1.2 , MED_NONOR); - printf("MEDchampEcr2 : %d \n",ret); - } - } - - // on met champ2 sans pas de temps pour pouvoir le lire aussi par defaut ! - if (ret == 0) - { - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - MED_NOPDT," ", 0. , MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ3,MED_FLOAT64,champ3_comp,champ3_unit,2); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble, - MED_NO_INTERLACE, nquad4, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_QUAD4, - MED_NOPDT," ", 0., MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - } - - /***************************************************************************/ - - ret = MEDfermer(fid); - printf("MEDfermer : %d\n",ret); - - return 0; -} - diff --git a/src/MEDMEM/create_poly3D.c b/src/MEDMEM/create_poly3D.c deleted file mode 100644 index 82f9a5068..000000000 --- a/src/MEDMEM/create_poly3D.c +++ /dev/null @@ -1,438 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// -/* - creation d'une geometrie 3d : - maillé en : - - 2 polyedres - ayant pour faces 3 polygones - 9 quadrangles - 6 triangles - - 1 tetra4 - -*/ - -#include <med.h> -#include <string.h> - -int main (int argc, char **argv) -{ - med_err ret; - med_idt fid; - char maa[MED_TAILLE_NOM+1] = "poly3D"; - char maadesc[MED_TAILLE_DESC+1] = "Example de maillage non structure 3D avec 2 polyedres+1tetra4 comme mailles et 3 polygones comme faces"; - med_int mdim = 3; - med_int nnoe = 19; - /* - les noeuds: - */ - med_float coo[57] = { - 2.0, 3.0, 2.0, - 3.0, 2.0, 2.0, - 4.0, 1.0, 2.0, - 2.0, 0.0, 2.0, - 0.0, 1.0, 2.0, - 1.0, 2.0, 2.0, - 2.0, 3.0, 1.0, - 3.0, 2.0, 0.0, - 4.0, 1.0, 0.0, - 2.0, 0.0, 0.0, - 0.0, 1.0, 0.0, - 1.0, 2.0, 0.0, - 5.0, 3.0, 2.0, - 7.0, 2.0, 2.0, - 6.0, 0.0, 2.0, - 6.0, 3.0, 0.0, - 7.0, 2.0, 0.0, - 6.0, 0.0, -1.0, - 5.0, 1.0, -3.0 - }; - char nomcoo[3*MED_TAILLE_PNOM+1] = "x y z "; - char unicoo[3*MED_TAILLE_PNOM+1] = "cm cm cm "; - /* char nomnoe[18*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4";*/ - char *nomnoe ; - med_int numnoe[19] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; - med_int nufano[19] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - /* - les elements: - */ - /* Faces QUAD4 */ - med_int nquad4 = 8; - med_int quad4[32] = { - 1, 7, 8, 2, - 2, 8, 9, 3, - 4, 3, 9, 10, - 5, 4, 10, 11, - 6, 5, 11, 12, - 1, 6, 12, 7, - 14, 13, 16, 17, - 8, 9, 17, 16 - }; - char nomquad4[MED_TAILLE_PNOM*8+1] = "quad1 quad2 quad3 quad4 quad5 quad6 quad7 quad8 "; - med_int numquad4[9] = {2,3,4,5,6,7,12,17}; - med_int nufaquad4[9] = {-1,-1,-1,-1,-1,-1,-1,-1}; - - /* Faces TRIA3 */ - med_int ntria3 = 6; - med_int tria3[18] = { - 7, 12, 8, - 15, 14, 17, - 15, 17, 18, - 15, 18, 9, - 3, 15, 9, - 18, 17, 9 - }; - char nomtria3[MED_TAILLE_PNOM*6+1] = "tria1 tria2 tria3 tria4 tria5 tria6 "; - med_int numtria3[6] = {8,13,14,15,16,18}; - med_int nufatria3[6] = {-2,-2,-2,-2,-2,-2}; - - /* Faces POLYGONE */ - med_int npolygon = 3; - med_int nindexpolygon = 4; - med_int indexpolygon [4] = { - 1, 7, 12, 17 - }; - med_int polygon[16] = { - 1, 2, 3, 4, 5, 6, - 10, 9, 8, 12, 11, - 13, 14, 15, 3, 2 - }; - char nompolygon[MED_TAILLE_PNOM*3+1] = "polygon1 polygon2 polygon3 "; - med_int numpolygon[3] = {1,9,10}; - med_int nufapolygon[3] = {-3,-3,-3}; - - /* Mailles POLYEDRE */ - med_int npolyhedron = 2; - med_int npolyhedronfaces = 19; - med_int npolyhedronnodes = 74; - med_int polyhedronconnectivity[74] = {1,2,3,4,5,6,1,7,8,2,2,8,9,3,4,3,9,10,5,4,10,11,6,5,11,12,1,6,12,7,7,12,8,10,9,8,12,11, - 13,14,15,3,2,13,2,8,16,14,13,16,17,15,14,17,15,17,18,15,18,9,3,15,9,2,3,9,8,8,9,17,16,9,18,17}; - med_int polyhedronfacesindex[20] = {1,7,11,15,19,23,27,31,34, - 39,44,48,52,55,58,61,64,68,72,75}; - med_int polyhedronindex[3] = {1,10,20}; - char nompolyhedron[MED_TAILLE_PNOM*2+1] = "polyhedron1 polyhedron2 "; - med_int numpolyhedron[2] = {2,3}; - med_int nufapolyhedron[2] = {-4,-4}; - - /* Mailles TETRA4 */ - med_int ntetra4 = 1; - med_int tetra4[4] = { - 17, 9, 18, 19 - }; - char nomtetra4[MED_TAILLE_PNOM*1+1] = "tetra1 "; - med_int numtetra4[1] = {1}; - med_int nufatetra4[1] = {-5}; - - - char nomfam[MED_TAILLE_NOM+1]; - med_int numfam; - char attdes[MED_TAILLE_DESC+1]; - med_int natt; - med_int attide; - med_int attval; - med_int ngro; - char gro[MED_TAILLE_LNOM+1]; - int i; - int nfame = 2; - int nfamn = 1; - - /* - Some fields : 2 on nodes : one int and one double , one on cells : double - */ - char champ1[MED_TAILLE_NOM+1]="fieldnodeint" ; - char champ1_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ1_unit[MED_TAILLE_PNOM+1]="M " ; - med_int fieldnodeint[19] = {1,1,3,2,2,3,4,4,5,6,6,7,8,8,9,9,9,10,5}; - - char champ2[MED_TAILLE_NOM+1]="fieldnodedouble" ; - char champ2_comp[MED_TAILLE_PNOM+1]="comp1 " ; - char champ2_unit[MED_TAILLE_PNOM+1]="J " ; - med_float fieldnodedouble1[19] = {1.,3.,4.,1.,3.,4.,3.,2.,5.,6.,4.,3.,1.,5.,6.,4.,3.,7.,3.}; - med_float fieldnodedouble2[19] = {1.,2.,2.,3.,3.,3.,4.,4.,5.,2.,8.,9.,6.,7.,1.,2.,5.,8.,4.}; - - char champ3[MED_TAILLE_NOM+1]="fieldfacedouble" ; - char champ3_comp[MED_TAILLE_PNOM*2+1]="comp1 comp2 " ; - char champ3_unit[MED_TAILLE_PNOM*2+1]="M/S m/s " ; - med_float fieldfacedouble[6*2] = {0.,1.,1.,1.,1.,2.,2.,3.,3.,4.,4.,6.}; - - /***************************************************************************/ - fid = MEDouvrir("poly3D.med",MED_LECTURE_ECRITURE); - if (fid < 0) - ret = -1; - else - ret = 0; - printf("MEDouvrir : %d\n",ret); - - /***************************************************************************/ - if (ret == 0) - ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); - printf("MEDmaaCr : %d\n",ret); - if (ret == 0) - ret = MEDunvCr(fid,maa); - printf("MEDunvCr : %d\n",ret); - - /***************************************************************************/ - if (ret == 0) - ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, - nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, - nufano,nnoe); - printf("MEDnoeudsEcr : %d\n",ret); - - /* ecriture des faces MED_QUAD4 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,quad4,MED_FULL_INTERLACE, - nomquad4,MED_FAUX,numquad4,MED_VRAI,nufaquad4,nquad4, - MED_MAILLE,MED_QUAD4,MED_NOD); - printf("MEDelementsEcr for quad : %d \n",ret); - - /* ecriture des faces MED_TRIA3 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,tria3,MED_FULL_INTERLACE, - nomtria3,MED_FAUX,numtria3,MED_VRAI,nufatria3,ntria3, - MED_MAILLE,MED_TRIA3,MED_NOD); - printf("MEDelementsEcr for tria : %d \n",ret); - - /* ecriture des faces MED_POLYGONE : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles - Dans ce cas il n existe pas de routine globale (Warning !!) */ - if (ret == 0) - ret = MEDpolygoneConnEcr(fid,maa,indexpolygon,nindexpolygon,polygon, - MED_MAILLE,MED_NOD); - printf("MEDpolygoneConnEcr: %d \n",ret); - - if (ret == 0) - MEDnomEcr(fid,maa,nompolygon,npolygon,MED_MAILLE,MED_POLYGONE); - printf("MEDnomEcr for polygon : %d \n",ret); - - if (ret == 0) - MEDnumEcr(fid,maa,numpolygon,npolygon,MED_MAILLE,MED_POLYGONE); - printf("MEDnumEcr for polygon : %d \n",ret); - - if (ret == 0) - MEDfamEcr(fid,maa,nufapolygon,npolygon,MED_MAILLE,MED_POLYGONE); - printf("MEDfamEcr for polygon : %d \n",ret); - - /* ecriture des mailles MED_POLYEDRE : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles - Dans ce cas il n existe pas de routine globale (Warning !!) */ - if (ret == 0) - ret = MEDpolyedreConnEcr(fid,maa,polyhedronindex,npolyhedron+1,polyhedronfacesindex,npolyhedronfaces+1,polyhedronconnectivity,MED_NOD); - printf("MEDpolyedreConnEcr: %d \n",ret); - - if (ret == 0) - ret = MEDnomEcr(fid,maa,nompolyhedron,npolyhedron,MED_MAILLE,MED_POLYEDRE); - printf("MEDnomEcr for polyhedron : %d \n",ret); - - if (ret == 0) - ret = MEDnumEcr(fid,maa,numpolyhedron,npolyhedron,MED_MAILLE,MED_POLYEDRE); - printf("MEDnumEcr for polyhedron : %d \n",ret); - - if (ret == 0) - ret = MEDfamEcr(fid,maa,nufapolyhedron,npolyhedron,MED_MAILLE,MED_POLYEDRE); - printf("MEDfamEcr for polyhedron : %d \n",ret); - - /* ecriture des mailles TETRA4 : - - connectivite - - noms (optionnel) - - numeros (optionnel) - - numeros des familles */ - if (ret == 0) - ret = MEDelementsEcr(fid,maa,mdim,tetra4,MED_FULL_INTERLACE, - nomtetra4,MED_FAUX,numtetra4,MED_VRAI,nufatetra4,ntetra4, - MED_MAILLE,MED_TETRA4,MED_NOD); - printf("MEDelementsEcr for tetra : %d \n",ret); - - /***************************************************************************/ - /* ecriture des familles */ - /* Conventions : - - toujours creer une famille de numero 0 ne comportant aucun attribut - ni groupe (famille de reference pour les noeuds ou les elements - qui ne sont rattaches a aucun groupe ni attribut) - - les numeros de familles de noeuds sont > 0 - - les numeros de familles des elements sont < 0 - - rien d'imposer sur les noms de familles - */ - - /* la famille 0 */ - if (ret == 0) - { - strcpy(nomfam,"FAMILLE_0"); - numfam = 0; - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, - gro,0); - } - printf("MEDfamCr : %d \n",ret); - - /* on cree : - - 2 familles d'elements de dimension (d) - en fait de face (-10) - */ - /* - if (ret == 0) - { - numfam = -1; - strcpy(nomfam,"FAMILLE_FACE_QUAD4"); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe0"); - ngro = 1; - - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - - numfam = -2; - strcpy(nomfam,"FAMILLE_FACE_TRIA3"); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe0"); - ngro = 1; - - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - - numfam = -3; - strcpy(nomfam,"FAMILLE_FACE_POLYGONS"); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe0"); - ngro = 1; - - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - - numfam = -4; - strcpy(nomfam,"FAMILLE_MAILLE_POLYHEDRON"); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe0"); - ngro = 1; - - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - - numfam = -5; - strcpy(nomfam,"FAMILLE_MAILLE_TETRA4"); - sprintf(nomfam,"%s%d",nomfam,-numfam); - attide = 1; - attval = numfam*100; - natt = 1; - strcpy(attdes,"description attribut"); - strcpy(gro,"groupe0"); - ngro = 1; - - ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, - natt,gro,ngro); - printf("MEDfamCr : %d\n",ret); - } - */ - /***************************************************************************/ - /* - Les champs - */ - if (ret == 0) - { - ret = MEDchampCr(fid,champ1,MED_INT32,champ1_comp,champ1_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ1, (unsigned char *)fieldnodeint, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - MED_NOPDT," ", 0., MED_NONOR); - - printf("MEDchampEcr : %d \n",ret); - } - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ2,MED_FLOAT64,champ2_comp,champ2_unit,1); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - 1,"S ", 1.1 , MED_NONOR); - printf("MEDchampEcr1 : %d \n",ret); - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble2, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - 2,"S ", 1.2 , MED_NONOR); - printf("MEDchampEcr2 : %d \n",ret); - } - } - - // on met champ2 sans pas de temps pour pouvoir le lire aussi par defaut ! - if (ret == 0) - { - ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, - MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, - MED_NOPDT," ", 0. , MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - - if (ret == 0) - { - ret = MEDchampCr(fid,champ3,MED_FLOAT64,champ3_comp,champ3_unit,2); - printf("MEDchampCr : %d \n",ret); - if (ret == 0) { - ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldfacedouble, - MED_NO_INTERLACE, ntria3, MED_NOGAUSS, MED_ALL, - MED_NOPFL, MED_NO_PFLMOD, MED_FACE, MED_TRIA3, - MED_NOPDT," ", 0., MED_NONOR); - printf("MEDchampEcr : %d \n",ret); - } - } - /***************************************************************************/ - - ret = MEDfermer(fid); - printf("MEDfermer : %d\n",ret); - - return 0; -} - diff --git a/src/MEDMEM/duplicateMED.cxx b/src/MEDMEM/duplicateMED.cxx deleted file mode 100644 index a8c6648f2..000000000 --- a/src/MEDMEM/duplicateMED.cxx +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include<string> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_Med.hxx" - -using namespace std; -using namespace MEDMEM; -void usage(char * name) -{ - cout << " " << name << " <input med file> <output med file> " <<endl ; - cout << " " << "(the two file name are mandatory)" << endl ; - exit(-1); -} - -int main (int argc, char ** argv) { - if (argc != 3) usage(argv[0]); - - string filenameIN = argv[1] ; - string filenameOUT = argv[2] ; - - try { - - MED myMed(MED_DRIVER,filenameIN) ; // do readFilestruct ! - - // we read all meshes and fields in filenameIN - myMed.read() ; - - // we write all in file filenameOUT : - int id = myMed.addDriver(MED_DRIVER,filenameOUT) ; - myMed.write(id); - - } catch (MEDEXCEPTION& ex) { - MESSAGE(ex.what()) ; - } - -} diff --git a/src/MEDMEM/duplicateMEDMESH.cxx b/src/MEDMEM/duplicateMEDMESH.cxx deleted file mode 100644 index 1bafc1d59..000000000 --- a/src/MEDMEM/duplicateMEDMESH.cxx +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include<string> -#include<deque> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_define.hxx" - -#include "MEDMEM_Med.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_Support.hxx" - -#include "MEDMEM_GenDriver.hxx" -#include "MEDMEM_MedMedDriver.hxx" -#include "MEDMEM_MedMeshDriver.hxx" - -using namespace std; -using namespace MEDMEM; -int main (int argc, char ** argv) { - string filenameIN = argv[1] ; - string filenameOUT = argv[2] ; - - MED * myMed = new MED() ; - MED_MED_RDONLY_DRIVER myMedDriver(filenameIN,myMed) ; - - // we read all meshes in filenameIN - try { - - //int read ; !! UNUSED VARIABLE !! - myMedDriver.open(); - myMedDriver.readFileStruct(); - myMedDriver.close(); - - // read all mesh - MESSAGE("Read all meshes :") ; - int NumberOfMeshes = myMed->getNumberOfMeshes() ; - MESSAGE("Number of meshes : "<<NumberOfMeshes) ; - deque<string> MeshName = myMed->getMeshNames() ; - map<string,MESH*> _meshes ; - for (int i=0; i<NumberOfMeshes; i++) { - _meshes[MeshName[i]]=myMed->getMesh(MeshName[i]) ; - _meshes[MeshName[i]]->read(); - MESSAGE(" - Mesh "<<i+1<<", named "<<MeshName[i]<<" read !"); - MED_MESH_WRONLY_DRIVER myMeshDriver(filenameOUT,_meshes[MeshName[i]]); - MESSAGE("After declaration of MED_MESH_DRIVER"); - myMeshDriver.setMeshName(MeshName[i]); - MESSAGE("After setMeshName"); - myMeshDriver.open() ; - MESSAGE("After open"); - myMeshDriver.write() ; - MESSAGE("After write"); - myMeshDriver.close() ; - MESSAGE("After close"); - } - - // set support : support must be calculated with mesh information !!! - myMed->updateSupport() ; - - } catch (MEDEXCEPTION& ex){ - MESSAGE(ex.what()) ; - } -} diff --git a/src/MEDMEM/ensight2med.cxx b/src/MEDMEM/ensight2med.cxx deleted file mode 100644 index 7d5aaf03c..000000000 --- a/src/MEDMEM/ensight2med.cxx +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include<string> -#include<deque> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_define.hxx" - -#include "MEDMEM_Med.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_EnsightMedDriver.hxx" - -using namespace std; -using namespace MEDMEM; -void usage(char * name) -{ - cout << " ERROR ABOUT SYNTAX " << endl ; - cout << " " << name << " <input ensight file> <output med file> " << endl ; - exit(-1); -} - -// ensight2med toto.case toto.med => input : toto.case => output : toto.med.... - -int main (int argc, char ** argv) { - - string filenameIN ; - string filenameOUT; - - if ( argc == 3 ) { - filenameIN = argv[1] ; - filenameOUT = argv[2] ; - cout << " reading all into the Ensight file " << filenameIN << " and writing all into the Med file " << filenameOUT << endl ; - - MED myMed(ENSIGHT_DRIVER,filenameIN) ; - myMed.read() ; - - int id = myMed.addDriver(MED_DRIVER,filenameOUT); - myMed.write(id); - } - else usage(argv[0]); - -} - - diff --git a/src/MEDMEM/med2_1_To_med2_2.cxx b/src/MEDMEM/med2_1_To_med2_2.cxx deleted file mode 100644 index ee3dda992..000000000 --- a/src/MEDMEM/med2_1_To_med2_2.cxx +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_medimport_src.hxx" - -using namespace std; -using namespace MEDMEM; - -int main (int argc, char ** argv) -{ - if (argc != 2) - { - cerr << "Usage : " << argv[0] - << " fileNameIn" << endl ; - cerr << "Where - fileNameIn is .med V2.1 file supplied by the user including all the directory path" << endl; - cerr << "fileNameOut is .med V2.3.2 file produced by this command in the directory $HOME/TMP_Med2_3Files/" << endl; - cerr << "This command is supposed to be the same as the med File V2.2 medimport utility" << endl << endl; - cerr << "It will produce a med V2.3.2 file fileNameOut which will be in the directory $HOME/TMP_Med2_3Files/" << endl; - cerr << "with the same root name as fileNameIn: " << endl; - cerr << "If fileNameIn is /aPath/file.med so fileNameOut will be $HOME/TMP_Med2_3Files/file.med" << endl; - exit(-1); - } - - string fileNameIn = argv[1] ; - char * fileNameOut = med2_1_To_med2_3((const_cast <char *> - (fileNameIn.c_str()))); - - if (fileNameOut == ((char *) NULL)) - { - cerr << "A problem has occured in the importation of the file " << fileNameIn.c_str() << " into " << fileNameOut << endl; - } - else if(fileNameOut != string(fileNameIn).c_str()) - { - cerr << "the convertion has been successfull !! The resulting file is " << string(fileNameOut).c_str() << endl; - } - else - { - cerr << "No nedd to converte because the file is al ready a med 2.3.2 file" << endl; - } - - return 0; -} diff --git a/src/MEDMEM/med2ensight.cxx b/src/MEDMEM/med2ensight.cxx deleted file mode 100644 index 28a5a9a40..000000000 --- a/src/MEDMEM/med2ensight.cxx +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include<string> -#include<deque> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_define.hxx" - -#include "MEDMEM_Med.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_EnsightMedDriver.hxx" - -using namespace std; -using namespace MEDMEM; - -void usage(char * name) -{ - cout << " ERROR ABOUT SYNTAX " << endl ; - cout << " " << name << " <input med file> <output ensight file> " << endl ; - exit(-1); -} - -int main (int argc, char ** argv) { - - string filenameIN ; - string filenameOUT; - - if ( argc == 3 ) { - filenameIN = argv[1] ; - filenameOUT = argv[2] ; - cout << "-> reading all into the Med file " << filenameIN << " and writing all into the Ensight file " << filenameOUT << endl ; - - MED myMed(MED_DRIVER,filenameIN) ; - - cout << "-> Read all meshes " ; - int NumberOfMeshes = myMed.getNumberOfMeshes() ; - cout << "( "<<NumberOfMeshes << " ) :" << endl ; - deque<string> MeshName = myMed.getMeshNames() ; - for (int i=0; i<NumberOfMeshes; i++) { - myMed.getMesh(MeshName[i])->read() ; - cout << "-> Mesh "<<i+1<<", named "<<MeshName[i]<<" is read !" << endl; - } - - myMed.updateSupport() ; - - cout << "-> Read all fields " ; - int NumberOfFields = myMed.getNumberOfFields() ; - cout << "( "<<NumberOfFields << " ) :" << endl; - deque<string> FieldName = myMed.getFieldNames() ; - for (int i=0; i<NumberOfFields; i++) { - deque<DT_IT_> FieldIteration = myMed.getFieldIteration(FieldName[i]) ; - cout << "-> Field "<<i+1<<", named "<<FieldName[i] << " :" << endl ; - int NumberOfIteration = FieldIteration.size() ; - cout << " Number of iteration pair : "<< NumberOfIteration << endl; - for (int j=0; j<NumberOfIteration; j++) { - FIELD_ * myField = myMed.getField(FieldName[i],FieldIteration[j].dt,FieldIteration[j].it) ; - - myField->read() ; - cout << " * Iteration "<<FieldIteration[j].dt<<" and order number "<<FieldIteration[j].it<<" ) is read !" << endl; - } - } - int id = myMed.addDriver(ENSIGHT_DRIVER,filenameOUT,MED_EN::MED_ECRI) ; - myMed.write(id) ; - } - else usage(argv[0]); -} diff --git a/src/MEDMEM/med2vtk.cxx b/src/MEDMEM/med2vtk.cxx deleted file mode 100644 index a3e353175..000000000 --- a/src/MEDMEM/med2vtk.cxx +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include<string> -#include<deque> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_define.hxx" - -#include "MEDMEM_Med.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_VtkMedDriver.hxx" - -using namespace std; -using namespace MEDMEM; -void usage(char * name) -{ - cout << " " << name << " <input med file> <output vtk file> " <<endl ; - cout << " " << "(the two file name are mandatory)" << endl ; - exit(-1); -} - -int main (int argc, char ** argv) { - if (argc != 3) usage(argv[0]); - - string filenameIN = argv[1] ; - string filenameOUT = argv[2] ; - - try { - ///////////////////////////////////////////////// - // we read all meshes and fields in filenameIN // - ///////////////////////////////////////////////// - MED myMed(MED_DRIVER,filenameIN) ; - - // read all meshes - //////////////////// - - cout << "Read all meshes " ; - int NumberOfMeshes = myMed.getNumberOfMeshes() ; - cout << "( "<<NumberOfMeshes << " ) :" << endl ; - deque<string> MeshName = myMed.getMeshNames() ; - for (int i=0; i<NumberOfMeshes; i++) { - myMed.getMesh(MeshName[i])->read() ; - cout << " - Mesh "<<i+1<<", named "<<MeshName[i]<<" is read !" << endl; - } - - // PROVISOIRE - /////////////// - - // set support : support must be calculated with mesh information !!! - myMed.updateSupport() ; - - // read all fields - //////////////////// - - cout << "Read all fields " ; - int NumberOfFields = myMed.getNumberOfFields() ; - cout << "( "<<NumberOfFields << " ) :" << endl; - deque<string> FieldName = myMed.getFieldNames() ; - for (int i=0; i<NumberOfFields; i++) { - deque<DT_IT_> FieldIteration = myMed.getFieldIteration(FieldName[i]) ; - cout << " - Field "<<i+1<<", named "<<FieldName[i] << " :" << endl ; - int NumberOfIteration = FieldIteration.size() ; - cout << " Number of iteration pair : "<< NumberOfIteration << endl; - for (int j=0; j<NumberOfIteration; j++) { - FIELD_ * myField = myMed.getField(FieldName[i],FieldIteration[j].dt,FieldIteration[j].it) ; - - myField->read() ; - cout << " * Iteration "<<FieldIteration[j].dt<<" and order number "<<FieldIteration[j].it<<" ) is read !" << endl; - } - } - - ////////////////////////////////////////// - // we write all in VTK file filenameOUT // - ///////////////////////////////////////// - int id = myMed.addDriver(VTK_DRIVER,filenameOUT) ; - myMed.write(id) ; - - } - catch (MEDEXCEPTION& ex){ - cout << ex.what() << endl ; - } - -} diff --git a/src/MEDMEM/med_test.cxx b/src/MEDMEM/med_test.cxx deleted file mode 100644 index b68e3e5ce..000000000 --- a/src/MEDMEM/med_test.cxx +++ /dev/null @@ -1,472 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include<string> - -#include <math.h> -#include <stdlib.h> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_Group.hxx" - -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_MedFieldDriver.hxx" -#include "MEDMEM_define.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -double dmax(double x, double y) { return (x>y)?x:y;} - -double dmin(double x, double y) { return (x>y)?y:x;} - -double infty = 1.e20; - -void affiche_support(const SUPPORT * mySupport) -{ - cout << " - Name : "<<mySupport->getName().c_str()<<endl ; - cout << " - Description : "<<mySupport->getDescription().c_str()<<endl ; - cout << " - Entity : "<<mySupport->getEntity()<<endl ; - cout << " - Entities list : "<<endl ; - if (!(mySupport->isOnAllElements())) { - int NumberOfTypes = mySupport->getNumberOfTypes() ; - cout<<" - NumberOfTypes : "<<NumberOfTypes<<endl; - const medGeometryElement * Types = mySupport->getTypes() ; - for (int j=0;j<NumberOfTypes;j++) { - cout << " * Type "<<Types[j]<<" : " ; - int NumberOfElements = mySupport->getNumberOfElements(Types[j]) ; - const int * Number = mySupport->getNumber(Types[j]) ; - for (int k=0; k<NumberOfElements;k++) - cout << Number[k] << " "; - cout << endl ; - } - } else - cout << " Is on all entities !"<< endl; -} - - -void affiche_famille(MESH *myMesh,medEntityMesh Entity) -{ - int NumberOfFamilies = myMesh->getNumberOfFamilies(Entity) ; - cout << "NumberOfFamilies : "<<NumberOfFamilies<<endl; - for (int i=1; i<NumberOfFamilies+1;i++) { - const FAMILY* myFamily = myMesh->getFamily(Entity,i); - affiche_support(myFamily); - cout << " - Identifier : "<<myFamily->getIdentifier()<<endl ; - int NumberOfAttributes = myFamily->getNumberOfAttributes() ; - cout << " - Attributes ("<<NumberOfAttributes<<") :"<<endl; - for (int j=1;j<NumberOfAttributes+1;j++) - cout << " * "<<myFamily->getAttributeIdentifier(j)<<" : "<<myFamily->getAttributeValue(j)<<", "<<myFamily->getAttributeDescription(j).c_str()<<endl ; - int NumberOfGroups = myFamily->getNumberOfGroups() ; - cout << " - Groups ("<<NumberOfGroups<<") :"<<endl; - for (int j=1;j<NumberOfGroups+1;j++) - cout << " * "<<myFamily->getGroupName(j).c_str()<<endl ; - } -} - -void affiche_groupe(MESH *myMesh,medEntityMesh Entity) -{ - int NumberOfGroups = myMesh->getNumberOfGroups(Entity) ; - cout << "NumberOfGroups : "<<NumberOfGroups<<endl; - for (int i=1; i<NumberOfGroups+1;i++) { - const GROUP* myGroup = myMesh->getGroup(Entity,i); - affiche_support(myGroup); - int NumberOfFamillies = myGroup->getNumberOfFamilies() ; - cout << " - Families ("<<NumberOfFamillies<<") :"<<endl; - for (int j=1;j<NumberOfFamillies+1;j++) - cout << " * "<<myGroup->getFamily(j)->getName().c_str()<<endl ; - } -} - -int main (int argc, char ** argv) { - - if ((argc !=3) && (argc != 4)) { - cerr << "Usage : " << argv[0] - << " filename meshname [fieldname]" << endl << endl; - exit(-1); - } - - string filename = argv[1] ; - string meshname = argv[2] ; - - // MESH * myMesh= new MESH(MED_DRIVER,filename,meshname) ; - MESH * myMesh= new MESH() ; - myMesh->setName(meshname); - MED_MESH_RDONLY_DRIVER myMeshDriver(filename,myMesh) ; - myMeshDriver.setMeshName(meshname); - myMeshDriver.open() ; - myMeshDriver.read() ; - myMeshDriver.close() ; - - // int drv = myMesh->addDriver(MED_DRIVER,"sortie.med",meshname); - // myMesh->write(drv); - - - int SpaceDimension = myMesh->getSpaceDimension() ; - int MeshDimension = myMesh->getMeshDimension() ; - int NumberOfNodes = myMesh->getNumberOfNodes() ; - - cout << "Space Dimension : " << SpaceDimension << endl << endl ; - - cout << "Mesh Dimension : " << MeshDimension << endl << endl ; - - const double * Coordinates = myMesh->getCoordinates(MED_FULL_INTERLACE) ; - - cout << "Show Nodes Coordinates : " << endl ; - - cout << "Name :" << endl ; - const string * CoordinatesNames = myMesh->getCoordinatesNames() ; - for(int i=0; i<SpaceDimension ; i++) { - cout << " - " << CoordinatesNames[i] << endl ; - } - cout << "Unit :" << endl ; - const string * CoordinatesUnits = myMesh->getCoordinatesUnits() ; - for(int i=0; i<SpaceDimension ; i++) { - cout << " - " << CoordinatesUnits[i] << endl ; - } - for(int i=0; i<NumberOfNodes ; i++) { - cout << "Nodes " << i+1 << " : " ; - for (int j=0; j<SpaceDimension ; j++) - cout << Coordinates[i*SpaceDimension+j] << " " ; - cout << endl ; - } - - int NumberOfTypes = myMesh->getNumberOfTypes(MED_CELL) ; - const medGeometryElement * Types = myMesh->getTypes(MED_CELL) ; - - cout << "Show Connectivity (Nodal) :" << endl ; - for (int i=0; i<NumberOfTypes; i++) { - cout << "For type " << Types[i] << " : " << endl ; - int NumberOfElements = myMesh->getNumberOfElements(MED_CELL,Types[i]); - const int * connectivity = myMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,Types[i]); - int NomberOfNodesPerCell = Types[i]%100 ; - for (int j=0;j<NumberOfElements;j++){ - cout << "Element "<< j+1 <<" : " ; - for (int k=0;k<NomberOfNodesPerCell;k++) - cout << connectivity[j*NomberOfNodesPerCell+k]<<" "; - cout << endl ; - } - } - - cout << "Show Family :"<<endl ; - affiche_famille(myMesh,MED_NODE); - affiche_famille(myMesh,MED_CELL); - affiche_famille(myMesh,MED_FACE); - affiche_famille(myMesh,MED_EDGE); - - cout << "Show Group :"<<endl ; - affiche_groupe(myMesh,MED_NODE); - affiche_groupe(myMesh,MED_CELL); - affiche_groupe(myMesh,MED_FACE); - affiche_groupe(myMesh,MED_EDGE); - - cout << "Show Reverse Nodal Connectivity :" << endl ; - const int * ReverseNodalConnectivity = myMesh->getReverseConnectivity(MED_NODAL) ; - const int * ReverseNodalConnectivityIndex = myMesh->getReverseConnectivityIndex(MED_NODAL) ; - for (int i=0; i<NumberOfNodes; i++) { - cout << "Node "<<i+1<<" : " ; - for (int j=ReverseNodalConnectivityIndex[i];j<ReverseNodalConnectivityIndex[i+1];j++) - cout << ReverseNodalConnectivity[j-1] << " " ; - cout << endl ; - } - - cout << "Show Connectivity (Descending) :" << endl ; - int NumberOfElements ; - const int * connectivity ; - const int * connectivity_index ; - myMesh->calculateConnectivity(MED_FULL_INTERLACE,MED_DESCENDING,MED_CELL); - try { - NumberOfElements = myMesh->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS); - connectivity = myMesh->getConnectivity(MED_FULL_INTERLACE,MED_DESCENDING,MED_CELL,MED_ALL_ELEMENTS); - connectivity_index = myMesh->getConnectivityIndex(MED_DESCENDING,MED_CELL); - } - catch (MEDEXCEPTION m) { - cout << m.what() << endl ; - exit (-1) ; - } - for (int j=0;j<NumberOfElements;j++) { - cout << "Element "<<j+1<<" : " ; - for (int k=connectivity_index[j];k<connectivity_index[j+1];k++) - cout << connectivity[k-1]<<" "; - cout << endl ; - } - - cout << "Show Reverse Descending Connectivity :" << endl ; - const int * ReverseDescendingConnectivity = myMesh->getReverseConnectivity(MED_DESCENDING) ; - const int * ReverseDescendingConnectivityIndex = myMesh->getReverseConnectivityIndex(MED_DESCENDING) ; - - int NumberOfConstituents = 0; - string constituent ; - medEntityMesh constituentEntity ; - - if (MeshDimension==3) { - constituent = "Face" ; - constituentEntity = MED_FACE ; - } - - if (MeshDimension==2) { - constituent = "Edge" ; - constituentEntity = MED_EDGE ; - } - - if (MeshDimension==1) { - INFOS("ERROR : MeshDimension = 1 !"); - INFOS("We could not see Reverse Descending Connectivity.") ; - } else { - NumberOfConstituents = myMesh->getNumberOfElements (constituentEntity,MED_ALL_ELEMENTS); - for (int i=0; i<NumberOfConstituents; i++) { - cout << constituent <<i+1<<" : " ; - for (int j=ReverseDescendingConnectivityIndex[i];j<ReverseDescendingConnectivityIndex[i+1];j++) - cout << ReverseDescendingConnectivity[j-1] << " " ; - cout << endl ; - } - } - cout << "Show "<<constituent<<" Connectivity (Nodal) :" << endl ; - const int * face_connectivity = myMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,constituentEntity,MED_ALL_ELEMENTS); - const int * face_connectivity_index = myMesh->getConnectivityIndex(MED_NODAL,constituentEntity); - for (int i=0; i<NumberOfConstituents; i++) { - cout << constituent <<i+1<<" : " ; - for (int j=face_connectivity_index[i];j<face_connectivity_index[i+1];j++) - cout << face_connectivity[j-1]<<" "; - cout << endl ; - } - - /* test of normal, area, volume, barycenter */ - - SUPPORT * support1 = (SUPPORT*) NULL; - - //FIELD<double>* normal = new FIELD<double>::FIELD(); - //FIELD<double>* length = new FIELD<double>::FIELD(); - //normal = NULL; - //length = NULL; - string support_name = "Support on all " ; - support_name+=constituent; - support1 = new SUPPORT(myMesh,support_name,constituentEntity); - cout << "Building of the Support on all cells dimensionned (Meshdim-1) of the mesh :"<< endl ; - cout << "Face in 3D or Edge in 2D" << endl; - - cout << "Getting the normal of each face of this support !" << endl ; - - FIELD<double>* normal = myMesh->getNormal(support1); - - double normal_square, norm ; - double maxnorm=-infty; - double minnorm=infty; - double tmp_value ; - for (int i = 1; i<=NumberOfConstituents;i++) { - normal_square = 0. ; - cout << "Normal " << i << " " ; - for (int j=1; j<=SpaceDimension; j++) { - tmp_value = normal->getValueIJ(i,j) ; - normal_square += tmp_value*tmp_value ; - cout << tmp_value << " " ; - } - norm = sqrt(normal_square); - maxnorm = dmax(maxnorm,norm); - minnorm = dmin(minnorm,norm); - cout << ", Norm = " << norm << endl; - } - cout << "Max Norm " << maxnorm << " Min Norm " << minnorm << endl; - - delete normal ; - - if (SpaceDimension == 2) - { - cout << "Getting the length of each edge !" << endl ; - - FIELD<double>* length = myMesh->getLength(support1); - - double length_value,maxlength,minlength; - maxlength = -infty; - minlength = infty; - for (int i = 1; i<=NumberOfConstituents;i++) - { - length_value = length->getValueIJ(i,1) ; - cout << "Length " << i << " " << length_value << endl; - maxlength = dmax(maxlength,length_value); - minlength = dmin(minlength,length_value); - } - cout << "Max Length " << maxlength << " Min Length " << minlength << endl; - - delete length ; - } - - delete support1 ; - - cout << "Building of the Support on all space-dimensionned cells of the mesh :"<< endl ; - SUPPORT * support = new SUPPORT(myMesh); - - cout << "Getting the barycenter of each element of this support !" << endl ; - - //FIELD<double>* barycenter = new FIELD<double>::FIELD(); - - FIELD<double>* barycenter = myMesh->getBarycenter(support); - NumberOfElements = myMesh->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS); - - for (int i = 1; i<=NumberOfElements;i++) - { - if (SpaceDimension == 3) - cout << "Barycenter " << i << " " << barycenter->getValueIJ(i,1) << " " << barycenter->getValueIJ(i,2) << " " << barycenter->getValueIJ(i,3) << endl; - - if (SpaceDimension == 2) - cout << "Barycenter " << i << " " << barycenter->getValueIJ(i,1) << " " << barycenter->getValueIJ(i,2) << endl; - } - - delete barycenter ; - - //FIELD<double>* volume = new FIELD<double>::FIELD(); - //FIELD<double>* area = new FIELD<double>::FIELD(); - //volume = NULL; - //area = NULL; - - if (SpaceDimension == 3) - { - cout << "Getting the Volume of each element of this support which is a 3D one !" << endl; - - FIELD<double>* volume = myMesh->getVolume(support); - - double maxvol,minvol,voltot; - maxvol = -infty; - minvol = infty; - voltot = 0.0; - for (int i = 1; i<=NumberOfElements;i++) - { - cout << "Volume " << i << " " << volume->getValueIJ(i,1) << endl; - maxvol = dmax(maxvol,volume->getValueIJ(i,1)); - minvol = dmin(minvol,volume->getValueIJ(i,1)); - voltot = voltot + volume->getValueIJ(i,1); - } - - cout << "Max Volume " << maxvol << " Min Volume " << minvol << endl; - cout << "Support Volume " << voltot << endl; - - delete volume ; - } - else if (SpaceDimension == 2) - { - cout << "Getting the Area of each element of this support which is a 2D one !" << endl; - - FIELD<double>* area = myMesh->getArea(support); - - // cout << "nb of comp "<< area->getNumberOfComponents() << " length " << area->getSupport()->getNumberOfElements(MED_ALL_ELEMENTS) << endl; - - double maxarea,minarea,areatot; - maxarea = -infty; - minarea = infty; - areatot = 0.0; - for (int i = 1; i<=NumberOfElements;i++) - { - cout << "Area " << i << " " << area->getValueIJ(i,1) << endl; - maxarea = dmax(maxarea,area->getValueIJ(i,1)); - minarea = dmin(minarea,area->getValueIJ(i,1)); - areatot = areatot + area->getValueIJ(i,1); - } - - cout << "Max Area " << maxarea << " Min Area " << minarea << endl; - cout << "Support Area " << areatot << endl; - - delete area ; - } - - delete support ; - - //if (barycenter != NULL) delete barycenter; - //if (volume != NULL ) delete volume; - //if (area != NULL ) delete area; - - - if (argc < 4) return 0; - - // read field : - - if (argc != 4) exit(0) ; - // else we have a field ! - - string fieldname = argv[3]; - - // SUPPORT * mySupport = new SUPPORT(myMesh,"On_all_node",MED_NODE); - SUPPORT * mySupport = new SUPPORT(myMesh,"On_all_cell",MED_CELL); - FIELD<double> * myField= new FIELD<double>() ; - - myField->setName(fieldname); - myField->setSupport(mySupport); - MED_FIELD_RDONLY_DRIVER<double> myFieldDriver(filename,myField) ; - myFieldDriver.setFieldName(fieldname); - myFieldDriver.open() ; - - try { - myFieldDriver.read() ; - } catch (...) { - delete mySupport ; - mySupport = new SUPPORT(myMesh,"On_all_node",MED_NODE); - myField->setSupport(mySupport); - try { - myFieldDriver.read() ; - } catch (...) { - cout << "Field " << fieldname << " not found !!!" << endl ; - exit (-1) ; - } - } - - myFieldDriver.close() ; - - cout << "Field "<< myField->getName() << " : " <<myField->getDescription() << endl ; - int NumberOfComponents = myField->getNumberOfComponents() ; - cout << "- Nombre de composantes : "<< NumberOfComponents << endl ; - for (int i=1; i<NumberOfComponents+1; i++) { - cout << " - composante "<<i<<" :"<<endl ; - cout << " - nom : "<<myField->getComponentName(i)<< endl; - cout << " - description : "<<myField->getComponentDescription(i) << endl; - cout << " - units : "<<myField->getMEDComponentUnit(i) << endl; - } - cout << "- iteration :" << endl ; - cout << " - numero : " << myField->getIterationNumber()<< endl ; - cout << " - ordre : " << myField->getOrderNumber()<< endl ; - cout << " - temps : " << myField->getTime()<< endl ; - - cout << "- Valeurs :"<<endl; - int NumberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); - // for (int i=1; i<NumberOfComponents+1; i++) { - // double * value = myField->getValueI(MED_NO_INTERLACE,i) ; - // for (int j=0; j<NumberOf; j++) - // cout << value[j]<< " "; - // cout<<endl; - // } - MEDMEM_Array<double> * myvalue = myField->getArrayNoGauss(); - const double * value ; - for (int i=1; i<NumberOf+1; i++) { - value = myvalue->getRow(i) ; - for (int j=0; j<NumberOfComponents; j++) - cout << value[j]<< " "; - cout<<endl; - } - cout<<endl; - - delete myField; - delete mySupport; - - delete myMesh ; - - return 0; -} diff --git a/src/MEDMEM/testAnalFile.cxx b/src/MEDMEM/testAnalFile.cxx deleted file mode 100644 index a16db0cbb..000000000 --- a/src/MEDMEM/testAnalFile.cxx +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// -#include <string> -#include <deque> -#include <iostream> -#include "MEDMEM_MedMedDriver.hxx" -#include "MEDMEM_Med.hxx" -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_DriverFactory.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -int main(int argc, char *argv[]) -{ - if (argc !=2) - { - cerr << "Usage : " << argv[0] - << " fileName.med where fileName.med should be a med file" << endl; - cerr << " It will then generate two med files fileNameAnal_V21.med (med V2.1 format)" << endl; - cerr << "and fileNameAnal_V21.med (med V2.2 format)" << endl << endl; - exit(-1); - } - - int i; - // This test program is more or less designed to work with file TimeStamps.med - // If you want to use it for other Med files, you have to alter the mounting in memory of the fields f1 and f2 - //string fileIn="/export/home/geay32/SALOME225/KERNEL_SRC/examples/TimeStamps.med"; - - string fileIn = argv[1] ; - const string ext=".med"; - string::size_type pos=fileIn.find(ext,0); - string baseName (fileIn, 0, pos); // nom sans extension - string fileOut21=baseName + "Anal_V21.med"; - string fileOut22=baseName + "Anal_V22.med"; - - MED *myMed=new MED; - MED_MED_RDONLY_DRIVER *driverIn=new MED_MED_RDONLY_DRIVER(fileIn,myMed); - driverIn->open(); - driverIn->readFileStruct(); - driverIn->close(); - int nbOfMeshes=myMed->getNumberOfMeshes(); - int nbOfFields=myMed->getNumberOfFields(); - cout << nbOfMeshes << " --- " << nbOfFields << endl; - deque<string> names=myMed->getMeshNames(); - for(i=0;i<nbOfMeshes;i++) - cout << names[i] << endl; - cout << "************* " << endl; - deque<string> names2=myMed->getFieldNames(); - for(i=0;i<nbOfFields;i++) - cout << names2[i] << endl; - MESH *mesh=myMed->getMesh(names[0]); - mesh->read(); - myMed->updateSupport(); - deque<DT_IT_> iterations=myMed->getFieldIteration(names2[2]); - cout << iterations.size() << endl; - FIELD_ *f1=myMed->getField(names2[2],iterations[0].dt,iterations[0].it); - FIELD_ *f2=myMed->getField(names2[2],iterations[1].dt,iterations[1].it); - FIELD<double> *f1s=(FIELD<double> *)f1; - f1s->read(); - FIELD<double> *f2s=(FIELD<double> *)f2; - f2s->read(); - DRIVERFACTORY::setMedFileVersionForWriting(V21); - int id=mesh->addDriver(MED_DRIVER,fileOut21,mesh->getName()); - mesh->write(id); - id=f1s->addDriver(MED_DRIVER, fileOut21, f1s->getName()); - f1s->write(id); - id=f2s->addDriver(MED_DRIVER, fileOut21, f2s->getName()); - f2s->write(id); - - DRIVERFACTORY::setMedFileVersionForWriting(V22); - id=mesh->addDriver(MED_DRIVER,fileOut22,mesh->getName()); - mesh->write(id); - id=f1s->addDriver(MED_DRIVER, fileOut22, f1s->getName()); - f1s->write(id); - id=f2s->addDriver(MED_DRIVER, fileOut22, f2s->getName()); - f2s->write(id); - - delete myMed; - return 0; -} - diff --git a/src/MEDMEM/test_GaussLocalization.cxx b/src/MEDMEM/test_GaussLocalization.cxx deleted file mode 100644 index 89c2d0191..000000000 --- a/src/MEDMEM/test_GaussLocalization.cxx +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// -#include <stdlib.h> -#include <string> - -#define INTERLACING_TAG FullInterlace - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_define.hxx" -#include "MEDMEM_GaussLocalization.hxx" -#include "MEDMEM_ArrayInterface.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -#define _a 0.446948490915965 -#define _b 0.091576213509771 -#define _p1 0.11169079483905 -#define _p2 0.0549758718227661 - -int main (int argc, char ** argv) { - - typedef MEDMEM_ArrayInterface<double,INTERLACING_TAG,NoGauss>::Array Array; - - - /* Caractéristiques du model n° 1 de localisation des points de gauss pour le champ n°1*/ - MED_EN::medGeometryElement typeGeo = MED_TRIA6; - - int ngauss1_1 = 6; - string gauss1_1("Model n1"); - double refcoo1 [12] = { -1.0,1.0, -1.0,-1.0, 1.0,-1.0, -1.0,0.0, 0.0,-1.0, 0.0,0.0 }; - - double gscoo1_1[12] = { 2*_b-1, 1-4*_b, 2*_b-1, 2*_b-1, 1-4*_b, - 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 }; - double wg1_1[6] = { 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 }; - - - assert( ( (typeGeo%100)*(typeGeo/100) ) == 12 ); - - GAUSS_LOCALIZATION<INTERLACING_TAG> myloc1 = GAUSS_LOCALIZATION<INTERLACING_TAG>(gauss1_1,typeGeo,ngauss1_1, - Array(refcoo1,typeGeo/100,(typeGeo%100) ), - Array(gscoo1_1,typeGeo/100,ngauss1_1), - vector<double> (wg1_1,wg1_1+ngauss1_1) - ); - GAUSS_LOCALIZATION<INTERLACING_TAG> myloc1bis = GAUSS_LOCALIZATION<INTERLACING_TAG>(gauss1_1,typeGeo,ngauss1_1, - refcoo1,gscoo1_1, - wg1_1); - - cout << "myloc1 == myloc1bis " << (myloc1 == myloc1bis) << endl; - cout << "myloc1 : " << endl << myloc1 << endl; -} diff --git a/src/MEDMEM/test_MEDMEM_Array.cxx b/src/MEDMEM/test_MEDMEM_Array.cxx deleted file mode 100644 index bbb8428d5..000000000 --- a/src/MEDMEM/test_MEDMEM_Array.cxx +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include "MEDMEM_Array.hxx" - -using namespace std; -using namespace MEDMEM; -int main (int argc, char ** argv) { - - int SpaceDimension = 3 ; - int NumberOfNodes = 4 ; - MEDARRAY<int> * myArray = new MEDARRAY<int>(SpaceDimension,NumberOfNodes,MED_EN::MED_FULL_INTERLACE) ; - - //const int * value = myArray->get(MED_FULL_INTERLACE) ; - for (int i=1; i<=NumberOfNodes; i++) - for (int j=1; j<=SpaceDimension; j++) - myArray->setIJ(i,j,i) ; - - int numberof ; - MESSAGE("Show all 1 :"); - numberof = myArray->getLeadingValue() ; - for (int i=1; i<=myArray->getLengthValue() ; i++) { - //int * node = myArray->getI(MED_FULL_INTERLACE,i) ; - const int * node = myArray->getRow(i) ; - cout << " - " ; - for (int j=0;j<numberof;j++) - cout << node[j] << " " ; - cout << endl ; - } - MESSAGE("Show all 2 :"); - numberof = myArray->getLengthValue() ; - for (int i=1; i<=myArray->getLeadingValue() ; i++) { - //int * node = myArray->getJ(MED_NO_INTERLACE,i) ; - const int * node = myArray->getColumn(i) ; - cout << " - " ; - for (int j=0;j<numberof;j++) - cout << node[j] << " " ; - cout << endl ; - } - MESSAGE("Show all 3 :"); - numberof = myArray->getLeadingValue() ; - for (int i=1; i<=myArray->getLengthValue() ; i++) { - cout << " - " ; - for (int j=1;j<numberof+1;j++) - cout << myArray->getIJ(i,j) << " " ; - cout << endl ; - } - - MESSAGE("Show all 0 :"); - numberof = myArray->getLeadingValue() ; - int length = myArray->getLengthValue() ; - const int * NoInterlaceArray = myArray->get(MED_EN::MED_NO_INTERLACE) ; - for (int i=0; i<length ; i++) { - cout << " - " ; - for (int j=0;j<numberof;j++) - cout << NoInterlaceArray[j*length+i] << " " ; - cout << endl ; - } - - delete myArray ; - - return 0 ; -} diff --git a/src/MEDMEM/test_MEDMEM_CellModel.cxx b/src/MEDMEM/test_MEDMEM_CellModel.cxx deleted file mode 100644 index 8c84d48d6..000000000 --- a/src/MEDMEM/test_MEDMEM_CellModel.cxx +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include "MEDMEM_CellModel.hxx" -#include "MEDMEM_DriversDef.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -int main (int argc, char ** argv) { - list<medGeometryElement> geomList = meshEntities[MED_CELL] ; - list<medGeometryElement>::iterator itGeomList ; - for(itGeomList=geomList.begin();itGeomList!=geomList.end();itGeomList++) { - CELLMODEL myCellModel((MED_EN::medGeometryElement)(*itGeomList)) ; - - cout << "First CellModel :" << endl << endl ; - - cout << myCellModel << endl ; - - cout << "Number of constituents type : "<<myCellModel.getNumberOfConstituentsType() << endl ; - - set <medGeometryElement> geomType = myCellModel.getAllConstituentsType() ; - set <medGeometryElement>::iterator geomTypeIt ; - cout << "Types list : " ; - for(geomTypeIt=geomType.begin();geomTypeIt!=geomType.end();geomTypeIt++) - cout << (*geomTypeIt) << " " ; - cout << endl; - - map <medGeometryElement,int> myMap = myCellModel.getNumberOfConstituentsForeachType() ; - map <medGeometryElement,int>::iterator myMapIt ; - for(myMapIt=myMap.begin();myMapIt!=myMap.end();myMapIt++) - cout << " - " << (*myMapIt).second << " constituent(s) of type " << (*myMapIt).first << endl ; - cout << endl; - - cout << "Second CellModel :" << endl << endl ; - CELLMODEL myCellModel2=myCellModel ; - cout << myCellModel2 << endl ; - - cout << "Third CellModel :" << endl << endl ; - CELLMODEL myCellModel3 ; - myCellModel3=myCellModel ; - cout << myCellModel3 << endl ; - } -} diff --git a/src/MEDMEM/test_MEDMEM_Meshing.cxx b/src/MEDMEM/test_MEDMEM_Meshing.cxx deleted file mode 100644 index 41dfc0457..000000000 --- a/src/MEDMEM/test_MEDMEM_Meshing.cxx +++ /dev/null @@ -1,657 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// - -//#define protected public -//#define private public - -#include "MEDMEM_Meshing.hxx" -#include "MEDMEM_Group.hxx" -#include "MEDMEM_Field.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; -using namespace DRIVERFACTORY; - -int main (int argc, char ** argv) { - - if (argc >2) { - cerr << "Usage : " << argv[0] - << " filenameRoot" << endl; - cerr << " where filenameRoot is a root filename, the program will produce" << endl; - cerr << " 3 files filenameRoot21.med filenameRoot22.med and filenameRoot.vtk" << endl << endl; - exit(-1); - } - - string filenameRoot; - if (argc==1) - // filename to save the generated MESH - filenameRoot = "/tmp/test_MEDMEM_Meshing" ; - else - filenameRoot=argv[1]; - - string filenameMed21 = filenameRoot+"_V21.med"; - string filenameMed22 = filenameRoot+"_V22.med"; - string filenameVtk = filenameRoot+".vtk"; - - MESHING myMeshing ; - myMeshing.setName("meshing") ; - - // define coordinates - - int SpaceDimension = 3 ; - int NumberOfNodes = 19 ; - double Coordinates[57] = { - 0.0, 0.0, 0.0, - 0.0, 0.0, 1.0, - 2.0, 0.0, 1.0, - 0.0, 2.0, 1.0, - -2.0, 0.0, 1.0, - 0.0, -2.0, 1.0, - 1.0, 1.0, 2.0, - -1.0, 1.0, 2.0, - -1.0, -1.0, 2.0, - 1.0, -1.0, 2.0, - 1.0, 1.0, 3.0, - -1.0, 1.0, 3.0, - -1.0, -1.0, 3.0, - 1.0, -1.0, 3.0, - 1.0, 1.0, 4.0, - -1.0, 1.0, 4.0, - -1.0, -1.0, 4.0, - 1.0, -1.0, 4.0, - 0.0, 0.0, 5.0 - }; - - myMeshing.setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,"CARTESIAN",MED_FULL_INTERLACE); - - string Names[3] = { "X","Y","Z" } ; - myMeshing.setCoordinatesNames(Names); - - string Units[3] = { "cm","cm","cm" } ; - myMeshing.setCoordinatesUnits(Units) ; - - // define conectivities - - // cell part - - const int NumberOfTypes = 3 ; - medGeometryElement Types[NumberOfTypes] = {MED_TETRA4,MED_PYRA5,MED_HEXA8} ; - const int NumberOfElements[NumberOfTypes] = {12,2,2} ; - - myMeshing.setNumberOfTypes(NumberOfTypes,MED_CELL); - myMeshing.setTypes(Types,MED_CELL); - myMeshing.setNumberOfElements(NumberOfElements,MED_CELL); - - const int sizeTetra = 12*4 ; - int ConnectivityTetra[sizeTetra]= - { - 1,2,3,6, - 1,2,4,3, - 1,2,5,4, - 1,2,6,5, - 2,7,4,3, - 2,8,5,4, - 2,9,6,5, - 2,10,3,6, - 2,7,3,10, - 2,8,4,7, - 2,9,5,8, - 2,10,6,9 - }; - - myMeshing.setConnectivity(ConnectivityTetra,MED_CELL,MED_TETRA4); - - int ConnectivityPyra[2*5]= - { - 7,8,9,10,2, - 15,18,17,16,19 - }; - - myMeshing.setConnectivity(ConnectivityPyra,MED_CELL,MED_PYRA5); - - int ConnectivityHexa[2*8]= - { - 11,12,13,14,7,8,9,10, - 15,16,17,18,11,12,13,14 - }; - - myMeshing.setConnectivity(ConnectivityHexa,MED_CELL,MED_HEXA8); - - // face part - - const int NumberOfFacesTypes = 2 ; - medGeometryElement FacesTypes[NumberOfFacesTypes] = {MED_TRIA3,MED_QUAD4} ; - const int NumberOfFacesElements[NumberOfFacesTypes] = {4,4} ; - - myMeshing.setNumberOfTypes(NumberOfFacesTypes,MED_FACE); - myMeshing.setTypes(FacesTypes,MED_FACE); - myMeshing.setNumberOfElements(NumberOfFacesElements,MED_FACE); - - const int sizeTria = 3*4 ; - int ConnectivityTria[sizeTria]= - { - 1,4,3, - 1,5,4, - 1,6,5, - 1,3,6 - }; - - myMeshing.setConnectivity(ConnectivityTria,MED_FACE,MED_TRIA3); - - int ConnectivityQua[4*4]= - { - 7,8,9,10, - 11,12,13,14, - 11,7,8,12, - 12,8,9,13 - }; - - myMeshing.setConnectivity(ConnectivityQua,MED_FACE,MED_QUAD4); - - int meshDimension = SpaceDimension; // because there 3D cells in the mesh - myMeshing.setMeshDimension(meshDimension); - - // edge part - - // not yet implemented : if set, results are unpredictable. - - // Some groups : - - // Node : - - GROUP partialGroupOnNodes ; - { - partialGroupOnNodes.setName("SomeNodes"); - partialGroupOnNodes.setMesh(&myMeshing); - partialGroupOnNodes.setEntity(MED_NODE); - partialGroupOnNodes.setNumberOfGeometricType(1); - medGeometryElement myTypes[1] = {MED_NONE}; - partialGroupOnNodes.setGeometricType(myTypes); - const int myNumberOfElements[1] = {4} ; - partialGroupOnNodes.setNumberOfElements(myNumberOfElements); - const int index[1+1] = {1,5} ; - const int value[4]= { 1,4,5,7} ; - partialGroupOnNodes.setNumber(index,value); - } - myMeshing.addGroup(partialGroupOnNodes); - - - GROUP partialGroupOnNodes2 ; - { - partialGroupOnNodes2.setName("OtherNodes"); - partialGroupOnNodes2.setMesh(&myMeshing); - partialGroupOnNodes2.setEntity(MED_NODE); - partialGroupOnNodes2.setNumberOfGeometricType(1); - medGeometryElement myTypes[1] = {MED_NONE}; - partialGroupOnNodes2.setGeometricType(myTypes); - const int myNumberOfElements[1] = {3} ; - partialGroupOnNodes2.setNumberOfElements(myNumberOfElements); - const int index[1+1] = {1,4} ; - const int value[3]= { 2,3,6} ; - partialGroupOnNodes2.setNumber(index,value); - } - myMeshing.addGroup(partialGroupOnNodes2); - - - // Cell : - - GROUP partialGroupOnCells ; - { - partialGroupOnCells.setName("SomeCells"); - partialGroupOnCells.setMesh(&myMeshing); - partialGroupOnCells.setEntity(MED_CELL); - partialGroupOnCells.setNumberOfGeometricType(3); - medGeometryElement myTypes[3] = {MED_TETRA4,MED_PYRA5,MED_HEXA8}; - partialGroupOnCells.setGeometricType(myTypes); - const int myNumberOfElements[3] = {4,1,2} ; - partialGroupOnCells.setNumberOfElements(myNumberOfElements); - const int index[3+1] = {1,5,6,8} ; - const int value[4+1+2]= - { - 2,7,8,12, - 13, - 15,16 - }; - partialGroupOnCells.setNumber(index,value); - } - myMeshing.addGroup(partialGroupOnCells); - - - GROUP partialGroupOnCells2 ; - { - partialGroupOnCells2.setName("OtherCells"); - partialGroupOnCells2.setMesh(&myMeshing); - partialGroupOnCells2.setEntity(MED_CELL); - partialGroupOnCells2.setNumberOfGeometricType(2); - medGeometryElement myTypes[] = {MED_TETRA4,MED_PYRA5}; - partialGroupOnCells2.setGeometricType(myTypes); - const int myNumberOfElements[] = {4,1} ; - partialGroupOnCells2.setNumberOfElements(myNumberOfElements); - const int index[2+1] = {1,5,6} ; - const int value[4+1]= - { - 3,4,5,9, - 14 - }; - partialGroupOnCells2.setNumber(index,value); - } - myMeshing.addGroup(partialGroupOnCells2); - - - // Face : - - GROUP partialGroupOnFaces ; - { - partialGroupOnFaces.setName("SomeFaces"); - partialGroupOnFaces.setMesh(&myMeshing); - partialGroupOnFaces.setEntity(MED_FACE); - partialGroupOnFaces.setNumberOfGeometricType(2); - medGeometryElement myTypes[2] = {MED_TRIA3,MED_QUAD4}; - partialGroupOnFaces.setGeometricType(myTypes); - const int myNumberOfElements[2] = {2,3} ; - partialGroupOnFaces.setNumberOfElements(myNumberOfElements); - const int index[2+1] = {1,3,6} ; - const int value[2+3]= - { - 2,4, - 5,6,8 - } ; - partialGroupOnFaces.setNumber(index,value); - } - myMeshing.addGroup(partialGroupOnFaces); - - - GROUP partialGroupOnFaces2 ; - { - partialGroupOnFaces2.setName("OtherFaces"); - partialGroupOnFaces2.setMesh(&myMeshing); - partialGroupOnFaces2.setEntity(MED_FACE); - medGeometryElement myTypes[1] = {MED_TRIA3}; - int myNumberOfElements[1] = {2} ; - int value[2]= - { - 1,3 - } ; - // partialGroupOnFaces2.setNumber(index,value); - partialGroupOnFaces2.setpartial("description",1,2,myTypes,myNumberOfElements,value); - } - myMeshing.addGroup(partialGroupOnFaces2); - - // all right, we save it in Med 2.1 2.2 and vtk ! - - medFileVersion version = getMedFileVersionForWriting(); - if (version == V21) - setMedFileVersionForWriting(V22); - - int idMed22 = myMeshing.addDriver(MED_DRIVER,filenameMed22,myMeshing.getName()); - myMeshing.write(idMed22) ; - - version = getMedFileVersionForWriting(); - if (version == V22) - setMedFileVersionForWriting(V21); - - int idMed21 = myMeshing.addDriver(MED_DRIVER,filenameMed21,myMeshing.getName()); - myMeshing.write(idMed21) ; - - int idVtk = myMeshing.addDriver(VTK_DRIVER,filenameVtk,myMeshing.getName()); - myMeshing.write(idVtk) ; - - // we build now 8 fields : 4 fields double (integer) : - // 2 fields on nodes (cells) : - // 1 scalar (vector) - - SUPPORT * supportOnNodes = new SUPPORT(&myMeshing,"On_All_Nodes",MED_NODE); - int numberOfNodes = supportOnNodes->getNumberOfElements(MED_ALL_ELEMENTS); - - SUPPORT * supportOnCells = new SUPPORT(&myMeshing,"On_All_Cells",MED_CELL); - int numberOfCells = supportOnCells->getNumberOfElements(MED_ALL_ELEMENTS); - - FIELD<double> * fieldDoubleScalarOnNodes = new FIELD<double>(supportOnNodes,1); - fieldDoubleScalarOnNodes->setName("fieldScalarDoubleNode"); - fieldDoubleScalarOnNodes->setIterationNumber(-1); - fieldDoubleScalarOnNodes->setOrderNumber(-1); - fieldDoubleScalarOnNodes->setTime(0.0); - - fieldDoubleScalarOnNodes->setComponentName(1,"Vx"); - fieldDoubleScalarOnNodes->setComponentDescription(1,"comp1"); - fieldDoubleScalarOnNodes->setMEDComponentUnit(1,"unit1"); - - FIELD<double>* fieldDoubleScalarOnPartialNodes = new FIELD<double>(&partialGroupOnNodes,1); - fieldDoubleScalarOnPartialNodes->setName("fieldScalarDoublePartialNodes"); - fieldDoubleScalarOnPartialNodes->setIterationNumber(-1); - fieldDoubleScalarOnPartialNodes->setOrderNumber(-1); - fieldDoubleScalarOnPartialNodes->setTime(0.0); - fieldDoubleScalarOnPartialNodes->setComponentName(1,"Vx"); - fieldDoubleScalarOnPartialNodes->setComponentDescription(1,"comp1"); - fieldDoubleScalarOnPartialNodes->setMEDComponentUnit(1,"unit1"); - - - FIELD<double> * fieldDoubleVectorOnNodes = new FIELD<double>(supportOnNodes,SpaceDimension); - fieldDoubleVectorOnNodes->setName("fieldVectorDoubleNode"); - fieldDoubleVectorOnNodes->setIterationNumber(-1); - fieldDoubleVectorOnNodes->setOrderNumber(-1); - fieldDoubleVectorOnNodes->setTime(0.0); - - fieldDoubleVectorOnNodes->setComponentName(1,"Vx"); - fieldDoubleVectorOnNodes->setComponentDescription(1,"comp1"); - fieldDoubleVectorOnNodes->setMEDComponentUnit(1,"unit1"); - fieldDoubleVectorOnNodes->setComponentName(2,"Vy"); - fieldDoubleVectorOnNodes->setComponentDescription(2,"comp2"); - fieldDoubleVectorOnNodes->setMEDComponentUnit(2,"unit2"); - fieldDoubleVectorOnNodes->setComponentName(3,"Vz"); - fieldDoubleVectorOnNodes->setComponentDescription(3,"comp3"); - fieldDoubleVectorOnNodes->setMEDComponentUnit(3,"unit3"); - - FIELD<double> * fieldDoubleScalarOnCells = new FIELD<double>(supportOnCells,1); - fieldDoubleScalarOnCells->setName("fieldScalarDoubleCell"); - fieldDoubleScalarOnCells->setIterationNumber(-1); - fieldDoubleScalarOnCells->setOrderNumber(-1); - fieldDoubleScalarOnCells->setTime(0.0); - - fieldDoubleScalarOnCells->setComponentName(1,"Vx"); - fieldDoubleScalarOnCells->setComponentDescription(1,"comp1"); - fieldDoubleScalarOnCells->setMEDComponentUnit(1,"unit1"); - - - FIELD<double> * fieldDoubleScalarOnPartialCells = new FIELD<double>(&partialGroupOnCells,1); - fieldDoubleScalarOnPartialCells->setName("fieldScalarDoublePartialCell"); - fieldDoubleScalarOnPartialCells->setIterationNumber(-1); - fieldDoubleScalarOnPartialCells->setOrderNumber(-1); - fieldDoubleScalarOnPartialCells->setTime(0.0); - - fieldDoubleScalarOnPartialCells->setComponentName(1,"Vx"); - fieldDoubleScalarOnPartialCells->setComponentDescription(1,"comp1"); - fieldDoubleScalarOnPartialCells->setMEDComponentUnit(1,"unit1"); - - FIELD<double> * fieldDoubleScalarOnPartialFaces = new FIELD<double>(&partialGroupOnFaces,1); - fieldDoubleScalarOnPartialFaces->setName("fieldScalarDoublePartialFace"); - fieldDoubleScalarOnPartialFaces->setIterationNumber(-1); - fieldDoubleScalarOnPartialFaces->setOrderNumber(-1); - fieldDoubleScalarOnPartialFaces->setTime(0.0); - fieldDoubleScalarOnPartialFaces->setComponentName(1,"Vx"); - fieldDoubleScalarOnPartialFaces->setComponentDescription(1,"comp1"); - fieldDoubleScalarOnPartialFaces->setMEDComponentUnit(1,"unit1"); - - FIELD<double> * fieldDoubleVectorOnPartialFaces = new FIELD<double>(&partialGroupOnFaces2,2); - fieldDoubleVectorOnPartialFaces->setName("fieldVectorDoublePartialFace"); - fieldDoubleVectorOnPartialFaces->setIterationNumber(-1); - fieldDoubleVectorOnPartialFaces->setOrderNumber(-1); - fieldDoubleVectorOnPartialFaces->setTime(0.0); - fieldDoubleVectorOnPartialFaces->setComponentName(1,"Vx"); - fieldDoubleVectorOnPartialFaces->setComponentName(2,"Vy"); - - fieldDoubleVectorOnPartialFaces->setComponentDescription(1,"comp1"); - fieldDoubleVectorOnPartialFaces->setComponentDescription(2,"comp2"); - - fieldDoubleVectorOnPartialFaces->setMEDComponentUnit(1,"unit1"); - fieldDoubleVectorOnPartialFaces->setMEDComponentUnit(2,"unit2"); - - - FIELD<double> * fieldDoubleVectorOnCells = new FIELD<double>(supportOnCells,SpaceDimension); - fieldDoubleVectorOnCells->setName("fieldVectorrDoubleCell"); - fieldDoubleVectorOnCells->setIterationNumber(-1); - fieldDoubleVectorOnCells->setOrderNumber(-1); - fieldDoubleVectorOnCells->setTime(0.0); - - fieldDoubleVectorOnCells->setComponentName(1,"Vx"); - fieldDoubleVectorOnCells->setComponentDescription(1,"comp1"); - fieldDoubleVectorOnCells->setMEDComponentUnit(1,"unit1"); - fieldDoubleVectorOnCells->setComponentName(2,"Vy"); - fieldDoubleVectorOnCells->setComponentDescription(2,"comp2"); - fieldDoubleVectorOnCells->setMEDComponentUnit(2,"unit2"); - fieldDoubleVectorOnCells->setComponentName(3,"Vz"); - fieldDoubleVectorOnCells->setComponentDescription(3,"comp3"); - fieldDoubleVectorOnCells->setMEDComponentUnit(3,"unit3"); - - FIELD<int> * fieldIntScalarOnNodes = new FIELD<int>(supportOnNodes,1); - fieldIntScalarOnNodes->setName("fieldScalarIntNode"); - fieldIntScalarOnNodes->setIterationNumber(-1); - fieldIntScalarOnNodes->setOrderNumber(-1); - fieldIntScalarOnNodes->setTime(0.0); - - fieldIntScalarOnNodes->setComponentName(1,"Vx"); - fieldIntScalarOnNodes->setComponentDescription(1,"comp1"); - fieldIntScalarOnNodes->setMEDComponentUnit(1,"unit1"); - - FIELD<int> * fieldIntVectorOnNodes = new FIELD<int>(supportOnNodes,SpaceDimension); - fieldIntVectorOnNodes->setName("fieldVectorIntNode"); - fieldIntVectorOnNodes->setIterationNumber(-1); - fieldIntVectorOnNodes->setOrderNumber(-1); - fieldIntVectorOnNodes->setTime(0.0); - - fieldIntVectorOnNodes->setComponentName(1,"Vx"); - fieldIntVectorOnNodes->setComponentDescription(1,"comp1"); - fieldIntVectorOnNodes->setMEDComponentUnit(1,"unit1"); - fieldIntVectorOnNodes->setComponentName(2,"Vy"); - fieldIntVectorOnNodes->setComponentDescription(2,"comp2"); - fieldIntVectorOnNodes->setMEDComponentUnit(2,"unit2"); - fieldIntVectorOnNodes->setComponentName(3,"Vz"); - fieldIntVectorOnNodes->setComponentDescription(3,"comp3"); - fieldIntVectorOnNodes->setMEDComponentUnit(3,"unit3"); - - FIELD<int> * fieldIntScalarOnCells = new FIELD<int>(supportOnCells,1); - fieldIntScalarOnCells->setName("fieldScalarIntCell"); - fieldIntScalarOnCells->setIterationNumber(-1); - fieldIntScalarOnCells->setOrderNumber(-1); - fieldIntScalarOnCells->setTime(0.0); - - fieldIntScalarOnCells->setComponentName(1,"Vx"); - fieldIntScalarOnCells->setComponentDescription(1,"comp1"); - fieldIntScalarOnCells->setMEDComponentUnit(1,"unit1"); - - FIELD<int> * fieldIntVectorOnCells = new FIELD<int>(supportOnCells,SpaceDimension); - fieldIntVectorOnCells->setName("fieldVectorrIntCell"); - fieldIntVectorOnCells->setIterationNumber(-1); - fieldIntVectorOnCells->setOrderNumber(-1); - fieldIntVectorOnCells->setTime(0.0); - - fieldIntVectorOnCells->setComponentName(1,"Vx"); - fieldIntVectorOnCells->setComponentDescription(1,"comp1"); - fieldIntVectorOnCells->setMEDComponentUnit(1,"unit1"); - fieldIntVectorOnCells->setComponentName(2,"Vy"); - fieldIntVectorOnCells->setComponentDescription(2,"comp2"); - fieldIntVectorOnCells->setMEDComponentUnit(2,"unit2"); - fieldIntVectorOnCells->setComponentName(3,"Vz"); - fieldIntVectorOnCells->setComponentDescription(3,"comp3"); - fieldIntVectorOnCells->setMEDComponentUnit(3,"unit3"); - - for (int i = 0; i<numberOfNodes; i++) - { - double valueDbl1, valueDbl2, valueDbl3; - int valueInt1, valueInt2, valueInt3; - valueInt1 = i+1; - valueInt2 = i+2; - valueInt3 = i+3; - valueDbl1 = valueInt1*0.1; - valueDbl2 = valueInt2*0.1; - valueDbl3 = valueInt3*0.1; - fieldDoubleScalarOnNodes->setValueIJ(i+1,1,valueDbl1); - - fieldIntScalarOnNodes->setValueIJ(i+1,1,valueInt1); - - fieldDoubleVectorOnNodes->setValueIJ(i+1,1,valueDbl1); - fieldDoubleVectorOnNodes->setValueIJ(i+1,2,valueDbl2); - fieldDoubleVectorOnNodes->setValueIJ(i+1,3,valueDbl3); - - fieldIntVectorOnNodes->setValueIJ(i+1,1,valueInt1); - fieldIntVectorOnNodes->setValueIJ(i+1,2,valueInt2); - fieldIntVectorOnNodes->setValueIJ(i+1,3,valueInt3); - } - - for (int i = 0; i<numberOfCells; i++) - { - double valueDbl1, valueDbl2, valueDbl3; - int valueInt1, valueInt2, valueInt3; - valueInt1 = i+1; - valueInt2 = i+2; - valueInt3 = i+3; - valueDbl1 = valueInt1*0.1; - valueDbl2 = valueInt2*0.1; - valueDbl3 = valueInt3*0.1; - fieldDoubleScalarOnCells->setValueIJ(i+1,1,valueDbl1); - - fieldIntScalarOnCells->setValueIJ(i+1,1,valueInt1); - - fieldDoubleVectorOnCells->setValueIJ(i+1,1,valueDbl1); - fieldDoubleVectorOnCells->setValueIJ(i+1,2,valueDbl2); - fieldDoubleVectorOnCells->setValueIJ(i+1,3,valueDbl3); - - fieldIntVectorOnCells->setValueIJ(i+1,1,valueInt1); - fieldIntVectorOnCells->setValueIJ(i+1,2,valueInt2); - fieldIntVectorOnCells->setValueIJ(i+1,3,valueInt3); - } - - for (int i=0; i<partialGroupOnNodes.getNumberOfElements(MED_ALL_ELEMENTS); i++) - { - const int* number=partialGroupOnNodes.getNumber(MED_ALL_ELEMENTS); - fieldDoubleScalarOnPartialNodes->setValueIJ(number[i],1,i+1); - } - - for (int i=0; i<partialGroupOnCells.getNumberOfElements(MED_ALL_ELEMENTS); i++) - { - const int* number=partialGroupOnCells.getNumber(MED_ALL_ELEMENTS); - fieldDoubleScalarOnPartialCells->setValueIJ(number[i],1,i+1); - } - - for (int i=0; i<partialGroupOnFaces.getNumberOfElements(MED_ALL_ELEMENTS); i++) - { - const int* number=partialGroupOnFaces.getNumber(MED_ALL_ELEMENTS); - fieldDoubleScalarOnPartialFaces->setValueIJ(number[i],1,i+1); - } - - for (int i=0; i<partialGroupOnFaces2.getNumberOfElements(MED_ALL_ELEMENTS); i++) - { - const int* number=partialGroupOnFaces2.getNumber(MED_ALL_ELEMENTS); - fieldDoubleVectorOnPartialFaces->setValueIJ(number[i],1,i+1); - fieldDoubleVectorOnPartialFaces->setValueIJ(number[i],2,-i-1); - } - - version = getMedFileVersionForWriting(); - if (version == V22) - setMedFileVersionForWriting(V21); - - idMed21 = fieldDoubleScalarOnNodes->addDriver(MED_DRIVER,filenameMed21,fieldDoubleScalarOnNodes->getName()); - fieldDoubleScalarOnNodes->write(idMed21) ; - - idMed21 = fieldIntScalarOnNodes->addDriver(MED_DRIVER,filenameMed21,fieldIntScalarOnNodes->getName()); - fieldIntScalarOnNodes->write(idMed21) ; - - idMed21 = fieldDoubleVectorOnNodes->addDriver(MED_DRIVER,filenameMed21,fieldDoubleVectorOnNodes->getName()); - fieldDoubleVectorOnNodes->write(idMed21) ; - - idMed21 = fieldIntVectorOnNodes->addDriver(MED_DRIVER,filenameMed21,fieldIntVectorOnNodes->getName()); - fieldIntVectorOnNodes->write(idMed21) ; - - idMed21 = fieldDoubleScalarOnCells->addDriver(MED_DRIVER,filenameMed21,fieldDoubleScalarOnCells->getName()); - fieldDoubleScalarOnCells->write(idMed21) ; - - idMed21 = fieldIntScalarOnCells->addDriver(MED_DRIVER,filenameMed21,fieldIntScalarOnCells->getName()); - fieldIntScalarOnCells->write(idMed21) ; - - idMed21 = fieldDoubleVectorOnCells->addDriver(MED_DRIVER,filenameMed21,fieldDoubleVectorOnCells->getName()); - fieldDoubleVectorOnCells->write(idMed21) ; - - idMed21 = fieldIntVectorOnCells->addDriver(MED_DRIVER,filenameMed21,fieldIntVectorOnCells->getName()); - fieldIntVectorOnCells->write(idMed21) ; - - - version = getMedFileVersionForWriting(); - if (version == V21) - setMedFileVersionForWriting(V22); - - idMed22 = fieldDoubleScalarOnNodes->addDriver(MED_DRIVER,filenameMed22,fieldDoubleScalarOnNodes->getName()); - fieldDoubleScalarOnNodes->write(idMed22) ; - - idMed22 = fieldIntScalarOnNodes->addDriver(MED_DRIVER,filenameMed22,fieldIntScalarOnNodes->getName()); - fieldIntScalarOnNodes->write(idMed22) ; - - idMed22 = fieldDoubleVectorOnNodes->addDriver(MED_DRIVER,filenameMed22,fieldDoubleVectorOnNodes->getName()); - fieldDoubleVectorOnNodes->write(idMed22) ; - - idMed22 = fieldIntVectorOnNodes->addDriver(MED_DRIVER,filenameMed22,fieldIntVectorOnNodes->getName()); - fieldIntVectorOnNodes->write(idMed22) ; - - idMed22 = fieldDoubleScalarOnCells->addDriver(MED_DRIVER,filenameMed22,fieldDoubleScalarOnCells->getName()); - fieldDoubleScalarOnCells->write(idMed22) ; - - idMed22 = fieldIntScalarOnCells->addDriver(MED_DRIVER,filenameMed22,fieldIntScalarOnCells->getName()); - fieldIntScalarOnCells->write(idMed22) ; - - idMed22 = fieldDoubleVectorOnCells->addDriver(MED_DRIVER,filenameMed22,fieldDoubleVectorOnCells->getName()); - fieldDoubleVectorOnCells->write(idMed22) ; - - idMed22 = fieldIntVectorOnCells->addDriver(MED_DRIVER,filenameMed22,fieldIntVectorOnCells->getName()); - fieldIntVectorOnCells->write(idMed22) ; - - idMed22 = fieldDoubleScalarOnPartialNodes->addDriver(MED_DRIVER,filenameMed22,fieldDoubleScalarOnPartialNodes->getName()); - fieldDoubleScalarOnPartialNodes->write(idMed22) ; - - idMed22 = fieldDoubleScalarOnPartialCells->addDriver(MED_DRIVER,filenameMed22,fieldDoubleScalarOnPartialCells->getName()); - fieldDoubleScalarOnPartialCells->write(idMed22) ; - - idMed22 = fieldDoubleScalarOnPartialFaces->addDriver(MED_DRIVER,filenameMed22,fieldDoubleScalarOnPartialFaces->getName()); - fieldDoubleScalarOnPartialFaces->write(idMed22) ; - - idMed22 = fieldDoubleVectorOnPartialFaces->addDriver(MED_DRIVER,filenameMed22,fieldDoubleVectorOnPartialFaces->getName()); - fieldDoubleVectorOnPartialFaces->write(idMed22) ; - - - idVtk = fieldDoubleScalarOnNodes->addDriver(VTK_DRIVER,filenameVtk,fieldDoubleScalarOnNodes->getName()); - fieldDoubleScalarOnNodes->writeAppend(idVtk) ; - - idVtk = fieldIntScalarOnNodes->addDriver(VTK_DRIVER,filenameVtk,fieldIntScalarOnNodes->getName()); - fieldIntScalarOnNodes->writeAppend(idVtk) ; - - idVtk = fieldDoubleVectorOnNodes->addDriver(VTK_DRIVER,filenameVtk,fieldDoubleVectorOnNodes->getName()); - fieldDoubleVectorOnNodes->writeAppend(idVtk) ; - - idVtk = fieldIntVectorOnNodes->addDriver(VTK_DRIVER,filenameVtk,fieldIntVectorOnNodes->getName()); - fieldIntVectorOnNodes->writeAppend(idVtk) ; - - idVtk = fieldDoubleScalarOnCells->addDriver(VTK_DRIVER,filenameVtk,fieldDoubleScalarOnCells->getName()); - fieldDoubleScalarOnCells->writeAppend(idVtk) ; - - idVtk = fieldIntScalarOnCells->addDriver(VTK_DRIVER,filenameVtk,fieldIntScalarOnCells->getName()); - fieldIntScalarOnCells->writeAppend(idVtk) ; - - idVtk = fieldDoubleVectorOnCells->addDriver(VTK_DRIVER,filenameVtk,fieldDoubleVectorOnCells->getName()); - fieldDoubleVectorOnCells->writeAppend(idVtk) ; - - idVtk = fieldIntVectorOnCells->addDriver(VTK_DRIVER,filenameVtk,fieldIntVectorOnCells->getName()); - fieldIntVectorOnCells->writeAppend(idVtk) ; - - - delete fieldDoubleScalarOnNodes; - delete fieldIntScalarOnNodes; - delete fieldDoubleVectorOnNodes; - delete fieldIntVectorOnNodes; - delete fieldDoubleScalarOnCells; - delete fieldIntScalarOnCells; - delete fieldDoubleVectorOnCells; - delete fieldIntVectorOnCells; - delete fieldDoubleScalarOnPartialCells; - delete fieldDoubleScalarOnPartialNodes; - delete fieldDoubleScalarOnPartialFaces; - delete fieldDoubleVectorOnPartialFaces; - - delete supportOnNodes; - delete supportOnCells; -} diff --git a/src/MEDMEM/test_MEDMEM_MeshingFlica.cxx b/src/MEDMEM/test_MEDMEM_MeshingFlica.cxx deleted file mode 100644 index 353890df3..000000000 --- a/src/MEDMEM/test_MEDMEM_MeshingFlica.cxx +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -#include "MEDMEM_Meshing.hxx" -#include "MEDMEM_Group.hxx" - -double coords[108]= - {0, 0.21504, 0.21504, 0, 0.43008, - 0.43008, 0.21504, 0, 0.43008, 0, - 0.21504, 0.21504, 0, 0.43008, - 0.43008, 0.21504, 0, 0.43008, 0, - 0.21504, 0.21504, 0, 0.43008, - 0.43008, 0.21504, 0, 0.43008, 0, - 0.21504, 0.21504, 0, 0.43008, - 0.43008, 0.21504, 0, 0.43008, - //coordY - 0, 0, 0.21504, 0.21504, 0, 0.21504, - 0.43008, 0.43008, 0.43008, 0, 0, - 0.21504, 0.21504, 0, 0.21504, - 0.43008, 0.43008, 0.43008, 0, 0, - 0.21504, 0.21504, 0, 0.21504, - 0.43008, 0.43008, 0.43008, 0, 0, - 0.21504, 0.21504, 0, 0.21504, - 0.43008, 0.43008, 0.43008, - //coordZ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.15677, 0.15677, - 0.15677, 0.15677, 0.15677, - 0.15677, 0.15677, 0.15677, - 0.15677, 0.1934, 0.1934, - 0.1934, 0.1934, 0.1934, - 0.1934, 0.1934, 0.1934, - 0.1934, 0.3485, 0.3485, - 0.3485, 0.3485, 0.3485, - 0.3485, 0.3485, 0.3485, - 0.3485}; - -int connNodalCellClassical[48]= - { 1, 2, 3, 4, 10, 11, 12, 13, - 4, 3, 7, 8, 13, 12, 16, 17, - 10, 11, 12, 13, 19, 20, 21, 22, - 13, 12, 16, 17, 22, 21, 25, 26, - 19, 20, 21, 22, 28, 29, 30, 31, - 22, 21, 25, 26, 31, 30, 34, 35 }; - -int polyHedraInd[7]={1, 7, 13, 19, 25, 31, 37}; -int polyHedraFacesInd[37]={ - 1, 5, 9, 13, 17, 21, - 25, 29, 33, 37, 41, 45, - 49, 53, 57, 61, 65, 69, - 73, 77, 81, 85, 89, 93, - 97, 101, 105, 109, 113, 117, - 121, 125, 129, 133, 137, 141, - 145 }; - -int polyHedraConn[144]={ - 2, 3, 6, 5, 11, 14, 15, 12, 2, 5, 14, 11, 5, 6, 15, 14, 6, 3, 12, 15, 3, 2, 11, 12, - 3, 7, 9, 6, 12, 15, 18, 16, 3, 6, 15, 12, 6, 9, 18, 15, 9, 7, 16, 18, 7, 3, 12, 16, - 11, 12, 15, 14, 20, 23, 24, 21, 11, 14, 23, 20, 14, 15, 24, 23, 15, 12, 21, 24, 12, 11, 20, 21, - 12, 16, 18, 15, 21, 24, 27, 25, 12, 15, 24, 21, 15, 18, 27, 24, 18, 16, 25, 27, 16, 12, 21, 25, - 20, 21, 24, 23, 29, 32, 33, 30, 20, 23, 32, 29, 23, 24, 33, 32, 24, 21, 30, 33, 21, 20, 29, 30, - 21, 25, 27, 24, 30, 33, 36, 34, 21, 24, 33, 30, 24, 27, 36, 33, 27, 25, 34, 36, 25, 21, 30, 34 }; - -int connNodalFaceClassical[116]= - { 1, 2, 3, 4, - 10, 13, 12, 11, - 1, 2, 11, 10, - 2, 3, 12, 11, - 3, 4, 13, 12, - 4, 1, 10, 13, - 4, 3, 7, 8, - 13, 17, 16, 12, - 3, 7, 16, 12, - 7, 8, 17, 16, - 8, 4, 13, 17, - 19, 22, 21, 20, - 10, 11, 20, 19, - 11, 12, 21, 20, - 12, 13, 22, 21, - 13, 10, 19, 22, - 22, 26, 25, 21, - 12, 16, 25, 21, - 16, 17, 26, 25, - 17, 13, 22, 26, - 28, 31, 30, 29, - 19, 20, 29, 28, - 20, 21, 30, 29, - 21, 22, 31, 30, - 22, 19, 28, 31, - 31, 35, 34, 30, - 21, 25, 34, 30, - 25, 26, 35, 34, - 26, 22, 31, 35}; - -int cpolygonsIndex[24]= - { 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, - 73, 77, 81, 85, 89, 93}; - -int cpolygonsValue[92]= - {2, 5, 6, 3, - 11, 12, 15, 14, - 2, 5, 14, 11, - 5, 6, 15, 14, - 6, 3, 12, 15, - 3, 6, 9, 7, - 12, 16, 18, 15, - 6, 9, 18, 15, - 9, 7, 16, 18, - 20, 21, 24, 23, - 11, 14, 23, 20, - 14, 15, 24, 23, - 15, 12, 21, 24, - 21, 25, 27, 24, - 15, 18, 27, 24, - 18, 16, 25, 27, - 29, 30, 33, 32, - 20, 23, 32, 29, - 23, 24, 33, 32, - 24, 21, 30, 33, - 30, 34, 36, 33, - 24, 27, 36, 33, - 27, 25, 34, 36}; - -int bottom[4]={1,7,30,35}; MED_EN::medGeometryElement bottomTypes[2]={MED_EN::MED_QUAD4, MED_EN::MED_POLYGON }; int bottomIndex[3]={1,3,5}; int bottomNbOfElts[2]={2,2}; -int top[4]={21,26,46,50}; MED_EN::medGeometryElement topTypes[2]={MED_EN::MED_QUAD4, MED_EN::MED_POLYGON }; int topIndex[3]={1,3,5}; int topNbOfElts[2]={2,2}; -int side[24]={ 3, 6, 10, 11, 13, 16, 19, 20, 22, 25, 28, 29, 32, 33, 37, 38, 40, 41, 44, 45, - 47, 48, 51, 52}; MED_EN::medGeometryElement sideTypes[2]={MED_EN::MED_QUAD4, MED_EN::MED_POLYGON }; int sideIndex[3]={1,13,25}; int sideNbOfElts[2]={12,12}; - -using namespace MEDMEM; - -void addMedFacesGroup( MESHING& meshing, int nFaces, const int *groupValue, - string groupName, const MED_EN::medGeometryElement *mytypes, const int *index, const int *myNumberOfElements, int nbOfGeomTypes) - { - GROUP faces ; - faces.setName(groupName) ; - faces.setMesh(&meshing) ; - faces.setEntity(MED_EN::MED_FACE) ; - faces.setNumberOfGeometricType(nbOfGeomTypes) ; - faces.setGeometricType(mytypes); - faces.setNumberOfElements(myNumberOfElements) ; - faces.setNumber(index, groupValue) ; - meshing.addGroup(faces) ; - } - -int main() -{ - MESHING* meshing = new MESHING(); - meshing->setName( "TESTMESH" ); - meshing->setSpaceDimension(3); - const int nNodes=36; - meshing->setNumberOfNodes(nNodes); - meshing->setCoordinates(3, nNodes, coords, "CARTESIAN", - MED_EN::MED_NO_INTERLACE); - string coordname[3] = { "x", "y", "z" }; - meshing->setCoordinatesNames(coordname); - string coordunit[3] = { "m", "m", "m" }; - meshing->setCoordinatesUnits(coordunit); - //Cell connectivity info for classical elts - const MED_EN::medGeometryElement classicalTypesCell[1]={MED_EN::MED_HEXA8}; - const int nbOfCellElts[1]={6}; - meshing->setNumberOfTypes(1,MED_EN::MED_CELL); - meshing->setTypes(classicalTypesCell,MED_EN::MED_CELL); - meshing->setNumberOfElements(nbOfCellElts,MED_EN::MED_CELL); - meshing->setMeshDimension(3); - //Face connectivity info for classical elts - const MED_EN::medGeometryElement classicalTypesFace[1]={MED_EN::MED_QUAD4}; - const int nbOfFaceElts[1]={29}; - meshing->setNumberOfTypes(1,MED_EN::MED_FACE); - meshing->setTypes(classicalTypesFace,MED_EN::MED_FACE); - meshing->setNumberOfElements(nbOfFaceElts,MED_EN::MED_FACE); - //All cell conn - meshing->setConnectivity(connNodalCellClassical,MED_EN::MED_CELL,MED_EN::MED_HEXA8); - meshing->setPolyhedraConnectivity(polyHedraInd,polyHedraFacesInd,polyHedraConn,6,MED_EN::MED_CELL); - //All face conn - meshing->setConnectivity(connNodalFaceClassical,MED_EN::MED_FACE,MED_EN::MED_QUAD4); - meshing->setPolygonsConnectivity(cpolygonsIndex,cpolygonsValue,23,MED_EN::MED_FACE); - //Adding some groups on faces - addMedFacesGroup( *meshing, 4, bottom, "BottomFaces",bottomTypes,bottomIndex,bottomNbOfElts,2) ; - addMedFacesGroup( *meshing, 4, top, "TopFaces",topTypes,topIndex,topNbOfElts,2) ; - addMedFacesGroup( *meshing, 24, side, "SideFaces",sideTypes,sideIndex,sideNbOfElts,2) ; - //writing... - int id=meshing->addDriver(MED_DRIVER,"/tmp/totoFlica_V22.med"); - meshing->write(id); - delete meshing; - return 0; -} diff --git a/src/MEDMEM/test_MEDMEM_MeshingPoly.cxx b/src/MEDMEM/test_MEDMEM_MeshingPoly.cxx deleted file mode 100644 index fab4bf668..000000000 --- a/src/MEDMEM/test_MEDMEM_MeshingPoly.cxx +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include "MEDMEM_Meshing.hxx" -#include "MEDMEM_Field.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -int main (int argc, char ** argv) { - double Coordinates[57] = { - 2.0, 3.0, 2.0, - 3.0, 2.0, 2.0, - 4.0, 1.0, 2.0, - 2.0, 0.0, 2.0, - 0.0, 1.0, 2.0, - 1.0, 2.0, 2.0, - 2.0, 3.0, 1.0, - 3.0, 2.0, 0.0, - 4.0, 1.0, 0.0, - 2.0, 0.0, 0.0, - 0.0, 1.0, 0.0, - 1.0, 2.0, 0.0, - 5.0, 3.0, 2.0, - 7.0, 2.0, 2.0, - 6.0, 0.0, 2.0, - 6.0, 3.0, 0.0, - 7.0, 2.0, 0.0, - 6.0, 0.0, -1.0, - 5.0, 1.0, -3.0}; - - const int REFnodalConnOfFaces[74] = { - 1, 2, 3, 4, 5, 6, // Polyhedron 1 - 1, 7, 8, 2, - 2, 8, 9, 3, - 4, 3, 9, 10, - 5, 4, 10, 11, - 6, 5, 11, 12, - 1, 6, 12, 7, - 7, 12, 8, - 10, 9, 8, 12, 11, - - 13, 14, 15, 3, 2, // Polyhedron 2 - 13, 2, 8, 16, - 14, 13, 16, 17, - 15, 14, 17, - 15, 17, 18, - 15, 18, 9, - 3, 15, 9, - 2, 3, 9, 8, - 8, 9, 17, 16, - 9, 18, 17}; - - const int REFfacesIndex[20] = { - 1, 7, 11, 15, 19, 23, 27, 31, 34, - 39, 44, 48, 52, 55, 58, 61, 64, 68, 72, 75}; - - const int REFpolyIndex[3] = {1, 10, 20}; - - double PolygonCoordinates[27] = { - 2.0, 3.0, 12.0, - 3.0, 2.0, 12.0, - 4.0, 1.0, 12.0, - 2.0, 0.0, 12.0, - 0.0, 1.0, 12.0, - 1.0, 2.0, 12.0, - 5.0, 3.0, 12.0, - 7.0, 2.0, 12.0, - 6.0, 0.0, 12.0}; - - const int REFpolygonFaces[11] = { - 1, 2, 3, 4, 5, 6, // Polygon 1 - 7, 8, 9, 3, 2}; // Polygon 2 - - const int REFpolygonIndex[3] = {1, 7, 12}; - - MESHING myMeshing; - myMeshing.setName("meshing"); - - int NumberOfNodes = 19; - int SpaceDimension = 3; - int MeshDimension = 3; - - const int NumberOfTypes = 1; - medGeometryElement Types[NumberOfTypes] = {MED_TETRA4}; - const int NumberOfElements[NumberOfTypes] = {1}; - - myMeshing.setNumberOfTypes(NumberOfTypes, MED_CELL); - - myMeshing.setCoordinates(SpaceDimension, NumberOfNodes, Coordinates, - "CARTESIAN", MED_FULL_INTERLACE); - myMeshing.setSpaceDimension(SpaceDimension); - myMeshing.setMeshDimension(MeshDimension); - myMeshing.setTypes(Types, MED_CELL); - myMeshing.setNumberOfElements(NumberOfElements, MED_CELL); - - string Names[3] = {"X","Y","Z"}; - myMeshing.setCoordinatesNames(Names); - - string Units[3] = {"cm","cm","cm"}; - myMeshing.setCoordinatesUnits(Units); - - const int sizeTetra = 4*1 ; - int ConnectivityTetra[sizeTetra]= - { - 17, 9, 18, 19 - }; - - myMeshing.setConnectivity(ConnectivityTetra, MED_CELL, MED_TETRA4); - - myMeshing.setPolyhedraConnectivity(REFpolyIndex, REFfacesIndex, - REFnodalConnOfFaces, 2, MED_CELL); - - - MESHING myPolygonMeshing; - myPolygonMeshing.setName("PolygonMeshing"); - - NumberOfNodes = 9; - SpaceDimension = 3; - MeshDimension = 2; - medGeometryElement PolygonTypes[NumberOfTypes] = {MED_TRIA3}; - const int PolygonNumberOfElements[NumberOfTypes] = {2}; - - myPolygonMeshing.setNumberOfTypes(NumberOfTypes, MED_CELL); - - myPolygonMeshing.setCoordinates(SpaceDimension, NumberOfNodes, PolygonCoordinates, - "CARTESIAN", MED_FULL_INTERLACE); - myPolygonMeshing.setSpaceDimension(SpaceDimension); - myPolygonMeshing.setMeshDimension(MeshDimension); - myPolygonMeshing.setTypes(PolygonTypes, MED_CELL); - myPolygonMeshing.setNumberOfElements(PolygonNumberOfElements, MED_CELL); - - myPolygonMeshing.setCoordinatesNames(Names); - myPolygonMeshing.setCoordinatesUnits(Units); - - const int sizeTri = 3*2 ; - int ConnectivityTri[sizeTri]= - { - 1, 7, 2, 3, 9, 4 - }; - - myPolygonMeshing.setConnectivity(ConnectivityTri, MED_CELL, MED_TRIA3); - myPolygonMeshing.setPolygonsConnectivity(REFpolygonIndex, REFpolygonFaces, 2, MED_CELL); - SUPPORT *sup2 = new SUPPORT(&myPolygonMeshing); - FIELD<double> *areas = myPolygonMeshing.getArea(sup2); - const double *vals2 = areas->getValue(); - const double REFAreaOfPolyg[4] ={1.5, 2, 6, 6.5}; - int nbPts=0; - int i; - for(i=0;i<4;i++) - if(fabs(REFAreaOfPolyg[i]-vals2[i])<1e-12) - nbPts++; - delete areas; - delete sup2; - - SUPPORT *sup = new SUPPORT(&myMeshing); - FIELD<double> *vols = myMeshing.getVolume(sup); - const double *vals = vols->getValue(); - const double REFVolOfPolyHedron[3] = {2.333333333333333, 11.66666666666666, 13.83224131414673}; - for(i=0;i<3;i++) - if(fabs(REFVolOfPolyHedron[i]-vals[i])<1e-12) - nbPts++; - - delete vols; - delete sup; - if(nbPts==7) - { - cout << "ALL TESTS OK !!!" << endl; - } - else - { - cout << "TEST FAILS !!!" << endl; - return -1; - } - cout << "Writing test " << endl; - int idMed22 = myMeshing.addDriver(MED_DRIVER,"totoPoly_V22.med",myMeshing.getName()); - myMeshing.write(idMed22); - -} diff --git a/src/MEDMEM/test_MEDMEM_Meshing_poly.cxx b/src/MEDMEM/test_MEDMEM_Meshing_poly.cxx deleted file mode 100644 index 155a5cb9d..000000000 --- a/src/MEDMEM/test_MEDMEM_Meshing_poly.cxx +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include "MEDMEM_Meshing.hxx" -#include "MEDMEM_DriverFactory.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; -using namespace DRIVERFACTORY; - -int main (int argc, char ** argv) -{ - // Traitement arguments - if (argc > 2) - { - cerr << "Usage : " << argv[0] - << " filenameRoot" << endl << endl - << "-> creer un maillage et le sauve dans le fichier filenameRoot22.med sous le format Med Fichier V2.2 car il contient un polygon." << endl; - exit(-1); - } - - string filenameRoot; - if (argc==2) - filenameRoot= argv[1] ; - else - filenameRoot="/tmp/testMeshingPoly"; - - string medfilename = filenameRoot + "22.med"; - - // Creation maillage - //*********************************************************************************** - - MESHING myMeshing; - myMeshing.setName("myMeshing"); - - // define coordinates - - int SpaceDimension = 2; - int NumberOfNodes = 11; - double Coordinates[2*11] = { - 0.0, 0.0, - 0.5, 0.0, - 1.0, 0.0, - 0.25, 0.5, - 0.5, 0.5, - 0.75, 0.5, - 0.0, 1.0, - 0.5, 1.0, - 1.0, 1.0, - 1.5, 0.0, - 1.5, 1.0, - }; - - myMeshing.setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,"CARTESIAN",MED_FULL_INTERLACE); - - string Names[3] = { "X","Y","Z" }; - myMeshing.setCoordinatesNames(Names); - - string Units[3] = { "cm","cm","cm" }; - myMeshing.setCoordinatesUnits(Units); - - // define conectivities of classic types - - // cell part - - const int NumberOfTypes = 2; - medGeometryElement Types[NumberOfTypes] = {MED_TRIA3,MED_QUAD4}; - const int NumberOfElements[NumberOfTypes] = {1,4}; - - myMeshing.setNumberOfTypes(NumberOfTypes,MED_CELL); - myMeshing.setTypes(Types,MED_CELL); - myMeshing.setNumberOfElements(NumberOfElements,MED_CELL); - - int ConnectivityTria[1*3]= - { - 7,4,1 - }; - - myMeshing.setConnectivity(ConnectivityTria,MED_CELL,MED_TRIA3); - - int ConnectivityQuad[4*4]= - { - 4,5,2,1, - 5,6,3,2, - 7,8,5,4, - 8,9,6,5 - }; - - myMeshing.setConnectivity(ConnectivityQuad,MED_CELL,MED_QUAD4); - - int MeshDimension = SpaceDimension ; - // because there are 2D cells in the mesh - - myMeshing.setMeshDimension(MeshDimension) ; - - // then define eventuel polygonal cells - - int ConnectivityPolygon[1*5]= - { - 9,11,10,3,6 - }; - int ConnectivityPolygonIndex[2]= - { - 1,6 - }; - - myMeshing.setPolygonsConnectivity(ConnectivityPolygonIndex,ConnectivityPolygon,1,MED_CELL); - - // Ecriture fichier - - medFileVersion version = getMedFileVersionForWriting(); - if (version == V21) - setMedFileVersionForWriting(V22); - - int idMed22 = myMeshing.addDriver(MED_DRIVER,medfilename,myMeshing.getName()); - myMeshing.write(idMed22) ; - - // int idVtk = myMeshing.addDriver(VTK_DRIVER,"toto.vtk",myMeshing.getName()); - // myMeshing.write(idVtk) ; - - //************************************************************************************ - - // impression de controle - cout << endl; - cout << "Impression de MESHING : " << endl; - cout << myMeshing; - -} diff --git a/src/MEDMEM/test_MEDMEM_ModulusArray.cxx b/src/MEDMEM/test_MEDMEM_ModulusArray.cxx deleted file mode 100644 index 677ea23c1..000000000 --- a/src/MEDMEM/test_MEDMEM_ModulusArray.cxx +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include "MEDMEM_ModulusArray.hxx" - -using namespace std; -using namespace MEDMEM; - -int main (int argc, char ** argv) { - using namespace std ; - - int array[5]={0,1,2,1,4} ; - MEDMODULUSARRAY modulusArray(5,array); - - cout<<"ModuloArray :"<<endl; - for(int i=-10;i<15;i++) - cout <<" - A["<<i<<"]="<<modulusArray[i]<<endl; - cout <<endl; - - // test compare - int ret ; - - int array2[5]={1,4,0,1,2} ; - MEDMODULUSARRAY modulusArray2(5,array2) ; - cout<<"Same arrays, same order ... "; - if ((ret=modulusArray2.compare(modulusArray))!=1) - cout << "Error : two arrays must be identical !"<<ret<<endl; - else - cout << "OK" <<endl; - - int array3[5]={1,2,1,0,4} ; - MEDMODULUSARRAY modulusArray3(5,array3) ; - cout<<"Same arrays, reverse order ... "; - if ((ret=modulusArray3.compare(modulusArray))!=-1) - cout << "Error : two arrays are in reverse order !"<<ret<<endl; - else - cout << "OK" <<endl; - - int array4[6]={1,2,1,0} ; - MEDMODULUSARRAY modulusArray4(4,array4) ; - cout<<"Different arrays size ... "; - if ((ret=modulusArray4.compare(modulusArray))!=0) - cout << "Error : two arrays have different size !"<<ret<<endl; - else - cout << "OK" <<endl; - - int array5[5]={1,2,1,0,1} ; - MEDMODULUSARRAY modulusArray5(5,array5) ; - cout<<"Different array, same size ... "; - if ((ret=modulusArray5.compare(modulusArray))!=0) - cout << "Error : two arrays are not be identical !"<<ret<<endl; - else - cout << "OK" <<endl; - - // test small array : - - // 1 - int array6[1]={1} ; - MEDMODULUSARRAY modulusArray6(1,array6); - - cout<<"ModuloArray 1 :"<<endl; - for(int i=-10;i<15;i++) - cout <<" - A["<<i<<"]="<<modulusArray6[i]<<endl; - cout <<endl; - - int array7[1]={1} ; - MEDMODULUSARRAY modulusArray7(1,array7); - cout<<"Same arrays, same order ... "; - if ((ret=modulusArray6.compare(modulusArray7))!=1) - cout << "Error : two arrays are identical !"<<ret<<endl; - else - cout << "OK" <<endl; - int array8[1]={2} ; - MEDMODULUSARRAY modulusArray8(1,array8); - cout<<"Different arrays ... "; - if ((ret=modulusArray6.compare(modulusArray8))!=0) - cout << "Error : two arrays are different !"<<ret<<endl; - else - cout << "OK" <<endl; - - - // 2 - int array60[2]={1,2} ; - MEDMODULUSARRAY modulusArray60(2,array60); - - cout<<"ModuloArray 2 :"<<endl; - for(int i=-10;i<15;i++) - cout <<" - A["<<i<<"]="<<modulusArray60[i]<<endl; - cout <<endl; - - int array70[2]={1,2} ; - MEDMODULUSARRAY modulusArray70(2,array70); - cout<<"Same arrays, same order ... "; - if ((ret=modulusArray60.compare(modulusArray70))!=1) - cout << "Error : two arrays are identical !"<<ret<<endl; - else - cout << "OK" <<endl; - int array80[2]={2,2} ; - MEDMODULUSARRAY modulusArray80(2,array80); - cout<<"Different arrays ... "; - if ((ret=modulusArray60.compare(modulusArray80))!=0) - cout << "Error : two arrays are different !"<<ret<<endl; - else - cout << "OK" <<endl; - int array90[2]={2,1} ; - MEDMODULUSARRAY modulusArray90(2,array90); - cout<<"Same arrays, reverse order ... "; - if ((ret=modulusArray60.compare(modulusArray90))!=-1) - cout << "Error : two arrays are in reverse order !"<<ret<<endl; - else - cout << "OK" <<endl; - - - - - - return 0 ; -} diff --git a/src/MEDMEM/test_MEDMEM_PolyConnectivity.cxx b/src/MEDMEM/test_MEDMEM_PolyConnectivity.cxx deleted file mode 100644 index d454d9022..000000000 --- a/src/MEDMEM/test_MEDMEM_PolyConnectivity.cxx +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -// This program test the implementation of the class CONNECTIVITY for Polygons and Polyhedron. // - -#include "MEDMEM_Connectivity.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -int main(void) -{ - CONNECTIVITY myNodalConnectivity; - CONNECTIVITY myDescendingConnectivity; - - //POLYGONS - const med_int NumberOfPolygons = 2; - const med_int ConnectivitySize = 12; -//CCRT med_int PolygonsConnectivityIndex[NumberOfPolygons+1] = {1,7,13}; - int PolygonsConnectivityIndex[NumberOfPolygons+1] = {1,7,13}; - - //Nodal -//CCRT med_int PolygonsNodalConnectivity[ConnectivitySize] = {1,2,3,4,5,10,10,5,6,7,8,9}; - int PolygonsNodalConnectivity[ConnectivitySize] = {1,2,3,4,5,10,10,5,6,7,8,9}; - - myNodalConnectivity.setPolygonsConnectivity(MED_NODAL,MED_CELL,PolygonsNodalConnectivity,PolygonsConnectivityIndex,ConnectivitySize,NumberOfPolygons); - - //Descending -//CCRT med_int PolygonsDescendingConnectivity[ConnectivitySize] = {1,2,3,4,11,10,11,5,6,7,8,9}; - int PolygonsDescendingConnectivity[ConnectivitySize] = {1,2,3,4,11,10,11,5,6,7,8,9}; - - myDescendingConnectivity.setPolygonsConnectivity(MED_DESCENDING,MED_CELL,PolygonsDescendingConnectivity,PolygonsConnectivityIndex,ConnectivitySize,NumberOfPolygons); - - //POLYHEDRON - const med_int NumberOfPolyhedron = 2; -//CCRT med_int PolyhedronIndex[NumberOfPolyhedron+1] = {1,10,20}; - int PolyhedronIndex[NumberOfPolyhedron+1] = {1,10,20}; - - //Nodal - const med_int NumberOfFaces = 19; - const med_int NumberOfNodes = 74; -//CCRT med_int PolyhedronFacesIndex[NumberOfFaces+1] = {1,7,11,15,19,23,27,31,34,39,44,48,52,55,58,61,64,68,72,75}; - int PolyhedronFacesIndex[NumberOfFaces+1] = {1,7,11,15,19,23,27,31,34,39,44,48,52,55,58,61,64,68,72,75}; -//CCRT med_int PolyhedronNodalConnectivity[NumberOfNodes] = {1,2,3,4,5,6,1,7,8,2,2,8,9,3,4,3,9,10,5,4,10,11,6,5,11,12,1,6,12,7,7,12,8,10,9,8,12,11,13,14,15,3,2,13,2,8,16,14,13,16,17,15,14,17,15,17,18,15,18,9,3,15,9,2,3,9,8,8,9,17,16,9,18,17}; - int PolyhedronNodalConnectivity[NumberOfNodes] = {1,2,3,4,5,6,1,7,8,2,2,8,9,3,4,3,9,10,5,4,10,11,6,5,11,12,1,6,12,7,7,12,8,10,9,8,12,11,13,14,15,3,2,13,2,8,16,14,13,16,17,15,14,17,15,17,18,15,18,9,3,15,9,2,3,9,8,8,9,17,16,9,18,17}; - - myNodalConnectivity.setPolyhedronConnectivity(MED_NODAL,PolyhedronNodalConnectivity,PolyhedronIndex,NumberOfNodes,NumberOfPolyhedron,PolyhedronFacesIndex,NumberOfFaces); - - //Descending - const med_int DescendingConnectivitySize = 19; -//CCRT med_int PolyhedronDescendingConnectivity[DescendingConnectivitySize] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,3,17,18}; - int PolyhedronDescendingConnectivity[DescendingConnectivitySize] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,3,17,18}; - - myDescendingConnectivity.setPolyhedronConnectivity(MED_DESCENDING,PolyhedronDescendingConnectivity,PolyhedronIndex,DescendingConnectivitySize,NumberOfPolyhedron); - - cout << myNodalConnectivity; - cout << myDescendingConnectivity; - - return 0; -} diff --git a/src/MEDMEM/test_MEDMEM_PolyDriverMedMeshRead.cxx b/src/MEDMEM/test_MEDMEM_PolyDriverMedMeshRead.cxx deleted file mode 100644 index c1643c8ff..000000000 --- a/src/MEDMEM/test_MEDMEM_PolyDriverMedMeshRead.cxx +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -// This program test the implementation of the class MED_MESH_RDONLY_DRIVER for Polygons and Polyhedron. // - -#include "MEDMEM_define.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_MedMeshDriver.hxx" - -using namespace std; -using namespace MEDMEM; - - -int main (int argc, char ** argv) -{ - if (argc <3) // after 3, ignored ! - { - cerr << "Usage : " << argv[0] - << " filename meshname" << endl << endl; - exit(-1); - } - - string filename = argv[1]; - string meshname = argv[2]; - - MESH * myMesh = new MESH(); - myMesh->setName(meshname); - MED_MESH_RDONLY_DRIVER myMeshReadDriver(filename,myMesh); - myMeshReadDriver.setMeshName(meshname); - myMeshReadDriver.open(); - myMeshReadDriver.read(); - myMeshReadDriver.close(); - - cout << * myMesh << endl; - - delete myMesh; - return 0; -} diff --git a/src/MEDMEM/test_MEDMEM_PolyDriverMedMeshWrite.cxx b/src/MEDMEM/test_MEDMEM_PolyDriverMedMeshWrite.cxx deleted file mode 100644 index 263bb047f..000000000 --- a/src/MEDMEM/test_MEDMEM_PolyDriverMedMeshWrite.cxx +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -// This program test the implementation of the class MED_MESH_WRONLY_DRIVER for Polygons and Polyhedron. // - -#include "MEDMEM_define.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_MedMeshDriver.hxx" - -using namespace std; -using namespace MEDMEM; - - -int main (int argc, char ** argv) -{ - if (argc <3) // after 3, ignored ! - { - cerr << "Usage : " << argv[0] - << " filename meshname" << endl << endl; - exit(-1); - } - - string filename = argv[1]; - string meshname = argv[2]; - - // Lecture d'un fichier MED - MESH * myMesh = new MESH(); - myMesh->setName(meshname); - MED_MESH_RDONLY_DRIVER myMeshReadDriver(filename,myMesh); - myMeshReadDriver.setMeshName(meshname); - myMeshReadDriver.open(); - myMeshReadDriver.read(); - myMeshReadDriver.close(); - - // Ecriture dans un fichier MED - string filename2 = filename + "_copy"; - MED_MESH_WRONLY_DRIVER myMeshWriteDriver(filename2,myMesh); - myMeshWriteDriver.setMeshName(meshname); - myMeshWriteDriver.open(); - myMeshWriteDriver.write(); - myMeshWriteDriver.close(); - - - delete myMesh; - return 0; -} diff --git a/src/MEDMEM/test_MEDMEM_PolyhedronArray.cxx b/src/MEDMEM/test_MEDMEM_PolyhedronArray.cxx deleted file mode 100644 index a8ca2c104..000000000 --- a/src/MEDMEM/test_MEDMEM_PolyhedronArray.cxx +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -// This program test the implementation of the POLYHEDRONARRAY class. // - -#include "MEDMEM_PolyhedronArray.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -int main(void) -{ - POLYHEDRONARRAY myPArray(2,11,40); - med_int polyhedronindex[2] = {1,7}; - med_int facesindex[11] = {1,5,9,13,17,21,25,28,31,34,37}; - med_int nodes[40] = {1,2,6,5,2,3,7,6,4,3,7,8,1,4,8,5,1,2,3,4,5,6,7,8,5,6,9,6,7,9,7,8,9,8,5,9,5,6,7,8}; - - myPArray.setPolyhedronIndex(polyhedronindex); - myPArray.setFacesIndex(facesindex); - myPArray.setNodes(nodes); - - POLYHEDRONARRAY myPArray2(myPArray); - - const med_int* __polyhedronindex = myPArray2.getPolyhedronIndex(); - const med_int* __facesindex = myPArray2.getFacesIndex(); - const med_int* __nodes = myPArray2.getNodes(); - - cout << "__polyhedronindex =" << endl; - for (int i=0; i<2; i++) - cout << __polyhedronindex[i] << endl; - cout << "__facesindex =" << endl; - for (int i=0; i<11; i++) - cout << __facesindex[i] << endl; - cout << "__nodes =" << endl; - for (int i=0; i<40; i++) - cout << __nodes[i] << endl; - - return 0; -} diff --git a/src/MEDMEM/test_MEDMEM_SkyLineArray.cxx b/src/MEDMEM/test_MEDMEM_SkyLineArray.cxx deleted file mode 100644 index 667c5833e..000000000 --- a/src/MEDMEM/test_MEDMEM_SkyLineArray.cxx +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include "MEDMEM_SkyLineArray.hxx" - -using namespace std; -using namespace MEDMEM; - -int main (int argc, char ** argv) { - int NumberOfCell = 3 ; // 1 triangle,1 quadrangle,1 triangle - int Size = 10 ; // 10 nodes - - int * index = new int[NumberOfCell+1] ; - index[0]=1; - index[1]=4; - index[2]=8; - index[3]=11; - int * value = new int[Size] ; - value[0]=1; // first - value[1]=2; - value[2]=5; - value[3]=2; // second - value[4]=3; - value[5]=5; - value[6]=6; - value[7]=3; // thirst - value[8]=4; - value[9]=6; - // value[]=; // forth - - MEDSKYLINEARRAY * myArray = new MEDSKYLINEARRAY(NumberOfCell,Size,index,value) ; - - cout << "Show all 1 :" << endl ; - for (int i=1; i<NumberOfCell+1 ; i++) { - const int * cell = myArray->getI(i) ; - int numberof = myArray->getNumberOfI(i) ; - cout << " - " ; - for (int j=0;j<numberof;j++) - cout << cell[j] << " " ; - cout << endl ; - } - cout << "Show all 2 :" << endl ; - for (int i=1; i<NumberOfCell+1 ; i++) { - cout << " - " ; - int numberof = myArray->getNumberOfI(i) ; - for (int j=1;j<numberof+1;j++) - cout << myArray->getIJ(i,j) << " " ; - cout << endl ; - } - - MEDSKYLINEARRAY * myArray2 = new MEDSKYLINEARRAY(*myArray) ; - delete myArray ; - - cout << "Show all 3 :" << endl ; - const int * index2 = myArray2->getIndex() ; - for (int i=1; i<=NumberOfCell ; i++) { - cout << " - " ; - for (int j=index2[i-1];j<index2[i];j++) - cout << myArray2->getIndexValue(j) << " " ; - cout << endl ; - } - - delete myArray2 ; - delete[] index ; - delete[] value ; - - return 0 ; -} - diff --git a/src/MEDMEM/test_MEDMEM_nArray.cxx b/src/MEDMEM/test_MEDMEM_nArray.cxx deleted file mode 100644 index 06386acf7..000000000 --- a/src/MEDMEM/test_MEDMEM_nArray.cxx +++ /dev/null @@ -1,430 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// -#include <stdlib.h> -#include <iostream> -#include <stdio.h> - -#include "MEDMEM_ArrayInterface.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_IndexCheckingPolicy.hxx" -#include "MEDMEM_ArrayConvert.hxx" - -using namespace MEDMEM; - -int main(void) { - - const int mdim = 2; - const int nbelem1 = 20; - - // TEST n° 1 FullInterlace et NoGauss - std::cout << std::endl; - std::cout << "Test de MEDMEM_Array en FullInterlace et NoGauss : " << std::endl; - std::cout << std::endl; - - bool test1ok = true; - const double * myArray1Ptr = 0; - const double array1Ref[] = { 11 , 12 , 21 , 22 , 31 , 32 , 41 , 42 , 51 , 52 , - 61 , 62 , 71 , 72 , 81 , 82 , 91 , 92 , 101 , 102 , - 111 , 112 , 121 , 122 , 131 , 132 , 141 , 142 , - 151 , 152 , 161 , 162 , 171 , 172 , 181 , 182 , - 191 , 192 , 201 , 202 }; - - const double array2Ref[] = { 11 , 21 , 31 , 41 , 51 , 61 , 71 , 81 , 91 , 101 - , 111 , 121 , 131 , 141 , 151 , 161 , 171 , 181 - , 191 , 201 , - 12 , 22 , 32 , 42 , 52 , 62 , 72 , 82 , 92 , 102 - , 112 , 122 , 132 , 142 , 152 , 162 , 172 , 182 - , 192 , 202 }; - - MEDMEM_Array<double> myArray1(mdim,nbelem1); - - for (int i =1; i <= nbelem1; i++) - for (int j =1; j <= mdim; j++) - myArray1.setIJ(i,j,i*10+j); - - myArray1Ptr = myArray1.getPtr(); - for (int i =0; i < mdim*nbelem1; i++) - test1ok = test1ok && ( myArray1Ptr[i] == array1Ref[i] ); - - std::cout << "- Egualité de myArray1 et de myArray1Ref : " << test1ok << std::endl ; - - test1ok = true; - MEDMEM_Array<double> myArray1bis(myArray1, false); - myArray1Ptr = myArray1bis.getPtr(); - for (int i =0; i < mdim*nbelem1; i++) - test1ok = test1ok && ( myArray1Ptr[i] == array1Ref[i] ); - std::cout << "- Constructeur par recopie en FullInterlace et NoGauss : " << test1ok << std::endl; - - test1ok = true; - MEDMEM_Array<double> myArray1ter; - myArray1ter = myArray1; - myArray1Ptr = myArray1ter.getPtr(); - for (int i =0; i < mdim*nbelem1; i++) - test1ok = test1ok && ( myArray1Ptr[i] == array1Ref[i] ); - std::cout << "- Opérateur d'affectation en FullInterlace et NoGauss : " << test1ok << std::endl; - - - test1ok = true; - MEDMEM_Array<double> myArray1qua(mdim,nbelem1); - myArray1Ptr = myArray1qua.getPtr(); - - for (int i =1; i <= nbelem1; i++) - myArray1qua.setRow(i,&array1Ref[(i-1)*mdim]); - - for (int i =0; i < mdim*nbelem1; i++) - test1ok = test1ok && ( myArray1Ptr[i] == array1Ref[i] ); - std::cout << "- Méthode setRow en FullInterlace et NoGauss : " << test1ok << std::endl; - - std::cout << "- Test de levée d'exception pour getColumn : "; - try { - myArray1qua.getColumn(1); - } - catch (MEDMEM::MEDEXCEPTION &m) { - std::cout << m.what() << endl ; - } - - test1ok = true; - MEDMEM_Array<double,NoInterlaceNoGaussPolicy> * myArray1cin = ArrayConvert(myArray1); - myArray1Ptr = myArray1cin->getPtr(); - int elemno = 0; - for (int j=1; j <= mdim; j++) - for (int i=1; i <= nbelem1 ; i++ ) { - test1ok = test1ok - && ( myArray1cin->getIJ(i,j) == array2Ref[elemno] ) - && ( myArray1Ptr[elemno] == array2Ref[elemno] ); - elemno++; - } - std::cout << "- Convertion du mode FullInterlaceNoGaussPolicy au mode NoInterlaceNoGaussPolicy : " - << test1ok << std::endl; - - - - // TEST n°2 NoInterlace et NoGauss - std::cout << std::endl; - std::cout << "Test de MEDMEM_Array en NoInterlace et NoGauss : " << std::endl; - std::cout << std::endl; - - bool test2ok = true; - const double * myArray2Ptr = 0; - - MEDMEM_Array<double,NoInterlaceNoGaussPolicy> myArray2(mdim,nbelem1); - - for (int i =1; i <= nbelem1; i++) - for (int j =1; j <= mdim; j++) - myArray2.setIJ(i,j,i*10+j); - - myArray2Ptr = myArray2.getPtr(); - for (int i =0; i < mdim*nbelem1; i++) - test2ok = test2ok && ( myArray2Ptr[i] == array2Ref[i] ); - - std::cout << "- Egualité de myArray2 et de myArray2Ref : " << test2ok << std::endl ; - - test2ok = true; - MEDMEM_Array<double,NoInterlaceNoGaussPolicy> myArray2bis(myArray2, false); - myArray2Ptr = myArray2bis.getPtr(); - for (int i =0; i < mdim*nbelem1; i++) - test2ok = test2ok && ( myArray2Ptr[i] == array2Ref[i] ); - std::cout << "- Constructeur par recopie en NoInterlace et NoGauss : " << test2ok << std::endl; - - test2ok = true; - MEDMEM_Array<double,NoInterlaceNoGaussPolicy> myArray2ter; - myArray2ter = myArray2; - myArray2Ptr = myArray2ter.getPtr(); - for (int i =0; i < mdim*nbelem1; i++) - test2ok = test2ok && ( myArray2Ptr[i] == array2Ref[i] ); - std::cout << "- Opérateur d'affectation en NoInterlace et NoGauss : " << test2ok << std::endl; - - test2ok = true; - MEDMEM_Array<double,NoInterlaceNoGaussPolicy> myArray2qua(mdim,nbelem1); - myArray2Ptr = myArray2qua.getPtr(); - - for (int j =1; j <= mdim; j++) - myArray2qua.setColumn(j,&array2Ref[nbelem1*(j-1)]); - - for (int i =0; i < mdim*nbelem1; i++) - test2ok = test2ok && ( myArray2Ptr[i] == array2Ref[i] ); - std::cout << "- Méthode setColumn en NoInterlace et NoGauss : " << test2ok << std::endl; - - std::cout << "- Test de levée d'exception pour getRow : " ; - try { - myArray2qua.getRow(1); - } - catch (MEDMEM::MEDEXCEPTION &m) { - std::cout << m.what() << endl ; - } - - test2ok = true; - MEDMEM_Array<double,FullInterlaceNoGaussPolicy> * myArray2cin = ArrayConvert(myArray2); - myArray2Ptr = myArray2cin->getPtr(); - elemno = 0; - for (int i=1; i <= nbelem1 ; i++ ) - for (int j=1; j <= mdim; j++) { - test2ok = test2ok - && ( myArray2cin->getIJ(i,j) == array1Ref[elemno] ) - && ( myArray2Ptr[elemno] == array1Ref[elemno] ); - elemno++; - } - std::cout << "- Convertion du mode NoInterlaceNoGaussPolicy au mode FullInterlaceNoGaussPolicy : " - << test2ok << std::endl; - - - // TEST n°3 FullInterlace et Gauss - const int nbelem2 = 5; - const int nbtypegeo = 2; - const int nbelgeoc[nbtypegeo+1] = {1,3,6}; - const int nbgaussgeo[nbtypegeo+1] = {-1,2,3}; - - std::cout << std::endl; - std::cout << "Test de MEDMEM_Array en FullInterlace et Gauss : " << std::endl; - std::cout << std::endl; - - bool test3ok = true; - const double * myArray3Ptr = 0; - const double array3Ref[] = {1.11 , 1.12 , 1.21 , 1.22 , - 2.11 , 2.12 , 2.21 , 2.22 , - 13.11 , 13.12 , 13.21 , 13.22 , 13.31 , 13.32 , - 14.11 , 14.12 , 14.21 , 14.22 , 14.31 , 14.32 , - 15.11 , 15.12 , 15.21 , 15.22 , 15.31 , 15.32 }; - - const double array4Ref[] = { 1.11 , 1.21 , 2.11 , 2.21, - 13.11 , 13.21 , 13.31 , 14.11 , 14.21 , 14.31 , - 15.11 , 15.21 , 15.31 , - 1.12 , 1.22 , 2.12 , 2.22 , - 13.12 , 13.22 , 13.32 , 14.12 , 14.22 , 14.32 , - 15.12 , 15.22 , 15.32 }; - - MEDMEM_Array<double,FullInterlaceGaussPolicy> myArray3(mdim,nbelem2,nbtypegeo,nbelgeoc,nbgaussgeo); - - elemno = 1; - for (int ntyp=1; ntyp <= nbtypegeo; ntyp++ ) { - for (int i=0; i < (nbelgeoc[ntyp]-nbelgeoc[ntyp-1]) ; i++ ) { - for (int k=1; k <= nbgaussgeo[ntyp]; k++) - for (int j=1; j <= mdim; j++) { - myArray3.setIJK(elemno,j,k,elemno+(ntyp-1)*10+0.1*k+0.01*j); - } - elemno++; - } - } - myArray3Ptr = myArray3.getPtr(); - for (int i =0; i < myArray3.getArraySize(); i++) - test3ok = test3ok && ( myArray3Ptr[i] == array3Ref[i] ); - - std::cout << "- Egualité de myArray3 et de myArray3Ref : " << test3ok << std::endl ; - - test3ok = true; - MEDMEM_Array<double,FullInterlaceGaussPolicy> myArray3bis(myArray3, false); - myArray3Ptr = myArray3bis.getPtr(); - - elemno = 0; - for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) - for (int k=1; k <= myArray3bis.getNbGauss(i); k++) - for (int j=1; j <= mdim; j++) { - test3ok = test3ok - && ( myArray3bis.getIJK(i,j,k) == array3Ref[elemno] ) - && ( myArray3Ptr[elemno] == array3Ref[elemno] ); - elemno++; - } - std::cout << "- Constructeur par recopie en FullInterlace et Gauss : " << test3ok << std::endl; - - test3ok = true; - MEDMEM_Array<double,FullInterlaceGaussPolicy> myArray3ter; - myArray3ter = myArray3; //Opérateur d'affectation - myArray3Ptr = myArray3ter.getPtr(); - - elemno = 0; - for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) - for (int k=1; k <= myArray3ter.getNbGauss(i); k++) - for (int j=1; j <= mdim; j++) { - test3ok = test3ok - && ( myArray3ter.getIJK(i,j,k) == array3Ref[elemno] ) - && ( myArray3Ptr[elemno] == array3Ref[elemno] ); - elemno++; - } - - std::cout << "- Opérateur d'affectation en FullInterlace et Gauss : " << test3ok << std::endl; - - - test3ok = true; - MEDMEM_Array<double,FullInterlaceGaussPolicy> myArray3qua(mdim,nbelem2, - nbtypegeo,nbelgeoc,nbgaussgeo); - myArray3Ptr = myArray3qua.getPtr(); - - int cumul = 0; - for (int i =1; i <= nbelem2; i++){ - myArray3qua.setRow(i,&array3Ref[cumul]); - cumul+=myArray3qua.getNbGauss(i)*mdim; - }; - - for (int i =0; i < myArray3qua.getArraySize(); i++) - test3ok = test3ok && ( myArray3Ptr[i] == array3Ref[i] ); - std::cout << "- Méthode setRow en FullInterlace et Gauss : " << test3ok << std::endl; - - std::cout << "- Test de levée d'exception pour getColumn : " ; - try { - myArray3qua.getColumn(1); - } - catch (MEDMEM::MEDEXCEPTION &m) { - std::cout << m.what() << endl ; - } - - test3ok = true; - MEDMEM_Array<double,NoInterlaceGaussPolicy> * myArray3cin = ArrayConvert(myArray3); - myArray3Ptr = myArray3cin->getPtr(); - elemno = 0; - for (int j=1; j <= mdim; j++) - for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) - for (int k=1; k <= myArray3cin->getNbGauss(i); k++) { - test3ok = test3ok - && ( myArray3cin->getIJK(i,j,k) == array4Ref[elemno] ) - && ( myArray3Ptr[elemno] == array4Ref[elemno] ); - elemno++; - } - std::cout << "- Convertion du mode FullInterlaceGaussPolicy au mode NoInterlaceGaussPolicy : " - << test3ok << std::endl; - - - // TEST n°4 NoInterlace et Gauss - std::cout << std::endl; - std::cout << "Test de MEDMEM_Array en NoInterlace et Gauss : " << std::endl; - std::cout << std::endl; - - bool test4ok = true; - const double * myArray4Ptr = 0; - - MEDMEM_Array<double,NoInterlaceGaussPolicy> myArray4(mdim,nbelem2,nbtypegeo,nbelgeoc,nbgaussgeo); - - elemno = 1; - for (int ntyp=1; ntyp <= nbtypegeo; ntyp++ ) { - for (int i=0; i < (nbelgeoc[ntyp]-nbelgeoc[ntyp-1]) ; i++ ) { - for (int k=1; k <= nbgaussgeo[ntyp]; k++) - for (int j=1; j <= mdim; j++) { - myArray4.setIJK(elemno,j,k,elemno+(ntyp-1)*10+0.1*k+0.01*j); - } - elemno++; - } - } - myArray4Ptr = myArray4.getPtr(); - for (int i =0; i < myArray4.getArraySize(); i++) { - test4ok = test4ok && ( myArray4Ptr[i] == array4Ref[i] ); - } - std::cout << "- Egualité de myArray4 et de myArray4Ref : " << test4ok << std::endl ; - - test4ok = true; - MEDMEM_Array<double,NoInterlaceGaussPolicy> myArray4bis(myArray4, false); - myArray4Ptr = myArray4bis.getPtr(); - - elemno = 0; - for (int j=1; j <= mdim; j++) - for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) - for (int k=1; k <= myArray4bis.getNbGauss(i); k++) { - test4ok = test4ok - && ( myArray4bis.getIJK(i,j,k) == array4Ref[elemno] ) - && ( myArray4Ptr[elemno] == array4Ref[elemno] ); - elemno++; - } - std::cout << "- Constructeur par recopie en NoInterlace et Gauss : " << test4ok << std::endl; - - test4ok = true; - MEDMEM_Array<double,NoInterlaceGaussPolicy> myArray4ter; - myArray4ter = myArray4; // Opérateur d'affectation - myArray4Ptr = myArray4ter.getPtr(); - - elemno = 0; - for (int j=1; j <= mdim; j++) - for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) - for (int k=1; k <= myArray4ter.getNbGauss(i); k++) { - test4ok = test4ok - && ( myArray4ter.getIJK(i,j,k) == array4Ref[elemno] ) - && ( myArray4Ptr[elemno] == array4Ref[elemno] ); - elemno++; - } - - std::cout << "- Opérateur d'affectation en NoInterlace et Gauss : " << test4ok << std::endl; - - - test4ok = true; - MEDMEM_Array<double,NoInterlaceGaussPolicy> myArray4qua(mdim,nbelem2,nbtypegeo,nbelgeoc,nbgaussgeo); - myArray4Ptr = myArray4qua.getPtr(); - - for (int j =1; j <= mdim; j++) - myArray4qua.setColumn(j,&array4Ref[(myArray4qua.getArraySize()/mdim)*(j-1)]); - - for (int i =0; i < myArray4qua.getArraySize(); i++) - test4ok = test4ok && ( myArray4Ptr[i] == array4Ref[i] ); - std::cout << "- Méthode setColumn en NoInterlace et Gauss : " << test4ok << std::endl; - - std::cout << "- Test de levée d'exception pour getRow : " ; - try { - myArray4qua.getRow(1); - } - catch (MEDMEM::MEDEXCEPTION &m) { - std::cout << m.what() << endl ; - } - - - test4ok = true; - MEDMEM_Array<double,FullInterlaceGaussPolicy> * myArray4cin = ArrayConvert(myArray4); - //// MEDMEM_Array<double,FullInterlaceGaussPolicy> * myArray4cin; - ////ArrayConvert(myArray4,myArray4cin); - // typedef MEDMEM_Array<double,FullInterlaceGaussPolicy> MyArray; - // MyArray myArray4cin MyArray(myArray4); - // myArray4cin.convert(myArray4); - // MEDMEM_Array<double,FullInterlaceGaussPolicy> myArray4cin(myArray4); - myArray4Ptr = myArray4cin->getPtr(); - elemno = 0; - for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) - for (int k=1; k <= myArray4cin->getNbGauss(i); k++) - for (int j=1; j <= mdim; j++) { - test4ok = test4ok - && ( myArray4cin->getIJK(i,j,k) == array3Ref[elemno] ) - && ( myArray4cin->getIJK(i,j,k) == myArray3.getIJK(i,j,k) ) - && ( myArray4Ptr[elemno] == array3Ref[elemno] ); - elemno++; - } - - std::cout << "- Convertion du mode NoInterlaceGaussPolicy au mode FullInterlaceGaussPolicy : " - << test4ok << std::endl; - - - //TEST DES METHODES D'INTERROGATION en NoInterlace et Gauss : - // MEDMEM_ArrayInterface<double,NoInterlace,Gauss>::Array & myArray4bis = myField4bis.getArray(); - - std::cout << std::endl; - std::cout << "Test de la méthode getDim : " << myArray4bis.getDim() << std::endl; - std::cout << "Test de la méthode getNbelem : " << myArray4bis.getNbElem() << std::endl; - std::cout << "Test de la méthode getArraySize : " << myArray4bis.getArraySize() << std::endl; - std::cout << "Test de la méthode getInterlacingType : " << myArray4bis.getInterlacingType() << std::endl; - - - // Test de levée d'exception si MED_ARRAY compilée avec une politique de checking - std::cout << std::endl; - std::cout << "Test de levée d'exception pour indice incohérent " << std::endl; - try { - myArray4.getIJ(0,2); //L'exception génère des blocks perdus (A voir) - } - catch (MEDMEM::MEDEXCEPTION &m) { - std::cout << m.what() << endl ; - } - - - - return 0; - -}; - diff --git a/src/MEDMEM/test_MEDMEM_poly3D.cxx b/src/MEDMEM/test_MEDMEM_poly3D.cxx deleted file mode 100755 index 4d79c118e..000000000 --- a/src/MEDMEM/test_MEDMEM_poly3D.cxx +++ /dev/null @@ -1,310 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -// This program test the implementation of the class MED_MESH_RDONLY_DRIVER for Polygons and Polyhedron. // - -#include "MEDMEM_define.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_ModulusArray.hxx" -#include "MEDMEM_MedMeshDriver.hxx" -#include <vector> - -#define MESHNAME "poly3D" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -#define DIM_OF_FIELD 3 - - -class SupportTester { -private: - const int *_tabOfNodes; - vector<int> _eltsActiveYet; - vector<int> _lgthOfEltsActiveYet; -public: - SupportTester(const int *tabOfNodes, int nbOfElts, int nbOfNodesPerElt); - SupportTester(const int *tabOfNodes, int nbOfElts, const int *nbOfNodesPerElt); - bool isIncludedAndNotAlreadyConsumed(const int *tabOfNodesOfTheElementToTest); - bool areAllEltsConsumed(); -private: - static bool areEquivalent(const int *nodes1, const int *nodes2, int nbOfNodes); -}; - -SupportTester::SupportTester(const int *tabOfNodes, int nbOfElts, int nbOfNodesPerElt):_tabOfNodes(tabOfNodes) -{ - for(int i=0;i<nbOfElts;i++) - { - _eltsActiveYet.push_back(i*nbOfNodesPerElt); - _lgthOfEltsActiveYet.push_back(nbOfNodesPerElt); - } -} - -SupportTester::SupportTester(const int *tabOfNodes, int nbOfElts, const int *nbOfNodesPerElt):_tabOfNodes(tabOfNodes) -{ - int offset=0; - for(int i=0;i<nbOfElts;i++) - { - _eltsActiveYet.push_back(offset); - _lgthOfEltsActiveYet.push_back(nbOfNodesPerElt[i]); - } -} - -bool SupportTester::isIncludedAndNotAlreadyConsumed(const int *tabOfNodesOfTheElementToTest) -{ - vector<int>::iterator iter2=_lgthOfEltsActiveYet.begin(); - for(vector<int>::iterator iter=_eltsActiveYet.begin();iter!=_eltsActiveYet.end();iter++) - if(areEquivalent(_tabOfNodes+(*iter),tabOfNodesOfTheElementToTest,*iter2)) - { - _eltsActiveYet.erase(iter); - _lgthOfEltsActiveYet.erase(iter2); - return true; - } - else - { - iter2++; - } - return false; -} - -bool SupportTester::areAllEltsConsumed() -{ - return _eltsActiveYet.size()==0; -} - -bool SupportTester::areEquivalent(const int *nodes1, const int *nodes2, int nbOfNodes) -{ - MEDMODULUSARRAY arr1(nbOfNodes,nodes1); - MEDMODULUSARRAY arr2(nbOfNodes,nodes2); - return arr1.compare(arr2)!=0; -} - -int main (int argc, char ** argv) -{ - if (argc<2) // after 2, ignored ! - { - cerr << "Usage : " << argv[0] << " poly3D.med typically in ../../share/salome/resources/med" << endl << endl; - exit(-1); - } - int nbOfPtsForTest=0; - int i; - string filename = argv[1]; - MESH * myMesh = new MESH; - myMesh->setName(MESHNAME); - MED_MESH_RDONLY_DRIVER myMeshReadDriver(filename,myMesh); - myMeshReadDriver.setMeshName(MESHNAME); - myMeshReadDriver.open(); - myMeshReadDriver.read(); - myMeshReadDriver.close(); - //Test 1 : test if connectivity of poly3D mesh is OK - if(myMesh->getMeshDimension()==3 && myMesh->getSpaceDimension()==3) - nbOfPtsForTest++; - if(myMesh->getNumberOfElementsWithPoly(MED_EN::MED_CELL,MED_EN::MED_TETRA4)==1 && myMesh->getNumberOfElementsWithPoly(MED_EN::MED_CELL,MED_EN::MED_POLYHEDRA)==2) - nbOfPtsForTest++; - const int REFnodalConnForTetra[4]={17, 9, 18, 19}; - const int *connForTetraToTest=myMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,MED_TETRA4); - const int *connIndForTetraToTest=myMesh->getConnectivityIndex(MED_NODAL,MED_CELL); - for(i=connIndForTetraToTest[0]-1;i<connIndForTetraToTest[1]-1;i++) - if(connForTetraToTest[i]==REFnodalConnForTetra[i]) - nbOfPtsForTest++; - //6 - const int *globIndex=myMesh->getPolyhedronIndex(MED_NODAL); - const int *nodalConnOfFaces=myMesh->getPolyhedronConnectivity(MED_NODAL); - const int *facesIndex=myMesh->getPolyhedronFacesIndex(); - if(globIndex[1]-globIndex[0]==9 && globIndex[2]-globIndex[1]==10)// resp 9 faces and 10 faces are in polyh 1 and 2. - nbOfPtsForTest++; - //7 - const int REFfacesIndex[20]={1, 7, 11, 15, 19, 23, 27, 31, 34, 39, 44, 48, 52, 55, 58, 61, 64, 68, 72, 75}; - const int REFnodalConnOfFaces[74]={1, 2, 3, 4, 5, 6, // Polyhedron 1 - 1, 7, 8, 2, - 2, 8, 9, 3, - 4, 3, 9, 10, - 5, 4, 10, 11, - 6, 5, 11, 12, - 1, 6, 12, 7, - 7, 12, 8, 10, - 9, 8, 12, 11, - - 13, 14, 15, 3, 2, // Polyhedron 2 - 13, 2, 8, 16, - 14, 13, 16, 17, - 15, 14, 17, 15, - 17, 18, 15, - 18, 9, 3, - 15, 9, 2, - 3, 9, 8, - 8, 9, 17, 16, - 9, 18, 17 }; - for(i=0;i<20;i++) - if(REFfacesIndex[i]==facesIndex[i]) - nbOfPtsForTest++; - for(i=0;i<74;i++) - if(REFnodalConnOfFaces[i]==nodalConnOfFaces[i]) - nbOfPtsForTest++; - if(nbOfPtsForTest!=101) - { - cout << "TEST1 K0 ! : Invalid Globaldata in memory..." << endl; - return 1; - } - // TEST 2 : FAMILY - nbOfPtsForTest=0; - vector<FAMILY*> families=myMesh->getFamilies(MED_FACE); - if(families.size()==3) - nbOfPtsForTest++; - vector<FAMILY *>::iterator iter=families.begin(); - FAMILY *fam1=*(iter++); - FAMILY *fam2=*(iter++); - FAMILY *fam3=*(iter); - const int *nbs; - // family 1 - if(fam1->getNumberOfTypes()==1 && fam1->getTypes()[0]==MED_POLYGON && fam1->getNumberOfElements(MED_ALL_ELEMENTS)==3) - nbOfPtsForTest++; - nbs=fam1->getNumber(MED_ALL_ELEMENTS); - const int REFTabForPolyg[16]={1, 2, 3, 4, 5, 6, 10, 9, 8, 12, 11, 13, 14, 15, 3, 2}; - const int REFTabForPolygLgth[3]={6,5,5}; - SupportTester test1(REFTabForPolyg,3,REFTabForPolygLgth); - for(i=0;i<3;i++) - { - int lgth; - const int *conn=((CONNECTIVITY *)myMesh->getConnectivityptr())->getConnectivityOfAnElementWithPoly(MED_NODAL,MED_FACE,nbs[i],lgth); - if(test1.isIncludedAndNotAlreadyConsumed(conn)) - nbOfPtsForTest++; - } - if(test1.areAllEltsConsumed()) - nbOfPtsForTest++; - // family 2 - if(fam2->getNumberOfElements(MED_ALL_ELEMENTS)==8) - nbOfPtsForTest++; - nbs=fam2->getNumber(MED_ALL_ELEMENTS); - const int REFTabForQuad[32]={1, 7, 8, 2, 2, 8, 9, 3, 4, 3, 9, 10, 5, 4, 10, 11, 6, 5, 11, 12, 1, 6, 12, 7, 14, 13, 16, 17, 8, 9, 17, 16}; - SupportTester test2(REFTabForQuad,8,4); - for(i=0;i<8;i++) - { - int lgth; - const int *conn=((CONNECTIVITY *)myMesh->getConnectivityptr())->getConnectivityOfAnElementWithPoly(MED_NODAL,MED_FACE,nbs[i],lgth); - if(test2.isIncludedAndNotAlreadyConsumed(conn)) - nbOfPtsForTest++; - } - if(test2.areAllEltsConsumed()) - nbOfPtsForTest++; - // family 3 - if(fam3->getNumberOfElements(MED_ALL_ELEMENTS)==6) - nbOfPtsForTest++; - nbs=fam3->getNumber(MED_ALL_ELEMENTS); - const int REFTabForTria[18]={7, 12, 8, 15, 14, 17, 15, 17, 18, 15, 18, 9, 3, 15, 9, 18, 17, 9}; - SupportTester test3(REFTabForTria,6,3); - for(i=0;i<6;i++) - { - int lgth; - const int *conn=((CONNECTIVITY *)myMesh->getConnectivityptr())->getConnectivityOfAnElementWithPoly(MED_NODAL,MED_FACE,nbs[i],lgth); - if(test3.isIncludedAndNotAlreadyConsumed(conn)) - nbOfPtsForTest++; - } - if(test3.areAllEltsConsumed()) - nbOfPtsForTest++; - if(nbOfPtsForTest!=21) - { - cout << "TEST2 K0 ! : Invalid data in memory for families !!!" << endl; - return 1; - } - // TEST 3 : volumes, aeras, barycenter - nbOfPtsForTest=0; - SUPPORT *supOnCell=new SUPPORT(myMesh); - FIELD<double>* vol1=myMesh->getVolume(supOnCell); - int lgth=vol1->getValueLength(); - const double *vals=vol1->getValue(); - if(lgth==3) - nbOfPtsForTest++; - const double REFVolOfPolyHedron[3]={2.333333333333333,11.66666666666666,13.83224131414673}; - for(i=0;i<3;i++) - if(fabs(REFVolOfPolyHedron[i]-vals[i])<1e-12) - nbOfPtsForTest++; - delete vol1; - FIELD<double>* bary=myMesh->getBarycenter(supOnCell); - lgth=bary->getValueLength(); - vals=bary->getValue(); - if(lgth==9) - nbOfPtsForTest++; - const double REFBaryOfPolyHedron[9]= {5.5, 1, -1, 2, 1.5, 1.0833333333333333, 5.1, 1.6, 0.9}; - for(i=0;i<9;i++) - if(fabs(REFBaryOfPolyHedron[i]-vals[i])<1e-12) - nbOfPtsForTest++; - delete bary; - delete supOnCell; - //area - vol1=myMesh->getArea(fam1); - lgth=vol1->getValueLength(); - vals=vol1->getValue(); - if(lgth==3) - nbOfPtsForTest++; - const double REFAreaForPolyg[3]={6,5,6.5}; - for(i=0;i<3;i++) - if(fabs(REFAreaForPolyg[i]-vals[i])<1e-12) - nbOfPtsForTest++; - - vol1=myMesh->getArea(fam2); - lgth=vol1->getValueLength(); - vals=vol1->getValue(); - if(lgth==8) - nbOfPtsForTest++; - const double REFAreaForQuad[8]={2.1213203435596424, 2.8284271247461903, 4.4721359549995796, 4.4721359549995796, - 2.8284271247461903, 2.1213203435596428, 3.6798724963767362, 4}; - for(i=0;i<8;i++) - if(fabs(REFAreaForQuad[i]-vals[i])<1e-12) - nbOfPtsForTest++; - delete vol1; - - vol1=myMesh->getArea(fam3); - lgth=vol1->getValueLength(); - vals=vol1->getValue(); - if(lgth==6) - nbOfPtsForTest++; - const double REFAreaForTri[6]={2.9580398915498081, 1.4142135623730951, 2.2360679774997898, - 3.3541019662496847, 3.3541019662496847, 2.2360679774997898}; - for(i=0;i<6;i++) - if(fabs(REFAreaForTri[i]-vals[i])<1e-12) - nbOfPtsForTest++; - delete vol1; - if(nbOfPtsForTest!=34) - { - cout << "TEST3 K0 ! : Error in caluclation of basic properties !!!" << endl; - return 1; - } - // TEST 4 -- CHECK FOR Reverse descending using getBoundaryElements. - nbOfPtsForTest=0; - SUPPORT *bound=myMesh->getBoundaryElements(MED_NODE); - if(bound->getNumberOfElements(MED_ALL_ELEMENTS)==19) - nbOfPtsForTest++; - if(bound->isOnAllElements()) - nbOfPtsForTest++; - if(nbOfPtsForTest!=2) - { - cout << "TEST4 K0 ! : Error in getBoundaryElements probably due to Reverse descending !!!" << endl; - return 1; - } - delete bound; - /////////// - cout << "ALL TESTS OK !!!" << endl; - delete myMesh; - return 0; -} diff --git a/src/MEDMEM/test_affect_medarray.cxx b/src/MEDMEM/test_affect_medarray.cxx deleted file mode 100644 index e0dcd5177..000000000 --- a/src/MEDMEM/test_affect_medarray.cxx +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -/* Programme de test du constructeur de copies de la classe MEDARRAY de MEDMEM - jroy - 16/12/2002 */ - -#include <string> - -#include <math.h> -#include <stdlib.h> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_Group.hxx" - -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_MedFieldDriver.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_define.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -void affiche_medarray(MEDARRAY<double> & myMedArray) -{ - int numberof ; - MESSAGE("Show all 1 :"); - numberof = myMedArray.getLeadingValue() ; - for (int i=1; i<=myMedArray.getLengthValue() ; i++) { - const double * node = myMedArray.getRow(i) ; - cout << " - " ; - for (int j=0;j<numberof;j++) - cout << node[j] << " " ; - cout << endl ; - } - MESSAGE("Show all 2 :"); - numberof = myMedArray.getLengthValue() ; - for (int i=1; i<=myMedArray.getLeadingValue() ; i++) { - const double * node = myMedArray.getColumn(i) ; - cout << " - " ; - for (int j=0;j<numberof;j++) - cout << node[j] << " " ; - cout << endl ; - } - MESSAGE("Show all 3 :"); - numberof = myMedArray.getLeadingValue() ; - for (int i=1; i<=myMedArray.getLengthValue() ; i++) { - cout << " - " ; - for (int j=1;j<numberof+1;j++) - cout << myMedArray.getIJ(i,j) << " " ; - cout << endl ; - } - - MESSAGE("Show all 0 :"); - numberof = myMedArray.getLeadingValue() ; - int length = myMedArray.getLengthValue() ; - const double * NoInterlaceArray = myMedArray.get(MED_NO_INTERLACE) ; - for (int i=0; i<length ; i++) { - cout << " - " ; - for (int j=0;j<numberof;j++) - cout << NoInterlaceArray[j*length+i] << " " ; - cout << endl ; - } - - - /* - cout << "Nombre de lignes : " << myMedArray.getLengthValue() << endl; - cout << "Nombre de colonnes : " << myMedArray.getLeadingValue() << endl; - cout << "Mode d'écriture en mémoire : " << myMedArray.getMode() << endl; - cout << "Valeurs (_valuesDefault) :" << endl; - - for (med_int i=1; i<=myMedArray.getLengthValue(); i++) { - for (med_int j=1; j<=myMedArray.getLeadingValue(); j++) - cout << i << " " << j << " " << myMedArray.getIJ(i,j) << " " << endl; - } - */ -} - - -int main (int argc, char ** argv) { - /* - if ((argc !=3) && (argc != 4)) { - cerr << "Usage : " << argv[0] - << " filename meshname fieldname" << endl << endl; - exit(-1); - } - */ - const med_int nb_noeuds = 8; - const med_int dimension = 3; - const medModeSwitch mode = MED_NO_INTERLACE; - - - MEDARRAY<double> * myMedArray = new MEDARRAY<double>(dimension,nb_noeuds,mode); - for (med_int i=1; i<=myMedArray->getLengthValue(); i++) { - for (med_int j=1; j<=myMedArray->getLeadingValue(); j++) - myMedArray->setIJ(i,j,(double) random()); - }; - - affiche_medarray(* myMedArray); - MEDARRAY<double> * myMedArray2 = new MEDARRAY<double>(); - * myMedArray2 = * myMedArray; - // delete myMedArray; // si on recopie les tableaux - affiche_medarray(* myMedArray2); - delete myMedArray; // si on ne recopie pas les tableaux - delete myMedArray2; - - return 0; -} diff --git a/src/MEDMEM/test_copie_connectivity.cxx b/src/MEDMEM/test_copie_connectivity.cxx deleted file mode 100644 index c25111890..000000000 --- a/src/MEDMEM/test_copie_connectivity.cxx +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -/* Programme de test du constructeur de copies de la classe CONNECTIVITY de MEDMEM - jroy - 19/12/2002 */ - -#include <string> - -#include <math.h> -#include <stdlib.h> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_Group.hxx" - -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_MedFieldDriver.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_define.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -void affiche_connectivity(const CONNECTIVITY * myConnectivity, MESH * myMesh) -{ - int SpaceDimension = myMesh->getSpaceDimension() ; - int MeshDimension = myMesh->getMeshDimension() ; - int NumberOfNodes = myMesh->getNumberOfNodes() ; - - int NumberOfTypes = myMesh->getNumberOfTypes(MED_CELL) ; - const medGeometryElement * Types = myMesh->getTypes(MED_CELL) ; - - cout << "Show Connectivity (Nodal) :" << endl ; - for (int i=0; i<NumberOfTypes; i++) { - cout << "For type " << Types[i] << " : " << endl ; - int NumberOfElements = myMesh->getNumberOfElements(MED_CELL,Types[i]); - const int * connectivity = myMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,Types[i]); - int NomberOfNodesPerCell = Types[i]%100 ; - for (int j=0;j<NumberOfElements;j++){ - cout << "Element "<< j+1 <<" : " ; - for (int k=0;k<NomberOfNodesPerCell;k++) - cout << connectivity[j*NomberOfNodesPerCell+k]<<" "; - cout << endl ; - } - } - - cout << "Show Reverse Nodal Connectivity :" << endl ; - const int * ReverseNodalConnectivity = myMesh->getReverseConnectivity(MED_NODAL) ; - const int * ReverseNodalConnectivityIndex = myMesh->getReverseConnectivityIndex(MED_NODAL) ; - for (int i=0; i<NumberOfNodes; i++) { - cout << "Node "<<i+1<<" : " ; - for (int j=ReverseNodalConnectivityIndex[i];j<ReverseNodalConnectivityIndex[i+1];j++) - cout << ReverseNodalConnectivity[j-1] << " " ; - cout << endl ; - } - - cout << "Show Connectivity (Descending) :" << endl ; - int NumberOfElements ; - const int * connectivity ; - const int * connectivity_index ; - myMesh->calculateConnectivity(MED_FULL_INTERLACE,MED_DESCENDING,MED_CELL); - try { - NumberOfElements = myMesh->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS); - connectivity = myMesh->getConnectivity(MED_FULL_INTERLACE,MED_DESCENDING,MED_CELL,MED_ALL_ELEMENTS); - connectivity_index = myMesh->getConnectivityIndex(MED_DESCENDING,MED_CELL); - } - catch (MEDEXCEPTION m) { - cout << m.what() << endl ; - exit (-1) ; - } - for (int j=0;j<NumberOfElements;j++) { - cout << "Element "<<j+1<<" : " ; - for (int k=connectivity_index[j];k<connectivity_index[j+1];k++) - cout << connectivity[k-1]<<" "; - cout << endl ; - } - - cout << "Show Reverse Descending Connectivity :" << endl ; - const int * ReverseDescendingConnectivity = myMesh->getReverseConnectivity(MED_DESCENDING) ; - const int * ReverseDescendingConnectivityIndex = myMesh->getReverseConnectivityIndex(MED_DESCENDING) ; - - int NumberOfConstituents = 0; - string constituent ; - medEntityMesh constituentEntity ; - - if (MeshDimension==3) { - constituent = "Face" ; - constituentEntity = MED_FACE ; - } - - if (MeshDimension==2) { - constituent = "Edge" ; - constituentEntity = MED_EDGE ; - } - - if (MeshDimension==1) { - MESSAGE("ERROR : MeshDimension = 1 !"); - MESSAGE("We could not see Reverse Descending Connectivity.") ; - } else { - NumberOfConstituents = myMesh->getNumberOfElements (constituentEntity,MED_ALL_ELEMENTS); - for (int i=0; i<NumberOfConstituents; i++) { - cout << constituent <<i+1<<" : " ; - for (int j=ReverseDescendingConnectivityIndex[i];j<ReverseDescendingConnectivityIndex[i+1];j++) - cout << ReverseDescendingConnectivity[j-1] << " " ; - cout << endl ; - } - } - cout << "Show "<<constituent<<" Connectivity (Nodal) :" << endl ; - const int * face_connectivity = myMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,constituentEntity,MED_ALL_ELEMENTS); - const int * face_connectivity_index = myMesh->getConnectivityIndex(MED_NODAL,constituentEntity); - for (int i=0; i<NumberOfConstituents; i++) { - cout << constituent <<i+1<<" : " ; - for (int j=face_connectivity_index[i];j<face_connectivity_index[i+1];j++) - cout << face_connectivity[j-1]<<" "; - cout << endl ; - } -} - - -int main (int argc, char ** argv) { - - if (argc <3) { // after 3, ignored ! - cerr << "Usage : " << argv[0] - << " filename meshname" << endl << endl; - exit(-1); - } - - string filename = argv[1] ; - string meshname = argv[2] ; - - //Construction d'un maillage - MESH * myMesh= new MESH() ; - myMesh->setName(meshname); - MED_MESH_RDONLY_DRIVER myMeshDriver(filename,myMesh) ; - myMeshDriver.setMeshName(meshname); - myMeshDriver.open() ; - myMeshDriver.read() ; //A partir d'ici la connectivité est construite - myMeshDriver.close() ; - - const CONNECTIVITY * myConnectivity = myMesh->getConnectivityptr(); - affiche_connectivity(myConnectivity, myMesh); - - CONNECTIVITY * myConnectivity2 = new CONNECTIVITY(* myConnectivity); - affiche_connectivity(myConnectivity2, myMesh); - - CONNECTIVITY * myConnectivity3 = new CONNECTIVITY(* myConnectivity2); - delete myConnectivity2; - affiche_connectivity(myConnectivity3, myMesh); - delete myConnectivity3; - - delete myMesh ; - - return 0; -} diff --git a/src/MEDMEM/test_copie_coordinate.cxx b/src/MEDMEM/test_copie_coordinate.cxx deleted file mode 100644 index 54599409c..000000000 --- a/src/MEDMEM/test_copie_coordinate.cxx +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -/* Programme de test du constructeur de copies de la classe COORDINATE de MEDMEM - jroy - 17/12/2002 */ - -#include <string> - -#include <math.h> -#include <stdlib.h> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_Group.hxx" - -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_MedFieldDriver.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_define.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -void affiche_tableau(const double * myArray, int nb_lignes, int nb_colonnes) -{ - cout << "Nombre de lignes : " << nb_lignes << endl; - cout << "Nombre de colonnes : " << nb_colonnes << endl; - cout << "Valeurs :" << endl; - - for (int i=0; i<nb_lignes; i++) { - for (int j=0; j<nb_colonnes; j++) - cout << myArray[j*nb_lignes+i] << " "; - cout << endl;} -} - -void affiche_coordinate(COORDINATE & myCoordinate, int _numberofNodes, int _spaceDimension) -{ - cout << "- Système de coordonnées : " << myCoordinate.getCoordinatesSystem() << endl; - cout << "- Tableau des coordonnées : " << endl; - // affiche_medarray(* myCoordinate.getCoordinatePtr()); - affiche_tableau(myCoordinate.getCoordinates(MED_NO_INTERLACE),_numberofNodes,_spaceDimension); - //on récupère les dimensions - // int _spaceDimension = (int) myCoordinate.getCoordinatePtr()->getLeadingValue(); - //int _numberofNodes = (int) myCoordinate.getCoordinatePtr()->getLengthValue(); - cout << "- Nom des coordonnées : " << endl; - for (int i=1; i<=_spaceDimension; i++) - cout << i << " " << myCoordinate.getCoordinateName(i) << endl; - // cout<<myCoordinate.getCoordinatesNames()<<endl; - cout << "- Unité des coordonnées : " << endl; - for (int i=1; i<=_spaceDimension; i++) - cout << i << " " << myCoordinate.getCoordinateUnit(i) << endl; - cout << "- Indices des noeuds : " << endl; - // cout<<myCoordinate.getNodesNumbers()<<endl; - for (int i=0; i<_numberofNodes; i++) - cout << i << " " << myCoordinate.getNodesNumbers()[i] << endl; -} - - -int main (int argc, char ** argv) { - /* - if ((argc !=3) && (argc != 4)) { - cerr << "Usage : " << argv[0] - << " filename meshname fieldname" << endl << endl; - exit(-1); - } - */ - const med_int numberofNodes = 5; - const med_int spaceDimension = 3; - const medModeSwitch mode = MED_FULL_INTERLACE; - - //construction tableau MEDARRAY des coordonnées - MEDARRAY<double> * myMedArray = new MEDARRAY<double>(spaceDimension,numberofNodes,mode); - for (med_int i=1; i<=myMedArray->getLengthValue(); i++) { - for (med_int j=1; j<=myMedArray->getLeadingValue(); j++) - myMedArray->setIJ(i,j,(double) random()); - }; - - //construction noms des coordonnées - string * myCoordinatesNames = new string[spaceDimension]; - if (spaceDimension >= 1) myCoordinatesNames[0] = "x"; - if (spaceDimension >= 2) myCoordinatesNames[1] = "y"; - if (spaceDimension >= 3) myCoordinatesNames[2] = "z"; - - //construction unités des coordonnées - string * myCoordinatesUnits = new string[spaceDimension]; - if (spaceDimension >= 1) myCoordinatesUnits[0] = "m"; - if (spaceDimension >= 2) myCoordinatesUnits[1] = "m"; - if (spaceDimension >= 3) myCoordinatesUnits[2] = "m"; - - //construction des indices des noeuds - int * myNodeNumber = new int[numberofNodes]; - for (int i=0; i<numberofNodes; i++) - myNodeNumber[i]=numberofNodes-i-1; - - //construction de l'objet COORDINATE - COORDINATE * myCoordinate = new COORDINATE(); - myCoordinate->setCoordinates(myMedArray); - myCoordinate->setCoordinatesNames(myCoordinatesNames); - myCoordinate->setCoordinatesUnits(myCoordinatesUnits); - myCoordinate->setNodesNumbers(myNodeNumber); - - // myCoordinate->setCoordinatesNames((string *)NULL); - // myCoordinate->setNodesNumbers((int *) NULL); - - delete myMedArray ; - delete[] myCoordinatesNames ; - delete[] myCoordinatesUnits ; - delete[] myNodeNumber ; - - affiche_coordinate(* myCoordinate,numberofNodes,spaceDimension); - COORDINATE * myCoordinate2 = new COORDINATE(* myCoordinate); - delete myCoordinate ; - - affiche_coordinate(* myCoordinate2,numberofNodes,spaceDimension); - delete myCoordinate2 ; - - return 0; -} diff --git a/src/MEDMEM/test_copie_family.cxx b/src/MEDMEM/test_copie_family.cxx deleted file mode 100644 index 1e8a14403..000000000 --- a/src/MEDMEM/test_copie_family.cxx +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include<string> - -#include <math.h> -#include <stdlib.h> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_Group.hxx" - -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_MedFieldDriver.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_define.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -void affiche_support(const SUPPORT * mySupport) -{ - cout << " - Name : "<<mySupport->getName().c_str()<<endl ; - cout << " - Description : "<<mySupport->getDescription().c_str()<<endl ; - cout << " - Entity : "<<mySupport->getEntity()<<endl ; - cout << " - Entities list : "<<endl ; - if (!(mySupport->isOnAllElements())) { - int NumberOfTypes = mySupport->getNumberOfTypes() ; - cout<<" - NumberOfTypes : "<<NumberOfTypes<<endl; - const medGeometryElement * Types = mySupport->getTypes() ; - for (int j=0;j<NumberOfTypes;j++) { - cout<<" * Type "<<Types[j]<<" : "; - int NumberOfElements = mySupport->getNumberOfElements(Types[j]) ; - const int * Number = mySupport->getNumber(Types[j]) ; - for (int k=0; k<NumberOfElements;k++) - cout << Number[k] << " "; - cout << endl ; - } - } else - cout << " Is on all entities !"<< endl; -} - - -void affiche_famille(const FAMILY * myFamily) -{ - affiche_support(myFamily); - cout << " - Identifier : "<<myFamily->getIdentifier()<<endl ; - int NumberOfAttributes = myFamily->getNumberOfAttributes() ; - cout << " - Attributes ("<<NumberOfAttributes<<") :"<<endl; - for (int j=1;j<NumberOfAttributes+1;j++) - cout << " * "<<myFamily->getAttributeIdentifier(j)<<" : "<<myFamily->getAttributeValue(j)<<", "<<myFamily->getAttributeDescription(j).c_str()<<endl ; - int NumberOfGroups = myFamily->getNumberOfGroups() ; - cout << " - Groups ("<<NumberOfGroups<<") :"<<endl; - for (int j=1;j<NumberOfGroups+1;j++) - cout << " * "<<myFamily->getGroupName(j).c_str()<<endl ; -} - -void affiche_groupe(MESH *myMesh,medEntityMesh Entity) -{ - int NumberOfGroups = myMesh->getNumberOfGroups(Entity) ; - cout << "NumberOfGroups : "<<NumberOfGroups<<endl; - for (int i=1; i<NumberOfGroups+1;i++) { - const GROUP* myGroup = myMesh->getGroup(Entity,i); - affiche_support(myGroup); - int NumberOfFamillies = myGroup->getNumberOfFamilies() ; - cout << " - Families ("<<NumberOfFamillies<<") :"<<endl; - for (int j=1;j<NumberOfFamillies+1;j++) - cout << " * "<<myGroup->getFamily(j)->getName().c_str()<<endl ; - } -} - -int main (int argc, char ** argv) { - int read; - - if (argc <3) { // after 3, ignored ! - cerr << "Usage : " << argv[0] - << " filename meshname" << endl << endl; - exit(-1); - } - - string filename = argv[1] ; - string meshname = argv[2] ; - - MESH * myMesh= new MESH() ; - myMesh->setName(meshname); - MED_MESH_RDONLY_DRIVER myMeshDriver(filename,myMesh) ; - myMeshDriver.setMeshName(meshname); - myMeshDriver.open() ; - myMeshDriver.read() ; - myMeshDriver.close() ; - - const FAMILY * myFamily = myMesh->getFamily(MED_NODE,1); - //On renseigne les attributs spécifiques à FAMILY (p/r à SUPPORT) et non renseignés lors de la lecture du maillage -// int NumberOfAttribute = 3; -// int *AttributeIdentifier = new int[NumberOfAttribute]; -// int *AttributeValue = new int[NumberOfAttribute]; -// string *AttributeDescription = new string[NumberOfAttribute]; -// char *tmp; -// for (int i=0;i<NumberOfAttribute;i++) -// { -// AttributeIdentifier[i]=i+1; -// AttributeValue[i]=(i+1)*10; -// sprintf(tmp,"Attribut N° %d",i+1); -// AttributeDescription[i]=tmp; -// } - -// myFamily->setNumberOfAttributes(NumberOfAttribute); -// myFamily->setAttributesIdentifiers (AttributeIdentifier); -// myFamily->setAttributesValues (AttributeValue); -// myFamily->setAttributesDescriptions (AttributeDescription); - - cout << "Show Family :"<<endl ; - affiche_famille(myFamily); - FAMILY * myFamily2 = new FAMILY(* myFamily); - //delete myFamily; - cout << "Show Family2 :"<<endl ; - affiche_famille(myFamily2); - FAMILY * myFamily3 = new FAMILY(* myFamily2); - delete myFamily2; - cout << "Show Family3 :"<<endl ; - affiche_famille(myFamily3); - delete myFamily3; - - cout << "That's all"<<endl ; - - /* - cout << "Show Group :"<<endl ; - affiche_groupe(myMesh,MED_NODE); - affiche_groupe(myMesh,MED_CELL); - affiche_groupe(myMesh,MED_FACE); - affiche_groupe(myMesh,MED_EDGE); - */ - - delete myMesh; - - return 0; -} diff --git a/src/MEDMEM/test_copie_fieldT.cxx b/src/MEDMEM/test_copie_fieldT.cxx deleted file mode 100644 index 00e435c4d..000000000 --- a/src/MEDMEM/test_copie_fieldT.cxx +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -/* Programme de test du constructeur de copies de la classe FIELD_ de MEDMEM - jroy - 12/12/2002 */ - -#include<string> - -#include <math.h> -#include <stdlib.h> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_Group.hxx" - -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_MedFieldDriver.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_FieldConvert.hxx" -#include "MEDMEM_define.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - - -void affiche_field_(FIELD_ * myField, const SUPPORT * mySupport) -{ - cout << "Field "<< myField->getName() << " : " <<myField->getDescription() << endl ; - int NumberOfComponents = myField->getNumberOfComponents() ; - cout << "- Nombre de composantes : "<< NumberOfComponents << endl ; - for (int i=1; i<NumberOfComponents+1; i++) { - cout << " - composante "<<i<<" :"<<endl ; - cout << " - nom : "<<myField->getComponentName(i)<< endl; - cout << " - description : "<<myField->getComponentDescription(i) << endl; - cout << " - units : "<<myField->getMEDComponentUnit(i) << endl; - } - cout << "- iteration :" << endl ; - cout << " - numero : " << myField->getIterationNumber()<< endl ; - cout << " - ordre : " << myField->getOrderNumber()<< endl ; - cout << " - temps : " << myField->getTime()<< endl ; - - cout << "- Type : " << myField->getValueType()<< endl; - - cout << "- Adresse support : " << mySupport << endl; -} - -template <class INTERLACING_TAG> -void affiche_fieldT(FIELD<double, INTERLACING_TAG> * myField, - const SUPPORT * mySupport) -{ - affiche_field_((FIELD_ *) myField, mySupport); - - cout << "- Valeurs :"<<endl; - int NumberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); - int NumberOfComponents = myField->getNumberOfComponents() ; - - if ( myField->getInterlacingType() == MED_EN::MED_FULL_INTERLACE ) { - for (int i=1; i<NumberOf+1; i++) { - const double * value = myField->getRow(i) ; - for (int j=0; j<NumberOfComponents; j++) - cout << value[j]<< " "; - cout<<endl; - } - } - else { - for (int j=1; j<NumberOfComponents+1; j++) { - const double * value = myField->getColumn(j) ; - for (int i=0; i<NumberOf; i++) - cout << value[i]<< " "; - cout<<endl; - } - } -} - -int main (int argc, char ** argv) { - // int read; !! UNUSED VARIABLE !! - - if ((argc !=3) && (argc != 4)) { - cerr << "Usage : " << argv[0] - << " filename meshname fieldname" << endl << endl; - exit(-1); - } - - string filename = argv[1] ; - string meshname = argv[2] ; - - MESH * myMesh= new MESH() ; - myMesh->setName(meshname); - MED_MESH_RDONLY_DRIVER myMeshDriver(filename,myMesh) ; - myMeshDriver.setMeshName(meshname); - int current = myMesh->addDriver(myMeshDriver); - myMesh->read(current); - - // read field : - if (argc != 4) exit(0) ; - // else we have a field ! - string fieldname = argv[3]; - - FIELD<double> * myField ; - // SUPPORT * mySupport = new SUPPORT(myMesh,"On_all_node",MED_NODE); - SUPPORT * mySupport = new SUPPORT(myMesh,"On_all_cell",MED_CELL); - try { - myField = new FIELD<double>(mySupport,MED_DRIVER,filename,fieldname) ; - } catch (...) { - delete mySupport ; - mySupport = new SUPPORT(myMesh,"On_all_node",MED_NODE); - try { - myField = new FIELD<double>(mySupport,MED_DRIVER,filename,fieldname) ; - } catch (...) { - cout << "Field double " << fieldname << " not found !!!" << endl ; - exit (-1) ; - } - } - - affiche_fieldT(myField, mySupport); - FIELD<double> * myField2 = new FIELD<double>(* myField); // Contructeur par recopie, sauf SUPPORT - delete myField; // Ne détruit pas le Support - affiche_fieldT(myField2, myField2->getSupport()); - FIELD<double,NoInterlace> * myField3 = FieldConvert( *myField2 ); - delete myField2; - - affiche_fieldT(myField3, myField3->getSupport()); - FIELD<double,FullInterlace> * myField4 = FieldConvert( *myField3 ); - delete myField3; - affiche_fieldT(myField4, myField4->getSupport()); - delete myField4; - - FIELD<double,NoInterlace> * myField5 = new FIELD<double,NoInterlace>(mySupport,MED_DRIVER,filename,fieldname) ; - affiche_fieldT(myField5, myField5->getSupport()); - delete myField5; - - delete mySupport ; - delete myMesh ; - - return 0; -} diff --git a/src/MEDMEM/test_copie_field_.cxx b/src/MEDMEM/test_copie_field_.cxx deleted file mode 100644 index 878550572..000000000 --- a/src/MEDMEM/test_copie_field_.cxx +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -/* Programme de test du constructeur de copies de la classe FIELD_ de MEDMEM - jroy - 12/12/2002 */ - -#include<string> - -#include <math.h> -#include <stdlib.h> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_Group.hxx" - -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_MedFieldDriver.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_define.hxx" - -using namespace MEDMEM; -using namespace MED_EN; - - -void affiche_field(FIELD_ * myField, const SUPPORT * mySupport) -{ - cout << "Field "<< myField->getName() << " : " <<myField->getDescription() << endl ; - int NumberOfComponents = myField->getNumberOfComponents() ; - cout << "- Nombre de composantes : "<< NumberOfComponents << endl ; - for (int i=1; i<NumberOfComponents+1; i++) { - cout << " - composante "<<i<<" :"<<endl ; - cout << " - nom : "<<myField->getComponentName(i)<< endl; - cout << " - description : "<<myField->getComponentDescription(i) << endl; - cout << " - units : "<<myField->getMEDComponentUnit(i) << endl; - } - cout << "- iteration :" << endl ; - cout << " - numero : " << myField->getIterationNumber()<< endl ; - cout << " - ordre : " << myField->getOrderNumber()<< endl ; - cout << " - temps : " << myField->getTime()<< endl ; - - cout << "- Type : " << myField->getValueType()<< endl; - /* - cout << "- Valeurs :"<<endl; - int NumberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); - - for (int i=1; i<NumberOf+1; i++) { - double * value = myField->getValueI(MED_FULL_INTERLACE,i) ; - for (int j=0; j<NumberOfComponents; j++) - cout << value[j]<< " "; - cout<<endl; - } - */ - cout << "- Adresse support : " << mySupport << endl; -} - - -int main (int argc, char ** argv) { - // int read; !! UNUSED VARIABLE !! - - if ((argc !=3) && (argc != 4)) { - cerr << "Usage : " << argv[0] - << " filename meshname fieldname" << endl << endl; - exit(-1); - } - - string filename = argv[1] ; - string meshname = argv[2] ; - - // MESH * myMesh= new MESH(MED_DRIVER,filename,meshname) ; - MESH * myMesh= new MESH() ; - myMesh->setName(meshname); - MED_MESH_RDONLY_DRIVER myMeshDriver(filename,myMesh) ; - myMeshDriver.setMeshName(meshname); - myMeshDriver.open() ; - myMeshDriver.read() ; - myMeshDriver.close() ; - - // int drv = myMesh->addDriver(MED_DRIVER,"sortie.med",meshname); - // myMesh->write(drv); - - - - - // if (argc < 4) return 0; - - // read field : - - if (argc != 4) exit(0) ; - // else we have a field ! - - string fieldname = argv[3]; - - - // SUPPORT * mySupport = new SUPPORT(myMesh,"On_all_node",MED_NODE); - SUPPORT * mySupport = new SUPPORT(myMesh,"On_all_cell",MED_EN::MED_CELL); - FIELD<double> * myField = new FIELD<double>() ; - - myField->setName(fieldname); - myField->setSupport(mySupport); - MED_FIELD_RDONLY_DRIVER<double> myFieldDriver(filename,myField) ; - myFieldDriver.setFieldName(fieldname); - myFieldDriver.open() ; - - try { - myFieldDriver.read() ; - } catch (...) { - delete mySupport ; - mySupport = new SUPPORT(myMesh,"On_all_node",MED_EN::MED_NODE); - myField->setSupport(mySupport); - try { - myFieldDriver.read() ; - } catch (...) { - cout << "Field " << fieldname << " not found !!!" << endl ; - exit (-1) ; - } - } - - myFieldDriver.close() ; - - FIELD_ * pt_field_ = myField; - affiche_field(pt_field_, mySupport); - FIELD_ * pt_field_2 = new FIELD_(* pt_field_); - delete myField; - affiche_field(pt_field_2, pt_field_2->getSupport()); - - delete pt_field_2 ; - - delete mySupport ; - delete myMesh ; - - return 0; -} diff --git a/src/MEDMEM/test_copie_group.cxx b/src/MEDMEM/test_copie_group.cxx deleted file mode 100644 index d8b625719..000000000 --- a/src/MEDMEM/test_copie_group.cxx +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include<string> - -#include <math.h> -#include <stdlib.h> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_Group.hxx" - -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_MedFieldDriver.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_define.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -void affiche_support(const SUPPORT * mySupport) -{ - cout << " - Name : "<<mySupport->getName().c_str()<<endl ; - cout << " - Description : "<<mySupport->getDescription().c_str()<<endl ; - cout << " - Entity : "<<mySupport->getEntity()<<endl ; - cout << " - Entities list : "<<endl ; - if (!(mySupport->isOnAllElements())) { - int NumberOfTypes = mySupport->getNumberOfTypes() ; - cout<<" - NumberOfTypes : "<<NumberOfTypes<<endl; - const medGeometryElement * Types = mySupport->getTypes() ; - for (int j=0;j<NumberOfTypes;j++) { - cout<<" * Type "<<Types[j]<<" : "; - int NumberOfElements = mySupport->getNumberOfElements(Types[j]) ; - const int * Number = mySupport->getNumber(Types[j]) ; - for (int k=0; k<NumberOfElements;k++) - cout << Number[k] << " "; - cout << endl ; - } - } else - cout << " Is on all entities !"<< endl; -} - - -void affiche_famille(const FAMILY * myFamily) -{ - affiche_support(myFamily); - cout << " - Identifier : "<<myFamily->getIdentifier()<<endl ; - int NumberOfAttributes = myFamily->getNumberOfAttributes() ; - cout << " - Attributes ("<<NumberOfAttributes<<") :"<<endl; - for (int j=1;j<NumberOfAttributes+1;j++) - cout << " * "<<myFamily->getAttributeIdentifier(j)<<" : "<<myFamily->getAttributeValue(j)<<", "<<myFamily->getAttributeDescription(j).c_str()<<endl ; - int NumberOfGroups = myFamily->getNumberOfGroups() ; - cout << " - Groups ("<<NumberOfGroups<<") :"<<endl; - for (int j=1;j<NumberOfGroups+1;j++) - cout << " * "<<myFamily->getGroupName(j).c_str()<<endl ; -} - -void affiche_groupe(const GROUP * myGroup) -{ - affiche_support(myGroup); - int NumberOfFamillies = myGroup->getNumberOfFamilies() ; - cout << " - Families ("<<NumberOfFamillies<<") :"<<endl; - for (int j=1;j<NumberOfFamillies+1;j++) - cout << " * "<<myGroup->getFamily(j)->getName().c_str()<<endl ; -} - -int main (int argc, char ** argv) { - int read; - - if (argc <3) { // after 3, ignored ! - cerr << "Usage : " << argv[0] - << " filename meshname" << endl << endl; - exit(-1); - } - - string filename = argv[1] ; - string meshname = argv[2] ; - - MESH * myMesh= new MESH() ; - myMesh->setName(meshname); - MED_MESH_RDONLY_DRIVER myMeshDriver(filename,myMesh) ; - myMeshDriver.setMeshName(meshname); - myMeshDriver.open() ; - myMeshDriver.read() ; - myMeshDriver.close() ; - - const GROUP * myGroup = myMesh->getGroup(MED_NODE,1); - cout << "Show Group :"<<endl ; - affiche_groupe(myGroup); - GROUP * myGroup2 = new GROUP(* myGroup); - //delete myGroup; // no because in mesh !! - affiche_groupe(myGroup2); - GROUP * myGroup3 = new GROUP(* myGroup2); - delete myGroup2; - affiche_groupe(myGroup3); - delete myGroup3; - - delete myMesh ; - - return 0; -} diff --git a/src/MEDMEM/test_copie_medarray.cxx b/src/MEDMEM/test_copie_medarray.cxx deleted file mode 100644 index f25da6fd7..000000000 --- a/src/MEDMEM/test_copie_medarray.cxx +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -/* Programme de test du constructeur de copies de la classe MEDARRAY de MEDMEM - jroy - 16/12/2002 */ - -#include <string> - -#include <math.h> -#include <stdlib.h> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_Group.hxx" - -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_MedFieldDriver.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_define.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -void affiche_medarray(MEDARRAY<double> & myMedArray) -{ - int numberof ; - MESSAGE("Show all 1 :"); - numberof = myMedArray.getLeadingValue() ; - for (int i=1; i<=myMedArray.getLengthValue() ; i++) { - const double * node = myMedArray.getRow(i) ; - cout << " - " ; - for (int j=0;j<numberof;j++) - cout << node[j] << " " ; - cout << endl ; - } - MESSAGE("Show all 2 :"); - numberof = myMedArray.getLengthValue() ; - for (int i=1; i<=myMedArray.getLeadingValue() ; i++) { - const double * node = myMedArray.getColumn(i) ; - cout << " - " ; - for (int j=0;j<numberof;j++) - cout << node[j] << " " ; - cout << endl ; - } - MESSAGE("Show all 3 :"); - numberof = myMedArray.getLeadingValue() ; - for (int i=1; i<=myMedArray.getLengthValue() ; i++) { - cout << " - " ; - for (int j=1;j<numberof+1;j++) - cout << myMedArray.getIJ(i,j) << " " ; - cout << endl ; - } - - MESSAGE("Show all 0 :"); - numberof = myMedArray.getLeadingValue() ; - int length = myMedArray.getLengthValue() ; - const double * NoInterlaceArray = myMedArray.get(MED_NO_INTERLACE) ; - for (int i=0; i<length ; i++) { - cout << " - " ; - for (int j=0;j<numberof;j++) - cout << NoInterlaceArray[j*length+i] << " " ; - cout << endl ; - } - - - /* - cout << "Nombre de lignes : " << myMedArray.getLengthValue() << endl; - cout << "Nombre de colonnes : " << myMedArray.getLeadingValue() << endl; - cout << "Mode d'écriture en mémoire : " << myMedArray.getMode() << endl; - cout << "Valeurs (_valuesDefault) :" << endl; - - for (med_int i=1; i<=myMedArray.getLengthValue(); i++) { - for (med_int j=1; j<=myMedArray.getLeadingValue(); j++) - cout << i << " " << j << " " << myMedArray.getIJ(i,j) << " " << endl; - } - */ -} - - -int main (int argc, char ** argv) { - /* - if ((argc !=3) && (argc != 4)) { - cerr << "Usage : " << argv[0] - << " filename meshname fieldname" << endl << endl; - exit(-1); - } - */ - const med_int nb_noeuds = 8; - const med_int dimension = 3; - const medModeSwitch mode = MED_NO_INTERLACE; - - - MEDARRAY<double> * myMedArray = new MEDARRAY<double>(dimension,nb_noeuds,mode); - for (med_int i=1; i<=myMedArray->getLengthValue(); i++) { - for (med_int j=1; j<=myMedArray->getLeadingValue(); j++) - myMedArray->setIJ(i,j,(double) random()); - }; - - affiche_medarray(* myMedArray); - MEDARRAY<double> * myMedArray2 = new MEDARRAY<double>(* myMedArray,false); - delete myMedArray; - affiche_medarray(* myMedArray2); - MEDARRAY<double> * myMedArray3 = new MEDARRAY<double>(10,20); - (* myMedArray3) = (* myMedArray2) ; - delete myMedArray2; - affiche_medarray(* myMedArray3); - delete myMedArray3; - - return 0; -} diff --git a/src/MEDMEM/test_copie_mesh.cxx b/src/MEDMEM/test_copie_mesh.cxx deleted file mode 100644 index e8f5e001c..000000000 --- a/src/MEDMEM/test_copie_mesh.cxx +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include<string> - -#include <math.h> -#include <stdlib.h> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_Group.hxx" - -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_MedFieldDriver.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_define.hxx" - -using namespace std; -using namespace MEDMEM; - -int main (int argc, char ** argv) { - int read; - - if (argc <3) { // after 3, ignored ! - cerr << "Usage : " << argv[0] - << " filename meshname" << endl << endl; - exit(-1); - } - - string filename = argv[1] ; - string meshname = argv[2] ; - - MESH * myMesh= new MESH() ; - myMesh->setName(meshname); - MED_MESH_RDONLY_DRIVER myMeshDriver(filename,myMesh) ; - myMeshDriver.setMeshName(meshname); - myMeshDriver.open() ; - myMeshDriver.read() ; - myMeshDriver.close() ; - - cout << * myMesh << endl; - MESH * myMesh2 = new MESH(* myMesh); - delete myMesh; - cout << * myMesh2 << endl; - delete myMesh2; - - return 0; -} diff --git a/src/MEDMEM/test_copie_support.cxx b/src/MEDMEM/test_copie_support.cxx deleted file mode 100644 index e8322ba97..000000000 --- a/src/MEDMEM/test_copie_support.cxx +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include<string> - -#include <math.h> -#include <stdlib.h> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_Group.hxx" - -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_MedFieldDriver.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_define.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -void affiche_support(const SUPPORT * mySupport) -{ - cout << " - Name : "<<mySupport->getName().c_str()<<endl ; - cout << " - Description : "<<mySupport->getDescription().c_str()<<endl ; - cout << " - Entity : "<<mySupport->getEntity()<<endl ; - cout << " - Entities list : "<<endl ; - if (!(mySupport->isOnAllElements())) { - int NumberOfTypes = mySupport->getNumberOfTypes() ; - cout<<" - NumberOfTypes : "<<NumberOfTypes<<endl; - const medGeometryElement * Types = mySupport->getTypes() ; - for (int j=0;j<NumberOfTypes;j++) { - cout<<" * Type "<<Types[j]<<" : "; - int NumberOfElements = mySupport->getNumberOfElements(Types[j]) ; - const int * Number = mySupport->getNumber(Types[j]) ; - for (int k=0; k<NumberOfElements;k++) - cout << Number[k] << " "; - cout << endl ; - } - } else - cout << " Is on all entities !"<< endl; -} - - -void affiche_famille(MESH *myMesh,medEntityMesh Entity) -{ - int NumberOfFamilies = myMesh->getNumberOfFamilies(Entity) ; - cout << "NumberOfFamilies : "<<NumberOfFamilies<<endl; - for (int i=1; i<NumberOfFamilies+1;i++) { - const FAMILY* myFamily = myMesh->getFamily(Entity,i); - affiche_support(myFamily); - cout << " - Identifier : "<<myFamily->getIdentifier()<<endl ; - int NumberOfAttributes = myFamily->getNumberOfAttributes() ; - cout << " - Attributes ("<<NumberOfAttributes<<") :"<<endl; - for (int j=1;j<NumberOfAttributes+1;j++) - cout << " * "<<myFamily->getAttributeIdentifier(j)<<" : "<<myFamily->getAttributeValue(j)<<", "<<myFamily->getAttributeDescription(j).c_str()<<endl ; - int NumberOfGroups = myFamily->getNumberOfGroups() ; - cout << " - Groups ("<<NumberOfGroups<<") :"<<endl; - for (int j=1;j<NumberOfGroups+1;j++) - cout << " * "<<myFamily->getGroupName(j).c_str()<<endl ; - } -} - -void affiche_groupe(MESH *myMesh,medEntityMesh Entity) -{ - int NumberOfGroups = myMesh->getNumberOfGroups(Entity) ; - cout << "NumberOfGroups : "<<NumberOfGroups<<endl; - for (int i=1; i<NumberOfGroups+1;i++) { - const GROUP* myGroup = myMesh->getGroup(Entity,i); - affiche_support(myGroup); - int NumberOfFamillies = myGroup->getNumberOfFamilies() ; - cout << " - Families ("<<NumberOfFamillies<<") :"<<endl; - for (int j=1;j<NumberOfFamillies+1;j++) - cout << " * "<<myGroup->getFamily(j)->getName().c_str()<<endl ; - } -} - -int main (int argc, char ** argv) { - int read; - - if (argc <3) { // after 3, ignored ! - cerr << "Usage : " << argv[0] - << " filename meshname" << endl << endl; - exit(-1); - } - - string filename = argv[1] ; - string meshname = argv[2] ; - - MESH * myMesh= new MESH() ; - myMesh->setName(meshname); - MED_MESH_RDONLY_DRIVER myMeshDriver(filename,myMesh) ; - myMeshDriver.setMeshName(meshname); - myMeshDriver.open() ; - myMeshDriver.read() ; - myMeshDriver.close() ; - - //Construction d'un support total - SUPPORT * mySupport = new SUPPORT(myMesh,"Support on CELLs",MED_CELL); - - cout << "Show Support on all :"<<endl ; - affiche_support(mySupport); - SUPPORT * mySupport2 = new SUPPORT(* mySupport); - delete mySupport; - affiche_support(mySupport2); - delete mySupport2; - - //Construction d'un support partiel - mySupport = new SUPPORT(myMesh,"Support on CELLs",MED_CELL); - mySupport->setAll(false); - - // int NumberOfGeometricType = 1; - int NumberOfGeometricType = 0; - // int TotalNumberOfEntity = 2; - // medGeometryElement * GeometricTypePartial = new medGeometryElement[NumberOfGeometricType]; - // GeometricTypePartial[0] = MED_HEXA8; - int TotalNumberOfElements = 0; - int * NumberOfElements = new int[myMesh->getNumberOfTypes(MED_CELL)]; - // NumberOfEntity[0] = 2; - // int * NumberValue = new int[TotalNumberOfEntity]; - int * NumberValue = new int[myMesh->getGlobalNumberingIndex(MED_CELL)[myMesh->getNumberOfTypes(MED_CELL)]-1]; - // NumberValue[0] = 14; - // NumberValue[1] = 15; - int cmp = 0; - medGeometryElement * GeometricTypePartial = new medGeometryElement[myMesh->getNumberOfTypes(MED_CELL)]; - const medGeometryElement * GeometricType = myMesh->getTypes(MED_CELL); - for (int i=0;i<myMesh->getNumberOfTypes(MED_CELL);i=i+2) - { - NumberOfGeometricType=NumberOfGeometricType+1; - TotalNumberOfElements=TotalNumberOfElements+myMesh->getNumberOfElements(MED_CELL,GeometricType[i]); - NumberOfElements[i/2]=myMesh->getNumberOfElements(MED_CELL,GeometricType[i]); - for (int j=0;j<myMesh->getNumberOfElements(MED_CELL,GeometricType[i]);j++) - { - NumberValue[cmp]=myMesh->getGlobalNumberingIndex(MED_CELL)[i]+j; - cmp=cmp+1; - } - GeometricTypePartial[i/2]=GeometricType[i]; - } - - mySupport->setpartial("Support partiel",NumberOfGeometricType,TotalNumberOfElements,GeometricTypePartial,NumberOfElements,NumberValue); - - delete[] NumberOfElements ; - delete[] NumberValue ; - delete[] GeometricTypePartial ; - - cout << "Show Partial Support :"<<endl ; - affiche_support(mySupport); - mySupport2 = new SUPPORT(* mySupport); - delete mySupport; - affiche_support(mySupport2); - delete mySupport2; - - /* - cout << "Show Family :"<<endl ; - affiche_famille(myMesh,MED_NODE); - affiche_famille(myMesh,MED_CELL); - affiche_famille(myMesh,MED_FACE); - affiche_famille(myMesh,MED_EDGE); - - cout << "Show Group :"<<endl ; - affiche_groupe(myMesh,MED_NODE); - affiche_groupe(myMesh,MED_CELL); - affiche_groupe(myMesh,MED_FACE); - affiche_groupe(myMesh,MED_EDGE); - */ - - delete myMesh ; - - return 0; -} diff --git a/src/MEDMEM/test_gibi_driver.cxx b/src/MEDMEM/test_gibi_driver.cxx deleted file mode 100644 index 831db81d3..000000000 --- a/src/MEDMEM/test_gibi_driver.cxx +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include "MEDMEM_GibiMeshDriver.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_DriverFactory.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; -using namespace DRIVERFACTORY; - -int main (int argc, char ** argv) -{ - /* process the arguments */ - if (argc != 2) - { - cerr << "Usage : " << argv[0] - << "Gibifilename" << endl << endl - << "-> lit le fichier gibi filename ,crée 3 fichiers : MED 2.1, 2.2 et VTK" << endl; - exit(-1); - } - - string gibifilename = argv[1]; - - // Construction des noms de fichier - const string ext=".sauve"; - string::size_type pos=gibifilename.find(ext,0); - string basename (gibifilename, 0, pos); // nom sans extension - string medfile21=basename+"_V21.med"; // nom fichier med 2.1 à creer - string medfile22=basename+"_V22.med"; // nom fichier med 2.2 à creer - string vtkfile=basename+".vtk"; // nom fichier vtk à creer - string::size_type pos1=gibifilename.rfind('/'); - string meshName (gibifilename,pos1+1,pos-pos1-1); // get rid of directory & extension - cout << meshName << endl; - - // lecture du fichier gibi - // MESH * myMesh= new MESH(GIBI_DRIVER,gibifilename); - MESH * myMesh= new MESH() ; - GIBI_MESH_RDONLY_DRIVER myGibiMeshDriver(gibifilename, myMesh) ; - myGibiMeshDriver.open() ; - myGibiMeshDriver.read() ; - myGibiMeshDriver.close() ; - - cout << "Impression de MESH : " << endl; - cout << *myMesh; - - // creation des fichiers med 2.1 et 2.2 - medFileVersion version = getMedFileVersionForWriting(); - if (version == V22) - setMedFileVersionForWriting(V21); - - cout << "creation du fichier med 21 : " << endl; - int idMed21 = myMesh->addDriver(MED_DRIVER, medfile21, meshName); - myMesh->write(idMed21) ; - - version = getMedFileVersionForWriting(); - if (version == V21) - setMedFileVersionForWriting(V22); - - cout << "creation du fichier med 22 : " << endl; - int idMed22 = myMesh->addDriver(MED_DRIVER, medfile22, meshName); - myMesh->write(idMed22) ; - - // creation d'un fichier vtk - cout << "creation d'un fichier vtk : " << endl; - int idVtk = myMesh->addDriver(VTK_DRIVER, vtkfile, meshName); - myMesh->write(idVtk) ; - delete myMesh; - - // remontée mémoire du fichier med 21 - myMesh= new MESH(MED_DRIVER,medfile21,meshName); - //myMesh= new MESH() ; - //myMesh->setName(meshName); - //MED_MESH_RDONLY_DRIVER myMeshDriver(medfile,myMesh) ; - //myMeshDriver.setMeshName(meshName); - //myMeshDriver.open() ; - //myMeshDriver.read() ; - //myMeshDriver.close() ; - //cout << "Impression 2 de MESH : " << endl; - //cout << *myMesh; - delete myMesh; - - // remontée mémoire du fichier med 22 - myMesh= new MESH(MED_DRIVER,medfile22,meshName); - - delete myMesh; -} diff --git a/src/MEDMEM/test_grid.cxx b/src/MEDMEM/test_grid.cxx deleted file mode 100644 index 8d5cb61b6..000000000 --- a/src/MEDMEM/test_grid.cxx +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include "MEDMEM_Grid.hxx" - -using namespace MEDMEM; -using namespace MED_EN; - -static void usage(const char * test) -{ - cerr << "Usage : " << test - << " SpaceDimension nbMaille" << endl << endl - << "-> Crée une grille cartesienne en dimension SpaceDimension avec nbMaille suivant chaque direction" << endl; - exit(-1); -} - -int main (int argc, char ** argv) { - - /* process the arguments */ - if (argc != 3) - usage(argv[0]); - - const int SpaceDimension=atoi(argv[1]); - const int nbMaille=atoi(argv[2]); - if(SpaceDimension>3 || SpaceDimension<1 || nbMaille<1) - usage(argv[0]); - - // Creation des tableaux necessaires à la construction de GRID - std::vector<int> nMaille(SpaceDimension,nbMaille); - std::vector<double> Origine(SpaceDimension,0.0); - std::vector<double> pas(SpaceDimension,10.0); - std::vector<std::vector<double> > XYZ_Array(SpaceDimension); - for(int i=0;i!=SpaceDimension;++i) - { - XYZ_Array[i].resize(nMaille[i]+1); // nbre de noeuds = nbre de mailles +1 - XYZ_Array[i][0]=Origine[i]; - for(int j=1;j!=XYZ_Array[i].size();++j) - XYZ_Array[i][j]=XYZ_Array[i][j-1] + pas[j-1]; - } - - std::vector<std::string> coord_name(SpaceDimension,"X"); - if(SpaceDimension>=2) - coord_name[1]="Y"; - if(SpaceDimension>=3) - coord_name[2]="Z"; - std::vector<std::string> coord_unit(SpaceDimension,"cm"); - - // creation du pointeur MESH à partir d'un GRID, test affichage - std::auto_ptr<MEDMEM::MESH> Mesh (new MEDMEM::GRID( XYZ_Array, coord_name, coord_unit, MED_CARTESIAN) ); - const MEDMEM::CONNECTIVITY* conn = Mesh->getConnectivityptr(); - std::cout << "Affichage du maillage : " << endl << *Mesh << endl; -} diff --git a/src/MEDMEM/test_operation_fielddouble.cxx b/src/MEDMEM/test_operation_fielddouble.cxx deleted file mode 100644 index e156b825b..000000000 --- a/src/MEDMEM/test_operation_fielddouble.cxx +++ /dev/null @@ -1,418 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -// Programme de test des operations sur les champs - -#include <string> -#include <iostream> -#include <iomanip> -#include <cmath> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_Group.hxx" - -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_MedFieldDriver.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_define.hxx" - -double myfunction1(double x) -{ - return 0.25*(x-1.0); -} - - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -void affiche_field_(FIELD_ * myField, const SUPPORT * mySupport) -{ - cout << "Field "<< myField->getName() << " : " <<myField->getDescription() << endl ; - int NumberOfComponents = myField->getNumberOfComponents() ; - cout << "- Nombre de composantes : "<< NumberOfComponents << endl ; - cout << "- Nombre de valeurs : "<< myField->getNumberOfValues() << endl ; - for (int i=1; i<NumberOfComponents+1; i++) { - cout << " - composante "<<i<<" :"<<endl ; - cout << " - nom : "<<myField->getComponentName(i)<< endl; - cout << " - description : "<<myField->getComponentDescription(i) << endl; - cout << " - units : "<<myField->getMEDComponentUnit(i) << endl; - } - cout << "- iteration :" << endl ; - cout << " - numero : " << myField->getIterationNumber()<< endl ; - cout << " - ordre : " << myField->getOrderNumber()<< endl ; - cout << " - temps : " << myField->getTime()<< endl ; - - cout << "- Type : " << myField->getValueType()<< endl; - - cout << "- Adresse support : " << mySupport << endl; -} - -void affiche_fieldT(FIELD<double> * myField, const SUPPORT * mySupport) -{ - affiche_field_((FIELD_ *) myField, mySupport); - - cout << "- Valeurs :"<<endl; - int NumberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); - int NumberOfComponents = myField->getNumberOfComponents() ; - - for (int i=1; i<NumberOf+1; i++) { - const double * value = myField->getRow(i) ; - for (int j=0; j<NumberOfComponents; j++) - cout << value[j]<< " "; - cout<<endl; - } - cout << endl; - cout << "Norme euclidienne : " << myField->norm2() << endl; - cout << "Norme max : " << myField->normMax() << endl; - try - { - for (int i=1; i<=myField->getNumberOfComponents(); ++i) - cout << "Norme L2 - comp=" << i << " : " << myField->normL2(i) << endl; - cout << "Norme L2 : " << myField->normL2() << endl; - - for (int i=1; i<=myField->getNumberOfComponents(); ++i) - cout << "Norme L1 - comp=" << i << " : " << myField->normL1(i) << endl; - cout << "Norme L1 : " << myField->normL1() << endl; - } - catch (MEDEXCEPTION &ex) - { - cout << ex.what() << endl; - } -} - -void affiche_valeur_field(const FIELD<double>& f) -{ - const int tailleMax=12; - const int taille=f.getNumberOfValues()*f.getNumberOfComponents(); - const double * value=f.getValue(); - if(taille<=tailleMax) - for(int i=0;i<taille;i++) - cout << setw(3) << value[i] << " "; - else - { - for(int i=0; i<tailleMax/2; ++i) - cout << setw(3) << value[i] << " "; - cout << " ... "; - for(int i=taille-tailleMax/2 ; i<taille; ++i) - cout << setw(3) << value[i] << " "; - } -} - -void checkOperation(const FIELD<double>& resOp, const FIELD<double>& f1, const FIELD<double>& f2, - char Op, const char* intitule, int verbose) -{ - int res=0; - - // get pointers to inside arrays of values - const double * value=resOp.getValue(); - const double * value1=f1.getValue(); - const double * value2=f2.getValue(); - const int size=f1.getNumberOfValues()*f1.getNumberOfComponents(); // size of field1 - - // check size compatibility - if(f1.getNumberOfValues()*f1.getNumberOfComponents()!=size || - resOp.getNumberOfValues()*resOp.getNumberOfComponents()!=size) - res=1; - - if(!res) - { - switch(Op) - { - case '+': - for(int i=0; i!=size; ++i) - if(value[i]!=value1[i]+value2[i]) - res+=1; - break; - case '-': - for(int i=0; i!=size; ++i) - if(value[i]!=value1[i]-value2[i]) - res+=1; - break; - case 'n': - for(int i=0; i!=size; ++i) - if(value[i]!=-value1[i]) - res+=1; - break; - case '*': - for(int i=0; i!=size; ++i) - if(value[i]!=value1[i]*value2[i]) - res+=1; - break; - case '/': - for(int i=0; i!=size; ++i) - if(value2[i]!=0.0) - if(value[i]!=value1[i]/value2[i]) - res+=1; - break; - case '=': - for(int i=0; i!=size; ++i) - if(value[i]!=value2[i]) - res+=1; - break; - case 'a': - for(int i=0; i!=size; ++i) - if(value[i]!=value1[i]+value2[i]*value2[i]) - res+=1; - break; - } - - } - - if (verbose) - cout << endl << intitule << "["; - cout << res; - if (verbose) - { - cout << "] : "; - affiche_valeur_field(resOp); - } - else - cout << endl; -} - -int main (int argc, char ** argv) -{ - /* process the arguments */ - int verbose=0; // verbose=1 if the verbose mode is selected - int res=0; // unit test result - int ntest=0; // numéro du test - - if (argc>=2 && !strcmp(argv[1],"-v")) - verbose=1; - - if (argc != 4+verbose) - { - cerr << "Usage : " << argv[0] - << "[-v] filename meshname fieldname" << endl << endl - << "-> tests field's operations on the FIELD<double> fieldname" << endl - << "Use optional option -v to select verbose mode" << endl; - exit(-1); - } - string filename = argv[verbose+1]; - string meshname = argv[verbose+2];// Maintenant plus très utile - string fieldname = argv[verbose+3]; - - /* read MESH, SUPPORT and FIELDS */ - //MESH * myMesh = new MESH(MED_DRIVER,filename,meshname); - - MESH * myMesh; - const SUPPORT * mySupport; - FIELD<double> * myField1; - - try { - - myField1 = new FIELD<double>(MED_DRIVER,filename,fieldname) ; - mySupport = myField1->getSupport(); - myMesh = new MESH(MED_DRIVER,filename,mySupport->getMeshName()); - mySupport->setMesh(myMesh); - - FIELD<double> * myField2 = new FIELD<double>(* myField1); - FIELD<double> myFieldPlus = *myField1 + *myField2; - if(verbose) { - // affichage des nprmes,des champs f1, f2, scalarProduct(f1,f2) et f1+f2 - FIELD<double>* myField1_vol=myField1->getSupport()->getMesh()->getVolume(myField1->getSupport()); - cout << "Norme L2 calculee en fournissant le volume : " << myField1->normL2(myField1_vol) << endl; - for (int i=1; i<=myField1->getNumberOfComponents(); ++i) - cout << "Norme L2 - comp=" << i << " : " << myField1->normL2(i,myField1_vol) << endl; - cout << "Norme L1 calculee en fournissant le volume : " << myField1->normL1(myField1_vol) << endl; - for (int i=1; i<=myField1->getNumberOfComponents(); ++i) - cout << "Norme L1 - comp=" << i << " : " << myField1->normL1(i,myField1_vol) << endl; - delete myField1_vol; - - affiche_fieldT(myField1, myField1->getSupport()); - cout << endl << string(60,'-') << endl; - affiche_fieldT(myField2, myField2->getSupport()); - cout << endl << string(60,'-') << endl; - - FIELD<double>* myFieldDot = FIELD<double>::scalarProduct(*myField1, *myField2); - affiche_fieldT(myFieldDot, myFieldDot->getSupport()); - delete myFieldDot; - cout << endl << string(60,'-') << endl ; - affiche_fieldT(&myFieldPlus, myFieldPlus.getSupport()); - cout << endl << string(60,'-') << endl << endl ; - } - - - // Verifie plusieurs cas de non compatibilité - - // test 1 : Unites non compatibles - const string unite=myField1->getMEDComponentUnit(1); - myField1->setMEDComponentUnit(1,string("UniteBidon")); - ntest++; res=1; - try - { - FIELD<double> myFieldPlus = *myField1 + *myField2; - if(verbose) - { - cout << endl << string(60,'-') << endl; - cout<< "Test " << ntest << " : incompatibilité d'unité : " << endl << endl; - } - } - catch (MEDEXCEPTION & ex) - { - res=0; - if(verbose) - cout << ex.what() << endl; - myField1->setMEDComponentUnit(1,unite); - } - cout << res << endl; - - // test 2 : numberOfComponents non compatibles - const int numberOfComponents =myField1->getNumberOfComponents(); - myField1->setNumberOfComponents(13); - ntest++; res=1; - try - { - if(verbose) - { - cout << endl << string(60,'-') << endl; - cout<< "Test " << ntest << " : incompatibilité nombre de composantes : " << endl << endl; - } - FIELD<double> myFieldPlus = *myField1 + *myField2; - } - catch (MEDEXCEPTION & ex) - { - res=0; - if(verbose) - cout << endl << ex.what() << endl << endl; - myField1->setNumberOfComponents(numberOfComponents); - } - cout << res << endl; - - // test 3 : supports non compatibles - const SUPPORT mySupport2(myMesh,"On_all_node",MED_NODE); - myField1->setSupport(&mySupport2); - ntest++; res=1; - try - { - if(verbose) - cout << endl << string(60,'-') << endl << "Test " << ntest << " : incompatibilité des supports" << endl << endl; - FIELD<double> myFieldPlus = *myField1 + *myField2; - } - catch (MEDEXCEPTION & ex) - { - res=0; - if(verbose) - cout << ex.what() << endl << endl << endl; - myField1->setSupport(mySupport); - } - cout << res << endl; - - // test 4 : champs de taille nulle - myField1->setNumberOfComponents(0); - myField2->setNumberOfComponents(0); - ntest++; res=2; - try - { - if(verbose) - cout<< endl << string(60,'-') << endl << "Test " << ntest << " : incompatibilité taille nulle" << endl << endl; - FIELD<double> myFieldPlus = *myField1 + *myField2; - } - catch (MEDEXCEPTION & ex) - { - --res; - if(verbose) - cout << ex.what() << endl << endl ; - } - try - { - double mynorm2=myField1->norm2(); - } - catch (MEDEXCEPTION & ex) - { - --res; - if(verbose) - cout << ex.what() << endl << endl ; - myField1->setNumberOfComponents(numberOfComponents); - myField2->setNumberOfComponents(numberOfComponents); - } - cout << res << endl; - - // Apres toutes ces exceptions, des opérations qui marchent! - - if(verbose) - { - cout<< endl << string(60,'-') << endl << "Test " << ++ntest << " : Operations arithmétiques" << endl; - cout << endl << " f1 : "; affiche_valeur_field(*myField1); - cout << endl << " f2 : "; affiche_valeur_field(*myField2); - cout << endl << string(140,'-'); - } - - // Test du résultats de certaines opérations et affichage si verbose - checkOperation(myFieldPlus, *myField1, *myField2, '+', " f1+f2 ", verbose); - FIELD<double>* myFieldadd = FIELD<double>::add(*myField1, *myField2); - checkOperation( *myFieldadd, *myField1, *myField2, '+', "add(f1,f2)", verbose); - delete myFieldadd; - - FIELD<double> myFieldMoins = *myField1 - *myField2; - checkOperation(myFieldMoins, *myField1, *myField2, '-', " f1-f2 ", verbose); - FIELD<double>* myFieldsub = FIELD<double>::sub(*myField1, *myField2); - checkOperation( *myFieldsub, *myField1, *myField2, '-', "sub(f1,f2)", verbose); - delete myFieldsub; - FIELD<double> myFieldNeg = -(*myField1); - checkOperation(myFieldNeg, *myField1, *myField1, 'n', " -f1 ", verbose); - - FIELD<double> myFieldFois = *myField1 * *myField2; - checkOperation(myFieldFois, *myField1, *myField2, '*', " f1*f2 ", verbose); - FIELD<double>* myFieldmul = FIELD<double>::mul(*myField1, *myField2); - checkOperation( *myFieldmul, *myField1, *myField2, '*', "mul(f1,f2)", verbose); - - FIELD<double> myFieldDiv = *myField1 / *myField2; - checkOperation(myFieldDiv, *myField1, *myField2, '/', " f1/f2 ", verbose); - FIELD<double>* myFielddiv = FIELD<double>::div(*myField1, *myField2); - checkOperation( *myFielddiv, *myField1, *myField2, '/', "div(f1,f2)", verbose); - delete myFielddiv; - - FIELD<double> myFieldAsso = (*myField1)+(*myField2)*(*myField2); - checkOperation(myFieldAsso, *myField1, *myField2, 'a', " f1+f2*f2 ", verbose); - - myField1->applyLin(4.0,1.0); - checkOperation(*myField1, *myField2, *myField2, 'l', " 4.f1 + 1 ", verbose); - myField1->applyFunc<myfunction1>(); - checkOperation( *myField1, *myField2, *myField1, '=', "CB : ->f1)", verbose); - - *myField1 += *myField2; - checkOperation(*myField1, *myField2, *myField2, '+', " f1+=f2 ", verbose); - - *myField1 -= *myField2; - checkOperation(*myField1, *myField2, *myField2, '=', " f1-=f2 ", verbose); - - *myField1 *= *myField2; - checkOperation(*myField1, *myField2, *myField2, '*', " f1*=f2 ", verbose); - *myField1 /= *myField2; - checkOperation(*myField1, *myFieldmul, *myField2, '/', " f1/=f2 ", verbose); - delete myFieldmul; - - - delete myField1; - delete myField2; - delete mySupport ; - delete myMesh ; - - } - catch ( MEDEXCEPTION & ex) { - cout << ex.what() << endl; - } - - return 0; -} diff --git a/src/MEDMEM/test_operation_fieldint.cxx b/src/MEDMEM/test_operation_fieldint.cxx deleted file mode 100644 index 53abf6af7..000000000 --- a/src/MEDMEM/test_operation_fieldint.cxx +++ /dev/null @@ -1,320 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -// Programme de test des operations sur les champs - -#include <string> -#include <iostream> -#include <iomanip> -#include <cmath> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_Family.hxx" -#include "MEDMEM_Group.hxx" - -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_MedFieldDriver.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_define.hxx" - -using namespace MEDMEM; -using namespace MED_EN; - -int myfunction1(int x) -{ - return 2*x; -} - -int myfunction2(int x) -{ - return x/2; -} - -using namespace std; -void affiche_field_(FIELD_ * myField, const SUPPORT * mySupport) -{ - cout << "Field "<< myField->getName() << " : " <<myField->getDescription() << endl ; - int NumberOfComponents = myField->getNumberOfComponents() ; - cout << "- Nombre de composantes : "<< NumberOfComponents << endl ; - cout << "- Nombre de valeurs : "<< myField->getNumberOfValues() << endl ; - for (int i=1; i<NumberOfComponents+1; i++) { - cout << " - composante "<<i<<" :"<<endl ; - cout << " - nom : "<<myField->getComponentName(i)<< endl; - cout << " - description : "<<myField->getComponentDescription(i) << endl; - cout << " - units : "<<myField->getMEDComponentUnit(i) << endl; - } - cout << "- iteration :" << endl ; - cout << " - numero : " << myField->getIterationNumber()<< endl ; - cout << " - ordre : " << myField->getOrderNumber()<< endl ; - cout << " - temps : " << myField->getTime()<< endl ; - - cout << "- Type : " << myField->getValueType()<< endl; - - cout << "- Adresse support : " << mySupport << endl; -} - -void affiche_fieldT(FIELD<int> * myField, const SUPPORT * mySupport) -{ - affiche_field_((FIELD_ *) myField, mySupport); - - cout << "- Valeurs :"<<endl; - int NumberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); - int NumberOfComponents = myField->getNumberOfComponents() ; - - for (int i=1; i<NumberOf+1; i++) { - const int * value = myField->getRow(i) ; - for (int j=0; j<NumberOfComponents; j++) - cout << value[j]<< " "; - cout<<endl; - } - std::cout << std::endl; - std::cout << "Norme euclidienne : " << myField->norm2() << endl; - std::cout << "Norme max : " << myField->normMax() << endl; - try - { - for (int i=1; i<=myField->getNumberOfComponents(); ++i) - std::cout << "Norme L2 - comp=" << i << " : " << myField->normL2(i) << endl; - std::cout << "Norme L2 : " << myField->normL2() << endl; - - for (int i=1; i<=myField->getNumberOfComponents(); ++i) - std::cout << "Norme L1 - comp=" << i << " : " << myField->normL1(i) << endl; - std::cout << "Norme L1 : " << myField->normL1() << endl; - } - catch (MEDEXCEPTION &ex) - { - std::cout << ex.what() << std::endl; - } -} - -void affiche_valeur_field(const char * intitule, const int taille, const FIELD<int>& f) -{ - const int * value=f.getValue(); - std::cout << endl << intitule; - for(int i=0;i<taille;i++) - std::cout << setw(3) << value[i] << " "; -} - -int main (int argc, char ** argv) -{ - if (argc != 4) - { - cerr << "Usage : " << argv[0] - << " filename meshname fieldname" << endl << endl; - exit(-1); - } - string filename = argv[1] ; - string meshname = argv[2] ; - string fieldname = argv[3]; - - MESH * myMesh = new MESH(MED_DRIVER,filename,meshname); - SUPPORT * mySupport; - FIELD<int> * myField1; - try - { - /* read MESH, SUPPORT and FIELD */ - mySupport = new SUPPORT(myMesh,"Support on all Cells",MED_CELL); - myField1 = new FIELD<int>(mySupport,MED_DRIVER,filename,fieldname) ; - } - catch (MEDEXCEPTION &ex) - { - delete mySupport ; - mySupport = new SUPPORT(myMesh,"On_all_node",MED_NODE); - try - { - myField1 = new FIELD<int>(mySupport,MED_DRIVER,filename,fieldname) ; - myField1->setValueIJ(10,1,-9); // pour tester les normes max avec une valeur negative - } - catch (...) - { - cout << "Field int " << fieldname << " not found !!!" << endl ; - exit (-1) ; - } - } - - FIELD<int> * myField2 = new FIELD<int>(* myField1); - //myField1->setNumberOfValues(16); // PROVISOIRE !! BUG - //myField2->setNumberOfValues(16); // PROVISOIRE !! BUG -// FIELD<int>* myField1_vol=myField1->getSupport()->getMesh()->getVolume(myField1->getSupport()); -// affiche_fieldT(myField1_vol, myField1->getSupport()); - - affiche_fieldT(myField1, myField1->getSupport()); - std::cout << endl << string(60,'-') << endl; - affiche_fieldT(myField2, myField2->getSupport()); - - // Verifie plusieurs cas de non compatibilité - - // Unites non compatibles - const string unite=myField1->getMEDComponentUnit(1); - myField1->setMEDComponentUnit(1,string("UniteBidon")); - try - { - std::cout << endl << string(60,'-') << endl; - std::cout<< "Test incompatibilité d'unité :" << endl; - FIELD<int> myFieldPlus = *myField1 + *myField2; - } - catch (MEDEXCEPTION & ex) - { - std::cout << "MEDEXCEPTION : " << ex.what() << endl; - myField1->setMEDComponentUnit(1,unite); - } - - // numberOfComponents non compatibles - const int numberOfComponents =myField1->getNumberOfComponents(); - myField1->setNumberOfComponents(4); - try - { - std::cout << endl << string(60,'-') << endl; - std::cout<< "Test incompatibilité nombre de composantes :" << endl; - FIELD<int> myFieldPlus = *myField1 + *myField2; - } - catch (MEDEXCEPTION & ex) - { - std::cout << ex.what() << endl; - myField1->setNumberOfComponents(numberOfComponents); - } - - // supports non compatibles - const SUPPORT mySupport2(myMesh,"On_all_node",MED_NODE); - myField1->setSupport(&mySupport2); - try - { - std::cout << endl << string(60,'-') << endl; - std::cout<< "Test incompatibilité des supports :" << endl; - FIELD<int> myFieldPlus = *myField1 + *myField2; - } - catch (MEDEXCEPTION & ex) - { - std::cout << ex.what() << endl; - myField1->setSupport(mySupport); - } - - // champs de taille nulle - myField1->setNumberOfComponents(0); - myField2->setNumberOfComponents(0); - try - { - std::cout << endl << string(60,'-') << endl; - std::cout<< "Test incompatibilité taille nulle :" << endl; - FIELD<int> myFieldPlus = *myField1 + *myField2; - } - catch (MEDEXCEPTION & ex) - { - std::cout << ex.what() << endl; - } - try - { - double mynorm2=myField1->norm2(); - } - catch (MEDEXCEPTION & ex) - { - std::cout << ex.what() << endl; - myField1->setNumberOfComponents(numberOfComponents); - myField2->setNumberOfComponents(numberOfComponents); - } - - // Apres toutes ces exceptions, des opérations qui marchent! - - FIELD<int> myFieldPlus = *myField1 + *myField2; - FIELD<int> myFieldMoins = *myField1 - *myField2; - FIELD<int> myFieldNeg = -(*myField1); - FIELD<int> myFieldFois = *myField1 * *myField2; - FIELD<int> myFieldDiv = *myField1 / *myField2; - FIELD<int> myFieldAsso = (*myField1)+(*myField2)*(*myField2); - FIELD<int>* myFieldadd = FIELD<int>::add(*myField1, *myField2); - FIELD<int>* myFieldsub = FIELD<int>::sub(*myField1, *myField2); - FIELD<int>* myFieldmul = FIELD<int>::mul(*myField1, *myField2); - FIELD<int>* myFielddiv = FIELD<int>::div(*myField1, *myField2); - FIELD<int>* myFieldDot = FIELD<int>::scalarProduct(*myField1, *myField2); - - std::cout << endl << string(60,'-') << endl << "f1+f2 :" << endl << endl; - affiche_fieldT(&myFieldPlus, myFieldPlus.getSupport()); - std::cout << endl << string(60,'-') << endl << "add(f1,f2) :" << endl << endl; - affiche_fieldT(myFieldadd, myFieldadd->getSupport()); - std::cout << endl << string(60,'-') << endl << "scalarProduct(f1,f2) :" << endl << endl; - affiche_fieldT(myFieldDot, myFieldDot->getSupport()); - std::cout << endl << string(60,'-') << endl << " - f1 :" << endl << endl; - affiche_fieldT(&myFieldNeg, myFieldNeg.getSupport()); - - int size=myFieldPlus.getNumberOfValues()*myFieldPlus.getNumberOfComponents(); - - std::cout << endl << string(60,'-') << endl << "Tests opérations :" << endl << endl; - affiche_valeur_field(" f1 :", size, *myField1); - affiche_valeur_field(" f2 :", size, *myField2); - std::cout << endl << " " << string(4*size,'-'); - - affiche_valeur_field(" + :", size, myFieldPlus); - affiche_valeur_field(" add :", size, *myFieldadd); - affiche_valeur_field(" - :", size, myFieldMoins); - affiche_valeur_field(" sub :", size, *myFieldsub); - affiche_valeur_field(" * :", size, myFieldFois); - affiche_valeur_field(" mul :", size, *myFieldmul); - affiche_valeur_field(" / :", size, myFieldDiv); - affiche_valeur_field(" div :", size, *myFielddiv); - affiche_valeur_field("f1+f2*f1:", size, myFieldAsso); - affiche_valeur_field(" - f1 :", size, myFieldNeg); - - // Test applyLin - std::cout << endl; - myField1->applyLin(1,1); - affiche_valeur_field(" f1+1 :", size, *myField1); - myField1->applyLin(1,-1); - affiche_valeur_field(" -> f1 :", size, *myField1); - - // Test applyFunc - std::cout << endl; - myField1->applyFunc<myfunction1>(); - affiche_valeur_field(" CB 2f1 :", size, *myField1); - myField1->applyFunc<myfunction2>(); - affiche_valeur_field(" -> f1 :", size, *myField1); - - // Test operateur += - std::cout << endl; - *myField1 += *myField2; - affiche_valeur_field(" f1+=f2 :", size, *myField1); - - // Test operateur *= - *myField1 *= *myField2; - affiche_valeur_field(" f1*=f2 :", size, *myField1); - - // Test operateur /= - *myField1 /= *myField2; - affiche_valeur_field(" f1/=f2 :", size, *myField1); - - // Test operateur -= - *myField1 -= *myField2; - affiche_valeur_field(" f1-=f2 :", size, *myField1); - - std::cout << endl << endl; - - - delete myFieldadd; - delete myFieldsub; - delete myFieldmul; - delete myFielddiv; - delete myFieldDot; -// delete myField1_vol; - - delete myField1; - delete myField2; - delete mySupport ; - delete myMesh ; - return 0; -} diff --git a/src/MEDMEM/test_porflow_driver.cxx b/src/MEDMEM/test_porflow_driver.cxx deleted file mode 100644 index e26b0ba6f..000000000 --- a/src/MEDMEM/test_porflow_driver.cxx +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -#include "MEDMEM_PorflowMeshDriver.hxx" -#include "MEDMEM_Mesh.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -int main (int argc, char ** argv) -{ - /* process the arguments */ - if (argc != 2) - { - cerr << "Usage : " << argv[0] - << " Porflowfilename" << endl << endl - << "-> lit le fichier Porflowfilename ,crée 2 fichiers : MED et VTK" << endl; - exit(-1); - } - - string porflowfilename = argv[1]; - - // Construction des noms de fichier - const string ext=".inp"; - string::size_type pos=porflowfilename.find(ext,0); - string basename (porflowfilename, 0, pos); // nom sans extension - string medfile=basename+".med"; // nom fichier med à creer - string vtkfile=basename+".vtk"; // nom fichier vtk à creer - string::size_type pos1=porflowfilename.rfind('/'); - string meshName (porflowfilename,pos1+1,pos-pos1-1); //get rid of directory & extension - cout << meshName << endl; - - // lecture du fichier porflow - MESH * myMesh= new MESH() ; - PORFLOW_MESH_RDONLY_DRIVER myPorflowMeshDriver(porflowfilename, myMesh) ; - myPorflowMeshDriver.open() ; - myPorflowMeshDriver.read() ; - myPorflowMeshDriver.close() ; - - cout << "Impression de MESH : " << endl; - cout << *myMesh; - - // creation d'un fichier med - cout << "creation d'un fichier med : " << endl; - int idMed = myMesh->addDriver(MED_DRIVER, medfile, meshName); - myMesh->write(idMed) ; - - // creation d'un fichier vtk - cout << "creation d'un fichier vtk : " << endl; - int idVtk = myMesh->addDriver(VTK_DRIVER, vtkfile, meshName); - myMesh->write(idVtk) ; - - - int SpaceDimension = myMesh->getSpaceDimension() ; - int MeshDimension = myMesh->getMeshDimension() ; - int NumberOfNodes = myMesh->getNumberOfNodes() ; - - cout << "Space Dimension : " << SpaceDimension << endl << endl ; - - cout << "Mesh Dimension : " << MeshDimension << endl << endl ; - - const double * Coordinates = myMesh->getCoordinates(MED_FULL_INTERLACE) ; - - cout << "Show Nodes Coordinates : " << endl ; - - cout << "Name :" << endl ; - const string * CoordinatesNames = myMesh->getCoordinatesNames() ; - for(int i=0; i<SpaceDimension ; i++) { - cout << " - " << CoordinatesNames[i] << endl ; - } - cout << "Unit :" << endl ; - const string * CoordinatesUnits = myMesh->getCoordinatesUnits() ; - for(int i=0; i<SpaceDimension ; i++) { - cout << " - " << CoordinatesUnits[i] << endl ; - } - for(int i=0; i<NumberOfNodes ; i++) { - cout << "Nodes " << i+1 << " : " ; - for (int j=0; j<SpaceDimension ; j++) - cout << Coordinates[i*SpaceDimension+j] << " " ; - cout << endl ; - } - - cout << "The END" << endl; - delete myMesh; - - // remontée du fichier med en mémoire - myMesh= new MESH(MED_DRIVER,medfile,meshName); - delete myMesh; - -} diff --git a/src/MEDMEM/test_profil_MedFieldDriver.cxx b/src/MEDMEM/test_profil_MedFieldDriver.cxx deleted file mode 100644 index 618cf1bf7..000000000 --- a/src/MEDMEM/test_profil_MedFieldDriver.cxx +++ /dev/null @@ -1,252 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// - -#include <stdlib.h> -#include<string> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_MedFieldDriver.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_define.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -void affiche_field_(FIELD_ * myField, const SUPPORT * mySupport) -{ - cout << "Field "<< myField->getName() << " : " <<myField->getDescription() << endl ; - int NumberOfComponents = myField->getNumberOfComponents() ; - cout << "- Nombre de composantes : "<< NumberOfComponents << endl ; - for (int i=1; i<NumberOfComponents+1; i++) { - cout << " - composante "<<i<<" :"<<endl ; - cout << " - nom : "<<myField->getComponentName(i)<< endl; - cout << " - description : "<<myField->getComponentDescription(i) << endl; - cout << " - units : "<<myField->getMEDComponentUnit(i) << endl; - } - cout << "- iteration :" << endl ; - cout << " - numero : " << myField->getIterationNumber()<< endl ; - cout << " - ordre : " << myField->getOrderNumber()<< endl ; - cout << " - temps : " << myField->getTime()<< endl ; - - cout << "- Type : " << myField->getValueType()<< endl; - - cout << "- Adresse support : " << mySupport << endl; -} - -template <class INTERLACING_TAG> -void affiche_fieldT(FIELD<double, INTERLACING_TAG> * myField, - const SUPPORT * mySupport) -{ - const double * value = 0; - const int * number = 0; - - affiche_field_((FIELD_ *) myField, mySupport); - - cout.setf(ios::fixed); - cout << "- Valeurs :"<<endl; - bool onAll = mySupport->isOnAllElements(); - int NumberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); - cout << "mySupport->getNumberOfElements(MED_ALL_ELEMENTS)" << NumberOf << endl; - int NumberOfComponents = myField->getNumberOfComponents() ; - cout << "myField->getNumberOfComponents()" << NumberOfComponents << endl; - if (!onAll) number = mySupport->getNumber(MED_ALL_ELEMENTS); - - if ( myField->getInterlacingType() == MED_EN::MED_FULL_INTERLACE ) { - for (int i=1; i<NumberOf+1; i++) { - if (onAll) - value = myField->getRow(i) ; - else - value = myField->getRow(number[i-1]); - for (int j=0; j<NumberOfComponents; j++) - cout << value[j]<< " "; - cout<<endl; - } - } - else { - for (int j=1; j<NumberOfComponents+1; j++) { - value = myField->getColumn(j) ; - for (int i=0; i<NumberOf; i++) - cout << value[i]<< " "; - cout<<endl; - } - } -} - -int main (int argc, char ** argv) { - - if ((argc !=3) && (argc != 5)) { - cerr << "Usage : " << argv[0] - << " filename fieldName [iterationNumber] [orderNumber]" << endl << endl; - exit(-1); - } - - string fileName = argv[1] ; - string fieldName = argv[2] ; - int iterationNumber=-1,orderNumber=-1; - if ( argv[3] ) iterationNumber = atoi(argv[3]); - if ( argv[4] ) orderNumber = atoi(argv[4]); - - string meshName=""; //"MAILTRQU"; - //goto mode3; - ///////////////////////////////////////////////////////////////////////////////////////// - // TEST PREMIER MODE : - // Le fichier MED lu contient le maillage associé au champ demandé (qui contient des profils ) - // Le driver du FIELD automatiquement crée est capable de lire les profils MEDFICHIER - // (le SUPPORT est crée automatiquement, le nom du maillage associé est disponible dans - // le SUPPORT mais la relation SUPPORT-MESH est non initialisée car le MESH n'est pas chargé). - // Le driver utilise les informations du maillage dans le fichier pour transcrire les profils - // de la numérotation locale MEDFICHIER à la numérotation globale MEDMEMOIRE). - // A l'écriture, il se repose également sur le maillage contenu dans le fichier - // pour effecuter la renumérotation. - { - FIELD<double> * myField1 = new FIELD<double>(MED_DRIVER,fileName,fieldName, - iterationNumber, orderNumber); - affiche_fieldT(myField1, myField1->getSupport()); - - // Pour éviter de modifier le fichier d'origine, - // on en crée une copie avec uniquement le maillage. - // Rem : Pour le test, le chargement du maillage n'est pas nécessaire - // On pourrait réécrire le Champ dans le fichier d'origine - // sous un autre nom. - // Attention si le driver MED_MESH modifie le nombre d'éléments d'un type géométrique : - // le calcul de renumérotation à l'écriture du champ risque d'être faux ! - meshName = myField1->getSupport()->getMeshName(); - MESH * myMesh = new MESH(MED_DRIVER,fileName,meshName); - MED_MESH_WRONLY_DRIVER myMeshDriver1("Copy_withmesh_"+fileName,myMesh); - int current=myMesh->addDriver(myMeshDriver1); - myMesh->write(current); - delete myMesh; - - // On ajoute un driver en écriture, comme la relation SUPPORT-MESH n'est pas - // initialisée, le driver doit trouver le maillage dans le fichier cible - // pour réaliser la transcription des profils MEDMEMOIRE à MEDFICHIER. - MED_FIELD_WRONLY_DRIVER<double> myFieldDriver2("Copy_withmesh_"+fileName,myField1) ; - current = myField1->addDriver(myFieldDriver2); - myField1->write(current); - delete myField1; - } - - mode2: - ///////////////////////////////////////////////////////////////////////////// - // TEST DEUXIEME MODE : - // Lecture idem 1er mode - // A l'écriture, le fichier cible ne contient pas le maillage mais la - // relation SUPPORT-MESH étant établie le driver utilise les informations - // dans le maillage en mémoire pour transcrire les profils. - // Selon le modèle MED FICHIER, ce mode est interdit : le fichier doit au moins - // contenir un lien sur le maillage (information pas encore exploitée dans MEDMEMOIRE - // : pas de gestion de montage/démontage des fichiers ) - // Attention si le driver MED_MESH modifie le nombre d'éléments d'un type géométrique : - // le calcul de renumérotation à l'écriture du champ risque d'être faux car les - // profils crées à la lecture son basés sur le nombre d'éléments par type géoémtrique - // du maillage contenu dans le fichier à la lecture. - // Une solution consisterait à prendre en compte le montage de fichiers distants - // et de prendre en compte la différence de nombre d'éléments par type géométrique - // entre le maillage MEDMEM et le maillage MEDFICHIER - // (Hum ! : Il serait plus simple que MEDMEMOIRE ne recalcule pas systématiquement - // ce que l'on ne lui demande pas, ce qui permettrait aussi de réécrire à l'identique - // un fichier que l'on vient de lire) - { - FIELD<double> * myField2 = new FIELD<double>(MED_DRIVER,fileName,fieldName, - iterationNumber, orderNumber); - - meshName = myField2->getSupport()->getMeshName(); - MESH * myMesh2 = new MESH(MED_DRIVER,fileName,meshName); - - const SUPPORT * mySupport2=myField2->getSupport(); - mySupport2->setMesh(myMesh2); - - // On ajoute un driver en écriture, comme la relation SUPPORT-MESH est - // initialisée, le driver utilise le maillage en mémoire - // pour réaliser la transcription des profils MEDMEMOIRE à MEDFICHIER. - MED_FIELD_WRONLY_DRIVER<double> myFieldDriver3("Copy_nomesh_"+fileName,myField2) ; - int current = myField2->addDriver(myFieldDriver3); - myField2->write(current); - - //Pour regarder le fichier produit avec MDUMP decommenter ces trois lignes - //car le fichier qui est produit n'est pas à la norme MED - //Il doit contenir soit le maillage associé soit un lien vers le maillage associé. - //MED_MESH_WRONLY_DRIVER myMeshDriver2("Copy_nomesh_"+fileName,myMesh2); - //current=myMesh2->addDriver(myMeshDriver2); - //myMesh2->write(current); - - delete myField2; - delete myMesh2; - - - } - mode3: - // TEST TROISIEME MODE : - // A la lecture, le fichier MED lu ne contient pas le maillage associé au champ demandé - // (mais un lien MEDFICHIER qui n'est pas exploité à ce jour). - // Cependant avant sa lecture le FIELD a été associé à un SUPPORT - // avec le lien au MESH préalablement chargé. - // Le driver du FIELD (automatiquement crée) est capable de lire les profils MEDFICHIER - // et utilise la relation SUPPORT-MESH initialisée pour transcrire les profils - // de la numérotation locale MEDFICHIER à la numérotation globale MEDMEMOIRE). - // REM: Une fois le champ chargé, il possède un nouveau support, le premier peut être libéré. - // En effet le driver du FIELD se fit uniquement au type géométriques définis dans le champ MEDFICHIER - // pour créer son SUPPORT car un SUPPORT crée "onAll" à partir d'un MESH repose sur tous - // les types géométriques du MESH ce qui n'est pas forcément le cas d'un champ MEDFICHIER - // (même sans profil) lu à posteriori. - { - med_2_3::med_err err=-1; - med_2_3::med_idt id = med_2_3::MEDouvrir(const_cast<char *> ( ("Copy_nomesh_"+fileName).c_str()), - med_2_3::MED_LECTURE_ECRITURE); - if (id <=0) cout << "Erreur dans MEDouvrir pour le fichier " << "Copy_nomesh_"+fileName <<endl; - - err=med_2_3::MEDlienEcr(id, const_cast<char *> ( ("Copy_withmesh_"+fileName).c_str()), - const_cast<char *> (meshName.c_str()) ); - if (err !=0) cout << "Erreur dans MEDlienEcr pour le maillage distant " << meshName - <<" contenu dans le fichier " << "Copy_withmesh_"+fileName <<endl; - - - err=med_2_3::MEDfermer(id); - - MESH * myMesh3 = new MESH(MED_DRIVER,fileName,meshName); - const SUPPORT * mySupport3= new SUPPORT(myMesh3,"Temporary Support",MED_CELL); - FIELD<double> * myField3 = new FIELD<double>(mySupport3,MED_DRIVER,"Copy_nomesh_"+fileName,fieldName, - iterationNumber, orderNumber); - delete mySupport3; // Il est déjà possible de libérer ce SUPPORT - - //TEST à la réecriture : - string cpy("__Copy"); - vector < string > pflNames = myField3->getSupport()->getProfilNames(); - for (int i=0; i< pflNames.size(); ++i) { - pflNames[i].resize(pflNames[i].size()-cpy.size()); - pflNames[i]+=cpy; - } - const_cast<SUPPORT*>(myField3->getSupport())->setProfilNames(pflNames); - MED_FIELD_WRONLY_DRIVER<double> myFieldDriver4("Copy_nomesh_"+fileName,myField3) ; - myFieldDriver4.setFieldName(myField3->getName()+"__Copy"); - int current = myField3->addDriver(myFieldDriver4); - myField3->write(current); - - delete myMesh3; - delete myField3; - - - //ESSAYER AVEC MAILLAGE DS FICHIER ET LIEN SUPORT-MESH PRESENTS SIMULTANEMENT - //EN VERSION COHERENTE ET NON COHERENTE - } -} diff --git a/src/MEDMEM/test_profil_gauss_MedFieldDriver.cxx b/src/MEDMEM/test_profil_gauss_MedFieldDriver.cxx deleted file mode 100644 index fc030688a..000000000 --- a/src/MEDMEM/test_profil_gauss_MedFieldDriver.cxx +++ /dev/null @@ -1,461 +0,0 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// - -#include <stdlib.h> -#include<string> - -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_Field.hxx" -#include "MEDMEM_MedFieldDriver.hxx" -#include "MEDMEM_Support.hxx" -#include "MEDMEM_define.hxx" -#include "MEDMEM_GaussLocalization.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -#define INTERLACING_MODE FullInterlace -int fct2(int i,const int * number) { return i;}; -int fct1(int i,const int * number) { return number[i]; }; - -void affiche_field_(FIELD_ * myField) -{ - cout << "Field "<< myField->getName() << " : " <<myField->getDescription() << endl ; - int NumberOfComponents = myField->getNumberOfComponents() ; - cout << "- Nombre de composantes : "<< NumberOfComponents << endl ; - for (int i=1; i<NumberOfComponents+1; i++) { - cout << " - composante "<<i<<" :"<<endl ; - cout << " - nom : "<<myField->getComponentName(i)<< endl; - cout << " - description : "<<myField->getComponentDescription(i) << endl; - cout << " - units : "<<myField->getMEDComponentUnit(i) << endl; - } - cout << "- iteration :" << endl ; - cout << " - numero : " << myField->getIterationNumber()<< endl ; - cout << " - ordre : " << myField->getOrderNumber()<< endl ; - cout << " - temps : " << myField->getTime()<< endl ; - - cout << "- Type : " << myField->getValueType()<< endl; - //PRESENCE DE POINTS DE GAUSS -} - -// Cas de traitement des valeurs sans spécificité concernant -// les points de Gauss ou les profils -// Pas de spécificité concernant le type géométrique -template <class INTERLACING_TAG> -void affiche_fieldT(FIELD<double,INTERLACING_TAG> * myField) -{ - const double * value = 0; - affiche_field_((FIELD_ *) myField); - - cout.setf(ios::fixed); - - int numberOf = myField->getNumberOfValues(); - int numberOfComponents = myField->getNumberOfComponents() ; - int valueLength = myField->getValueLength(); - int numberOfGeometricType = myField->getNumberOfGeometricTypes(); - const int * nbOfElements = myField->getNumberOfElements(); - const MED_EN::medGeometryElement * typeList = myField->getGeometricTypes(); - // Suivant le traitement, on peut faire sortir si il y a des points de Gauss - // ou des profils - - cout << "myField->getValueLength (MED_ALL_ELEMENTS) : " << valueLength << endl; - cout << "myField->getNumberOfElements (MED_ALL_ELEMENTS) : " << numberOf << endl; - cout << "myField->getNumberOfComponents () : " << numberOfComponents << endl; - cout << "myField->getNumberOfGeometricType () : " << numberOfGeometricType << endl; - for (int i=0; i < numberOfGeometricType; i++) { - cout << "Number Of Elements on type "<< MED_EN::geoNames[typeList[i]] - <<" : "<< nbOfElements[i] << endl; - cout << "Number Of Gauss Points on type "<< MED_EN::geoNames[typeList[i]] - <<" : "<< myField->getNumberOfGaussPoints(typeList[i]) << endl; - cout << "Localization description : " << endl << myField->getGaussLocalization(typeList[i]) << endl; - } - - cout << "- Valeurs :"<<endl; - for (int index=0; index < valueLength; index++) { - cout << "value["<<index<<"] = "<< value[index]; - cout<<endl; - } - -} - -// Spécialisation du traitement pour le mode FullInterlace -// Spécifité de traitement par rapport aux profils (utilisation du SUPPORT) -// Pas de spécificité concernant le type géométrique -// Pas de spécificité concernant les points de Gauss -template <> -void affiche_fieldT(FIELD<double, FullInterlace> * myField) -{ - const double * value = 0; - const int * number = 0; - - affiche_field_((FIELD_ *) myField); - const SUPPORT * mySupport=myField->getSupport(); - - cout.setf(ios::fixed); - - - int numberOfComponents = myField->getNumberOfComponents() ; - int valueLength = myField->getValueLength(); - const int * nbGaussPoints = myField->getNumberOfGaussPoints(); - - int numberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); - int numberOfGeometricType = mySupport->getNumberOfTypes(); - const int * nbOfElements = mySupport->getNumberOfElements(); - const MED_EN::medGeometryElement * typeList = mySupport->getTypes(); - bool onAll = mySupport->isOnAllElements(); - - cout << "mySupport->getValueLength (MED_ALL_ELEMENTS) : " << valueLength << endl; - cout << "mySupport->getNumberOfElements (MED_ALL_ELEMENTS) : " << numberOf << endl; - cout << "mySupport->getNumberOfComponents () : " << numberOfComponents << endl; - cout << "mySupport->getNumberOfGeometricType () : " << numberOfGeometricType << endl; - assert(numberOf == myField->getNumberOfValues() ); - - // S'il existe des profils, je récupère la liste des numéros d'éléments - // pour tous les types géométriques - for (int i=0; i < numberOfGeometricType; i++) { - cout << "Number Of Elements on type "<< MED_EN::geoNames[typeList[i]] - <<" : "<< nbOfElements[i] << endl; - cout << "Number Of Gauss Points on type "<< MED_EN::geoNames[typeList[i]] - <<" : "<< nbGaussPoints[i] << endl; - cout << "Localization description : " << endl << myField->getGaussLocalization(typeList[i]) << endl; - } - - // On récupère la liste complète - if (!onAll) number = mySupport->getNumber(MED_ALL_ELEMENTS); - - int elNo = -1; - cout << "- Valeurs :" << endl; - for (int i=1; i<=numberOf; i++) { - if (onAll) elNo = i; else elNo = number[i-1]; - //cout << endl << "myField->getRow("<<elNo<<") : "<< myField->getRow(elNo) << endl; - value = myField->getRow(elNo) ; - //UP: getRow prend un numéro d'élément qui existe, getRow(1) n'existe pas forcément si il y a un profil - //qui ne défini pas cet indice - //cout << endl << " Valeur de getNbGaussI("<<elNo<<") :" << myField->getNbGaussI(elNo) << endl; - for (int j=0; j<numberOfComponents*myField->getNbGaussI(elNo); j++) - //UP : Prend en compte le nombre de points de Gauss de l'élément elNo - cout << "value["<< elNo << "] = " << value[j] << " "; - cout<<endl; - } - -} - -// Spécialisation du traitement pour le mode NoInterlace -// Spécifité de traitement par rapport aux profils (utilisation du SUPPORT) -// Pas de spécificité concernant le type géométrique -// Pas de spécificité concernant les points de Gauss -template <> -void affiche_fieldT(FIELD<double, NoInterlace> * myField) -{ - const double * value = 0; - const int * number = 0; - - affiche_field_((FIELD_ *) myField); - const SUPPORT * mySupport=myField->getSupport(); - - cout.setf(ios::fixed); - - - int numberOfComponents = myField->getNumberOfComponents() ; - int valueLength = myField->getValueLength(); - const int * nbGaussPoints = myField->getNumberOfGaussPoints(); - - int numberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); - int numberOfGeometricType = mySupport->getNumberOfTypes(); - const int * nbOfElements = mySupport->getNumberOfElements(); - const MED_EN::medGeometryElement * typeList = mySupport->getTypes(); - bool onAll = mySupport->isOnAllElements(); - - cout << "mySupport->getValueLength (MED_ALL_ELEMENTS) : " << valueLength << endl; - cout << "mySupport->getNumberOfElements (MED_ALL_ELEMENTS) : " << numberOf << endl; - cout << "mySupport->getNumberOfComponents () : " << numberOfComponents << endl; - cout << "mySupport->getNumberOfGeometricType () : " << numberOfGeometricType << endl; - cout << "mySupport->getNumberOfElements(MED_ALL_ELEMENTS) : " << numberOf << endl; - assert(numberOf == myField->getNumberOfValues() ); - - // S'il existe des profils, je récupère la liste des numéros d'éléments - // pour tous les types géométriques - for (int i=0; i < numberOfGeometricType; i++) { - cout << "Number Of Elements on type "<< MED_EN::geoNames[typeList[i]] - <<" : "<< nbOfElements[i] << endl; - cout << "Number Of Gauss Points on type "<< MED_EN::geoNames[typeList[i]] - <<" : "<< nbGaussPoints[i] << endl; - cout << "Localization description : " << endl << myField->getGaussLocalization(typeList[i]) << endl; - } - - - int (* fct)(int,const int *); - - if (!onAll) { - number = mySupport->getNumber(MED_ALL_ELEMENTS); - fct=fct1; - } else - fct=fct2; - - int oneDimlength = valueLength/numberOfComponents; - for (int j=1; j<=numberOfComponents; j++) { - value = myField->getColumn(j) ; - for (int i=0; i<oneDimlength; i++) - cout << "value["<< fct(i,number) << ","<<j<<"]" << value[ fct(i,number) ] << " "; - cout<<endl; - } - -} - - -template <class T, class INTERLACING_TAG> -void affiche_fieldT2(FIELD< T, INTERLACING_TAG> * myField) -{}; - - -// Spécialisation du traitement pour le mode FullInterlace -// Spécifité de traitement par rapport aux profils (utilisation du SUPPORT) -// Spécificité concernant le type géométrique -// Spécificité concernant les points de Gauss -template <> -void affiche_fieldT2(FIELD<double, FullInterlace> * myField) -{ - const int * number = 0; - - affiche_field_((FIELD_ *) myField); - const SUPPORT * mySupport=myField->getSupport(); - - cout.setf(ios::fixed); - - - int numberOfComponents = myField->getNumberOfComponents() ; - int valueLength = myField->getValueLength(); - const int * nbGaussPoints = myField->getNumberOfGaussPoints(); - - int numberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); - int numberOfGeometricType = mySupport->getNumberOfTypes(); - const int * nbOfElements = mySupport->getNumberOfElements(); - const MED_EN::medGeometryElement * typeList = mySupport->getTypes(); - bool onAll = mySupport->isOnAllElements(); - - cout << "mySupport->getValueLength (MED_ALL_ELEMENTS) : " << valueLength << endl; - cout << "mySupport->getNumberOfElements (MED_ALL_ELEMENTS) : " << numberOf << endl; - cout << "mySupport->getNumberOfComponents () : " << numberOfComponents << endl; - cout << "mySupport->getNumberOfGeometricType () : " << numberOfGeometricType << endl; - cout << "mySupport->getNumberOfElements(MED_ALL_ELEMENTS) : " << numberOf << endl; - assert(numberOf == myField->getNumberOfValues() ); - - // S'il existe des profils, je récupère la liste des numéros d'éléments - // pour tous les types géométriques - for (int i=0; i < numberOfGeometricType; i++) { - cout << "Number Of Elements on type "<< MED_EN::geoNames[typeList[i]] - <<" : "<< nbOfElements[i] << endl; - cout << "Number Of Gauss Points on type "<< MED_EN::geoNames[typeList[i]] - <<" : "<< nbGaussPoints[i] << endl; - } - - - int (* fct)(int,const int *); - - if (!onAll) { - number = mySupport->getNumber(MED_ALL_ELEMENTS); - fct=fct1; - } else - fct=fct2; - - cout << "- Valeurs :"<<endl; - - int elemno = 1; - for (int ntyp=1; ntyp <= numberOfGeometricType; ntyp++ ) { - for (int i=0; i < nbOfElements[ntyp-1] ; i++ ) { - for (int k=1; k <= nbGaussPoints[ntyp-1]; k++) - for (int j=1; j <= numberOfComponents; j++) { - cout << " value["<< fct(elemno-1,number) << "," <<j<<","<<k<<"] = " - << myField->getValueIJK(fct(elemno-1,number),j,k); - } - elemno++; - cout << endl; - } - } - - assert((elemno-1) == numberOf); - -} - - -int main (int argc, char ** argv) { - - if ((argc !=3) && (argc != 5)) { - cerr << "Usage : " << argv[0] - << " filename fieldName [iterationNumber] [orderNumber]" << endl << endl; - exit(-1); - } - - string fileName = argv[1] ; - string fieldName = argv[2] ; - int iterationNumber=-1,orderNumber=-1; - if ( argv[3] ) iterationNumber = atoi(argv[3]); - if ( argv[4] ) orderNumber = atoi(argv[4]); - - string meshName="";//"MAILTRQU"; - //goto mode2; - ///////////////////////////////////////////////////////////////////////////////////////// - // TEST PREMIER MODE : - // Le fichier MED lu contient le maillage associé au champ demandé (qui contient des profils ) - // Le driver du FIELD automatiquement crée est capable de lire les profils MEDFICHIER - // (le SUPPORT est crée automatiquement, le nom du maillage associé est disponible dans - // le SUPPORT mais la relation SUPPORT-MESH est non initialisée car le MESH n'est pas chargé). - // Le driver utilise les informations du maillage dans le fichier pour transcrire les profils - // de la numérotation locale MEDFICHIER à la numérotation globale MEDMEMOIRE). - // A l'écriture, il se repose également sur le maillage contenu dans le fichier - // pour effecuter la renumérotation. - { - FIELD<double,INTERLACING_MODE> * myField1 = new FIELD<double,INTERLACING_MODE>(MED_DRIVER,fileName,fieldName, - iterationNumber, orderNumber); - affiche_fieldT(myField1); - cout << endl; - affiche_fieldT2(myField1); - - // Pour éviter de modifier le fichier d'origine, - // on en crée une copie avec uniquement le maillage. - // Rem : Pour le test, le chargement du maillage n'est pas nécessaire - // On pourrait réécrire le Champ dans le fichier d'origine - // sous un autre nom. - // Attention si le driver MED_MESH modifie le nombre d'éléments d'un type géométrique : - // le calcul de renumérotation à l'écriture du champ risque d'être faux ! - meshName = myField1->getSupport()->getMeshName(); - MESH * myMesh = new MESH(MED_DRIVER,fileName,meshName); - MED_MESH_WRONLY_DRIVER myMeshDriver1("Copy_withmesh_"+fileName,myMesh); - int current=myMesh->addDriver(myMeshDriver1); - myMesh->write(current); - delete myMesh; - - // On ajoute un driver en écriture, comme la relation SUPPORT-MESH n'est pas - // initialisée, le driver doit trouver le maillage dans le fichier cible - // pour réaliser la transcription des profils MEDMEMOIRE à MEDFICHIER. - MED_FIELD_WRONLY_DRIVER<double> myFieldDriver2("Copy_withmesh_"+fileName,myField1) ; - current = myField1->addDriver(myFieldDriver2); - myField1->write(current); - delete myField1; - } - - mode2: - ///////////////////////////////////////////////////////////////////////////// - // TEST DEUXIEME MODE : - // Lecture idem 1er mode - // A l'écriture, le fichier cible ne contient pas le maillage mais la - // relation SUPPORT-MESH est établie, le driver peut donc utiliser les informations - // dans le maillage pour transcrire les profils. - // Selon le modèle MED FICHIER, ce mode est interdit : le fichier doit au moins - // contenir un lien sur le maillage (information pas encore exploitée dans MEDMEMOIRE - // : pas de gestion de montage/démontage des fichiers ) - // Attention si le driver MED_MESH modifie le nombre d'éléments d'un type géométrique : - // le calcul de renumérotation à l'écriture du champ risque d'être faux car les - // profils crées à la lecture sont basés sur le nombre d'éléments par type géoémtrique - // du maillage contenu dans le fichier à la lecture. - // Une solution consisterait à prendre en compte le montage de fichiers distants - // et de prendre en compte la différence de nombre d'éléments par type géométrique - // entre le maillage MEDMEM et le maillage MEDFICHIER - // (Hum ! : Il serait plus simple que MEDMEMOIRE ne recalcule pas systématiquement - // ce que l'on ne lui demande pas, ce qui permettrait aussi de réécrire à l'identique - // un fichier que l'on vient de lire) - { - FIELD<double,INTERLACING_MODE> * myField2 = new FIELD<double,INTERLACING_MODE>(MED_DRIVER,fileName,fieldName, - iterationNumber, orderNumber); - - meshName = myField2->getSupport()->getMeshName(); - MESH * myMesh2 = new MESH(MED_DRIVER,fileName,meshName); - - const SUPPORT * mySupport2=myField2->getSupport(); - mySupport2->setMesh(myMesh2); - - // On ajoute un driver en écriture, comme la relation SUPPORT-MESH est - // initialisée, le driver utilise le maillage en mémoire - // pour réaliser la transcription des profils MEDMEMOIRE à MEDFICHIER. - MED_FIELD_WRONLY_DRIVER<double> myFieldDriver3("Copy_nomesh_"+fileName,myField2) ; - int current = myField2->addDriver(myFieldDriver3); - myField2->write(current); - - //Pour regarder le fichier produit avec MDUMP decommenter ces trois lignes - //car le fichier qui est produit n'est pas à la norme MED - //Il doit contenir soit le maillage associé soit un lien vers le maillage associé. - //MED_MESH_WRONLY_DRIVER myMeshDriver2("Copy_nomesh_"+fileName,myMesh2); - //current=myMesh2->addDriver(myMeshDriver2); - //myMesh2->write(current); - - delete myField2; - delete myMesh2; - - - } - mode3: - // TEST TROISIEME MODE : - // A la lecture, le fichier MED lu ne contient pas le maillage associé au champ demandé - // (mais un lien MEDFICHIER qui n'est pas exploité à ce jour). - // Cependant avant sa lecture le FIELD a été associé à un SUPPORT - // avec le lien au MESH préalablement chargé. - // Le driver du FIELD (automatiquement crée) est capable de lire les profils MEDFICHIER - // et utilise la relation SUPPORT-MESH initialisée pour transcrire les profils - // de la numérotation locale MEDFICHIER à la numérotation globale MEDMEMOIRE). - // REM: Une fois le champ chargé, il possède un nouveau support, le premier peut être libéré. - // En effet le driver du FIELD se fit uniquement au type géométriques définis dans le champ MEDFICHIER - // pour créer son SUPPORT car un SUPPORT crée "onAll" à partir d'un MESH repose sur tous - // les types géométriques du MESH ce qui n'est pas forcément le cas d'un champ MEDFICHIER - // (même sans profil) lu à posteriori. - { - med_2_3::med_err err=-1; - med_2_3::med_idt id = med_2_3::MEDouvrir(const_cast<char *> ( ("Copy_nomesh_"+fileName).c_str()), - med_2_3::MED_LECTURE_ECRITURE); - if (id <=0) cout << "Erreur dans MEDouvrir pour le fichier " << "Copy_nomesh_"+fileName <<endl; - - err=med_2_3::MEDlienEcr(id, const_cast<char *> ( ("Copy_withmesh_"+fileName).c_str()), - const_cast<char *> (meshName.c_str()) ); - if (err !=0) cout << "Erreur dans MEDlienEcr pour le maillage distant " << meshName - <<" contenu dans le fichier " << "Copy_withmesh_"+fileName <<endl; - - - err=med_2_3::MEDfermer(id); - - MESH * myMesh3 = new MESH(MED_DRIVER,fileName,meshName); - const SUPPORT * mySupport3= new SUPPORT(myMesh3,"Temporary Support",MED_CELL); - FIELD<double,INTERLACING_MODE> * myField3 = new FIELD<double,INTERLACING_MODE>(mySupport3,MED_DRIVER,"Copy_nomesh_"+fileName,fieldName, iterationNumber, orderNumber); - delete mySupport3; // Il est déjà possible de libérer ce SUPPORT - - //TEST à la réecriture (renommage des profils - // à cause de MEDprofilEcr qui ne prend pas en compte le mode - // MED_LECTURE_AJOUT) ): - string cpy("__Copy"); - vector < string > pflNames = myField3->getSupport()->getProfilNames(); - for (int i=0; i< pflNames.size(); ++i) { - pflNames[i].resize(pflNames[i].size()-cpy.size()); - pflNames[i]+=cpy; - } - const_cast<SUPPORT*>(myField3->getSupport())->setProfilNames(pflNames); - - MED_FIELD_WRONLY_DRIVER<double> myFieldDriver4("Copy_nomesh_"+fileName,myField3) ; - myFieldDriver4.setFieldName(myField3->getName()+"__Copy"); - int current = myField3->addDriver(myFieldDriver4); - myField3->write(current); - - delete myMesh3; - delete myField3; - - - //ESSAYER AVEC MAILLAGE DS FICHIER ET LIEN SUPORT-MESH PRESENTS SIMULTANEMENT - //EN VERSION COHERENTE ET NON COHERENTE - } -} diff --git a/src/MEDMEM/test_write_groups_poly.cxx b/src/MEDMEM/test_write_groups_poly.cxx deleted file mode 100644 index 5e97c0ab6..000000000 --- a/src/MEDMEM/test_write_groups_poly.cxx +++ /dev/null @@ -1,146 +0,0 @@ -#include "MEDMEM_Meshing.hxx" -#include "MEDMEM_Group.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -void addMedFacesGroup (MESHING& meshing, int nFaces, int *groupValue, string groupName) -{ - GROUP faces; - int myNumberOfElements[1]; - medGeometryElement mytypes[1]; - int index[2]; - faces.setName(groupName); - faces.setMesh(&meshing); - faces.setEntity(MED_EN::MED_FACE); - faces.setNumberOfGeometricType(1); - mytypes[0] = MED_EN::MED_POLYGON; - faces.setGeometricType(mytypes); - myNumberOfElements[0] = nFaces; - faces.setNumberOfElements(myNumberOfElements); - index[0] = 1; - index[1] = nFaces; - faces.setNumber(index, groupValue); - meshing.addGroup(faces); -} - -int main() -{ - MESHING *pmesh = new MESHING; - pmesh->setName( "C2MESH" ); - pmesh->setSpaceDimension(3); - pmesh->setNumberOfTypes(0, MED_EN::MED_CELL); - pmesh->setMeshDimension(3); - int nb_hexagone = 7; - int nbmailles_axiales = 2; - int nNodes = 6 * nb_hexagone * nbmailles_axiales; - // int nNodes=*max_element (connec, connec+6*nb_hexagone*nbmailles_axiales); - pmesh->setNumberOfNodes(nNodes); - - double coord[] = { - 44.401823743922364, 0 , 0, 55.698259110886582, 6.5220000000000002, 0, - 55.698259110886582, 19.566000000000003, 0, 44.401823743922364, 26.088000000000001, 0, - 33.105388376958146, 19.566000000000003, 0, 33.105388376958146, 6.5220000000000002, 0, - 66.9946944778508 , 0 , 0, 78.291129844815018, 6.5220000000000002, 0, - 78.291129844815018, 19.566000000000003, 0, 66.9946944778508 , 26.088000000000001, 0, - 55.698259110886582, 19.566000000000003, 0, 55.698259110886582, 6.5220000000000002, 0, - 33.105388376958146, 19.565999999999999, 0, 44.401823743922364, 26.088000000000001, 0, - 44.401823743922364, 39.131999999999998, 0, 33.105388376958146, 45.653999999999996, 0, - 21.808953009993928, 39.131999999999998, 0, 21.808953009993928, 26.088000000000001, 0, - 55.698259110886582, 19.565999999999999, 0, 66.9946944778508 , 26.088000000000001, 0, - 66.9946944778508 , 39.131999999999998, 0, 55.698259110886582, 45.653999999999996, 0, - 44.401823743922364, 39.131999999999998, 0, 44.401823743922364, 26.088000000000001, 0, - 78.291129844815018, 19.565999999999999, 0, 89.587565211779236, 26.088000000000001, 0, - 89.587565211779236, 39.131999999999998, 0, 78.291129844815018, 45.653999999999996, 0, - 66.9946944778508 , 39.131999999999998, 0, 66.9946944778508 , 26.088000000000001, 0, - 44.401823743922364, 39.132000000000005, 0, 55.698259110886582, 45.654000000000003, 0, - 55.698259110886582, 58.698 , 0, 44.401823743922364, 65.219999999999999, 0, - 33.105388376958146, 58.698 , 0, 33.105388376958146, 45.654000000000003, 0, - 66.9946944778508 , 39.132000000000005, 0, 78.291129844815018, 45.654000000000003, 0, - 78.291129844815018, 58.698 , 0, 66.9946944778508 , 65.219999999999999, 0, - 55.698259110886582, 58.698 , 0, 55.698259110886582, 45.654000000000003, 0, - 44.401823743922364, 0 , 1, 55.698259110886582, 6.5220000000000002, 1, - 55.698259110886582, 19.566000000000003, 1, 44.401823743922364, 26.088000000000001, 1, - 33.105388376958146, 19.566000000000003, 1, 33.105388376958146, 6.5220000000000002, 1, - 66.9946944778508 , 0 , 1, 78.291129844815018, 6.5220000000000002, 1, - 78.291129844815018, 19.566000000000003, 1, 66.9946944778508 , 26.088000000000001, 1, - 55.698259110886582, 19.566000000000003, 1, 55.698259110886582, 6.5220000000000002, 1, - 33.105388376958146, 19.565999999999999, 1, 44.401823743922364, 26.088000000000001, 1, - 44.401823743922364, 39.131999999999998, 1, 33.105388376958146, 45.653999999999996, 1, - 21.808953009993928, 39.131999999999998, 1, 21.808953009993928, 26.088000000000001, 1, - 55.698259110886582, 19.565999999999999, 1, 66.9946944778508 , 26.088000000000001, 1, - 66.9946944778508 , 39.131999999999998, 1, 55.698259110886582, 45.653999999999996, 1, - 44.401823743922364, 39.131999999999998, 1, 44.401823743922364, 26.088000000000001, 1, - 78.291129844815018, 19.565999999999999, 1, 89.587565211779236, 26.088000000000001, 1, - 89.587565211779236, 39.131999999999998, 1, 78.291129844815018, 45.653999999999996, 1, - 66.9946944778508 , 39.131999999999998, 1, 66.9946944778508 , 26.088000000000001, 1, - 44.401823743922364, 39.132000000000005, 1, 55.698259110886582, 45.654000000000003, 1, - 55.698259110886582, 58.698 , 1, 44.401823743922364, 65.219999999999999, 1, - 33.105388376958146, 58.698 , 1, 33.105388376958146, 45.654000000000003, 1, - 66.9946944778508 , 39.132000000000005, 1, 78.291129844815018, 45.654000000000003, 1, - 78.291129844815018, 58.698 , 1, 66.9946944778508 , 65.219999999999999, 1, - 55.698259110886582, 58.698 , 1, 55.698259110886582, 45.654000000000003, 1}; - - pmesh->setCoordinates(3, nNodes, coord, "CARTESIAN", MED_EN::MED_FULL_INTERLACE); - - string coordname[3] = { "x", "y", "z" }; - pmesh->setCoordinatesNames(coordname); - - // Set coordinates units - string coordunit[3] = { "cm", "cm", "cm" }; - pmesh->setCoordinatesUnits(coordunit); - - int polyHInd[] = {1, 9, 17, 25, 33, 41, 49, 57}; - int polyHFacesInd[] = {1 , 7 , 13 , 17 , 21 , 25 , 29 , 33 , - 37 , 43 , 49 , 53 , 57 , 61 , 65 , 69 , - 73 , 79 , 85 , 89 , 93 , 97 , 101, 105, - 109, 115, 121, 125, 129, 133, 137, 141, - 145, 151, 157, 161, 165, 169, 173, 177, - 181, 187, 193, 197, 201, 205, 209, 213, - 217, 223, 229, 233, 237, 241, 245, 249, 253}; - int polyHConn[] = { - 1,2,3,4,5,6, 43,44,45,46,47,48, 1,2,44,43, 2,3,45,44, - 3,4,46,45, 4,5,47,46, 5,6,48,47, 6,1,43,48, // #1 - 7,8,9,10,3,2, 49,50,51,52,45,44, 7,8,50,49, 8,9,51,50, - 9,10,52,51, 10,3,45,52, 3,2,44,45, 2,7,49,44, // #2 - 5,4,15,16,17,18, 47,46,57,58,59,60, 5,4,46,47, 4,15,57,46, - 15,16,58,57, 16,17,59,58, 17,18,60,59, 18,5,47,60, // #3 - 3,10,21,22,15,4, 45,52,63,64,57,46, 3,10,52,45, 10,21,63,52, - 21,22,64,63, 22,15,57,64, 15,4,46,57, 4,3,45,46, // #4 - 9,26,27,28,21,10, 51,68,69,70,63,52, 9,26,68,51, 26,27,69,68, - 27,28,70,69, 28,21,63,70, 21,10,52,63, 10,9,51,52, // #5 - 15,22,33,34,35,16, 57,64,75,76,77,58, 15,22,64,57, 22,33,75,64, - 33,34,76,75, 34,35,77,76, 35,16,58,77, 16,15,57,58, // #6 - 21,28,39,40,33,22, 63,70,81,82,75,64, 21,28,70,63, 28,39,81,70, - 39,40,82,81, 40,33,75,82, 33,22,64,75, 22,21,63,64}; // #7 - - pmesh->setPolyhedraConnectivity(polyHInd, polyHFacesInd, polyHConn, - nb_hexagone*(nbmailles_axiales-1), MED_EN::MED_CELL); - - int cpolygonsindex[] = {1, 7, 13, 19, 25, 31, 37, 43, 49, 55, 61, 67, 73, 79, 85}; - int connec[] = { - 1 , 2 , 3 , 4 , 5 , 6 , - 7 , 8 , 9 , 10, 3 , 2 , - 5 , 4 , 15, 16, 17, 18, - 3 , 10, 21, 22, 15, 4 , - 9 , 26, 27, 28, 21, 10, - 15, 22, 33, 34, 35, 16, - 21, 28, 39, 40, 33, 22, - 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 45, 44, - 47, 46, 57, 58, 59, 60, - 45, 52, 63, 64, 57, 46, - 51, 68, 69, 70, 63, 52, - 57, 64, 75, 76, 77, 58, - 63, 70, 81, 82, 75, 64}; - - pmesh->setNumberOfTypes(0, MED_EN::MED_FACE); - pmesh->setPolygonsConnectivity(cpolygonsindex, connec, nb_hexagone*nbmailles_axiales, MED_EN::MED_FACE); - - int bottom[] = {1, 2, 3, 4, 5, 6, 7}; - addMedFacesGroup(*pmesh, nb_hexagone, bottom, "BottomFaces"); - - int id = pmesh->addDriver(MED_DRIVER, "cronoshexa.med", pmesh->getName()); - pmesh->write(id); -} diff --git a/src/MEDMEM/tests/readCoordinate.cxx b/src/MEDMEM/tests/readCoordinate.cxx deleted file mode 100755 index 49cbb8c79..000000000 --- a/src/MEDMEM/tests/readCoordinate.cxx +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -// -// -// File : readCoordinate.cxx -// Module : MED - -#include<string> -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_define.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_MedMeshDriver.hxx" - -using namespace std; -using namespace MEDMEM; - -#define MED_TAILLE_PNOM 16 - -void usage(char * name) -{ - cout << " " << name <<" <file name>"<< " <mesh name> " << " <interlace mode>" << endl; - cout << " " << "displays all Nodes Coordinates in mdump mode" << endl; - cout << endl; - cout << " " << "mesh name is mandatory. Try mdump if necessary" << endl; - cout << " " << "values for interlace mode are : " << endl; - cout << " " << "MED_FULL_INTERLACE (default value) or MED_NO_INTERLACE" << endl; - exit(-1); -} - -int main (int argc, char ** argv) { - - if (argc < 3) usage(argv[0]); - if (argc > 4) usage(argv[0]); - - string fileName = argv[1]; - string meshName = argv[2]; - - MED_EN::medModeSwitch Mode = MED_EN::MED_FULL_INTERLACE; - if (argc==4) - { - string comp=argv[3]; - if ( comp == "MED_NO_INTERLACE" ) Mode = MED_EN::MED_NO_INTERLACE; - else if ( comp != "MED_FULL_INTERLACE") usage(argv[0]); - } - - - MESH * myMesh= new MESH() ; - myMesh->setName(meshName); - MED_MESH_RDONLY_DRIVER myMeshDriver(fileName,myMesh); - try - { - myMeshDriver.setMeshName(meshName); - myMeshDriver.open(); - } - catch (const exception & ex) - { - MESSAGE("Catch Exception : "); - SCRUTE(ex.what()); - }; - MESSAGE("Open done"); - - try - { - myMeshDriver.read(); - } - catch (const exception & ex) - { - MESSAGE("Catch Exception : "); - SCRUTE(ex.what()); - }; - MESSAGE("Read done"); - - int SpaceDimension = myMesh->getSpaceDimension() ; - int MeshDimension = myMesh->getMeshDimension() ; - int NumberOfNodes = myMesh->getNumberOfNodes() ; - - cout << "(************************)"<<endl; - cout << "(* NOEUDS DU MAILLAGE : *)"<<endl; - cout << "(************************)"<<endl; - - string typeRepere = myMesh->getCoordinatesSystem(); - if ( typeRepere.size() == 0 ) typeRepere ="0"; - cout << "- Type de repere des coordonnees : " << typeRepere << endl; - - string chainevide(MED_TAILLE_PNOM+2,' '); - cout << "- Nom des coordonnees : " << endl ; - const string * CoordinatesNames = myMesh->getCoordinatesNames() ; - for (int i=0; i < SpaceDimension ; i++) - { - string bonnelongueur=chainevide; - bonnelongueur.replace(1,CoordinatesNames[i].size(),CoordinatesNames[i]); - cout << bonnelongueur; - } - cout <<endl; - - cout << "- Unites des coordonnees : " << endl ; - const string * CoordinatesUnits = myMesh->getCoordinatesUnits() ; - for ( int i=0; i < SpaceDimension ; i++) - { - string bonnelongueur=chainevide; - bonnelongueur.replace(1,CoordinatesUnits[i].size(),CoordinatesUnits[i]); - cout << bonnelongueur; - } - cout <<endl; - - const double * Coordinates = myMesh->getCoordinates(Mode) ; - cout << "- Coordonnees des noeuds : " << endl; - for (int i=0; i < SpaceDimension*NumberOfNodes; i++) - { - fprintf(stdout," %f ",Coordinates[i]); - } - cout <<endl; - - delete myMesh; - -} diff --git a/src/MEDMEM/tests/readEntete.cxx b/src/MEDMEM/tests/readEntete.cxx deleted file mode 100755 index e9a3503ae..000000000 --- a/src/MEDMEM/tests/readEntete.cxx +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -// -// -// File : readEntete.cxx -// Module : MED - -#include<string> -#include "MEDMEM_Exception.hxx" -#include "MEDMEM_define.hxx" -#include "MEDMEM_Mesh.hxx" -#include "MEDMEM_MedMeshDriver.hxx" -#include "MEDMEM_DriversDef.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -void usage(char * name) -{ - cout << " " << name <<" <file name>"<< " <mesh name> " << " <interlace mode>" << endl; - cout << " " << "displays all Nodes Coordinates in mdump mode" << endl; - cout << endl; - cout << " " << "mesh name is mandatory. Try mdump if necessary" << endl; - cout << " " << "values for interlace mode are : " << endl; - cout << " " << "MED_FULL_INTERLACE (default value) or MED_NO_INTERLACE" << endl; - exit(-1); -} - -int main (int argc, char ** argv) { - - if (argc < 3) usage(argv[0]); - if (argc > 4) usage(argv[0]); - - string fileName = argv[1]; - string meshName = argv[2]; - - medModeSwitch Mode = MED_FULL_INTERLACE; - if (argc==4) - { - string comp=argv[3]; - if ( comp == "MED_NO_INTERLACE" ) Mode = MED_NO_INTERLACE; - else if ( comp != "MED_FULL_INTERLACE") usage(argv[0]); - } - - - MESH * myMesh= new MESH() ; - myMesh->setName(meshName); - MED_MESH_RDONLY_DRIVER myMeshDriver(fileName,myMesh); - try - { - myMeshDriver.setMeshName(meshName); - myMeshDriver.open(); - } - catch (const exception & ex) - { - MESSAGE("Catch Exception : "); - SCRUTE(ex.what()); - }; - MESSAGE("Open done"); - - try - { - myMeshDriver.read(); - } - catch (const exception & ex) - { - MESSAGE("Catch Exception : "); - SCRUTE(ex.what()); - }; - MESSAGE("Read done"); - - int SpaceDimension = myMesh->getSpaceDimension(); - int MeshDimension = myMesh->getMeshDimension(); - int NumberOfNodes = myMesh->getNumberOfNodes(); - - cout << "(****************************)" << endl; - cout << "(* INFORMATIONS GENERALES : *)" << endl; - cout << "(****************************)" << endl; - - // string chainevide(MED_TAILLE_PNOM+2,' '); - cout << "- Nom du maillage : <<" << meshName << ">>" << endl; - cout << "- Dimension d'espace : "<< SpaceDimension << endl; - cout << "- Dimension du maillage : "<< MeshDimension << endl; - cout << "- Pas de nom universel " << endl ; - cout << "- Nombre de noeuds : " << NumberOfNodes << " " << endl; - - int NumberOfTypes = myMesh->getNumberOfTypes(MED_CELL); - const medGeometryElement * Types; - - cout << "- Nombre de Type de mailles : " << NumberOfTypes << endl; - - if (NumberOfTypes > 0) - { - Types = myMesh->getTypes(MED_CELL); - - cout << " Types : "; - for (int itype=0; itype<NumberOfTypes; itype++) cout << Types[itype] << " "; - cout << endl; - - const list<medGeometryElement> currentEntity = meshEntities[MED_CELL]; - list<medGeometryElement>::const_iterator currentGeometry; - - for (currentGeometry = currentEntity.begin(); - currentGeometry != currentEntity.end(); - currentGeometry++) - { - cout << "- Nombre de mailles de type "; - cout << geoNames[(*currentGeometry)] << " : "; - cout << myMesh->getNumberOfElements(MED_CELL,(MED_EN::medGeometryElement)(*currentGeometry)); - cout << " " << endl; - } - } - - NumberOfTypes = myMesh->getNumberOfTypes(MED_FACE); - - cout << "- Nombre de Type de faces : " << NumberOfTypes << endl; - - if (NumberOfTypes > 0) - { - Types = myMesh->getTypes(MED_FACE); - - cout << " Types : "; - for (int itype=0; itype<NumberOfTypes; itype++) cout << Types[itype] << " "; - cout << endl; - - const list<medGeometryElement> currentEntity2 = meshEntities[MED_FACE]; - list<medGeometryElement>::const_iterator currentGeometry; - - for (currentGeometry = currentEntity2.begin(); - currentGeometry != currentEntity2.end(); - currentGeometry++) - { - cout << "- Nombre de faces de type "; - cout << geoNames[(*currentGeometry)] << " : "; - cout << myMesh->getNumberOfElements(MED_FACE,(*currentGeometry)); - cout << " " << endl; - } - } - - NumberOfTypes = myMesh->getNumberOfTypes(MED_EDGE); - - cout << "- Nombre de Type de aretes : " << NumberOfTypes << endl; - - if (NumberOfTypes > 0) - { - Types = myMesh->getTypes(MED_EDGE); - - cout << " Types : "; - for (int itype=0; itype<NumberOfTypes; itype++) cout << Types[itype] << " "; - cout << endl; - - const list<medGeometryElement> currentEntity3 = meshEntities[MED_EDGE]; - list<medGeometryElement>::const_iterator currentGeometry; - - for (currentGeometry = currentEntity3.begin(); - currentGeometry != currentEntity3.end(); - currentGeometry++) - { - cout << "- Nombre d'aretes de type "; - cout << geoNames[(*currentGeometry)] << " : "; - cout << myMesh->getNumberOfElements(MED_EDGE,(*currentGeometry)); - cout << " " << endl; - } - } - - delete myMesh; -} diff --git a/src/MEDMEM/tests/testUArray.cxx b/src/MEDMEM/tests/testUArray.cxx deleted file mode 100755 index f857ead43..000000000 --- a/src/MEDMEM/tests/testUArray.cxx +++ /dev/null @@ -1,349 +0,0 @@ -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -// -// -// File : testUArray.cxx -// Module : MED - -#include <cstdlib> // pour l'acces à EXIT_SUCCESS et EXIT_FAILURE -#include "MEDMEM_Utilities.hxx" -#include "MEDMEM_Array.hxx" - -using namespace std; -using namespace MEDMEM; - -void imprime(string titre,const int * myValues,const int * myOthers, int lignes, int colonnes) -{ - cout << " " <<titre << endl<< endl; - cout << "Full Interlace : " << endl; - if (myValues != NULL) - { - for (int i=0; i<lignes; i++) - { - cout << " - "; - for (int k=0; k< colonnes; k++) - { - cout << myValues[k + i * colonnes]<< " " ; - } - cout << endl; - } - } - else - { - cout << "Pointeur Null : pas de valeur" << endl << endl; - } - cout << endl; - cout << "No Interlace : " << endl; - - if (myOthers != NULL) - { - for (int k=0; k< colonnes; k++) - { - cout << " - "; - for (int i=0; i<lignes; i++) - { - cout << myOthers[i + k*lignes]<< " " ; - } - cout << endl; - } - } - else - { - cout << "Pointeur Null : pas de valeur" << endl << endl; - } - cout << endl; -} - -int main (int argc, char ** argv) -{ - - /* ---------------------------------------------------------- */ - /* */ - /* INITIALISATION */ - /* */ - /* - constructeur new MEDARRAY<int>(int,int,mode) */ - /* - get sur le pointeur MED_FULL_INTERLACE */ - /* - initialisation des valeurs (coordonnées ieme elt = I+1) */ - /* - get sur le pointeur MED_NO_INTERLACE */ - /* ---------------------------------------------------------- */ - - int SpaceDimension = 3; - int NumberOfNodes = 4; - - - - MEDARRAY<int> * myArrayfull= new MEDARRAY<int>(SpaceDimension,NumberOfNodes,MED_EN::MED_FULL_INTERLACE); - ASSERT(myArrayfull != NULL); - - const int * myValues = myArrayfull->get(MED_EN::MED_FULL_INTERLACE); - ASSERT(myValues!= NULL); - - for (int i=0; i<NumberOfNodes; i++) - { - for (int k=0; k<SpaceDimension; k++) - { - //myValues[i* SpaceDimension +k]=i + 1; - myArrayfull->setIJ(i+1,k+1,i+1) ; - } - } - - const int * myOthers = myArrayfull->get(MED_EN::MED_NO_INTERLACE) ; - ASSERT(myOthers != NULL); - - imprime("Initialisation full interlace (xi=yi=zi=i+1)",myValues,myOthers,NumberOfNodes,SpaceDimension); - - MEDARRAY<int> * myArrayno= new MEDARRAY<int>(SpaceDimension,NumberOfNodes,MED_EN::MED_NO_INTERLACE); - ASSERT(myArrayno != NULL); - const int * myValuesno = myArrayno->get(MED_EN::MED_NO_INTERLACE); - ASSERT(myValuesno!= NULL); - - for (int k=0; k<SpaceDimension; k++) - { - for (int i=0; i<NumberOfNodes; i++) - { - //myValuesno[i +k*NumberOfNodes]=k + 1; - myArrayno->setIJ(i+1,k+1,k+1) ; - } - } - - const int * myOthersno = myArrayno->get(MED_EN::MED_FULL_INTERLACE) ; - ASSERT(myOthersno != NULL); - - imprime("Initialisation no interlace (xi=yi=zi=i+1)",myOthersno,myValuesno,NumberOfNodes,SpaceDimension); - - - /* ---------------------------------------------------------- */ - /* */ - /* Tests des Fonctions Set */ - /* */ - /* - setI sur l'element 1 avec des coordonnees a 100 */ - /* - setJ sur l'element 1 avec des coordonnees a 100 */ - /* - setIJ sur (1,2) avec une coordonnee = 1992 */ - /* - set avec l ensemble des coordonnes remises à i */ - /* ---------------------------------------------------------- */ - - - int * myNewLine = new int[SpaceDimension]; - for (int i = 0; i < SpaceDimension; i++) - myNewLine[i] = myValues[i] * 100; - try - { - myArrayfull->setI(1, myNewLine); - } - catch ( const std::exception &e ) - { - cout << "--------------" << endl; - cout << " Pb au setI " << endl; - cout << "--------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "---------------" << endl; - cout << " Pb au setI " << endl; - cout << "---------------" << endl; - } - - delete [] myNewLine; - imprime("1er element : coordonnees à 100",myValues,myOthers,NumberOfNodes,SpaceDimension); - - int * myNewCol = new int[NumberOfNodes]; - for (int i = 0; i < NumberOfNodes; i++) - myNewCol[i] = 100; - try - { - myArrayno->setJ(1, myNewCol); - } - catch ( const std::exception &e ) - { - cout << "--------------" << endl; - cout << " Pb au setJ " << endl; - cout << "--------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "---------------" << endl; - cout << " Pb au setJ " << endl; - cout << "---------------" << endl; - } - - delete [] myNewCol; - imprime("1eres coordonnees à 100",myOthersno,myValuesno,NumberOfNodes,SpaceDimension); - - try - { - myArrayfull->setIJ(1,2,1992); - } - catch ( const std::exception &e ) - { - cout << "---------------------------" << endl; - cout << " Pb au setIJ() de 1 , 2 " << endl; - cout << "---------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-----------------------------" << endl; - cout << " Pb au setIJ() de 1 , 2 " << endl; - cout << "-----------------------------" << endl; - } - - imprime("1er element : 2ieme coordonnee = 1992",myValues,myOthers,NumberOfNodes,SpaceDimension); - - - try - { - myArrayno->setIJ(1,2,1992); - } - catch ( const std::exception &e ) - { - cout << "---------------------------" << endl; - cout << " Pb au setIJ() de 1 , 2 " << endl; - cout << "---------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-----------------------------" << endl; - cout << " Pb au setIJ() de 1 , 2 " << endl; - cout << "-----------------------------" << endl; - } - - imprime("1er element : 2ieme coordonnee = 1992",myValues,myOthers,NumberOfNodes,SpaceDimension); - - int * mynewvalues= new int [ NumberOfNodes*SpaceDimension ]; - for (int i=0; i<NumberOfNodes*SpaceDimension; i++) - { - mynewvalues[i]=i; - } - try - { - myArrayfull->set(MED_EN::MED_FULL_INTERLACE,mynewvalues); - myValues = myArrayfull->get(MED_EN::MED_FULL_INTERLACE); - myOthers = myArrayfull->get(MED_EN::MED_NO_INTERLACE); - } - catch ( const std::exception &e ) - { - cout << "-------------" << endl; - cout << " Pb au set " << endl; - cout << "-------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "--------------" << endl; - cout << " Pb au set " << endl; - cout << "--------------" << endl; - } - imprime("remise valeur a i sur myArrayfull med full interlace",myValues,myOthers,NumberOfNodes,SpaceDimension); - - try - { - myArrayno->set(MED_EN::MED_FULL_INTERLACE,mynewvalues); - myValuesno = myArrayfull->get(MED_EN::MED_FULL_INTERLACE); - myOthersno = NULL; - } - catch ( const std::exception &e ) - { - cout << "-------------" << endl; - cout << " Pb au set " << endl; - cout << "-------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "--------------" << endl; - cout << " Pb au setI " << endl; - cout << "--------------" << endl; - } - imprime("set full interlace de myArrayno",myValuesno,myOthersno,NumberOfNodes,SpaceDimension); - - /* ---------------------------------------------------------- */ - /* */ - /* Tests des constructeurs */ - /* Tests des Fonctions Get */ - /* */ - /* */ - /* ---------------------------------------------------------- */ - - MEDARRAY<int> * myArrayShare = new MEDARRAY<int>( *myArrayfull); - const int * sharevalues = myArrayShare->get(MED_EN::MED_FULL_INTERLACE ); - const int * shareno = myArrayShare->get(MED_EN::MED_NO_INTERLACE); - imprime("test contructeur par recopie non profonde",sharevalues,shareno,NumberOfNodes,SpaceDimension); - - myArrayfull->setIJ(1,2,1992); - ASSERT(myArrayShare->getIJ(1,2) == 1992); - imprime("change valeur tableau source, impression tableau cible",sharevalues,shareno,NumberOfNodes,SpaceDimension); - - myArrayShare->setIJ(1,2,1995); - ASSERT(myArrayfull->getIJ(1,2) == 1995); - imprime("change valeur tableau cible, impression tableau source",myValues,myOthers,NumberOfNodes,SpaceDimension); - - delete myArrayShare; - imprime("tableau cible apres destruction tableau source",myValues,myOthers,NumberOfNodes,SpaceDimension); - - MEDARRAY<int> * myArrayShare2 = new MEDARRAY<int>( *myArrayfull,true); - sharevalues = myArrayShare2->get(MED_EN::MED_FULL_INTERLACE ); - shareno = myArrayShare2->get(MED_EN::MED_NO_INTERLACE ); - imprime("test contructeur par recopie profonde",sharevalues,shareno,NumberOfNodes,SpaceDimension); - - myArrayfull->setIJ(1,2,18); - imprime("change valeur tableau source, impression tableau cible",sharevalues,shareno,NumberOfNodes,SpaceDimension); - - myArrayShare2->setIJ(1,2,19); - imprime("change valeur tableau cible, impression tableau source",myValues,myOthers,NumberOfNodes,SpaceDimension); - - myArrayno->set(MED_EN::MED_NO_INTERLACE,mynewvalues); - myArrayno->setIJ(2,1,1); - myValuesno = myArrayno->get(MED_EN::MED_NO_INTERLACE); - myOthersno = myArrayno->get(MED_EN::MED_FULL_INTERLACE); - imprime("Initialisation no interlace (0...11)",myOthersno,myValuesno,NumberOfNodes,SpaceDimension); - - MEDARRAY<int> * myArrayShare3 = new MEDARRAY<int>( *myArrayno); - sharevalues = myArrayShare3->get(MED_EN::MED_FULL_INTERLACE); - shareno = myArrayShare3->get(MED_EN::MED_NO_INTERLACE); - imprime("test contructeur par recopie non profonde",sharevalues,shareno,NumberOfNodes,SpaceDimension); - - myArrayno->setIJ(1,2,1992); - ASSERT(myArrayShare3->getIJ(1,2) == 1992); - imprime("change valeur tableau source, impression tableau cible",sharevalues,shareno,NumberOfNodes,SpaceDimension); - - myArrayShare3->setIJ(1,2,1995); - ASSERT(myArrayno->getIJ(1,2) == 1995); - imprime("change valeur tableau cible, impression tableau source",myValuesno,myOthersno,NumberOfNodes,SpaceDimension); - - delete myArrayno; - delete [] mynewvalues; - delete myArrayfull; - delete myArrayShare2; - delete myArrayShare3; - MESSAGE("FIN NORMALE DU TRAITEMENT"); - return EXIT_SUCCESS ; -} -/* - inline medModeSwitch getMode() const ; -*/ diff --git a/src/MEDMEM/tests/testUArray.cxx.ok b/src/MEDMEM/tests/testUArray.cxx.ok deleted file mode 100755 index ec26ccafa..000000000 --- a/src/MEDMEM/tests/testUArray.cxx.ok +++ /dev/null @@ -1,313 +0,0 @@ -#include <cstdlib> // pour l'acces à EXIT_SUCCESS et EXIT_FAILURE -#include "MEDMEM_Utilities.hxx" -#include "MEDMEM_Array.hxx" -using namespace MEDMEM; - -int main (int argc, char ** argv) -{ - - int SpaceDimension = 3; - int NumberOfNodes = 4; - MEDARRAY<int> * myArray = new MEDARRAY<int>(SpaceDimension,NumberOfNodes,MED_FULL_INTERLACE) ; - ASSERT(myArray != NULL); - - int * value = myArray->get(MED_FULL_INTERLACE) ; - ASSERT(value!= NULL); - - for (int i=0; i<SpaceDimension*NumberOfNodes; i++) - value[i]=i ; - - int leadingValue; - try - { - leadingValue = myArray->getLeadingValue() ; - ASSERT (leadingValue == SpaceDimension); - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au getLeadingValue() " << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------------------" << endl; - cout << " Pb au getLeadingValue() " << endl; - cout << "-------------------------------" << endl; - return EXIT_FAILURE ; - } - - int lengthValue; - try - { - lengthValue = myArray->getLengthValue() ; - ASSERT(lengthValue == NumberOfNodes) - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au getLengthValue() " << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------------------" << endl; - cout << " Pb au getLengthValue() " << endl; - cout << "-------------------------------" << endl; - return EXIT_FAILURE ; - } - - cout << "Show all using getI and full interlace :" << endl; - for (int i=1; i<=lengthValue; i++) - { - try - { - int * node = myArray->getI(MED_FULL_INTERLACE,i) ; - cout << " - " ; - for (int j=0;j<leadingValue;j++) - cout << node[j] << " " ; - cout << endl ; - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au getI() valeur de i " << i << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------------------" << endl; - cout << " Pb au getI() valeur de i " << i << endl; - cout << "-------------------------------" << endl; - return EXIT_FAILURE ; - } - } - - cout << "Show all using getI and no interlace :" << endl; - for (int i=1; i<=leadingValue; i++) - { - try - { - int * node = myArray->getI(MED_NO_INTERLACE,i) ; - cout << " - " ; - for (int j=0;j<lengthValue;j++) - cout << node[j] << " " ; - cout << endl ; - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au getI() valeur de i " << i << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------------------" << endl; - cout << " Pb au getI() valeur de i " << i << endl; - cout << "-------------------------------" << endl; - return EXIT_FAILURE ; - } - } - - cout << "Show all using getIJ :" << endl; - for (int i=1; i<=lengthValue ; i++) - { - int j; - try - { - cout << " - " ; - for (j=1;j<leadingValue+1;j++) - cout << myArray->getIJ(i,j) << " " ; - cout << endl ; - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au getIJ() i " << i << " j " << j << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------------------" << endl; - cout << " Pb au getIJ() i " << i << " j " << j << endl; - cout << "-------------------------------" << endl; - return EXIT_FAILURE ; - } - } - - cout << "Show all using get and MED_NO_INTERLACE :" << endl; - try - { - int * NoInterlaceArray = myArray->get(MED_NO_INTERLACE) ; - for (int i=0; i<lengthValue ; i++) - { - cout << " - " ; - for (int j=0;j<leadingValue;j++) - cout << NoInterlaceArray[j*lengthValue+i] << " " ; - cout << endl ; - } - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au get " << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "---------------" << endl; - cout << " Pb au get " << endl; - cout << "---------------" << endl; - return EXIT_FAILURE ; - } - - - cout << endl << endl << "Tests des fonctions Set " << endl; - - int * myNewInt = new int[SpaceDimension*NumberOfNodes]; - for (int i=0; i<SpaceDimension*NumberOfNodes; i++) - { - myNewInt[i]=i*10 ; - } - - try - { - myArray->set(MED_FULL_INTERLACE, myNewInt); - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au set " << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "---------------" << endl; - cout << " Pb au set " << endl; - cout << "---------------" << endl; - return EXIT_FAILURE ; - } - delete [] myNewInt; - - cout << "Nouvelles valeurs (x10) : get avec Full interlace : " << endl; - int * myNewValue; - try - { - myNewValue = myArray->get(MED_FULL_INTERLACE) ; - ASSERT(myNewValue!= NULL); - } - catch ( const std::exception &e ) - { - cout << "-----------------" << endl; - cout << " Pb au get " << endl; - cout << "-----------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "---------------" << endl; - cout << " Pb au get " << endl; - cout << "---------------" << endl; - } - - cout << " - "; - for (int i=0; i<SpaceDimension*NumberOfNodes; i++) - cout << myNewValue[i]<< " " ; - cout << endl; - - - int * myNewLine = new int[SpaceDimension]; - for (int i = 0; i < SpaceDimension; i++) - myNewLine[i] = i * 100; - - try - { - myArray->setI(MED_FULL_INTERLACE, 1, myNewLine); - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au getLengthValue() " << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "---------------" << endl; - cout << " Pb au setI " << endl; - cout << "---------------" << endl; - } - delete [] myNewLine; - - try - { - myNewValue = myArray->getI(MED_FULL_INTERLACE,1) ; - ASSERT(myNewValue!= NULL); - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au getLengthValue() " << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "---------------" << endl; - cout << " Pb au getI " << endl; - cout << "---------------" << endl; - } - - cout << endl << " Nouvelles valeurs (x100) sur la 1ere ligne: get avec Full interlace : "; - cout << endl << " - "; - for (int i=0; i<SpaceDimension; i++) - cout << myNewValue[i]<< " " ; - cout << endl; - - try - { - myArray->setIJ(1,1,1992); - } - catch ( const std::exception &e ) - { - cout << "---------------------------" << endl; - cout << " Pb au setIJ() de 1 , 1 " << endl; - cout << "---------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-----------------------------" << endl; - cout << " Pb au setIJ() de 1 , 1 " << endl; - cout << "-----------------------------" << endl; - } - - cout << "Nouvelle valeur avec setIJ et getIJ" << endl; - cout << " - " << myArray->getIJ(1,1) << endl; - - delete myArray; - return EXIT_SUCCESS ; -} - -/* - inline medModeSwitch getMode() const ; - -*/ diff --git a/src/MEDMEM/tests/testUCellModel.cxx b/src/MEDMEM/tests/testUCellModel.cxx deleted file mode 100755 index a56637103..000000000 --- a/src/MEDMEM/tests/testUCellModel.cxx +++ /dev/null @@ -1,372 +0,0 @@ -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -// -// -// File : testUCellModel.cxx -// Module : MED - -#include <set> -#include <cstdlib> -#include "MEDMEM_Utilities.hxx" - -#include "MEDMEM_CellModel.hxx" -#include "MEDMEM_define.hxx" -#include "MEDMEM_DriversDef.hxx" - -using namespace std; -using namespace MEDMEM; -using namespace MED_EN; - -#define MED_NBR_GEOMETRIE_MAILLE 15 - -void usage(char * name) -{ - cout << " " << name << endl; -} - -int main (int argc, char ** argv) -{ - - if (argc < 1) usage(argv[0]); - - - cout << "CELLMODEL Test" << endl ; - cout << "--------------" << endl; - - /* ----------------------------------------------------- - Construction de tous les types de cellmodel possibles - ----------------------------------------------------- - */ - - CELLMODEL * tous =new CELLMODEL[MED_NBR_GEOMETRIE_MAILLE ]; - const medGeometryElement allCellType[MED_NBR_GEOMETRIE_MAILLE ]= - {MED_POINT1, MED_SEG2, MED_SEG3, MED_TRIA3, - MED_QUAD4, MED_TRIA6, MED_QUAD8, MED_TETRA4, - MED_PYRA5, MED_PENTA6, MED_HEXA8, MED_TETRA10, - MED_PYRA13, MED_PENTA15, MED_HEXA20 }; - - for (int i=0; i<MED_NBR_GEOMETRIE_MAILLE ; i++) - { - tous[i]=CELLMODEL(allCellType[i]); - } - - /* ----------------------------------------------------- - Boucle sur tous les types de cellmodel possibles - - Chaque Méthode de cellmodel est appelee - ----------------------------------------------------- - */ - for (int i=0; i<MED_NBR_GEOMETRIE_MAILLE ; i++) - { - cout << endl; - cout << geoNames[tous[i].getType()] << endl; - cout << "__________________" << endl; - - try - { - cout << "CellModel de Nom : " << tous[i].getName() << endl; - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au getName() " << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------------------" << endl; - cout << " Pb au getName() " << endl; - cout << "-------------------------------" << endl; - return EXIT_FAILURE ; - }; - - try - { - cout << "Nb de Vertexes : " << tous[i].getNumberOfVertexes() << endl; - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au getNumberOfVertexes() " << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "---------------------------------------" << endl; - cout << " Pb au getNumberOfVertexes() " << endl; - cout << "---------------------------------------" << endl; - return EXIT_FAILURE ; - }; - - try - { - cout << "Nb de Noeuds : " << tous[i].getNumberOfNodes() << endl; - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au getNumberOfNodes() " << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "---------------------------------" << endl; - cout << " Pb au getNumberOfNodes() " << endl; - cout << "---------------------------------" << endl; - return EXIT_FAILURE ; - }; - - int dimension; - try - { - dimension=tous[i].getDimension(); - cout << "Dimension : " << dimension << endl; - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au getDimension() " << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------------------" << endl; - cout << " Pb au getDimension() " << endl; - cout << "-------------------------------" << endl; - return EXIT_FAILURE ; - } - - for (int dim=1; dim< dimension; dim++) - { - int dim2=dimension - dim; - cout << "Nb d elements de dimension " << dim << " : "; - - try - { - cout << tous[i].getNumberOfConstituents(dim)<< endl; - } - catch ( const std::exception &e ) - { - cout << "------------------------------------" << endl; - cout << " Pb au getNumberOfConstituents() " << endl; - cout << "------------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "------------------------------------" << endl; - cout << " Pb au getNumberOfConstituents() " << endl; - cout << "------------------------------------" << endl; - return EXIT_FAILURE ; - }; - } -/* - - try - { - int** v1=tous[i].getConstituents(dim2); - if ( v1.size() != tous[i].getNumberOfConstituents(dim2) ) - { - cout << "----------------------------" << endl; - cout << " Pb au getConstituents() " << endl; - cout << "----------------------------" << endl; - } - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au getConstituents() " << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "----------------------------" << endl; - cout << " Pb au getConstituents() " << endl; - cout << "----------------------------" << endl; - return EXIT_FAILURE ; - }; - - cout << "Types de ces elements " << endl; - - set <medGeometryElement> setGeomElt; - medGeometryElement * vt; - int taille; - try - { - vt=tous[i].getConstituentsType(dim2); - taille=tous[i].getNumberOfConstituents(dim2); - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au getConstituentsType() " << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "--------------------------------" << endl; - cout << " Pb au getConstituentsType() " << endl; - cout << "--------------------------------" << endl; - return EXIT_FAILURE ; - }; - for (int k=0; k<taille;k++) - { - try - { - medGeometryElement me=tous[i].getConstituentType(dim2,k+1); - if ( vt[k] != me ) - { - cout << "-------------------------------" << endl; - cout << " Pb au getConstituentType() " << endl; - cout << "-------------------------------" << endl; - } - setGeomElt.insert(me); - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au getConstituentType() " << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "--------------------------------" << endl; - cout << " Pb au getConstituentsType() " << endl; - cout << "--------------------------------" << endl; - return EXIT_FAILURE ; - } - } -*/ -/* - set <medGeometryElement>::iterator iter_s; - for (iter_s=setGeomElt.begin() ;iter_s!=setGeomElt.end();iter_s++) - { - cout << geoNames[(*iter_s)] << endl; - } - - cout << "Impression des coordonnées du 1er Element de ce type" << endl; - try - { - vector<int> v2=tous[i].getNodesConstituent(dim2,1); - for (int k=0; k<v2.size();k++) - { - cout << v2[k] << " "; - try - { - int verif=tous[i].getNodeConstituent(dim2,1,k+1); - if ( v2[k] != verif) - { - cout << "-------------------------------" << endl; - cout << " Pb au getNodeConstituent() " << endl; - cout << "-------------------------------" << endl; - } - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au getNodeConstituent() " << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------------------" << endl; - cout << " Pb au getNodeConstituent() " << endl; - cout << "-------------------------------" << endl; - return EXIT_FAILURE ; - } - } - cout << endl; - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au getNodeConstituent() " << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "--------------------------------" << endl; - cout << " Pb au getNodeConstituent() " << endl; - cout << "--------------------------------" << endl; - return EXIT_FAILURE ; - } -*/ - - cout << endl; -/* - if ( dimension > 1 ) - { - try - { - cout << "Informations particulieres - dimension " << dimension - 1 << endl; - set <medGeometryElement>::iterator iter_s; - for (iter_s=tous[i].getAllConstituentsType().begin() ; - iter_s!=tous[i].getAllConstituentsType().end();iter_s++) - { - cout << geoNames[*iter_s] << endl; - } - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << " Pb au getAllConstituentsType() " << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "------------------------------------" << endl; - cout << " Pb au getAllConstituentsType() " << endl; - cout << "------------------------------------" << endl; - return EXIT_FAILURE ; - } - } -*/ - - } - - delete[] tous ; - - return EXIT_SUCCESS ; -/* - Reste a Tester - // Return number of constituents foreach type (which dimension is _dimension-1). - map <medGeometryElement,int> getNumberOfConstituentsForeachType() const; -*/ -} diff --git a/src/MEDMEM/tests/testUCoordinate.cxx b/src/MEDMEM/tests/testUCoordinate.cxx deleted file mode 100755 index f4bcc9c1b..000000000 --- a/src/MEDMEM/tests/testUCoordinate.cxx +++ /dev/null @@ -1,402 +0,0 @@ -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -// -// -// File : testUCoordinate.cxx -// Module : MED - -#include <cstdlib> -#include <cmath> -#include "MEDMEM_Utilities.hxx" - -#include "MEDMEM_define.hxx" -#include "MEDMEM_Array.hxx" -#include "MEDMEM_Coordinate.hxx" -#include <string> - -using namespace std; -using namespace MEDMEM; - -void usage(char * name) -{ - cout << " " << name << endl; -} - -int main (int argc, char ** argv) -{ - - - if (argc < 1) usage(argv[0]); - - const double pouieme = 0.009; - - cout << "COORDINATE Test" << endl; - cout << "---------------" << endl; - - int SpaceDim = 3; - int NbOfNodes = 5; - - string * noms = new string[3]; - noms[0]=" X "; - noms[1]=" Y "; - noms[2]=" Z "; - - string units[3]; - units[0]=" m "; - units[1]=" m "; - units[2]=" m "; - - int * numbers=new int[5]; - for (int i=0; i< 5; i++) numbers[i] =10+i; - - MED_EN::medModeSwitch ModeFull=MED_EN::MED_FULL_INTERLACE; - MED_EN::medModeSwitch ModeNo=MED_EN::MED_NO_INTERLACE; - double coor[15] = {0,0,0,0,0,1,0,1,0,1,0,0,0.5,0.5,0.5} ; - ASSERT(SpaceDim*NbOfNodes == 15); - - - cout << " - mode : MED_FULL_INTERLACE" << endl; - cout << " - dimension de l espace : " << SpaceDim << endl; - cout << " - nombre de noeuds : " << NbOfNodes << endl; - - double * coor1 = new double[SpaceDim*NbOfNodes]; - for( int k=0 ; k<SpaceDim*NbOfNodes ; k++ ) - coor1[k] = coor[k] ; - - MEDARRAY<double>* CoordinateArray = new MEDARRAY<double>(coor1,SpaceDim,NbOfNodes,ModeFull); - COORDINATE mycoo; - try - { - mycoo.setCoordinates(CoordinateArray); - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << "pb avec setCoordinates" << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------------------" << endl; - cout << "pb avec setCoordinates" << endl; - cout << "-------------------------------" << endl; - return EXIT_FAILURE ; - }; - - //--------------------------------------------------------------------// - // Tests des methodes // - // // - // - setCoordinatesNames // - // - setCoordinatesUnits // - // - setCoordinatesSystem // - // - setNodesNumbers // - // // - //--------------------------------------------------------------------// - try - { - mycoo.setCoordinatesNames(noms); - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << "pb avec setCoordinatesNames" << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------------------" << endl; - cout << "pb avec setCoordinatesNames" << endl; - cout << "-------------------------------" << endl; - return EXIT_FAILURE ; - }; - - try - { - mycoo.setCoordinatesUnits(units); - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << "pb avec setCoordinatesUnits" << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------------------" << endl; - cout << "pb avec setCoordinatesUnits" << endl; - cout << "-------------------------------" << endl; - return EXIT_FAILURE ; - }; - - try - { - mycoo.setCoordinatesSystem("cartesien"); - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << "pb avec setCoordinatesSystem" << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------------------" << endl; - cout << "pb avec setCoordinatesSystem" << endl; - cout << "-------------------------------" << endl; - return EXIT_FAILURE ; - }; - - try - { - mycoo.setNodesNumbers(numbers); - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << "pb avec setNodesNumbers" << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------------------" << endl; - cout << "pb avec setNodesNumbers" << endl; - cout << "-------------------------------" << endl; - return EXIT_FAILURE ; - }; - - //--------------------------------------------------------------------// - // Tests des methodes // - // // - // - getCoordinatesNames // - // - getCoordinatesUnits // - // - getCoordinatesUnit // - // - getCoordinatesSystem // - // - getNodesNumbers // - // // - //--------------------------------------------------------------------// - - cout << endl << " Relecture des Coordonnees" << endl << endl; - - try - { - cout << " Le systeme est : " << mycoo.getCoordinatesSystem() << endl; - } - catch ( const std::exception &e ) - { - cout << "-------------------------------" << endl; - cout << "pb avec getCoordinatesSystem" << endl; - cout << "-------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------------------" << endl; - cout << "pb avec getCoordinatesSystem" << endl; - cout << "-------------------------------" << endl; - return EXIT_FAILURE ; - }; - - const string * units2; - try - { - units2=mycoo.getCoordinatesUnits(); - for (int axe = 0; axe < SpaceDim; axe++) - { - try - { - string verif = mycoo.getCoordinateUnit(axe+1); - if (verif != units2[axe]) - cout << "Pb avec les noms des axes" << endl; - } - catch ( const std::exception &e ) - { - cout << "-------------------------" << endl; - cout << "pb avec getCoordinateUnit" << endl; - cout << "-------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------------" << endl; - cout << "pb avec getCoordinateUnit" << endl; - cout << "-------------------------" << endl; - return EXIT_FAILURE ; - }; - } - } - catch ( const std::exception &e ) - { - cout << "---------------------------" << endl; - cout << "pb avec getCoordinatesUnits" << endl; - cout << "---------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "---------------------------" << endl; - cout << "pb avec getCoordinatesUnits" << endl; - cout << "---------------------------" << endl; - return EXIT_FAILURE ; - }; - - const string * noms2; - try - { - noms2=mycoo.getCoordinatesNames(); - for (int axe = 0; axe < SpaceDim; axe++) - { - try - { - string verif = mycoo.getCoordinateName(axe+1); - if (verif != noms2[axe]) - cout << "Pb avec les noms des axes" << endl; - } - catch ( const std::exception &e ) - { - cout << "-------------------------" << endl; - cout << "pb avec getCoordinateName" << endl; - cout << "-------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------------" << endl; - cout << "pb avec getCoordinateName" << endl; - cout << "-------------------------" << endl; - return EXIT_FAILURE ; - }; - } - } - catch ( const std::exception &e ) - { - cout << "---------------------------" << endl; - cout << "pb avec getCoordinatesNames" << endl; - cout << "---------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "---------------------------" << endl; - cout << "pb avec getCoordinatesNames" << endl; - cout << "---------------------------" << endl; - return EXIT_FAILURE ; - }; - - - try - { - const double * coor2=mycoo.getCoordinates(ModeFull); - - for (int axe = 0; axe < SpaceDim; axe++) - { - - cout << "Coordonnees sur l'Axe : " << noms2[axe] ; - cout << " dont l unite est " << units2[axe] << endl; - - try - { - const double * coor3=mycoo.getCoordinateAxis(axe+1); - for (int num=0; num < NbOfNodes; num++) - { - try - { - const double d = mycoo.getCoordinate(num + 1,axe+1); - cout << d <<" , "; - ASSERT(fabs(d - coor3[num]) < pouieme); - ASSERT(fabs(d - coor2[(num * SpaceDim)+axe]) < pouieme); - ASSERT(fabs(d - coor [(num * SpaceDim)+axe]) < pouieme); - } - catch ( const std::exception &e ) - { - cout << "----------------------" << endl; - cout << "pb avec getCoordinates" << endl; - cout << "----------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "----------------------" << endl; - cout << "pb avec getCoordinates" << endl; - cout << "----------------------" << endl; - return EXIT_FAILURE ; - }; - } - cout << endl; - } - catch ( const std::exception &e ) - { - cout << "-------------------------" << endl; - cout << "pb avec getCoordinateAxis" << endl; - cout << "-------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------------" << endl; - cout << "pb avec getCoordinateAxis" << endl; - cout << "-------------------------" << endl; - return EXIT_FAILURE ; - } - } - } - catch ( const std::exception &e ) - { - cout << "----------------------" << endl; - cout << "pb avec getCoordinates" << endl; - cout << "----------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "----------------------" << endl; - cout << "pb avec getCoordinates" << endl; - cout << "----------------------" << endl; - return EXIT_FAILURE ; - }; - - - delete [] noms ; - delete [] numbers; - delete [] coor1; - - delete CoordinateArray ; - - MESSAGE("FIN normale du traitement"); - return EXIT_SUCCESS ; -} - diff --git a/src/MEDMEM/tests/testUGeoNameMeshEntities.cxx b/src/MEDMEM/tests/testUGeoNameMeshEntities.cxx deleted file mode 100755 index 2d1a0ae2b..000000000 --- a/src/MEDMEM/tests/testUGeoNameMeshEntities.cxx +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -// -// -// File : testUGeoNameMeshEntities.cxx -// Module : MED - -#include "MEDMEM_DriversDef.hxx" - -using namespace std; -void usage(char * name) -{ - cout << " " << name << endl; - cout << " " << "displays all avalaible geometry elements" << endl; - cout << " " << "display then all avalaible entities, and for each" << endl; - cout << " " << "all possible geomety element" << endl; - cout << endl; - exit(-1); -} - -int main (int argc, char ** argv) -{ - - if (argc < 1) usage(argv[0]); - - - cout << "GEO_NAME Test" << endl ; - cout << "-------------" << endl << endl; - MED_EN::GEO_NAME::const_iterator currentGeom; - for (currentGeom = MED_EN::geoNames.begin(); - currentGeom != MED_EN::geoNames.end(); - currentGeom++) - { - cout << (*currentGeom).second << endl; - }; - - MED_EN::MESH_ENTITIES::const_iterator currentEntity; - list<MED_EN::medGeometryElement>::const_iterator currentGeometry; - - cout << endl; - cout << "MESH_ENTITIES Test" << endl ; - cout << "------------------" << endl << endl; - for (currentEntity = MED_EN::meshEntities.begin(); - currentEntity != MED_EN::meshEntities.end(); - currentEntity++) - { - cout << (*((MED_EN::entNames).find((*currentEntity).first))).second <<endl; - for (currentGeometry = (*currentEntity).second.begin(); - currentGeometry != (*currentEntity).second.end(); - currentGeometry++) - { - cout << MED_EN::geoNames[(MED_EN::medGeometryElement)(*currentGeometry)] << endl; - } - cout << endl; - } - -} diff --git a/src/MEDMEM/tests/testUMedException.cxx b/src/MEDMEM/tests/testUMedException.cxx deleted file mode 100644 index c973999d3..000000000 --- a/src/MEDMEM/tests/testUMedException.cxx +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -// -// -// File : testUMedException.cxx -// Module : MED - -#include <cstdlib> -#include "MEDMEM_STRING.hxx" -#include "MEDMEM_Exception.hxx" - -using namespace std; -using namespace MEDMEM; - -int main (int argc, char ** argv) -{ - MEDEXCEPTION a = MEDEXCEPTION("test med exception"); - cout << a << endl;; - cout << a.what() << endl;; - - MEDEXCEPTION b(a); - cout << b << endl; - cout << b.what() << endl;; - - MEDEXCEPTION c("test med exception",argv[0],14); - cout << c << endl; - cout << c.what() << endl;; - - STRING msgErr; - msgErr << "ESSAI::ESSAI()! "<< 4 << "ieme essai "; - cout << MEDEXCEPTION (LOCALIZED(msgErr)).what() << endl ; - - const char * LOC = "toto" ; - cout << MEDEXCEPTION (LOCALIZED(STRING(LOC)<<" et titi")).what() << endl ; - - return EXIT_SUCCESS; - -}; diff --git a/src/MEDMEM/tests/testUModulusArray.cxx b/src/MEDMEM/tests/testUModulusArray.cxx deleted file mode 100644 index d24d44042..000000000 --- a/src/MEDMEM/tests/testUModulusArray.cxx +++ /dev/null @@ -1,426 +0,0 @@ -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -// -// -// File : testUModulusArray.cxx -// Module : MED - -#include <cstdlib> -#include <exception> -#include "MEDMEM_Utilities.hxx" -#include "MEDMEM_ModulusArray.hxx" -using namespace std; -using namespace MEDMEM; - -int main (int argc, char ** argv) -{ - - using namespace std ; - - int array[5]={0,1,2,1,4} ; - MEDMODULUSARRAY modulusArray(5,array); - - cout << " ModulusArray : " << endl; - cout << " _______________" << endl; - for(int i=-10;i<15;i++) - { - cout <<" - A[" << i <<"]="<<modulusArray[i]<<endl; - } - cout << endl; - - // ------------ - // test compare - // ------------ - - int ret ; - int array2[5]={1,4,0,1,2} ; - MEDMODULUSARRAY modulusArray2(5,array2) ; - - cout << " Test compare : mêmes tableaux mêmes ordres ..." << endl; - - try - { - ret=modulusArray2.compare(modulusArray); - } - catch ( const std::exception &e ) - { - cout << "-----------------" << endl; - cout << " pb avec compare " << endl; - cout << "-----------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-----------------" << endl; - cout << " pb avec compare " << endl; - cout << "-----------------" << endl; - return EXIT_FAILURE ; - } - - if (ret!=1) - { - cout << "-----------------------------------------------------" << endl; - cout << " pb avec compare entre modulusArray et modulusArray2 " << endl; - cout << " Les deux tableaux sont identiques " << endl; - cout << "-----------------------------------------------------" << endl; - return EXIT_FAILURE ; - } - else - { - cout << " compare entre modulusArray et modulusArray2 : OK" << endl; - cout << endl; - } - - int array3[5]={1,2,1,0,4} ; - MEDMODULUSARRAY modulusArray3(5,array3) ; - - cout << " Test compare : mêmes tableaux ordres inverses ..." << endl; - - try - { - ret=modulusArray3.compare(modulusArray); - } - catch (const std::exception &e ) - { - cout << "-----------------" << endl; - cout << " pb avec compare " << endl; - cout << "-----------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-----------------" << endl; - cout << " pb avec compare " << endl; - cout << "-----------------" << endl; - return EXIT_FAILURE ; - } - - if (ret!=-1) - { - cout << "-----------------------------------------------------" << endl; - cout << " pb avec compare entre modulusArray et modulusArray3 " << endl; - cout << " Les deux tableaux sont inverses " << endl; - cout << "-----------------------------------------------------" << endl; - return EXIT_FAILURE ; - } - else - { - cout << " compare entre modulusArray et modulusArray3 : OK" << endl; - cout << endl; - } - - int array4[6]={1,2,1,0} ; - MEDMODULUSARRAY modulusArray4(4,array4) ; - - cout << " Test compare : Tableaux de differentes tailles ... " << endl; - try - { - ret=modulusArray4.compare(modulusArray); - } - catch (const std::exception &e ) - { - cout << "-----------------" << endl; - cout << " pb avec compare " << endl; - cout << "-----------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-----------------" << endl; - cout << " pb avec compare " << endl; - cout << "-----------------" << endl; - return EXIT_FAILURE ; - } - - if (ret!=0) - { - cout << "-----------------------------------------------------" << endl; - cout << " pb avec compare entre modulusArray et modulusArray4 " << endl; - cout << " Les deux n ont pas la meme taille " << endl; - cout << "-----------------------------------------------------" << endl; - return EXIT_FAILURE ; - } - else - { - cout << " compare entre modulusArray et modulusArray4 : OK" << endl; - cout << endl; - } - - int array5[5]={1,2,1,0,1} ; - MEDMODULUSARRAY modulusArray5(5,array5) ; - cout << " Test compare : tableaux differents de même taille ..." << endl; - try - { - ret=modulusArray5.compare(modulusArray); - } - catch (const std::exception &e ) - { - cout << "-----------------" << endl; - cout << " pb avec compare " << endl; - cout << "-----------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-----------------" << endl; - cout << " pb avec compare " << endl; - cout << "-----------------" << endl; - return EXIT_FAILURE ; - } - - if (ret!=0) - { - cout << "-----------------------------------------------------" << endl; - cout << " pb avec compare entre modulusArray et modulusArray5 " << endl; - cout << " Les deux tableaux sont differents " << endl; - cout << "-----------------------------------------------------" << endl; - return EXIT_FAILURE ; - } - else - { - cout << " compare entre modulusArray et modulusArray5 : OK" << endl; - cout << endl; - } - - // test small array : - // taille 1 - int array6[1]={1} ; - MEDMODULUSARRAY modulusArray6(1,array6); - - cout << " ModulusArray 1 : " << endl; - cout << " __________________" << endl; - - for(int i=-10;i<15;i++) - { - cout <<" - A[" << i <<"]="<<modulusArray6[i]<<endl; - } - cout << endl; - - int array7[1]={1} ; - MEDMODULUSARRAY modulusArray7(1,array7); - - cout << " Test compare : mêmes tableaux mêmes ordres ..." << endl; - try - { - ret=modulusArray6.compare(modulusArray7); - } - catch ( const std::exception &e ) - { - cout << "-----------------" << endl; - cout << " pb avec compare " << endl; - cout << "-----------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-----------------" << endl; - cout << " pb avec compare " << endl; - cout << "-----------------" << endl; - return EXIT_FAILURE ; - } - - if (ret!=1) - { - cout << "-----------------------------------------------------" << endl; - cout << " pb avec compare entre modulusArray6 et modulusArray7" << endl; - cout << " Les deux tableaux sont identiques " << endl; - cout << "-----------------------------------------------------" << endl; - return EXIT_FAILURE ; - } - else - { - cout << " compare entre modulusArray6 et modulusArray7 : OK" << endl ; - cout << endl; - } - - int array8[1]={2} ; - MEDMODULUSARRAY modulusArray8(1,array8); - - cout << " Test compare : tableaux differents "<< endl; - try - { - ret=modulusArray6.compare(modulusArray8); - } - catch ( const std::exception &e ) - { - cout << "-----------------" << endl; - cout << " pb avec compare " << endl; - cout << "-----------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-----------------" << endl; - cout << " pb avec compare " << endl; - cout << "-----------------" << endl; - return EXIT_FAILURE ; - } - - if (ret!=0) - { - cout << "-----------------------------------------------------" << endl; - cout << " pb avec compare entre modulusArray6 et modulusArray8" << endl; - cout << " Les deux tableaux sont differents" << endl; - cout << "-----------------------------------------------------" << endl; - return EXIT_FAILURE ; - } - else - { - cout << " compare entre modulusArray6 et modulusArray8 : OK" << endl; - cout << endl; - } - - - // 2 - int array60[2]={1,2} ; - MEDMODULUSARRAY modulusArray60(2,array60); - - - cout << " ModulusArray 2 : " << endl; - cout << " __________________" << endl; - - for(int i=-10;i<15;i++) - { - cout <<" - A[" << i <<"]="<<modulusArray60[i]<<endl; - } - cout << endl; - - int array70[2]={1,2} ; - MEDMODULUSARRAY modulusArray70(2,array70); - cout << " Test compare : mêmes tableaux mêmes ordres ..." << endl; - - try - { - ret=modulusArray60.compare(modulusArray70); - } - catch ( const std::exception &e ) - { - cout << "-----------------" << endl; - cout << " pb avec compare " << endl; - cout << "-----------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-----------------" << endl; - cout << " pb avec compare " << endl; - cout << "-----------------" << endl; - return EXIT_FAILURE ; - } - - if (ret!=1) - { - cout << "--------------------------------------------------------" << endl; - cout << " pb avec compare entre modulusArray60 et modulusArray70 " << endl; - cout << " Les deux tableaux sont identiques " << endl; - cout << "--------------------------------------------------------" << endl; - return EXIT_FAILURE ; - } - else - { - cout << " compare entre modulusArray60 et modulusArray70 : OK" << endl; - cout << endl; - } - - int array80[2]={2,2} ; - MEDMODULUSARRAY modulusArray80(2,array80); - - cout << " Test compare : tableaux differents ..." << endl; - - try - { - ret=modulusArray60.compare(modulusArray80); - } - catch ( const std::exception &e ) - { - cout << "-----------------" << endl; - cout << " pb avec compare " << endl; - cout << "-----------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-----------------" << endl; - cout << " pb avec compare " << endl; - cout << "-----------------" << endl; - return EXIT_FAILURE ; - } - - if (ret!=0) - { - cout << "--------------------------------------------------------" << endl; - cout << " pb avec compare entre modulusArray60 et modulusArray80 " << endl; - cout << " Les deux tableaux sont differents " << endl; - cout << "--------------------------------------------------------" << endl; - return EXIT_FAILURE ; - } - else - { - cout << " compare entre modulusArray60 et modulusArray80 : OK" << endl; - cout << endl; - } - - int array90[2]={2,1} ; - MEDMODULUSARRAY modulusArray90(2,array90); - cout << " Test compare : tableaux differents ordres inverses ..." << endl; - try - { - ret=modulusArray60.compare(modulusArray90); - } - catch ( const std::exception &e ) - { - cout << "-----------------" << endl; - cout << " pb avec compare " << endl; - cout << "-----------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-----------------" << endl; - cout << " pb avec compare " << endl; - cout << "-----------------" << endl; - return EXIT_FAILURE ; - } - - if (ret!=-1) - { - cout << "--------------------------------------------------------" << endl; - cout << " pb avec compare entre modulusArray60 et modulusArray90 " << endl; - cout << " Les deux tableaux sont differents " << endl; - cout << "--------------------------------------------------------" << endl; - return EXIT_FAILURE ; - } - else - { - cout << " compare entre modulusArray60 et modulusArray90 : OK" << endl; - cout << endl; - } - - return EXIT_SUCCESS ; -} diff --git a/src/MEDMEM/tests/testUPointerOf.cxx b/src/MEDMEM/tests/testUPointerOf.cxx deleted file mode 100644 index da7f46312..000000000 --- a/src/MEDMEM/tests/testUPointerOf.cxx +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (C) 2003 CEA/DEN, EDF R&D -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -// File : testUPointerOf.cxx -// Module : MED - -#include "MEDMEM_Utilities.hxx" -#include "MEDMEM_PointerOf.hxx" -#include "MEDMEM_Exception.hxx" - -using namespace std; -using namespace MEDMEM; - - -int main (int argc, char ** argv) -{ - cout << "PointerOf Test" << endl ; - cout << "--------------" << endl; - - const int size=10; - PointerOf<int> P; - - // Creation d'un PointerOf de int - // et vérification de la methode set en essayant avec - // une taille nulle, négative puis positive - try - { - P.set(0); - ASSERT((int *)P == NULL); - } - catch ( const std::exception &e ) - { - cout << "-------------------------" << endl; - cout << " pb avec set(taille = 0) " << endl; - cout << "-------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - - try - { - P.set(-1 * size); - ASSERT((int *)P == NULL); - } - catch ( const std::exception &e ) - { - cout << "---------------------" << endl; - cout << " pb avec set(taille) " << endl; - cout << "---------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - - try - { - P.set(size); - ASSERT((int *)P != NULL); - } - catch ( const std::exception &e ) - { - cout << "---------------------" << endl; - cout << " pb avec set(taille) " << endl; - cout << "---------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - for (int i=0; i < size; i++) - { - P[i]=i; - } - - PointerOf<int> P2(10); - - P2=P; - for (int i=0; i < size; i++) - { - SCRUTE(P2[i]); - } - - int * p=new int [size]; - for (int i=0; i < size; i++) - { - p[i]=i*10; - } - - P2.set(p); - PointerOf<int> P3(p); - - for (int i=0; i < size; i++) - { - SCRUTE(P2[i]); - SCRUTE(P3[i]); - } - - const PointerOf<int> P4(p); - const PointerOf<int> P5(P4); - delete [] p; - -} diff --git a/src/MEDMEM/tests/testUSkyLineArray.cxx b/src/MEDMEM/tests/testUSkyLineArray.cxx deleted file mode 100644 index b4440ec86..000000000 --- a/src/MEDMEM/tests/testUSkyLineArray.cxx +++ /dev/null @@ -1,239 +0,0 @@ -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -// -// -// File : testUSkyLineArray.cxx -// Module : MED - -#include <cstdlib> -#include "MEDMEM_Utilities.hxx" -#include "MEDMEM_SkyLineArray.hxx" - -using namespace std; -using namespace MEDMEM; - -int main (int argc, char ** argv) -{ - - int NumberOfCell = 3 ; // 1 triangle,1 quadrangle,1 triangle - int Size = 10 ; // 10 nodes - - int * index = new int[NumberOfCell+1]; - index[0]=1; - index[1]=4; - index[2]=8; - index[3]=11; - - int * value = new int[Size]; - value[0]=1; // first - value[1]=2; - value[2]=5; - value[3]=2; // second - value[4]=3; - value[5]=5; - value[6]=6; - value[7]=3; // thirst - value[8]=4; - value[9]=6; - - MEDSKYLINEARRAY * myArray = new MEDSKYLINEARRAY(NumberOfCell,Size,index,value) ; - - const int * ArrayIndex ; - try - { - ArrayIndex = myArray->getIndex() ; - } - catch ( const std::exception &e ) - { - cout << "----------------" << endl; - cout << "pb avec getIndex" << endl; - cout << "----------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "----------------" << endl; - cout << "pb avec getIndex" << endl; - cout << "----------------" << endl; - return EXIT_FAILURE ; - } - - const int * ArrayValue ; - try - { - ArrayValue = myArray->getValue() ; - } - catch ( const std::exception &e ) - { - cout << "----------------" << endl; - cout << "pb avec getValue" << endl; - cout << "----------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "----------------" << endl; - cout << "pb avec getValue" << endl; - cout << "----------------" << endl; - return EXIT_FAILURE ; - } - - - try - { - ASSERT(myArray->getNumberOf()==NumberOfCell); - cout << myArray->getNumberOf() << endl; - } - catch ( const std::exception &e ) - { - cout << "-------------------" << endl; - cout << "pb avec getNumberOf" << endl; - cout << "-------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------" << endl; - cout << "pb avec getNumberOf" << endl; - cout << "-------------------" << endl; - return EXIT_FAILURE ; - } - - try - { - ASSERT(myArray->getLength()==Size); - cout << myArray->getLength() << endl; - } - catch ( const std::exception &e ) - { - cout << "-------------------" << endl; - cout << "pb avec getLength" << endl; - cout << "-------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------" << endl; - cout << "pb avec getLength" << endl; - cout << "-------------------" << endl; - return EXIT_FAILURE ; - } - - cout << "Show all :" << endl ; - for (int i=1; i< NumberOfCell+1 ; i++) - { - const int * cell; - try - { - cell = myArray->getI(i) ; - } - catch ( const std::exception &e ) - { - cout << "-----------------------------" << endl; - cout << "pb avec getI, valeur de i : " << i << endl; - cout << "-----------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------" << endl; - cout << "pb avec getI, valeur de i : " << i << endl; - cout << "-------------------" << endl; - return EXIT_FAILURE ; - } - - int numberof; - try - { - numberof= myArray->getNumberOfI(i) ; - ASSERT(numberof==index[i]-index[i-1]); - } - catch ( const std::exception &e ) - { - cout << "----------------------------------" << endl; - cout << "pb avec getNumberOfI, valeur de i : " << i << endl; - cout << "----------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "----------------------------------" << endl; - cout << "pb avec getNumberOfI, valeur de i : " << i << endl; - cout << "----------------------------------" << endl; - return EXIT_FAILURE ; - } - - cout << " - " ; - for (int j=0;j<numberof;j++) - { - cout << cell[j] << " " ; - try - { - int verif=myArray->getIJ(i,j+1); - if (verif != cell[j]) - { - cout << "----------------------------------" << endl; - cout << " incoherence dans les valeurs : " << endl; - cout << " cell[" << j << "] : " << cell[j] << endl; - cout << " getIJ(" << i <<"," << j << ") : " << verif << endl; - cout << "----------------------------------" << endl; - return EXIT_FAILURE ; - } - } - catch ( const std::exception &e ) - { - cout << "----------------------------------" << endl; - cout << "pb avec getIJ, valeurs de i / j : " << i << " " << j<< endl; - cout << "----------------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "----------------------------------" << endl; - cout << "pb avec getIJ, valeurs de i / j : " << i << " " << j<< endl; - cout << "----------------------------------" << endl; - return EXIT_FAILURE ; - } - } - cout << endl ; - } - - delete[] index ; - delete[] value ; - - delete myArray; - MESSAGE("FIN normale du traitement"); - return EXIT_SUCCESS ; - - -/* - MEDSKYLINEARRAY( const MEDSKYLINEARRAY &myArray ); - void setMEDSKYLINEARRAY( const med_int count, const med_int length, med_int* index , med_int* value ) ; - - -*/ -} diff --git a/src/MEDMEM/tests/testUUnit.cxx b/src/MEDMEM/tests/testUUnit.cxx deleted file mode 100755 index 97ec2f945..000000000 --- a/src/MEDMEM/tests/testUUnit.cxx +++ /dev/null @@ -1,402 +0,0 @@ -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// -// -// -// File : testUUnit.cxx -// Module : MED - -#include <cstdlib> -#include <exception> - -#include "MEDMEM_Unit.hxx" -using namespace std; -using namespace MEDMEM; - -int main (int argc, char ** argv) -{ - - cout << "UNIT Test" << endl ; - cout << "---------" << endl; - - UNIT testu; - try - { - testu.setName("ForTesting") ; - } - catch ( const std::exception &e ) - { - cout << "-----------------" << endl; - cout << " pb avec setName " << endl; - cout << "-----------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-----------------" << endl; - cout << " pb avec setName " << endl; - cout << "-----------------" << endl; - return EXIT_FAILURE ; - } - - try - { - testu.setDescription("all values are setted 10") ; - } - catch ( const std::exception &e ) - { - cout << "------------------------" << endl; - cout << " pb avec setDescription " << endl; - cout << "------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "------------------------" << endl; - cout << " pb avec setDescription " << endl; - cout << "------------------------" << endl; - return EXIT_FAILURE ; - } - - try - { - testu.setMasse(10); - } - catch ( const std::exception &e ) - { - cout << "------------------" << endl; - cout << " pb avec setMasse " << endl; - cout << "------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "------------------" << endl; - cout << " pb avec setMasse " << endl; - cout << "------------------" << endl; - return EXIT_FAILURE ; - } - - try - { - testu.setLength(10); - } - catch ( const std::exception &e ) - { - cout << "-------------------" << endl; - cout << " pb avec setLength " << endl; - cout << "-------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------" << endl; - cout << " pb avec setLength " << endl; - cout << "-------------------" << endl; - return EXIT_FAILURE ; - } - - try - { - testu.setTime(10); - } - catch ( const std::exception &e ) - { - cout << "-----------------" << endl; - cout << " pb avec setTime " << endl; - cout << "-----------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-----------------" << endl; - cout << " pb avec setTime " << endl; - cout << "-----------------" << endl; - return EXIT_FAILURE ; - } - - try - { - testu.setTemperature(10); - } - catch ( const std::exception &e ) - { - cout << "------------------------" << endl; - cout << " pb avec setTemperature " << endl; - cout << "------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "------------------------" << endl; - cout << " pb avec setTemperature " << endl; - cout << "------------------------" << endl; - return EXIT_FAILURE ; - } - - try - { - testu.setMatterQuantity(10); - } - catch ( const std::exception &e ) - { - cout << "---------------------------" << endl; - cout << " pb avec setMatterQuantity " << endl; - cout << "---------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "---------------------------" << endl; - cout << " pb avec setMatterQuantity " << endl; - cout << "---------------------------" << endl; - return EXIT_FAILURE ; - } - - try - { - testu.setCurrentStrength(10) ; - } - catch ( const std::exception &e ) - { - cout << "---------------------------" << endl; - cout << " pb avec setCurrentStrengt " << endl; - cout << "---------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "---------------------------" << endl; - cout << " pb avec setCurrentStrengt " << endl; - cout << "---------------------------" << endl; - return EXIT_FAILURE ; - } - - try - { - testu.setLightIntensity(10) ; - } - catch ( const std::exception &e ) - { - cout << "---------------------------" << endl; - cout << " pb avec setLightIntensity " << endl; - cout << "---------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "---------------------------" << endl; - cout << " pb avec setLightIntensity " << endl; - cout << "---------------------------" << endl; - return EXIT_FAILURE ; - } - - - try - { - cout << testu.getName() << endl ; - } - catch ( const std::exception &e ) - { - cout << "-----------------" << endl; - cout << " pb avec getName " << endl; - cout << "-----------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-----------------" << endl; - cout << " pb avec getName " << endl; - cout << "-----------------" << endl; - return EXIT_FAILURE ; - } - - try - { - cout << testu.getDescription() << endl ; - } - catch ( const std::exception &e ) - { - cout << "------------------------" << endl; - cout << " pb avec getDescription " << endl; - cout << "------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "------------------------" << endl; - cout << " pb avec getDescription " << endl; - cout << "------------------------" << endl; - return EXIT_FAILURE ; - } - - try - { - cout << testu.getMasse() << endl ; - } - catch ( const std::exception &e ) - { - cout << "------------------" << endl; - cout << " pb avec getMasse " << endl; - cout << "------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "------------------" << endl; - cout << " pb avec getMasse " << endl; - cout << "------------------" << endl; - return EXIT_FAILURE ; - } - - try - { - cout << testu.getLength() << endl ; - } - catch ( const std::exception &e ) - { - cout << "-------------------" << endl; - cout << " pb avec getLength " << endl; - cout << "-------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-------------------" << endl; - cout << " pb avec getLength " << endl; - cout << "-------------------" << endl; - return EXIT_FAILURE ; - } - - try - { - cout << testu.getTime() << endl ; - } - catch ( const std::exception &e ) - { - cout << "-----------------" << endl; - cout << " pb avec getTime " << endl; - cout << "-----------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "-----------------" << endl; - cout << " pb avec getTime " << endl; - cout << "-----------------" << endl; - return EXIT_FAILURE ; - } - - try - { - cout << testu.getTemperature() << endl ; - } - catch ( const std::exception &e ) - { - cout << "------------------------" << endl; - cout << " pb avec getTemperature " << endl; - cout << "------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "------------------------" << endl; - cout << " pb avec getTemperature " << endl; - cout << "------------------------" << endl; - return EXIT_FAILURE ; - } - - try - { - cout << testu.getMatterQuantity() << endl ; - } - catch ( const std::exception &e ) - { - cout << "---------------------------" << endl; - cout << " pb avec getMatterQuantity " << endl; - cout << "---------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "---------------------------" << endl; - cout << " pb avec getMatterQuantity " << endl; - cout << "---------------------------" << endl; - return EXIT_FAILURE ; - } - - try - { - cout << testu.getCurrentStrength() << endl ; - } - catch ( const std::exception &e ) - { - cout << "----------------------------" << endl; - cout << " pb avec getCurrentStrength " << endl; - cout << "----------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "----------------------------" << endl; - cout << " pb avec getCurrentStrength " << endl; - cout << "----------------------------" << endl; - return EXIT_FAILURE ; - } - - try - { - cout << testu.getLightIntensity() << endl ; - } - catch ( const std::exception &e ) - { - cout << "---------------------------" << endl; - cout << " pb avec getLightIntensity " << endl; - cout << "---------------------------" << endl; - MESSAGE( "catched exception : " << e.what() ) ; - return EXIT_FAILURE ; - } - catch (...) - { - cout << "---------------------------" << endl; - cout << " pb avec getLightIntensity " << endl; - cout << "---------------------------" << endl; - return EXIT_FAILURE ; - } - - return EXIT_SUCCESS ; - -} ; diff --git a/src/MEDMEMBinTest/Makefile.am b/src/MEDMEMBinTest/Makefile.am new file mode 100644 index 000000000..739e5b346 --- /dev/null +++ b/src/MEDMEMBinTest/Makefile.am @@ -0,0 +1,214 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +# MED MEDMEM : MED files in memory +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +# first '.' says that this folder must be compiled before Test (MEDMEM/Test uses MEDMEM) +#if CPPUNIT_IS_OK +# SUBDIRS=. Test +#endif + +#DIST_SUBDIRS= Test + +#lib_LTLIBRARIES= libMEDMEMBinTest.la + + +#libmedmem_la_LDFLAGS= -L$(top_builddir)/lib@LIB_LOCATION_SUFFIX@/salome +#libMEDMEMBinTest_la_CPPFLAGS= $(MED2_INCLUDES) $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ \ +# -I$(srcdir)/../MEDWrapper/Base \ +# -I$(srcdir)/../MEDWrapper/V2_1/Core -I$(srcdir)/../INTERPOLATION + +# change motivated by the bug KERNEL4778. +#libMEDMEMBinTest_la_LDFLAGS=$(MED2_LIBS) $(HDF5_LIBS) ../MEDWrapper/V2_1/Core/libmed_V2_1.la \ +# ../MEDWrapper/Base/libMEDWrapperBase.la $(STDLIB) +#if MED_ENABLE_KERNEL +# libMEDMEMBinTest_la_CPPFLAGS+= ${KERNEL_CXXFLAGS} +# libMEDMEMBinTest_la_LDFLAGS+= ${KERNEL_LDFLAGS} -lSALOMELocalTrace +#endif + +AM_CPPFLAGS= $(MED2_INCLUDES) $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ \ + -I$(srcdir)/../MEDWrapper/Base \ + -I$(srcdir)/../MEDWrapper/V2_1/Core -I$(srcdir)/../INTERPOLATION \ + -I$(srcdir)/../MEDMEM + +LDADD= $(MED2_LIBS) $(HDF5_LIBS) ../MEDWrapper/V2_1/Core/libmed_V2_1.la \ + ../MEDWrapper/Base/libMEDWrapperBase.la $(STDLIB) ../MEDMEM/libmedmem.la + +if MED_ENABLE_KERNEL + AM_CPPFLAGS+= ${KERNEL_CXXFLAGS} + LDADD+= ${KERNEL_LDFLAGS} -lSALOMELocalTrace -lSALOMEBasics +endif + + +bin_PROGRAMS= \ + ensight2med med2ensight convertToPoly \ + med2_1_To_med2_2 med2vtk duplicateMED medmembin_test duplicateMEDMESH test_write_groups_poly\ + test_MEDMEM_ModulusArray test_MEDMEM_Array test_MEDMEM_SkyLineArray \ + test_MEDMEM_CellModel testUPointerOf testUCoordinate testUUnit \ + testUGeoNameMeshEntities testUMedException testUModulusArray \ + testUSkyLineArray testUArray testUCellModel readEntete readCoordinate \ + test_copie_field_ test_copie_fieldT test_copie_coordinate \ + test_copie_medarray test_copie_connectivity test_copie_support \ + test_copie_family test_copie_group test_copie_mesh test_affect_medarray \ + test_MEDMEM_Meshing test_MEDMEM_MeshingPoly test_operation_fielddouble \ + test_operation_fieldint test_gibi_driver test_porflow_driver \ + test_grid test_MEDMEM_PolyhedronArray test_MEDMEM_PolyConnectivity \ + test_MEDMEM_PolyDriverMedMeshRead test_MEDMEM_PolyDriverMedMeshWrite \ + test_MEDMEM_poly3D test_MEDMEM_nArray test_MEDMEM_Meshing_poly test_profil_MedFieldDriver \ + test_profil_gauss_MedFieldDriver test_GaussLocalization testAnalFile test_MEDMEM_MeshingFlica testConvertPolygon \ + create_mesh create_mesh_c2q4s2 create_mesh_c3h8q4 create_mesh_c3h8q4_wrong \ + create_mesh_c2q4s2_wrong create_grid create_mesh_c2q4 create_mesh_c3h8 create_poly3D + +#AM_CPPFLAGS= $(libMEDMEMBinTest_la_CPPFLAGS) +#LDADD= $(libMEDMEMBinTest_la_LDFLAGS) -lm libMEDMEMBinTest.la + +TESTS = $(bin_PROGRAMS) + +# tests that fail because they require arguments +XFAIL_TESTS = \ + convertToPoly \ + duplicateMED \ + duplicateMEDMESH \ + ensight2med \ + med2_1_To_med2_2 \ + med2ensight \ + med2vtk \ + medmembin_test \ + readCoordinate \ + readEntete \ + testAnalFile \ + test_MEDMEM_PolyDriverMedMeshRead \ + test_MEDMEM_PolyDriverMedMeshWrite \ + test_MEDMEM_poly3D \ + test_copie_connectivity \ + test_copie_family \ + test_copie_fieldT \ + test_copie_field_ \ + test_copie_group \ + test_copie_mesh \ + test_copie_support \ + test_gibi_driver \ + test_grid \ + test_operation_fielddouble \ + test_operation_fieldint \ + test_porflow_driver \ + test_profil_MedFieldDriver \ + test_profil_gauss_MedFieldDriver + +# scripts running tests with appropriate arguments +SCRIPT_TESTS = \ + scripts/check_convertToPoly \ + scripts/check_duplicateMED \ + scripts/check_ensight2med \ + scripts/check_med2_1_To_med2_2 \ + scripts/check_med2ensight \ + scripts/check_med2vtk \ + scripts/check_readCoordinate \ + scripts/check_readEntete \ + scripts/check_testAnalFile \ + scripts/check_test_MEDMEM_PolyDriverMedMeshRead \ + scripts/check_test_MEDMEM_PolyDriverMedMeshWrite \ + scripts/check_test_MEDMEM_poly3D \ + scripts/check_test_copie_connectivity \ + scripts/check_test_copie_family \ + scripts/check_test_copie_fieldT \ + scripts/check_test_copie_field_ \ + scripts/check_test_copie_group \ + scripts/check_test_copie_mesh \ + scripts/check_test_copie_support \ + scripts/check_test_gibi_driver \ + scripts/check_test_grid \ + scripts/check_test_operation_fielddouble \ + scripts/check_test_operation_fieldint \ + scripts/check_test_porflow_driver \ + scripts/check_test_profil_MedFieldDriver \ + scripts/check_test_profil_gauss_MedFieldDriver + +TESTS_ENVIRONMENT = $(SHELL) + +TESTS += $(SCRIPT_TESTS) + +#if MED_ENABLE_KERNEL +# LDADD+=-lSALOMEBasics +#endif + +dist_convertToPoly_SOURCES= convertToPoly.cxx +dist_ensight2med_SOURCES= ensight2med.cxx +dist_med2ensight_SOURCES= med2ensight.cxx +dist_med2_1_To_med2_2_SOURCES= med2_1_To_med2_2.cxx +dist_med2vtk_SOURCES= med2vtk.cxx +dist_duplicateMED_SOURCES= duplicateMED.cxx +dist_medmembin_test_SOURCES= med_test.cxx +dist_duplicateMEDMESH_SOURCES= duplicateMEDMESH.cxx +dist_test_write_groups_poly_SOURCES= test_write_groups_poly.cxx +dist_test_MEDMEM_ModulusArray_SOURCES= test_MEDMEM_ModulusArray.cxx +dist_test_MEDMEM_Array_SOURCES= test_MEDMEM_Array.cxx +dist_test_MEDMEM_SkyLineArray_SOURCES= test_MEDMEM_SkyLineArray.cxx +dist_test_MEDMEM_CellModel_SOURCES= test_MEDMEM_CellModel.cxx +dist_testUPointerOf_SOURCES= tests/testUPointerOf.cxx +dist_testUCoordinate_SOURCES= tests/testUCoordinate.cxx +dist_testUUnit_SOURCES= tests/testUUnit.cxx +dist_testUGeoNameMeshEntities_SOURCES= tests/testUGeoNameMeshEntities.cxx +dist_testUMedException_SOURCES= tests/testUMedException.cxx +dist_testUModulusArray_SOURCES= tests/testUModulusArray.cxx +dist_testUSkyLineArray_SOURCES= tests/testUSkyLineArray.cxx +dist_testUArray_SOURCES= tests/testUArray.cxx +dist_testUCellModel_SOURCES= tests/testUCellModel.cxx +dist_readEntete_SOURCES= tests/readEntete.cxx +dist_readCoordinate_SOURCES= tests/readCoordinate.cxx +dist_test_copie_field__SOURCES= test_copie_field_.cxx +dist_test_copie_fieldT_SOURCES= test_copie_fieldT.cxx +dist_test_copie_coordinate_SOURCES= test_copie_coordinate.cxx +dist_test_copie_medarray_SOURCES= test_copie_medarray.cxx +dist_test_copie_connectivity_SOURCES= test_copie_connectivity.cxx +dist_test_copie_support_SOURCES= test_copie_support.cxx +dist_test_copie_family_SOURCES= test_copie_family.cxx +dist_test_copie_group_SOURCES= test_copie_group.cxx +dist_test_copie_mesh_SOURCES= test_copie_mesh.cxx +dist_test_affect_medarray_SOURCES= test_affect_medarray.cxx +dist_test_MEDMEM_Meshing_SOURCES= test_MEDMEM_Meshing.cxx +dist_test_MEDMEM_MeshingPoly_SOURCES= test_MEDMEM_MeshingPoly.cxx +dist_test_operation_fielddouble_SOURCES= test_operation_fielddouble.cxx +dist_test_operation_fieldint_SOURCES= test_operation_fieldint.cxx +dist_test_gibi_driver_SOURCES= test_gibi_driver.cxx +dist_test_porflow_driver_SOURCES= test_porflow_driver.cxx +dist_test_grid_SOURCES= test_grid.cxx +dist_test_MEDMEM_PolyhedronArray_SOURCES= test_MEDMEM_PolyhedronArray.cxx +dist_test_MEDMEM_PolyConnectivity_SOURCES= test_MEDMEM_PolyConnectivity.cxx +dist_test_MEDMEM_PolyDriverMedMeshRead_SOURCES= test_MEDMEM_PolyDriverMedMeshRead.cxx +dist_test_MEDMEM_PolyDriverMedMeshWrite_SOURCES= test_MEDMEM_PolyDriverMedMeshWrite.cxx +dist_test_MEDMEM_poly3D_SOURCES= test_MEDMEM_poly3D.cxx +dist_test_MEDMEM_nArray_SOURCES= test_MEDMEM_nArray.cxx +dist_test_MEDMEM_Meshing_poly_SOURCES= test_MEDMEM_Meshing_poly.cxx +dist_test_profil_MedFieldDriver_SOURCES= test_profil_MedFieldDriver.cxx +dist_test_profil_gauss_MedFieldDriver_SOURCES= test_profil_gauss_MedFieldDriver.cxx +dist_test_GaussLocalization_SOURCES= test_GaussLocalization.cxx +dist_testAnalFile_SOURCES= testAnalFile.cxx +dist_test_MEDMEM_MeshingFlica_SOURCES= test_MEDMEM_MeshingFlica.cxx +dist_testConvertPolygon_SOURCES=testConvertPolygon.cxx + +OBSOLETE_FILES = \ + create_poly2D.c \ + testAG.cxx + +EXTRA_DIST += $(OBSOLETE_FILES) $(SCRIPT_TESTS) diff --git a/src/MEDMEMBinTest/convertToPoly.cxx b/src/MEDMEMBinTest/convertToPoly.cxx new file mode 100755 index 000000000..26e7b3749 --- /dev/null +++ b/src/MEDMEMBinTest/convertToPoly.cxx @@ -0,0 +1,50 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_Mesh.hxx" +#include <iostream> + +using namespace MED_EN; +using namespace MEDMEM; +using namespace std; + +int main(int argc, char** argv) +{ + if( argc != 4 ) + { + cout << "Usage: convertToPoly input_med_file output_med_file mesh_name" << endl; + return -1; + } + else + { + string filename(argv[1]); + string meshname(argv[3]); + string outputfilename(argv[2]); + + MESH mesh(MED_DRIVER, filename, meshname); + + mesh.convertToPoly(); + + int id = mesh.addDriver(MED_DRIVER,outputfilename,meshname); + mesh.write(id); + return 0; + } +} diff --git a/src/MEDMEMBinTest/create_grid.c b/src/MEDMEMBinTest/create_grid.c new file mode 100644 index 000000000..7b8a47f72 --- /dev/null +++ b/src/MEDMEMBinTest/create_grid.c @@ -0,0 +1,445 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +/*---------------------------------------------------------------------------- + MED MEDMEM : MED files in memory + + File : create_grid.c + Module : MED +----------------------------------------------------------------------------*/ + +/****************************************************************************** + * - Nom du fichier : test19.c + * + * - Description : ecriture des objets MED relatifs aux grilles + * MED V2.0 + * + *****************************************************************************/ + +#include <med.h> +#include <string.h> + +/****************************************************************************** + * - creation d'un fichier MED + * - ecriture des noeuds : coordonnees en mode MED_FULL_INTERLACE, + * noms,numeros,numeros de familles + * - ecriture des familles d'un maillage MED + * 2.0 via les routines de bas niveau + * - fermeture du fichier + *****************************************************************************/ + +int main (int argc, char **argv) +{ + + /* Ecriture d'un premier maillage non structure (test14 + test8) + ************************************************************** */ + + med_err ret; + med_idt fid; + /* la dimension du maillage */ + med_int mdim = 2; + /* nom du maillage de longueur maxi MED_TAILLE_NOM */ + char maa[MED_TAILLE_NOM+1] = "maa1"; + /* description du maillage de longueur maxi MED_TAIIL_DESC */ + char maadesc[MED_TAILLE_DESC+1] = "Example de maillage structure 2D"; + /* le nombre de noeuds */ + med_int nnoe = 4; + /* table des coordonnees + profil : (dimension * nombre de noeuds) */ + med_float coo[8] = {0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0}; + med_int nbr[2] = {2, 2}; + /* tables des noms et des unites des coordonnees + profil : (dimension*MED_TAILLE_PNOM+1) */ + char nomcoo[2*MED_TAILLE_PNOM+1] = "x y "; + char unicoo[2*MED_TAILLE_PNOM+1] = "cm cm "; + + char nomcooi[MED_TAILLE_PNOM+1] = "x "; + char unicooi[MED_TAILLE_PNOM+1] = "cm "; + /* tables des noms, numeros, numeros de familles des noeuds + autant d'elements que de noeuds - les noms ont pout longueur + MED_TAILLE_PNOM */ + char nomnoe[4*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4 "; + med_int numnoe[4] = {1,2,3,4}; + med_int nufano[4] = {0,1,2,2}; + char nomfam[MED_TAILLE_NOM+1]; + med_int numfam; + char attdes[MED_TAILLE_DESC+1]; + med_int natt; + med_int attide; + med_int attval; + med_int ngro; + char gro[MED_TAILLE_LNOM+1]; + int i, ip1; + int nfame = 1; + int nfamn = 2; + med_int famNodeStd[4]; + med_int famElmtStd[1]; + med_int famFaceStd[4]; + med_int famNodeCart[16]; + med_int famElmtCart[9]; + med_int famFaceCart[24]; + /* + les elements: + */ + med_int nquad4 = 1; + med_int quad4[4] = { + 1, 2, 4, 3 + }; + char nomquad4[MED_TAILLE_PNOM*1+1] = "quad1 "; + med_int numquad4[1] = {1}; + med_int nufaquad4[1] = {-1}; + + fid = MEDouvrir("test19.med",MED_LECTURE_ECRITURE); + if (fid < 0) + ret = -1; + else + ret = 0; + printf("MEDouvrir : %d\n",ret); + + /* creation du maillage maa de dimension 2 */ + if (ret == 0) + ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); + printf("MEDmaaCr : %d\n",ret); + + /* ecriture des noeuds d'un maillage MED : + - des coo en mode MED_FULL_INTERLACE : (X1,Y1,X2,Y2,X3,Y3,...) + dans un repere cartesien + - des noms (optionnel dans un fichier MED) + - des numeros (optionnel dans un fichier MED) + - des numeros de familles des noeuds */ + if (ret == 0) + ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, + nomcoo,unicoo,nomnoe,MED_VRAI,numnoe,MED_VRAI, + nufano,nnoe); + printf("MEDnoeudsEcr : %d\n",ret); + + /* ecriture des mailles MED_QUAD4 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,quad4,MED_FULL_INTERLACE, + nomquad4,MED_FAUX,numquad4,MED_VRAI,nufaquad4,nquad4, + MED_MAILLE,MED_QUAD4,MED_NOD); + printf("MEDelementsEcr : %d\n",ret); + + /* ecriture des familles */ + /* Conventions : + - toujours creer une famille de numero 0 ne comportant aucun attribut + ni groupe (famille de reference pour les noeuds ou les elements + qui ne sont rattaches a aucun groupe ni attribut) + - les numeros de familles de noeuds sont > 0 + - les numeros de familles des elements sont < 0 + - rien d'imposer sur les noms de familles + */ + + /* la famille 0 */ + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_0"); + numfam = 0; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, + gro,0); + } + printf("MEDfamCr : %d \n",ret); + + /* on cree pour correspondre aux cas tests precedents, 3 familles + d'elements (-1,-2,-3) et deux familles de noeuds (1,2) */ + if (ret == 0) + { + nfame = 1; + for (i=0;i<nfame;i++) + { + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_ELEMENT_"); + numfam = -(i+1); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe1"); + ngro = 1; + printf("%s - %d - %d - %d - %d \n",nomfam,numfam,attide,attval, + ngro); + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr (elements) : %d\n",ret); + } + } + } + + if (ret == 0) + { + nfamn = 2; + for (i=0;i<nfamn;i++) + { + if(ret == 0) + { + strcpy(nomfam,"FAMILLE_NOEUD_"); + numfam = i+1; + sprintf(nomfam,"%s%d",nomfam,numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe1"); + ngro = 1; + printf("%s - %d - %d - %d - %d \n",nomfam,numfam,attide,attval, + ngro); + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr (nodes) : %d\n",ret); + } + } + } + + + /* fermeture du fichier */ + ret = MEDfermer(fid); + printf("MEDfermer : %d\n",ret); + + /* Ecriture d'un deuxieme maillage structure : grille standard + ************************************************************* */ + + fid = MEDouvrir("test19.med", MED_LECTURE_ECRITURE); + if (fid < 0) + ret = -1; + else + ret = 0; + printf("MEDouvrir : %d\n",ret); + + strcpy(maa, "Grille Standard"); + strcpy(maadesc, "Example de maillage structure grille standard 2D"); + /* creation du maillage grille standard maa de dimension 2 */ + if (ret == 0) + ret = MEDmaaCr(fid, maa, mdim, MED_STRUCTURE, maadesc); + printf("MEDmaaCr : %d\n",ret); + + if (ret == 0) + ret = MEDnatureGrilleEcr(fid, maa, MED_GRILLE_STANDARD); + printf("MEDnatureGrilleEcr : %d\n",ret); + + /* ecriture des noeuds d'un maillage MED : + - des coo en mode MED_FULL_INTERLACE : (X1,Y1,X2,Y2,X3,Y3,...) + dans un repere cartesien + - des noms (optionnel dans un fichier MED) + - des numeros (optionnel dans un fichier MED) + - des numeros de familles des noeuds */ +/* if (ret == 0) */ +/* ret = MEDstructureCoordEcr(fid,maa,mdim,nbr); */ +/* printf("MEDstructureCoordEcr : %d\n",ret); */ + + if (ret == 0) + ret = MEDcoordEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,nnoe,MED_CART, + nomcoo,unicoo); + printf("MEDcoordEcr : %d\n",ret); + + if (ret == 0) + ret = MEDstructureCoordEcr(fid,maa,mdim,nbr); + printf("MEDstructureCoordEcr : %d\n",ret); + + /* Ecriture des familles de la grille standard */ + + /* les noeuds */ + + if (ret == 0) { + famNodeStd[ 0]=1; famNodeStd[ 1]=1; + famNodeStd[ 2]=2; famNodeStd[ 3]=2; + + ret = MEDfamEcr(fid, maa, famNodeStd, 4, MED_NOEUD, 0); + }; + printf("MEDfamEcr for Nodes : %d\n",ret); + + /* les elements */ + + if (ret == 0) { + famElmtStd[ 0]=0; + + ret = MEDfamEcr(fid, maa, famElmtStd, 1, MED_MAILLE, MED_QUAD4); + }; + printf("MEDfamEcr for Elements : %d\n",ret); + + /* les faces/edges */ + + if (ret == 0) { + for (i=0; i<4; i++) famFaceStd[i]=0; + + ret = MEDfamEcr(fid, maa, famFaceStd, 4, MED_ARETE, MED_SEG2); + }; + printf("MEDfamEcr for Elements : %d\n",ret); + + /* la famille 0 */ + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_0"); + numfam = 0; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, + gro,0); + } + printf("MEDfamCr : %d\n",ret); + + if (ret == 0) + { + nfamn = 2; + for (i=0;i<nfamn;i++) + { + if(ret == 0) + { + strcpy(nomfam,"FAMILLE_NOEUD_"); + numfam = i+1; + sprintf(nomfam,"%s%d",nomfam,numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe1"); + ngro = 1; + printf("%s - %d - %d - %d - %d \n",nomfam,numfam,attide,attval, + ngro); + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr (nodes) : %d\n",ret); + } + } + } + + /* fermeture du fichier */ + ret = MEDfermer(fid); + printf("MEDfermer : %d\n",ret); + + /* Ecriture d'un troisieme maillage structure : grille cartesienne + *************************************************************** */ + + fid = MEDouvrir("test19.med", MED_LECTURE_ECRITURE); + if (fid < 0) + ret = -1; + else + ret = 0; + printf("MEDouvrir : %d\n",ret); + + strcpy(maa, "Grille Cartesienne"); + strcpy(maadesc, "Example de maillage structure grille cartesienne 2D"); + /* creation d'une grille cartesienne maa de dimension 2 */ + if (ret == 0) + ret = MEDmaaCr(fid, maa, mdim, MED_STRUCTURE, maadesc); + printf("MEDmaaCr : %d\n",ret); + + if (ret == 0) + ret = MEDnatureGrilleEcr(fid, maa, MED_GRILLE_CARTESIENNE); + printf("MEDnatureGrilleEcr : %d\n",ret); + + /* Ecriture des indices de la grille cartesienne : + - des coo en mode MED_FULL_INTERLACE : (X1,Y1,X2,Y2,X3,Y3,...) */ + for (i=0; i<mdim; i++) { + ip1 = i + 1; + coo[0] = 1.1+i; + coo[1] = 1.2+i; + coo[2] = 1.3+i; + coo[3] = 1.4+i; + if (ret == 0) { + ret = MEDindicesCoordEcr(fid, maa, mdim, coo, nnoe, ip1, + nomcooi, unicooi); + }; + }; + printf("MEDindicesCoordEcr : %d\n",ret); + + /* Ecriture des familles de la grille cartesienne */ + + /* les noeuds */ + + if (ret == 0) { + famNodeCart[ 0]=3; famNodeCart[ 1]=3; famNodeCart[ 2]=2; famNodeCart[ 3]=1; + famNodeCart[ 4]=7; famNodeCart[ 5]=8; famNodeCart[ 6]=2; famNodeCart[ 7]=4; + famNodeCart[ 8]=2; famNodeCart[ 9]=9; famNodeCart[10]=0; famNodeCart[11]=2; + famNodeCart[12]=5; famNodeCart[13]=5; famNodeCart[14]=6; famNodeCart[15]=7; + + ret = MEDfamEcr(fid, maa, famNodeCart, 16, MED_NOEUD, 0); + }; + printf("MEDfamEcr for Nodes : %d\n",ret); + + /* les elements */ + + if (ret == 0) { + for(i=0; i<9; i++) famElmtCart[i]=0; + + ret = MEDfamEcr(fid, maa, famElmtCart, 9, MED_MAILLE, MED_QUAD4); + }; + printf("MEDfamEcr for Elements : %d\n",ret); + + /* les faces/edges */ + + if (ret == 0) { + for(i=0; i<24; i++) famFaceCart[i]=0; + + ret = MEDfamEcr(fid, maa, famFaceCart, 24, MED_ARETE, MED_SEG2); + }; + printf("MEDfamEcr for Elements : %d\n",ret); + + /* la famille 0 */ + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_0"); + numfam = 0; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, + gro,0); + } + printf("MEDfamCr : %d \n",ret); + + if (ret == 0) + { + nfamn = 9; + for (i=0;i<nfamn;i++) + { + if(ret == 0) + { + strcpy(nomfam,"FAMILLE_NOEUD_"); + numfam = i+1; + sprintf(nomfam,"%s%d",nomfam,numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe1"); + ngro = 1; + printf("%s - %d - %d - %d - %d \n",nomfam,numfam,attide,attval, + ngro); + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr (nodes) : %d\n",ret); + } + } + } + + /* fermeture du fichier */ + ret = MEDfermer(fid); + printf("MEDfermer : %d\n",ret); + + if ( getenv("srcdir") ) { + /* we are in 'make check' */ + remove( "test19.med" ); + printf("Remove generated file"); + } + + return 0; +} diff --git a/src/MEDMEMBinTest/create_mesh.c b/src/MEDMEMBinTest/create_mesh.c new file mode 100644 index 000000000..a46ccc879 --- /dev/null +++ b/src/MEDMEMBinTest/create_mesh.c @@ -0,0 +1,416 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include <med.h> +#include <string.h> + +int main (int argc, char **argv) +{ + med_err ret; + med_idt fid; + char maa[MED_TAILLE_NOM+1] = "maa1"; + char maadesc[MED_TAILLE_DESC+1] = "Example de maillage non structure 3D"; + med_int mdim = 3; + med_int nnoe = 19; + med_float coo[57] = { + 0.0, 0.0, 0.0, + 0.0, 0.0, 1.0, + 2.0, 0.0, 1.0, + 0.0, 2.0, 1.0, + -2.0, 0.0, 1.0, + 0.0, -2.0, 1.0, + 1.0, 1.0, 2.0, + -1.0, 1.0, 2.0, + -1.0, -1.0, 2.0, + 1.0, -1.0, 2.0, + 1.0, 1.0, 3.0, + -1.0, 1.0, 3.0, + -1.0, -1.0, 3.0, + 1.0, -1.0, 3.0, + 1.0, 1.0, 4.0, + -1.0, 1.0, 4.0, + -1.0, -1.0, 4.0, + 1.0, -1.0, 4.0, + 0.0, 0.0, 5.0 + }; + char nomcoo[3*MED_TAILLE_PNOM+1] = "x y z "; + char unicoo[3*MED_TAILLE_PNOM+1] = "cm cm cm "; + /* char nomnoe[19*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4";*/ + char *nomnoe ; + med_int numnoe[19] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + med_int nufano[19] = {1,1,3,3,0,0,2,0,4,0,4,2,4,2,4,2,4,1,3}; + + med_int ntet4 = 12; + med_int tet4[12*4] = { + 1,2,3,6, + 1,2,4,3, + 1,2,5,4, + 1,2,6,5, + 2,7,4,3, + 2,8,5,4, + 2,9,6,5, + 2,10,3,6, + 2,7,3,10, + 2,8,4,7, + 2,9,5,8, + 2,10,6,9 + }; + char * nomtet4 ; + med_int numtet4[12] = {1,2,3,4,5,6,7,8,9,10,11,12}; + med_int nufatet4[12] = {-1,-1,-1,-1,0,0,0,0,0,0,-2,-3}; + + med_int npyra5 = 2; + med_int pyra5[5*2] = { + 7,8,9,10,2, + 15,18,17,16,19 + }; + char nompyra5[MED_TAILLE_PNOM*2+1] = "pyra1 pyra2 "; + med_int numpyra5[2] = {13,16}; + med_int nufapyra5[2] = {0,-3}; + + med_int nhexa8 = 2; + med_int hexa8[8*2] = { + 11,12,13,14,7,8,9,10, + 15,16,17,18,11,12,13,14 + }; + char nomhexa8[MED_TAILLE_PNOM*2+1] = "hexa1 hexa2 "; + med_int numhexa8[2] = {14,15}; + med_int nufahexa8[2] = {0,0}; + + char nomfam[MED_TAILLE_NOM+1]; + med_int numfam; + char attdes[MED_TAILLE_DESC+1]; + med_int natt; + med_int attide; + med_int attval; + med_int ngro; + char gro[MED_TAILLE_LNOM+1]; + char gro2[MED_TAILLE_LNOM*2+1]; + char gro3[MED_TAILLE_LNOM*3+1]; + int i; + int nfame = 3; + int nfamn = 2; + + + /* + Some fields : 2 on nodes : one int and one double , one on cells : double + */ + char champ1[MED_TAILLE_NOM+1]="fieldnodeint" ; + char champ1_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ1_unit[MED_TAILLE_PNOM+1]="M " ; + med_int fieldnodeint[19] = {1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7}; + + char champ2[MED_TAILLE_NOM+1]="fieldnodedouble" ; + char champ2_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ2_unit[MED_TAILLE_PNOM+1]="J " ; + med_float fieldnodedouble1[19] = {1.,1.,1.,2.,2.,2.,3.,3.,3.,4.,4.,4.,5.,5.,5.,6.,6.,6.,7.}; + med_float fieldnodedouble2[19] = {1.,2.,2.,2.,3.,3.,3.,4.,4.,4.,5.,5.,5.,6.,6.,6.,7.,7.,7.}; + + char champ3[MED_TAILLE_NOM+1]="fieldcelldoublevector" ; + char champ3_comp[MED_TAILLE_PNOM*3+1]="comp1 comp2 comp3 " ; + char champ3_unit[MED_TAILLE_PNOM*3+1]="m/s m/s m/s " ; + med_float fieldcelldouble1[12*3] = {1.,1.,1.,2.,2.,2.,3.,3.,3.,4.,4.,4.,0.,0.,0.,1.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,0.,0.,0.,1.,1.,1.,0.,0.,0.}; + med_float fieldcelldouble2[2*3] = {5.,5.,0.,1.,0.,1.}; + med_float fieldcelldouble3[2*3] = {6.,6.,1.,0.,1.,0.}; + + char champ4[MED_TAILLE_NOM+1]="fieldcelldoublescalar" ; + char champ4_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ4_unit[MED_TAILLE_PNOM+1]="m/s " ; + med_float fieldcelldouble4[12] = {1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.}; + med_float fieldcelldouble5[2] = {2.,2.}; + med_float fieldcelldouble6[2] = {3.,3.}; + + /***************************************************************************/ + fid = MEDouvrir("pointe.med",MED_LECTURE_ECRITURE); + if (fid < 0) + ret = -1; + else + ret = 0; + printf("MEDouvrir : %d\n",ret); + + /***************************************************************************/ + if (ret == 0) + ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); + printf("MEDmaaCr : %d\n",ret); + if (ret == 0) + ret = MEDunvCr(fid,maa); + printf("MEDunvCr : %d\n",ret); + + /***************************************************************************/ + if (ret == 0) + ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, + nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, + nufano,nnoe); + printf("MEDnoeudsEcr : %d\n",ret); + + + /***************************************************************************/ + /* ecriture des mailles MED_TETRA4 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,tet4,MED_FULL_INTERLACE, + nomtet4,MED_FAUX,numtet4,MED_VRAI,nufatet4,ntet4, + MED_MAILLE,MED_TETRA4,MED_NOD); + printf("MEDelementsEcr : %d \n",ret); + + /* ecriture des mailles MED_PYRA5 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,pyra5,MED_FULL_INTERLACE, + nompyra5,MED_VRAI,numpyra5,MED_VRAI,nufapyra5,npyra5, + MED_MAILLE,MED_PYRA5,MED_NOD); + printf("MEDelementsEcr : %d \n",ret); + + /* ecriture des mailles MED_HEXA8 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,hexa8,MED_FULL_INTERLACE, + nomhexa8,MED_FAUX,numhexa8,MED_VRAI,nufahexa8,nhexa8, + MED_MAILLE,MED_HEXA8,MED_NOD); + printf("MEDelementsEcr : %d \n",ret); + + /***************************************************************************/ + /* ecriture des familles */ + /* Conventions : + - toujours creer une famille de numero 0 ne comportant aucun attribut + ni groupe (famille de reference pour les noeuds ou les elements + qui ne sont rattaches a aucun groupe ni attribut) + - les numeros de familles de noeuds sont > 0 + - les numeros de familles des elements sont < 0 + - rien d'imposer sur les noms de familles + */ + + /* la famille 0 */ + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_0"); + numfam = 0; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, + gro,0); + } + printf("MEDfamCr : %d \n",ret); + + /* on cree : + - 3 familles d'elements (-1,-2,-3) et + - 2 familles de noeuds (1,2) + */ + if (ret == 0) + { + nfame = 3; + for (i=0;i<nfame;i++) + { + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_ELEMENT_"); + numfam = -(i+1); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe1"); + ngro = 1; + /*printf("nomfam : %s - numfam : %d - attide : %d - attval : %d - ngro : %d \n",nomfam,numfam,attide,attval,ngro);*/ + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + } + } + + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_NOEUD_1"); + numfam = 1; + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro2,"groupe2"); + strcpy(gro2+MED_TAILLE_LNOM,"groupe3"); + ngro = 2; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro2,ngro); + printf("MEDfamCr : %d\n",ret); + } + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_NOEUD_2"); + numfam = 2; + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro2,"groupe3"); + strcpy(gro2+MED_TAILLE_LNOM,"groupe4"); + ngro = 2; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro2,ngro); + printf("MEDfamCr : %d\n",ret); + } + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_NOEUD_3"); + numfam = 3; + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro2,"groupe2"); + strcpy(gro2+MED_TAILLE_LNOM,"groupe4"); + ngro = 2; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro2,ngro); + printf("MEDfamCr : %d\n",ret); + } + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_NOEUD_4"); + numfam = 4; + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe5"); + ngro = 1; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + + /***************************************************************************/ + /* + Les champs + */ + if (ret == 0) + { + ret = MEDchampCr(fid,champ1,MED_INT32,champ1_comp,champ1_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ1, (unsigned char *)fieldnodeint, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + MED_NOPDT," ", 0., MED_NONOR); + + printf("MEDchampEcr : %d \n",ret); + } + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ2,MED_FLOAT64,champ2_comp,champ2_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + 1,"S ", 1.1 , MED_NONOR); + printf("MEDchampEcr1 : %d \n",ret); + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble2, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + 2,"S ", 1.2 , MED_NONOR); + printf("MEDchampEcr2 : %d \n",ret); + } + } + + /* on met champ2 sans pas de temps pour pouvoir le lire aussi par defaut !*/ + if (ret == 0) + { +/* ret = MEDchampCr(fid,champ2,MED_REEL64,champ2_comp,champ2_unit,1); */ +/* printf("MEDchampCr : %d \n",ret); */ + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + MED_NOPDT," ", 0. , MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ3,MED_FLOAT64,champ3_comp,champ3_unit,3); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble1, + MED_NO_INTERLACE, ntet4, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_TETRA4, + MED_NOPDT," ", 0., MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble3, + MED_NO_INTERLACE, nhexa8, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_HEXA8, + MED_NOPDT," ", 0., MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble2, + MED_NO_INTERLACE, npyra5, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_PYRA5, + MED_NOPDT," ", 0., MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ4,MED_FLOAT64,champ4_comp,champ4_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ4, (unsigned char *)fieldcelldouble4, + MED_NO_INTERLACE, ntet4, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_TETRA4, + MED_NOPDT," ", 0., MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + ret = MEDchampEcr(fid, maa, champ4, (unsigned char *)fieldcelldouble6, + MED_NO_INTERLACE, nhexa8, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_HEXA8, + MED_NOPDT," ", 0., MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + ret = MEDchampEcr(fid, maa, champ4, (unsigned char *)fieldcelldouble5, + MED_NO_INTERLACE, npyra5, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_PYRA5, + MED_NOPDT," ", 0., MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + } + + /***************************************************************************/ + ret = MEDfermer(fid); + printf("MEDfermer : %d\n",ret); + + if ( getenv("srcdir") ) { + /* we are in 'make check' */ + remove( "pointe.med" ); + printf("Remove generated file"); + } + + return 0; +} + diff --git a/src/MEDMEMBinTest/create_mesh_c2q4.c b/src/MEDMEMBinTest/create_mesh_c2q4.c new file mode 100644 index 000000000..1bf6eb574 --- /dev/null +++ b/src/MEDMEMBinTest/create_mesh_c2q4.c @@ -0,0 +1,251 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +/* + creation d'une geometrie 2d : un cube [0,1]^2 + maillé uniformement en quadrangle reguliers; + avec en plus une partie des aretes (une partie + des arretes de la frontiere) du maillage. + ATTENTION : 3 noeuds dans chaque direction +*/ + +#include <med.h> +#include <string.h> + +int main (int argc, char **argv) +{ + med_err ret; + med_idt fid; + char maa[MED_TAILLE_NOM+1] = "carre_en_quad4"; + char maadesc[MED_TAILLE_DESC+1] = "Example de maillage non structure 2D"; + med_int mdim = 2; + med_int nnoe = 9; + /* + les noeuds: + */ + med_float coo[18] = { + 0.0, 0.0, + 0.5, 0.0, + 1.0, 0.0, + 0.0, 0.5, + 0.5, 0.5, + 1.0, 0.5, + 0.0, 1.0, + 0.5, 1.0, + 1.0, 1.0 + }; + char nomcoo[2*MED_TAILLE_PNOM+1] = "x y "; + char unicoo[2*MED_TAILLE_PNOM+1] = "cm cm "; + /* char nomnoe[19*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4";*/ + char *nomnoe ; + med_int numnoe[9] = {1,2,3,4,5,6,7,8,9}; + med_int nufano[9] = {0,0,0,0,0,0,0,0,0}; + /* + les elements: + */ + med_int nquad4 = 4; + med_int quad4[16] = { + 4, 5, 2, 1, + 5, 6, 3, 2, + 7, 8, 5, 4, + 8, 9, 6, 5 + }; + char nomquad4[MED_TAILLE_PNOM*4+1] = "quad1 quad2 quad3 quad4 "; + med_int numquad4[4] = {1,2,3,4}; + med_int nufaquad4[4] = {-1,-1,0,0}; + + char nomfam[MED_TAILLE_NOM+1]; + med_int numfam; + char attdes[MED_TAILLE_DESC+1]; + med_int natt; + med_int attide; + med_int attval; + med_int ngro; + char gro[MED_TAILLE_LNOM+1]; + int i; + int nfame = 1; + int nfamn = 1; + + /* + Some fields : 2 on nodes : one int and one double , one on cells : double + */ + char champ1[MED_TAILLE_NOM+1]="fieldnodeint" ; + char champ1_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ1_unit[MED_TAILLE_PNOM+1]="M " ; + med_int fieldnodeint[9] = {1,1,3,2,2,3,4,4,5}; + + char champ2[MED_TAILLE_NOM+1]="fieldnodedouble" ; + char champ2_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ2_unit[MED_TAILLE_PNOM+1]="J " ; + med_float fieldnodedouble1[9] = {1.,3.,4.,1.,3.,4.,3.,2.,5.}; + med_float fieldnodedouble2[9] = {1.,2.,2.,3.,3.,3.,4.,4.,5.}; + + char champ3[MED_TAILLE_NOM+1]="fieldcelldouble" ; + char champ3_comp[MED_TAILLE_PNOM*2+1]="comp1 comp2 " ; + char champ3_unit[MED_TAILLE_PNOM*2+1]="M/S m/s " ; + med_float fieldcelldouble[4*2] = {0.,1.,1.,1.,1.,2.,2.,3.}; + + /***************************************************************************/ + fid = MEDouvrir("carre_en_quad4.med",MED_LECTURE_ECRITURE); + if (fid < 0) + ret = -1; + else + ret = 0; + printf("MEDouvrir : %d\n",ret); + + /***************************************************************************/ + if (ret == 0) + ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); + printf("MEDmaaCr : %d\n",ret); + if (ret == 0) + ret = MEDunvCr(fid,maa); + printf("MEDunvCr : %d\n",ret); + + /***************************************************************************/ + if (ret == 0) + ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, + nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, + nufano,nnoe); + printf("MEDnoeudsEcr : %d\n",ret); + + /* ecriture des mailles MED_QUAD4 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,quad4,MED_FULL_INTERLACE, + nomquad4,MED_FAUX,numquad4,MED_VRAI,nufaquad4,nquad4, + MED_MAILLE,MED_QUAD4,MED_NOD); + printf("MEDelementsEcr : %d \n",ret); + + /***************************************************************************/ + /* ecriture des familles */ + /* Conventions : + - toujours creer une famille de numero 0 ne comportant aucun attribut + ni groupe (famille de reference pour les noeuds ou les elements + qui ne sont rattaches a aucun groupe ni attribut) + - les numeros de familles de noeuds sont > 0 + - les numeros de familles des elements sont < 0 + - rien d'imposer sur les noms de familles + */ + + /* la famille 0 */ + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_0"); + numfam = 0; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, + gro,0); + } + printf("MEDfamCr : %d \n",ret); + + /* on cree : + - 1 familles d'elements de dimension (d) + en fait de face (-10) + */ + + if (ret == 0) + { + numfam = -1; + strcpy(nomfam,"FAMILLE_CELL_"); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe0"); + ngro = 1; + + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + /***************************************************************************/ + /* + Les champs + */ + if (ret == 0) + { + ret = MEDchampCr(fid,champ1,MED_INT32,champ1_comp,champ1_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ1, (unsigned char *)fieldnodeint, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + MED_NOPDT," ", 0., MED_NONOR); + + printf("MEDchampEcr : %d \n",ret); + } + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ2,MED_FLOAT64,champ2_comp,champ2_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + 1,"S ", 1.1 , MED_NONOR); + printf("MEDchampEcr1 : %d \n",ret); + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble2, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + 2,"S ", 1.2 , MED_NONOR); + printf("MEDchampEcr2 : %d \n",ret); + } + } + + /* on met champ2 sans pas de temps pour pouvoir le lire aussi par defaut ! */ + if (ret == 0) + { + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + MED_NOPDT," ", 0. , MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ3,MED_FLOAT64,champ3_comp,champ3_unit,2); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble, + MED_NO_INTERLACE, nquad4, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_QUAD4, + MED_NOPDT," ", 0., MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + } + + /***************************************************************************/ + + ret = MEDfermer(fid); + printf("MEDfermer : %d\n",ret); + + if ( getenv("srcdir") ) + /* we are in 'make check' */ + remove( "carre_en_quad4.med" ); + + return 0; +} diff --git a/src/MEDMEMBinTest/create_mesh_c2q4s2.c b/src/MEDMEMBinTest/create_mesh_c2q4s2.c new file mode 100644 index 000000000..3b4f84236 --- /dev/null +++ b/src/MEDMEMBinTest/create_mesh_c2q4s2.c @@ -0,0 +1,315 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +/* + creation d'une geometrie 2d : un cube [0,1]^2 + maillé uniformement en quadrangle reguliers; + avec en plus une partie des aretes (une partie + des arretes de la frontiere) du maillage. + ATTENTION : 3 noeuds dans chaque direction +*/ + +#include <med.h> +#include <string.h> + +int main (int argc, char **argv) +{ + med_err ret; + med_idt fid; + char maa[MED_TAILLE_NOM+1] = "carre_en_quad4_seg2"; + char maadesc[MED_TAILLE_DESC+1] = "Example de maillage non structure 2D"; + med_int mdim = 2; + med_int nnoe = 9; + /* + les noeuds: + */ + med_float coo[18] = { + 0.0, 0.0, + 0.5, 0.0, + 1.0, 0.0, + 0.0, 0.5, + 0.5, 0.5, + 1.0, 0.5, + 0.0, 1.0, + 0.5, 1.0, + 1.0, 1.0 + }; + char nomcoo[2*MED_TAILLE_PNOM+1] = "x y "; + char unicoo[2*MED_TAILLE_PNOM+1] = "cm cm "; + /* char nomnoe[19*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4";*/ + char *nomnoe ; + med_int numnoe[9] = {1,2,3,4,5,6,7,8,9}; + med_int nufano[9] = {0,0,0,0,0,0,0,0,0}; + /* + les elements: + */ + med_int nquad4 = 4; + med_int quad4[16] = { + 4, 5, 2, 1, + 5, 6, 3, 2, + 7, 8, 5, 4, + 8, 9, 6, 5 + }; + char nomquad4[MED_TAILLE_PNOM*4+1] = "quad1 quad2 quad3 quad4 "; + med_int numquad4[4] = {1,2,3,4}; + med_int nufaquad4[4] = {-10,-10,0,0}; + + /* + Les Faces qui dans ce cas (2D) sont des arretes + */ + + med_int nseg2 = 6; + med_int seg2[18] = { + 6, 3, 0, + 8, 9, 0, + 3, 2, 0, + 9, 6, 0, + 2, 5, 0, + 5, 8, 0 + }; + char nomseg2[MED_TAILLE_PNOM*6+1] = "seg1 seg2 seg3 seg4 seg5 seg6 "; + med_int numseg2[6] = {1,2,3,4,5,6}; + med_int nufaseg2[6] = {-1,-2,-1,-1,-2,-2}; + + char nomfam[MED_TAILLE_NOM+1]; + med_int numfam; + char attdes[MED_TAILLE_DESC+1]; + med_int natt; + med_int attide; + med_int attval; + med_int ngro; + char gro[MED_TAILLE_LNOM+1]; + int i; + int nfame = 1; + int nfamn = 1; + + /* + Some fields : 2 on nodes : one int and one double , one on cells : double + */ + char champ1[MED_TAILLE_NOM+1]="fieldnodeint" ; + char champ1_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ1_unit[MED_TAILLE_PNOM+1]="M " ; + med_int fieldnodeint[9] = {1,1,3,2,2,3,4,4,5}; + + char champ2[MED_TAILLE_NOM+1]="fieldnodedouble" ; + char champ2_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ2_unit[MED_TAILLE_PNOM+1]="J " ; + med_float fieldnodedouble1[9] = {1.,3.,4.,1.,3.,4.,3.,2.,5.}; + med_float fieldnodedouble2[9] = {1.,2.,2.,3.,3.,3.,4.,4.,5.}; + + char champ3[MED_TAILLE_NOM+1]="fieldcelldouble" ; + char champ3_comp[MED_TAILLE_PNOM*2+1]="comp1 comp2 " ; + char champ3_unit[MED_TAILLE_PNOM*2+1]="M/S m/s " ; + med_float fieldcelldouble[4*2] = {0.,1.,1.,1.,1.,2.,2.,3.}; + + /***************************************************************************/ + fid = MEDouvrir("carre_en_quad4_seg2.med",MED_LECTURE_ECRITURE); + if (fid < 0) + ret = -1; + else + ret = 0; + printf("MEDouvrir : %d\n",ret); + + /***************************************************************************/ + if (ret == 0) + ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); + printf("MEDmaaCr : %d\n",ret); + if (ret == 0) + ret = MEDunvCr(fid,maa); + printf("MEDunvCr : %d\n",ret); + + /***************************************************************************/ + if (ret == 0) + ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, + nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, + nufano,nnoe); + printf("MEDnoeudsEcr : %d\n",ret); + + /* ecriture des mailles MED_QUAD4 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,quad4,MED_FULL_INTERLACE, + nomquad4,MED_FAUX,numquad4,MED_VRAI,nufaquad4,nquad4, + MED_MAILLE,MED_QUAD4,MED_NOD); + printf("MEDelementsEcr : %d \n",ret); + + /* ecriture des mailles MED_SEG2 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,seg2,MED_FULL_INTERLACE, + nomseg2,MED_FAUX,numseg2,MED_VRAI,nufaseg2,nseg2, + MED_MAILLE,MED_SEG2,MED_NOD); + printf("%d \n",ret); + + /***************************************************************************/ + /* ecriture des familles */ + /* Conventions : + - toujours creer une famille de numero 0 ne comportant aucun attribut + ni groupe (famille de reference pour les noeuds ou les elements + qui ne sont rattaches a aucun groupe ni attribut) + - les numeros de familles de noeuds sont > 0 + - les numeros de familles des elements sont < 0 + - rien d'imposer sur les noms de familles + */ + + /* la famille 0 */ + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_0"); + numfam = 0; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, + gro,0); + } + printf("%d \n",ret); + + /* on cree : + - 1 familles d'elements de dimension (d-1) + en fait de edge (-1) + - 1 familles d'elements de dimension (d-1) + en fait de edge (-2) + - 1 familles d'elements de dimension (d) + en fait de face (-10) + */ + + if (ret == 0) + { + numfam = -1; + strcpy(nomfam,"FAMILLE_EDGE_"); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe1"); + ngro = 1; + + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + if (ret == 0) + { + numfam = -2; + strcpy(nomfam,"FAMILLE_EDGE_"); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe1"); + ngro = 1; + + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + if (ret == 0) + { + numfam = -10; + strcpy(nomfam,"FAMILLE_CELL_"); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe0"); + ngro = 1; + + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + /***************************************************************************/ + /* + Les champs + */ + if (ret == 0) + { + ret = MEDchampCr(fid,champ1,MED_INT32,champ1_comp,champ1_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ1, (unsigned char *)fieldnodeint, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + MED_NOPDT," ", 0., MED_NONOR); + + printf("MEDchampEcr : %d \n",ret); + } + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ2,MED_FLOAT64,champ2_comp,champ2_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + 1,"S ", 1.1 , MED_NONOR); + printf("MEDchampEcr1 : %d \n",ret); + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble2, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + 2,"S ", 1.2 , MED_NONOR); + printf("MEDchampEcr2 : %d \n",ret); + } + } + + /* on met champ2 sans pas de temps pour pouvoir le lire aussi par defaut !*/ + if (ret == 0) + { + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + MED_NOPDT," ", 0. , MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ3,MED_FLOAT64,champ3_comp,champ3_unit,2); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble, + MED_NO_INTERLACE, nquad4, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_QUAD4, + MED_NOPDT," ", 0., MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + } + + /***************************************************************************/ + + ret = MEDfermer(fid); + printf("%d\n",ret); + + if ( getenv("srcdir") ) + /* we are in 'make check' */ + remove( "carre_en_quad4_seg2.med" ); + + return 0; +} diff --git a/src/MEDMEMBinTest/create_mesh_c2q4s2_wrong.c b/src/MEDMEMBinTest/create_mesh_c2q4s2_wrong.c new file mode 100644 index 000000000..641e88f83 --- /dev/null +++ b/src/MEDMEMBinTest/create_mesh_c2q4s2_wrong.c @@ -0,0 +1,319 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +/* + creation d'une geometrie 2d : un cube [0,1]^2 + maillé uniformement en quadrangle reguliers; + avec en plus une partie des aretes (une partie + des arretes de la frontiere) du maillage. + ATTENTION : 3 noeuds dans chaque direction +*/ + +#include <med.h> +#include <string.h> + +int main (int argc, char **argv) +{ + med_err ret; + med_idt fid; + char maa[MED_TAILLE_NOM+1] = "carre_en_quad4_seg2_wrong"; + char maadesc[MED_TAILLE_DESC+1] = "Example de maillage non structure 2D"; + med_int mdim = 2; + med_int nnoe = 9; + /* + les noeuds: + */ + med_float coo[18] = { + 0.0, 0.0, + 0.5, 0.0, + 1.0, 0.0, + 0.0, 0.5, + 0.5, 0.5, + 1.0, 0.5, + 0.0, 1.0, + 0.5, 1.0, + 1.0, 1.0 + }; + char nomcoo[2*MED_TAILLE_PNOM+1] = "x y "; + char unicoo[2*MED_TAILLE_PNOM+1] = "cm cm "; + /* char nomnoe[19*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4";*/ + char *nomnoe ; + med_int numnoe[9] = {1,2,3,4,5,6,7,8,9}; + med_int nufano[9] = {0,0,0,0,0,0,0,0,0}; + /* + les elements: + */ + med_int nquad4 = 4; + med_int quad4[16] = { + 4, 5, 2, 1, + 5, 6, 3, 2, + 7, 8, 5, 4, + 8, 9, 6, 5 + }; + char nomquad4[MED_TAILLE_PNOM*4+1] = "quad1 quad2 quad3 quad4 "; + med_int numquad4[4] = {1,2,3,4}; + med_int nufaquad4[4] = {-10,-10,0,0}; + + /* + Les Faces qui dans ce cas (2D) sont des arretes + + a face is wrongly oriented, it is just to test the applidation + duplicateMEDMESH + */ + + med_int nseg2 = 6; + med_int seg2[12] = { + 6, 3, + 8, 9, + 3, 2, + /*9, 6,*/ + 6, 9, + 2, 5, + 5, 8 + }; + char nomseg2[MED_TAILLE_PNOM*6+1] = "seg1 seg2 seg3 seg4 seg5 seg6 "; + med_int numseg2[6] = {1,2,3,4,5,6}; + med_int nufaseg2[6] = {-1,-2,-1,-1,-2,-2}; + + char nomfam[MED_TAILLE_NOM+1]; + med_int numfam; + char attdes[MED_TAILLE_DESC+1]; + med_int natt; + med_int attide; + med_int attval; + med_int ngro; + char gro[MED_TAILLE_LNOM+1]; + int i; + int nfame = 1; + int nfamn = 1; + + /* + Some fields : 2 on nodes : one int and one double , one on cells : double + */ + char champ1[MED_TAILLE_NOM+1]="fieldnodeint" ; + char champ1_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ1_unit[MED_TAILLE_PNOM+1]="M " ; + med_int fieldnodeint[9] = {1,1,3,2,2,3,4,4,5}; + + char champ2[MED_TAILLE_NOM+1]="fieldnodedouble" ; + char champ2_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ2_unit[MED_TAILLE_PNOM+1]="J " ; + med_float fieldnodedouble1[9] = {1.,3.,4.,1.,3.,4.,3.,2.,5.}; + med_float fieldnodedouble2[9] = {1.,2.,2.,3.,3.,3.,4.,4.,5.}; + + char champ3[MED_TAILLE_NOM+1]="fieldcelldouble" ; + char champ3_comp[MED_TAILLE_PNOM*2+1]="comp1 comp2 " ; + char champ3_unit[MED_TAILLE_PNOM*2+1]="M/S m/s " ; + med_float fieldcelldouble[4*2] = {0.,1.,1.,1.,1.,2.,2.,3.}; + + /***************************************************************************/ + fid = MEDouvrir("carre_en_quad4_seg2_wrong.med",MED_LECTURE_ECRITURE); + if (fid < 0) + ret = -1; + else + ret = 0; + printf("MEDouvrir : %d\n",ret); + + /***************************************************************************/ + if (ret == 0) + ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); + printf("MEDmaaCr : %d\n",ret); + if (ret == 0) + ret = MEDunvCr(fid,maa); + printf("MEDunvCr : %d\n",ret); + + /***************************************************************************/ + if (ret == 0) + ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, + nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, + nufano,nnoe); + printf("MEDnoeudsEcr : %d\n",ret); + + /* ecriture des mailles MED_QUAD4 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,quad4,MED_FULL_INTERLACE, + nomquad4,MED_FAUX,numquad4,MED_VRAI,nufaquad4,nquad4, + MED_MAILLE,MED_QUAD4,MED_NOD); + printf("MEDelementsEcr : %d \n",ret); + + /* ecriture des mailles MED_SEG2 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,seg2,MED_FULL_INTERLACE, + nomseg2,MED_FAUX,numseg2,MED_VRAI,nufaseg2,nseg2, + MED_ARETE,MED_SEG2,MED_NOD); + printf("MEDelementsEcr : %d \n",ret); + + /***************************************************************************/ + /* ecriture des familles */ + /* Conventions : + - toujours creer une famille de numero 0 ne comportant aucun attribut + ni groupe (famille de reference pour les noeuds ou les elements + qui ne sont rattaches a aucun groupe ni attribut) + - les numeros de familles de noeuds sont > 0 + - les numeros de familles des elements sont < 0 + - rien d'imposer sur les noms de familles + */ + + /* la famille 0 */ + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_0"); + numfam = 0; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, + gro,0); + } + printf("%d \n",ret); + + /* on cree : + - 1 familles d'elements de dimension (d-1) + en fait de edge (-1) + - 1 familles d'elements de dimension (d-1) + en fait de edge (-2) + - 1 familles d'elements de dimension (d) + en fait de face (-10) + */ + + if (ret == 0) + { + numfam = -1; + strcpy(nomfam,"FAMILLE_EDGE_"); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe1"); + ngro = 1; + + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + if (ret == 0) + { + numfam = -2; + strcpy(nomfam,"FAMILLE_EDGE_"); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe1"); + ngro = 1; + + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + if (ret == 0) + { + numfam = -10; + strcpy(nomfam,"FAMILLE_CELL_"); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe0"); + ngro = 1; + + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + /***************************************************************************/ + /* + Les champs + */ + if (ret == 0) + { + ret = MEDchampCr(fid,champ1,MED_INT32,champ1_comp,champ1_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ1, (unsigned char *)fieldnodeint, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + MED_NOPDT," ", 0., MED_NONOR); + + printf("MEDchampEcr : %d \n",ret); + } + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ2,MED_FLOAT64,champ2_comp,champ2_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + 1,"S ", 1.1 , MED_NONOR); + printf("MEDchampEcr1 : %d \n",ret); + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble2, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + 2,"S ", 1.2 , MED_NONOR); + printf("MEDchampEcr2 : %d \n",ret); + } + } + + /* on met champ2 sans pas de temps pour pouvoir le lire aussi par defaut !*/ + if (ret == 0) + { + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + MED_NOPDT," ", 0. , MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ3,MED_FLOAT64,champ3_comp,champ3_unit,2); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble, + MED_NO_INTERLACE, nquad4, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_QUAD4, + MED_NOPDT," ", 0., MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + } + + /***************************************************************************/ + + ret = MEDfermer(fid); + printf("%d\n",ret); + + if ( getenv("srcdir") ) + /* we are in 'make check' */ + remove( "carre_en_quad4_seg2_wrong.med" ); + + return 0; +} diff --git a/src/MEDMEMBinTest/create_mesh_c3h8.c b/src/MEDMEMBinTest/create_mesh_c3h8.c new file mode 100644 index 000000000..19a9cf890 --- /dev/null +++ b/src/MEDMEMBinTest/create_mesh_c3h8.c @@ -0,0 +1,308 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +/* + creation d'une geometrie 3d : un cube [0,1]^3 + maillé uniformement en hexahedres reguliers; + avec en plus une partie des faces (une partie + des faces de la frontiere) du maillage. + ATTENTION : 3 noeuds dans chaque direction +*/ + +#include <med.h> +#include <string.h> + +int main (int argc, char **argv) +{ + med_err ret; + med_idt fid; + char maa[MED_TAILLE_NOM+1] = "CUBE_EN_HEXA8"; + char maadesc[MED_TAILLE_DESC+1] = "Example de maillage non structure 3D"; + med_int mdim = 3; + med_int nnoe = 27; + /* + les noeuds: + */ + med_float coo[81] = { + 0.0, 0.0, 0.0, + 0.5, 0.0, 0.0, + 1.0, 0.0, 0.0, + 0.0, 0.5, 0.0, + 0.5, 0.5, 0.0, + 1.0, 0.5, 0.0, + 0.0, 1.0, 0.0, + 0.5, 1.0, 0.0, + 1.0, 1.0, 0.0, + 0.0, 0.0, 0.5, + 0.5, 0.0, 0.5, + 1.0, 0.0, 0.5, + 0.0, 0.5, 0.5, + 0.5, 0.5, 0.5, + 1.0, 0.5, 0.5, + 0.0, 1.0, 0.5, + 0.5, 1.0, 0.5, + 1.0, 1.0, 0.5, + 0.0, 0.0, 1.0, + 0.5, 0.0, 1.0, + 1.0, 0.0, 1.0, + 0.0, 0.5, 1.0, + 0.5, 0.5, 1.0, + 1.0, 0.5, 1.0, + 0.0, 1.0, 1.0, + 0.5, 1.0, 1.0, + 1.0, 1.0, 1.0 + }; + char nomcoo[3*MED_TAILLE_PNOM+1] = "x y z "; + char unicoo[3*MED_TAILLE_PNOM+1] = "cm cm cm "; + /* char nomnoe[19*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4";*/ + char *nomnoe ; + med_int numnoe[27] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27}; + med_int nufano[27] = {1,1,1,1,1,1,1,1,1,3,3,3,3,0,3,3,3,3,2,2,2,2,2,2,2,2,2}; + /* + les elements: + */ + med_int nhexa8 = 8; + med_int hexa8[64] = { + 4, 13, 14, 5, 1, 10, 11, 2, + 5, 14, 15, 6, 2, 11, 12, 3, + 7, 16, 17, 8, 4, 13, 14, 5, + 8, 17, 18, 9, 5, 14, 15, 6, + 13, 22, 23, 14, 10, 19, 20, 11, + 14, 23, 24, 15, 11, 20, 21, 12, + 16, 25, 26, 17, 13, 22, 23, 14, + 17, 26, 27, 18, 14, 23, 24, 15 + }; + char nomhexa8[MED_TAILLE_PNOM*8+1] = "hexa1 hexa2 hexa3 hexa4 hexa5 hexa6 hexa7 hexa8 "; + med_int numhexa8[8] = {1,2,3,4,5,6,7,8}; + med_int nufahexa8[8] = {-1,-1,-1,-1,-2,-2,-2,-2}; + + char nomfam[MED_TAILLE_NOM+1]; + med_int numfam; + char attdes[MED_TAILLE_DESC+1]; + med_int natt; + med_int attide; + med_int attval; + med_int ngro; + char gro[MED_TAILLE_LNOM+1]; + int i; + int nfame = 1; + int nfamn = 1; + int nfamf = 1; + + /* + Some fields : 2 on nodes : one int and one double , one on cells : double + */ + + char champ1[MED_TAILLE_NOM+1]="fieldnodeint" ; + char champ1_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ1_unit[MED_TAILLE_PNOM+1]="M " ; + med_int fieldnodeint[27] = {1,1,3,2,2,3,4,4,5,1,1,3,2,2,3,4,4,5,1,1,3,2,2,3,4,4,5}; + + char champ2[MED_TAILLE_NOM+1]="fieldnodedouble" ; + char champ2_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ2_unit[MED_TAILLE_PNOM+1]="J " ; + med_float fieldnodedouble1[27] = {1.,3.,4.,1.,3.,4.,3.,2.,5.,1.,3.,4.,1.,3.,4.,3.,2.,5.,1.,3.,4.,1.,3.,4.,3.,2.,5.}; + med_float fieldnodedouble2[27] = {1.,2.,2.,3.,3.,3.,4.,4.,5.,1.,2.,2.,3.,3.,3.,4.,4.,5.,1.,2.,2.,3.,3.,3.,4.,4.,5.}; + + char champ3[MED_TAILLE_NOM+1]="fieldcelldouble" ; + char champ3_comp[MED_TAILLE_PNOM*3+1]="comp1 comp2 comp3 " ; + char champ3_unit[MED_TAILLE_PNOM*3+1]="M/S m/s m/s " ; + med_float fieldcelldouble[8*3] = {0.,1.,1.,1.,1.,2.,2.,3.,0.,1.,1.,1.,1.,2.,2.,3.,0.,1.,1.,1.,1.,2.,2.,3.}; + + /***************************************************************************/ + fid = MEDouvrir("cube_hexa8.med",MED_LECTURE_ECRITURE); + if (fid < 0) + ret = -1; + else + ret = 0; + printf("MEDouvrir : %d\n",ret); + + /***************************************************************************/ + if (ret == 0) + ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); + printf("MEDmaaCr : %d\n",ret); + if (ret == 0) + ret = MEDunvCr(fid,maa); + printf("MEDunvCr : %d\n",ret); + + /***************************************************************************/ + if (ret == 0) + ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, + nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, + nufano,nnoe); + printf("MEDnoeudsEcr : %d\n",ret); + + /* ecriture des mailles MED_HEXA8 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,hexa8,MED_FULL_INTERLACE, + nomhexa8,MED_FAUX,numhexa8,MED_VRAI,nufahexa8,nhexa8, + MED_MAILLE,MED_HEXA8,MED_NOD); + printf("MEDelementsEcr : %d \n",ret); + + /***************************************************************************/ + /* ecriture des familles */ + /* Conventions : + - toujours creer une famille de numero 0 ne comportant aucun attribut + ni groupe (famille de reference pour les noeuds ou les elements + qui ne sont rattaches a aucun groupe ni attribut) + - les numeros de familles de noeuds sont > 0 + - les numeros de familles des elements sont < 0 + - rien d'imposer sur les noms de familles + */ + + /* la famille 0 */ + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_0"); + numfam = 0; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, + gro,0); + } + printf("%d \n",ret); + + /* on cree : + - 2 familles d'elements (-1,-2) et + - 3 familles de noeuds (1,2,3) + */ + + if (ret == 0) + { + nfame = 2; + for (i=0;i<nfame;i++) + { + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_ELEMENT_"); + numfam = -(i+1); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe1"); + ngro = 1; + + /*printf("nomfam : %s - numfam : %d - attide : %d - attval : %d - ngro : %d \n",nomfam,numfam,attide,attval,ngro);*/ + + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + } + } + + if (ret == 0) + { + nfamn = 3; + for (i=0;i<nfamn;i++) + { + if(ret == 0) + { + strcpy(nomfam,"FAMILLE_NOEUD_"); + numfam = i+1; + sprintf(nomfam,"%s%d",nomfam,numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe2"); + ngro = 1; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + } + } + + /***************************************************************************/ + /* + Les champs + */ + if (ret == 0) + { + ret = MEDchampCr(fid,champ1,MED_INT32,champ1_comp,champ1_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ1, (unsigned char *)fieldnodeint, + MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + MED_NOPDT," ", 0., MED_NONOR); + + printf("MEDchampEcr : %d \n",ret); + } + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ2,MED_FLOAT64,champ2_comp,champ2_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, + MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + 1,"S ", 1.1 , MED_NONOR); + printf("MEDchampEcr1 : %d \n",ret); + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble2, + MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + 2,"S ", 1.2 , MED_NONOR); + printf("MEDchampEcr2 : %d \n",ret); + } + } + + /* on met champ2 sans pas de temps pour pouvoir le lire aussi par defaut !*/ + if (ret == 0) + { + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, + MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + MED_NOPDT," ", 0. , MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ3,MED_FLOAT64,champ3_comp,champ3_unit,3); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble, + MED_FULL_INTERLACE, nhexa8, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_HEXA8, + MED_NOPDT," ", 0., MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + } + + /***************************************************************************/ + + ret = MEDfermer(fid); + printf("%d\n",ret); + + if ( getenv("srcdir") ) + /* we are in 'make check' */ + remove( "cube_hexa8.med" ); + + return 0; +} diff --git a/src/MEDMEMBinTest/create_mesh_c3h8q4.c b/src/MEDMEMBinTest/create_mesh_c3h8q4.c new file mode 100644 index 000000000..74bdce08c --- /dev/null +++ b/src/MEDMEMBinTest/create_mesh_c3h8q4.c @@ -0,0 +1,365 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +/* + creation d'une geometrie 3d : un cube [0,1]^3 + maillé uniformement en hexahedres reguliers; + avec en plus une partie des faces (une partie + des faces de la frontiere) du maillage. + ATTENTION : 3 noeuds dans chaque direction +*/ + +#include <med.h> +#include <string.h> + +int main (int argc, char **argv) +{ + med_err ret; + med_idt fid; + char maa[MED_TAILLE_NOM+1] = "CUBE_EN_HEXA8_QUAD4"; + char maadesc[MED_TAILLE_DESC+1] = "Example de maillage non structure 3D"; + med_int mdim = 3; + med_int nnoe = 27; + /* + les noeuds: + */ + med_float coo[81] = { + 0.0, 0.0, 0.0, + 0.5, 0.0, 0.0, + 1.0, 0.0, 0.0, + 0.0, 0.5, 0.0, + 0.5, 0.5, 0.0, + 1.0, 0.5, 0.0, + 0.0, 1.0, 0.0, + 0.5, 1.0, 0.0, + 1.0, 1.0, 0.0, + 0.0, 0.0, 0.5, + 0.5, 0.0, 0.5, + 1.0, 0.0, 0.5, + 0.0, 0.5, 0.5, + 0.5, 0.5, 0.5, + 1.0, 0.5, 0.5, + 0.0, 1.0, 0.5, + 0.5, 1.0, 0.5, + 1.0, 1.0, 0.5, + 0.0, 0.0, 1.0, + 0.5, 0.0, 1.0, + 1.0, 0.0, 1.0, + 0.0, 0.5, 1.0, + 0.5, 0.5, 1.0, + 1.0, 0.5, 1.0, + 0.0, 1.0, 1.0, + 0.5, 1.0, 1.0, + 1.0, 1.0, 1.0 + }; + char nomcoo[3*MED_TAILLE_PNOM+1] = "x y z "; + char unicoo[3*MED_TAILLE_PNOM+1] = "cm cm cm "; + /* char nomnoe[19*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4";*/ + char *nomnoe ; + med_int numnoe[27] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27}; + med_int nufano[27] = {1,1,1,1,1,1,1,1,1,3,3,3,3,0,3,3,3,3,2,2,2,2,2,2,2,2,2}; + /* + les elements: + */ + med_int nhexa8 = 8; + med_int hexa8[64] = { + 4, 13, 14, 5, 1, 10, 11, 2, + 5, 14, 15, 6, 2, 11, 12, 3, + 7, 16, 17, 8, 4, 13, 14, 5, + 8, 17, 18, 9, 5, 14, 15, 6, + 13, 22, 23, 14, 10, 19, 20, 11, + 14, 23, 24, 15, 11, 20, 21, 12, + 16, 25, 26, 17, 13, 22, 23, 14, + 17, 26, 27, 18, 14, 23, 24, 15 + }; + char nomhexa8[MED_TAILLE_PNOM*8+1] = "hexa1 hexa2 hexa3 hexa4 hexa5 hexa6 hexa7 hexa8 "; + med_int numhexa8[8] = {1,2,3,4,5,6,7,8}; + med_int nufahexa8[8] = {-1,-1,-1,-1,-2,-2,-2,-2}; + + /* + Les Faces qui dans ce cas (2D) sont des arretes + */ + + med_int nquad4 = 8; + med_int quad4[40] = { + 20, 21, 24, 23, 0, + 22, 23, 26, 25, 0, + 19, 20, 23, 22, 0, + 23, 24, 27, 26, 0, + 1 , 4, 5, 2, 0, + 5, 8, 9, 6, 0, + 2, 5, 6, 3, 0, + 7, 8, 5, 4, 0 + }; + + char nomquad4[MED_TAILLE_PNOM*8+1] = "quad1 quad2 quad3 quad4 quad5 quad6 quad7 quad8 "; + med_int numquad4[8] = {1,2,3,4,5,6,7,8}; + med_int nufaquad4[8] = {-3,-3,-3,-3,-4, -4, -4 , -4}; + + char nomfam[MED_TAILLE_NOM+1]; + med_int numfam; + char attdes[MED_TAILLE_DESC+1]; + med_int natt; + med_int attide; + med_int attval; + med_int ngro; + char gro[MED_TAILLE_LNOM+1]; + int i; + int nfame = 1; + int nfamn = 1; + int nfamf = 1; + + /* + Some fields : 2 on nodes : one int and one double , one on cells : double + */ + + char champ1[MED_TAILLE_NOM+1]="fieldnodeint" ; + char champ1_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ1_unit[MED_TAILLE_PNOM+1]="M " ; + med_int fieldnodeint[27] = {1,1,3,2,2,3,4,4,5,1,1,3,2,2,3,4,4,5,1,1,3,2,2,3,4,4,5}; + + char champ2[MED_TAILLE_NOM+1]="fieldnodedouble" ; + char champ2_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ2_unit[MED_TAILLE_PNOM+1]="J " ; + med_float fieldnodedouble1[27] = {1.,3.,4.,1.,3.,4.,3.,2.,5.,1.,3.,4.,1.,3.,4.,3.,2.,5.,1.,3.,4.,1.,3.,4.,3.,2.,5.}; + med_float fieldnodedouble2[27] = {1.,2.,2.,3.,3.,3.,4.,4.,5.,1.,2.,2.,3.,3.,3.,4.,4.,5.,1.,2.,2.,3.,3.,3.,4.,4.,5.}; + + char champ3[MED_TAILLE_NOM+1]="fieldcelldouble" ; + char champ3_comp[MED_TAILLE_PNOM*3+1]="comp1 comp2 comp3 " ; + char champ3_unit[MED_TAILLE_PNOM*3+1]="M/S m/s m/s " ; + med_float fieldcelldouble[8*3] = {0.,1.,1.,1.,1.,2.,2.,3.,0.,1.,1.,1.,1.,2.,2.,3.,0.,1.,1.,1.,1.,2.,2.,3.}; + + /***************************************************************************/ + fid = MEDouvrir("cube_hexa8_quad4.med",MED_LECTURE_ECRITURE); + if (fid < 0) + ret = -1; + else + ret = 0; + printf("MEDouvrir : %d\n",ret); + + /***************************************************************************/ + if (ret == 0) + ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); + printf("MEDmaaCr : %d\n",ret); + if (ret == 0) + ret = MEDunvCr(fid,maa); + printf("MEDunvCr : %d\n",ret); + + /***************************************************************************/ + if (ret == 0) + ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, + nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, + nufano,nnoe); + printf("MEDnoeudsEcr : %d\n",ret); + + /* ecriture des mailles MED_HEXA8 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,hexa8,MED_FULL_INTERLACE, + nomhexa8,MED_FAUX,numhexa8,MED_VRAI,nufahexa8,nhexa8, + MED_MAILLE,MED_HEXA8,MED_NOD); + printf("MEDelementsEcr : %d \n",ret); + + /* ecriture des mailles MED_QUAD4 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,quad4,MED_FULL_INTERLACE, + nomquad4,MED_FAUX,numquad4,MED_VRAI,nufaquad4,nquad4, + MED_MAILLE,MED_QUAD4,MED_NOD); + printf("%d \n",ret); + + /***************************************************************************/ + /* ecriture des familles */ + /* Conventions : + - toujours creer une famille de numero 0 ne comportant aucun attribut + ni groupe (famille de reference pour les noeuds ou les elements + qui ne sont rattaches a aucun groupe ni attribut) + - les numeros de familles de noeuds sont > 0 + - les numeros de familles des elements sont < 0 + - rien d'imposer sur les noms de familles + */ + + /* la famille 0 */ + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_0"); + numfam = 0; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, + gro,0); + } + printf("%d \n",ret); + + /* on cree : + - 2 familles d'elements (-1,-2) et + - 3 familles de noeuds (1,2,3) + - 1 famille(s) d'elements de dimension (d-1) + en fait de face (-3) + */ + + if (ret == 0) + { + nfame = 2; + for (i=0;i<nfame;i++) + { + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_ELEMENT_"); + numfam = -(i+1); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe1"); + ngro = 1; + + /*printf("nomfam : %s - numfam : %d - attide : %d - attval : %d - ngro : %d \n",nomfam,numfam,attide,attval,ngro);*/ + + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + } + } + + if (ret == 0) + { + nfamn = 3; + for (i=0;i<nfamn;i++) + { + if(ret == 0) + { + strcpy(nomfam,"FAMILLE_NOEUD_"); + numfam = i+1; + sprintf(nomfam,"%s%d",nomfam,numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe2"); + ngro = 1; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + } + } + + if (ret == 0) + { + nfamf = 2; + for (i=0;i<nfamf;i++) + { + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_FACE_"); + numfam = -(i+3); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe3"); + ngro = 1; + /*printf("nomfam : %s - numfam : %d - attide : %d - attval : %d - ngro : %d \n",nomfam,numfam,attide,attval,ngro);*/ + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + } + } + + /***************************************************************************/ + /* + Les champs + */ + if (ret == 0) + { + ret = MEDchampCr(fid,champ1,MED_INT32,champ1_comp,champ1_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ1, (unsigned char *)fieldnodeint, + MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + MED_NOPDT," ", 0., MED_NONOR); + + printf("MEDchampEcr : %d \n",ret); + } + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ2,MED_FLOAT64,champ2_comp,champ2_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, + MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + 1,"S ", 1.1 , MED_NONOR); + printf("MEDchampEcr1 : %d \n",ret); + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble2, + MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + 2,"S ", 1.2 , MED_NONOR); + printf("MEDchampEcr2 : %d \n",ret); + } + } + + /* on met champ2 sans pas de temps pour pouvoir le lire aussi par defaut !*/ + if (ret == 0) + { + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, + MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + MED_NOPDT," ", 0. , MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ3,MED_FLOAT64,champ3_comp,champ3_unit,3); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble, + MED_FULL_INTERLACE, nhexa8, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_HEXA8, + MED_NOPDT," ", 0., MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + } + + /***************************************************************************/ + + ret = MEDfermer(fid); + printf("%d\n",ret); + + if ( getenv("srcdir") ) + /* we are in 'make check' */ + remove( "cube_hexa8_quad4.med" ); + + return 0; +} diff --git a/src/MEDMEMBinTest/create_mesh_c3h8q4_wrong.c b/src/MEDMEMBinTest/create_mesh_c3h8q4_wrong.c new file mode 100644 index 000000000..8a73bcda1 --- /dev/null +++ b/src/MEDMEMBinTest/create_mesh_c3h8q4_wrong.c @@ -0,0 +1,369 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +/* + creation d'une geometrie 3d : un cube [0,1]^3 + maillé uniformement en hexahedres reguliers; + avec en plus une partie des faces (une partie + des faces de la frontiere) du maillage. + ATTENTION : 3 noeuds dans chaque direction +*/ + +#include <med.h> +#include <string.h> + +int main (int argc, char **argv) +{ + med_err ret; + med_idt fid; + char maa[MED_TAILLE_NOM+1] = "CUBE_EN_HEXA8_QUAD4_WRONG"; + char maadesc[MED_TAILLE_DESC+1] = "Example de maillage non structure 3D"; + med_int mdim = 3; + med_int nnoe = 27; + /* + les noeuds: + */ + med_float coo[81] = { + 0.0, 0.0, 0.0, + 0.5, 0.0, 0.0, + 1.0, 0.0, 0.0, + 0.0, 0.5, 0.0, + 0.5, 0.5, 0.0, + 1.0, 0.5, 0.0, + 0.0, 1.0, 0.0, + 0.5, 1.0, 0.0, + 1.0, 1.0, 0.0, + 0.0, 0.0, 0.5, + 0.5, 0.0, 0.5, + 1.0, 0.0, 0.5, + 0.0, 0.5, 0.5, + 0.5, 0.5, 0.5, + 1.0, 0.5, 0.5, + 0.0, 1.0, 0.5, + 0.5, 1.0, 0.5, + 1.0, 1.0, 0.5, + 0.0, 0.0, 1.0, + 0.5, 0.0, 1.0, + 1.0, 0.0, 1.0, + 0.0, 0.5, 1.0, + 0.5, 0.5, 1.0, + 1.0, 0.5, 1.0, + 0.0, 1.0, 1.0, + 0.5, 1.0, 1.0, + 1.0, 1.0, 1.0 + }; + char nomcoo[3*MED_TAILLE_PNOM+1] = "x y z "; + char unicoo[3*MED_TAILLE_PNOM+1] = "cm cm cm "; + /* char nomnoe[19*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4";*/ + char *nomnoe ; + med_int numnoe[27] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27}; + med_int nufano[27] = {1,1,1,1,1,1,1,1,1,3,3,3,3,0,3,3,3,3,2,2,2,2,2,2,2,2,2}; + /* + les elements: + */ + med_int nhexa8 = 8; + med_int hexa8[64] = { + 4, 13, 14, 5, 1, 10, 11, 2, + 5, 14, 15, 6, 2, 11, 12, 3, + 7, 16, 17, 8, 4, 13, 14, 5, + 8, 17, 18, 9, 5, 14, 15, 6, + 13, 22, 23, 14, 10, 19, 20, 11, + 14, 23, 24, 15, 11, 20, 21, 12, + 16, 25, 26, 17, 13, 22, 23, 14, + 17, 26, 27, 18, 14, 23, 24, 15 + }; + char nomhexa8[MED_TAILLE_PNOM*8+1] = "hexa1 hexa2 hexa3 hexa4 hexa5 hexa6 hexa7 hexa8 "; + med_int numhexa8[8] = {1,2,3,4,5,6,7,8}; + med_int nufahexa8[8] = {-1,-1,-1,-1,-2,-2,-2,-2}; + + /* + Les Faces qui dans ce cas (2D) sont des arretes + + a face is wrongly oriented, it is just to test the applidation + duplicateMEDMESH + */ + + med_int nquad4 = 8; + med_int quad4[32] = { + 20, 21, 24, 23, + 22, 23, 26, 25, + 19, 20, 23, 22, + 23, 24, 27, 26, + /*1 , 4, 5, 2,*/ + 1 , 2, 5, 4, + 5, 8, 9, 6, + 2, 5, 6, 3, + 7, 8, 5, 4 + }; + + char nomquad4[MED_TAILLE_PNOM*8+1] = "quad1 quad2 quad3 quad4 quad5 quad6 quad7 quad8 "; + med_int numquad4[8] = {1,2,3,4,5,6,7,8}; + med_int nufaquad4[8] = {-3,-3,-3,-3,-4, -4, -4 , -4}; + + char nomfam[MED_TAILLE_NOM+1]; + med_int numfam; + char attdes[MED_TAILLE_DESC+1]; + med_int natt; + med_int attide; + med_int attval; + med_int ngro; + char gro[MED_TAILLE_LNOM+1]; + int i; + int nfame = 1; + int nfamn = 1; + int nfamf = 1; + + /* + Some fields : 2 on nodes : one int and one double , one on cells : double + */ + + char champ1[MED_TAILLE_NOM+1]="fieldnodeint" ; + char champ1_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ1_unit[MED_TAILLE_PNOM+1]="M " ; + med_int fieldnodeint[27] = {1,1,3,2,2,3,4,4,5,1,1,3,2,2,3,4,4,5,1,1,3,2,2,3,4,4,5}; + + char champ2[MED_TAILLE_NOM+1]="fieldnodedouble" ; + char champ2_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ2_unit[MED_TAILLE_PNOM+1]="J " ; + med_float fieldnodedouble1[27] = {1.,3.,4.,1.,3.,4.,3.,2.,5.,1.,3.,4.,1.,3.,4.,3.,2.,5.,1.,3.,4.,1.,3.,4.,3.,2.,5.}; + med_float fieldnodedouble2[27] = {1.,2.,2.,3.,3.,3.,4.,4.,5.,1.,2.,2.,3.,3.,3.,4.,4.,5.,1.,2.,2.,3.,3.,3.,4.,4.,5.}; + + char champ3[MED_TAILLE_NOM+1]="fieldcelldouble" ; + char champ3_comp[MED_TAILLE_PNOM*3+1]="comp1 comp2 comp3 " ; + char champ3_unit[MED_TAILLE_PNOM*3+1]="M/S m/s m/s " ; + med_float fieldcelldouble[8*3] = {0.,1.,1.,1.,1.,2.,2.,3.,0.,1.,1.,1.,1.,2.,2.,3.,0.,1.,1.,1.,1.,2.,2.,3.}; + + /***************************************************************************/ + fid = MEDouvrir("cube_hexa8_quad4_wrong.med",MED_LECTURE_ECRITURE); + if (fid < 0) + ret = -1; + else + ret = 0; + printf("MEDouvrir : %d\n",ret); + + /***************************************************************************/ + if (ret == 0) + ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); + printf("MEDmaaCr : %d\n",ret); + if (ret == 0) + ret = MEDunvCr(fid,maa); + printf("MEDunvCr : %d\n",ret); + + /***************************************************************************/ + if (ret == 0) + ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, + nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, + nufano,nnoe); + printf("MEDnoeudsEcr : %d\n",ret); + + /* ecriture des mailles MED_HEXA8 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,hexa8,MED_FULL_INTERLACE, + nomhexa8,MED_FAUX,numhexa8,MED_VRAI,nufahexa8,nhexa8, + MED_MAILLE,MED_HEXA8,MED_NOD); + printf("MEDelementsEcr : %d \n",ret); + + /* ecriture des mailles MED_QUAD4 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,quad4,MED_FULL_INTERLACE, + nomquad4,MED_FAUX,numquad4,MED_VRAI,nufaquad4,nquad4, + MED_FACE,MED_QUAD4,MED_NOD); + printf("MEDelementsEcr : %d \n",ret); + + /***************************************************************************/ + /* ecriture des familles */ + /* Conventions : + - toujours creer une famille de numero 0 ne comportant aucun attribut + ni groupe (famille de reference pour les noeuds ou les elements + qui ne sont rattaches a aucun groupe ni attribut) + - les numeros de familles de noeuds sont > 0 + - les numeros de familles des elements sont < 0 + - rien d'imposer sur les noms de familles + */ + + /* la famille 0 */ + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_0"); + numfam = 0; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, + gro,0); + } + printf("%d \n",ret); + + /* on cree : + - 2 familles d'elements (-1,-2) et + - 3 familles de noeuds (1,2,3) + - 1 famille(s) d'elements de dimension (d-1) + en fait de face (-3) + */ + + if (ret == 0) + { + nfame = 2; + for (i=0;i<nfame;i++) + { + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_ELEMENT_"); + numfam = -(i+1); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe1"); + ngro = 1; + + /*printf("nomfam : %s - numfam : %d - attide : %d - attval : %d - ngro : %d \n",nomfam,numfam,attide,attval,ngro);*/ + + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + } + } + + if (ret == 0) + { + nfamn = 3; + for (i=0;i<nfamn;i++) + { + if(ret == 0) + { + strcpy(nomfam,"FAMILLE_NOEUD_"); + numfam = i+1; + sprintf(nomfam,"%s%d",nomfam,numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe2"); + ngro = 1; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + } + } + + if (ret == 0) + { + nfamf = 2; + for (i=0;i<nfamf;i++) + { + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_FACE_"); + numfam = -(i+3); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe3"); + ngro = 1; + /*printf("nomfam : %s - numfam : %d - attide : %d - attval : %d - ngro : %d \n",nomfam,numfam,attide,attval,ngro);*/ + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + } + } + + /***************************************************************************/ + /* + Les champs + */ + if (ret == 0) + { + ret = MEDchampCr(fid,champ1,MED_INT32,champ1_comp,champ1_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ1, (unsigned char *)fieldnodeint, + MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + MED_NOPDT," ", 0., MED_NONOR); + + printf("MEDchampEcr : %d \n",ret); + } + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ2,MED_FLOAT64,champ2_comp,champ2_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, + MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + 1,"S ", 1.1 , MED_NONOR); + printf("MEDchampEcr1 : %d \n",ret); + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble2, + MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + 2,"S ", 1.2 , MED_NONOR); + printf("MEDchampEcr2 : %d \n",ret); + } + } + + /* on met champ2 sans pas de temps pour pouvoir le lire aussi par defaut !*/ + if (ret == 0) + { + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, + MED_FULL_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + MED_NOPDT," ", 0. , MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ3,MED_FLOAT64,champ3_comp,champ3_unit,3); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble, + MED_FULL_INTERLACE, nhexa8, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_HEXA8, + MED_NOPDT," ", 0., MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + } + + /***************************************************************************/ + + ret = MEDfermer(fid); + printf("%d\n",ret); + + if ( getenv("srcdir") ) + /* we are in 'make check' */ + remove( "cube_hexa8_quad4_wrong.med" ); + + return 0; +} diff --git a/src/MEDMEMBinTest/create_poly2D.c b/src/MEDMEMBinTest/create_poly2D.c new file mode 100644 index 000000000..c6528da90 --- /dev/null +++ b/src/MEDMEMBinTest/create_poly2D.c @@ -0,0 +1,334 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +/* + creation d'une geometrie 2d : + maillé en 4 quadrangles reguliers + 1 triangle et 1 polygone. + +*/ + +#include <med.h> +#include <string.h> + +int main (int argc, char **argv) +{ + med_err ret; + med_idt fid; + char maa[MED_TAILLE_NOM+1] = "poly2D"; + char maadesc[MED_TAILLE_DESC+1] = "Example de maillage non structure 2D avec 1 polygone"; + med_int mdim = 2; + med_int nnoe = 11; + /* + les noeuds: + */ + med_float coo[22] = { + 0.0, 0.0, + 0.5, 0.0, + 1.0, 0.0, + 0.25, 0.5, + 0.5, 0.5, + 0.75, 0.5, + 0.0, 1.0, + 0.5, 1.0, + 1.0, 1.0, + 1.5, 0.0, + 1.5, 1.0 + }; + char nomcoo[2*MED_TAILLE_PNOM+1] = "x y "; + char unicoo[2*MED_TAILLE_PNOM+1] = "cm cm "; + /* char nomnoe[19*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4";*/ + char *nomnoe ; + med_int numnoe[11] = {1,2,3,4,5,6,7,8,9,10,11}; + med_int nufano[11] = {0,0,0,0,0,0,0,0,0,0,0}; + /* + les elements: + */ + med_int nquad4 = 4; + med_int quad4[16] = { + 4, 5, 2, 1, + 5, 6, 3, 2, + 7, 8, 5, 4, + 8, 9, 6, 5 + }; + char nomquad4[MED_TAILLE_PNOM*4+1] = "quad1 quad2 quad3 quad4 "; + med_int numquad4[4] = {1,2,3,4}; + med_int nufaquad4[4] = {-1,-1,0,0}; + + med_int ntria3 = 1; + med_int tria3[3] = { + 7, 4, 1 + }; + char nomtria3[MED_TAILLE_PNOM+1] = "tria1 "; + med_int numtria3[1] = {1}; + med_int nufatria3[1] = {-2}; + + med_int npoly = 1; + med_int nindexpoly = 2; + med_int indexpoly [2] = { + 1,6 + }; + med_int poly[5] = { + 9,11,10,3,6 + }; + char nompoly[MED_TAILLE_PNOM+1] = "poly "; + med_int numpoly[1] = {1}; + med_int nufapoly[1] = {-3}; + + char nomfam[MED_TAILLE_NOM+1]; + med_int numfam; + char attdes[MED_TAILLE_DESC+1]; + med_int natt; + med_int attide; + med_int attval; + med_int ngro; + char gro[MED_TAILLE_LNOM+1]; + int i; + int nfame = 2; + int nfamn = 1; + + /* + Some fields : 2 on nodes : one int and one double , one on cells : double + */ + char champ1[MED_TAILLE_NOM+1]="fieldnodeint" ; + char champ1_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ1_unit[MED_TAILLE_PNOM+1]="M " ; + med_int fieldnodeint[9] = {1,1,3,2,2,3,4,4,5}; + + char champ2[MED_TAILLE_NOM+1]="fieldnodedouble" ; + char champ2_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ2_unit[MED_TAILLE_PNOM+1]="J " ; + med_float fieldnodedouble1[9] = {1.,3.,4.,1.,3.,4.,3.,2.,5.}; + med_float fieldnodedouble2[9] = {1.,2.,2.,3.,3.,3.,4.,4.,5.}; + + char champ3[MED_TAILLE_NOM+1]="fieldcelldouble" ; + char champ3_comp[MED_TAILLE_PNOM*2+1]="comp1 comp2 " ; + char champ3_unit[MED_TAILLE_PNOM*2+1]="M/S m/s " ; + med_float fieldcelldouble[4*2] = {0.,1.,1.,1.,1.,2.,2.,3.}; + + /***************************************************************************/ + fid = MEDouvrir("poly2D.med",MED_LECTURE_ECRITURE); + if (fid < 0) + ret = -1; + else + ret = 0; + printf("MEDouvrir : %d\n",ret); + + /***************************************************************************/ + if (ret == 0) + ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); + printf("MEDmaaCr : %d\n",ret); + if (ret == 0) + ret = MEDunvCr(fid,maa); + printf("MEDunvCr : %d\n",ret); + + /***************************************************************************/ + if (ret == 0) + ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, + nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, + nufano,nnoe); + printf("MEDnoeudsEcr : %d\n",ret); + + /* ecriture des mailles MED_QUAD4 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,quad4,MED_FULL_INTERLACE, + nomquad4,MED_FAUX,numquad4,MED_VRAI,nufaquad4,nquad4, + MED_MAILLE,MED_QUAD4,MED_NOD); + printf("MEDelementsEcr for quad : %d \n",ret); + + /* ecriture des mailles MED_TRIA3 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,tria3,MED_FULL_INTERLACE, + nomtria3,MED_FAUX,numtria3,MED_VRAI,nufatria3,ntria3, + MED_MAILLE,MED_TRIA3,MED_NOD); + printf("MEDelementsEcr for tria : %d \n",ret); + + /* ecriture des mailles MED_POLYGONE: + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles + Dans ce cas il n existe pas de routine globale (Warning !!) + */ + + if (ret == 0) + ret = MEDpolygoneConnEcr(fid,maa,indexpoly,nindexpoly,poly, + MED_MAILLE,MED_NOD); + printf("MEDpolygoneConnEcr: %d \n",ret); + + if (ret == 0) + MEDnomEcr(fid,maa,nompoly,npoly,MED_MAILLE,MED_POLYGONE); + printf("MEDnomEcr for poly : %d \n",ret); + + if (ret == 0) + MEDnumEcr(fid,maa,numpoly,npoly,MED_MAILLE,MED_POLYGONE); + printf("MEDnumEcr for poly : %d \n",ret); + + if (ret == 0) + MEDfamEcr(fid,maa,nufapoly,npoly,MED_MAILLE,MED_POLYGONE); + printf("MEDfamEcr for poly : %d \n",ret); + + + /***************************************************************************/ + /* ecriture des familles */ + /* Conventions : + - toujours creer une famille de numero 0 ne comportant aucun attribut + ni groupe (famille de reference pour les noeuds ou les elements + qui ne sont rattaches a aucun groupe ni attribut) + - les numeros de familles de noeuds sont > 0 + - les numeros de familles des elements sont < 0 + - rien d'imposer sur les noms de familles + */ + + /* la famille 0 */ + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_0"); + numfam = 0; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, + gro,0); + } + printf("MEDfamCr : %d \n",ret); + + /* on cree : + - 2 familles d'elements de dimension (d) + en fait de face (-10) + */ + if (ret == 0) + { + numfam = -1; + strcpy(nomfam,"FAMILLE_CELL_"); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe0"); + ngro = 1; + + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + + numfam = -2; + strcpy(nomfam,"FAMILLE_CELL_"); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe0"); + ngro = 1; + + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + + numfam = -3; + strcpy(nomfam,"FAMILLE_CELL_"); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe0"); + ngro = 1; + + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + + /***************************************************************************/ + /* + Les champs + */ + if (ret == 0) + { + ret = MEDchampCr(fid,champ1,MED_INT32,champ1_comp,champ1_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ1, (unsigned char *)fieldnodeint, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + MED_NOPDT," ", 0., MED_NONOR); + + printf("MEDchampEcr : %d \n",ret); + } + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ2,MED_FLOAT64,champ2_comp,champ2_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + 1,"S ", 1.1 , MED_NONOR); + printf("MEDchampEcr1 : %d \n",ret); + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble2, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + 2,"S ", 1.2 , MED_NONOR); + printf("MEDchampEcr2 : %d \n",ret); + } + } + + // on met champ2 sans pas de temps pour pouvoir le lire aussi par defaut ! + if (ret == 0) + { + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + MED_NOPDT," ", 0. , MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ3,MED_FLOAT64,champ3_comp,champ3_unit,2); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldcelldouble, + MED_NO_INTERLACE, nquad4, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_MAILLE, MED_QUAD4, + MED_NOPDT," ", 0., MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + } + + /***************************************************************************/ + + ret = MEDfermer(fid); + printf("MEDfermer : %d\n",ret); + + return 0; +} + diff --git a/src/MEDMEMBinTest/create_poly3D.c b/src/MEDMEMBinTest/create_poly3D.c new file mode 100644 index 000000000..5e55287f2 --- /dev/null +++ b/src/MEDMEMBinTest/create_poly3D.c @@ -0,0 +1,445 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +/* + creation d'une geometrie 3d : + maillé en : + - 2 polyedres + ayant pour faces 3 polygones + 9 quadrangles + 6 triangles + - 1 tetra4 + +*/ + +#include <med.h> +#include <string.h> + +int main (int argc, char **argv) +{ + med_err ret; + med_idt fid; + char maa[MED_TAILLE_NOM+1] = "poly3D"; + char maadesc[MED_TAILLE_DESC+1] = "Example de maillage non structure 3D avec 2 polyedres+1tetra4 comme mailles et 3 polygones comme faces"; + med_int mdim = 3; + med_int nnoe = 19; + /* + les noeuds: + */ + med_float coo[57] = { + 2.0, 3.0, 2.0, + 3.0, 2.0, 2.0, + 4.0, 1.0, 2.0, + 2.0, 0.0, 2.0, + 0.0, 1.0, 2.0, + 1.0, 2.0, 2.0, + 2.0, 3.0, 1.0, + 3.0, 2.0, 0.0, + 4.0, 1.0, 0.0, + 2.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 1.0, 2.0, 0.0, + 5.0, 3.0, 2.0, + 7.0, 2.0, 2.0, + 6.0, 0.0, 2.0, + 6.0, 3.0, 0.0, + 7.0, 2.0, 0.0, + 6.0, 0.0, -1.0, + 5.0, 1.0, -3.0 + }; + char nomcoo[3*MED_TAILLE_PNOM+1] = "x y z "; + char unicoo[3*MED_TAILLE_PNOM+1] = "cm cm cm "; + /* char nomnoe[18*MED_TAILLE_PNOM+1] = "nom1 nom2 nom3 nom4";*/ + char *nomnoe ; + med_int numnoe[19] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + med_int nufano[19] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + /* + les elements: + */ + /* Faces QUAD4 */ + med_int nquad4 = 8; + med_int quad4[32] = { + 1, 7, 8, 2, + 2, 8, 9, 3, + 4, 3, 9, 10, + 5, 4, 10, 11, + 6, 5, 11, 12, + 1, 6, 12, 7, + 14, 13, 16, 17, + 8, 9, 17, 16 + }; + char nomquad4[MED_TAILLE_PNOM*8+1] = "quad1 quad2 quad3 quad4 quad5 quad6 quad7 quad8 "; + med_int numquad4[9] = {2,3,4,5,6,7,12,17}; + med_int nufaquad4[9] = {-1,-1,-1,-1,-1,-1,-1,-1}; + + /* Faces TRIA3 */ + med_int ntria3 = 6; + med_int tria3[18] = { + 7, 12, 8, + 15, 14, 17, + 15, 17, 18, + 15, 18, 9, + 3, 15, 9, + 18, 17, 9 + }; + char nomtria3[MED_TAILLE_PNOM*6+1] = "tria1 tria2 tria3 tria4 tria5 tria6 "; + med_int numtria3[6] = {8,13,14,15,16,18}; + med_int nufatria3[6] = {-2,-2,-2,-2,-2,-2}; + + /* Faces POLYGONE */ + med_int npolygon = 3; + med_int nindexpolygon = 4; + med_int indexpolygon [4] = { + 1, 7, 12, 17 + }; + med_int polygon[16] = { + 1, 2, 3, 4, 5, 6, + 10, 9, 8, 12, 11, + 13, 14, 15, 3, 2 + }; + char nompolygon[MED_TAILLE_PNOM*3+1] = "polygon1 polygon2 polygon3 "; + med_int numpolygon[3] = {1,9,10}; + med_int nufapolygon[3] = {-3,-3,-3}; + + /* Mailles POLYEDRE */ + med_int npolyhedron = 2; + med_int npolyhedronfaces = 19; + med_int npolyhedronnodes = 74; + med_int polyhedronconnectivity[74] = {1,2,3,4,5,6,1,7,8,2,2,8,9,3,4,3,9,10,5,4,10,11,6,5,11,12,1,6,12,7,7,12,8,10,9,8,12,11, + 13,14,15,3,2,13,2,8,16,14,13,16,17,15,14,17,15,17,18,15,18,9,3,15,9,2,3,9,8,8,9,17,16,9,18,17}; + med_int polyhedronfacesindex[20] = {1,7,11,15,19,23,27,31,34, + 39,44,48,52,55,58,61,64,68,72,75}; + med_int polyhedronindex[3] = {1,10,20}; + char nompolyhedron[MED_TAILLE_PNOM*2+1] = "polyhedron1 polyhedron2 "; + med_int numpolyhedron[2] = {2,3}; + med_int nufapolyhedron[2] = {-4,-4}; + + /* Mailles TETRA4 */ + med_int ntetra4 = 1; + med_int tetra4[4] = { + 17, 9, 18, 19 + }; + char nomtetra4[MED_TAILLE_PNOM*1+1] = "tetra1 "; + med_int numtetra4[1] = {1}; + med_int nufatetra4[1] = {-5}; + + + char nomfam[MED_TAILLE_NOM+1]; + med_int numfam; + char attdes[MED_TAILLE_DESC+1]; + med_int natt; + med_int attide; + med_int attval; + med_int ngro; + char gro[MED_TAILLE_LNOM+1]; + int i; + int nfame = 2; + int nfamn = 1; + + /* + Some fields : 2 on nodes : one int and one double , one on cells : double + */ + char champ1[MED_TAILLE_NOM+1]="fieldnodeint" ; + char champ1_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ1_unit[MED_TAILLE_PNOM+1]="M " ; + med_int fieldnodeint[19] = {1,1,3,2,2,3,4,4,5,6,6,7,8,8,9,9,9,10,5}; + + char champ2[MED_TAILLE_NOM+1]="fieldnodedouble" ; + char champ2_comp[MED_TAILLE_PNOM+1]="comp1 " ; + char champ2_unit[MED_TAILLE_PNOM+1]="J " ; + med_float fieldnodedouble1[19] = {1.,3.,4.,1.,3.,4.,3.,2.,5.,6.,4.,3.,1.,5.,6.,4.,3.,7.,3.}; + med_float fieldnodedouble2[19] = {1.,2.,2.,3.,3.,3.,4.,4.,5.,2.,8.,9.,6.,7.,1.,2.,5.,8.,4.}; + + char champ3[MED_TAILLE_NOM+1]="fieldfacedouble" ; + char champ3_comp[MED_TAILLE_PNOM*2+1]="comp1 comp2 " ; + char champ3_unit[MED_TAILLE_PNOM*2+1]="M/S m/s " ; + med_float fieldfacedouble[6*2] = {0.,1.,1.,1.,1.,2.,2.,3.,3.,4.,4.,6.}; + + /***************************************************************************/ + fid = MEDouvrir("poly3D.med",MED_LECTURE_ECRITURE); + if (fid < 0) + ret = -1; + else + ret = 0; + printf("MEDouvrir : %d\n",ret); + + /***************************************************************************/ + if (ret == 0) + ret = MEDmaaCr(fid,maa,mdim,MED_NON_STRUCTURE,maadesc); + printf("MEDmaaCr : %d\n",ret); + if (ret == 0) + ret = MEDunvCr(fid,maa); + printf("MEDunvCr : %d\n",ret); + + /***************************************************************************/ + if (ret == 0) + ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, + nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, + nufano,nnoe); + printf("MEDnoeudsEcr : %d\n",ret); + + /* ecriture des faces MED_QUAD4 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,quad4,MED_FULL_INTERLACE, + nomquad4,MED_FAUX,numquad4,MED_VRAI,nufaquad4,nquad4, + MED_MAILLE,MED_QUAD4,MED_NOD); + printf("MEDelementsEcr for quad : %d \n",ret); + + /* ecriture des faces MED_TRIA3 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,tria3,MED_FULL_INTERLACE, + nomtria3,MED_FAUX,numtria3,MED_VRAI,nufatria3,ntria3, + MED_MAILLE,MED_TRIA3,MED_NOD); + printf("MEDelementsEcr for tria : %d \n",ret); + + /* ecriture des faces MED_POLYGONE : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles + Dans ce cas il n existe pas de routine globale (Warning !!) */ + if (ret == 0) + ret = MEDpolygoneConnEcr(fid,maa,indexpolygon,nindexpolygon,polygon, + MED_MAILLE,MED_NOD); + printf("MEDpolygoneConnEcr: %d \n",ret); + + if (ret == 0) + MEDnomEcr(fid,maa,nompolygon,npolygon,MED_MAILLE,MED_POLYGONE); + printf("MEDnomEcr for polygon : %d \n",ret); + + if (ret == 0) + MEDnumEcr(fid,maa,numpolygon,npolygon,MED_MAILLE,MED_POLYGONE); + printf("MEDnumEcr for polygon : %d \n",ret); + + if (ret == 0) + MEDfamEcr(fid,maa,nufapolygon,npolygon,MED_MAILLE,MED_POLYGONE); + printf("MEDfamEcr for polygon : %d \n",ret); + + /* ecriture des mailles MED_POLYEDRE : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles + Dans ce cas il n existe pas de routine globale (Warning !!) */ + if (ret == 0) + ret = MEDpolyedreConnEcr(fid,maa,polyhedronindex,npolyhedron+1,polyhedronfacesindex,npolyhedronfaces+1,polyhedronconnectivity,MED_NOD); + printf("MEDpolyedreConnEcr: %d \n",ret); + + if (ret == 0) + ret = MEDnomEcr(fid,maa,nompolyhedron,npolyhedron,MED_MAILLE,MED_POLYEDRE); + printf("MEDnomEcr for polyhedron : %d \n",ret); + + if (ret == 0) + ret = MEDnumEcr(fid,maa,numpolyhedron,npolyhedron,MED_MAILLE,MED_POLYEDRE); + printf("MEDnumEcr for polyhedron : %d \n",ret); + + if (ret == 0) + ret = MEDfamEcr(fid,maa,nufapolyhedron,npolyhedron,MED_MAILLE,MED_POLYEDRE); + printf("MEDfamEcr for polyhedron : %d \n",ret); + + /* ecriture des mailles TETRA4 : + - connectivite + - noms (optionnel) + - numeros (optionnel) + - numeros des familles */ + if (ret == 0) + ret = MEDelementsEcr(fid,maa,mdim,tetra4,MED_FULL_INTERLACE, + nomtetra4,MED_FAUX,numtetra4,MED_VRAI,nufatetra4,ntetra4, + MED_MAILLE,MED_TETRA4,MED_NOD); + printf("MEDelementsEcr for tetra : %d \n",ret); + + /***************************************************************************/ + /* ecriture des familles */ + /* Conventions : + - toujours creer une famille de numero 0 ne comportant aucun attribut + ni groupe (famille de reference pour les noeuds ou les elements + qui ne sont rattaches a aucun groupe ni attribut) + - les numeros de familles de noeuds sont > 0 + - les numeros de familles des elements sont < 0 + - rien d'imposer sur les noms de familles + */ + + /* la famille 0 */ + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_0"); + numfam = 0; + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes,0, + gro,0); + } + printf("MEDfamCr : %d \n",ret); + + /* on cree : + - 2 familles d'elements de dimension (d) + en fait de face (-10) + */ + /* + if (ret == 0) + { + numfam = -1; + strcpy(nomfam,"FAMILLE_FACE_QUAD4"); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe0"); + ngro = 1; + + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + + numfam = -2; + strcpy(nomfam,"FAMILLE_FACE_TRIA3"); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe0"); + ngro = 1; + + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + + numfam = -3; + strcpy(nomfam,"FAMILLE_FACE_POLYGONS"); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe0"); + ngro = 1; + + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + + numfam = -4; + strcpy(nomfam,"FAMILLE_MAILLE_POLYHEDRON"); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe0"); + ngro = 1; + + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + + numfam = -5; + strcpy(nomfam,"FAMILLE_MAILLE_TETRA4"); + sprintf(nomfam,"%s%d",nomfam,-numfam); + attide = 1; + attval = numfam*100; + natt = 1; + strcpy(attdes,"description attribut"); + strcpy(gro,"groupe0"); + ngro = 1; + + ret = MEDfamCr(fid,maa,nomfam,numfam,&attide,&attval,attdes, + natt,gro,ngro); + printf("MEDfamCr : %d\n",ret); + } + */ + /***************************************************************************/ + /* + Les champs + */ + if (ret == 0) + { + ret = MEDchampCr(fid,champ1,MED_INT32,champ1_comp,champ1_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ1, (unsigned char *)fieldnodeint, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + MED_NOPDT," ", 0., MED_NONOR); + + printf("MEDchampEcr : %d \n",ret); + } + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ2,MED_FLOAT64,champ2_comp,champ2_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + 1,"S ", 1.1 , MED_NONOR); + printf("MEDchampEcr1 : %d \n",ret); + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble2, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + 2,"S ", 1.2 , MED_NONOR); + printf("MEDchampEcr2 : %d \n",ret); + } + } + + // on met champ2 sans pas de temps pour pouvoir le lire aussi par defaut ! + if (ret == 0) + { + ret = MEDchampEcr(fid, maa, champ2, (unsigned char *)fieldnodedouble1, + MED_NO_INTERLACE, nnoe, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_NOEUD, 0, + MED_NOPDT," ", 0. , MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + + if (ret == 0) + { + ret = MEDchampCr(fid,champ3,MED_FLOAT64,champ3_comp,champ3_unit,2); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) { + ret = MEDchampEcr(fid, maa, champ3, (unsigned char *)fieldfacedouble, + MED_NO_INTERLACE, ntria3, MED_NOGAUSS, MED_ALL, + MED_NOPFL, MED_NO_PFLMOD, MED_FACE, MED_TRIA3, + MED_NOPDT," ", 0., MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + } + /***************************************************************************/ + + ret = MEDfermer(fid); + printf("MEDfermer : %d\n",ret); + + if ( getenv("srcdir") ) + /* we are in 'make check' */ + remove( "poly3D.med" ); + + return 0; +} + diff --git a/src/MEDMEMBinTest/duplicateMED.cxx b/src/MEDMEMBinTest/duplicateMED.cxx new file mode 100644 index 000000000..9aeaf3857 --- /dev/null +++ b/src/MEDMEMBinTest/duplicateMED.cxx @@ -0,0 +1,57 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include<string> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_Med.hxx" + +using namespace std; +using namespace MEDMEM; +void usage(char * name) +{ + cout << " " << name << " <input med file> <output med file> " <<endl ; + cout << " " << "(the two file name are mandatory)" << endl ; + exit(-1); +} + +int main (int argc, char ** argv) { + if (argc != 3) usage(argv[0]); + + string filenameIN = argv[1] ; + string filenameOUT = argv[2] ; + + try { + + MED myMed(MED_DRIVER,filenameIN) ; // do readFilestruct ! + + // we read all meshes and fields in filenameIN + myMed.read() ; + + // we write all in file filenameOUT : + int id = myMed.addDriver(MED_DRIVER,filenameOUT) ; + myMed.write(id); + + } catch (MEDEXCEPTION& ex) { + MESSAGE_MED(ex.what()) ; + } + +} diff --git a/src/MEDMEMBinTest/duplicateMEDMESH.cxx b/src/MEDMEMBinTest/duplicateMEDMESH.cxx new file mode 100644 index 000000000..f7cf255c1 --- /dev/null +++ b/src/MEDMEMBinTest/duplicateMEDMESH.cxx @@ -0,0 +1,89 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include<string> +#include<deque> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_define.hxx" + +#include "MEDMEM_Med.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Support.hxx" + +#include "MEDMEM_GenDriver.hxx" +#include "MEDMEM_MedMedDriver.hxx" +#include "MEDMEM_MedMeshDriver.hxx" + +using namespace std; +using namespace MEDMEM; +int main (int argc, char ** argv) { + + if ( argc < 3 ) { + cout << "Usage: " << argv[0] << "<input med file> <output med file>" << endl; + return -1; + } + string filenameIN = argv[1] ; + string filenameOUT = argv[2] ; + + MED * myMed = new MED() ; + MED_MED_RDONLY_DRIVER myMedDriver(filenameIN,myMed) ; + + // we read all meshes in filenameIN + try { + + //int read ; !! UNUSED VARIABLE !! + myMedDriver.open(); + myMedDriver.readFileStruct(); + myMedDriver.close(); + + // read all mesh + MESSAGE_MED("Read all meshes :") ; + int NumberOfMeshes = myMed->getNumberOfMeshes() ; + MESSAGE_MED("Number of meshes : "<<NumberOfMeshes) ; + deque<string> MeshName = myMed->getMeshNames() ; + map<string,MESH*> _meshes ; + for (int i=0; i<NumberOfMeshes; i++) { + _meshes[MeshName[i]]=myMed->getMesh(MeshName[i]) ; + _meshes[MeshName[i]]->read(); + MESSAGE_MED(" - Mesh "<<i+1<<", named "<<MeshName[i]<<" read !"); + MED_MESH_WRONLY_DRIVER myMeshDriver(filenameOUT,_meshes[MeshName[i]]); + MESSAGE_MED("After declaration of MED_MESH_DRIVER"); + myMeshDriver.setMeshName(MeshName[i]); + MESSAGE_MED("After setMeshName"); + myMeshDriver.open() ; + MESSAGE_MED("After open"); + myMeshDriver.write() ; + MESSAGE_MED("After write"); + myMeshDriver.close() ; + MESSAGE_MED("After close"); + } + + // set support : support must be calculated with mesh information !!! + myMed->updateSupport() ; + + } catch (MEDEXCEPTION& ex){ + MESSAGE_MED(ex.what()) ; + return -1; + } + return 0; +} diff --git a/src/MEDMEMBinTest/ensight2med.cxx b/src/MEDMEMBinTest/ensight2med.cxx new file mode 100644 index 000000000..4fd1900b8 --- /dev/null +++ b/src/MEDMEMBinTest/ensight2med.cxx @@ -0,0 +1,112 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include<string> +#include<deque> +#include<vector> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_define.hxx" + +#include "MEDMEM_Med.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_EnsightMedDriver.hxx" + +using namespace std; +using namespace MEDMEM; +void usage(char * name) +{ + cout << " ERROR ABOUT SYNTAX " << endl ; + cout << " " << name << " <input ensight file> <output med file> [I - to read into MED_INT32 fields]" + << endl ; + exit(-1); +} + +// ensight2med toto.case toto.med => input : toto.case => output : toto.med.... + +int main (int argc, char ** argv) { + + string filenameIN ; + string filenameOUT; + + if ( argc == 3 ) { + filenameIN = argv[1] ; + filenameOUT = argv[2] ; + cout << " reading all into the Ensight file " << filenameIN << " and writing all into the Med file " << filenameOUT << endl ; + + MED myMed(ENSIGHT_DRIVER,filenameIN) ; + myMed.read() ; + + int id = myMed.addDriver(MED_DRIVER,filenameOUT); + myMed.write(id); + } + else if ( argc == 4 && strncmp(argv[3], "I", 1 )==0 ) + { + // we read all variables into INT32 fields + // (we need such fields for test_operation_fieldint) + + filenameIN = argv[1] ; + filenameOUT = argv[2] ; + MED myMed(ENSIGHT_DRIVER,filenameIN); + + // read-write the mesh + if ( myMed.getNumberOfMeshes() < 1 ) { + cout << "No meshes found in EnSight file " << filenameIN << endl; + return -1; + } + vector<string> meshNames( myMed.getNumberOfMeshes() ); + myMed.getMeshNames( &meshNames[0] ); + MESH * mesh = myMed.getMesh( meshNames[0] ); + mesh->read(); + int drv = mesh->addDriver(MED_DRIVER, filenameOUT, mesh->getName() ); + mesh->write( drv ); + + // read-write fields + int nbFields = myMed.getNumberOfFields(); + vector<string> fieldNames( nbFields ); + myMed.getFieldNames( &fieldNames[0] ); + for ( int i = 0; i < nbFields; ++i ) + { + deque<DT_IT_> dis = myMed.getFieldIteration( fieldNames[i] ); + for ( deque<DT_IT_>::iterator d_i = dis.begin(); d_i != dis.end(); ++d_i ) + { + FIELD_* f = myMed.getField( fieldNames[i], d_i->dt, d_i->it ); + FIELD<int> intF(ENSIGHT_DRIVER, filenameIN, f->getName() ); + // replace zero values as theses fields are used for division + int nbVals = intF.getValueLength(); + int* values = const_cast<int*>(intF.getValue()); + while ( nbVals-- ) { + if ( values[nbVals]==0 ) + values[nbVals]= nbVals%5 + 1; + } + int drv = intF.addDriver(MED_DRIVER, filenameOUT, f->getName() ); + intF.write( drv ); + } + } + } + else usage(argv[0]); + +} + + diff --git a/src/MEDMEMBinTest/med2_1_To_med2_2.cxx b/src/MEDMEMBinTest/med2_1_To_med2_2.cxx new file mode 100644 index 000000000..e08fa1ada --- /dev/null +++ b/src/MEDMEMBinTest/med2_1_To_med2_2.cxx @@ -0,0 +1,62 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_medimport_src.hxx" +#include <cstdlib> + +using namespace std; +using namespace MEDMEM; + +int main (int argc, char ** argv) +{ + if (argc != 2) + { + cerr << "Usage : " << argv[0] + << " fileNameIn" << endl ; + cerr << "Where - fileNameIn is .med V2.1 file supplied by the user including all the directory path" << endl; + cerr << "fileNameOut is .med V2.3.2 file produced by this command in the directory $HOME/TMP_Med2_3Files/" << endl; + cerr << "This command is supposed to be the same as the med File V2.2 medimport utility" << endl << endl; + cerr << "It will produce a med V2.3.2 file fileNameOut which will be in the directory $HOME/TMP_Med2_3Files/" << endl; + cerr << "with the same root name as fileNameIn: " << endl; + cerr << "If fileNameIn is /aPath/file.med so fileNameOut will be $HOME/TMP_Med2_3Files/file.med" << endl; + exit(-1); + } + + string fileNameIn = argv[1] ; + char * fileNameOut = med2_1_To_med2_3((const_cast <char *> + (fileNameIn.c_str()))); + + if (fileNameOut == ((char *) NULL)) + { + cerr << "A problem has occured in the importation of the file " << fileNameIn.c_str() << " into " << fileNameOut << endl; + } + else if(fileNameOut != string(fileNameIn).c_str()) + { + cerr << "the convertion has been successfull !! The resulting file is " << string(fileNameOut).c_str() << endl; + } + else + { + cerr << "No nedd to converte because the file is al ready a med 2.3.2 file" << endl; + } + + return 0; +} diff --git a/src/MEDMEMBinTest/med2ensight.cxx b/src/MEDMEMBinTest/med2ensight.cxx new file mode 100644 index 000000000..fe3f82ad1 --- /dev/null +++ b/src/MEDMEMBinTest/med2ensight.cxx @@ -0,0 +1,88 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include<string> +#include<deque> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_define.hxx" + +#include "MEDMEM_Med.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_EnsightMedDriver.hxx" + +using namespace std; +using namespace MEDMEM; + +void usage(char * name) +{ + cout << " ERROR ABOUT SYNTAX " << endl ; + cout << " " << name << " <input med file> <output ensight file> " << endl ; + exit(-1); +} + +int main (int argc, char ** argv) { + + string filenameIN ; + string filenameOUT; + + if ( argc == 3 ) { + filenameIN = argv[1] ; + filenameOUT = argv[2] ; + cout << "-> reading all into the Med file " << filenameIN << " and writing all into the Ensight file " << filenameOUT << endl ; + + MED myMed(MED_DRIVER,filenameIN) ; + + cout << "-> Read all meshes " ; + int NumberOfMeshes = myMed.getNumberOfMeshes() ; + cout << "( "<<NumberOfMeshes << " ) :" << endl ; + deque<string> MeshName = myMed.getMeshNames() ; + for (int i=0; i<NumberOfMeshes; i++) { + myMed.getMesh(MeshName[i])->read() ; + cout << "-> Mesh "<<i+1<<", named "<<MeshName[i]<<" is read !" << endl; + } + + myMed.updateSupport() ; + + cout << "-> Read all fields " ; + int NumberOfFields = myMed.getNumberOfFields() ; + cout << "( "<<NumberOfFields << " ) :" << endl; + deque<string> FieldName = myMed.getFieldNames() ; + for (int i=0; i<NumberOfFields; i++) { + deque<DT_IT_> FieldIteration = myMed.getFieldIteration(FieldName[i]) ; + cout << "-> Field "<<i+1<<", named "<<FieldName[i] << " :" << endl ; + int NumberOfIteration = FieldIteration.size() ; + cout << " Number of iteration pair : "<< NumberOfIteration << endl; + for (int j=0; j<NumberOfIteration; j++) { + FIELD_ * myField = myMed.getField(FieldName[i],FieldIteration[j].dt,FieldIteration[j].it) ; + + myField->read() ; + cout << " * Iteration "<<FieldIteration[j].dt<<" and order number "<<FieldIteration[j].it<<" ) is read !" << endl; + } + } + int id = myMed.addDriver(ENSIGHT_DRIVER,filenameOUT,MED_EN::WRONLY) ; + myMed.write(id) ; + } + else usage(argv[0]); +} diff --git a/src/MEDMEMBinTest/med2vtk.cxx b/src/MEDMEMBinTest/med2vtk.cxx new file mode 100644 index 000000000..e99ed7861 --- /dev/null +++ b/src/MEDMEMBinTest/med2vtk.cxx @@ -0,0 +1,105 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include<string> +#include<deque> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_define.hxx" + +#include "MEDMEM_Med.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_VtkMedDriver.hxx" + +using namespace std; +using namespace MEDMEM; +void usage(char * name) +{ + cout << " " << name << " <input med file> <output vtk file> " <<endl ; + cout << " " << "(the two file name are mandatory)" << endl ; + exit(-1); +} + +int main (int argc, char ** argv) { + if (argc != 3) usage(argv[0]); + + string filenameIN = argv[1] ; + string filenameOUT = argv[2] ; + + try { + ///////////////////////////////////////////////// + // we read all meshes and fields in filenameIN // + ///////////////////////////////////////////////// + MED myMed(MED_DRIVER,filenameIN) ; + + // read all meshes + //////////////////// + + cout << "Read all meshes " ; + int NumberOfMeshes = myMed.getNumberOfMeshes() ; + cout << "( "<<NumberOfMeshes << " ) :" << endl ; + deque<string> MeshName = myMed.getMeshNames() ; + for (int i=0; i<NumberOfMeshes; i++) { + myMed.getMesh(MeshName[i])->read() ; + cout << " - Mesh "<<i+1<<", named "<<MeshName[i]<<" is read !" << endl; + } + + // PROVISOIRE + /////////////// + + // set support : support must be calculated with mesh information !!! + myMed.updateSupport() ; + + // read all fields + //////////////////// + + cout << "Read all fields " ; + int NumberOfFields = myMed.getNumberOfFields() ; + cout << "( "<<NumberOfFields << " ) :" << endl; + deque<string> FieldName = myMed.getFieldNames() ; + for (int i=0; i<NumberOfFields; i++) { + deque<DT_IT_> FieldIteration = myMed.getFieldIteration(FieldName[i]) ; + cout << " - Field "<<i+1<<", named "<<FieldName[i] << " :" << endl ; + int NumberOfIteration = FieldIteration.size() ; + cout << " Number of iteration pair : "<< NumberOfIteration << endl; + for (int j=0; j<NumberOfIteration; j++) { + FIELD_ * myField = myMed.getField(FieldName[i],FieldIteration[j].dt,FieldIteration[j].it) ; + + myField->read() ; + cout << " * Iteration "<<FieldIteration[j].dt<<" and order number "<<FieldIteration[j].it<<" ) is read !" << endl; + } + } + + ////////////////////////////////////////// + // we write all in VTK file filenameOUT // + ///////////////////////////////////////// + int id = myMed.addDriver(VTK_DRIVER,filenameOUT) ; + myMed.write(id) ; + + } + catch (MEDEXCEPTION& ex){ + cout << ex.what() << endl ; + } + +} diff --git a/src/MEDMEMBinTest/med_test.cxx b/src/MEDMEMBinTest/med_test.cxx new file mode 100644 index 000000000..8ffbdb725 --- /dev/null +++ b/src/MEDMEMBinTest/med_test.cxx @@ -0,0 +1,474 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include<string> + +#include <math.h> +#include <stdlib.h> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Group.hxx" + +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_MedFieldDriver.hxx" +#include "MEDMEM_define.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +double dmax(double x, double y) { return (x>y)?x:y;} + +double dmin(double x, double y) { return (x>y)?y:x;} + +double infty = 1.e20; + +void affiche_support(const SUPPORT * mySupport) +{ + cout << " - Name : "<<mySupport->getName().c_str()<<endl ; + cout << " - Description : "<<mySupport->getDescription().c_str()<<endl ; + cout << " - Entity : "<<mySupport->getEntity()<<endl ; + cout << " - Entities list : "<<endl ; + if (!(mySupport->isOnAllElements())) { + int NumberOfTypes = mySupport->getNumberOfTypes() ; + cout<<" - NumberOfTypes : "<<NumberOfTypes<<endl; + const medGeometryElement * Types = mySupport->getTypes() ; + for (int j=0;j<NumberOfTypes;j++) { + cout << " * Type "<<Types[j]<<" : " ; + int NumberOfElements = mySupport->getNumberOfElements(Types[j]) ; + const int * Number = mySupport->getNumber(Types[j]) ; + for (int k=0; k<NumberOfElements;k++) + cout << Number[k] << " "; + cout << endl ; + } + } else + cout << " Is on all entities !"<< endl; +} + + +void affiche_famille(MESH *myMesh,medEntityMesh Entity) +{ + int NumberOfFamilies = myMesh->getNumberOfFamilies(Entity) ; + cout << "NumberOfFamilies : "<<NumberOfFamilies<<endl; + for (int i=1; i<NumberOfFamilies+1;i++) { + const FAMILY* myFamily = myMesh->getFamily(Entity,i); + affiche_support(myFamily); + cout << " - Identifier : "<<myFamily->getIdentifier()<<endl ; + int NumberOfAttributes = myFamily->getNumberOfAttributes() ; + cout << " - Attributes ("<<NumberOfAttributes<<") :"<<endl; + for (int j=1;j<NumberOfAttributes+1;j++) + cout << " * "<<myFamily->getAttributeIdentifier(j)<<" : "<<myFamily->getAttributeValue(j)<<", "<<myFamily->getAttributeDescription(j).c_str()<<endl ; + int NumberOfGroups = myFamily->getNumberOfGroups() ; + cout << " - Groups ("<<NumberOfGroups<<") :"<<endl; + for (int j=1;j<NumberOfGroups+1;j++) + cout << " * "<<myFamily->getGroupName(j).c_str()<<endl ; + } +} + +void affiche_groupe(MESH *myMesh,medEntityMesh Entity) +{ + int NumberOfGroups = myMesh->getNumberOfGroups(Entity) ; + cout << "NumberOfGroups : "<<NumberOfGroups<<endl; + for (int i=1; i<NumberOfGroups+1;i++) { + const GROUP* myGroup = myMesh->getGroup(Entity,i); + affiche_support(myGroup); + int NumberOfFamillies = myGroup->getNumberOfFamilies() ; + cout << " - Families ("<<NumberOfFamillies<<") :"<<endl; + for (int j=1;j<NumberOfFamillies+1;j++) + cout << " * "<<myGroup->getFamily(j)->getName().c_str()<<endl ; + } +} + +int main (int argc, char ** argv) { + + if ((argc !=3) && (argc != 4)) { + cerr << "Usage : " << argv[0] + << " filename meshname [fieldname]" << endl << endl; + exit(-1); + } + + string filename = argv[1] ; + string meshname = argv[2] ; + + // MESH * myMesh= new MESH(MED_DRIVER,filename,meshname) ; + MESH * myMesh= new MESH() ; + myMesh->setName(meshname); + MED_MESH_RDONLY_DRIVER myMeshDriver(filename,myMesh) ; + myMeshDriver.setMeshName(meshname); + myMeshDriver.open() ; + myMeshDriver.read() ; + myMeshDriver.close() ; + + // int drv = myMesh->addDriver(MED_DRIVER,"sortie.med",meshname); + // myMesh->write(drv); + + + int SpaceDimension = myMesh->getSpaceDimension() ; + int MeshDimension = myMesh->getMeshDimension() ; + int NumberOfNodes = myMesh->getNumberOfNodes() ; + + cout << "Space Dimension : " << SpaceDimension << endl << endl ; + + cout << "Mesh Dimension : " << MeshDimension << endl << endl ; + + const double * Coordinates = myMesh->getCoordinates(MED_FULL_INTERLACE) ; + + cout << "Show Nodes Coordinates : " << endl ; + + cout << "Name :" << endl ; + const string * CoordinatesNames = myMesh->getCoordinatesNames() ; + for(int i=0; i<SpaceDimension ; i++) { + cout << " - " << CoordinatesNames[i] << endl ; + } + cout << "Unit :" << endl ; + const string * CoordinatesUnits = myMesh->getCoordinatesUnits() ; + for(int i=0; i<SpaceDimension ; i++) { + cout << " - " << CoordinatesUnits[i] << endl ; + } + for(int i=0; i<NumberOfNodes ; i++) { + cout << "Nodes " << i+1 << " : " ; + for (int j=0; j<SpaceDimension ; j++) + cout << Coordinates[i*SpaceDimension+j] << " " ; + cout << endl ; + } + + int NumberOfTypes = myMesh->getNumberOfTypes(MED_CELL) ; + const medGeometryElement * Types = myMesh->getTypes(MED_CELL) ; + + cout << "Show Connectivity (Nodal) :" << endl ; + for (int i=0; i<NumberOfTypes; i++) { + cout << "For type " << Types[i] << " : " << endl ; + int NumberOfElements = myMesh->getNumberOfElements(MED_CELL,Types[i]); + const int * connectivity = myMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,Types[i]); + int NomberOfNodesPerCell = Types[i]%100 ; + for (int j=0;j<NumberOfElements;j++){ + cout << "Element "<< j+1 <<" : " ; + for (int k=0;k<NomberOfNodesPerCell;k++) + cout << connectivity[j*NomberOfNodesPerCell+k]<<" "; + cout << endl ; + } + } + + cout << "Show Family :"<<endl ; + affiche_famille(myMesh,MED_NODE); + affiche_famille(myMesh,MED_CELL); + affiche_famille(myMesh,MED_FACE); + affiche_famille(myMesh,MED_EDGE); + + cout << "Show Group :"<<endl ; + affiche_groupe(myMesh,MED_NODE); + affiche_groupe(myMesh,MED_CELL); + affiche_groupe(myMesh,MED_FACE); + affiche_groupe(myMesh,MED_EDGE); + + cout << "Show Reverse Nodal Connectivity :" << endl ; + const int * ReverseNodalConnectivity = myMesh->getReverseConnectivity(MED_NODAL) ; + const int * ReverseNodalConnectivityIndex = myMesh->getReverseConnectivityIndex(MED_NODAL) ; + for (int i=0; i<NumberOfNodes; i++) { + cout << "Node "<<i+1<<" : " ; + for (int j=ReverseNodalConnectivityIndex[i];j<ReverseNodalConnectivityIndex[i+1];j++) + cout << ReverseNodalConnectivity[j-1] << " " ; + cout << endl ; + } + + cout << "Show Connectivity (Descending) :" << endl ; + int NumberOfElements ; + const int * connectivity ; + const int * connectivity_index ; + myMesh->calculateConnectivity(MED_FULL_INTERLACE,MED_DESCENDING,MED_CELL); + try { + NumberOfElements = myMesh->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS); + connectivity = myMesh->getConnectivity(MED_FULL_INTERLACE,MED_DESCENDING,MED_CELL,MED_ALL_ELEMENTS); + connectivity_index = myMesh->getConnectivityIndex(MED_DESCENDING,MED_CELL); + } + catch (MEDEXCEPTION m) { + cout << m.what() << endl ; + exit (-1) ; + } + for (int j=0;j<NumberOfElements;j++) { + cout << "Element "<<j+1<<" : " ; + for (int k=connectivity_index[j];k<connectivity_index[j+1];k++) + cout << connectivity[k-1]<<" "; + cout << endl ; + } + + cout << "Show Reverse Descending Connectivity :" << endl ; + const int * ReverseDescendingConnectivity = myMesh->getReverseConnectivity(MED_DESCENDING) ; + const int * ReverseDescendingConnectivityIndex = myMesh->getReverseConnectivityIndex(MED_DESCENDING) ; + + int NumberOfConstituents = 0; + string constituent ; + medEntityMesh constituentEntity ; + + if (MeshDimension==3) { + constituent = "Face" ; + constituentEntity = MED_FACE ; + } + + if (MeshDimension==2) { + constituent = "Edge" ; + constituentEntity = MED_EDGE ; + } + + if (MeshDimension==1) { + INFOS_MED("ERROR : MeshDimension = 1 !"); + INFOS_MED("We could not see Reverse Descending Connectivity.") ; + } else { + NumberOfConstituents = myMesh->getNumberOfElements (constituentEntity,MED_ALL_ELEMENTS); + for (int i=0; i<NumberOfConstituents; i++) { + cout << constituent <<i+1<<" : " ; + for (int j=ReverseDescendingConnectivityIndex[i];j<ReverseDescendingConnectivityIndex[i+1];j++) + cout << ReverseDescendingConnectivity[j-1] << " " ; + cout << endl ; + } + } + cout << "Show "<<constituent<<" Connectivity (Nodal) :" << endl ; + const int * face_connectivity = myMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,constituentEntity,MED_ALL_ELEMENTS); + const int * face_connectivity_index = myMesh->getConnectivityIndex(MED_NODAL,constituentEntity); + for (int i=0; i<NumberOfConstituents; i++) { + cout << constituent <<i+1<<" : " ; + for (int j=face_connectivity_index[i];j<face_connectivity_index[i+1];j++) + cout << face_connectivity[j-1]<<" "; + cout << endl ; + } + + /* test of normal, area, volume, barycenter */ + + SUPPORT * support1 = (SUPPORT*) NULL; + + //FIELD<double>* normal = new FIELD<double>::FIELD(); + //FIELD<double>* length = new FIELD<double>::FIELD(); + //normal = NULL; + //length = NULL; + string support_name = "Support on all " ; + support_name+=constituent; + support1 = new SUPPORT(myMesh,support_name,constituentEntity); + cout << "Building of the Support on all cells dimensionned (Meshdim-1) of the mesh :"<< endl ; + cout << "Face in 3D or Edge in 2D" << endl; + + cout << "Getting the normal of each face of this support !" << endl ; + + FIELD<double>* normal = myMesh->getNormal(support1); + + double normal_square, norm ; + double maxnorm=-infty; + double minnorm=infty; + double tmp_value ; + for (int i = 1; i<=NumberOfConstituents;i++) { + normal_square = 0. ; + cout << "Normal " << i << " " ; + for (int j=1; j<=SpaceDimension; j++) { + tmp_value = normal->getValueIJ(i,j) ; + normal_square += tmp_value*tmp_value ; + cout << tmp_value << " " ; + } + norm = sqrt(normal_square); + maxnorm = dmax(maxnorm,norm); + minnorm = dmin(minnorm,norm); + cout << ", Norm = " << norm << endl; + } + cout << "Max Norm " << maxnorm << " Min Norm " << minnorm << endl; + + delete normal ; + + if (SpaceDimension == 2) + { + cout << "Getting the length of each edge !" << endl ; + + FIELD<double>* length = myMesh->getLength(support1); + + double length_value,maxlength,minlength; + maxlength = -infty; + minlength = infty; + for (int i = 1; i<=NumberOfConstituents;i++) + { + length_value = length->getValueIJ(i,1) ; + cout << "Length " << i << " " << length_value << endl; + maxlength = dmax(maxlength,length_value); + minlength = dmin(minlength,length_value); + } + cout << "Max Length " << maxlength << " Min Length " << minlength << endl; + + delete length ; + } + + delete support1 ; + + cout << "Building of the Support on all space-dimensionned cells of the mesh :"<< endl ; + SUPPORT * support = new SUPPORT(myMesh); + + cout << "Getting the barycenter of each element of this support !" << endl ; + + //FIELD<double>* barycenter = new FIELD<double>::FIELD(); + + FIELD<double>* barycenter = myMesh->getBarycenter(support); + NumberOfElements = myMesh->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS); + + for (int i = 1; i<=NumberOfElements;i++) + { + if (SpaceDimension == 3) + cout << "Barycenter " << i << " " << barycenter->getValueIJ(i,1) << " " << barycenter->getValueIJ(i,2) << " " << barycenter->getValueIJ(i,3) << endl; + + if (SpaceDimension == 2) + cout << "Barycenter " << i << " " << barycenter->getValueIJ(i,1) << " " << barycenter->getValueIJ(i,2) << endl; + } + + delete barycenter ; + + //FIELD<double>* volume = new FIELD<double>::FIELD(); + //FIELD<double>* area = new FIELD<double>::FIELD(); + //volume = NULL; + //area = NULL; + + if (SpaceDimension == 3) + { + cout << "Getting the Volume of each element of this support which is a 3D one !" << endl; + + FIELD<double>* volume = myMesh->getVolume(support); + + double maxvol,minvol,voltot; + maxvol = -infty; + minvol = infty; + voltot = 0.0; + for (int i = 1; i<=NumberOfElements;i++) + { + cout << "Volume " << i << " " << volume->getValueIJ(i,1) << endl; + maxvol = dmax(maxvol,volume->getValueIJ(i,1)); + minvol = dmin(minvol,volume->getValueIJ(i,1)); + voltot = voltot + volume->getValueIJ(i,1); + } + + cout << "Max Volume " << maxvol << " Min Volume " << minvol << endl; + cout << "Support Volume " << voltot << endl; + + delete volume ; + } + else if (SpaceDimension == 2) + { + cout << "Getting the Area of each element of this support which is a 2D one !" << endl; + + FIELD<double>* area = myMesh->getArea(support); + + // cout << "nb of comp "<< area->getNumberOfComponents() << " length " << area->getSupport()->getNumberOfElements(MED_ALL_ELEMENTS) << endl; + + double maxarea,minarea,areatot; + maxarea = -infty; + minarea = infty; + areatot = 0.0; + for (int i = 1; i<=NumberOfElements;i++) + { + cout << "Area " << i << " " << area->getValueIJ(i,1) << endl; + maxarea = dmax(maxarea,area->getValueIJ(i,1)); + minarea = dmin(minarea,area->getValueIJ(i,1)); + areatot = areatot + area->getValueIJ(i,1); + } + + cout << "Max Area " << maxarea << " Min Area " << minarea << endl; + cout << "Support Area " << areatot << endl; + + delete area ; + } + + delete support ; + + //if (barycenter != NULL) delete barycenter; + //if (volume != NULL ) delete volume; + //if (area != NULL ) delete area; + + + if (argc < 4) return 0; + + // read field : + + if (argc != 4) exit(0) ; + // else we have a field ! + + string fieldname = argv[3]; + + // SUPPORT * mySupport = new SUPPORT(myMesh,"On_all_node",MED_NODE); + SUPPORT * mySupport = new SUPPORT(myMesh,"On_all_cell",MED_CELL); + FIELD<double> * myField= new FIELD<double>() ; + + myField->setName(fieldname); + myField->setSupport(mySupport); + MED_FIELD_RDONLY_DRIVER<double> myFieldDriver(filename,myField) ; + myFieldDriver.setFieldName(fieldname); + myFieldDriver.open() ; + + try { + myFieldDriver.read() ; + } catch (...) { + delete mySupport ; + mySupport = new SUPPORT(myMesh,"On_all_node",MED_NODE); + myField->setSupport(mySupport); + try { + myFieldDriver.read() ; + } catch (...) { + cout << "Field " << fieldname << " not found !!!" << endl ; + exit (-1) ; + } + } + + myFieldDriver.close() ; + + cout << "Field "<< myField->getName() << " : " <<myField->getDescription() << endl ; + int NumberOfComponents = myField->getNumberOfComponents() ; + cout << "- Nombre de composantes : "<< NumberOfComponents << endl ; + for (int i=1; i<NumberOfComponents+1; i++) { + cout << " - composante "<<i<<" :"<<endl ; + cout << " - nom : "<<myField->getComponentName(i)<< endl; + cout << " - description : "<<myField->getComponentDescription(i) << endl; + cout << " - units : "<<myField->getMEDComponentUnit(i) << endl; + } + cout << "- iteration :" << endl ; + cout << " - numero : " << myField->getIterationNumber()<< endl ; + cout << " - ordre : " << myField->getOrderNumber()<< endl ; + cout << " - temps : " << myField->getTime()<< endl ; + + cout << "- Valeurs :"<<endl; + int NumberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); + // for (int i=1; i<NumberOfComponents+1; i++) { + // double * value = myField->getValueI(MED_NO_INTERLACE,i) ; + // for (int j=0; j<NumberOf; j++) + // cout << value[j]<< " "; + // cout<<endl; + // } + MEDMEM_Array<double> * myvalue = myField->getArrayNoGauss(); + const double * value ; + for (int i=1; i<NumberOf+1; i++) { + value = myvalue->getRow(i) ; + for (int j=0; j<NumberOfComponents; j++) + cout << value[j]<< " "; + cout<<endl; + } + cout<<endl; + + delete myField; + delete mySupport; + + delete myMesh ; + + return 0; +} diff --git a/src/MEDMEMBinTest/scripts/check_convertToPoly b/src/MEDMEMBinTest/scripts/check_convertToPoly new file mode 100644 index 000000000..0ea38fda8 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_convertToPoly @@ -0,0 +1,22 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +infile=${srcdir}/../../resources/BoxTetra2.med + +outfile=$outdir/convertToPoly_BoxTetra2.med + +./convertToPoly $infile $outfile BoxTetra2 + +ok=$? + +rm $outfile + +exit $ok diff --git a/src/MEDMEMBinTest/scripts/check_duplicateMED b/src/MEDMEMBinTest/scripts/check_duplicateMED new file mode 100644 index 000000000..50b651298 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_duplicateMED @@ -0,0 +1,22 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +infile=${srcdir}/../../resources/pointe.med + +outfile=$outdir/duplicateMED_pointe.med + +./duplicateMED $infile $outfile + +ok=$? + +rm $outfile + +exit $ok diff --git a/src/MEDMEMBinTest/scripts/check_ensight2med b/src/MEDMEMBinTest/scripts/check_ensight2med new file mode 100644 index 000000000..45591afe1 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_ensight2med @@ -0,0 +1,22 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +infile=${srcdir}/../../resources/blow5_ascii.case + +outfile=${outdir}/ensight2med.med + +./ensight2med $infile $outfile + +ok=$? + +rm $outfile + +exit $ok diff --git a/src/MEDMEMBinTest/scripts/check_med2_1_To_med2_2 b/src/MEDMEMBinTest/scripts/check_med2_1_To_med2_2 new file mode 100644 index 000000000..34cd0f0a1 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_med2_1_To_med2_2 @@ -0,0 +1,22 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +infile=${srcdir}/../../resources/pointe.med + +outfile=./pointe.med2.3 + +./med2_1_To_med2_2 $infile + +ok=$? + +rm $outfile + +exit $ok diff --git a/src/MEDMEMBinTest/scripts/check_med2ensight b/src/MEDMEMBinTest/scripts/check_med2ensight new file mode 100644 index 000000000..8013b0e99 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_med2ensight @@ -0,0 +1,30 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +infile=${srcdir}/../../resources/pointe.med + +outfile=${outdir}/pointe.case + +./med2ensight $infile $outfile + +ok=$? + +rm $outfile +rm ${outdir}/pointe.geo +rm ${outdir}/pointe.fieldcelldoublescalar +rm ${outdir}/pointe.fieldcelldoublevector +rm ${outdir}/pointe.fieldnodedouble000 +rm ${outdir}/pointe.fieldnodedouble001 +rm ${outdir}/pointe.fieldnodedouble002 +rm ${outdir}/pointe.fieldnodeint + + +exit $ok diff --git a/src/MEDMEMBinTest/scripts/check_med2vtk b/src/MEDMEMBinTest/scripts/check_med2vtk new file mode 100644 index 000000000..8c34ecf99 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_med2vtk @@ -0,0 +1,22 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +infile=${srcdir}/../../resources/pointe.med + +outfile=$outdir/pointe.vtk + +./med2vtk $infile $outfile + +ok=$? + +rm $outfile + +exit $ok diff --git a/src/MEDMEMBinTest/scripts/check_readCoordinate b/src/MEDMEMBinTest/scripts/check_readCoordinate new file mode 100644 index 000000000..952a71e55 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_readCoordinate @@ -0,0 +1,17 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +infile=${srcdir}/../../resources/pointe.med + +./readCoordinate $infile maa1 + +exit + diff --git a/src/MEDMEMBinTest/scripts/check_readEntete b/src/MEDMEMBinTest/scripts/check_readEntete new file mode 100644 index 000000000..e57151a1d --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_readEntete @@ -0,0 +1,17 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +infile=${srcdir}/../../resources/pointe.med + +./readEntete $infile maa1 + +exit + diff --git a/src/MEDMEMBinTest/scripts/check_testAnalFile b/src/MEDMEMBinTest/scripts/check_testAnalFile new file mode 100644 index 000000000..7f2bcdab4 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_testAnalFile @@ -0,0 +1,25 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +initfile=${srcdir}/../../resources/TimeStamps.med +infile=$outdir/testAnalFile.med + +cp $initfile $infile + +./testAnalFile $infile + +ok=$? + +rm $infile +rm $outdir/testAnalFileAnal_V21.med +rm $outdir/testAnalFileAnal_V22.med + +exit $ok diff --git a/src/MEDMEMBinTest/scripts/check_test_MEDMEM_PolyDriverMedMeshRead b/src/MEDMEMBinTest/scripts/check_test_MEDMEM_PolyDriverMedMeshRead new file mode 100644 index 000000000..aafd9b28b --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_test_MEDMEM_PolyDriverMedMeshRead @@ -0,0 +1,17 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +infile=${srcdir}/../../resources/pointe_import22.med + +./test_MEDMEM_PolyDriverMedMeshRead $infile maa1 + +exit + diff --git a/src/MEDMEMBinTest/scripts/check_test_MEDMEM_PolyDriverMedMeshWrite b/src/MEDMEMBinTest/scripts/check_test_MEDMEM_PolyDriverMedMeshWrite new file mode 100644 index 000000000..a67764ce7 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_test_MEDMEM_PolyDriverMedMeshWrite @@ -0,0 +1,25 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +initfile=${srcdir}/../../resources/pointe_import22.med +infile=$outdir/test_MEDMEM_PolyDriverMedMeshWrite.med +outfile=$outdir/test_MEDMEM_PolyDriverMedMeshWrite.med_copy + +cp $initfile $infile + +./test_MEDMEM_PolyDriverMedMeshWrite $infile maa1 + +ok=$? + +rm $infile +rm $outfile + +exit $ok diff --git a/src/MEDMEMBinTest/scripts/check_test_MEDMEM_poly3D b/src/MEDMEMBinTest/scripts/check_test_MEDMEM_poly3D new file mode 100644 index 000000000..61fff263a --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_test_MEDMEM_poly3D @@ -0,0 +1,17 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +infile=${srcdir}/../../resources/poly3D.med + +./test_MEDMEM_poly3D $infile poly3D + +exit + diff --git a/src/MEDMEMBinTest/scripts/check_test_copie_connectivity b/src/MEDMEMBinTest/scripts/check_test_copie_connectivity new file mode 100644 index 000000000..3bf10436e --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_test_copie_connectivity @@ -0,0 +1,17 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +infile=${srcdir}/../../resources/pointe.med + +./test_copie_connectivity $infile maa1 + +exit + diff --git a/src/MEDMEMBinTest/scripts/check_test_copie_family b/src/MEDMEMBinTest/scripts/check_test_copie_family new file mode 100644 index 000000000..515861ee7 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_test_copie_family @@ -0,0 +1,17 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +infile=${srcdir}/../../resources/pointe_import22.med + +./test_copie_family $infile maa1 + +exit + diff --git a/src/MEDMEMBinTest/scripts/check_test_copie_fieldT b/src/MEDMEMBinTest/scripts/check_test_copie_fieldT new file mode 100644 index 000000000..7e878ee53 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_test_copie_fieldT @@ -0,0 +1,21 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +infile=${srcdir}/../../resources/pointe.med + +./test_copie_fieldT $infile maa1 fieldcelldoublescalar + +if test $? -ne 0; then exit -1;fi + +./test_copie_fieldT $infile maa1 fieldnodedouble + +exit + diff --git a/src/MEDMEMBinTest/scripts/check_test_copie_field_ b/src/MEDMEMBinTest/scripts/check_test_copie_field_ new file mode 100644 index 000000000..10cec17a3 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_test_copie_field_ @@ -0,0 +1,21 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +infile=${srcdir}/../../resources/pointe.med + +./test_copie_field_ $infile maa1 fieldcelldoublevector + +if test $? -ne 0; then exit -1;fi + +./test_copie_field_ $infile maa1 fieldnodeint + +exit + diff --git a/src/MEDMEMBinTest/scripts/check_test_copie_group b/src/MEDMEMBinTest/scripts/check_test_copie_group new file mode 100644 index 000000000..2c6a3ce0b --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_test_copie_group @@ -0,0 +1,17 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +infile=${srcdir}/../../resources/pointe_import22.med + +./test_copie_group $infile maa1 + +exit + diff --git a/src/MEDMEMBinTest/scripts/check_test_copie_mesh b/src/MEDMEMBinTest/scripts/check_test_copie_mesh new file mode 100644 index 000000000..23b274d97 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_test_copie_mesh @@ -0,0 +1,17 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +infile=${srcdir}/../../resources/pointe_import22.med + +./test_copie_mesh $infile maa1 + +exit + diff --git a/src/MEDMEMBinTest/scripts/check_test_copie_support b/src/MEDMEMBinTest/scripts/check_test_copie_support new file mode 100644 index 000000000..7babf60f5 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_test_copie_support @@ -0,0 +1,17 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +infile=${srcdir}/../../resources/pointe_import22.med + +./test_copie_support $infile maa1 + +exit + diff --git a/src/MEDMEMBinTest/scripts/check_test_gibi_driver b/src/MEDMEMBinTest/scripts/check_test_gibi_driver new file mode 100644 index 000000000..6882f3e01 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_test_gibi_driver @@ -0,0 +1,26 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +initfile=${srcdir}/../../resources/mail-test1-4-1.sauve +infile=${outdir}/test_gibi_driver.sauve + +cp $initfile $infile + +./test_gibi_driver $infile + +ok=$? + +rm $infile +rm ${outdir}/test_gibi_driver.vtk +rm ${outdir}/test_gibi_driver_V21.med +rm ${outdir}/test_gibi_driver_V22.med + +exit $ok diff --git a/src/MEDMEMBinTest/scripts/check_test_grid b/src/MEDMEMBinTest/scripts/check_test_grid new file mode 100644 index 000000000..fc35bc4e0 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_test_grid @@ -0,0 +1,6 @@ +#! /bin/sh -f + +./test_grid 3 5 + +exit + diff --git a/src/MEDMEMBinTest/scripts/check_test_operation_fielddouble b/src/MEDMEMBinTest/scripts/check_test_operation_fielddouble new file mode 100644 index 000000000..8bde40628 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_test_operation_fielddouble @@ -0,0 +1,17 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +infile=${srcdir}/../../resources/pointe_import22.med + +./test_operation_fielddouble $infile maa1 fieldcelldoublescalar + +exit + diff --git a/src/MEDMEMBinTest/scripts/check_test_operation_fieldint b/src/MEDMEMBinTest/scripts/check_test_operation_fieldint new file mode 100755 index 000000000..22d8fbb96 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_test_operation_fieldint @@ -0,0 +1,27 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +# make med file containing int field on cells from ensight file + +infile=${srcdir}/../../resources/blow5_ascii.case +outfile=${outdir}/test_operation_fieldint.med + +./ensight2med $infile $outfile I + +# main test +./test_operation_fieldint $outfile EnsightMesh displacement_c + +ok=$? + +echo $outfile +rm $outfile + +exit $ok diff --git a/src/MEDMEMBinTest/scripts/check_test_porflow_driver b/src/MEDMEMBinTest/scripts/check_test_porflow_driver new file mode 100644 index 000000000..4132743de --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_test_porflow_driver @@ -0,0 +1,31 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +initfile=${srcdir}/../../resources/cube.inp +xyzfile=${srcdir}/../../resources/cube.xyz +cncfile=${srcdir}/../../resources/cube.cnc +infile=${outdir}/test_porflow_driver.inp + +cp $initfile $infile +cp $xyzfile ${outdir}/cube.xyz +cp $cncfile ${outdir}/cube.cnc + +./test_porflow_driver $infile + +ok=$? + +rm $infile +rm ${outdir}/cube.xyz +rm ${outdir}/cube.cnc +rm ${outdir}/test_porflow_driver.med +rm ${outdir}/test_porflow_driver.vtk + +exit $ok diff --git a/src/MEDMEMBinTest/scripts/check_test_profil_MedFieldDriver b/src/MEDMEMBinTest/scripts/check_test_profil_MedFieldDriver new file mode 100644 index 000000000..7cd28a437 --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_test_profil_MedFieldDriver @@ -0,0 +1,27 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +initfile=${srcdir}/../../resources/zzzz121b_without_tr6.med +infile=test_profil_MedFieldDriver.med + +curdir=`pwd` +cd $outdir +cp $initfile ./$infile + +$curdir/test_profil_MedFieldDriver $infile RESUZERODEPL____________________ 1 1 + +ok=$? + +rm $infile +rm Copy_withmesh_test_profil_MedFieldDriver.med +rm Copy_nomesh_test_profil_MedFieldDriver.med + +exit $ok diff --git a/src/MEDMEMBinTest/scripts/check_test_profil_gauss_MedFieldDriver b/src/MEDMEMBinTest/scripts/check_test_profil_gauss_MedFieldDriver new file mode 100644 index 000000000..0a9f1761e --- /dev/null +++ b/src/MEDMEMBinTest/scripts/check_test_profil_gauss_MedFieldDriver @@ -0,0 +1,27 @@ +#! /bin/sh -f + +outdir="/tmp" +if test "z$TMP" != "z" && test -e $TMP; then + outdir=$TMP +else + if test "z$TMPDIR" != "z" && test -e $TMPDIR; then + outdir=$TMPDIR + fi +fi + +initfile=${srcdir}/../../resources/zzzz121b_without_tr6.med +infile=test_profil_gauss_MedFieldDriver.med + +curdir=`pwd` +cd $outdir +cp $initfile ./$infile + +$curdir/test_profil_gauss_MedFieldDriver $infile RESUZEROSIEF_ELGA_DEPL__________ 1 1 + +ok=$? + +rm $infile +rm Copy_withmesh_test_profil_gauss_MedFieldDriver.med +rm Copy_nomesh_test_profil_gauss_MedFieldDriver.med + +exit $ok diff --git a/src/MEDMEMBinTest/testAG.cxx b/src/MEDMEMBinTest/testAG.cxx new file mode 100644 index 000000000..b7cdc85d8 --- /dev/null +++ b/src/MEDMEMBinTest/testAG.cxx @@ -0,0 +1,120 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Group.hxx" +#include "MEDMEM_Meshing.hxx" +#include "MEDMEM_MedMeshDriver22.hxx" + +using namespace MED_EN; +using namespace std; +using namespace MEDMEM; + +void addMedFacesGroup( MESHING& meshing, int nFaces, int *groupValue,string groupName) + { + GROUP faces ; + int myNumberOfElements[1]; + medGeometryElement mytypes[1]; + int index[2]; + int nbOfGeomTypes; + faces.setName(groupName) ; + faces.setMesh(&meshing) ; + faces.setEntity(MED_EN::MED_FACE) ; + faces.setNumberOfGeometricType(1) ; + mytypes[0]=MED_EN::MED_POLYGON; + faces.setGeometricType(mytypes); + myNumberOfElements[0]=nFaces; + faces.setNumberOfElements(myNumberOfElements) ; + index[0]=1; index[1]=nFaces; + faces.setNumber(index, groupValue) ; + meshing.addGroup(faces) ; + } + +const int NB_OF_HEXA=1; +const int NB_OF_CELL_AXIAL=1; +char NomBottom[]="Bottom"; + +int main() +{ + MESHING *pmesh=new MESHING; + pmesh->setName( "RJHMESH" ) ; + pmesh->setSpaceDimension(3) ; + + double coord3DTab[36]={0.024155000000000003, 0.041837687256826218, -0.30499999999999999, 0.048310000000000013, -1.015761910347357e-17, -0.30499999999999999, 0.096620000000000011, -1.8329792978583059e-18, + -0.30499999999999999, 0.12077499999999999, 0.041837687256826225, -0.30499999999999999, 0.096620000000000011, 0.083675374513652451, -0.30499999999999999, 0.048310000000000013, 0.083675374513652465, + -0.30499999999999999, 0.024155000000000003, 0.041837687256826218, -0.2863, 0.048310000000000013, -1.015761910347357e-17, -0.2863, 0.096620000000000011, -1.8329792978583059e-18, -0.2863, + 0.12077499999999999, 0.041837687256826225, -0.2863, 0.096620000000000011, 0.083675374513652451, -0.2863, 0.048310000000000013, 0.083675374513652465, -0.2863}; + vector<double> coords3D(coord3DTab,coord3DTab+36); + unsigned nNodes=coords3D.size()/3; + pmesh->setNumberOfNodes(nNodes); + pmesh->setCoordinates(3, nNodes, &(coords3D[0]), "CARTESIAN",MED_EN::MED_FULL_INTERLACE); + string coordname[3] = { "x", "y", "z" } ; + pmesh->setCoordinatesNames(coordname) ; + // Set coordinates units + string coordunit[3] = { "cm", "cm", "cm" } ; + pmesh->setCoordinatesUnits(coordunit) ; + pmesh->setNumberOfTypes(0, MED_EN::MED_CELL); + pmesh->setMeshDimension(3); + pmesh->setNumberOfTypes(1,MED_EN::MED_FACE); + medGeometryElement mytypes2D[1]={MED_QUAD4}; + // + int conn2DClassicalTab[24]={2, 3, 9, 8, 3, 4, 10, 9, 4, 5, 11, 10, 5, 6, 12, 11, 6, 1, 7, 12, 1, 2, 8, 7}; + vector<int> conn2DClassical(conn2DClassicalTab,conn2DClassicalTab+24); + // + int nbOfElemsFace=conn2DClassical.size()/4; + pmesh->setTypes(mytypes2D,MED_EN::MED_FACE); + pmesh->setNumberOfElements(&nbOfElemsFace,MED_EN::MED_FACE); + // + int polyHInd[2]={1, 9}; + int polyHFaceInd[9]={1, 7, 13, 17, 21, 25, 29, 33, 37}; + int polyHFaceConn[36]={8, 9, 10, 11, 12, 7, 2, 1, 6, 5, 4, 3, 2, 3, 9, 8, 3, 4, 10, 9, 4, 5, 11, 10, 5, 6, 12, 11, 6, 1, 7, 12, 1, 2, 8, 7}; + // + pmesh->setPolyhedraConnectivity(polyHInd,polyHFaceInd,polyHFaceConn,NB_OF_HEXA*(NB_OF_CELL_AXIAL),MED_EN::MED_CELL); + pmesh->setConnectivity(&conn2DClassical[0], MED_EN::MED_FACE, MED_EN::MED_QUAD4); + // + int conn2DPolyIndTab[3]={1, 7, 13}; + vector<int > conn2DPolyInd(conn2DPolyIndTab,conn2DPolyIndTab+3); + int conn2DPolyTab[12]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + // + pmesh->setPolygonsConnectivity(&conn2DPolyInd[0],conn2DPolyTab,conn2DPolyInd.size()-1,MED_EN::MED_FACE); + int bottom=7; + addMedFacesGroup(*pmesh,1,&bottom,NomBottom); + int id = pmesh->addDriver(MED_DRIVER, "coeur.med", pmesh->getName()); + pmesh->write(id) ; + pmesh->rmDriver(id); + delete pmesh; + // + + MESH mesh;//(MED_DRIVER,,"RJHMESH");//"/home/geay/test_FGUI.med","FluidMesh_1");//../STEP3/coeur.med","RJHMESH"); + mesh.setName("RJHMESH"); + MED_MESH_RDONLY_DRIVER22 *drv=new MED_MESH_RDONLY_DRIVER22("coeur.med",&mesh); + drv->desactivateFacesComputation(); + int newDrv=mesh.addDriver(*drv); + delete drv; + mesh.read(newDrv); + cout << " *** " << mesh.getNumberOfTypes(MED_EN::MED_FACE) << endl; + cout << "Expected 8 - having " << mesh.getNumberOfElementsWithPoly(MED_FACE,MED_ALL_ELEMENTS) << endl; + cout << "Expected 6 - having " << mesh.getNumberOfElements(MED_FACE,MED_ALL_ELEMENTS) << endl; + cout << "Expected 6 - having " << mesh.getNumberOfElements(MED_FACE,MED_QUAD4) << endl; + cout << "Expected 1 - having " << mesh.getNumberOfElementsWithPoly(MED_CELL,MED_ALL_ELEMENTS) << endl; + cout << "Expected 0 - having " << mesh.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) << endl; + return 0; +} diff --git a/src/MEDMEMBinTest/testAnalFile.cxx b/src/MEDMEMBinTest/testAnalFile.cxx new file mode 100644 index 000000000..12fa9244a --- /dev/null +++ b/src/MEDMEMBinTest/testAnalFile.cxx @@ -0,0 +1,104 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include <string> +#include <deque> +#include <iostream> +#include "MEDMEM_MedMedDriver.hxx" +#include "MEDMEM_Med.hxx" +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_DriverFactory.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +int main(int argc, char *argv[]) +{ + if (argc !=2) + { + cerr << "Usage : " << argv[0] + << " fileName.med where fileName.med should be a med file" << endl; + cerr << " It will then generate two med files fileNameAnal_V21.med (med V2.1 format)" << endl; + cerr << "and fileNameAnal_V21.med (med V2.2 format)" << endl << endl; + exit(-1); + } + + int i; + // This test program is more or less designed to work with file TimeStamps.med + // If you want to use it for other Med files, you have to alter the mounting in memory of the fields f1 and f2 + //string fileIn="/export/home/geay32/SALOME225/KERNEL_SRC/examples/TimeStamps.med"; + + string fileIn = argv[1] ; + const string ext=".med"; + string::size_type pos=fileIn.find(ext,0); + string baseName (fileIn, 0, pos); // nom sans extension + string fileOut21=baseName + "Anal_V21.med"; + string fileOut22=baseName + "Anal_V22.med"; + + MED *myMed=new MED; + MED_MED_RDONLY_DRIVER *driverIn=new MED_MED_RDONLY_DRIVER(fileIn,myMed); + driverIn->open(); + driverIn->readFileStruct(); + driverIn->close(); + int nbOfMeshes=myMed->getNumberOfMeshes(); + int nbOfFields=myMed->getNumberOfFields(); + cout << nbOfMeshes << " --- " << nbOfFields << endl; + deque<string> names=myMed->getMeshNames(); + for(i=0;i<nbOfMeshes;i++) + cout << names[i] << endl; + cout << "************* " << endl; + deque<string> names2=myMed->getFieldNames(); + for(i=0;i<nbOfFields;i++) + cout << names2[i] << endl; + MESH *mesh=myMed->getMesh(names[0]); + mesh->read(); + myMed->updateSupport(); + deque<DT_IT_> iterations=myMed->getFieldIteration(names2[2]); + cout << iterations.size() << endl; + FIELD_ *f1=myMed->getField(names2[2],iterations[0].dt,iterations[0].it); + FIELD_ *f2=myMed->getField(names2[2],iterations[1].dt,iterations[1].it); + FIELD<double> *f1s=(FIELD<double> *)f1; + f1s->read(); + FIELD<double> *f2s=(FIELD<double> *)f2; + f2s->read(); + DRIVERFACTORY::setMedFileVersionForWriting(V21); + int id=mesh->addDriver(MED_DRIVER,fileOut21,mesh->getName()); + mesh->write(id); + id=f1s->addDriver(MED_DRIVER, fileOut21, f1s->getName()); + f1s->write(id); + id=f2s->addDriver(MED_DRIVER, fileOut21, f2s->getName()); + f2s->write(id); + + DRIVERFACTORY::setMedFileVersionForWriting(V22); + id=mesh->addDriver(MED_DRIVER,fileOut22,mesh->getName()); + mesh->write(id); + id=f1s->addDriver(MED_DRIVER, fileOut22, f1s->getName()); + f1s->write(id); + id=f2s->addDriver(MED_DRIVER, fileOut22, f2s->getName()); + f2s->write(id); + + delete myMed; + return 0; +} + diff --git a/src/MEDMEMBinTest/testConvertPolygon.cxx b/src/MEDMEMBinTest/testConvertPolygon.cxx new file mode 100644 index 000000000..8f28c430c --- /dev/null +++ b/src/MEDMEMBinTest/testConvertPolygon.cxx @@ -0,0 +1,61 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_Mesh.hxx" + +int main() +{ + // Get file to convert. + string file; + // During 'make check' $srcdir exists + if ( getenv("srcdir") ) { + file = string( getenv("srcdir")) + "/../../resources/"; + } + else if ( getenv( "MED_ROOT_DIR")) { + // after installation + file = string( getenv( "MED_ROOT_DIR" )) + "/share/salome/resources/med/"; + } + else + { + return -1; + } + file += "BoxTetra2.med"; + cout << "File to cnvert: " << file << endl; + // convertion + MEDMEM::MESH mesh(MEDMEM::MED_DRIVER, file.c_str(), "BoxTetra2"); + mesh.convertToPoly(); + + // File to store conversion result + if ( getenv("TMP") ) + file = getenv("TMP"); + else if ( getenv("TMPDIR") ) + file = getenv("TMPDIR"); + else + file = "/tmp"; + file += "/pointe_testConvertPolygon.med"; + + int id=mesh.addDriver(MEDMEM::MED_DRIVER,file.c_str(),"mesh"); + mesh.write(id); + + remove(file.c_str()); + + return 0; +} diff --git a/src/MEDMEMBinTest/test_GaussLocalization.cxx b/src/MEDMEMBinTest/test_GaussLocalization.cxx new file mode 100644 index 000000000..759d76320 --- /dev/null +++ b/src/MEDMEMBinTest/test_GaussLocalization.cxx @@ -0,0 +1,71 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include <stdlib.h> +#include <string> + +#define INTERLACING_TAG FullInterlace + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_define.hxx" +#include "MEDMEM_GaussLocalization.hxx" +#include "MEDMEM_ArrayInterface.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +#define _a 0.446948490915965 +#define _b 0.091576213509771 +#define _p1 0.11169079483905 +#define _p2 0.0549758718227661 + +int main (int argc, char ** argv) { + + typedef MEDMEM_ArrayInterface<double,INTERLACING_TAG,NoGauss>::Array Array; + + + /* Caractéristiques du model n° 1 de localisation des points de gauss pour le champ n°1*/ + MED_EN::medGeometryElement typeGeo = MED_TRIA6; + + int ngauss1_1 = 6; + string gauss1_1("Model n1"); + double refcoo1 [12] = { -1.0,1.0, -1.0,-1.0, 1.0,-1.0, -1.0,0.0, 0.0,-1.0, 0.0,0.0 }; + + double gscoo1_1[12] = { 2*_b-1, 1-4*_b, 2*_b-1, 2*_b-1, 1-4*_b, + 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 }; + double wg1_1[6] = { 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 }; + + + assert( ( (typeGeo%100)*(typeGeo/100) ) == 12 ); + + GAUSS_LOCALIZATION<INTERLACING_TAG> myloc1 = GAUSS_LOCALIZATION<INTERLACING_TAG>(gauss1_1,typeGeo,ngauss1_1, + Array(refcoo1,typeGeo/100,(typeGeo%100) ), + Array(gscoo1_1,typeGeo/100,ngauss1_1), + vector<double> (wg1_1,wg1_1+ngauss1_1) + ); + GAUSS_LOCALIZATION<INTERLACING_TAG> myloc1bis = GAUSS_LOCALIZATION<INTERLACING_TAG>(gauss1_1,typeGeo,ngauss1_1, + refcoo1,gscoo1_1, + wg1_1); + + cout << "myloc1 == myloc1bis " << (myloc1 == myloc1bis) << endl; + cout << "myloc1 : " << endl << myloc1 << endl; +} diff --git a/src/MEDMEMBinTest/test_MEDMEM_Array.cxx b/src/MEDMEMBinTest/test_MEDMEM_Array.cxx new file mode 100644 index 000000000..030b09f82 --- /dev/null +++ b/src/MEDMEMBinTest/test_MEDMEM_Array.cxx @@ -0,0 +1,81 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_Array.hxx" + +using namespace std; +using namespace MEDMEM; +int main (int argc, char ** argv) { + + int SpaceDimension = 3 ; + int NumberOfNodes = 4 ; + MEDARRAY<int> * myArray = new MEDARRAY<int>(SpaceDimension,NumberOfNodes,MED_EN::MED_FULL_INTERLACE) ; + + //const int * value = myArray->get(MED_FULL_INTERLACE) ; + for (int i=1; i<=NumberOfNodes; i++) + for (int j=1; j<=SpaceDimension; j++) + myArray->setIJ(i,j,i) ; + + int numberof ; + MESSAGE_MED("Show all 1 :"); + numberof = myArray->getLeadingValue() ; + for (int i=1; i<=myArray->getLengthValue() ; i++) { + //int * node = myArray->getI(MED_FULL_INTERLACE,i) ; + const int * node = myArray->getRow(i) ; + cout << " - " ; + for (int j=0;j<numberof;j++) + cout << node[j] << " " ; + cout << endl ; + } + MESSAGE_MED("Show all 2 :"); + numberof = myArray->getLengthValue() ; + for (int i=1; i<=myArray->getLeadingValue() ; i++) { + //int * node = myArray->getJ(MED_NO_INTERLACE,i) ; + const int * node = myArray->getColumn(i) ; + cout << " - " ; + for (int j=0;j<numberof;j++) + cout << node[j] << " " ; + cout << endl ; + } + MESSAGE_MED("Show all 3 :"); + numberof = myArray->getLeadingValue() ; + for (int i=1; i<=myArray->getLengthValue() ; i++) { + cout << " - " ; + for (int j=1;j<numberof+1;j++) + cout << myArray->getIJ(i,j) << " " ; + cout << endl ; + } + + MESSAGE_MED("Show all 0 :"); + numberof = myArray->getLeadingValue() ; + int length = myArray->getLengthValue() ; + const int * NoInterlaceArray = myArray->get(MED_EN::MED_NO_INTERLACE) ; + for (int i=0; i<length ; i++) { + cout << " - " ; + for (int j=0;j<numberof;j++) + cout << NoInterlaceArray[j*length+i] << " " ; + cout << endl ; + } + + delete myArray ; + + return 0 ; +} diff --git a/src/MEDMEMBinTest/test_MEDMEM_CellModel.cxx b/src/MEDMEMBinTest/test_MEDMEM_CellModel.cxx new file mode 100644 index 000000000..f4221fe92 --- /dev/null +++ b/src/MEDMEMBinTest/test_MEDMEM_CellModel.cxx @@ -0,0 +1,63 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_CellModel.hxx" +#include "MEDMEM_DriversDef.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +int main (int argc, char ** argv) { + list<medGeometryElement> geomList = meshEntities[MED_CELL] ; + list<medGeometryElement>::iterator itGeomList ; + for(itGeomList=geomList.begin();itGeomList!=geomList.end();itGeomList++) { + CELLMODEL myCellModel((MED_EN::medGeometryElement)(*itGeomList)) ; + + cout << "First CellModel :" << endl << endl ; + + cout << myCellModel << endl ; + + cout << "Number of constituents type : "<<myCellModel.getNumberOfConstituentsType() << endl ; + + set <medGeometryElement> geomType = myCellModel.getAllConstituentsType() ; + set <medGeometryElement>::iterator geomTypeIt ; + cout << "Types list : " ; + for(geomTypeIt=geomType.begin();geomTypeIt!=geomType.end();geomTypeIt++) + cout << (*geomTypeIt) << " " ; + cout << endl; + + map <medGeometryElement,int> myMap = myCellModel.getNumberOfConstituentsForeachType() ; + map <medGeometryElement,int>::iterator myMapIt ; + for(myMapIt=myMap.begin();myMapIt!=myMap.end();myMapIt++) + cout << " - " << (*myMapIt).second << " constituent(s) of type " << (*myMapIt).first << endl ; + cout << endl; + + cout << "Second CellModel :" << endl << endl ; + CELLMODEL myCellModel2=myCellModel ; + cout << myCellModel2 << endl ; + + cout << "Third CellModel :" << endl << endl ; + CELLMODEL myCellModel3 ; + myCellModel3=myCellModel ; + cout << myCellModel3 << endl ; + } +} diff --git a/src/MEDMEMBinTest/test_MEDMEM_Meshing.cxx b/src/MEDMEMBinTest/test_MEDMEM_Meshing.cxx new file mode 100644 index 000000000..600e914ad --- /dev/null +++ b/src/MEDMEMBinTest/test_MEDMEM_Meshing.cxx @@ -0,0 +1,671 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +//#define protected public +//#define private public +// +#include "MEDMEM_Meshing.hxx" +#include "MEDMEM_Group.hxx" +#include "MEDMEM_Field.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; +using namespace DRIVERFACTORY; + +int main (int argc, char ** argv) { + + if (argc >2) { + cerr << "Usage : " << argv[0] + << " filenameRoot" << endl; + cerr << " where filenameRoot is a root filename, the program will produce" << endl; + cerr << " 3 files filenameRoot21.med filenameRoot22.med and filenameRoot.vtk" << endl << endl; + exit(-1); + } + + string filenameRoot; + if (argc==1) { + // filename to save the generated MESH + if ( getenv("TMP")) + filenameRoot=getenv("TMP"); + else if (getenv("TMPDIR")) + filenameRoot=getenv("TMPDIR"); + else + filenameRoot="/tmp"; + filenameRoot += "/test_MEDMEM_Meshing" ; + } + else + filenameRoot=argv[1]; + + string filenameMed21 = filenameRoot+"_V21.med"; + string filenameMed22 = filenameRoot+"_V22.med"; + string filenameVtk = filenameRoot+".vtk"; + + MESHING myMeshing ; + myMeshing.setName("meshing") ; + + // define coordinates + + int SpaceDimension = 3 ; + int NumberOfNodes = 19 ; + double Coordinates[57] = { + 0.0, 0.0, 0.0, + 0.0, 0.0, 1.0, + 2.0, 0.0, 1.0, + 0.0, 2.0, 1.0, + -2.0, 0.0, 1.0, + 0.0, -2.0, 1.0, + 1.0, 1.0, 2.0, + -1.0, 1.0, 2.0, + -1.0, -1.0, 2.0, + 1.0, -1.0, 2.0, + 1.0, 1.0, 3.0, + -1.0, 1.0, 3.0, + -1.0, -1.0, 3.0, + 1.0, -1.0, 3.0, + 1.0, 1.0, 4.0, + -1.0, 1.0, 4.0, + -1.0, -1.0, 4.0, + 1.0, -1.0, 4.0, + 0.0, 0.0, 5.0 + }; + + myMeshing.setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,"CARTESIAN",MED_FULL_INTERLACE); + + string Names[3] = { "X","Y","Z" } ; + myMeshing.setCoordinatesNames(Names); + + string Units[3] = { "cm","cm","cm" } ; + myMeshing.setCoordinatesUnits(Units) ; + + // define conectivities + + // cell part + + const int NumberOfTypes = 3 ; + medGeometryElement Types[NumberOfTypes] = {MED_TETRA4,MED_PYRA5,MED_HEXA8} ; + const int NumberOfElements[NumberOfTypes] = {12,2,2} ; + + myMeshing.setNumberOfTypes(NumberOfTypes,MED_CELL); + myMeshing.setTypes(Types,MED_CELL); + myMeshing.setNumberOfElements(NumberOfElements,MED_CELL); + + const int sizeTetra = 12*4 ; + int ConnectivityTetra[sizeTetra]= + { + 1,2,3,6, + 1,2,4,3, + 1,2,5,4, + 1,2,6,5, + 2,7,4,3, + 2,8,5,4, + 2,9,6,5, + 2,10,3,6, + 2,7,3,10, + 2,8,4,7, + 2,9,5,8, + 2,10,6,9 + }; + + myMeshing.setConnectivity(ConnectivityTetra,MED_CELL,MED_TETRA4); + + int ConnectivityPyra[2*5]= + { + 7,8,9,10,2, + 15,18,17,16,19 + }; + + myMeshing.setConnectivity(ConnectivityPyra,MED_CELL,MED_PYRA5); + + int ConnectivityHexa[2*8]= + { + 11,12,13,14,7,8,9,10, + 15,16,17,18,11,12,13,14 + }; + + myMeshing.setConnectivity(ConnectivityHexa,MED_CELL,MED_HEXA8); + + // face part + + const int NumberOfFacesTypes = 2 ; + medGeometryElement FacesTypes[NumberOfFacesTypes] = {MED_TRIA3,MED_QUAD4} ; + const int NumberOfFacesElements[NumberOfFacesTypes] = {4,4} ; + + myMeshing.setNumberOfTypes(NumberOfFacesTypes,MED_FACE); + myMeshing.setTypes(FacesTypes,MED_FACE); + myMeshing.setNumberOfElements(NumberOfFacesElements,MED_FACE); + + const int sizeTria = 3*4 ; + int ConnectivityTria[sizeTria]= + { + 1,4,3, + 1,5,4, + 1,6,5, + 1,3,6 + }; + + myMeshing.setConnectivity(ConnectivityTria,MED_FACE,MED_TRIA3); + + int ConnectivityQua[4*4]= + { + 7,8,9,10, + 11,12,13,14, + 11,7,8,12, + 12,8,9,13 + }; + + myMeshing.setConnectivity(ConnectivityQua,MED_FACE,MED_QUAD4); + + int meshDimension = SpaceDimension; // because there 3D cells in the mesh + myMeshing.setMeshDimension(meshDimension); + + // edge part + + // not yet implemented : if set, results are unpredictable. + + // Some groups : + + // Node : + + GROUP partialGroupOnNodes ; + { + partialGroupOnNodes.setName("SomeNodes"); + partialGroupOnNodes.setMesh(&myMeshing); + partialGroupOnNodes.setEntity(MED_NODE); + partialGroupOnNodes.setNumberOfGeometricType(1); + medGeometryElement myTypes[1] = {MED_NONE}; + partialGroupOnNodes.setGeometricType(myTypes); + const int myNumberOfElements[1] = {4} ; + partialGroupOnNodes.setNumberOfElements(myNumberOfElements); + const int index[1+1] = {1,5} ; + const int value[4]= { 1,4,5,7} ; + partialGroupOnNodes.setNumber(index,value); + } + myMeshing.addGroup(partialGroupOnNodes); + + + GROUP partialGroupOnNodes2 ; + { + partialGroupOnNodes2.setName("OtherNodes"); + partialGroupOnNodes2.setMesh(&myMeshing); + partialGroupOnNodes2.setEntity(MED_NODE); + partialGroupOnNodes2.setNumberOfGeometricType(1); + medGeometryElement myTypes[1] = {MED_NONE}; + partialGroupOnNodes2.setGeometricType(myTypes); + const int myNumberOfElements[1] = {3} ; + partialGroupOnNodes2.setNumberOfElements(myNumberOfElements); + const int index[1+1] = {1,4} ; + const int value[3]= { 2,3,6} ; + partialGroupOnNodes2.setNumber(index,value); + } + myMeshing.addGroup(partialGroupOnNodes2); + + + // Cell : + + GROUP partialGroupOnCells ; + { + partialGroupOnCells.setName("SomeCells"); + partialGroupOnCells.setMesh(&myMeshing); + partialGroupOnCells.setEntity(MED_CELL); + partialGroupOnCells.setNumberOfGeometricType(3); + medGeometryElement myTypes[3] = {MED_TETRA4,MED_PYRA5,MED_HEXA8}; + partialGroupOnCells.setGeometricType(myTypes); + const int myNumberOfElements[3] = {4,1,2} ; + partialGroupOnCells.setNumberOfElements(myNumberOfElements); + const int index[3+1] = {1,5,6,8} ; + const int value[4+1+2]= + { + 2,7,8,12, + 13, + 15,16 + }; + partialGroupOnCells.setNumber(index,value); + } + myMeshing.addGroup(partialGroupOnCells); + + + GROUP partialGroupOnCells2 ; + { + partialGroupOnCells2.setName("OtherCells"); + partialGroupOnCells2.setMesh(&myMeshing); + partialGroupOnCells2.setEntity(MED_CELL); + partialGroupOnCells2.setNumberOfGeometricType(2); + medGeometryElement myTypes[] = {MED_TETRA4,MED_PYRA5}; + partialGroupOnCells2.setGeometricType(myTypes); + const int myNumberOfElements[] = {4,1} ; + partialGroupOnCells2.setNumberOfElements(myNumberOfElements); + const int index[2+1] = {1,5,6} ; + const int value[4+1]= + { + 3,4,5,9, + 14 + }; + partialGroupOnCells2.setNumber(index,value); + } + myMeshing.addGroup(partialGroupOnCells2); + + + // Face : + + GROUP partialGroupOnFaces ; + { + partialGroupOnFaces.setName("SomeFaces"); + partialGroupOnFaces.setMesh(&myMeshing); + partialGroupOnFaces.setEntity(MED_FACE); + partialGroupOnFaces.setNumberOfGeometricType(2); + medGeometryElement myTypes[2] = {MED_TRIA3,MED_QUAD4}; + partialGroupOnFaces.setGeometricType(myTypes); + const int myNumberOfElements[2] = {2,3} ; + partialGroupOnFaces.setNumberOfElements(myNumberOfElements); + const int index[2+1] = {1,3,6} ; + const int value[2+3]= + { + 2,4, + 5,6,8 + } ; + partialGroupOnFaces.setNumber(index,value); + } + myMeshing.addGroup(partialGroupOnFaces); + + + GROUP partialGroupOnFaces2 ; + { + partialGroupOnFaces2.setName("OtherFaces"); + partialGroupOnFaces2.setMesh(&myMeshing); + partialGroupOnFaces2.setEntity(MED_FACE); + medGeometryElement myTypes[1] = {MED_TRIA3}; + int myNumberOfElements[1] = {2} ; + int value[2]= + { + 1,3 + } ; + // partialGroupOnFaces2.setNumber(index,value); + partialGroupOnFaces2.setpartial("description",1,2,myTypes,myNumberOfElements,value); + } + myMeshing.addGroup(partialGroupOnFaces2); + + // all right, we save it in Med 2.1 2.2 and vtk ! + + medFileVersion version = getMedFileVersionForWriting(); + if (version == V21) + setMedFileVersionForWriting(V22); + + int idMed22 = myMeshing.addDriver(MED_DRIVER,filenameMed22,myMeshing.getName()); + myMeshing.write(idMed22) ; + + version = getMedFileVersionForWriting(); + if (version == V22) + setMedFileVersionForWriting(V21); + + int idMed21 = myMeshing.addDriver(MED_DRIVER,filenameMed21,myMeshing.getName()); + myMeshing.write(idMed21) ; + + int idVtk = myMeshing.addDriver(VTK_DRIVER,filenameVtk,myMeshing.getName()); + myMeshing.write(idVtk) ; + + // we build now 8 fields : 4 fields double (integer) : + // 2 fields on nodes (cells) : + // 1 scalar (vector) + + SUPPORT * supportOnNodes = new SUPPORT(&myMeshing,"On_All_Nodes",MED_NODE); + int numberOfNodes = supportOnNodes->getNumberOfElements(MED_ALL_ELEMENTS); + + SUPPORT * supportOnCells = new SUPPORT(&myMeshing,"On_All_Cells",MED_CELL); + int numberOfCells = supportOnCells->getNumberOfElements(MED_ALL_ELEMENTS); + + FIELD<double> * fieldDoubleScalarOnNodes = new FIELD<double>(supportOnNodes,1); + fieldDoubleScalarOnNodes->setName("fieldScalarDoubleNode"); + fieldDoubleScalarOnNodes->setIterationNumber(-1); + fieldDoubleScalarOnNodes->setOrderNumber(-1); + fieldDoubleScalarOnNodes->setTime(0.0); + + fieldDoubleScalarOnNodes->setComponentName(1,"Vx"); + fieldDoubleScalarOnNodes->setComponentDescription(1,"comp1"); + fieldDoubleScalarOnNodes->setMEDComponentUnit(1,"unit1"); + + FIELD<double>* fieldDoubleScalarOnPartialNodes = new FIELD<double>(&partialGroupOnNodes,1); + fieldDoubleScalarOnPartialNodes->setName("fieldScalarDoublePartialNodes"); + fieldDoubleScalarOnPartialNodes->setIterationNumber(-1); + fieldDoubleScalarOnPartialNodes->setOrderNumber(-1); + fieldDoubleScalarOnPartialNodes->setTime(0.0); + fieldDoubleScalarOnPartialNodes->setComponentName(1,"Vx"); + fieldDoubleScalarOnPartialNodes->setComponentDescription(1,"comp1"); + fieldDoubleScalarOnPartialNodes->setMEDComponentUnit(1,"unit1"); + + + FIELD<double> * fieldDoubleVectorOnNodes = new FIELD<double>(supportOnNodes,SpaceDimension); + fieldDoubleVectorOnNodes->setName("fieldVectorDoubleNode"); + fieldDoubleVectorOnNodes->setIterationNumber(-1); + fieldDoubleVectorOnNodes->setOrderNumber(-1); + fieldDoubleVectorOnNodes->setTime(0.0); + + fieldDoubleVectorOnNodes->setComponentName(1,"Vx"); + fieldDoubleVectorOnNodes->setComponentDescription(1,"comp1"); + fieldDoubleVectorOnNodes->setMEDComponentUnit(1,"unit1"); + fieldDoubleVectorOnNodes->setComponentName(2,"Vy"); + fieldDoubleVectorOnNodes->setComponentDescription(2,"comp2"); + fieldDoubleVectorOnNodes->setMEDComponentUnit(2,"unit2"); + fieldDoubleVectorOnNodes->setComponentName(3,"Vz"); + fieldDoubleVectorOnNodes->setComponentDescription(3,"comp3"); + fieldDoubleVectorOnNodes->setMEDComponentUnit(3,"unit3"); + + FIELD<double> * fieldDoubleScalarOnCells = new FIELD<double>(supportOnCells,1); + fieldDoubleScalarOnCells->setName("fieldScalarDoubleCell"); + fieldDoubleScalarOnCells->setIterationNumber(-1); + fieldDoubleScalarOnCells->setOrderNumber(-1); + fieldDoubleScalarOnCells->setTime(0.0); + + fieldDoubleScalarOnCells->setComponentName(1,"Vx"); + fieldDoubleScalarOnCells->setComponentDescription(1,"comp1"); + fieldDoubleScalarOnCells->setMEDComponentUnit(1,"unit1"); + + + FIELD<double> * fieldDoubleScalarOnPartialCells = new FIELD<double>(&partialGroupOnCells,1); + fieldDoubleScalarOnPartialCells->setName("fieldScalarDoublePartialCell"); + fieldDoubleScalarOnPartialCells->setIterationNumber(-1); + fieldDoubleScalarOnPartialCells->setOrderNumber(-1); + fieldDoubleScalarOnPartialCells->setTime(0.0); + + fieldDoubleScalarOnPartialCells->setComponentName(1,"Vx"); + fieldDoubleScalarOnPartialCells->setComponentDescription(1,"comp1"); + fieldDoubleScalarOnPartialCells->setMEDComponentUnit(1,"unit1"); + + FIELD<double> * fieldDoubleScalarOnPartialFaces = new FIELD<double>(&partialGroupOnFaces,1); + fieldDoubleScalarOnPartialFaces->setName("fieldScalarDoublePartialFace"); + fieldDoubleScalarOnPartialFaces->setIterationNumber(-1); + fieldDoubleScalarOnPartialFaces->setOrderNumber(-1); + fieldDoubleScalarOnPartialFaces->setTime(0.0); + fieldDoubleScalarOnPartialFaces->setComponentName(1,"Vx"); + fieldDoubleScalarOnPartialFaces->setComponentDescription(1,"comp1"); + fieldDoubleScalarOnPartialFaces->setMEDComponentUnit(1,"unit1"); + + FIELD<double> * fieldDoubleVectorOnPartialFaces = new FIELD<double>(&partialGroupOnFaces2,2); + fieldDoubleVectorOnPartialFaces->setName("fieldVectorDoublePartialFace"); + fieldDoubleVectorOnPartialFaces->setIterationNumber(-1); + fieldDoubleVectorOnPartialFaces->setOrderNumber(-1); + fieldDoubleVectorOnPartialFaces->setTime(0.0); + fieldDoubleVectorOnPartialFaces->setComponentName(1,"Vx"); + fieldDoubleVectorOnPartialFaces->setComponentName(2,"Vy"); + + fieldDoubleVectorOnPartialFaces->setComponentDescription(1,"comp1"); + fieldDoubleVectorOnPartialFaces->setComponentDescription(2,"comp2"); + + fieldDoubleVectorOnPartialFaces->setMEDComponentUnit(1,"unit1"); + fieldDoubleVectorOnPartialFaces->setMEDComponentUnit(2,"unit2"); + + + FIELD<double> * fieldDoubleVectorOnCells = new FIELD<double>(supportOnCells,SpaceDimension); + fieldDoubleVectorOnCells->setName("fieldVectorrDoubleCell"); + fieldDoubleVectorOnCells->setIterationNumber(-1); + fieldDoubleVectorOnCells->setOrderNumber(-1); + fieldDoubleVectorOnCells->setTime(0.0); + + fieldDoubleVectorOnCells->setComponentName(1,"Vx"); + fieldDoubleVectorOnCells->setComponentDescription(1,"comp1"); + fieldDoubleVectorOnCells->setMEDComponentUnit(1,"unit1"); + fieldDoubleVectorOnCells->setComponentName(2,"Vy"); + fieldDoubleVectorOnCells->setComponentDescription(2,"comp2"); + fieldDoubleVectorOnCells->setMEDComponentUnit(2,"unit2"); + fieldDoubleVectorOnCells->setComponentName(3,"Vz"); + fieldDoubleVectorOnCells->setComponentDescription(3,"comp3"); + fieldDoubleVectorOnCells->setMEDComponentUnit(3,"unit3"); + + FIELD<int> * fieldIntScalarOnNodes = new FIELD<int>(supportOnNodes,1); + fieldIntScalarOnNodes->setName("fieldScalarIntNode"); + fieldIntScalarOnNodes->setIterationNumber(-1); + fieldIntScalarOnNodes->setOrderNumber(-1); + fieldIntScalarOnNodes->setTime(0.0); + + fieldIntScalarOnNodes->setComponentName(1,"Vx"); + fieldIntScalarOnNodes->setComponentDescription(1,"comp1"); + fieldIntScalarOnNodes->setMEDComponentUnit(1,"unit1"); + + FIELD<int> * fieldIntVectorOnNodes = new FIELD<int>(supportOnNodes,SpaceDimension); + fieldIntVectorOnNodes->setName("fieldVectorIntNode"); + fieldIntVectorOnNodes->setIterationNumber(-1); + fieldIntVectorOnNodes->setOrderNumber(-1); + fieldIntVectorOnNodes->setTime(0.0); + + fieldIntVectorOnNodes->setComponentName(1,"Vx"); + fieldIntVectorOnNodes->setComponentDescription(1,"comp1"); + fieldIntVectorOnNodes->setMEDComponentUnit(1,"unit1"); + fieldIntVectorOnNodes->setComponentName(2,"Vy"); + fieldIntVectorOnNodes->setComponentDescription(2,"comp2"); + fieldIntVectorOnNodes->setMEDComponentUnit(2,"unit2"); + fieldIntVectorOnNodes->setComponentName(3,"Vz"); + fieldIntVectorOnNodes->setComponentDescription(3,"comp3"); + fieldIntVectorOnNodes->setMEDComponentUnit(3,"unit3"); + + FIELD<int> * fieldIntScalarOnCells = new FIELD<int>(supportOnCells,1); + fieldIntScalarOnCells->setName("fieldScalarIntCell"); + fieldIntScalarOnCells->setIterationNumber(-1); + fieldIntScalarOnCells->setOrderNumber(-1); + fieldIntScalarOnCells->setTime(0.0); + + fieldIntScalarOnCells->setComponentName(1,"Vx"); + fieldIntScalarOnCells->setComponentDescription(1,"comp1"); + fieldIntScalarOnCells->setMEDComponentUnit(1,"unit1"); + + FIELD<int> * fieldIntVectorOnCells = new FIELD<int>(supportOnCells,SpaceDimension); + fieldIntVectorOnCells->setName("fieldVectorrIntCell"); + fieldIntVectorOnCells->setIterationNumber(-1); + fieldIntVectorOnCells->setOrderNumber(-1); + fieldIntVectorOnCells->setTime(0.0); + + fieldIntVectorOnCells->setComponentName(1,"Vx"); + fieldIntVectorOnCells->setComponentDescription(1,"comp1"); + fieldIntVectorOnCells->setMEDComponentUnit(1,"unit1"); + fieldIntVectorOnCells->setComponentName(2,"Vy"); + fieldIntVectorOnCells->setComponentDescription(2,"comp2"); + fieldIntVectorOnCells->setMEDComponentUnit(2,"unit2"); + fieldIntVectorOnCells->setComponentName(3,"Vz"); + fieldIntVectorOnCells->setComponentDescription(3,"comp3"); + fieldIntVectorOnCells->setMEDComponentUnit(3,"unit3"); + + for (int i = 0; i<numberOfNodes; i++) + { + double valueDbl1, valueDbl2, valueDbl3; + int valueInt1, valueInt2, valueInt3; + valueInt1 = i+1; + valueInt2 = i+2; + valueInt3 = i+3; + valueDbl1 = valueInt1*0.1; + valueDbl2 = valueInt2*0.1; + valueDbl3 = valueInt3*0.1; + fieldDoubleScalarOnNodes->setValueIJ(i+1,1,valueDbl1); + + fieldIntScalarOnNodes->setValueIJ(i+1,1,valueInt1); + + fieldDoubleVectorOnNodes->setValueIJ(i+1,1,valueDbl1); + fieldDoubleVectorOnNodes->setValueIJ(i+1,2,valueDbl2); + fieldDoubleVectorOnNodes->setValueIJ(i+1,3,valueDbl3); + + fieldIntVectorOnNodes->setValueIJ(i+1,1,valueInt1); + fieldIntVectorOnNodes->setValueIJ(i+1,2,valueInt2); + fieldIntVectorOnNodes->setValueIJ(i+1,3,valueInt3); + } + + for (int i = 0; i<numberOfCells; i++) + { + double valueDbl1, valueDbl2, valueDbl3; + int valueInt1, valueInt2, valueInt3; + valueInt1 = i+1; + valueInt2 = i+2; + valueInt3 = i+3; + valueDbl1 = valueInt1*0.1; + valueDbl2 = valueInt2*0.1; + valueDbl3 = valueInt3*0.1; + fieldDoubleScalarOnCells->setValueIJ(i+1,1,valueDbl1); + + fieldIntScalarOnCells->setValueIJ(i+1,1,valueInt1); + + fieldDoubleVectorOnCells->setValueIJ(i+1,1,valueDbl1); + fieldDoubleVectorOnCells->setValueIJ(i+1,2,valueDbl2); + fieldDoubleVectorOnCells->setValueIJ(i+1,3,valueDbl3); + + fieldIntVectorOnCells->setValueIJ(i+1,1,valueInt1); + fieldIntVectorOnCells->setValueIJ(i+1,2,valueInt2); + fieldIntVectorOnCells->setValueIJ(i+1,3,valueInt3); + } + + for (int i=0; i<partialGroupOnNodes.getNumberOfElements(MED_ALL_ELEMENTS); i++) + { + const int* number=partialGroupOnNodes.getNumber(MED_ALL_ELEMENTS); + fieldDoubleScalarOnPartialNodes->setValueIJ(number[i],1,i+1); + } + + for (int i=0; i<partialGroupOnCells.getNumberOfElements(MED_ALL_ELEMENTS); i++) + { + const int* number=partialGroupOnCells.getNumber(MED_ALL_ELEMENTS); + fieldDoubleScalarOnPartialCells->setValueIJ(number[i],1,i+1); + } + + for (int i=0; i<partialGroupOnFaces.getNumberOfElements(MED_ALL_ELEMENTS); i++) + { + const int* number=partialGroupOnFaces.getNumber(MED_ALL_ELEMENTS); + fieldDoubleScalarOnPartialFaces->setValueIJ(number[i],1,i+1); + } + + for (int i=0; i<partialGroupOnFaces2.getNumberOfElements(MED_ALL_ELEMENTS); i++) + { + const int* number=partialGroupOnFaces2.getNumber(MED_ALL_ELEMENTS); + fieldDoubleVectorOnPartialFaces->setValueIJ(number[i],1,i+1); + fieldDoubleVectorOnPartialFaces->setValueIJ(number[i],2,-i-1); + } + + version = getMedFileVersionForWriting(); + if (version == V22) + setMedFileVersionForWriting(V21); + + idMed21 = fieldDoubleScalarOnNodes->addDriver(MED_DRIVER,filenameMed21,fieldDoubleScalarOnNodes->getName(),WRONLY); + fieldDoubleScalarOnNodes->write(idMed21) ; + + idMed21 = fieldIntScalarOnNodes->addDriver(MED_DRIVER,filenameMed21,fieldIntScalarOnNodes->getName(),WRONLY); + fieldIntScalarOnNodes->write(idMed21) ; + + idMed21 = fieldDoubleVectorOnNodes->addDriver(MED_DRIVER,filenameMed21,fieldDoubleVectorOnNodes->getName(),WRONLY); + fieldDoubleVectorOnNodes->write(idMed21) ; + + idMed21 = fieldIntVectorOnNodes->addDriver(MED_DRIVER,filenameMed21,fieldIntVectorOnNodes->getName(),WRONLY); + fieldIntVectorOnNodes->write(idMed21) ; + + idMed21 = fieldDoubleScalarOnCells->addDriver(MED_DRIVER,filenameMed21,fieldDoubleScalarOnCells->getName(),WRONLY); + fieldDoubleScalarOnCells->write(idMed21) ; + + idMed21 = fieldIntScalarOnCells->addDriver(MED_DRIVER,filenameMed21,fieldIntScalarOnCells->getName(),WRONLY); + fieldIntScalarOnCells->write(idMed21) ; + + idMed21 = fieldDoubleVectorOnCells->addDriver(MED_DRIVER,filenameMed21,fieldDoubleVectorOnCells->getName(),WRONLY); + fieldDoubleVectorOnCells->write(idMed21) ; + + idMed21 = fieldIntVectorOnCells->addDriver(MED_DRIVER,filenameMed21,fieldIntVectorOnCells->getName(),WRONLY); + fieldIntVectorOnCells->write(idMed21) ; + + + version = getMedFileVersionForWriting(); + if (version == V21) + setMedFileVersionForWriting(V22); + + idMed22 = fieldDoubleScalarOnNodes->addDriver(MED_DRIVER,filenameMed22,fieldDoubleScalarOnNodes->getName()); + fieldDoubleScalarOnNodes->write(idMed22) ; + + idMed22 = fieldIntScalarOnNodes->addDriver(MED_DRIVER,filenameMed22,fieldIntScalarOnNodes->getName()); + fieldIntScalarOnNodes->write(idMed22) ; + + idMed22 = fieldDoubleVectorOnNodes->addDriver(MED_DRIVER,filenameMed22,fieldDoubleVectorOnNodes->getName()); + fieldDoubleVectorOnNodes->write(idMed22) ; + + idMed22 = fieldIntVectorOnNodes->addDriver(MED_DRIVER,filenameMed22,fieldIntVectorOnNodes->getName()); + fieldIntVectorOnNodes->write(idMed22) ; + + idMed22 = fieldDoubleScalarOnCells->addDriver(MED_DRIVER,filenameMed22,fieldDoubleScalarOnCells->getName()); + fieldDoubleScalarOnCells->write(idMed22) ; + + idMed22 = fieldIntScalarOnCells->addDriver(MED_DRIVER,filenameMed22,fieldIntScalarOnCells->getName()); + fieldIntScalarOnCells->write(idMed22) ; + + idMed22 = fieldDoubleVectorOnCells->addDriver(MED_DRIVER,filenameMed22,fieldDoubleVectorOnCells->getName()); + fieldDoubleVectorOnCells->write(idMed22) ; + + idMed22 = fieldIntVectorOnCells->addDriver(MED_DRIVER,filenameMed22,fieldIntVectorOnCells->getName()); + fieldIntVectorOnCells->write(idMed22) ; + + idMed22 = fieldDoubleScalarOnPartialNodes->addDriver(MED_DRIVER,filenameMed22,fieldDoubleScalarOnPartialNodes->getName()); + fieldDoubleScalarOnPartialNodes->write(idMed22) ; + + idMed22 = fieldDoubleScalarOnPartialCells->addDriver(MED_DRIVER,filenameMed22,fieldDoubleScalarOnPartialCells->getName()); + fieldDoubleScalarOnPartialCells->write(idMed22) ; + + idMed22 = fieldDoubleScalarOnPartialFaces->addDriver(MED_DRIVER,filenameMed22,fieldDoubleScalarOnPartialFaces->getName()); + fieldDoubleScalarOnPartialFaces->write(idMed22) ; + + idMed22 = fieldDoubleVectorOnPartialFaces->addDriver(MED_DRIVER,filenameMed22,fieldDoubleVectorOnPartialFaces->getName()); + fieldDoubleVectorOnPartialFaces->write(idMed22) ; + + + idVtk = fieldDoubleScalarOnNodes->addDriver(VTK_DRIVER,filenameVtk,fieldDoubleScalarOnNodes->getName()); + fieldDoubleScalarOnNodes->writeAppend(idVtk) ; + + idVtk = fieldIntScalarOnNodes->addDriver(VTK_DRIVER,filenameVtk,fieldIntScalarOnNodes->getName()); + fieldIntScalarOnNodes->writeAppend(idVtk) ; + + idVtk = fieldDoubleVectorOnNodes->addDriver(VTK_DRIVER,filenameVtk,fieldDoubleVectorOnNodes->getName()); + fieldDoubleVectorOnNodes->writeAppend(idVtk) ; + + idVtk = fieldIntVectorOnNodes->addDriver(VTK_DRIVER,filenameVtk,fieldIntVectorOnNodes->getName()); + fieldIntVectorOnNodes->writeAppend(idVtk) ; + + idVtk = fieldDoubleScalarOnCells->addDriver(VTK_DRIVER,filenameVtk,fieldDoubleScalarOnCells->getName()); + fieldDoubleScalarOnCells->writeAppend(idVtk) ; + + idVtk = fieldIntScalarOnCells->addDriver(VTK_DRIVER,filenameVtk,fieldIntScalarOnCells->getName()); + fieldIntScalarOnCells->writeAppend(idVtk) ; + + idVtk = fieldDoubleVectorOnCells->addDriver(VTK_DRIVER,filenameVtk,fieldDoubleVectorOnCells->getName()); + fieldDoubleVectorOnCells->writeAppend(idVtk) ; + + idVtk = fieldIntVectorOnCells->addDriver(VTK_DRIVER,filenameVtk,fieldIntVectorOnCells->getName()); + fieldIntVectorOnCells->writeAppend(idVtk) ; + + if (argc==1) { + cout << "Remove generated files" << endl; + remove(filenameMed21.c_str()); + remove(filenameMed22.c_str()); + remove(filenameVtk.c_str()); + } + + delete fieldDoubleScalarOnNodes; + delete fieldIntScalarOnNodes; + delete fieldDoubleVectorOnNodes; + delete fieldIntVectorOnNodes; + delete fieldDoubleScalarOnCells; + delete fieldIntScalarOnCells; + delete fieldDoubleVectorOnCells; + delete fieldIntVectorOnCells; + delete fieldDoubleScalarOnPartialCells; + delete fieldDoubleScalarOnPartialNodes; + delete fieldDoubleScalarOnPartialFaces; + delete fieldDoubleVectorOnPartialFaces; + + delete supportOnNodes; + delete supportOnCells; +} diff --git a/src/MEDMEMBinTest/test_MEDMEM_MeshingFlica.cxx b/src/MEDMEMBinTest/test_MEDMEM_MeshingFlica.cxx new file mode 100644 index 000000000..d32a684e2 --- /dev/null +++ b/src/MEDMEMBinTest/test_MEDMEM_MeshingFlica.cxx @@ -0,0 +1,213 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_Meshing.hxx" +#include "MEDMEM_Group.hxx" + +double coords[108]= + {0, 0.21504, 0.21504, 0, 0.43008, + 0.43008, 0.21504, 0, 0.43008, 0, + 0.21504, 0.21504, 0, 0.43008, + 0.43008, 0.21504, 0, 0.43008, 0, + 0.21504, 0.21504, 0, 0.43008, + 0.43008, 0.21504, 0, 0.43008, 0, + 0.21504, 0.21504, 0, 0.43008, + 0.43008, 0.21504, 0, 0.43008, + //coordY + 0, 0, 0.21504, 0.21504, 0, 0.21504, + 0.43008, 0.43008, 0.43008, 0, 0, + 0.21504, 0.21504, 0, 0.21504, + 0.43008, 0.43008, 0.43008, 0, 0, + 0.21504, 0.21504, 0, 0.21504, + 0.43008, 0.43008, 0.43008, 0, 0, + 0.21504, 0.21504, 0, 0.21504, + 0.43008, 0.43008, 0.43008, + //coordZ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.15677, 0.15677, + 0.15677, 0.15677, 0.15677, + 0.15677, 0.15677, 0.15677, + 0.15677, 0.1934, 0.1934, + 0.1934, 0.1934, 0.1934, + 0.1934, 0.1934, 0.1934, + 0.1934, 0.3485, 0.3485, + 0.3485, 0.3485, 0.3485, + 0.3485, 0.3485, 0.3485, + 0.3485}; + +int connNodalCellClassical[48]= + { 1, 2, 3, 4, 10, 11, 12, 13, + 4, 3, 7, 8, 13, 12, 16, 17, + 10, 11, 12, 13, 19, 20, 21, 22, + 13, 12, 16, 17, 22, 21, 25, 26, + 19, 20, 21, 22, 28, 29, 30, 31, + 22, 21, 25, 26, 31, 30, 34, 35 }; + +int polyHedraInd[7]={1, 7, 13, 19, 25, 31, 37}; +int polyHedraFacesInd[37]={ + 1, 5, 9, 13, 17, 21, + 25, 29, 33, 37, 41, 45, + 49, 53, 57, 61, 65, 69, + 73, 77, 81, 85, 89, 93, + 97, 101, 105, 109, 113, 117, + 121, 125, 129, 133, 137, 141, + 145 }; + +int polyHedraConn[144]={ + 2, 3, 6, 5, 11, 14, 15, 12, 2, 5, 14, 11, 5, 6, 15, 14, 6, 3, 12, 15, 3, 2, 11, 12, + 3, 7, 9, 6, 12, 15, 18, 16, 3, 6, 15, 12, 6, 9, 18, 15, 9, 7, 16, 18, 7, 3, 12, 16, + 11, 12, 15, 14, 20, 23, 24, 21, 11, 14, 23, 20, 14, 15, 24, 23, 15, 12, 21, 24, 12, 11, 20, 21, + 12, 16, 18, 15, 21, 24, 27, 25, 12, 15, 24, 21, 15, 18, 27, 24, 18, 16, 25, 27, 16, 12, 21, 25, + 20, 21, 24, 23, 29, 32, 33, 30, 20, 23, 32, 29, 23, 24, 33, 32, 24, 21, 30, 33, 21, 20, 29, 30, + 21, 25, 27, 24, 30, 33, 36, 34, 21, 24, 33, 30, 24, 27, 36, 33, 27, 25, 34, 36, 25, 21, 30, 34 }; + +int connNodalFaceClassical[116]= + { 1, 2, 3, 4, + 10, 13, 12, 11, + 1, 2, 11, 10, + 2, 3, 12, 11, + 3, 4, 13, 12, + 4, 1, 10, 13, + 4, 3, 7, 8, + 13, 17, 16, 12, + 3, 7, 16, 12, + 7, 8, 17, 16, + 8, 4, 13, 17, + 19, 22, 21, 20, + 10, 11, 20, 19, + 11, 12, 21, 20, + 12, 13, 22, 21, + 13, 10, 19, 22, + 22, 26, 25, 21, + 12, 16, 25, 21, + 16, 17, 26, 25, + 17, 13, 22, 26, + 28, 31, 30, 29, + 19, 20, 29, 28, + 20, 21, 30, 29, + 21, 22, 31, 30, + 22, 19, 28, 31, + 31, 35, 34, 30, + 21, 25, 34, 30, + 25, 26, 35, 34, + 26, 22, 31, 35}; + +int cpolygonsIndex[24]= + { 1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, + 73, 77, 81, 85, 89, 93}; + +int cpolygonsValue[92]= + {2, 5, 6, 3, + 11, 12, 15, 14, + 2, 5, 14, 11, + 5, 6, 15, 14, + 6, 3, 12, 15, + 3, 6, 9, 7, + 12, 16, 18, 15, + 6, 9, 18, 15, + 9, 7, 16, 18, + 20, 21, 24, 23, + 11, 14, 23, 20, + 14, 15, 24, 23, + 15, 12, 21, 24, + 21, 25, 27, 24, + 15, 18, 27, 24, + 18, 16, 25, 27, + 29, 30, 33, 32, + 20, 23, 32, 29, + 23, 24, 33, 32, + 24, 21, 30, 33, + 30, 34, 36, 33, + 24, 27, 36, 33, + 27, 25, 34, 36}; + +int bottom[4]={1,7,30,35}; MED_EN::medGeometryElement bottomTypes[2]={MED_EN::MED_QUAD4, MED_EN::MED_POLYGON }; int bottomIndex[3]={1,3,5}; int bottomNbOfElts[2]={2,2}; +int top[4]={21,26,46,50}; MED_EN::medGeometryElement topTypes[2]={MED_EN::MED_QUAD4, MED_EN::MED_POLYGON }; int topIndex[3]={1,3,5}; int topNbOfElts[2]={2,2}; +int side[24]={ 3, 6, 10, 11, 13, 16, 19, 20, 22, 25, 28, 29, 32, 33, 37, 38, 40, 41, 44, 45, + 47, 48, 51, 52}; MED_EN::medGeometryElement sideTypes[2]={MED_EN::MED_QUAD4, MED_EN::MED_POLYGON }; int sideIndex[3]={1,13,25}; int sideNbOfElts[2]={12,12}; + +using namespace MEDMEM; + +void addMedFacesGroup( MESHING& meshing, int nFaces, const int *groupValue, + string groupName, const MED_EN::medGeometryElement *mytypes, const int *index, const int *myNumberOfElements, int nbOfGeomTypes) + { + GROUP faces ; + faces.setName(groupName) ; + faces.setMesh(&meshing) ; + faces.setEntity(MED_EN::MED_FACE) ; + faces.setNumberOfGeometricType(nbOfGeomTypes) ; + faces.setGeometricType(mytypes); + faces.setNumberOfElements(myNumberOfElements) ; + faces.setNumber(index, groupValue) ; + meshing.addGroup(faces) ; + } + +int main() +{ + MESHING* meshing = new MESHING(); + meshing->setName( "TESTMESH" ); + meshing->setSpaceDimension(3); + const int nNodes=36; + meshing->setNumberOfNodes(nNodes); + meshing->setCoordinates(3, nNodes, coords, "CARTESIAN", + MED_EN::MED_NO_INTERLACE); + string coordname[3] = { "x", "y", "z" }; + meshing->setCoordinatesNames(coordname); + string coordunit[3] = { "m", "m", "m" }; + meshing->setCoordinatesUnits(coordunit); + //Cell connectivity info for classical elts + const MED_EN::medGeometryElement classicalTypesCell[1]={MED_EN::MED_HEXA8}; + const int nbOfCellElts[1]={6}; + meshing->setNumberOfTypes(1,MED_EN::MED_CELL); + meshing->setTypes(classicalTypesCell,MED_EN::MED_CELL); + meshing->setNumberOfElements(nbOfCellElts,MED_EN::MED_CELL); + meshing->setMeshDimension(3); + //Face connectivity info for classical elts + const MED_EN::medGeometryElement classicalTypesFace[1]={MED_EN::MED_QUAD4}; + const int nbOfFaceElts[1]={29}; + meshing->setNumberOfTypes(1,MED_EN::MED_FACE); + meshing->setTypes(classicalTypesFace,MED_EN::MED_FACE); + meshing->setNumberOfElements(nbOfFaceElts,MED_EN::MED_FACE); + //All cell conn + meshing->setConnectivity(connNodalCellClassical,MED_EN::MED_CELL,MED_EN::MED_HEXA8); + meshing->setPolyhedraConnectivity(polyHedraInd,polyHedraFacesInd,polyHedraConn,6,MED_EN::MED_CELL); + //All face conn + meshing->setConnectivity(connNodalFaceClassical,MED_EN::MED_FACE,MED_EN::MED_QUAD4); + meshing->setPolygonsConnectivity(cpolygonsIndex,cpolygonsValue,23,MED_EN::MED_FACE); + //Adding some groups on faces + addMedFacesGroup( *meshing, 4, bottom, "BottomFaces",bottomTypes,bottomIndex,bottomNbOfElts,2) ; + addMedFacesGroup( *meshing, 4, top, "TopFaces",topTypes,topIndex,topNbOfElts,2) ; + addMedFacesGroup( *meshing, 24, side, "SideFaces",sideTypes,sideIndex,sideNbOfElts,2) ; + //writing... + string medfile = "/tmp"; + if ( getenv("TMP")) + medfile=getenv("TMP"); + else if (getenv("TMPDIR")) + medfile=getenv("TMPDIR"); + medfile += "/totoFlica_V22.med"; + + int id=meshing->addDriver(MED_DRIVER,medfile.c_str()); + meshing->write(id); + delete meshing; + + remove(medfile.c_str()); + + return 0; +} diff --git a/src/MEDMEMBinTest/test_MEDMEM_MeshingPoly.cxx b/src/MEDMEMBinTest/test_MEDMEM_MeshingPoly.cxx new file mode 100644 index 000000000..38d91bc7f --- /dev/null +++ b/src/MEDMEMBinTest/test_MEDMEM_MeshingPoly.cxx @@ -0,0 +1,199 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_Meshing.hxx" +#include "MEDMEM_Field.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +int main (int argc, char ** argv) { + double Coordinates[57] = { + 2.0, 3.0, 2.0, + 3.0, 2.0, 2.0, + 4.0, 1.0, 2.0, + 2.0, 0.0, 2.0, + 0.0, 1.0, 2.0, + 1.0, 2.0, 2.0, + 2.0, 3.0, 1.0, + 3.0, 2.0, 0.0, + 4.0, 1.0, 0.0, + 2.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 1.0, 2.0, 0.0, + 5.0, 3.0, 2.0, + 7.0, 2.0, 2.0, + 6.0, 0.0, 2.0, + 6.0, 3.0, 0.0, + 7.0, 2.0, 0.0, + 6.0, 0.0, -1.0, + 5.0, 1.0, -3.0}; + + const int REFnodalConnOfFaces[74] = { + 1, 2, 3, 4, 5, 6, // Polyhedron 1 + 1, 7, 8, 2, + 2, 8, 9, 3, + 4, 3, 9, 10, + 5, 4, 10, 11, + 6, 5, 11, 12, + 1, 6, 12, 7, + 7, 12, 8, + 10, 9, 8, 12, 11, + + 13, 14, 15, 3, 2, // Polyhedron 2 + 13, 2, 8, 16, + 14, 13, 16, 17, + 15, 14, 17, + 15, 17, 18, + 15, 18, 9, + 3, 15, 9, + 2, 3, 9, 8, + 8, 9, 17, 16, + 9, 18, 17}; + + const int REFfacesIndex[20] = { + 1, 7, 11, 15, 19, 23, 27, 31, 34, + 39, 44, 48, 52, 55, 58, 61, 64, 68, 72, 75}; + + const int REFpolyIndex[3] = {1, 10, 20}; + + double PolygonCoordinates[27] = { + 2.0, 3.0, 12.0, + 3.0, 2.0, 12.0, + 4.0, 1.0, 12.0, + 2.0, 0.0, 12.0, + 0.0, 1.0, 12.0, + 1.0, 2.0, 12.0, + 5.0, 3.0, 12.0, + 7.0, 2.0, 12.0, + 6.0, 0.0, 12.0}; + + const int REFpolygonFaces[11] = { + 1, 2, 3, 4, 5, 6, // Polygon 1 + 7, 8, 9, 3, 2}; // Polygon 2 + + const int REFpolygonIndex[3] = {1, 7, 12}; + + MESHING myMeshing; + myMeshing.setName("meshing"); + + int NumberOfNodes = 19; + int SpaceDimension = 3; + int MeshDimension = 3; + + const int NumberOfTypes = 1; + medGeometryElement Types[NumberOfTypes] = {MED_TETRA4}; + const int NumberOfElements[NumberOfTypes] = {1}; + + myMeshing.setNumberOfTypes(NumberOfTypes, MED_CELL); + + myMeshing.setCoordinates(SpaceDimension, NumberOfNodes, Coordinates, + "CARTESIAN", MED_FULL_INTERLACE); + myMeshing.setSpaceDimension(SpaceDimension); + myMeshing.setMeshDimension(MeshDimension); + myMeshing.setTypes(Types, MED_CELL); + myMeshing.setNumberOfElements(NumberOfElements, MED_CELL); + + string Names[3] = {"X","Y","Z"}; + myMeshing.setCoordinatesNames(Names); + + string Units[3] = {"cm","cm","cm"}; + myMeshing.setCoordinatesUnits(Units); + + const int sizeTetra = 4*1 ; + int ConnectivityTetra[sizeTetra]= + { + 17, 9, 18, 19 + }; + + myMeshing.setConnectivity(ConnectivityTetra, MED_CELL, MED_TETRA4); + + myMeshing.setPolyhedraConnectivity(REFpolyIndex, REFfacesIndex, + REFnodalConnOfFaces, 2, MED_CELL); + + + MESHING myPolygonMeshing; + myPolygonMeshing.setName("PolygonMeshing"); + + NumberOfNodes = 9; + SpaceDimension = 3; + MeshDimension = 2; + medGeometryElement PolygonTypes[NumberOfTypes] = {MED_TRIA3}; + const int PolygonNumberOfElements[NumberOfTypes] = {2}; + + myPolygonMeshing.setNumberOfTypes(NumberOfTypes, MED_CELL); + + myPolygonMeshing.setCoordinates(SpaceDimension, NumberOfNodes, PolygonCoordinates, + "CARTESIAN", MED_FULL_INTERLACE); + myPolygonMeshing.setSpaceDimension(SpaceDimension); + myPolygonMeshing.setMeshDimension(MeshDimension); + myPolygonMeshing.setTypes(PolygonTypes, MED_CELL); + myPolygonMeshing.setNumberOfElements(PolygonNumberOfElements, MED_CELL); + + myPolygonMeshing.setCoordinatesNames(Names); + myPolygonMeshing.setCoordinatesUnits(Units); + + const int sizeTri = 3*2 ; + int ConnectivityTri[sizeTri]= + { + 1, 7, 2, 3, 9, 4 + }; + + myPolygonMeshing.setConnectivity(ConnectivityTri, MED_CELL, MED_TRIA3); + myPolygonMeshing.setPolygonsConnectivity(REFpolygonIndex, REFpolygonFaces, 2, MED_CELL); + SUPPORT *sup2 = new SUPPORT(&myPolygonMeshing); + FIELD<double> *areas = myPolygonMeshing.getArea(sup2); + const double *vals2 = areas->getValue(); + const double REFAreaOfPolyg[4] ={1.5, 2, 6, 6.5}; + int nbPts=0; + int i; + for(i=0;i<4;i++) + if(fabs(REFAreaOfPolyg[i]-vals2[i])<1e-12) + nbPts++; + delete areas; + delete sup2; + + SUPPORT *sup = new SUPPORT(&myMeshing); + FIELD<double> *vols = myMeshing.getVolume(sup); + const double *vals = vols->getValue(); + const double REFVolOfPolyHedron[3] = {2.333333333333333, 11.66666666666666, 13.83224131414673}; + for(i=0;i<3;i++) + if(fabs(REFVolOfPolyHedron[i]-vals[i])<1e-12) + nbPts++; + + delete vols; + delete sup; + if(nbPts==7) + { + cout << "ALL TESTS OK !!!" << endl; + } + else + { + cout << "TEST FAILS !!!" << endl; + return -1; + } + cout << "Writing test " << endl; + int idMed22 = myMeshing.addDriver(MED_DRIVER,"totoPoly_V22.med",myMeshing.getName()); + myMeshing.write(idMed22); + + remove("totoPoly_V22.med"); +} diff --git a/src/MEDMEMBinTest/test_MEDMEM_Meshing_poly.cxx b/src/MEDMEMBinTest/test_MEDMEM_Meshing_poly.cxx new file mode 100644 index 000000000..acee14018 --- /dev/null +++ b/src/MEDMEMBinTest/test_MEDMEM_Meshing_poly.cxx @@ -0,0 +1,158 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_Meshing.hxx" +#include "MEDMEM_DriverFactory.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; +using namespace DRIVERFACTORY; + +int main (int argc, char ** argv) +{ + // Traitement arguments + if (argc > 2) + { + cerr << "Usage : " << argv[0] + << " filenameRoot" << endl << endl + << "-> creer un maillage et le sauve dans le fichier filenameRoot22.med sous le format Med Fichier V2.2 car il contient un polygon." << endl; + exit(-1); + } + + string filenameRoot; + if (argc==2) + filenameRoot= argv[1] ; + else { + if ( getenv("TMP")) + filenameRoot=getenv("TMP"); + else if (getenv("TMPDIR")) + filenameRoot=getenv("TMPDIR"); + else + filenameRoot="/tmp"; + filenameRoot+="/testMeshingPoly"; + } + + string medfilename = filenameRoot + "22.med"; + + // Creation maillage + //*********************************************************************************** + + MESHING myMeshing; + myMeshing.setName("myMeshing"); + + // define coordinates + + int SpaceDimension = 2; + int NumberOfNodes = 11; + double Coordinates[2*11] = { + 0.0, 0.0, + 0.5, 0.0, + 1.0, 0.0, + 0.25, 0.5, + 0.5, 0.5, + 0.75, 0.5, + 0.0, 1.0, + 0.5, 1.0, + 1.0, 1.0, + 1.5, 0.0, + 1.5, 1.0, + }; + + myMeshing.setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,"CARTESIAN",MED_FULL_INTERLACE); + + string Names[3] = { "X","Y","Z" }; + myMeshing.setCoordinatesNames(Names); + + string Units[3] = { "cm","cm","cm" }; + myMeshing.setCoordinatesUnits(Units); + + // define conectivities of classic types + + // cell part + + const int NumberOfTypes = 2; + medGeometryElement Types[NumberOfTypes] = {MED_TRIA3,MED_QUAD4}; + const int NumberOfElements[NumberOfTypes] = {1,4}; + + myMeshing.setNumberOfTypes(NumberOfTypes,MED_CELL); + myMeshing.setTypes(Types,MED_CELL); + myMeshing.setNumberOfElements(NumberOfElements,MED_CELL); + + int ConnectivityTria[1*3]= + { + 7,4,1 + }; + + myMeshing.setConnectivity(ConnectivityTria,MED_CELL,MED_TRIA3); + + int ConnectivityQuad[4*4]= + { + 4,5,2,1, + 5,6,3,2, + 7,8,5,4, + 8,9,6,5 + }; + + myMeshing.setConnectivity(ConnectivityQuad,MED_CELL,MED_QUAD4); + + int MeshDimension = SpaceDimension ; + // because there are 2D cells in the mesh + + myMeshing.setMeshDimension(MeshDimension) ; + + // then define eventuel polygonal cells + + int ConnectivityPolygon[1*5]= + { + 9,11,10,3,6 + }; + int ConnectivityPolygonIndex[2]= + { + 1,6 + }; + + myMeshing.setPolygonsConnectivity(ConnectivityPolygonIndex,ConnectivityPolygon,1,MED_CELL); + + // Ecriture fichier + + medFileVersion version = getMedFileVersionForWriting(); + if (version == V21) + setMedFileVersionForWriting(V22); + + int idMed22 = myMeshing.addDriver(MED_DRIVER,medfilename,myMeshing.getName()); + myMeshing.write(idMed22) ; + + // int idVtk = myMeshing.addDriver(VTK_DRIVER,"toto.vtk",myMeshing.getName()); + // myMeshing.write(idVtk) ; + + //************************************************************************************ + + // impression de controle + cout << endl; + cout << "Impression de MESHING : " << endl; + cout << myMeshing; + + if (argc==1) { + cout << "Remove generated file" << endl; + remove( medfilename.c_str() ); + } +} diff --git a/src/MEDMEMBinTest/test_MEDMEM_ModulusArray.cxx b/src/MEDMEMBinTest/test_MEDMEM_ModulusArray.cxx new file mode 100644 index 000000000..1222f9924 --- /dev/null +++ b/src/MEDMEMBinTest/test_MEDMEM_ModulusArray.cxx @@ -0,0 +1,136 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_ModulusArray.hxx" + +using namespace std; +using namespace MEDMEM; + +int main (int argc, char ** argv) { + using namespace std ; + + int array[5]={0,1,2,1,4} ; + MEDMODULUSARRAY modulusArray(5,array); + + cout<<"ModuloArray :"<<endl; + for(int i=-10;i<15;i++) + cout <<" - A["<<i<<"]="<<modulusArray[i]<<endl; + cout <<endl; + + // test compare + int ret ; + + int array2[5]={1,4,0,1,2} ; + MEDMODULUSARRAY modulusArray2(5,array2) ; + cout<<"Same arrays, same order ... "; + if ((ret=modulusArray2.compare(modulusArray))!=1) + cout << "Error : two arrays must be identical !"<<ret<<endl; + else + cout << "OK" <<endl; + + int array3[5]={1,2,1,0,4} ; + MEDMODULUSARRAY modulusArray3(5,array3) ; + cout<<"Same arrays, reverse order ... "; + if ((ret=modulusArray3.compare(modulusArray))!=-1) + cout << "Error : two arrays are in reverse order !"<<ret<<endl; + else + cout << "OK" <<endl; + + int array4[6]={1,2,1,0} ; + MEDMODULUSARRAY modulusArray4(4,array4) ; + cout<<"Different arrays size ... "; + if ((ret=modulusArray4.compare(modulusArray))!=0) + cout << "Error : two arrays have different size !"<<ret<<endl; + else + cout << "OK" <<endl; + + int array5[5]={1,2,1,0,1} ; + MEDMODULUSARRAY modulusArray5(5,array5) ; + cout<<"Different array, same size ... "; + if ((ret=modulusArray5.compare(modulusArray))!=0) + cout << "Error : two arrays are not be identical !"<<ret<<endl; + else + cout << "OK" <<endl; + + // test small array : + + // 1 + int array6[1]={1} ; + MEDMODULUSARRAY modulusArray6(1,array6); + + cout<<"ModuloArray 1 :"<<endl; + for(int i=-10;i<15;i++) + cout <<" - A["<<i<<"]="<<modulusArray6[i]<<endl; + cout <<endl; + + int array7[1]={1} ; + MEDMODULUSARRAY modulusArray7(1,array7); + cout<<"Same arrays, same order ... "; + if ((ret=modulusArray6.compare(modulusArray7))!=1) + cout << "Error : two arrays are identical !"<<ret<<endl; + else + cout << "OK" <<endl; + int array8[1]={2} ; + MEDMODULUSARRAY modulusArray8(1,array8); + cout<<"Different arrays ... "; + if ((ret=modulusArray6.compare(modulusArray8))!=0) + cout << "Error : two arrays are different !"<<ret<<endl; + else + cout << "OK" <<endl; + + + // 2 + int array60[2]={1,2} ; + MEDMODULUSARRAY modulusArray60(2,array60); + + cout<<"ModuloArray 2 :"<<endl; + for(int i=-10;i<15;i++) + cout <<" - A["<<i<<"]="<<modulusArray60[i]<<endl; + cout <<endl; + + int array70[2]={1,2} ; + MEDMODULUSARRAY modulusArray70(2,array70); + cout<<"Same arrays, same order ... "; + if ((ret=modulusArray60.compare(modulusArray70))!=1) + cout << "Error : two arrays are identical !"<<ret<<endl; + else + cout << "OK" <<endl; + int array80[2]={2,2} ; + MEDMODULUSARRAY modulusArray80(2,array80); + cout<<"Different arrays ... "; + if ((ret=modulusArray60.compare(modulusArray80))!=0) + cout << "Error : two arrays are different !"<<ret<<endl; + else + cout << "OK" <<endl; + int array90[2]={2,1} ; + MEDMODULUSARRAY modulusArray90(2,array90); + cout<<"Same arrays, reverse order ... "; + if ((ret=modulusArray60.compare(modulusArray90))!=-1) + cout << "Error : two arrays are in reverse order !"<<ret<<endl; + else + cout << "OK" <<endl; + + + + + + return 0 ; +} diff --git a/src/MEDMEMBinTest/test_MEDMEM_PolyConnectivity.cxx b/src/MEDMEMBinTest/test_MEDMEM_PolyConnectivity.cxx new file mode 100644 index 000000000..6bccd30bc --- /dev/null +++ b/src/MEDMEMBinTest/test_MEDMEM_PolyConnectivity.cxx @@ -0,0 +1,79 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// This program test the implementation of the class CONNECTIVITY for Polygons and Polyhedron. // +// +#include "MEDMEM_Connectivity.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +int main(void) +{ + CONNECTIVITY myNodalConnectivity; + CONNECTIVITY myDescendingConnectivity; + + //POLYGONS + const med_int NumberOfPolygons = 2; + const med_int ConnectivitySize = 12; +//CCRT med_int PolygonsConnectivityIndex[NumberOfPolygons+1] = {1,7,13}; + int PolygonsConnectivityIndex[NumberOfPolygons+1] = {1,7,13}; + + //Nodal +//CCRT med_int PolygonsNodalConnectivity[ConnectivitySize] = {1,2,3,4,5,10,10,5,6,7,8,9}; + int PolygonsNodalConnectivity[ConnectivitySize] = {1,2,3,4,5,10,10,5,6,7,8,9}; + + myNodalConnectivity.setPolygonsConnectivity(MED_NODAL,MED_CELL,PolygonsNodalConnectivity,PolygonsConnectivityIndex,ConnectivitySize,NumberOfPolygons); + + //Descending +//CCRT med_int PolygonsDescendingConnectivity[ConnectivitySize] = {1,2,3,4,11,10,11,5,6,7,8,9}; + int PolygonsDescendingConnectivity[ConnectivitySize] = {1,2,3,4,11,10,11,5,6,7,8,9}; + + myDescendingConnectivity.setPolygonsConnectivity(MED_DESCENDING,MED_CELL,PolygonsDescendingConnectivity,PolygonsConnectivityIndex,ConnectivitySize,NumberOfPolygons); + + //POLYHEDRON + const med_int NumberOfPolyhedron = 2; +//CCRT med_int PolyhedronIndex[NumberOfPolyhedron+1] = {1,10,20}; + int PolyhedronIndex[NumberOfPolyhedron+1] = {1,10,20}; + + //Nodal + const med_int NumberOfFaces = 19; + const med_int NumberOfNodes = 74; +//CCRT med_int PolyhedronFacesIndex[NumberOfFaces+1] = {1,7,11,15,19,23,27,31,34,39,44,48,52,55,58,61,64,68,72,75}; + int PolyhedronFacesIndex[NumberOfFaces+1] = {1,7,11,15,19,23,27,31,34,39,44,48,52,55,58,61,64,68,72,75}; +//CCRT med_int PolyhedronNodalConnectivity[NumberOfNodes] = {1,2,3,4,5,6,1,7,8,2,2,8,9,3,4,3,9,10,5,4,10,11,6,5,11,12,1,6,12,7,7,12,8,10,9,8,12,11,13,14,15,3,2,13,2,8,16,14,13,16,17,15,14,17,15,17,18,15,18,9,3,15,9,2,3,9,8,8,9,17,16,9,18,17}; + int PolyhedronNodalConnectivity[NumberOfNodes] = {1,2,3,4,5,6,1,7,8,2,2,8,9,3,4,3,9,10,5,4,10,11,6,5,11,12,1,6,12,7,7,12,8,10,9,8,12,11,13,14,15,3,2,13,2,8,16,14,13,16,17,15,14,17,15,17,18,15,18,9,3,15,9,2,3,9,8,8,9,17,16,9,18,17}; + + myNodalConnectivity.setPolyhedronConnectivity(MED_NODAL,PolyhedronNodalConnectivity,PolyhedronIndex,NumberOfNodes,NumberOfPolyhedron,PolyhedronFacesIndex,NumberOfFaces); + + //Descending + const med_int DescendingConnectivitySize = 19; +//CCRT med_int PolyhedronDescendingConnectivity[DescendingConnectivitySize] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,3,17,18}; + int PolyhedronDescendingConnectivity[DescendingConnectivitySize] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,3,17,18}; + + myDescendingConnectivity.setPolyhedronConnectivity(MED_DESCENDING,PolyhedronDescendingConnectivity,PolyhedronIndex,DescendingConnectivitySize,NumberOfPolyhedron); + + cout << myNodalConnectivity; + cout << myDescendingConnectivity; + + return 0; +} diff --git a/src/MEDMEMBinTest/test_MEDMEM_PolyDriverMedMeshRead.cxx b/src/MEDMEMBinTest/test_MEDMEM_PolyDriverMedMeshRead.cxx new file mode 100644 index 000000000..7646b322b --- /dev/null +++ b/src/MEDMEMBinTest/test_MEDMEM_PolyDriverMedMeshRead.cxx @@ -0,0 +1,56 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// This program test the implementation of the class MED_MESH_RDONLY_DRIVER for Polygons and Polyhedron. // +// +#include "MEDMEM_define.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_MedMeshDriver.hxx" + +using namespace std; +using namespace MEDMEM; + + +int main (int argc, char ** argv) +{ + if (argc <3) // after 3, ignored ! + { + cerr << "Usage : " << argv[0] + << " filename meshname" << endl << endl; + exit(-1); + } + + string filename = argv[1]; + string meshname = argv[2]; + + MESH * myMesh = new MESH(); + myMesh->setName(meshname); + MED_MESH_RDONLY_DRIVER myMeshReadDriver(filename,myMesh); + myMeshReadDriver.setMeshName(meshname); + myMeshReadDriver.open(); + myMeshReadDriver.read(); + myMeshReadDriver.close(); + + cout << * myMesh << endl; + + delete myMesh; + return 0; +} diff --git a/src/MEDMEMBinTest/test_MEDMEM_PolyDriverMedMeshWrite.cxx b/src/MEDMEMBinTest/test_MEDMEM_PolyDriverMedMeshWrite.cxx new file mode 100644 index 000000000..e76f525dc --- /dev/null +++ b/src/MEDMEMBinTest/test_MEDMEM_PolyDriverMedMeshWrite.cxx @@ -0,0 +1,64 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// This program test the implementation of the class MED_MESH_WRONLY_DRIVER for Polygons and Polyhedron. // +// +#include "MEDMEM_define.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_MedMeshDriver.hxx" + +using namespace std; +using namespace MEDMEM; + + +int main (int argc, char ** argv) +{ + if (argc <3) // after 3, ignored ! + { + cerr << "Usage : " << argv[0] + << " filename meshname" << endl << endl; + exit(-1); + } + + string filename = argv[1]; + string meshname = argv[2]; + + // Lecture d'un fichier MED + MESH * myMesh = new MESH(); + myMesh->setName(meshname); + MED_MESH_RDONLY_DRIVER myMeshReadDriver(filename,myMesh); + myMeshReadDriver.setMeshName(meshname); + myMeshReadDriver.open(); + myMeshReadDriver.read(); + myMeshReadDriver.close(); + + // Ecriture dans un fichier MED + string filename2 = filename + "_copy"; + MED_MESH_WRONLY_DRIVER myMeshWriteDriver(filename2,myMesh); + myMeshWriteDriver.setMeshName(meshname); + myMeshWriteDriver.open(); + myMeshWriteDriver.write(); + myMeshWriteDriver.close(); + + + delete myMesh; + return 0; +} diff --git a/src/MEDMEMBinTest/test_MEDMEM_PolyhedronArray.cxx b/src/MEDMEMBinTest/test_MEDMEM_PolyhedronArray.cxx new file mode 100644 index 000000000..c22dd4021 --- /dev/null +++ b/src/MEDMEMBinTest/test_MEDMEM_PolyhedronArray.cxx @@ -0,0 +1,58 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// This program test the implementation of the POLYHEDRONARRAY class. // +// +#include "MEDMEM_PolyhedronArray.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +int main(void) +{ + POLYHEDRONARRAY myPArray(2,11,40); + med_int polyhedronindex[2] = {1,7}; + med_int facesindex[11] = {1,5,9,13,17,21,25,28,31,34,37}; + med_int nodes[40] = {1,2,6,5,2,3,7,6,4,3,7,8,1,4,8,5,1,2,3,4,5,6,7,8,5,6,9,6,7,9,7,8,9,8,5,9,5,6,7,8}; + + myPArray.setPolyhedronIndex(polyhedronindex); + myPArray.setFacesIndex(facesindex); + myPArray.setNodes(nodes); + + POLYHEDRONARRAY myPArray2(myPArray); + + const med_int* __polyhedronindex = myPArray2.getPolyhedronIndex(); + const med_int* __facesindex = myPArray2.getFacesIndex(); + const med_int* __nodes = myPArray2.getNodes(); + + cout << "__polyhedronindex =" << endl; + for (int i=0; i<2; i++) + cout << __polyhedronindex[i] << endl; + cout << "__facesindex =" << endl; + for (int i=0; i<11; i++) + cout << __facesindex[i] << endl; + cout << "__nodes =" << endl; + for (int i=0; i<40; i++) + cout << __nodes[i] << endl; + + return 0; +} diff --git a/src/MEDMEMBinTest/test_MEDMEM_SkyLineArray.cxx b/src/MEDMEMBinTest/test_MEDMEM_SkyLineArray.cxx new file mode 100644 index 000000000..f90ef8c4f --- /dev/null +++ b/src/MEDMEMBinTest/test_MEDMEM_SkyLineArray.cxx @@ -0,0 +1,87 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_SkyLineArray.hxx" + +using namespace std; +using namespace MEDMEM; + +int main (int argc, char ** argv) { + int NumberOfCell = 3 ; // 1 triangle,1 quadrangle,1 triangle + int Size = 10 ; // 10 nodes + + int * index = new int[NumberOfCell+1] ; + index[0]=1; + index[1]=4; + index[2]=8; + index[3]=11; + int * value = new int[Size] ; + value[0]=1; // first + value[1]=2; + value[2]=5; + value[3]=2; // second + value[4]=3; + value[5]=5; + value[6]=6; + value[7]=3; // thirst + value[8]=4; + value[9]=6; + // value[]=; // forth + + MEDSKYLINEARRAY * myArray = new MEDSKYLINEARRAY(NumberOfCell,Size,index,value) ; + + cout << "Show all 1 :" << endl ; + for (int i=1; i<NumberOfCell+1 ; i++) { + const int * cell = myArray->getI(i) ; + int numberof = myArray->getNumberOfI(i) ; + cout << " - " ; + for (int j=0;j<numberof;j++) + cout << cell[j] << " " ; + cout << endl ; + } + cout << "Show all 2 :" << endl ; + for (int i=1; i<NumberOfCell+1 ; i++) { + cout << " - " ; + int numberof = myArray->getNumberOfI(i) ; + for (int j=1;j<numberof+1;j++) + cout << myArray->getIJ(i,j) << " " ; + cout << endl ; + } + + MEDSKYLINEARRAY * myArray2 = new MEDSKYLINEARRAY(*myArray) ; + delete myArray ; + + cout << "Show all 3 :" << endl ; + const int * index2 = myArray2->getIndex() ; + for (int i=1; i<=NumberOfCell ; i++) { + cout << " - " ; + for (int j=index2[i-1];j<index2[i];j++) + cout << myArray2->getIndexValue(j) << " " ; + cout << endl ; + } + + delete myArray2 ; + delete[] index ; + delete[] value ; + + return 0 ; +} + diff --git a/src/MEDMEMBinTest/test_MEDMEM_nArray.cxx b/src/MEDMEMBinTest/test_MEDMEM_nArray.cxx new file mode 100644 index 000000000..c2609036f --- /dev/null +++ b/src/MEDMEMBinTest/test_MEDMEM_nArray.cxx @@ -0,0 +1,433 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include <stdlib.h> +#include <iostream> +#include <stdio.h> + +#include "MEDMEM_ArrayInterface.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_IndexCheckingPolicy.hxx" +#include "MEDMEM_ArrayConvert.hxx" + +using namespace MEDMEM; + +int main(void) { + + const int mdim = 2; + const int nbelem1 = 20; + + // TEST n° 1 FullInterlace et NoGauss + std::cout << std::endl; + std::cout << "Test de MEDMEM_Array en FullInterlace et NoGauss : " << std::endl; + std::cout << std::endl; + + bool test1ok = true; + const double * myArray1Ptr = 0; + const double array1Ref[] = { 11 , 12 , 21 , 22 , 31 , 32 , 41 , 42 , 51 , 52 , + 61 , 62 , 71 , 72 , 81 , 82 , 91 , 92 , 101 , 102 , + 111 , 112 , 121 , 122 , 131 , 132 , 141 , 142 , + 151 , 152 , 161 , 162 , 171 , 172 , 181 , 182 , + 191 , 192 , 201 , 202 }; + + const double array2Ref[] = { 11 , 21 , 31 , 41 , 51 , 61 , 71 , 81 , 91 , 101 + , 111 , 121 , 131 , 141 , 151 , 161 , 171 , 181 + , 191 , 201 , + 12 , 22 , 32 , 42 , 52 , 62 , 72 , 82 , 92 , 102 + , 112 , 122 , 132 , 142 , 152 , 162 , 172 , 182 + , 192 , 202 }; + + MEDMEM_Array<double> myArray1(mdim,nbelem1); + + for (int i =1; i <= nbelem1; i++) + for (int j =1; j <= mdim; j++) + myArray1.setIJ(i,j,i*10+j); + + myArray1Ptr = myArray1.getPtr(); + for (int i =0; i < mdim*nbelem1; i++) + test1ok = test1ok && ( myArray1Ptr[i] == array1Ref[i] ); + + std::cout << "- Egualité de myArray1 et de myArray1Ref : " << test1ok << std::endl ; + + test1ok = true; + MEDMEM_Array<double> myArray1bis(myArray1, false); + myArray1Ptr = myArray1bis.getPtr(); + for (int i =0; i < mdim*nbelem1; i++) + test1ok = test1ok && ( myArray1Ptr[i] == array1Ref[i] ); + std::cout << "- Constructeur par recopie en FullInterlace et NoGauss : " << test1ok << std::endl; + + test1ok = true; + MEDMEM_Array<double> myArray1ter; + myArray1ter = myArray1; + myArray1Ptr = myArray1ter.getPtr(); + for (int i =0; i < mdim*nbelem1; i++) + test1ok = test1ok && ( myArray1Ptr[i] == array1Ref[i] ); + std::cout << "- Opérateur d'affectation en FullInterlace et NoGauss : " << test1ok << std::endl; + + + test1ok = true; + MEDMEM_Array<double> myArray1qua(mdim,nbelem1); + myArray1Ptr = myArray1qua.getPtr(); + + for (int i =1; i <= nbelem1; i++) + myArray1qua.setRow(i,&array1Ref[(i-1)*mdim]); + + for (int i =0; i < mdim*nbelem1; i++) + test1ok = test1ok && ( myArray1Ptr[i] == array1Ref[i] ); + std::cout << "- Méthode setRow en FullInterlace et NoGauss : " << test1ok << std::endl; + + std::cout << "- Test de levée d'exception pour getColumn : "; + try { + myArray1qua.getColumn(1); + } + catch (MEDMEM::MEDEXCEPTION &m) { + std::cout << m.what() << endl ; + } + + test1ok = true; + MEDMEM_Array<double,NoInterlaceNoGaussPolicy> * myArray1cin = ArrayConvert(myArray1); + myArray1Ptr = myArray1cin->getPtr(); + int elemno = 0; + for (int j=1; j <= mdim; j++) + for (int i=1; i <= nbelem1 ; i++ ) { + test1ok = test1ok + && ( myArray1cin->getIJ(i,j) == array2Ref[elemno] ) + && ( myArray1Ptr[elemno] == array2Ref[elemno] ); + elemno++; + } + std::cout << "- Convertion du mode FullInterlaceNoGaussPolicy au mode NoInterlaceNoGaussPolicy : " + << test1ok << std::endl; + + + + // TEST n°2 NoInterlace et NoGauss + std::cout << std::endl; + std::cout << "Test de MEDMEM_Array en NoInterlace et NoGauss : " << std::endl; + std::cout << std::endl; + + bool test2ok = true; + const double * myArray2Ptr = 0; + + MEDMEM_Array<double,NoInterlaceNoGaussPolicy> myArray2(mdim,nbelem1); + + for (int i =1; i <= nbelem1; i++) + for (int j =1; j <= mdim; j++) + myArray2.setIJ(i,j,i*10+j); + + myArray2Ptr = myArray2.getPtr(); + for (int i =0; i < mdim*nbelem1; i++) + test2ok = test2ok && ( myArray2Ptr[i] == array2Ref[i] ); + + std::cout << "- Egualité de myArray2 et de myArray2Ref : " << test2ok << std::endl ; + + test2ok = true; + MEDMEM_Array<double,NoInterlaceNoGaussPolicy> myArray2bis(myArray2, false); + myArray2Ptr = myArray2bis.getPtr(); + for (int i =0; i < mdim*nbelem1; i++) + test2ok = test2ok && ( myArray2Ptr[i] == array2Ref[i] ); + std::cout << "- Constructeur par recopie en NoInterlace et NoGauss : " << test2ok << std::endl; + + test2ok = true; + MEDMEM_Array<double,NoInterlaceNoGaussPolicy> myArray2ter; + myArray2ter = myArray2; + myArray2Ptr = myArray2ter.getPtr(); + for (int i =0; i < mdim*nbelem1; i++) + test2ok = test2ok && ( myArray2Ptr[i] == array2Ref[i] ); + std::cout << "- Opérateur d'affectation en NoInterlace et NoGauss : " << test2ok << std::endl; + + test2ok = true; + MEDMEM_Array<double,NoInterlaceNoGaussPolicy> myArray2qua(mdim,nbelem1); + myArray2Ptr = myArray2qua.getPtr(); + + for (int j =1; j <= mdim; j++) + myArray2qua.setColumn(j,&array2Ref[nbelem1*(j-1)]); + + for (int i =0; i < mdim*nbelem1; i++) + test2ok = test2ok && ( myArray2Ptr[i] == array2Ref[i] ); + std::cout << "- Méthode setColumn en NoInterlace et NoGauss : " << test2ok << std::endl; + + std::cout << "- Test de levée d'exception pour getRow : " ; + try { + myArray2qua.getRow(1); + } + catch (MEDMEM::MEDEXCEPTION &m) { + std::cout << m.what() << endl ; + } + + test2ok = true; + MEDMEM_Array<double,FullInterlaceNoGaussPolicy> * myArray2cin = ArrayConvert(myArray2); + myArray2Ptr = myArray2cin->getPtr(); + elemno = 0; + for (int i=1; i <= nbelem1 ; i++ ) + for (int j=1; j <= mdim; j++) { + test2ok = test2ok + && ( myArray2cin->getIJ(i,j) == array1Ref[elemno] ) + && ( myArray2Ptr[elemno] == array1Ref[elemno] ); + elemno++; + } + std::cout << "- Convertion du mode NoInterlaceNoGaussPolicy au mode FullInterlaceNoGaussPolicy : " + << test2ok << std::endl; + + + // TEST n°3 FullInterlace et Gauss + const int nbelem2 = 5; + const int nbtypegeo = 2; + const int nbelgeoc[nbtypegeo+1] = {1,3,6}; + const int nbgaussgeo[nbtypegeo+1] = {-1,2,3}; + + std::cout << std::endl; + std::cout << "Test de MEDMEM_Array en FullInterlace et Gauss : " << std::endl; + std::cout << std::endl; + + bool test3ok = true; + const double * myArray3Ptr = 0; + const double array3Ref[] = {1.11 , 1.12 , 1.21 , 1.22 , + 2.11 , 2.12 , 2.21 , 2.22 , + 13.11 , 13.12 , 13.21 , 13.22 , 13.31 , 13.32 , + 14.11 , 14.12 , 14.21 , 14.22 , 14.31 , 14.32 , + 15.11 , 15.12 , 15.21 , 15.22 , 15.31 , 15.32 }; + + const double array4Ref[] = { 1.11 , 1.21 , 2.11 , 2.21, + 13.11 , 13.21 , 13.31 , 14.11 , 14.21 , 14.31 , + 15.11 , 15.21 , 15.31 , + 1.12 , 1.22 , 2.12 , 2.22 , + 13.12 , 13.22 , 13.32 , 14.12 , 14.22 , 14.32 , + 15.12 , 15.22 , 15.32 }; + + MEDMEM_Array<double,FullInterlaceGaussPolicy> myArray3(mdim,nbelem2,nbtypegeo,nbelgeoc,nbgaussgeo); + + elemno = 1; + for (int ntyp=1; ntyp <= nbtypegeo; ntyp++ ) { + for (int i=0; i < (nbelgeoc[ntyp]-nbelgeoc[ntyp-1]) ; i++ ) { + for (int k=1; k <= nbgaussgeo[ntyp]; k++) + for (int j=1; j <= mdim; j++) { + myArray3.setIJK(elemno,j,k,elemno+(ntyp-1)*10+0.1*k+0.01*j); + } + elemno++; + } + } + myArray3Ptr = myArray3.getPtr(); + for (int i =0; i < myArray3.getArraySize(); i++) + test3ok = test3ok && ( myArray3Ptr[i] == array3Ref[i] ); + + std::cout << "- Egualité de myArray3 et de myArray3Ref : " << test3ok << std::endl ; + + test3ok = true; + MEDMEM_Array<double,FullInterlaceGaussPolicy> myArray3bis(myArray3, false); + myArray3Ptr = myArray3bis.getPtr(); + + elemno = 0; + for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) + for (int k=1; k <= myArray3bis.getNbGauss(i); k++) + for (int j=1; j <= mdim; j++) { + test3ok = test3ok + && ( myArray3bis.getIJK(i,j,k) == array3Ref[elemno] ) + && ( myArray3Ptr[elemno] == array3Ref[elemno] ); + elemno++; + } + std::cout << "- Constructeur par recopie en FullInterlace et Gauss : " << test3ok << std::endl; + + test3ok = true; + MEDMEM_Array<double,FullInterlaceGaussPolicy> myArray3ter; + myArray3ter = myArray3; //Opérateur d'affectation + myArray3Ptr = myArray3ter.getPtr(); + + elemno = 0; + for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) + for (int k=1; k <= myArray3ter.getNbGauss(i); k++) + for (int j=1; j <= mdim; j++) { + test3ok = test3ok + && ( myArray3ter.getIJK(i,j,k) == array3Ref[elemno] ) + && ( myArray3Ptr[elemno] == array3Ref[elemno] ); + elemno++; + } + + std::cout << "- Opérateur d'affectation en FullInterlace et Gauss : " << test3ok << std::endl; + + + test3ok = true; + MEDMEM_Array<double,FullInterlaceGaussPolicy> myArray3qua(mdim,nbelem2, + nbtypegeo,nbelgeoc,nbgaussgeo); + myArray3Ptr = myArray3qua.getPtr(); + + int cumul = 0; + for (int i =1; i <= nbelem2; i++){ + myArray3qua.setRow(i,&array3Ref[cumul]); + cumul+=myArray3qua.getNbGauss(i)*mdim; + }; + + for (int i =0; i < myArray3qua.getArraySize(); i++) + test3ok = test3ok && ( myArray3Ptr[i] == array3Ref[i] ); + std::cout << "- Méthode setRow en FullInterlace et Gauss : " << test3ok << std::endl; + + std::cout << "- Test de levée d'exception pour getColumn : " ; + try { + myArray3qua.getColumn(1); + } + catch (MEDMEM::MEDEXCEPTION &m) { + std::cout << m.what() << endl ; + } + + test3ok = true; + MEDMEM_Array<double,NoInterlaceGaussPolicy> * myArray3cin = ArrayConvert(myArray3); + myArray3Ptr = myArray3cin->getPtr(); + elemno = 0; + for (int j=1; j <= mdim; j++) + for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) + for (int k=1; k <= myArray3cin->getNbGauss(i); k++) { + test3ok = test3ok + && ( myArray3cin->getIJK(i,j,k) == array4Ref[elemno] ) + && ( myArray3Ptr[elemno] == array4Ref[elemno] ); + elemno++; + } + std::cout << "- Convertion du mode FullInterlaceGaussPolicy au mode NoInterlaceGaussPolicy : " + << test3ok << std::endl; + + + // TEST n°4 NoInterlace et Gauss + std::cout << std::endl; + std::cout << "Test de MEDMEM_Array en NoInterlace et Gauss : " << std::endl; + std::cout << std::endl; + + bool test4ok = true; + const double * myArray4Ptr = 0; + + MEDMEM_Array<double,NoInterlaceGaussPolicy> myArray4(mdim,nbelem2,nbtypegeo,nbelgeoc,nbgaussgeo); + + elemno = 1; + for (int ntyp=1; ntyp <= nbtypegeo; ntyp++ ) { + for (int i=0; i < (nbelgeoc[ntyp]-nbelgeoc[ntyp-1]) ; i++ ) { + for (int k=1; k <= nbgaussgeo[ntyp]; k++) + for (int j=1; j <= mdim; j++) { + myArray4.setIJK(elemno,j,k,elemno+(ntyp-1)*10+0.1*k+0.01*j); + } + elemno++; + } + } + myArray4Ptr = myArray4.getPtr(); + for (int i =0; i < myArray4.getArraySize(); i++) { + test4ok = test4ok && ( myArray4Ptr[i] == array4Ref[i] ); + } + std::cout << "- Egualité de myArray4 et de myArray4Ref : " << test4ok << std::endl ; + + test4ok = true; + MEDMEM_Array<double,NoInterlaceGaussPolicy> myArray4bis(myArray4, false); + myArray4Ptr = myArray4bis.getPtr(); + + elemno = 0; + for (int j=1; j <= mdim; j++) + for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) + for (int k=1; k <= myArray4bis.getNbGauss(i); k++) { + test4ok = test4ok + && ( myArray4bis.getIJK(i,j,k) == array4Ref[elemno] ) + && ( myArray4Ptr[elemno] == array4Ref[elemno] ); + elemno++; + } + std::cout << "- Constructeur par recopie en NoInterlace et Gauss : " << test4ok << std::endl; + + test4ok = true; + MEDMEM_Array<double,NoInterlaceGaussPolicy> myArray4ter; + myArray4ter = myArray4; // Opérateur d'affectation + myArray4Ptr = myArray4ter.getPtr(); + + elemno = 0; + for (int j=1; j <= mdim; j++) + for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) + for (int k=1; k <= myArray4ter.getNbGauss(i); k++) { + test4ok = test4ok + && ( myArray4ter.getIJK(i,j,k) == array4Ref[elemno] ) + && ( myArray4Ptr[elemno] == array4Ref[elemno] ); + elemno++; + } + + std::cout << "- Opérateur d'affectation en NoInterlace et Gauss : " << test4ok << std::endl; + + + test4ok = true; + MEDMEM_Array<double,NoInterlaceGaussPolicy> myArray4qua(mdim,nbelem2,nbtypegeo,nbelgeoc,nbgaussgeo); + myArray4Ptr = myArray4qua.getPtr(); + + for (int j =1; j <= mdim; j++) + myArray4qua.setColumn(j,&array4Ref[(myArray4qua.getArraySize()/mdim)*(j-1)]); + + for (int i =0; i < myArray4qua.getArraySize(); i++) + test4ok = test4ok && ( myArray4Ptr[i] == array4Ref[i] ); + std::cout << "- Méthode setColumn en NoInterlace et Gauss : " << test4ok << std::endl; + + std::cout << "- Test de levée d'exception pour getRow : " ; + try { + myArray4qua.getRow(1); + } + catch (MEDMEM::MEDEXCEPTION &m) { + std::cout << m.what() << endl ; + } + + + test4ok = true; + MEDMEM_Array<double,FullInterlaceGaussPolicy> * myArray4cin = ArrayConvert(myArray4); + //// MEDMEM_Array<double,FullInterlaceGaussPolicy> * myArray4cin; + ////ArrayConvert(myArray4,myArray4cin); + // typedef MEDMEM_Array<double,FullInterlaceGaussPolicy> MyArray; + // MyArray myArray4cin MyArray(myArray4); + // myArray4cin.convert(myArray4); + // MEDMEM_Array<double,FullInterlaceGaussPolicy> myArray4cin(myArray4); + myArray4Ptr = myArray4cin->getPtr(); + elemno = 0; + for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) + for (int k=1; k <= myArray4cin->getNbGauss(i); k++) + for (int j=1; j <= mdim; j++) { + test4ok = test4ok + && ( myArray4cin->getIJK(i,j,k) == array3Ref[elemno] ) + && ( myArray4cin->getIJK(i,j,k) == myArray3.getIJK(i,j,k) ) + && ( myArray4Ptr[elemno] == array3Ref[elemno] ); + elemno++; + } + + std::cout << "- Convertion du mode NoInterlaceGaussPolicy au mode FullInterlaceGaussPolicy : " + << test4ok << std::endl; + + + //TEST DES METHODES D'INTERROGATION en NoInterlace et Gauss : + // MEDMEM_ArrayInterface<double,NoInterlace,Gauss>::Array & myArray4bis = myField4bis.getArray(); + + std::cout << std::endl; + std::cout << "Test de la méthode getDim : " << myArray4bis.getDim() << std::endl; + std::cout << "Test de la méthode getNbelem : " << myArray4bis.getNbElem() << std::endl; + std::cout << "Test de la méthode getArraySize : " << myArray4bis.getArraySize() << std::endl; + std::cout << "Test de la méthode getInterlacingType : " << myArray4bis.getInterlacingType() << std::endl; + + + // Test de levée d'exception si MED_ARRAY compilée avec une politique de checking + std::cout << std::endl; + std::cout << "Test de levée d'exception pour indice incohérent " << std::endl; + try { + myArray4.getIJ(0,2); //L'exception génère des blocks perdus (A voir) + } + catch (MEDMEM::MEDEXCEPTION &m) { + std::cout << m.what() << endl ; + } + + + + return 0; + +}; + diff --git a/src/MEDMEMBinTest/test_MEDMEM_poly3D.cxx b/src/MEDMEMBinTest/test_MEDMEM_poly3D.cxx new file mode 100755 index 000000000..20bd5c897 --- /dev/null +++ b/src/MEDMEMBinTest/test_MEDMEM_poly3D.cxx @@ -0,0 +1,312 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// This program test the implementation of the class MED_MESH_RDONLY_DRIVER for Polygons and Polyhedron. // +// +#include "MEDMEM_define.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_ModulusArray.hxx" +#include "MEDMEM_MedMeshDriver.hxx" +#include <vector> + +#define MESHNAME "poly3D" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +#define DIM_OF_FIELD 3 + + +class SupportTester { +private: + const int *_tabOfNodes; + vector<int> _eltsActiveYet; + vector<int> _lgthOfEltsActiveYet; +public: + SupportTester(const int *tabOfNodes, int nbOfElts, int nbOfNodesPerElt); + SupportTester(const int *tabOfNodes, int nbOfElts, const int *nbOfNodesPerElt); + bool isIncludedAndNotAlreadyConsumed(const int *tabOfNodesOfTheElementToTest); + bool areAllEltsConsumed(); +private: + static bool areEquivalent(const int *nodes1, const int *nodes2, int nbOfNodes); +}; + +SupportTester::SupportTester(const int *tabOfNodes, int nbOfElts, int nbOfNodesPerElt):_tabOfNodes(tabOfNodes) +{ + for(int i=0;i<nbOfElts;i++) + { + _eltsActiveYet.push_back(i*nbOfNodesPerElt); + _lgthOfEltsActiveYet.push_back(nbOfNodesPerElt); + } +} + +SupportTester::SupportTester(const int *tabOfNodes, int nbOfElts, const int *nbOfNodesPerElt):_tabOfNodes(tabOfNodes) +{ + int offset=0; + for(int i=0;i<nbOfElts;i++) + { + _eltsActiveYet.push_back(offset); + _lgthOfEltsActiveYet.push_back(nbOfNodesPerElt[i]); + } +} + +bool SupportTester::isIncludedAndNotAlreadyConsumed(const int *tabOfNodesOfTheElementToTest) +{ + vector<int>::iterator iter2=_lgthOfEltsActiveYet.begin(); + for(vector<int>::iterator iter=_eltsActiveYet.begin();iter!=_eltsActiveYet.end();iter++) + if(areEquivalent(_tabOfNodes+(*iter),tabOfNodesOfTheElementToTest,*iter2)) + { + _eltsActiveYet.erase(iter); + _lgthOfEltsActiveYet.erase(iter2); + return true; + } + else + { + iter2++; + } + return false; +} + +bool SupportTester::areAllEltsConsumed() +{ + return _eltsActiveYet.size()==0; +} + +bool SupportTester::areEquivalent(const int *nodes1, const int *nodes2, int nbOfNodes) +{ + MEDMODULUSARRAY arr1(nbOfNodes,nodes1); + MEDMODULUSARRAY arr2(nbOfNodes,nodes2); + return arr1.compare(arr2)!=0; +} + +int main (int argc, char ** argv) +{ + if (argc<2) // after 2, ignored ! + { + cerr << "Usage : " << argv[0] << " poly3D.med typically in ../../share/salome/resources/med" << endl << endl; + exit(-1); + } + int nbOfPtsForTest=0; + int i; + string filename = argv[1]; + MESH * myMesh = new MESH; + myMesh->setName(MESHNAME); + MED_MESH_RDONLY_DRIVER myMeshReadDriver(filename,myMesh); + myMeshReadDriver.setMeshName(MESHNAME); + myMeshReadDriver.open(); + myMeshReadDriver.read(); + myMeshReadDriver.close(); + //Test 1 : test if connectivity of poly3D mesh is OK + if(myMesh->getMeshDimension()==3 && myMesh->getSpaceDimension()==3) + nbOfPtsForTest++; + if(myMesh->getNumberOfElementsWithPoly(MED_EN::MED_CELL,MED_EN::MED_TETRA4)==1 && myMesh->getNumberOfElementsWithPoly(MED_EN::MED_CELL,MED_EN::MED_POLYHEDRA)==2) + nbOfPtsForTest++; + const int REFnodalConnForTetra[4]={17, 9, 18, 19}; + const int *connForTetraToTest=myMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,MED_TETRA4); + const int *connIndForTetraToTest=myMesh->getConnectivityIndex(MED_NODAL,MED_CELL); + for(i=connIndForTetraToTest[0]-1;i<connIndForTetraToTest[1]-1;i++) + if(connForTetraToTest[i]==REFnodalConnForTetra[i]) + nbOfPtsForTest++; + //6 + const int *globIndex=myMesh->getPolyhedronIndex(MED_NODAL); + const int *nodalConnOfFaces=myMesh->getPolyhedronConnectivity(MED_NODAL); + const int *facesIndex=myMesh->getPolyhedronFacesIndex(); + if(globIndex[1]-globIndex[0]==9 && globIndex[2]-globIndex[1]==10)// resp 9 faces and 10 faces are in polyh 1 and 2. + nbOfPtsForTest++; + //7 + const int REFfacesIndex[20]={1, 7, 11, 15, 19, 23, 27, 31, 34, 39, 44, 48, 52, 55, 58, 61, 64, 68, 72, 75}; + const int REFnodalConnOfFaces[74]={1, 2, 3, 4, 5, 6, // Polyhedron 1 + 1, 7, 8, 2, + 2, 8, 9, 3, + 4, 3, 9, 10, + 5, 4, 10, 11, + 6, 5, 11, 12, + 1, 6, 12, 7, + 7, 12, 8, 10, + 9, 8, 12, 11, + + 13, 14, 15, 3, 2, // Polyhedron 2 + 13, 2, 8, 16, + 14, 13, 16, 17, + 15, 14, 17, 15, + 17, 18, 15, + 18, 9, 3, + 15, 9, 2, + 3, 9, 8, + 8, 9, 17, 16, + 9, 18, 17 }; + for(i=0;i<20;i++) + if(REFfacesIndex[i]==facesIndex[i]) + nbOfPtsForTest++; + for(i=0;i<74;i++) + if(REFnodalConnOfFaces[i]==nodalConnOfFaces[i]) + nbOfPtsForTest++; + if(nbOfPtsForTest!=101) + { + cout << "TEST1 K0 ! : Invalid Globaldata in memory..." << endl; + return 1; + } + // TEST 2 : FAMILY + nbOfPtsForTest=0; + vector<FAMILY*> families=myMesh->getFamilies(MED_FACE); + if(families.size()==3) + nbOfPtsForTest++; + vector<FAMILY *>::iterator iter=families.begin(); + FAMILY *fam1=*(iter++); + FAMILY *fam2=*(iter++); + FAMILY *fam3=*(iter); + const int *nbs; + // family 1 + if(fam1->getNumberOfTypes()==1 && fam1->getTypes()[0]==MED_POLYGON && fam1->getNumberOfElements(MED_ALL_ELEMENTS)==3) + nbOfPtsForTest++; + nbs=fam1->getNumber(MED_ALL_ELEMENTS); + const int REFTabForPolyg[16]={1, 2, 3, 4, 5, 6, 10, 9, 8, 12, 11, 13, 14, 15, 3, 2}; + const int REFTabForPolygLgth[3]={6,5,5}; + SupportTester test1(REFTabForPolyg,3,REFTabForPolygLgth); + for(i=0;i<3;i++) + { + int lgth; + const int *conn=((CONNECTIVITY *)myMesh->getConnectivityptr())->getConnectivityOfAnElementWithPoly(MED_NODAL,MED_FACE,nbs[i],lgth); + if(test1.isIncludedAndNotAlreadyConsumed(conn)) + nbOfPtsForTest++; + } + if(test1.areAllEltsConsumed()) + nbOfPtsForTest++; + // family 2 + if(fam2->getNumberOfElements(MED_ALL_ELEMENTS)==8) + nbOfPtsForTest++; + nbs=fam2->getNumber(MED_ALL_ELEMENTS); + const int REFTabForQuad[32]={1, 7, 8, 2, 2, 8, 9, 3, 4, 3, 9, 10, 5, 4, 10, 11, 6, 5, 11, 12, 1, 6, 12, 7, 14, 13, 16, 17, 8, 9, 17, 16}; + SupportTester test2(REFTabForQuad,8,4); + for(i=0;i<8;i++) + { + int lgth; + const int *conn=((CONNECTIVITY *)myMesh->getConnectivityptr())->getConnectivityOfAnElementWithPoly(MED_NODAL,MED_FACE,nbs[i],lgth); + if(test2.isIncludedAndNotAlreadyConsumed(conn)) + nbOfPtsForTest++; + } + if(test2.areAllEltsConsumed()) + nbOfPtsForTest++; + // family 3 + if(fam3->getNumberOfElements(MED_ALL_ELEMENTS)==6) + nbOfPtsForTest++; + nbs=fam3->getNumber(MED_ALL_ELEMENTS); + const int REFTabForTria[18]={7, 12, 8, 15, 14, 17, 15, 17, 18, 15, 18, 9, 3, 15, 9, 18, 17, 9}; + SupportTester test3(REFTabForTria,6,3); + for(i=0;i<6;i++) + { + int lgth; + const int *conn=((CONNECTIVITY *)myMesh->getConnectivityptr())->getConnectivityOfAnElementWithPoly(MED_NODAL,MED_FACE,nbs[i],lgth); + if(test3.isIncludedAndNotAlreadyConsumed(conn)) + nbOfPtsForTest++; + } + if(test3.areAllEltsConsumed()) + nbOfPtsForTest++; + if(nbOfPtsForTest!=21) + { + cout << "TEST2 K0 ! : Invalid data in memory for families !!!" << endl; + return 1; + } + // TEST 3 : volumes, aeras, barycenter + nbOfPtsForTest=0; + SUPPORT *supOnCell=new SUPPORT(myMesh); + FIELD<double>* vol1=myMesh->getVolume(supOnCell); + int lgth=vol1->getValueLength(); + const double *vals=vol1->getValue(); + if(lgth==3) + nbOfPtsForTest++; + const double REFVolOfPolyHedron[3]={2.333333333333333,11.66666666666666,13.83224131414673}; + for(i=0;i<3;i++) + if(fabs(REFVolOfPolyHedron[i]-vals[i])<1e-12) + nbOfPtsForTest++; + delete vol1; + FIELD<double>* bary=myMesh->getBarycenter(supOnCell); + lgth=bary->getValueLength(); + vals=bary->getValue(); + if(lgth==9) + nbOfPtsForTest++; + const double REFBaryOfPolyHedron[9]= {5.5, 1, -1, 2, 1.5, 1.0833333333333333, 5.1, 1.6, 0.9}; + for(i=0;i<9;i++) + if(fabs(REFBaryOfPolyHedron[i]-vals[i])<1e-12) + nbOfPtsForTest++; + delete bary; + delete supOnCell; + //area + vol1=myMesh->getArea(fam1); + lgth=vol1->getValueLength(); + vals=vol1->getValue(); + if(lgth==3) + nbOfPtsForTest++; + const double REFAreaForPolyg[3]={6,5,6.5}; + for(i=0;i<3;i++) + if(fabs(REFAreaForPolyg[i]-vals[i])<1e-12) + nbOfPtsForTest++; + + vol1=myMesh->getArea(fam2); + lgth=vol1->getValueLength(); + vals=vol1->getValue(); + if(lgth==8) + nbOfPtsForTest++; + const double REFAreaForQuad[8]={2.1213203435596424, 2.8284271247461903, 4.4721359549995796, 4.4721359549995796, + 2.8284271247461903, 2.1213203435596428, 3.6798724963767362, 4}; + for(i=0;i<8;i++) + if(fabs(REFAreaForQuad[i]-vals[i])<1e-12) + nbOfPtsForTest++; + delete vol1; + + vol1=myMesh->getArea(fam3); + lgth=vol1->getValueLength(); + vals=vol1->getValue(); + if(lgth==6) + nbOfPtsForTest++; + const double REFAreaForTri[6]={2.9580398915498081, 1.4142135623730951, 2.2360679774997898, + 3.3541019662496847, 3.3541019662496847, 2.2360679774997898}; + for(i=0;i<6;i++) + if(fabs(REFAreaForTri[i]-vals[i])<1e-12) + nbOfPtsForTest++; + delete vol1; + if(nbOfPtsForTest!=34) + { + cout << "TEST3 K0 ! : Error in caluclation of basic properties !!!" << endl; + return 1; + } + // TEST 4 -- CHECK FOR Reverse descending using getBoundaryElements. + nbOfPtsForTest=0; + SUPPORT *bound=myMesh->getBoundaryElements(MED_NODE); + if(bound->getNumberOfElements(MED_ALL_ELEMENTS)==19) + nbOfPtsForTest++; + if(bound->isOnAllElements()) + nbOfPtsForTest++; + if(nbOfPtsForTest!=2) + { + cout << "TEST4 K0 ! : Error in getBoundaryElements probably due to Reverse descending !!!" << endl; + return 1; + } + delete bound; + /////////// + cout << "ALL TESTS OK !!!" << endl; + delete myMesh; + return 0; +} diff --git a/src/MEDMEMBinTest/test_affect_medarray.cxx b/src/MEDMEMBinTest/test_affect_medarray.cxx new file mode 100644 index 000000000..43f0038c3 --- /dev/null +++ b/src/MEDMEMBinTest/test_affect_medarray.cxx @@ -0,0 +1,129 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +/* Programme de test du constructeur de copies de la classe MEDARRAY de MEDMEM + jroy - 16/12/2002 */ + +#include <string> + +#include <math.h> +#include <stdlib.h> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Group.hxx" + +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_MedFieldDriver.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_define.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +void affiche_medarray(MEDARRAY<double> & myMedArray) +{ + int numberof ; + MESSAGE_MED("Show all 1 :"); + numberof = myMedArray.getLeadingValue() ; + for (int i=1; i<=myMedArray.getLengthValue() ; i++) { + const double * node = myMedArray.getRow(i) ; + cout << " - " ; + for (int j=0;j<numberof;j++) + cout << node[j] << " " ; + cout << endl ; + } + MESSAGE_MED("Show all 2 :"); + numberof = myMedArray.getLengthValue() ; + for (int i=1; i<=myMedArray.getLeadingValue() ; i++) { + const double * node = myMedArray.getColumn(i) ; + cout << " - " ; + for (int j=0;j<numberof;j++) + cout << node[j] << " " ; + cout << endl ; + } + MESSAGE_MED("Show all 3 :"); + numberof = myMedArray.getLeadingValue() ; + for (int i=1; i<=myMedArray.getLengthValue() ; i++) { + cout << " - " ; + for (int j=1;j<numberof+1;j++) + cout << myMedArray.getIJ(i,j) << " " ; + cout << endl ; + } + + MESSAGE_MED("Show all 0 :"); + numberof = myMedArray.getLeadingValue() ; + int length = myMedArray.getLengthValue() ; + const double * NoInterlaceArray = myMedArray.get(MED_NO_INTERLACE) ; + for (int i=0; i<length ; i++) { + cout << " - " ; + for (int j=0;j<numberof;j++) + cout << NoInterlaceArray[j*length+i] << " " ; + cout << endl ; + } + + + /* + cout << "Nombre de lignes : " << myMedArray.getLengthValue() << endl; + cout << "Nombre de colonnes : " << myMedArray.getLeadingValue() << endl; + cout << "Mode d'écriture en mémoire : " << myMedArray.getMode() << endl; + cout << "Valeurs (_valuesDefault) :" << endl; + + for (med_int i=1; i<=myMedArray.getLengthValue(); i++) { + for (med_int j=1; j<=myMedArray.getLeadingValue(); j++) + cout << i << " " << j << " " << myMedArray.getIJ(i,j) << " " << endl; + } + */ +} + + +int main (int argc, char ** argv) { + /* + if ((argc !=3) && (argc != 4)) { + cerr << "Usage : " << argv[0] + << " filename meshname fieldname" << endl << endl; + exit(-1); + } + */ + const med_int nb_noeuds = 8; + const med_int dimension = 3; + const medModeSwitch mode = MED_NO_INTERLACE; + + + MEDARRAY<double> * myMedArray = new MEDARRAY<double>(dimension,nb_noeuds,mode); + for (med_int i=1; i<=myMedArray->getLengthValue(); i++) { + for (med_int j=1; j<=myMedArray->getLeadingValue(); j++) + myMedArray->setIJ(i,j,(double) rand()); + }; + + affiche_medarray(* myMedArray); + MEDARRAY<double> * myMedArray2 = new MEDARRAY<double>(); + * myMedArray2 = * myMedArray; + // delete myMedArray; // si on recopie les tableaux + affiche_medarray(* myMedArray2); + delete myMedArray; // si on ne recopie pas les tableaux + delete myMedArray2; + + return 0; +} diff --git a/src/MEDMEMBinTest/test_copie_connectivity.cxx b/src/MEDMEMBinTest/test_copie_connectivity.cxx new file mode 100644 index 000000000..057c4e62a --- /dev/null +++ b/src/MEDMEMBinTest/test_copie_connectivity.cxx @@ -0,0 +1,175 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +/* Programme de test du constructeur de copies de la classe CONNECTIVITY de MEDMEM + jroy - 19/12/2002 */ + +#include <string> + +#include <math.h> +#include <stdlib.h> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Group.hxx" + +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_MedFieldDriver.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_define.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +void affiche_connectivity(const CONNECTIVITY * myConnectivity, MESH * myMesh) +{ + int SpaceDimension = myMesh->getSpaceDimension() ; + int MeshDimension = myMesh->getMeshDimension() ; + int NumberOfNodes = myMesh->getNumberOfNodes() ; + + int NumberOfTypes = myMesh->getNumberOfTypes(MED_CELL) ; + const medGeometryElement * Types = myMesh->getTypes(MED_CELL) ; + + cout << "Show Connectivity (Nodal) :" << endl ; + for (int i=0; i<NumberOfTypes; i++) { + cout << "For type " << Types[i] << " : " << endl ; + int NumberOfElements = myMesh->getNumberOfElements(MED_CELL,Types[i]); + const int * connectivity = myMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_CELL,Types[i]); + int NomberOfNodesPerCell = Types[i]%100 ; + for (int j=0;j<NumberOfElements;j++){ + cout << "Element "<< j+1 <<" : " ; + for (int k=0;k<NomberOfNodesPerCell;k++) + cout << connectivity[j*NomberOfNodesPerCell+k]<<" "; + cout << endl ; + } + } + + cout << "Show Reverse Nodal Connectivity :" << endl ; + const int * ReverseNodalConnectivity = myMesh->getReverseConnectivity(MED_NODAL) ; + const int * ReverseNodalConnectivityIndex = myMesh->getReverseConnectivityIndex(MED_NODAL) ; + for (int i=0; i<NumberOfNodes; i++) { + cout << "Node "<<i+1<<" : " ; + for (int j=ReverseNodalConnectivityIndex[i];j<ReverseNodalConnectivityIndex[i+1];j++) + cout << ReverseNodalConnectivity[j-1] << " " ; + cout << endl ; + } + + cout << "Show Connectivity (Descending) :" << endl ; + int NumberOfElements ; + const int * connectivity ; + const int * connectivity_index ; + myMesh->calculateConnectivity(MED_FULL_INTERLACE,MED_DESCENDING,MED_CELL); + try { + NumberOfElements = myMesh->getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS); + connectivity = myMesh->getConnectivity(MED_FULL_INTERLACE,MED_DESCENDING,MED_CELL,MED_ALL_ELEMENTS); + connectivity_index = myMesh->getConnectivityIndex(MED_DESCENDING,MED_CELL); + } + catch (MEDEXCEPTION m) { + cout << m.what() << endl ; + exit (-1) ; + } + for (int j=0;j<NumberOfElements;j++) { + cout << "Element "<<j+1<<" : " ; + for (int k=connectivity_index[j];k<connectivity_index[j+1];k++) + cout << connectivity[k-1]<<" "; + cout << endl ; + } + + cout << "Show Reverse Descending Connectivity :" << endl ; + const int * ReverseDescendingConnectivity = myMesh->getReverseConnectivity(MED_DESCENDING) ; + const int * ReverseDescendingConnectivityIndex = myMesh->getReverseConnectivityIndex(MED_DESCENDING) ; + + int NumberOfConstituents = 0; + string constituent ; + medEntityMesh constituentEntity ; + + if (MeshDimension==3) { + constituent = "Face" ; + constituentEntity = MED_FACE ; + } + + if (MeshDimension==2) { + constituent = "Edge" ; + constituentEntity = MED_EDGE ; + } + + if (MeshDimension==1) { + MESSAGE_MED("ERROR : MeshDimension = 1 !"); + MESSAGE_MED("We could not see Reverse Descending Connectivity.") ; + } else { + NumberOfConstituents = myMesh->getNumberOfElements (constituentEntity,MED_ALL_ELEMENTS); + for (int i=0; i<NumberOfConstituents; i++) { + cout << constituent <<i+1<<" : " ; + for (int j=ReverseDescendingConnectivityIndex[i];j<ReverseDescendingConnectivityIndex[i+1];j++) + cout << ReverseDescendingConnectivity[j-1] << " " ; + cout << endl ; + } + } + cout << "Show "<<constituent<<" Connectivity (Nodal) :" << endl ; + const int * face_connectivity = myMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,constituentEntity,MED_ALL_ELEMENTS); + const int * face_connectivity_index = myMesh->getConnectivityIndex(MED_NODAL,constituentEntity); + for (int i=0; i<NumberOfConstituents; i++) { + cout << constituent <<i+1<<" : " ; + for (int j=face_connectivity_index[i];j<face_connectivity_index[i+1];j++) + cout << face_connectivity[j-1]<<" "; + cout << endl ; + } +} + + +int main (int argc, char ** argv) { + + if (argc <3) { // after 3, ignored ! + cerr << "Usage : " << argv[0] + << " filename meshname" << endl << endl; + exit(-1); + } + + string filename = argv[1] ; + string meshname = argv[2] ; + + //Construction d'un maillage + MESH * myMesh= new MESH() ; + myMesh->setName(meshname); + MED_MESH_RDONLY_DRIVER myMeshDriver(filename,myMesh) ; + myMeshDriver.setMeshName(meshname); + myMeshDriver.open() ; + myMeshDriver.read() ; //A partir d'ici la connectivité est construite + myMeshDriver.close() ; + + const CONNECTIVITY * myConnectivity = myMesh->getConnectivityptr(); + affiche_connectivity(myConnectivity, myMesh); + + CONNECTIVITY * myConnectivity2 = new CONNECTIVITY(* myConnectivity); + affiche_connectivity(myConnectivity2, myMesh); + + CONNECTIVITY * myConnectivity3 = new CONNECTIVITY(* myConnectivity2); + delete myConnectivity2; + affiche_connectivity(myConnectivity3, myMesh); + delete myConnectivity3; + + delete myMesh ; + + return 0; +} diff --git a/src/MEDMEMBinTest/test_copie_coordinate.cxx b/src/MEDMEMBinTest/test_copie_coordinate.cxx new file mode 100644 index 000000000..4d039f1ec --- /dev/null +++ b/src/MEDMEMBinTest/test_copie_coordinate.cxx @@ -0,0 +1,139 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +/* Programme de test du constructeur de copies de la classe COORDINATE de MEDMEM + jroy - 17/12/2002 */ + +#include <string> + +#include <math.h> +#include <stdlib.h> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Group.hxx" + +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_MedFieldDriver.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_define.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +void affiche_tableau(const double * myArray, int nb_lignes, int nb_colonnes) +{ + cout << "Nombre de lignes : " << nb_lignes << endl; + cout << "Nombre de colonnes : " << nb_colonnes << endl; + cout << "Valeurs :" << endl; + + for (int i=0; i<nb_lignes; i++) { + for (int j=0; j<nb_colonnes; j++) + cout << myArray[j*nb_lignes+i] << " "; + cout << endl;} +} + +void affiche_coordinate(COORDINATE & myCoordinate, int _numberofNodes, int _spaceDimension) +{ + cout << "- Système de coordonnées : " << myCoordinate.getCoordinatesSystem() << endl; + cout << "- Tableau des coordonnées : " << endl; + // affiche_medarray(* myCoordinate.getCoordinatePtr()); + affiche_tableau(myCoordinate.getCoordinates(MED_NO_INTERLACE),_numberofNodes,_spaceDimension); + //on récupère les dimensions + // int _spaceDimension = (int) myCoordinate.getCoordinatePtr()->getLeadingValue(); + //int _numberofNodes = (int) myCoordinate.getCoordinatePtr()->getLengthValue(); + cout << "- Nom des coordonnées : " << endl; + for (int i=1; i<=_spaceDimension; i++) + cout << i << " " << myCoordinate.getCoordinateName(i) << endl; + // cout<<myCoordinate.getCoordinatesNames()<<endl; + cout << "- Unité des coordonnées : " << endl; + for (int i=1; i<=_spaceDimension; i++) + cout << i << " " << myCoordinate.getCoordinateUnit(i) << endl; + cout << "- Indices des noeuds : " << endl; + // cout<<myCoordinate.getNodesNumbers()<<endl; + for (int i=0; i<_numberofNodes; i++) + cout << i << " " << myCoordinate.getNodesNumbers()[i] << endl; +} + + +int main (int argc, char ** argv) { + /* + if ((argc !=3) && (argc != 4)) { + cerr << "Usage : " << argv[0] + << " filename meshname fieldname" << endl << endl; + exit(-1); + } + */ + const med_int numberofNodes = 5; + const med_int spaceDimension = 3; + const medModeSwitch mode = MED_FULL_INTERLACE; + + //construction tableau MEDARRAY des coordonnées + MEDARRAY<double> * myMedArray = new MEDARRAY<double>(spaceDimension,numberofNodes,mode); + for (med_int i=1; i<=myMedArray->getLengthValue(); i++) { + for (med_int j=1; j<=myMedArray->getLeadingValue(); j++) + myMedArray->setIJ(i,j,(double) rand()); + }; + + //construction noms des coordonnées + string * myCoordinatesNames = new string[spaceDimension]; + if (spaceDimension >= 1) myCoordinatesNames[0] = "x"; + if (spaceDimension >= 2) myCoordinatesNames[1] = "y"; + if (spaceDimension >= 3) myCoordinatesNames[2] = "z"; + + //construction unités des coordonnées + string * myCoordinatesUnits = new string[spaceDimension]; + if (spaceDimension >= 1) myCoordinatesUnits[0] = "m"; + if (spaceDimension >= 2) myCoordinatesUnits[1] = "m"; + if (spaceDimension >= 3) myCoordinatesUnits[2] = "m"; + + //construction des indices des noeuds + int * myNodeNumber = new int[numberofNodes]; + for (int i=0; i<numberofNodes; i++) + myNodeNumber[i]=numberofNodes-i-1; + + //construction de l'objet COORDINATE + COORDINATE * myCoordinate = new COORDINATE(); + myCoordinate->setCoordinates(myMedArray); + myCoordinate->setCoordinatesNames(myCoordinatesNames); + myCoordinate->setCoordinatesUnits(myCoordinatesUnits); + myCoordinate->setNodesNumbers(myNodeNumber); + + // myCoordinate->setCoordinatesNames((string *)NULL); + // myCoordinate->setNodesNumbers((int *) NULL); + + delete myMedArray ; + delete[] myCoordinatesNames ; + delete[] myCoordinatesUnits ; + delete[] myNodeNumber ; + + affiche_coordinate(* myCoordinate,numberofNodes,spaceDimension); + COORDINATE * myCoordinate2 = new COORDINATE(* myCoordinate); + delete myCoordinate ; + + affiche_coordinate(* myCoordinate2,numberofNodes,spaceDimension); + delete myCoordinate2 ; + + return 0; +} diff --git a/src/MEDMEMBinTest/test_copie_family.cxx b/src/MEDMEMBinTest/test_copie_family.cxx new file mode 100644 index 000000000..a2e656f55 --- /dev/null +++ b/src/MEDMEMBinTest/test_copie_family.cxx @@ -0,0 +1,158 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include<string> + +#include <math.h> +#include <stdlib.h> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Group.hxx" + +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_MedFieldDriver.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_define.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +void affiche_support(const SUPPORT * mySupport) +{ + cout << " - Name : "<<mySupport->getName().c_str()<<endl ; + cout << " - Description : "<<mySupport->getDescription().c_str()<<endl ; + cout << " - Entity : "<<mySupport->getEntity()<<endl ; + cout << " - Entities list : "<<endl ; + if (!(mySupport->isOnAllElements())) { + int NumberOfTypes = mySupport->getNumberOfTypes() ; + cout<<" - NumberOfTypes : "<<NumberOfTypes<<endl; + const medGeometryElement * Types = mySupport->getTypes() ; + for (int j=0;j<NumberOfTypes;j++) { + cout<<" * Type "<<Types[j]<<" : "; + int NumberOfElements = mySupport->getNumberOfElements(Types[j]) ; + const int * Number = mySupport->getNumber(Types[j]) ; + for (int k=0; k<NumberOfElements;k++) + cout << Number[k] << " "; + cout << endl ; + } + } else + cout << " Is on all entities !"<< endl; +} + + +void affiche_famille(const FAMILY * myFamily) +{ + affiche_support(myFamily); + cout << " - Identifier : "<<myFamily->getIdentifier()<<endl ; + int NumberOfAttributes = myFamily->getNumberOfAttributes() ; + cout << " - Attributes ("<<NumberOfAttributes<<") :"<<endl; + for (int j=1;j<NumberOfAttributes+1;j++) + cout << " * "<<myFamily->getAttributeIdentifier(j)<<" : "<<myFamily->getAttributeValue(j)<<", "<<myFamily->getAttributeDescription(j).c_str()<<endl ; + int NumberOfGroups = myFamily->getNumberOfGroups() ; + cout << " - Groups ("<<NumberOfGroups<<") :"<<endl; + for (int j=1;j<NumberOfGroups+1;j++) + cout << " * "<<myFamily->getGroupName(j).c_str()<<endl ; +} + +void affiche_groupe(MESH *myMesh,medEntityMesh Entity) +{ + int NumberOfGroups = myMesh->getNumberOfGroups(Entity) ; + cout << "NumberOfGroups : "<<NumberOfGroups<<endl; + for (int i=1; i<NumberOfGroups+1;i++) { + const GROUP* myGroup = myMesh->getGroup(Entity,i); + affiche_support(myGroup); + int NumberOfFamillies = myGroup->getNumberOfFamilies() ; + cout << " - Families ("<<NumberOfFamillies<<") :"<<endl; + for (int j=1;j<NumberOfFamillies+1;j++) + cout << " * "<<myGroup->getFamily(j)->getName().c_str()<<endl ; + } +} + +int main (int argc, char ** argv) { + int read; + + if (argc <3) { // after 3, ignored ! + cerr << "Usage : " << argv[0] + << " filename meshname" << endl << endl; + exit(-1); + } + + string filename = argv[1] ; + string meshname = argv[2] ; + + MESH * myMesh= new MESH() ; + myMesh->setName(meshname); + MED_MESH_RDONLY_DRIVER myMeshDriver(filename,myMesh) ; + myMeshDriver.setMeshName(meshname); + myMeshDriver.open() ; + myMeshDriver.read() ; + myMeshDriver.close() ; + + const FAMILY * myFamily = myMesh->getFamily(MED_NODE,1); + //On renseigne les attributs spécifiques à FAMILY (p/r à SUPPORT) et non renseignés lors de la lecture du maillage +// int NumberOfAttribute = 3; +// int *AttributeIdentifier = new int[NumberOfAttribute]; +// int *AttributeValue = new int[NumberOfAttribute]; +// string *AttributeDescription = new string[NumberOfAttribute]; +// char *tmp; +// for (int i=0;i<NumberOfAttribute;i++) +// { +// AttributeIdentifier[i]=i+1; +// AttributeValue[i]=(i+1)*10; +// sprintf(tmp,"Attribut N° %d",i+1); +// AttributeDescription[i]=tmp; +// } + +// myFamily->setNumberOfAttributes(NumberOfAttribute); +// myFamily->setAttributesIdentifiers (AttributeIdentifier); +// myFamily->setAttributesValues (AttributeValue); +// myFamily->setAttributesDescriptions (AttributeDescription); + + cout << "Show Family :"<<endl ; + affiche_famille(myFamily); + FAMILY * myFamily2 = new FAMILY(* myFamily); + //delete myFamily; + cout << "Show Family2 :"<<endl ; + affiche_famille(myFamily2); + FAMILY * myFamily3 = new FAMILY(* myFamily2); + delete myFamily2; + cout << "Show Family3 :"<<endl ; + affiche_famille(myFamily3); + delete myFamily3; + + cout << "That's all"<<endl ; + + /* + cout << "Show Group :"<<endl ; + affiche_groupe(myMesh,MED_NODE); + affiche_groupe(myMesh,MED_CELL); + affiche_groupe(myMesh,MED_FACE); + affiche_groupe(myMesh,MED_EDGE); + */ + + delete myMesh; + + return 0; +} diff --git a/src/MEDMEMBinTest/test_copie_fieldT.cxx b/src/MEDMEMBinTest/test_copie_fieldT.cxx new file mode 100644 index 000000000..e5bc134a3 --- /dev/null +++ b/src/MEDMEMBinTest/test_copie_fieldT.cxx @@ -0,0 +1,157 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +/* Programme de test du constructeur de copies de la classe FIELD_ de MEDMEM + jroy - 12/12/2002 */ + +#include<string> + +#include <math.h> +#include <stdlib.h> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Group.hxx" + +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_MedFieldDriver.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_FieldConvert.hxx" +#include "MEDMEM_define.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + + +void affiche_field_(FIELD_ * myField, const SUPPORT * mySupport) +{ + cout << "Field "<< myField->getName() << " : " <<myField->getDescription() << endl ; + int NumberOfComponents = myField->getNumberOfComponents() ; + cout << "- Nombre de composantes : "<< NumberOfComponents << endl ; + for (int i=1; i<NumberOfComponents+1; i++) { + cout << " - composante "<<i<<" :"<<endl ; + cout << " - nom : "<<myField->getComponentName(i)<< endl; + cout << " - description : "<<myField->getComponentDescription(i) << endl; + cout << " - units : "<<myField->getMEDComponentUnit(i) << endl; + } + cout << "- iteration :" << endl ; + cout << " - numero : " << myField->getIterationNumber()<< endl ; + cout << " - ordre : " << myField->getOrderNumber()<< endl ; + cout << " - temps : " << myField->getTime()<< endl ; + + cout << "- Type : " << myField->getValueType()<< endl; + + cout << "- Adresse support : " << mySupport << endl; +} + +template <class INTERLACING_TAG> +void affiche_fieldT(FIELD<double, INTERLACING_TAG> * myField, + const SUPPORT * mySupport) +{ + affiche_field_((FIELD_ *) myField, mySupport); + + cout << "- Valeurs :"<<endl; + int NumberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); + int NumberOfComponents = myField->getNumberOfComponents() ; + + if ( myField->getInterlacingType() == MED_EN::MED_FULL_INTERLACE ) { + for (int i=1; i<NumberOf+1; i++) { + const double * value = myField->getRow(i) ; + for (int j=0; j<NumberOfComponents; j++) + cout << value[j]<< " "; + cout<<endl; + } + } + else { + for (int j=1; j<NumberOfComponents+1; j++) { + const double * value = myField->getColumn(j) ; + for (int i=0; i<NumberOf; i++) + cout << value[i]<< " "; + cout<<endl; + } + } +} + +int main (int argc, char ** argv) { + // int read; !! UNUSED VARIABLE !! + + if ((argc !=3) && (argc != 4)) { + cerr << "Usage : " << argv[0] + << " filename meshname fieldname" << endl << endl; + exit(-1); + } + + string filename = argv[1] ; + string meshname = argv[2] ; + + MESH * myMesh= new MESH() ; + myMesh->setName(meshname); + MED_MESH_RDONLY_DRIVER myMeshDriver(filename,myMesh) ; + myMeshDriver.setMeshName(meshname); + int current = myMesh->addDriver(myMeshDriver); + myMesh->read(current); + + // read field : + if (argc != 4) exit(0) ; + // else we have a field ! + string fieldname = argv[3]; + + FIELD<double> * myField ; + // SUPPORT * mySupport = new SUPPORT(myMesh,"On_all_node",MED_NODE); + SUPPORT * mySupport = new SUPPORT(myMesh,"On_all_cell",MED_CELL); + try { + myField = new FIELD<double>(mySupport,MED_DRIVER,filename,fieldname) ; + } catch (...) { + delete mySupport ; + mySupport = new SUPPORT(myMesh,"On_all_node",MED_NODE); + try { + myField = new FIELD<double>(mySupport,MED_DRIVER,filename,fieldname) ; + } catch (...) { + cout << "Field double " << fieldname << " not found !!!" << endl ; + exit (-1) ; + } + } + + affiche_fieldT(myField, mySupport); + FIELD<double> * myField2 = new FIELD<double>(* myField); // Contructeur par recopie, sauf SUPPORT + delete myField; // Ne détruit pas le Support + affiche_fieldT(myField2, myField2->getSupport()); + FIELD<double,NoInterlace> * myField3 = FieldConvert( *myField2 ); + delete myField2; + + affiche_fieldT(myField3, myField3->getSupport()); + FIELD<double,FullInterlace> * myField4 = FieldConvert( *myField3 ); + delete myField3; + affiche_fieldT(myField4, myField4->getSupport()); + delete myField4; + + FIELD<double,NoInterlace> * myField5 = new FIELD<double,NoInterlace>(mySupport,MED_DRIVER,filename,fieldname) ; + affiche_fieldT(myField5, myField5->getSupport()); + delete myField5; + + delete mySupport ; + delete myMesh ; + + return 0; +} diff --git a/src/MEDMEMBinTest/test_copie_field_.cxx b/src/MEDMEMBinTest/test_copie_field_.cxx new file mode 100644 index 000000000..19ddfe314 --- /dev/null +++ b/src/MEDMEMBinTest/test_copie_field_.cxx @@ -0,0 +1,153 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +/* Programme de test du constructeur de copies de la classe FIELD_ de MEDMEM + jroy - 12/12/2002 */ + +#include<string> + +#include <math.h> +#include <stdlib.h> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Group.hxx" + +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_MedFieldDriver.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_define.hxx" + +using namespace MEDMEM; +using namespace MED_EN; + + +void affiche_field(FIELD_ * myField, const SUPPORT * mySupport) +{ + cout << "Field "<< myField->getName() << " : " <<myField->getDescription() << endl ; + int NumberOfComponents = myField->getNumberOfComponents() ; + cout << "- Nombre de composantes : "<< NumberOfComponents << endl ; + for (int i=1; i<NumberOfComponents+1; i++) { + cout << " - composante "<<i<<" :"<<endl ; + cout << " - nom : "<<myField->getComponentName(i)<< endl; + cout << " - description : "<<myField->getComponentDescription(i) << endl; + cout << " - units : "<<myField->getMEDComponentUnit(i) << endl; + } + cout << "- iteration :" << endl ; + cout << " - numero : " << myField->getIterationNumber()<< endl ; + cout << " - ordre : " << myField->getOrderNumber()<< endl ; + cout << " - temps : " << myField->getTime()<< endl ; + + cout << "- Type : " << myField->getValueType()<< endl; + /* + cout << "- Valeurs :"<<endl; + int NumberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); + + for (int i=1; i<NumberOf+1; i++) { + double * value = myField->getValueI(MED_FULL_INTERLACE,i) ; + for (int j=0; j<NumberOfComponents; j++) + cout << value[j]<< " "; + cout<<endl; + } + */ + cout << "- Adresse support : " << mySupport << endl; +} + + +int main (int argc, char ** argv) { + // int read; !! UNUSED VARIABLE !! + + if ((argc !=3) && (argc != 4)) { + cerr << "Usage : " << argv[0] + << " filename meshname fieldname" << endl << endl; + exit(-1); + } + + string filename = argv[1] ; + string meshname = argv[2] ; + + // MESH * myMesh= new MESH(MED_DRIVER,filename,meshname) ; + MESH * myMesh= new MESH() ; + myMesh->setName(meshname); + MED_MESH_RDONLY_DRIVER myMeshDriver(filename,myMesh) ; + myMeshDriver.setMeshName(meshname); + myMeshDriver.open() ; + myMeshDriver.read() ; + myMeshDriver.close() ; + + // int drv = myMesh->addDriver(MED_DRIVER,"sortie.med",meshname); + // myMesh->write(drv); + + + + + // if (argc < 4) return 0; + + // read field : + + if (argc != 4) exit(0) ; + // else we have a field ! + + string fieldname = argv[3]; + + + // SUPPORT * mySupport = new SUPPORT(myMesh,"On_all_node",MED_NODE); + SUPPORT * mySupport = new SUPPORT(myMesh,"On_all_cell",MED_EN::MED_CELL); + FIELD<double> * myField = new FIELD<double>() ; + + myField->setName(fieldname); + myField->setSupport(mySupport); + MED_FIELD_RDONLY_DRIVER<double> myFieldDriver(filename,myField) ; + myFieldDriver.setFieldName(fieldname); + myFieldDriver.open() ; + + try { + myFieldDriver.read() ; + } catch (...) { + myField->setSupport(0); + delete mySupport ; + mySupport = new SUPPORT(myMesh,"On_all_node",MED_EN::MED_NODE); + myField->setSupport(mySupport); + try { + myFieldDriver.read() ; + } catch (...) { + cout << "Field " << fieldname << " not found !!!" << endl ; + exit (-1) ; + } + } + + myFieldDriver.close() ; + + FIELD_ * pt_field_ = myField; + affiche_field(pt_field_, mySupport); + FIELD_ * pt_field_2 = new FIELD_(* pt_field_); + delete myField; + affiche_field(pt_field_2, pt_field_2->getSupport()); + + delete pt_field_2 ; + + delete mySupport ; + delete myMesh ; + + return 0; +} diff --git a/src/MEDMEMBinTest/test_copie_group.cxx b/src/MEDMEMBinTest/test_copie_group.cxx new file mode 100644 index 000000000..64051cf27 --- /dev/null +++ b/src/MEDMEMBinTest/test_copie_group.cxx @@ -0,0 +1,122 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include<string> + +#include <math.h> +#include <stdlib.h> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Group.hxx" + +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_MedFieldDriver.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_define.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +void affiche_support(const SUPPORT * mySupport) +{ + cout << " - Name : "<<mySupport->getName().c_str()<<endl ; + cout << " - Description : "<<mySupport->getDescription().c_str()<<endl ; + cout << " - Entity : "<<mySupport->getEntity()<<endl ; + cout << " - Entities list : "<<endl ; + if (!(mySupport->isOnAllElements())) { + int NumberOfTypes = mySupport->getNumberOfTypes() ; + cout<<" - NumberOfTypes : "<<NumberOfTypes<<endl; + const medGeometryElement * Types = mySupport->getTypes() ; + for (int j=0;j<NumberOfTypes;j++) { + cout<<" * Type "<<Types[j]<<" : "; + int NumberOfElements = mySupport->getNumberOfElements(Types[j]) ; + const int * Number = mySupport->getNumber(Types[j]) ; + for (int k=0; k<NumberOfElements;k++) + cout << Number[k] << " "; + cout << endl ; + } + } else + cout << " Is on all entities !"<< endl; +} + + +void affiche_famille(const FAMILY * myFamily) +{ + affiche_support(myFamily); + cout << " - Identifier : "<<myFamily->getIdentifier()<<endl ; + int NumberOfAttributes = myFamily->getNumberOfAttributes() ; + cout << " - Attributes ("<<NumberOfAttributes<<") :"<<endl; + for (int j=1;j<NumberOfAttributes+1;j++) + cout << " * "<<myFamily->getAttributeIdentifier(j)<<" : "<<myFamily->getAttributeValue(j)<<", "<<myFamily->getAttributeDescription(j).c_str()<<endl ; + int NumberOfGroups = myFamily->getNumberOfGroups() ; + cout << " - Groups ("<<NumberOfGroups<<") :"<<endl; + for (int j=1;j<NumberOfGroups+1;j++) + cout << " * "<<myFamily->getGroupName(j).c_str()<<endl ; +} + +void affiche_groupe(const GROUP * myGroup) +{ + affiche_support(myGroup); + int NumberOfFamillies = myGroup->getNumberOfFamilies() ; + cout << " - Families ("<<NumberOfFamillies<<") :"<<endl; + for (int j=1;j<NumberOfFamillies+1;j++) + cout << " * "<<myGroup->getFamily(j)->getName().c_str()<<endl ; +} + +int main (int argc, char ** argv) { + int read; + + if (argc <3) { // after 3, ignored ! + cerr << "Usage : " << argv[0] + << " filename meshname" << endl << endl; + exit(-1); + } + + string filename = argv[1] ; + string meshname = argv[2] ; + + MESH * myMesh= new MESH() ; + myMesh->setName(meshname); + MED_MESH_RDONLY_DRIVER myMeshDriver(filename,myMesh) ; + myMeshDriver.setMeshName(meshname); + myMeshDriver.open() ; + myMeshDriver.read() ; + myMeshDriver.close() ; + + const GROUP * myGroup = myMesh->getGroup(MED_NODE,1); + cout << "Show Group :"<<endl ; + affiche_groupe(myGroup); + GROUP * myGroup2 = new GROUP(* myGroup); + //delete myGroup; // no because in mesh !! + affiche_groupe(myGroup2); + GROUP * myGroup3 = new GROUP(* myGroup2); + delete myGroup2; + affiche_groupe(myGroup3); + delete myGroup3; + + delete myMesh ; + + return 0; +} diff --git a/src/MEDMEMBinTest/test_copie_medarray.cxx b/src/MEDMEMBinTest/test_copie_medarray.cxx new file mode 100644 index 000000000..ea709b9f3 --- /dev/null +++ b/src/MEDMEMBinTest/test_copie_medarray.cxx @@ -0,0 +1,131 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +/* Programme de test du constructeur de copies de la classe MEDARRAY de MEDMEM + jroy - 16/12/2002 */ + +#include <string> + +#include <math.h> +#include <stdlib.h> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Group.hxx" + +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_MedFieldDriver.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_define.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +void affiche_medarray(MEDARRAY<double> & myMedArray) +{ + int numberof ; + MESSAGE_MED("Show all 1 :"); + numberof = myMedArray.getLeadingValue() ; + for (int i=1; i<=myMedArray.getLengthValue() ; i++) { + const double * node = myMedArray.getRow(i) ; + cout << " - " ; + for (int j=0;j<numberof;j++) + cout << node[j] << " " ; + cout << endl ; + } + MESSAGE_MED("Show all 2 :"); + numberof = myMedArray.getLengthValue() ; + for (int i=1; i<=myMedArray.getLeadingValue() ; i++) { + const double * node = myMedArray.getColumn(i) ; + cout << " - " ; + for (int j=0;j<numberof;j++) + cout << node[j] << " " ; + cout << endl ; + } + MESSAGE_MED("Show all 3 :"); + numberof = myMedArray.getLeadingValue() ; + for (int i=1; i<=myMedArray.getLengthValue() ; i++) { + cout << " - " ; + for (int j=1;j<numberof+1;j++) + cout << myMedArray.getIJ(i,j) << " " ; + cout << endl ; + } + + MESSAGE_MED("Show all 0 :"); + numberof = myMedArray.getLeadingValue() ; + int length = myMedArray.getLengthValue() ; + const double * NoInterlaceArray = myMedArray.get(MED_NO_INTERLACE) ; + for (int i=0; i<length ; i++) { + cout << " - " ; + for (int j=0;j<numberof;j++) + cout << NoInterlaceArray[j*length+i] << " " ; + cout << endl ; + } + + + /* + cout << "Nombre de lignes : " << myMedArray.getLengthValue() << endl; + cout << "Nombre de colonnes : " << myMedArray.getLeadingValue() << endl; + cout << "Mode d'écriture en mémoire : " << myMedArray.getMode() << endl; + cout << "Valeurs (_valuesDefault) :" << endl; + + for (med_int i=1; i<=myMedArray.getLengthValue(); i++) { + for (med_int j=1; j<=myMedArray.getLeadingValue(); j++) + cout << i << " " << j << " " << myMedArray.getIJ(i,j) << " " << endl; + } + */ +} + + +int main (int argc, char ** argv) { + /* + if ((argc !=3) && (argc != 4)) { + cerr << "Usage : " << argv[0] + << " filename meshname fieldname" << endl << endl; + exit(-1); + } + */ + const med_int nb_noeuds = 8; + const med_int dimension = 3; + const medModeSwitch mode = MED_NO_INTERLACE; + + + MEDARRAY<double> * myMedArray = new MEDARRAY<double>(dimension,nb_noeuds,mode); + for (med_int i=1; i<=myMedArray->getLengthValue(); i++) { + for (med_int j=1; j<=myMedArray->getLeadingValue(); j++) + myMedArray->setIJ(i,j,(double) rand()); + }; + + affiche_medarray(* myMedArray); + MEDARRAY<double> * myMedArray2 = new MEDARRAY<double>(* myMedArray,false); + delete myMedArray; + affiche_medarray(* myMedArray2); + MEDARRAY<double> * myMedArray3 = new MEDARRAY<double>(10,20); + (* myMedArray3) = (* myMedArray2) ; + delete myMedArray2; + affiche_medarray(* myMedArray3); + delete myMedArray3; + + return 0; +} diff --git a/src/MEDMEMBinTest/test_copie_mesh.cxx b/src/MEDMEMBinTest/test_copie_mesh.cxx new file mode 100644 index 000000000..5650c818a --- /dev/null +++ b/src/MEDMEMBinTest/test_copie_mesh.cxx @@ -0,0 +1,68 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include<string> + +#include <math.h> +#include <stdlib.h> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Group.hxx" + +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_MedFieldDriver.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_define.hxx" + +using namespace std; +using namespace MEDMEM; + +int main (int argc, char ** argv) { + int read; + + if (argc <3) { // after 3, ignored ! + cerr << "Usage : " << argv[0] + << " filename meshname" << endl << endl; + exit(-1); + } + + string filename = argv[1] ; + string meshname = argv[2] ; + + MESH * myMesh= new MESH() ; + myMesh->setName(meshname); + MED_MESH_RDONLY_DRIVER myMeshDriver(filename,myMesh) ; + myMeshDriver.setMeshName(meshname); + myMeshDriver.open() ; + myMeshDriver.read() ; + myMeshDriver.close() ; + + cout << * myMesh << endl; + MESH * myMesh2 = new MESH(* myMesh); + delete myMesh; + cout << * myMesh2 << endl; + delete myMesh2; + + return 0; +} diff --git a/src/MEDMEMBinTest/test_copie_support.cxx b/src/MEDMEMBinTest/test_copie_support.cxx new file mode 100644 index 000000000..838153539 --- /dev/null +++ b/src/MEDMEMBinTest/test_copie_support.cxx @@ -0,0 +1,190 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include<string> + +#include <math.h> +#include <stdlib.h> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Group.hxx" + +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_MedFieldDriver.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_define.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +void affiche_support(const SUPPORT * mySupport) +{ + cout << " - Name : "<<mySupport->getName().c_str()<<endl ; + cout << " - Description : "<<mySupport->getDescription().c_str()<<endl ; + cout << " - Entity : "<<mySupport->getEntity()<<endl ; + cout << " - Entities list : "<<endl ; + if (!(mySupport->isOnAllElements())) { + int NumberOfTypes = mySupport->getNumberOfTypes() ; + cout<<" - NumberOfTypes : "<<NumberOfTypes<<endl; + const medGeometryElement * Types = mySupport->getTypes() ; + for (int j=0;j<NumberOfTypes;j++) { + cout<<" * Type "<<Types[j]<<" : "; + int NumberOfElements = mySupport->getNumberOfElements(Types[j]) ; + const int * Number = mySupport->getNumber(Types[j]) ; + for (int k=0; k<NumberOfElements;k++) + cout << Number[k] << " "; + cout << endl ; + } + } else + cout << " Is on all entities !"<< endl; +} + + +void affiche_famille(MESH *myMesh,medEntityMesh Entity) +{ + int NumberOfFamilies = myMesh->getNumberOfFamilies(Entity) ; + cout << "NumberOfFamilies : "<<NumberOfFamilies<<endl; + for (int i=1; i<NumberOfFamilies+1;i++) { + const FAMILY* myFamily = myMesh->getFamily(Entity,i); + affiche_support(myFamily); + cout << " - Identifier : "<<myFamily->getIdentifier()<<endl ; + int NumberOfAttributes = myFamily->getNumberOfAttributes() ; + cout << " - Attributes ("<<NumberOfAttributes<<") :"<<endl; + for (int j=1;j<NumberOfAttributes+1;j++) + cout << " * "<<myFamily->getAttributeIdentifier(j)<<" : "<<myFamily->getAttributeValue(j)<<", "<<myFamily->getAttributeDescription(j).c_str()<<endl ; + int NumberOfGroups = myFamily->getNumberOfGroups() ; + cout << " - Groups ("<<NumberOfGroups<<") :"<<endl; + for (int j=1;j<NumberOfGroups+1;j++) + cout << " * "<<myFamily->getGroupName(j).c_str()<<endl ; + } +} + +void affiche_groupe(MESH *myMesh,medEntityMesh Entity) +{ + int NumberOfGroups = myMesh->getNumberOfGroups(Entity) ; + cout << "NumberOfGroups : "<<NumberOfGroups<<endl; + for (int i=1; i<NumberOfGroups+1;i++) { + const GROUP* myGroup = myMesh->getGroup(Entity,i); + affiche_support(myGroup); + int NumberOfFamillies = myGroup->getNumberOfFamilies() ; + cout << " - Families ("<<NumberOfFamillies<<") :"<<endl; + for (int j=1;j<NumberOfFamillies+1;j++) + cout << " * "<<myGroup->getFamily(j)->getName().c_str()<<endl ; + } +} + +int main (int argc, char ** argv) { + int read; + + if (argc <3) { // after 3, ignored ! + cerr << "Usage : " << argv[0] + << " filename meshname" << endl << endl; + exit(-1); + } + + string filename = argv[1] ; + string meshname = argv[2] ; + + MESH * myMesh= new MESH() ; + myMesh->setName(meshname); + MED_MESH_RDONLY_DRIVER myMeshDriver(filename,myMesh) ; + myMeshDriver.setMeshName(meshname); + myMeshDriver.open() ; + myMeshDriver.read() ; + myMeshDriver.close() ; + + //Construction d'un support total + SUPPORT * mySupport = new SUPPORT(myMesh,"Support on CELLs",MED_CELL); + + cout << "Show Support on all :"<<endl ; + affiche_support(mySupport); + SUPPORT * mySupport2 = new SUPPORT(* mySupport); + delete mySupport; + affiche_support(mySupport2); + delete mySupport2; + + //Construction d'un support partiel + mySupport = new SUPPORT(myMesh,"Support on CELLs",MED_CELL); + mySupport->setAll(false); + + // int NumberOfGeometricType = 1; + int NumberOfGeometricType = 0; + // int TotalNumberOfEntity = 2; + // medGeometryElement * GeometricTypePartial = new medGeometryElement[NumberOfGeometricType]; + // GeometricTypePartial[0] = MED_HEXA8; + int TotalNumberOfElements = 0; + int * NumberOfElements = new int[myMesh->getNumberOfTypes(MED_CELL)]; + // NumberOfEntity[0] = 2; + // int * NumberValue = new int[TotalNumberOfEntity]; + int * NumberValue = new int[myMesh->getGlobalNumberingIndex(MED_CELL)[myMesh->getNumberOfTypes(MED_CELL)]-1]; + // NumberValue[0] = 14; + // NumberValue[1] = 15; + int cmp = 0; + medGeometryElement * GeometricTypePartial = new medGeometryElement[myMesh->getNumberOfTypes(MED_CELL)]; + const medGeometryElement * GeometricType = myMesh->getTypes(MED_CELL); + for (int i=0;i<myMesh->getNumberOfTypes(MED_CELL);i=i+2) + { + NumberOfGeometricType=NumberOfGeometricType+1; + TotalNumberOfElements=TotalNumberOfElements+myMesh->getNumberOfElements(MED_CELL,GeometricType[i]); + NumberOfElements[i/2]=myMesh->getNumberOfElements(MED_CELL,GeometricType[i]); + for (int j=0;j<myMesh->getNumberOfElements(MED_CELL,GeometricType[i]);j++) + { + NumberValue[cmp]=myMesh->getGlobalNumberingIndex(MED_CELL)[i]+j; + cmp=cmp+1; + } + GeometricTypePartial[i/2]=GeometricType[i]; + } + + mySupport->setpartial("Support partiel",NumberOfGeometricType,TotalNumberOfElements,GeometricTypePartial,NumberOfElements,NumberValue); + + delete[] NumberOfElements ; + delete[] NumberValue ; + delete[] GeometricTypePartial ; + + cout << "Show Partial Support :"<<endl ; + affiche_support(mySupport); + mySupport2 = new SUPPORT(* mySupport); + delete mySupport; + affiche_support(mySupport2); + delete mySupport2; + + /* + cout << "Show Family :"<<endl ; + affiche_famille(myMesh,MED_NODE); + affiche_famille(myMesh,MED_CELL); + affiche_famille(myMesh,MED_FACE); + affiche_famille(myMesh,MED_EDGE); + + cout << "Show Group :"<<endl ; + affiche_groupe(myMesh,MED_NODE); + affiche_groupe(myMesh,MED_CELL); + affiche_groupe(myMesh,MED_FACE); + affiche_groupe(myMesh,MED_EDGE); + */ + + delete myMesh ; + + return 0; +} diff --git a/src/MEDMEMBinTest/test_gibi_driver.cxx b/src/MEDMEMBinTest/test_gibi_driver.cxx new file mode 100644 index 000000000..ff88bed42 --- /dev/null +++ b/src/MEDMEMBinTest/test_gibi_driver.cxx @@ -0,0 +1,106 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_GibiMeshDriver.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_DriverFactory.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; +using namespace DRIVERFACTORY; + +int main (int argc, char ** argv) +{ + /* process the arguments */ + if (argc != 2) + { + cerr << "Usage : " << argv[0] + << "Gibifilename" << endl << endl + << "-> lit le fichier gibi filename ,crée 3 fichiers : MED 2.1, 2.2 et VTK" << endl; + exit(-1); + } + + string gibifilename = argv[1]; + + // Construction des noms de fichier + const string ext=".sauve"; + string::size_type pos=gibifilename.find(ext,0); + string basename (gibifilename, 0, pos); // nom sans extension + string medfile21=basename+"_V21.med"; // nom fichier med 2.1 à creer + string medfile22=basename+"_V22.med"; // nom fichier med 2.2 à creer + string vtkfile=basename+".vtk"; // nom fichier vtk à creer + string::size_type pos1=gibifilename.rfind('/'); + string meshName (gibifilename,pos1+1,pos-pos1-1); // get rid of directory & extension + cout << meshName << endl; + + // lecture du fichier gibi + // MESH * myMesh= new MESH(GIBI_DRIVER,gibifilename); + MESH * myMesh= new MESH() ; + GIBI_MESH_RDONLY_DRIVER myGibiMeshDriver(gibifilename, myMesh) ; + myGibiMeshDriver.open() ; + myGibiMeshDriver.read() ; + myGibiMeshDriver.close() ; + + cout << "Impression de MESH : " << endl; + cout << *myMesh; + + // creation des fichiers med 2.1 et 2.2 + medFileVersion version = getMedFileVersionForWriting(); + if (version == V22) + setMedFileVersionForWriting(V21); + + cout << "creation du fichier med 21 : " << endl; + int idMed21 = myMesh->addDriver(MED_DRIVER, medfile21, meshName); + myMesh->write(idMed21) ; + + version = getMedFileVersionForWriting(); + if (version == V21) + setMedFileVersionForWriting(V22); + + cout << "creation du fichier med 22 : " << endl; + int idMed22 = myMesh->addDriver(MED_DRIVER, medfile22, meshName); + myMesh->write(idMed22) ; + + // creation d'un fichier vtk + cout << "creation d'un fichier vtk : " << endl; + int idVtk = myMesh->addDriver(VTK_DRIVER, vtkfile, meshName); + myMesh->write(idVtk) ; + delete myMesh; + + // remontée mémoire du fichier med 21 + myMesh= new MESH(MED_DRIVER,medfile21,meshName); + //myMesh= new MESH() ; + //myMesh->setName(meshName); + //MED_MESH_RDONLY_DRIVER myMeshDriver(medfile,myMesh) ; + //myMeshDriver.setMeshName(meshName); + //myMeshDriver.open() ; + //myMeshDriver.read() ; + //myMeshDriver.close() ; + //cout << "Impression 2 de MESH : " << endl; + //cout << *myMesh; + delete myMesh; + + // remontée mémoire du fichier med 22 + myMesh= new MESH(MED_DRIVER,medfile22,meshName); + + delete myMesh; +} diff --git a/src/MEDMEMBinTest/test_grid.cxx b/src/MEDMEMBinTest/test_grid.cxx new file mode 100644 index 000000000..bd90ae6dd --- /dev/null +++ b/src/MEDMEMBinTest/test_grid.cxx @@ -0,0 +1,71 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_Grid.hxx" +#include <memory> + +using namespace MEDMEM; +using namespace MED_EN; + +static void usage(const char * test) +{ + cerr << "Usage : " << test + << " SpaceDimension nbMaille" << endl << endl + << "-> Crée une grille cartesienne en dimension SpaceDimension avec nbMaille suivant chaque direction" << endl; + exit(-1); +} + +int main (int argc, char ** argv) { + + /* process the arguments */ + if (argc != 3) + usage(argv[0]); + + const int SpaceDimension=atoi(argv[1]); + const int nbMaille=atoi(argv[2]); + if(SpaceDimension>3 || SpaceDimension<1 || nbMaille<1) + usage(argv[0]); + + // Creation des tableaux necessaires à la construction de GRID + std::vector<int> nMaille(SpaceDimension,nbMaille); + std::vector<double> Origine(SpaceDimension,0.0); + std::vector<double> pas(SpaceDimension,10.0); + std::vector<std::vector<double> > XYZ_Array(SpaceDimension); + for(int i=0;i!=SpaceDimension;++i) + { + XYZ_Array[i].resize(nMaille[i]+1); // nbre de noeuds = nbre de mailles +1 + XYZ_Array[i][0]=Origine[i]; + for(int j=1;j!=XYZ_Array[i].size();++j) + XYZ_Array[i][j]=XYZ_Array[i][j-1] + pas[j-1]; + } + + std::vector<std::string> coord_name(SpaceDimension,"X"); + if(SpaceDimension>=2) + coord_name[1]="Y"; + if(SpaceDimension>=3) + coord_name[2]="Z"; + std::vector<std::string> coord_unit(SpaceDimension,"cm"); + + // creation du pointeur MESH à partir d'un GRID, test affichage + std::auto_ptr<MEDMEM::MESH> Mesh (new MEDMEM::GRID( XYZ_Array, coord_name, coord_unit, MED_CARTESIAN) ); + const MEDMEM::CONNECTIVITY* conn = Mesh->getConnectivityptr(); + std::cout << "Affichage du maillage : " << endl << *Mesh << endl; +} diff --git a/src/MEDMEMBinTest/test_operation_fielddouble.cxx b/src/MEDMEMBinTest/test_operation_fielddouble.cxx new file mode 100644 index 000000000..267fae13e --- /dev/null +++ b/src/MEDMEMBinTest/test_operation_fielddouble.cxx @@ -0,0 +1,420 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// Programme de test des operations sur les champs +// +#include <string> +#include <iostream> +#include <iomanip> +#include <cmath> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Group.hxx" + +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_MedFieldDriver.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_define.hxx" + +double myfunction1(double x) +{ + return 0.25*(x-1.0); +} + + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +void affiche_field_(FIELD_ * myField, const SUPPORT * mySupport) +{ + cout << "Field "<< myField->getName() << " : " <<myField->getDescription() << endl ; + int NumberOfComponents = myField->getNumberOfComponents() ; + cout << "- Nombre de composantes : "<< NumberOfComponents << endl ; + cout << "- Nombre de valeurs : "<< myField->getNumberOfValues() << endl ; + for (int i=1; i<NumberOfComponents+1; i++) { + cout << " - composante "<<i<<" :"<<endl ; + cout << " - nom : "<<myField->getComponentName(i)<< endl; + cout << " - description : "<<myField->getComponentDescription(i) << endl; + cout << " - units : "<<myField->getMEDComponentUnit(i) << endl; + } + cout << "- iteration :" << endl ; + cout << " - numero : " << myField->getIterationNumber()<< endl ; + cout << " - ordre : " << myField->getOrderNumber()<< endl ; + cout << " - temps : " << myField->getTime()<< endl ; + + cout << "- Type : " << myField->getValueType()<< endl; + + cout << "- Adresse support : " << mySupport << endl; +} + +void affiche_fieldT(FIELD<double> * myField, const SUPPORT * mySupport) +{ + affiche_field_((FIELD_ *) myField, mySupport); + + cout << "- Valeurs :"<<endl; + int NumberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); + int NumberOfComponents = myField->getNumberOfComponents() ; + + for (int i=1; i<NumberOf+1; i++) { + const double * value = myField->getRow(i) ; + for (int j=0; j<NumberOfComponents; j++) + cout << value[j]<< " "; + cout<<endl; + } + cout << endl; + cout << "Norme euclidienne : " << myField->norm2() << endl; + cout << "Norme max : " << myField->normMax() << endl; + try + { + for (int i=1; i<=myField->getNumberOfComponents(); ++i) + cout << "Norme L2 - comp=" << i << " : " << myField->normL2(i) << endl; + cout << "Norme L2 : " << myField->normL2() << endl; + + for (int i=1; i<=myField->getNumberOfComponents(); ++i) + cout << "Norme L1 - comp=" << i << " : " << myField->normL1(i) << endl; + cout << "Norme L1 : " << myField->normL1() << endl; + } + catch (MEDEXCEPTION &ex) + { + cout << ex.what() << endl; + } +} + +void affiche_valeur_field(const FIELD<double>& f) +{ + const int tailleMax=12; + const int taille=f.getNumberOfValues()*f.getNumberOfComponents(); + const double * value=f.getValue(); + if(taille<=tailleMax) + for(int i=0;i<taille;i++) + cout << setw(3) << value[i] << " "; + else + { + for(int i=0; i<tailleMax/2; ++i) + cout << setw(3) << value[i] << " "; + cout << " ... "; + for(int i=taille-tailleMax/2 ; i<taille; ++i) + cout << setw(3) << value[i] << " "; + } +} + +void checkOperation(const FIELD<double>& resOp, const FIELD<double>& f1, const FIELD<double>& f2, + char Op, const char* intitule, int verbose) +{ + int res=0; + + // get pointers to inside arrays of values + const double * value=resOp.getValue(); + const double * value1=f1.getValue(); + const double * value2=f2.getValue(); + const int size=f1.getNumberOfValues()*f1.getNumberOfComponents(); // size of field1 + + // check size compatibility + if(f1.getNumberOfValues()*f1.getNumberOfComponents()!=size || + resOp.getNumberOfValues()*resOp.getNumberOfComponents()!=size) + res=1; + + if(!res) + { + switch(Op) + { + case '+': + for(int i=0; i!=size; ++i) + if(value[i]!=value1[i]+value2[i]) + res+=1; + break; + case '-': + for(int i=0; i!=size; ++i) + if(value[i]!=value1[i]-value2[i]) + res+=1; + break; + case 'n': + for(int i=0; i!=size; ++i) + if(value[i]!=-value1[i]) + res+=1; + break; + case '*': + for(int i=0; i!=size; ++i) + if(value[i]!=value1[i]*value2[i]) + res+=1; + break; + case '/': + for(int i=0; i!=size; ++i) + if(value2[i]!=0.0) + if(value[i]!=value1[i]/value2[i]) + res+=1; + break; + case '=': + for(int i=0; i!=size; ++i) + if(value[i]!=value2[i]) + res+=1; + break; + case 'a': + for(int i=0; i!=size; ++i) + if(value[i]!=value1[i]+value2[i]*value2[i]) + res+=1; + break; + } + + } + + if (verbose) + cout << endl << intitule << "["; + cout << res; + if (verbose) + { + cout << "] : "; + affiche_valeur_field(resOp); + } + else + cout << endl; +} + +int main (int argc, char ** argv) +{ + /* process the arguments */ + int verbose=0; // verbose=1 if the verbose mode is selected + int res=0; // unit test result + int ntest=0; // numéro du test + + if (argc>=2 && !strcmp(argv[1],"-v")) + verbose=1; + + if (argc != 4+verbose) + { + cerr << "Usage : " << argv[0] + << "[-v] filename meshname fieldname" << endl << endl + << "-> tests field's operations on the FIELD<double> fieldname" << endl + << "Use optional option -v to select verbose mode" << endl; + exit(-1); + } + string filename = argv[verbose+1]; + string meshname = argv[verbose+2];// Maintenant plus très utile + string fieldname = argv[verbose+3]; + + /* read MESH, SUPPORT and FIELDS */ + //MESH * myMesh = new MESH(MED_DRIVER,filename,meshname); + + MESH * myMesh; + const SUPPORT * mySupport; + FIELD<double> * myField1; + + try { + + myField1 = new FIELD<double>(MED_DRIVER,filename,fieldname) ; + mySupport = myField1->getSupport(); + myMesh = new MESH(MED_DRIVER,filename,mySupport->getMeshName()); + mySupport->setMesh(myMesh); + + FIELD<double> * myField2 = new FIELD<double>(* myField1); + FIELD<double> myFieldPlus = *myField1 + *myField2; + if(verbose) { + // affichage des nprmes,des champs f1, f2, scalarProduct(f1,f2) et f1+f2 + FIELD<double>* myField1_vol=myField1->getSupport()->getMesh()->getVolume(myField1->getSupport()); + cout << "Norme L2 calculee en fournissant le volume : " << myField1->normL2(myField1_vol) << endl; + for (int i=1; i<=myField1->getNumberOfComponents(); ++i) + cout << "Norme L2 - comp=" << i << " : " << myField1->normL2(i,myField1_vol) << endl; + cout << "Norme L1 calculee en fournissant le volume : " << myField1->normL1(myField1_vol) << endl; + for (int i=1; i<=myField1->getNumberOfComponents(); ++i) + cout << "Norme L1 - comp=" << i << " : " << myField1->normL1(i,myField1_vol) << endl; + delete myField1_vol; + + affiche_fieldT(myField1, myField1->getSupport()); + cout << endl << string(60,'-') << endl; + affiche_fieldT(myField2, myField2->getSupport()); + cout << endl << string(60,'-') << endl; + + FIELD<double>* myFieldDot = FIELD<double>::scalarProduct(*myField1, *myField2); + affiche_fieldT(myFieldDot, myFieldDot->getSupport()); + delete myFieldDot; + cout << endl << string(60,'-') << endl ; + affiche_fieldT(&myFieldPlus, myFieldPlus.getSupport()); + cout << endl << string(60,'-') << endl << endl ; + } + + + // Verifie plusieurs cas de non compatibilité + + // test 1 : Unites non compatibles + const string unite=myField1->getMEDComponentUnit(1); + myField1->setMEDComponentUnit(1,string("UniteBidon")); + ntest++; res=1; + try + { + FIELD<double> myFieldPlus = *myField1 + *myField2; + if(verbose) + { + cout << endl << string(60,'-') << endl; + cout<< "Test " << ntest << " : incompatibilité d'unité : " << endl << endl; + } + } + catch (MEDEXCEPTION & ex) + { + res=0; + if(verbose) + cout << ex.what() << endl; + myField1->setMEDComponentUnit(1,unite); + } + cout << res << endl; + + // test 2 : numberOfComponents non compatibles + const int numberOfComponents =myField1->getNumberOfComponents(); + myField1->setNumberOfComponents(13); + ntest++; res=1; + try + { + if(verbose) + { + cout << endl << string(60,'-') << endl; + cout<< "Test " << ntest << " : incompatibilité nombre de composantes : " << endl << endl; + } + FIELD<double> myFieldPlus = *myField1 + *myField2; + } + catch (MEDEXCEPTION & ex) + { + res=0; + if(verbose) + cout << endl << ex.what() << endl << endl; + myField1->setNumberOfComponents(numberOfComponents); + } + cout << res << endl; + + // test 3 : supports non compatibles + const SUPPORT mySupport2(myMesh,"On_all_node",MED_NODE); + myField1->setSupport(&mySupport2); + ntest++; res=1; + try + { + if(verbose) + cout << endl << string(60,'-') << endl << "Test " << ntest << " : incompatibilité des supports" << endl << endl; + FIELD<double> myFieldPlus = *myField1 + *myField2; + } + catch (MEDEXCEPTION & ex) + { + res=0; + if(verbose) + cout << ex.what() << endl << endl << endl; + myField1->setSupport(mySupport); + } + cout << res << endl; + + // test 4 : champs de taille nulle + myField1->setNumberOfComponents(0); + myField2->setNumberOfComponents(0); + ntest++; res=2; + try + { + if(verbose) + cout<< endl << string(60,'-') << endl << "Test " << ntest << " : incompatibilité taille nulle" << endl << endl; + FIELD<double> myFieldPlus = *myField1 + *myField2; + } + catch (MEDEXCEPTION & ex) + { + --res; + if(verbose) + cout << ex.what() << endl << endl ; + } + try + { + double mynorm2=myField1->norm2(); + } + catch (MEDEXCEPTION & ex) + { + --res; + if(verbose) + cout << ex.what() << endl << endl ; + myField1->setNumberOfComponents(numberOfComponents); + myField2->setNumberOfComponents(numberOfComponents); + } + cout << res << endl; + + // Apres toutes ces exceptions, des opérations qui marchent! + + if(verbose) + { + cout<< endl << string(60,'-') << endl << "Test " << ++ntest << " : Operations arithmétiques" << endl; + cout << endl << " f1 : "; affiche_valeur_field(*myField1); + cout << endl << " f2 : "; affiche_valeur_field(*myField2); + cout << endl << string(140,'-'); + } + + // Test du résultats de certaines opérations et affichage si verbose + checkOperation(myFieldPlus, *myField1, *myField2, '+', " f1+f2 ", verbose); + FIELD<double>* myFieldadd = FIELD<double>::add(*myField1, *myField2); + checkOperation( *myFieldadd, *myField1, *myField2, '+', "add(f1,f2)", verbose); + delete myFieldadd; + + FIELD<double> myFieldMoins = *myField1 - *myField2; + checkOperation(myFieldMoins, *myField1, *myField2, '-', " f1-f2 ", verbose); + FIELD<double>* myFieldsub = FIELD<double>::sub(*myField1, *myField2); + checkOperation( *myFieldsub, *myField1, *myField2, '-', "sub(f1,f2)", verbose); + delete myFieldsub; + FIELD<double> myFieldNeg = -(*myField1); + checkOperation(myFieldNeg, *myField1, *myField1, 'n', " -f1 ", verbose); + + FIELD<double> myFieldFois = *myField1 * *myField2; + checkOperation(myFieldFois, *myField1, *myField2, '*', " f1*f2 ", verbose); + FIELD<double>* myFieldmul = FIELD<double>::mul(*myField1, *myField2); + checkOperation( *myFieldmul, *myField1, *myField2, '*', "mul(f1,f2)", verbose); + + FIELD<double> myFieldDiv = *myField1 / *myField2; + checkOperation(myFieldDiv, *myField1, *myField2, '/', " f1/f2 ", verbose); + FIELD<double>* myFielddiv = FIELD<double>::div(*myField1, *myField2); + checkOperation( *myFielddiv, *myField1, *myField2, '/', "div(f1,f2)", verbose); + delete myFielddiv; + + FIELD<double> myFieldAsso = (*myField1)+(*myField2)*(*myField2); + checkOperation(myFieldAsso, *myField1, *myField2, 'a', " f1+f2*f2 ", verbose); + + myField1->applyLin(4.0,1.0); + checkOperation(*myField1, *myField2, *myField2, 'l', " 4.f1 + 1 ", verbose); + myField1->applyFunc<myfunction1>(); + checkOperation( *myField1, *myField2, *myField1, '=', "CB : ->f1)", verbose); + + *myField1 += *myField2; + checkOperation(*myField1, *myField2, *myField2, '+', " f1+=f2 ", verbose); + + *myField1 -= *myField2; + checkOperation(*myField1, *myField2, *myField2, '=', " f1-=f2 ", verbose); + + *myField1 *= *myField2; + checkOperation(*myField1, *myField2, *myField2, '*', " f1*=f2 ", verbose); + *myField1 /= *myField2; + checkOperation(*myField1, *myFieldmul, *myField2, '/', " f1/=f2 ", verbose); + delete myFieldmul; + + + delete myField1; + delete myField2; + delete mySupport ; + delete myMesh ; + + } + catch ( MEDEXCEPTION & ex) { + cout << ex.what() << endl; + } + + return 0; +} diff --git a/src/MEDMEMBinTest/test_operation_fieldint.cxx b/src/MEDMEMBinTest/test_operation_fieldint.cxx new file mode 100644 index 000000000..5567c6083 --- /dev/null +++ b/src/MEDMEMBinTest/test_operation_fieldint.cxx @@ -0,0 +1,322 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// Programme de test des operations sur les champs +// +#include <string> +#include <iostream> +#include <iomanip> +#include <cmath> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Group.hxx" + +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_MedFieldDriver.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_define.hxx" + +using namespace MEDMEM; +using namespace MED_EN; + +int myfunction1(int x) +{ + return 2*x; +} + +int myfunction2(int x) +{ + return x/2; +} + +using namespace std; +void affiche_field_(FIELD_ * myField, const SUPPORT * mySupport) +{ + cout << "Field "<< myField->getName() << " : " <<myField->getDescription() << endl ; + int NumberOfComponents = myField->getNumberOfComponents() ; + cout << "- Nombre de composantes : "<< NumberOfComponents << endl ; + cout << "- Nombre de valeurs : "<< myField->getNumberOfValues() << endl ; + for (int i=1; i<NumberOfComponents+1; i++) { + cout << " - composante "<<i<<" :"<<endl ; + cout << " - nom : "<<myField->getComponentName(i)<< endl; + cout << " - description : "<<myField->getComponentDescription(i) << endl; + cout << " - units : "<<myField->getMEDComponentUnit(i) << endl; + } + cout << "- iteration :" << endl ; + cout << " - numero : " << myField->getIterationNumber()<< endl ; + cout << " - ordre : " << myField->getOrderNumber()<< endl ; + cout << " - temps : " << myField->getTime()<< endl ; + + cout << "- Type : " << myField->getValueType()<< endl; + + cout << "- Adresse support : " << mySupport << endl; +} + +void affiche_fieldT(FIELD<int> * myField, const SUPPORT * mySupport) +{ + affiche_field_((FIELD_ *) myField, mySupport); + + cout << "- Valeurs :"<<endl; + int NumberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); + int NumberOfComponents = myField->getNumberOfComponents() ; + + for (int i=1; i<NumberOf+1; i++) { + const int * value = myField->getRow(i) ; + for (int j=0; j<NumberOfComponents; j++) + cout << value[j]<< " "; + cout<<endl; + } + std::cout << std::endl; + std::cout << "Norme euclidienne : " << myField->norm2() << endl; + std::cout << "Norme max : " << myField->normMax() << endl; + try + { + for (int i=1; i<=myField->getNumberOfComponents(); ++i) + std::cout << "Norme L2 - comp=" << i << " : " << myField->normL2(i) << endl; + std::cout << "Norme L2 : " << myField->normL2() << endl; + + for (int i=1; i<=myField->getNumberOfComponents(); ++i) + std::cout << "Norme L1 - comp=" << i << " : " << myField->normL1(i) << endl; + std::cout << "Norme L1 : " << myField->normL1() << endl; + } + catch (MEDEXCEPTION &ex) + { + std::cout << ex.what() << std::endl; + } +} + +void affiche_valeur_field(const char * intitule, const int taille, const FIELD<int>& f) +{ + const int * value=f.getValue(); + std::cout << endl << intitule; + for(int i=0;i<taille;i++) + std::cout << setw(3) << value[i] << " "; +} + +int main (int argc, char ** argv) +{ + if (argc != 4) + { + cerr << "Usage : " << argv[0] + << " filename meshname fieldname" << endl << endl; + exit(-1); + } + string filename = argv[1] ; + string meshname = argv[2] ; + string fieldname = argv[3]; + + MESH * myMesh = new MESH(MED_DRIVER,filename,meshname); + SUPPORT * mySupport; + FIELD<int> * myField1; + try + { + /* read MESH, SUPPORT and FIELD */ + mySupport = new SUPPORT(myMesh,"Support on all Cells",MED_CELL); + myField1 = new FIELD<int>(mySupport,MED_DRIVER,filename,fieldname) ; + } + catch (MEDEXCEPTION &ex) + { + delete mySupport ; + mySupport = new SUPPORT(myMesh,"On_all_node",MED_NODE); + try + { + myField1 = new FIELD<int>(mySupport,MED_DRIVER,filename,fieldname) ; + myField1->setValueIJ(10,1,-9); // pour tester les normes max avec une valeur negative + } + catch (...) + { + cout << "Field int " << fieldname << " not found !!!" << endl ; + exit (-1) ; + } + } + + FIELD<int> * myField2 = new FIELD<int>(* myField1); + //myField1->setNumberOfValues(16); // PROVISOIRE !! BUG + //myField2->setNumberOfValues(16); // PROVISOIRE !! BUG +// FIELD<int>* myField1_vol=myField1->getSupport()->getMesh()->getVolume(myField1->getSupport()); +// affiche_fieldT(myField1_vol, myField1->getSupport()); + + affiche_fieldT(myField1, myField1->getSupport()); + std::cout << endl << string(60,'-') << endl; + affiche_fieldT(myField2, myField2->getSupport()); + + // Verifie plusieurs cas de non compatibilité + + // Unites non compatibles + const string unite=myField1->getMEDComponentUnit(1); + myField1->setMEDComponentUnit(1,string("UniteBidon")); + try + { + std::cout << endl << string(60,'-') << endl; + std::cout<< "Test incompatibilité d'unité :" << endl; + FIELD<int> myFieldPlus = *myField1 + *myField2; + } + catch (MEDEXCEPTION & ex) + { + std::cout << "MEDEXCEPTION : " << ex.what() << endl; + myField1->setMEDComponentUnit(1,unite); + } + + // numberOfComponents non compatibles + const int numberOfComponents =myField1->getNumberOfComponents(); + myField1->setNumberOfComponents(4); + try + { + std::cout << endl << string(60,'-') << endl; + std::cout<< "Test incompatibilité nombre de composantes :" << endl; + FIELD<int> myFieldPlus = *myField1 + *myField2; + } + catch (MEDEXCEPTION & ex) + { + std::cout << ex.what() << endl; + myField1->setNumberOfComponents(numberOfComponents); + } + + // supports non compatibles + const SUPPORT mySupport2(myMesh,"On_all_node",MED_NODE); + myField1->setSupport(&mySupport2); + try + { + std::cout << endl << string(60,'-') << endl; + std::cout<< "Test incompatibilité des supports :" << endl; + FIELD<int> myFieldPlus = *myField1 + *myField2; + } + catch (MEDEXCEPTION & ex) + { + std::cout << ex.what() << endl; + myField1->setSupport( myField2->getSupport() ); + } + + // champs de taille nulle + myField1->setNumberOfComponents(0); + myField2->setNumberOfComponents(0); + try + { + std::cout << endl << string(60,'-') << endl; + std::cout<< "Test incompatibilité taille nulle :" << endl; + FIELD<int> myFieldPlus = *myField1 + *myField2; + } + catch (MEDEXCEPTION & ex) + { + std::cout << ex.what() << endl; + } + try + { + double mynorm2=myField1->norm2(); + } + catch (MEDEXCEPTION & ex) + { + std::cout << ex.what() << endl; + myField1->setNumberOfComponents(numberOfComponents); + myField2->setNumberOfComponents(numberOfComponents); + } + + // Apres toutes ces exceptions, des opérations qui marchent! + + FIELD<int> myFieldPlus = *myField1 + *myField2; + FIELD<int> myFieldMoins = *myField1 - *myField2; + FIELD<int> myFieldNeg = -(*myField1); + FIELD<int> myFieldFois = *myField1 * *myField2; + FIELD<int> myFieldDiv = *myField1 / *myField2; + FIELD<int> myFieldAsso = (*myField1)+(*myField2)*(*myField2); + FIELD<int>* myFieldadd = FIELD<int>::add(*myField1, *myField2); + FIELD<int>* myFieldsub = FIELD<int>::sub(*myField1, *myField2); + FIELD<int>* myFieldmul = FIELD<int>::mul(*myField1, *myField2); + FIELD<int>* myFielddiv = FIELD<int>::div(*myField1, *myField2); + FIELD<int>* myFieldDot = FIELD<int>::scalarProduct(*myField1, *myField2); + + std::cout << endl << string(60,'-') << endl << "f1+f2 :" << endl << endl; + affiche_fieldT(&myFieldPlus, myFieldPlus.getSupport()); + std::cout << endl << string(60,'-') << endl << "add(f1,f2) :" << endl << endl; + affiche_fieldT(myFieldadd, myFieldadd->getSupport()); + std::cout << endl << string(60,'-') << endl << "scalarProduct(f1,f2) :" << endl << endl; + affiche_fieldT(myFieldDot, myFieldDot->getSupport()); + std::cout << endl << string(60,'-') << endl << " - f1 :" << endl << endl; + affiche_fieldT(&myFieldNeg, myFieldNeg.getSupport()); + + int size=myFieldPlus.getNumberOfValues()*myFieldPlus.getNumberOfComponents(); + + std::cout << endl << string(60,'-') << endl << "Tests opérations :" << endl << endl; + affiche_valeur_field(" f1 :", size, *myField1); + affiche_valeur_field(" f2 :", size, *myField2); + std::cout << endl << " " << string(4*size,'-'); + + affiche_valeur_field(" + :", size, myFieldPlus); + affiche_valeur_field(" add :", size, *myFieldadd); + affiche_valeur_field(" - :", size, myFieldMoins); + affiche_valeur_field(" sub :", size, *myFieldsub); + affiche_valeur_field(" * :", size, myFieldFois); + affiche_valeur_field(" mul :", size, *myFieldmul); + affiche_valeur_field(" / :", size, myFieldDiv); + affiche_valeur_field(" div :", size, *myFielddiv); + affiche_valeur_field("f1+f2*f1:", size, myFieldAsso); + affiche_valeur_field(" - f1 :", size, myFieldNeg); + + // Test applyLin + std::cout << endl; + myField1->applyLin(1,1); + affiche_valeur_field(" f1+1 :", size, *myField1); + myField1->applyLin(1,-1); + affiche_valeur_field(" -> f1 :", size, *myField1); + + // Test applyFunc + std::cout << endl; + myField1->applyFunc<myfunction1>(); + affiche_valeur_field(" CB 2f1 :", size, *myField1); + myField1->applyFunc<myfunction2>(); + affiche_valeur_field(" -> f1 :", size, *myField1); + + // Test operateur += + std::cout << endl; + *myField1 += *myField2; + affiche_valeur_field(" f1+=f2 :", size, *myField1); + + // Test operateur *= + *myField1 *= *myField2; + affiche_valeur_field(" f1*=f2 :", size, *myField1); + + // Test operateur /= + *myField1 /= *myField2; + affiche_valeur_field(" f1/=f2 :", size, *myField1); + + // Test operateur -= + *myField1 -= *myField2; + affiche_valeur_field(" f1-=f2 :", size, *myField1); + + std::cout << endl << endl; + + + delete myFieldadd; + delete myFieldsub; + delete myFieldmul; + delete myFielddiv; + delete myFieldDot; +// delete myField1_vol; + + delete myField1; + delete myField2; + delete mySupport ; + delete myMesh ; + return 0; +} diff --git a/src/MEDMEMBinTest/test_porflow_driver.cxx b/src/MEDMEMBinTest/test_porflow_driver.cxx new file mode 100644 index 000000000..1641cd1c5 --- /dev/null +++ b/src/MEDMEMBinTest/test_porflow_driver.cxx @@ -0,0 +1,109 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_PorflowMeshDriver.hxx" +#include "MEDMEM_Mesh.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +int main (int argc, char ** argv) +{ + /* process the arguments */ + if (argc != 2) + { + cerr << "Usage : " << argv[0] + << " Porflowfilename" << endl << endl + << "-> lit le fichier Porflowfilename ,crée 2 fichiers : MED et VTK" << endl; + exit(-1); + } + + string porflowfilename = argv[1]; + + // Construction des noms de fichier + const string ext=".inp"; + string::size_type pos=porflowfilename.find(ext,0); + string basename (porflowfilename, 0, pos); // nom sans extension + string medfile=basename+".med"; // nom fichier med à creer + string vtkfile=basename+".vtk"; // nom fichier vtk à creer + string::size_type pos1=porflowfilename.rfind('/'); + string meshName (porflowfilename,pos1+1,pos-pos1-1); //get rid of directory & extension + cout << meshName << endl; + + // lecture du fichier porflow + MESH * myMesh= new MESH() ; + PORFLOW_MESH_RDONLY_DRIVER myPorflowMeshDriver(porflowfilename, myMesh) ; + myPorflowMeshDriver.open() ; + myPorflowMeshDriver.read() ; + myPorflowMeshDriver.close() ; + + cout << "Impression de MESH : " << endl; + cout << *myMesh; + + // creation d'un fichier med + cout << "creation d'un fichier med : " << endl; + int idMed = myMesh->addDriver(MED_DRIVER, medfile, meshName); + myMesh->write(idMed) ; + + // creation d'un fichier vtk + cout << "creation d'un fichier vtk : " << endl; + int idVtk = myMesh->addDriver(VTK_DRIVER, vtkfile, meshName); + myMesh->write(idVtk) ; + + + int SpaceDimension = myMesh->getSpaceDimension() ; + int MeshDimension = myMesh->getMeshDimension() ; + int NumberOfNodes = myMesh->getNumberOfNodes() ; + + cout << "Space Dimension : " << SpaceDimension << endl << endl ; + + cout << "Mesh Dimension : " << MeshDimension << endl << endl ; + + const double * Coordinates = myMesh->getCoordinates(MED_FULL_INTERLACE) ; + + cout << "Show Nodes Coordinates : " << endl ; + + cout << "Name :" << endl ; + const string * CoordinatesNames = myMesh->getCoordinatesNames() ; + for(int i=0; i<SpaceDimension ; i++) { + cout << " - " << CoordinatesNames[i] << endl ; + } + cout << "Unit :" << endl ; + const string * CoordinatesUnits = myMesh->getCoordinatesUnits() ; + for(int i=0; i<SpaceDimension ; i++) { + cout << " - " << CoordinatesUnits[i] << endl ; + } + for(int i=0; i<NumberOfNodes ; i++) { + cout << "Nodes " << i+1 << " : " ; + for (int j=0; j<SpaceDimension ; j++) + cout << Coordinates[i*SpaceDimension+j] << " " ; + cout << endl ; + } + + cout << "The END" << endl; + delete myMesh; + + // remontée du fichier med en mémoire + myMesh= new MESH(MED_DRIVER,medfile,meshName); + delete myMesh; + +} diff --git a/src/MEDMEMBinTest/test_profil_MedFieldDriver.cxx b/src/MEDMEMBinTest/test_profil_MedFieldDriver.cxx new file mode 100644 index 000000000..6dde279ff --- /dev/null +++ b/src/MEDMEMBinTest/test_profil_MedFieldDriver.cxx @@ -0,0 +1,254 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include <stdlib.h> +#include<string> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_MedFieldDriver.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_define.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +void affiche_field_(FIELD_ * myField, const SUPPORT * mySupport) +{ + cout << "Field "<< myField->getName() << " : " <<myField->getDescription() << endl ; + int NumberOfComponents = myField->getNumberOfComponents() ; + cout << "- Nombre de composantes : "<< NumberOfComponents << endl ; + for (int i=1; i<NumberOfComponents+1; i++) { + cout << " - composante "<<i<<" :"<<endl ; + cout << " - nom : "<<myField->getComponentName(i)<< endl; + cout << " - description : "<<myField->getComponentDescription(i) << endl; + cout << " - units : "<<myField->getMEDComponentUnit(i) << endl; + } + cout << "- iteration :" << endl ; + cout << " - numero : " << myField->getIterationNumber()<< endl ; + cout << " - ordre : " << myField->getOrderNumber()<< endl ; + cout << " - temps : " << myField->getTime()<< endl ; + + cout << "- Type : " << myField->getValueType()<< endl; + + cout << "- Adresse support : " << mySupport << endl; +} + +template <class INTERLACING_TAG> +void affiche_fieldT(FIELD<double, INTERLACING_TAG> * myField, + const SUPPORT * mySupport) +{ + const double * value = 0; + const int * number = 0; + + affiche_field_((FIELD_ *) myField, mySupport); + + cout.setf(ios::fixed); + cout << "- Valeurs :"<<endl; + bool onAll = mySupport->isOnAllElements(); + int NumberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); + cout << "mySupport->getNumberOfElements(MED_ALL_ELEMENTS)" << NumberOf << endl; + int NumberOfComponents = myField->getNumberOfComponents() ; + cout << "myField->getNumberOfComponents()" << NumberOfComponents << endl; + if (!onAll) number = mySupport->getNumber(MED_ALL_ELEMENTS); + + if ( myField->getInterlacingType() == MED_EN::MED_FULL_INTERLACE ) { + for (int i=1; i<NumberOf+1; i++) { + if (onAll) + value = myField->getRow(i) ; + else + value = myField->getRow(number[i-1]); + for (int j=0; j<NumberOfComponents; j++) + cout << value[j]<< " "; + cout<<endl; + } + } + else { + for (int j=1; j<NumberOfComponents+1; j++) { + value = myField->getColumn(j) ; + for (int i=0; i<NumberOf; i++) + cout << value[i]<< " "; + cout<<endl; + } + } +} + +int main (int argc, char ** argv) { + + if ((argc !=3) && (argc != 5)) { + cerr << "Usage : " << argv[0] + << " filename fieldName [iterationNumber] [orderNumber]" << endl << endl; + exit(-1); + } + + string fileName = argv[1] ; + string fieldName = argv[2] ; + int iterationNumber=-1,orderNumber=-1; + if ( argv[3] ) iterationNumber = atoi(argv[3]); + if ( argv[4] ) orderNumber = atoi(argv[4]); + + string meshName=""; //"MAILTRQU"; + //goto mode3; + ///////////////////////////////////////////////////////////////////////////////////////// + // TEST PREMIER MODE : + // Le fichier MED lu contient le maillage associé au champ demandé (qui contient des profils ) + // Le driver du FIELD automatiquement crée est capable de lire les profils MEDFICHIER + // (le SUPPORT est crée automatiquement, le nom du maillage associé est disponible dans + // le SUPPORT mais la relation SUPPORT-MESH est non initialisée car le MESH n'est pas chargé). + // Le driver utilise les informations du maillage dans le fichier pour transcrire les profils + // de la numérotation locale MEDFICHIER à la numérotation globale MEDMEMOIRE). + // A l'écriture, il se repose également sur le maillage contenu dans le fichier + // pour effecuter la renumérotation. + { + FIELD<double> * myField1 = new FIELD<double>(MED_DRIVER,fileName,fieldName, + iterationNumber, orderNumber); + affiche_fieldT(myField1, myField1->getSupport()); + + // Pour éviter de modifier le fichier d'origine, + // on en crée une copie avec uniquement le maillage. + // Rem : Pour le test, le chargement du maillage n'est pas nécessaire + // On pourrait réécrire le Champ dans le fichier d'origine + // sous un autre nom. + // Attention si le driver MED_MESH modifie le nombre d'éléments d'un type géométrique : + // le calcul de renumérotation à l'écriture du champ risque d'être faux ! + meshName = myField1->getSupport()->getMeshName(); + MESH * myMesh = new MESH(MED_DRIVER,fileName,meshName); + MED_MESH_WRONLY_DRIVER myMeshDriver1("Copy_withmesh_"+fileName,myMesh); + int current=myMesh->addDriver(myMeshDriver1); + myMesh->write(current); + delete myMesh; + + // On ajoute un driver en écriture, comme la relation SUPPORT-MESH n'est pas + // initialisée, le driver doit trouver le maillage dans le fichier cible + // pour réaliser la transcription des profils MEDMEMOIRE à MEDFICHIER. + MED_FIELD_WRONLY_DRIVER<double> myFieldDriver2("Copy_withmesh_"+fileName,myField1) ; + current = myField1->addDriver(myFieldDriver2); + myField1->write(current); + delete myField1; + } + + mode2: + ///////////////////////////////////////////////////////////////////////////// + // TEST DEUXIEME MODE : + // Lecture idem 1er mode + // A l'écriture, le fichier cible ne contient pas le maillage mais la + // relation SUPPORT-MESH étant établie le driver utilise les informations + // dans le maillage en mémoire pour transcrire les profils. + // Selon le modèle MED FICHIER, ce mode est interdit : le fichier doit au moins + // contenir un lien sur le maillage (information pas encore exploitée dans MEDMEMOIRE + // : pas de gestion de montage/démontage des fichiers ) + // Attention si le driver MED_MESH modifie le nombre d'éléments d'un type géométrique : + // le calcul de renumérotation à l'écriture du champ risque d'être faux car les + // profils crées à la lecture son basés sur le nombre d'éléments par type géoémtrique + // du maillage contenu dans le fichier à la lecture. + // Une solution consisterait à prendre en compte le montage de fichiers distants + // et de prendre en compte la différence de nombre d'éléments par type géométrique + // entre le maillage MEDMEM et le maillage MEDFICHIER + // (Hum ! : Il serait plus simple que MEDMEMOIRE ne recalcule pas systématiquement + // ce que l'on ne lui demande pas, ce qui permettrait aussi de réécrire à l'identique + // un fichier que l'on vient de lire) + { + FIELD<double> * myField2 = new FIELD<double>(MED_DRIVER,fileName,fieldName, + iterationNumber, orderNumber); + + meshName = myField2->getSupport()->getMeshName(); + MESH * myMesh2 = new MESH(MED_DRIVER,fileName,meshName); + + const SUPPORT * mySupport2=myField2->getSupport(); + mySupport2->setMesh(myMesh2); + + // On ajoute un driver en écriture, comme la relation SUPPORT-MESH est + // initialisée, le driver utilise le maillage en mémoire + // pour réaliser la transcription des profils MEDMEMOIRE à MEDFICHIER. + MED_FIELD_WRONLY_DRIVER<double> myFieldDriver3("Copy_nomesh_"+fileName,myField2) ; + int current = myField2->addDriver(myFieldDriver3); + myField2->write(current); + + //Pour regarder le fichier produit avec MDUMP decommenter ces trois lignes + //car le fichier qui est produit n'est pas à la norme MED + //Il doit contenir soit le maillage associé soit un lien vers le maillage associé. + //MED_MESH_WRONLY_DRIVER myMeshDriver2("Copy_nomesh_"+fileName,myMesh2); + //current=myMesh2->addDriver(myMeshDriver2); + //myMesh2->write(current); + + delete myField2; + delete myMesh2; + + + } + mode3: + // TEST TROISIEME MODE : + // A la lecture, le fichier MED lu ne contient pas le maillage associé au champ demandé + // (mais un lien MEDFICHIER qui n'est pas exploité à ce jour). + // Cependant avant sa lecture le FIELD a été associé à un SUPPORT + // avec le lien au MESH préalablement chargé. + // Le driver du FIELD (automatiquement crée) est capable de lire les profils MEDFICHIER + // et utilise la relation SUPPORT-MESH initialisée pour transcrire les profils + // de la numérotation locale MEDFICHIER à la numérotation globale MEDMEMOIRE). + // REM: Une fois le champ chargé, il possède un nouveau support, le premier peut être libéré. + // En effet le driver du FIELD se fit uniquement au type géométriques définis dans le champ MEDFICHIER + // pour créer son SUPPORT car un SUPPORT crée "onAll" à partir d'un MESH repose sur tous + // les types géométriques du MESH ce qui n'est pas forcément le cas d'un champ MEDFICHIER + // (même sans profil) lu à posteriori. + { + med_2_3::med_err err=-1; + med_2_3::med_idt id = med_2_3::MEDouvrir(const_cast<char *> ( ("Copy_nomesh_"+fileName).c_str()), + med_2_3::MED_LECTURE_ECRITURE); + if (id <=0) cout << "Erreur dans MEDouvrir pour le fichier " << "Copy_nomesh_"+fileName <<endl; + + err=med_2_3::MEDlienEcr(id, const_cast<char *> ( ("Copy_withmesh_"+fileName).c_str()), + const_cast<char *> (meshName.c_str()) ); + if (err !=0) cout << "Erreur dans MEDlienEcr pour le maillage distant " << meshName + <<" contenu dans le fichier " << "Copy_withmesh_"+fileName <<endl; + + + err=med_2_3::MEDfermer(id); + + MESH * myMesh3 = new MESH(MED_DRIVER,fileName,meshName); + const SUPPORT * mySupport3= new SUPPORT(myMesh3,"Temporary Support",MED_CELL); + FIELD<double> * myField3 = new FIELD<double>(mySupport3,MED_DRIVER,"Copy_nomesh_"+fileName,fieldName, + iterationNumber, orderNumber); + delete mySupport3; // Il est déjà possible de libérer ce SUPPORT + + //TEST à la réecriture : + string cpy("__Copy"); + vector < string > pflNames = myField3->getSupport()->getProfilNames(); + for (int i=0; i< pflNames.size(); ++i) { + pflNames[i].resize(pflNames[i].size()-cpy.size()); + pflNames[i]+=cpy; + } + const_cast<SUPPORT*>(myField3->getSupport())->setProfilNames(pflNames); + MED_FIELD_WRONLY_DRIVER<double> myFieldDriver4("Copy_nomesh_"+fileName,myField3) ; + myFieldDriver4.setFieldName(myField3->getName()+"__Copy"); + int current = myField3->addDriver(myFieldDriver4); + myField3->write(current); + + delete myMesh3; + delete myField3; + + + //ESSAYER AVEC MAILLAGE DS FICHIER ET LIEN SUPORT-MESH PRESENTS SIMULTANEMENT + //EN VERSION COHERENTE ET NON COHERENTE + } +} diff --git a/src/MEDMEMBinTest/test_profil_gauss_MedFieldDriver.cxx b/src/MEDMEMBinTest/test_profil_gauss_MedFieldDriver.cxx new file mode 100644 index 000000000..1dec0f64c --- /dev/null +++ b/src/MEDMEMBinTest/test_profil_gauss_MedFieldDriver.cxx @@ -0,0 +1,463 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include <stdlib.h> +#include<string> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_MedFieldDriver.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_define.hxx" +#include "MEDMEM_GaussLocalization.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +#define INTERLACING_MODE FullInterlace +int fct2(int i,const int * number) { return i;}; +int fct1(int i,const int * number) { return number[i]; }; + +void affiche_field_(FIELD_ * myField) +{ + cout << "Field "<< myField->getName() << " : " <<myField->getDescription() << endl ; + int NumberOfComponents = myField->getNumberOfComponents() ; + cout << "- Nombre de composantes : "<< NumberOfComponents << endl ; + for (int i=1; i<NumberOfComponents+1; i++) { + cout << " - composante "<<i<<" :"<<endl ; + cout << " - nom : "<<myField->getComponentName(i)<< endl; + cout << " - description : "<<myField->getComponentDescription(i) << endl; + cout << " - units : "<<myField->getMEDComponentUnit(i) << endl; + } + cout << "- iteration :" << endl ; + cout << " - numero : " << myField->getIterationNumber()<< endl ; + cout << " - ordre : " << myField->getOrderNumber()<< endl ; + cout << " - temps : " << myField->getTime()<< endl ; + + cout << "- Type : " << myField->getValueType()<< endl; + //PRESENCE DE POINTS DE GAUSS +} + +// Cas de traitement des valeurs sans spécificité concernant +// les points de Gauss ou les profils +// Pas de spécificité concernant le type géométrique +template <class INTERLACING_TAG> +void affiche_fieldT(FIELD<double,INTERLACING_TAG> * myField) +{ + const double * value = 0; + affiche_field_((FIELD_ *) myField); + + cout.setf(ios::fixed); + + int numberOf = myField->getNumberOfValues(); + int numberOfComponents = myField->getNumberOfComponents() ; + int valueLength = myField->getValueLength(); + int numberOfGeometricType = myField->getNumberOfGeometricTypes(); + const int * nbOfElements = myField->getNumberOfElements(); + const MED_EN::medGeometryElement * typeList = myField->getGeometricTypes(); + // Suivant le traitement, on peut faire sortir si il y a des points de Gauss + // ou des profils + + cout << "myField->getValueLength (MED_ALL_ELEMENTS) : " << valueLength << endl; + cout << "myField->getNumberOfElements (MED_ALL_ELEMENTS) : " << numberOf << endl; + cout << "myField->getNumberOfComponents () : " << numberOfComponents << endl; + cout << "myField->getNumberOfGeometricType () : " << numberOfGeometricType << endl; + for (int i=0; i < numberOfGeometricType; i++) { + cout << "Number Of Elements on type "<< MED_EN::geoNames[typeList[i]] + <<" : "<< nbOfElements[i] << endl; + cout << "Number Of Gauss Points on type "<< MED_EN::geoNames[typeList[i]] + <<" : "<< myField->getNumberOfGaussPoints(typeList[i]) << endl; + cout << "Localization description : " << endl << myField->getGaussLocalization(typeList[i]) << endl; + } + + cout << "- Valeurs :"<<endl; + for (int index=0; index < valueLength; index++) { + cout << "value["<<index<<"] = "<< value[index]; + cout<<endl; + } + +} + +// Spécialisation du traitement pour le mode FullInterlace +// Spécifité de traitement par rapport aux profils (utilisation du SUPPORT) +// Pas de spécificité concernant le type géométrique +// Pas de spécificité concernant les points de Gauss +template <> +void affiche_fieldT(FIELD<double, FullInterlace> * myField) +{ + const double * value = 0; + const int * number = 0; + + affiche_field_((FIELD_ *) myField); + const SUPPORT * mySupport=myField->getSupport(); + + cout.setf(ios::fixed); + + + int numberOfComponents = myField->getNumberOfComponents() ; + int valueLength = myField->getValueLength(); + const int * nbGaussPoints = myField->getNumberOfGaussPoints(); + + int numberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); + int numberOfGeometricType = mySupport->getNumberOfTypes(); + const int * nbOfElements = mySupport->getNumberOfElements(); + const MED_EN::medGeometryElement * typeList = mySupport->getTypes(); + bool onAll = mySupport->isOnAllElements(); + + cout << "mySupport->getValueLength (MED_ALL_ELEMENTS) : " << valueLength << endl; + cout << "mySupport->getNumberOfElements (MED_ALL_ELEMENTS) : " << numberOf << endl; + cout << "mySupport->getNumberOfComponents () : " << numberOfComponents << endl; + cout << "mySupport->getNumberOfGeometricType () : " << numberOfGeometricType << endl; + assert(numberOf == myField->getNumberOfValues() ); + + // S'il existe des profils, je récupère la liste des numéros d'éléments + // pour tous les types géométriques + for (int i=0; i < numberOfGeometricType; i++) { + cout << "Number Of Elements on type "<< MED_EN::geoNames[typeList[i]] + <<" : "<< nbOfElements[i] << endl; + cout << "Number Of Gauss Points on type "<< MED_EN::geoNames[typeList[i]] + <<" : "<< nbGaussPoints[i] << endl; + cout << "Localization description : " << endl << myField->getGaussLocalization(typeList[i]) << endl; + } + + // On récupère la liste complète + if (!onAll) number = mySupport->getNumber(MED_ALL_ELEMENTS); + + int elNo = -1; + cout << "- Valeurs :" << endl; + for (int i=1; i<=numberOf; i++) { + if (onAll) elNo = i; else elNo = number[i-1]; + //cout << endl << "myField->getRow("<<elNo<<") : "<< myField->getRow(elNo) << endl; + value = myField->getRow(elNo) ; + //UP: getRow prend un numéro d'élément qui existe, getRow(1) n'existe pas forcément si il y a un profil + //qui ne défini pas cet indice + //cout << endl << " Valeur de getNbGaussI("<<elNo<<") :" << myField->getNbGaussI(elNo) << endl; + for (int j=0; j<numberOfComponents*myField->getNbGaussI(elNo); j++) + //UP : Prend en compte le nombre de points de Gauss de l'élément elNo + cout << "value["<< elNo << "] = " << value[j] << " "; + cout<<endl; + } + +} + +// Spécialisation du traitement pour le mode NoInterlace +// Spécifité de traitement par rapport aux profils (utilisation du SUPPORT) +// Pas de spécificité concernant le type géométrique +// Pas de spécificité concernant les points de Gauss +template <> +void affiche_fieldT(FIELD<double, NoInterlace> * myField) +{ + const double * value = 0; + const int * number = 0; + + affiche_field_((FIELD_ *) myField); + const SUPPORT * mySupport=myField->getSupport(); + + cout.setf(ios::fixed); + + + int numberOfComponents = myField->getNumberOfComponents() ; + int valueLength = myField->getValueLength(); + const int * nbGaussPoints = myField->getNumberOfGaussPoints(); + + int numberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); + int numberOfGeometricType = mySupport->getNumberOfTypes(); + const int * nbOfElements = mySupport->getNumberOfElements(); + const MED_EN::medGeometryElement * typeList = mySupport->getTypes(); + bool onAll = mySupport->isOnAllElements(); + + cout << "mySupport->getValueLength (MED_ALL_ELEMENTS) : " << valueLength << endl; + cout << "mySupport->getNumberOfElements (MED_ALL_ELEMENTS) : " << numberOf << endl; + cout << "mySupport->getNumberOfComponents () : " << numberOfComponents << endl; + cout << "mySupport->getNumberOfGeometricType () : " << numberOfGeometricType << endl; + cout << "mySupport->getNumberOfElements(MED_ALL_ELEMENTS) : " << numberOf << endl; + assert(numberOf == myField->getNumberOfValues() ); + + // S'il existe des profils, je récupère la liste des numéros d'éléments + // pour tous les types géométriques + for (int i=0; i < numberOfGeometricType; i++) { + cout << "Number Of Elements on type "<< MED_EN::geoNames[typeList[i]] + <<" : "<< nbOfElements[i] << endl; + cout << "Number Of Gauss Points on type "<< MED_EN::geoNames[typeList[i]] + <<" : "<< nbGaussPoints[i] << endl; + cout << "Localization description : " << endl << myField->getGaussLocalization(typeList[i]) << endl; + } + + + int (* fct)(int,const int *); + + if (!onAll) { + number = mySupport->getNumber(MED_ALL_ELEMENTS); + fct=fct1; + } else + fct=fct2; + + int oneDimlength = valueLength/numberOfComponents; + for (int j=1; j<=numberOfComponents; j++) { + value = myField->getColumn(j) ; + for (int i=0; i<oneDimlength; i++) + cout << "value["<< fct(i,number) << ","<<j<<"]" << value[ fct(i,number) ] << " "; + cout<<endl; + } + +} + + +template <class T, class INTERLACING_TAG> +void affiche_fieldT2(FIELD< T, INTERLACING_TAG> * myField) +{}; + + +// Spécialisation du traitement pour le mode FullInterlace +// Spécifité de traitement par rapport aux profils (utilisation du SUPPORT) +// Spécificité concernant le type géométrique +// Spécificité concernant les points de Gauss +template <> +void affiche_fieldT2(FIELD<double, FullInterlace> * myField) +{ + const int * number = 0; + + affiche_field_((FIELD_ *) myField); + const SUPPORT * mySupport=myField->getSupport(); + + cout.setf(ios::fixed); + + + int numberOfComponents = myField->getNumberOfComponents() ; + int valueLength = myField->getValueLength(); + const int * nbGaussPoints = myField->getNumberOfGaussPoints(); + + int numberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS); + int numberOfGeometricType = mySupport->getNumberOfTypes(); + const int * nbOfElements = mySupport->getNumberOfElements(); + const MED_EN::medGeometryElement * typeList = mySupport->getTypes(); + bool onAll = mySupport->isOnAllElements(); + + cout << "mySupport->getValueLength (MED_ALL_ELEMENTS) : " << valueLength << endl; + cout << "mySupport->getNumberOfElements (MED_ALL_ELEMENTS) : " << numberOf << endl; + cout << "mySupport->getNumberOfComponents () : " << numberOfComponents << endl; + cout << "mySupport->getNumberOfGeometricType () : " << numberOfGeometricType << endl; + cout << "mySupport->getNumberOfElements(MED_ALL_ELEMENTS) : " << numberOf << endl; + assert(numberOf == myField->getNumberOfValues() ); + + // S'il existe des profils, je récupère la liste des numéros d'éléments + // pour tous les types géométriques + for (int i=0; i < numberOfGeometricType; i++) { + cout << "Number Of Elements on type "<< MED_EN::geoNames[typeList[i]] + <<" : "<< nbOfElements[i] << endl; + cout << "Number Of Gauss Points on type "<< MED_EN::geoNames[typeList[i]] + <<" : "<< nbGaussPoints[i] << endl; + } + + + int (* fct)(int,const int *); + + if (!onAll) { + number = mySupport->getNumber(MED_ALL_ELEMENTS); + fct=fct1; + } else + fct=fct2; + + cout << "- Valeurs :"<<endl; + + int elemno = 1; + for (int ntyp=1; ntyp <= numberOfGeometricType; ntyp++ ) { + for (int i=0; i < nbOfElements[ntyp-1] ; i++ ) { + for (int k=1; k <= nbGaussPoints[ntyp-1]; k++) + for (int j=1; j <= numberOfComponents; j++) { + cout << " value["<< fct(elemno-1,number) << "," <<j<<","<<k<<"] = " + << myField->getValueIJK(fct(elemno-1,number),j,k); + } + elemno++; + cout << endl; + } + } + + assert((elemno-1) == numberOf); + +} + + +int main (int argc, char ** argv) { + + if ((argc !=3) && (argc != 5)) { + cerr << "Usage : " << argv[0] + << " filename fieldName [iterationNumber] [orderNumber]" << endl << endl; + exit(-1); + } + + string fileName = argv[1] ; + string fieldName = argv[2] ; + int iterationNumber=-1,orderNumber=-1; + if ( argv[3] ) iterationNumber = atoi(argv[3]); + if ( argv[4] ) orderNumber = atoi(argv[4]); + + string meshName="";//"MAILTRQU"; + //goto mode2; + ///////////////////////////////////////////////////////////////////////////////////////// + // TEST PREMIER MODE : + // Le fichier MED lu contient le maillage associé au champ demandé (qui contient des profils ) + // Le driver du FIELD automatiquement crée est capable de lire les profils MEDFICHIER + // (le SUPPORT est crée automatiquement, le nom du maillage associé est disponible dans + // le SUPPORT mais la relation SUPPORT-MESH est non initialisée car le MESH n'est pas chargé). + // Le driver utilise les informations du maillage dans le fichier pour transcrire les profils + // de la numérotation locale MEDFICHIER à la numérotation globale MEDMEMOIRE). + // A l'écriture, il se repose également sur le maillage contenu dans le fichier + // pour effecuter la renumérotation. + { + FIELD<double,INTERLACING_MODE> * myField1 = new FIELD<double,INTERLACING_MODE>(MED_DRIVER,fileName,fieldName, + iterationNumber, orderNumber); + affiche_fieldT(myField1); + cout << endl; + affiche_fieldT2(myField1); + + // Pour éviter de modifier le fichier d'origine, + // on en crée une copie avec uniquement le maillage. + // Rem : Pour le test, le chargement du maillage n'est pas nécessaire + // On pourrait réécrire le Champ dans le fichier d'origine + // sous un autre nom. + // Attention si le driver MED_MESH modifie le nombre d'éléments d'un type géométrique : + // le calcul de renumérotation à l'écriture du champ risque d'être faux ! + meshName = myField1->getSupport()->getMeshName(); + MESH * myMesh = new MESH(MED_DRIVER,fileName,meshName); + MED_MESH_WRONLY_DRIVER myMeshDriver1("Copy_withmesh_"+fileName,myMesh); + int current=myMesh->addDriver(myMeshDriver1); + myMesh->write(current); + delete myMesh; + + // On ajoute un driver en écriture, comme la relation SUPPORT-MESH n'est pas + // initialisée, le driver doit trouver le maillage dans le fichier cible + // pour réaliser la transcription des profils MEDMEMOIRE à MEDFICHIER. + MED_FIELD_WRONLY_DRIVER<double> myFieldDriver2("Copy_withmesh_"+fileName,myField1) ; + current = myField1->addDriver(myFieldDriver2); + myField1->write(current); + delete myField1; + } + + mode2: + ///////////////////////////////////////////////////////////////////////////// + // TEST DEUXIEME MODE : + // Lecture idem 1er mode + // A l'écriture, le fichier cible ne contient pas le maillage mais la + // relation SUPPORT-MESH est établie, le driver peut donc utiliser les informations + // dans le maillage pour transcrire les profils. + // Selon le modèle MED FICHIER, ce mode est interdit : le fichier doit au moins + // contenir un lien sur le maillage (information pas encore exploitée dans MEDMEMOIRE + // : pas de gestion de montage/démontage des fichiers ) + // Attention si le driver MED_MESH modifie le nombre d'éléments d'un type géométrique : + // le calcul de renumérotation à l'écriture du champ risque d'être faux car les + // profils crées à la lecture sont basés sur le nombre d'éléments par type géoémtrique + // du maillage contenu dans le fichier à la lecture. + // Une solution consisterait à prendre en compte le montage de fichiers distants + // et de prendre en compte la différence de nombre d'éléments par type géométrique + // entre le maillage MEDMEM et le maillage MEDFICHIER + // (Hum ! : Il serait plus simple que MEDMEMOIRE ne recalcule pas systématiquement + // ce que l'on ne lui demande pas, ce qui permettrait aussi de réécrire à l'identique + // un fichier que l'on vient de lire) + { + FIELD<double,INTERLACING_MODE> * myField2 = new FIELD<double,INTERLACING_MODE>(MED_DRIVER,fileName,fieldName, + iterationNumber, orderNumber); + + meshName = myField2->getSupport()->getMeshName(); + MESH * myMesh2 = new MESH(MED_DRIVER,fileName,meshName); + + const SUPPORT * mySupport2=myField2->getSupport(); + mySupport2->setMesh(myMesh2); + + // On ajoute un driver en écriture, comme la relation SUPPORT-MESH est + // initialisée, le driver utilise le maillage en mémoire + // pour réaliser la transcription des profils MEDMEMOIRE à MEDFICHIER. + MED_FIELD_WRONLY_DRIVER<double> myFieldDriver3("Copy_nomesh_"+fileName,myField2) ; + int current = myField2->addDriver(myFieldDriver3); + myField2->write(current); + + //Pour regarder le fichier produit avec MDUMP decommenter ces trois lignes + //car le fichier qui est produit n'est pas à la norme MED + //Il doit contenir soit le maillage associé soit un lien vers le maillage associé. + //MED_MESH_WRONLY_DRIVER myMeshDriver2("Copy_nomesh_"+fileName,myMesh2); + //current=myMesh2->addDriver(myMeshDriver2); + //myMesh2->write(current); + + delete myField2; + delete myMesh2; + + + } + mode3: + // TEST TROISIEME MODE : + // A la lecture, le fichier MED lu ne contient pas le maillage associé au champ demandé + // (mais un lien MEDFICHIER qui n'est pas exploité à ce jour). + // Cependant avant sa lecture le FIELD a été associé à un SUPPORT + // avec le lien au MESH préalablement chargé. + // Le driver du FIELD (automatiquement crée) est capable de lire les profils MEDFICHIER + // et utilise la relation SUPPORT-MESH initialisée pour transcrire les profils + // de la numérotation locale MEDFICHIER à la numérotation globale MEDMEMOIRE). + // REM: Une fois le champ chargé, il possède un nouveau support, le premier peut être libéré. + // En effet le driver du FIELD se fit uniquement au type géométriques définis dans le champ MEDFICHIER + // pour créer son SUPPORT car un SUPPORT crée "onAll" à partir d'un MESH repose sur tous + // les types géométriques du MESH ce qui n'est pas forcément le cas d'un champ MEDFICHIER + // (même sans profil) lu à posteriori. + { + med_2_3::med_err err=-1; + med_2_3::med_idt id = med_2_3::MEDouvrir(const_cast<char *> ( ("Copy_nomesh_"+fileName).c_str()), + med_2_3::MED_LECTURE_ECRITURE); + if (id <=0) cout << "Erreur dans MEDouvrir pour le fichier " << "Copy_nomesh_"+fileName <<endl; + + err=med_2_3::MEDlienEcr(id, const_cast<char *> ( ("Copy_withmesh_"+fileName).c_str()), + const_cast<char *> (meshName.c_str()) ); + if (err !=0) cout << "Erreur dans MEDlienEcr pour le maillage distant " << meshName + <<" contenu dans le fichier " << "Copy_withmesh_"+fileName <<endl; + + + err=med_2_3::MEDfermer(id); + + MESH * myMesh3 = new MESH(MED_DRIVER,fileName,meshName); + const SUPPORT * mySupport3= new SUPPORT(myMesh3,"Temporary Support",MED_CELL); + FIELD<double,INTERLACING_MODE> * myField3 = new FIELD<double,INTERLACING_MODE>(mySupport3,MED_DRIVER,"Copy_nomesh_"+fileName,fieldName, iterationNumber, orderNumber); + delete mySupport3; // Il est déjà possible de libérer ce SUPPORT + + //TEST à la réecriture (renommage des profils + // à cause de MEDprofilEcr qui ne prend pas en compte le mode + // MED_LECTURE_AJOUT) ): + string cpy("__Copy"); + vector < string > pflNames = myField3->getSupport()->getProfilNames(); + for (int i=0; i< pflNames.size(); ++i) { + pflNames[i].resize(pflNames[i].size()-cpy.size()); + pflNames[i]+=cpy; + } + const_cast<SUPPORT*>(myField3->getSupport())->setProfilNames(pflNames); + + MED_FIELD_WRONLY_DRIVER<double> myFieldDriver4("Copy_nomesh_"+fileName,myField3) ; + myFieldDriver4.setFieldName(myField3->getName()+"__Copy"); + int current = myField3->addDriver(myFieldDriver4); + myField3->write(current); + + delete myMesh3; + delete myField3; + + + //ESSAYER AVEC MAILLAGE DS FICHIER ET LIEN SUPORT-MESH PRESENTS SIMULTANEMENT + //EN VERSION COHERENTE ET NON COHERENTE + } +} diff --git a/src/MEDMEMBinTest/test_write_groups_poly.cxx b/src/MEDMEMBinTest/test_write_groups_poly.cxx new file mode 100644 index 000000000..959c8b767 --- /dev/null +++ b/src/MEDMEMBinTest/test_write_groups_poly.cxx @@ -0,0 +1,173 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_Meshing.hxx" +#include "MEDMEM_Group.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +void addMedFacesGroup (MESHING& meshing, int nFaces, int *groupValue, string groupName) +{ + GROUP faces; + int myNumberOfElements[1]; + medGeometryElement mytypes[1]; + int index[2]; + faces.setName(groupName); + faces.setMesh(&meshing); + faces.setEntity(MED_EN::MED_FACE); + faces.setNumberOfGeometricType(1); + mytypes[0] = MED_EN::MED_POLYGON; + faces.setGeometricType(mytypes); + myNumberOfElements[0] = nFaces; + faces.setNumberOfElements(myNumberOfElements); + index[0] = 1; + index[1] = nFaces; + faces.setNumber(index, groupValue); + meshing.addGroup(faces); +} + +int main() +{ + MESHING *pmesh = new MESHING; + pmesh->setName( "C2MESH" ); + pmesh->setSpaceDimension(3); + pmesh->setNumberOfTypes(0, MED_EN::MED_CELL); + pmesh->setMeshDimension(3); + int nb_hexagone = 7; + int nbmailles_axiales = 2; + int nNodes = 6 * nb_hexagone * nbmailles_axiales; + // int nNodes=*max_element (connec, connec+6*nb_hexagone*nbmailles_axiales); + pmesh->setNumberOfNodes(nNodes); + + double coord[] = { + 44.401823743922364, 0 , 0, 55.698259110886582, 6.5220000000000002, 0, + 55.698259110886582, 19.566000000000003, 0, 44.401823743922364, 26.088000000000001, 0, + 33.105388376958146, 19.566000000000003, 0, 33.105388376958146, 6.5220000000000002, 0, + 66.9946944778508 , 0 , 0, 78.291129844815018, 6.5220000000000002, 0, + 78.291129844815018, 19.566000000000003, 0, 66.9946944778508 , 26.088000000000001, 0, + 55.698259110886582, 19.566000000000003, 0, 55.698259110886582, 6.5220000000000002, 0, + 33.105388376958146, 19.565999999999999, 0, 44.401823743922364, 26.088000000000001, 0, + 44.401823743922364, 39.131999999999998, 0, 33.105388376958146, 45.653999999999996, 0, + 21.808953009993928, 39.131999999999998, 0, 21.808953009993928, 26.088000000000001, 0, + 55.698259110886582, 19.565999999999999, 0, 66.9946944778508 , 26.088000000000001, 0, + 66.9946944778508 , 39.131999999999998, 0, 55.698259110886582, 45.653999999999996, 0, + 44.401823743922364, 39.131999999999998, 0, 44.401823743922364, 26.088000000000001, 0, + 78.291129844815018, 19.565999999999999, 0, 89.587565211779236, 26.088000000000001, 0, + 89.587565211779236, 39.131999999999998, 0, 78.291129844815018, 45.653999999999996, 0, + 66.9946944778508 , 39.131999999999998, 0, 66.9946944778508 , 26.088000000000001, 0, + 44.401823743922364, 39.132000000000005, 0, 55.698259110886582, 45.654000000000003, 0, + 55.698259110886582, 58.698 , 0, 44.401823743922364, 65.219999999999999, 0, + 33.105388376958146, 58.698 , 0, 33.105388376958146, 45.654000000000003, 0, + 66.9946944778508 , 39.132000000000005, 0, 78.291129844815018, 45.654000000000003, 0, + 78.291129844815018, 58.698 , 0, 66.9946944778508 , 65.219999999999999, 0, + 55.698259110886582, 58.698 , 0, 55.698259110886582, 45.654000000000003, 0, + 44.401823743922364, 0 , 1, 55.698259110886582, 6.5220000000000002, 1, + 55.698259110886582, 19.566000000000003, 1, 44.401823743922364, 26.088000000000001, 1, + 33.105388376958146, 19.566000000000003, 1, 33.105388376958146, 6.5220000000000002, 1, + 66.9946944778508 , 0 , 1, 78.291129844815018, 6.5220000000000002, 1, + 78.291129844815018, 19.566000000000003, 1, 66.9946944778508 , 26.088000000000001, 1, + 55.698259110886582, 19.566000000000003, 1, 55.698259110886582, 6.5220000000000002, 1, + 33.105388376958146, 19.565999999999999, 1, 44.401823743922364, 26.088000000000001, 1, + 44.401823743922364, 39.131999999999998, 1, 33.105388376958146, 45.653999999999996, 1, + 21.808953009993928, 39.131999999999998, 1, 21.808953009993928, 26.088000000000001, 1, + 55.698259110886582, 19.565999999999999, 1, 66.9946944778508 , 26.088000000000001, 1, + 66.9946944778508 , 39.131999999999998, 1, 55.698259110886582, 45.653999999999996, 1, + 44.401823743922364, 39.131999999999998, 1, 44.401823743922364, 26.088000000000001, 1, + 78.291129844815018, 19.565999999999999, 1, 89.587565211779236, 26.088000000000001, 1, + 89.587565211779236, 39.131999999999998, 1, 78.291129844815018, 45.653999999999996, 1, + 66.9946944778508 , 39.131999999999998, 1, 66.9946944778508 , 26.088000000000001, 1, + 44.401823743922364, 39.132000000000005, 1, 55.698259110886582, 45.654000000000003, 1, + 55.698259110886582, 58.698 , 1, 44.401823743922364, 65.219999999999999, 1, + 33.105388376958146, 58.698 , 1, 33.105388376958146, 45.654000000000003, 1, + 66.9946944778508 , 39.132000000000005, 1, 78.291129844815018, 45.654000000000003, 1, + 78.291129844815018, 58.698 , 1, 66.9946944778508 , 65.219999999999999, 1, + 55.698259110886582, 58.698 , 1, 55.698259110886582, 45.654000000000003, 1}; + + pmesh->setCoordinates(3, nNodes, coord, "CARTESIAN", MED_EN::MED_FULL_INTERLACE); + + string coordname[3] = { "x", "y", "z" }; + pmesh->setCoordinatesNames(coordname); + + // Set coordinates units + string coordunit[3] = { "cm", "cm", "cm" }; + pmesh->setCoordinatesUnits(coordunit); + + int polyHInd[] = {1, 9, 17, 25, 33, 41, 49, 57}; + int polyHFacesInd[] = {1 , 7 , 13 , 17 , 21 , 25 , 29 , 33 , + 37 , 43 , 49 , 53 , 57 , 61 , 65 , 69 , + 73 , 79 , 85 , 89 , 93 , 97 , 101, 105, + 109, 115, 121, 125, 129, 133, 137, 141, + 145, 151, 157, 161, 165, 169, 173, 177, + 181, 187, 193, 197, 201, 205, 209, 213, + 217, 223, 229, 233, 237, 241, 245, 249, 253}; + int polyHConn[] = { + 1,2,3,4,5,6, 43,44,45,46,47,48, 1,2,44,43, 2,3,45,44, + 3,4,46,45, 4,5,47,46, 5,6,48,47, 6,1,43,48, // #1 + 7,8,9,10,3,2, 49,50,51,52,45,44, 7,8,50,49, 8,9,51,50, + 9,10,52,51, 10,3,45,52, 3,2,44,45, 2,7,49,44, // #2 + 5,4,15,16,17,18, 47,46,57,58,59,60, 5,4,46,47, 4,15,57,46, + 15,16,58,57, 16,17,59,58, 17,18,60,59, 18,5,47,60, // #3 + 3,10,21,22,15,4, 45,52,63,64,57,46, 3,10,52,45, 10,21,63,52, + 21,22,64,63, 22,15,57,64, 15,4,46,57, 4,3,45,46, // #4 + 9,26,27,28,21,10, 51,68,69,70,63,52, 9,26,68,51, 26,27,69,68, + 27,28,70,69, 28,21,63,70, 21,10,52,63, 10,9,51,52, // #5 + 15,22,33,34,35,16, 57,64,75,76,77,58, 15,22,64,57, 22,33,75,64, + 33,34,76,75, 34,35,77,76, 35,16,58,77, 16,15,57,58, // #6 + 21,28,39,40,33,22, 63,70,81,82,75,64, 21,28,70,63, 28,39,81,70, + 39,40,82,81, 40,33,75,82, 33,22,64,75, 22,21,63,64}; // #7 + + pmesh->setPolyhedraConnectivity(polyHInd, polyHFacesInd, polyHConn, + nb_hexagone*(nbmailles_axiales-1), MED_EN::MED_CELL); + + int cpolygonsindex[] = {1, 7, 13, 19, 25, 31, 37, 43, 49, 55, 61, 67, 73, 79, 85}; + int connec[] = { + 1 , 2 , 3 , 4 , 5 , 6 , + 7 , 8 , 9 , 10, 3 , 2 , + 5 , 4 , 15, 16, 17, 18, + 3 , 10, 21, 22, 15, 4 , + 9 , 26, 27, 28, 21, 10, + 15, 22, 33, 34, 35, 16, + 21, 28, 39, 40, 33, 22, + 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 45, 44, + 47, 46, 57, 58, 59, 60, + 45, 52, 63, 64, 57, 46, + 51, 68, 69, 70, 63, 52, + 57, 64, 75, 76, 77, 58, + 63, 70, 81, 82, 75, 64}; + + pmesh->setNumberOfTypes(0, MED_EN::MED_FACE); + pmesh->setPolygonsConnectivity(cpolygonsindex, connec, nb_hexagone*nbmailles_axiales, MED_EN::MED_FACE); + + int bottom[] = {1, 2, 3, 4, 5, 6, 7}; + addMedFacesGroup(*pmesh, nb_hexagone, bottom, "BottomFaces"); + + int id = pmesh->addDriver(MED_DRIVER, "cronoshexa.med", pmesh->getName()); + pmesh->write(id); + + if ( getenv("srcdir") ) + /* we are in 'make check' */ + remove( "cronoshexa.med" ); + + return 0; +} diff --git a/src/MEDMEMBinTest/tests/readCoordinate.cxx b/src/MEDMEMBinTest/tests/readCoordinate.cxx new file mode 100755 index 000000000..7eb17db31 --- /dev/null +++ b/src/MEDMEMBinTest/tests/readCoordinate.cxx @@ -0,0 +1,133 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// File : readCoordinate.cxx +// Module : MED +// +#include<string> +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_define.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_MedMeshDriver.hxx" + +using namespace std; +using namespace MEDMEM; + +#define MED_TAILLE_PNOM 16 + +void usage(char * name) +{ + cout << " " << name <<" <file name>"<< " <mesh name> " << " <interlace mode>" << endl; + cout << " " << "displays all Nodes Coordinates in mdump mode" << endl; + cout << endl; + cout << " " << "mesh name is mandatory. Try mdump if necessary" << endl; + cout << " " << "values for interlace mode are : " << endl; + cout << " " << "MED_FULL_INTERLACE (default value) or MED_NO_INTERLACE" << endl; + exit(-1); +} + +int main (int argc, char ** argv) { + + if (argc < 3) usage(argv[0]); + if (argc > 4) usage(argv[0]); + + string fileName = argv[1]; + string meshName = argv[2]; + + MED_EN::medModeSwitch Mode = MED_EN::MED_FULL_INTERLACE; + if (argc==4) + { + string comp=argv[3]; + if ( comp == "MED_NO_INTERLACE" ) Mode = MED_EN::MED_NO_INTERLACE; + else if ( comp != "MED_FULL_INTERLACE") usage(argv[0]); + } + + + MESH * myMesh= new MESH() ; + myMesh->setName(meshName); + MED_MESH_RDONLY_DRIVER myMeshDriver(fileName,myMesh); + try + { + myMeshDriver.setMeshName(meshName); + myMeshDriver.open(); + } + catch (const exception & ex) + { + MESSAGE_MED("Catch Exception : "); + SCRUTE_MED(ex.what()); + }; + MESSAGE_MED("Open done"); + + try + { + myMeshDriver.read(); + } + catch (const exception & ex) + { + MESSAGE_MED("Catch Exception : "); + SCRUTE_MED(ex.what()); + }; + MESSAGE_MED("Read done"); + + int SpaceDimension = myMesh->getSpaceDimension() ; + int MeshDimension = myMesh->getMeshDimension() ; + int NumberOfNodes = myMesh->getNumberOfNodes() ; + + cout << "(************************)"<<endl; + cout << "(* NOEUDS DU MAILLAGE : *)"<<endl; + cout << "(************************)"<<endl; + + string typeRepere = myMesh->getCoordinatesSystem(); + if ( typeRepere.size() == 0 ) typeRepere ="0"; + cout << "- Type de repere des coordonnees : " << typeRepere << endl; + + string chainevide(MED_TAILLE_PNOM+2,' '); + cout << "- Nom des coordonnees : " << endl ; + const string * CoordinatesNames = myMesh->getCoordinatesNames() ; + for (int i=0; i < SpaceDimension ; i++) + { + string bonnelongueur=chainevide; + bonnelongueur.replace(1,CoordinatesNames[i].size(),CoordinatesNames[i]); + cout << bonnelongueur; + } + cout <<endl; + + cout << "- Unites des coordonnees : " << endl ; + const string * CoordinatesUnits = myMesh->getCoordinatesUnits() ; + for ( int i=0; i < SpaceDimension ; i++) + { + string bonnelongueur=chainevide; + bonnelongueur.replace(1,CoordinatesUnits[i].size(),CoordinatesUnits[i]); + cout << bonnelongueur; + } + cout <<endl; + + const double * Coordinates = myMesh->getCoordinates(Mode) ; + cout << "- Coordonnees des noeuds : " << endl; + for (int i=0; i < SpaceDimension*NumberOfNodes; i++) + { + fprintf(stdout," %f ",Coordinates[i]); + } + cout <<endl; + + delete myMesh; + +} diff --git a/src/MEDMEMBinTest/tests/readEntete.cxx b/src/MEDMEMBinTest/tests/readEntete.cxx new file mode 100755 index 000000000..68c0364c1 --- /dev/null +++ b/src/MEDMEMBinTest/tests/readEntete.cxx @@ -0,0 +1,185 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// File : readEntete.cxx +// Module : MED +// +#include<string> +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_define.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_DriversDef.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +void usage(char * name) +{ + cout << " " << name <<" <file name>"<< " <mesh name> " << " <interlace mode>" << endl; + cout << " " << "displays all Nodes Coordinates in mdump mode" << endl; + cout << endl; + cout << " " << "mesh name is mandatory. Try mdump if necessary" << endl; + cout << " " << "values for interlace mode are : " << endl; + cout << " " << "MED_FULL_INTERLACE (default value) or MED_NO_INTERLACE" << endl; + exit(-1); +} + +int main (int argc, char ** argv) { + + if (argc < 3) usage(argv[0]); + if (argc > 4) usage(argv[0]); + + string fileName = argv[1]; + string meshName = argv[2]; + + medModeSwitch Mode = MED_FULL_INTERLACE; + if (argc==4) + { + string comp=argv[3]; + if ( comp == "MED_NO_INTERLACE" ) Mode = MED_NO_INTERLACE; + else if ( comp != "MED_FULL_INTERLACE") usage(argv[0]); + } + + + MESH * myMesh= new MESH() ; + myMesh->setName(meshName); + MED_MESH_RDONLY_DRIVER myMeshDriver(fileName,myMesh); + try + { + myMeshDriver.setMeshName(meshName); + myMeshDriver.open(); + } + catch (const exception & ex) + { + MESSAGE_MED("Catch Exception : "); + SCRUTE_MED(ex.what()); + }; + MESSAGE_MED("Open done"); + + try + { + myMeshDriver.read(); + } + catch (const exception & ex) + { + MESSAGE_MED("Catch Exception : "); + SCRUTE_MED(ex.what()); + }; + MESSAGE_MED("Read done"); + + int SpaceDimension = myMesh->getSpaceDimension(); + int MeshDimension = myMesh->getMeshDimension(); + int NumberOfNodes = myMesh->getNumberOfNodes(); + + cout << "(****************************)" << endl; + cout << "(* INFORMATIONS GENERALES : *)" << endl; + cout << "(****************************)" << endl; + + // string chainevide(MED_TAILLE_PNOM+2,' '); + cout << "- Nom du maillage : <<" << meshName << ">>" << endl; + cout << "- Dimension d'espace : "<< SpaceDimension << endl; + cout << "- Dimension du maillage : "<< MeshDimension << endl; + cout << "- Pas de nom universel " << endl ; + cout << "- Nombre de noeuds : " << NumberOfNodes << " " << endl; + + int NumberOfTypes = myMesh->getNumberOfTypes(MED_CELL); + const medGeometryElement * Types; + + cout << "- Nombre de Type de mailles : " << NumberOfTypes << endl; + + if (NumberOfTypes > 0) + { + Types = myMesh->getTypes(MED_CELL); + + cout << " Types : "; + for (int itype=0; itype<NumberOfTypes; itype++) cout << Types[itype] << " "; + cout << endl; + + const list<medGeometryElement> currentEntity = meshEntities[MED_CELL]; + list<medGeometryElement>::const_iterator currentGeometry; + + for (currentGeometry = currentEntity.begin(); + currentGeometry != currentEntity.end(); + currentGeometry++) + { + cout << "- Nombre de mailles de type "; + cout << geoNames[(*currentGeometry)] << " : "; + cout << myMesh->getNumberOfElements(MED_CELL,(MED_EN::medGeometryElement)(*currentGeometry)); + cout << " " << endl; + } + } + + NumberOfTypes = myMesh->getNumberOfTypes(MED_FACE); + + cout << "- Nombre de Type de faces : " << NumberOfTypes << endl; + + if (NumberOfTypes > 0) + { + Types = myMesh->getTypes(MED_FACE); + + cout << " Types : "; + for (int itype=0; itype<NumberOfTypes; itype++) cout << Types[itype] << " "; + cout << endl; + + const list<medGeometryElement> currentEntity2 = meshEntities[MED_FACE]; + list<medGeometryElement>::const_iterator currentGeometry; + + for (currentGeometry = currentEntity2.begin(); + currentGeometry != currentEntity2.end(); + currentGeometry++) + { + cout << "- Nombre de faces de type "; + cout << geoNames[(*currentGeometry)] << " : "; + cout << myMesh->getNumberOfElements(MED_FACE,(*currentGeometry)); + cout << " " << endl; + } + } + + NumberOfTypes = myMesh->getNumberOfTypes(MED_EDGE); + + cout << "- Nombre de Type de aretes : " << NumberOfTypes << endl; + + if (NumberOfTypes > 0) + { + Types = myMesh->getTypes(MED_EDGE); + + cout << " Types : "; + for (int itype=0; itype<NumberOfTypes; itype++) cout << Types[itype] << " "; + cout << endl; + + const list<medGeometryElement> currentEntity3 = meshEntities[MED_EDGE]; + list<medGeometryElement>::const_iterator currentGeometry; + + for (currentGeometry = currentEntity3.begin(); + currentGeometry != currentEntity3.end(); + currentGeometry++) + { + cout << "- Nombre d'aretes de type "; + cout << geoNames[(*currentGeometry)] << " : "; + cout << myMesh->getNumberOfElements(MED_EDGE,(*currentGeometry)); + cout << " " << endl; + } + } + + delete myMesh; +} diff --git a/src/MEDMEMBinTest/tests/testUArray.cxx b/src/MEDMEMBinTest/tests/testUArray.cxx new file mode 100755 index 000000000..78ea24b64 --- /dev/null +++ b/src/MEDMEMBinTest/tests/testUArray.cxx @@ -0,0 +1,349 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// File : testUArray.cxx +// Module : MED +// +#include <cstdlib> // pour l'acces à EXIT_SUCCESS et EXIT_FAILURE +#include "MEDMEM_Utilities.hxx" +#include "MEDMEM_Array.hxx" + +using namespace std; +using namespace MEDMEM; + +void imprime(string titre,const int * myValues,const int * myOthers, int lignes, int colonnes) +{ + cout << " " <<titre << endl<< endl; + cout << "Full Interlace : " << endl; + if (myValues != NULL) + { + for (int i=0; i<lignes; i++) + { + cout << " - "; + for (int k=0; k< colonnes; k++) + { + cout << myValues[k + i * colonnes]<< " " ; + } + cout << endl; + } + } + else + { + cout << "Pointeur Null : pas de valeur" << endl << endl; + } + cout << endl; + cout << "No Interlace : " << endl; + + if (myOthers != NULL) + { + for (int k=0; k< colonnes; k++) + { + cout << " - "; + for (int i=0; i<lignes; i++) + { + cout << myOthers[i + k*lignes]<< " " ; + } + cout << endl; + } + } + else + { + cout << "Pointeur Null : pas de valeur" << endl << endl; + } + cout << endl; +} + +int main (int argc, char ** argv) +{ + + /* ---------------------------------------------------------- */ + /* */ + /* INITIALISATION */ + /* */ + /* - constructeur new MEDARRAY<int>(int,int,mode) */ + /* - get sur le pointeur MED_FULL_INTERLACE */ + /* - initialisation des valeurs (coordonnées ieme elt = I+1) */ + /* - get sur le pointeur MED_NO_INTERLACE */ + /* ---------------------------------------------------------- */ + + int SpaceDimension = 3; + int NumberOfNodes = 4; + + + + MEDARRAY<int> * myArrayfull= new MEDARRAY<int>(SpaceDimension,NumberOfNodes,MED_EN::MED_FULL_INTERLACE); + ASSERT_MED(myArrayfull != NULL); + + const int * myValues = myArrayfull->get(MED_EN::MED_FULL_INTERLACE); + ASSERT_MED(myValues!= NULL); + + for (int i=0; i<NumberOfNodes; i++) + { + for (int k=0; k<SpaceDimension; k++) + { + //myValues[i* SpaceDimension +k]=i + 1; + myArrayfull->setIJ(i+1,k+1,i+1) ; + } + } + + const int * myOthers = myArrayfull->get(MED_EN::MED_NO_INTERLACE) ; + ASSERT_MED(myOthers != NULL); + + imprime("Initialisation full interlace (xi=yi=zi=i+1)",myValues,myOthers,NumberOfNodes,SpaceDimension); + + MEDARRAY<int> * myArrayno= new MEDARRAY<int>(SpaceDimension,NumberOfNodes,MED_EN::MED_NO_INTERLACE); + ASSERT_MED(myArrayno != NULL); + const int * myValuesno = myArrayno->get(MED_EN::MED_NO_INTERLACE); + ASSERT_MED(myValuesno!= NULL); + + for (int k=0; k<SpaceDimension; k++) + { + for (int i=0; i<NumberOfNodes; i++) + { + //myValuesno[i +k*NumberOfNodes]=k + 1; + myArrayno->setIJ(i+1,k+1,k+1) ; + } + } + + const int * myOthersno = myArrayno->get(MED_EN::MED_FULL_INTERLACE) ; + ASSERT_MED(myOthersno != NULL); + + imprime("Initialisation no interlace (xi=yi=zi=i+1)",myOthersno,myValuesno,NumberOfNodes,SpaceDimension); + + + /* ---------------------------------------------------------- */ + /* */ + /* Tests des Fonctions Set */ + /* */ + /* - setI sur l'element 1 avec des coordonnees a 100 */ + /* - setJ sur l'element 1 avec des coordonnees a 100 */ + /* - setIJ sur (1,2) avec une coordonnee = 1992 */ + /* - set avec l ensemble des coordonnes remises à i */ + /* ---------------------------------------------------------- */ + + + int * myNewLine = new int[SpaceDimension]; + for (int i = 0; i < SpaceDimension; i++) + myNewLine[i] = myValues[i] * 100; + try + { + myArrayfull->setI(1, myNewLine); + } + catch ( const std::exception &e ) + { + cout << "--------------" << endl; + cout << " Pb au setI " << endl; + cout << "--------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "---------------" << endl; + cout << " Pb au setI " << endl; + cout << "---------------" << endl; + } + + delete [] myNewLine; + imprime("1er element : coordonnees à 100",myValues,myOthers,NumberOfNodes,SpaceDimension); + + int * myNewCol = new int[NumberOfNodes]; + for (int i = 0; i < NumberOfNodes; i++) + myNewCol[i] = 100; + try + { + myArrayno->setJ(1, myNewCol); + } + catch ( const std::exception &e ) + { + cout << "--------------" << endl; + cout << " Pb au setJ " << endl; + cout << "--------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "---------------" << endl; + cout << " Pb au setJ " << endl; + cout << "---------------" << endl; + } + + delete [] myNewCol; + imprime("1eres coordonnees à 100",myOthersno,myValuesno,NumberOfNodes,SpaceDimension); + + try + { + myArrayfull->setIJ(1,2,1992); + } + catch ( const std::exception &e ) + { + cout << "---------------------------" << endl; + cout << " Pb au setIJ() de 1 , 2 " << endl; + cout << "---------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-----------------------------" << endl; + cout << " Pb au setIJ() de 1 , 2 " << endl; + cout << "-----------------------------" << endl; + } + + imprime("1er element : 2ieme coordonnee = 1992",myValues,myOthers,NumberOfNodes,SpaceDimension); + + + try + { + myArrayno->setIJ(1,2,1992); + } + catch ( const std::exception &e ) + { + cout << "---------------------------" << endl; + cout << " Pb au setIJ() de 1 , 2 " << endl; + cout << "---------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-----------------------------" << endl; + cout << " Pb au setIJ() de 1 , 2 " << endl; + cout << "-----------------------------" << endl; + } + + imprime("1er element : 2ieme coordonnee = 1992",myValues,myOthers,NumberOfNodes,SpaceDimension); + + int * mynewvalues= new int [ NumberOfNodes*SpaceDimension ]; + for (int i=0; i<NumberOfNodes*SpaceDimension; i++) + { + mynewvalues[i]=i; + } + try + { + myArrayfull->set(MED_EN::MED_FULL_INTERLACE,mynewvalues); + myValues = myArrayfull->get(MED_EN::MED_FULL_INTERLACE); + myOthers = myArrayfull->get(MED_EN::MED_NO_INTERLACE); + } + catch ( const std::exception &e ) + { + cout << "-------------" << endl; + cout << " Pb au set " << endl; + cout << "-------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "--------------" << endl; + cout << " Pb au set " << endl; + cout << "--------------" << endl; + } + imprime("remise valeur a i sur myArrayfull med full interlace",myValues,myOthers,NumberOfNodes,SpaceDimension); + + try + { + myArrayno->set(MED_EN::MED_FULL_INTERLACE,mynewvalues); + myValuesno = myArrayfull->get(MED_EN::MED_FULL_INTERLACE); + myOthersno = NULL; + } + catch ( const std::exception &e ) + { + cout << "-------------" << endl; + cout << " Pb au set " << endl; + cout << "-------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "--------------" << endl; + cout << " Pb au setI " << endl; + cout << "--------------" << endl; + } + imprime("set full interlace de myArrayno",myValuesno,myOthersno,NumberOfNodes,SpaceDimension); + + /* ---------------------------------------------------------- */ + /* */ + /* Tests des constructeurs */ + /* Tests des Fonctions Get */ + /* */ + /* */ + /* ---------------------------------------------------------- */ + + MEDARRAY<int> * myArrayShare = new MEDARRAY<int>( *myArrayfull); + const int * sharevalues = myArrayShare->get(MED_EN::MED_FULL_INTERLACE ); + const int * shareno = myArrayShare->get(MED_EN::MED_NO_INTERLACE); + imprime("test contructeur par recopie non profonde",sharevalues,shareno,NumberOfNodes,SpaceDimension); + + myArrayfull->setIJ(1,2,1992); + ASSERT_MED(myArrayShare->getIJ(1,2) == 1992); + imprime("change valeur tableau source, impression tableau cible",sharevalues,shareno,NumberOfNodes,SpaceDimension); + + myArrayShare->setIJ(1,2,1995); + ASSERT_MED(myArrayfull->getIJ(1,2) == 1995); + imprime("change valeur tableau cible, impression tableau source",myValues,myOthers,NumberOfNodes,SpaceDimension); + + delete myArrayShare; + imprime("tableau cible apres destruction tableau source",myValues,myOthers,NumberOfNodes,SpaceDimension); + + MEDARRAY<int> * myArrayShare2 = new MEDARRAY<int>( *myArrayfull,true); + sharevalues = myArrayShare2->get(MED_EN::MED_FULL_INTERLACE ); + shareno = myArrayShare2->get(MED_EN::MED_NO_INTERLACE ); + imprime("test contructeur par recopie profonde",sharevalues,shareno,NumberOfNodes,SpaceDimension); + + myArrayfull->setIJ(1,2,18); + imprime("change valeur tableau source, impression tableau cible",sharevalues,shareno,NumberOfNodes,SpaceDimension); + + myArrayShare2->setIJ(1,2,19); + imprime("change valeur tableau cible, impression tableau source",myValues,myOthers,NumberOfNodes,SpaceDimension); + + myArrayno->set(MED_EN::MED_NO_INTERLACE,mynewvalues); + myArrayno->setIJ(2,1,1); + myValuesno = myArrayno->get(MED_EN::MED_NO_INTERLACE); + myOthersno = myArrayno->get(MED_EN::MED_FULL_INTERLACE); + imprime("Initialisation no interlace (0...11)",myOthersno,myValuesno,NumberOfNodes,SpaceDimension); + + MEDARRAY<int> * myArrayShare3 = new MEDARRAY<int>( *myArrayno); + sharevalues = myArrayShare3->get(MED_EN::MED_FULL_INTERLACE); + shareno = myArrayShare3->get(MED_EN::MED_NO_INTERLACE); + imprime("test contructeur par recopie non profonde",sharevalues,shareno,NumberOfNodes,SpaceDimension); + + myArrayno->setIJ(1,2,1992); + ASSERT_MED(myArrayShare3->getIJ(1,2) == 1992); + imprime("change valeur tableau source, impression tableau cible",sharevalues,shareno,NumberOfNodes,SpaceDimension); + + myArrayShare3->setIJ(1,2,1995); + ASSERT_MED(myArrayno->getIJ(1,2) == 1995); + imprime("change valeur tableau cible, impression tableau source",myValuesno,myOthersno,NumberOfNodes,SpaceDimension); + + delete myArrayno; + delete [] mynewvalues; + delete myArrayfull; + delete myArrayShare2; + delete myArrayShare3; + MESSAGE_MED("FIN NORMALE DU TRAITEMENT"); + return EXIT_SUCCESS ; +} +/* + inline medModeSwitch getMode() const ; +*/ diff --git a/src/MEDMEMBinTest/tests/testUArray.cxx.ok b/src/MEDMEMBinTest/tests/testUArray.cxx.ok new file mode 100755 index 000000000..ec26ccafa --- /dev/null +++ b/src/MEDMEMBinTest/tests/testUArray.cxx.ok @@ -0,0 +1,313 @@ +#include <cstdlib> // pour l'acces à EXIT_SUCCESS et EXIT_FAILURE +#include "MEDMEM_Utilities.hxx" +#include "MEDMEM_Array.hxx" +using namespace MEDMEM; + +int main (int argc, char ** argv) +{ + + int SpaceDimension = 3; + int NumberOfNodes = 4; + MEDARRAY<int> * myArray = new MEDARRAY<int>(SpaceDimension,NumberOfNodes,MED_FULL_INTERLACE) ; + ASSERT(myArray != NULL); + + int * value = myArray->get(MED_FULL_INTERLACE) ; + ASSERT(value!= NULL); + + for (int i=0; i<SpaceDimension*NumberOfNodes; i++) + value[i]=i ; + + int leadingValue; + try + { + leadingValue = myArray->getLeadingValue() ; + ASSERT (leadingValue == SpaceDimension); + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au getLeadingValue() " << endl; + cout << "-------------------------------" << endl; + MESSAGE( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------------------" << endl; + cout << " Pb au getLeadingValue() " << endl; + cout << "-------------------------------" << endl; + return EXIT_FAILURE ; + } + + int lengthValue; + try + { + lengthValue = myArray->getLengthValue() ; + ASSERT(lengthValue == NumberOfNodes) + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au getLengthValue() " << endl; + cout << "-------------------------------" << endl; + MESSAGE( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------------------" << endl; + cout << " Pb au getLengthValue() " << endl; + cout << "-------------------------------" << endl; + return EXIT_FAILURE ; + } + + cout << "Show all using getI and full interlace :" << endl; + for (int i=1; i<=lengthValue; i++) + { + try + { + int * node = myArray->getI(MED_FULL_INTERLACE,i) ; + cout << " - " ; + for (int j=0;j<leadingValue;j++) + cout << node[j] << " " ; + cout << endl ; + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au getI() valeur de i " << i << endl; + cout << "-------------------------------" << endl; + MESSAGE( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------------------" << endl; + cout << " Pb au getI() valeur de i " << i << endl; + cout << "-------------------------------" << endl; + return EXIT_FAILURE ; + } + } + + cout << "Show all using getI and no interlace :" << endl; + for (int i=1; i<=leadingValue; i++) + { + try + { + int * node = myArray->getI(MED_NO_INTERLACE,i) ; + cout << " - " ; + for (int j=0;j<lengthValue;j++) + cout << node[j] << " " ; + cout << endl ; + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au getI() valeur de i " << i << endl; + cout << "-------------------------------" << endl; + MESSAGE( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------------------" << endl; + cout << " Pb au getI() valeur de i " << i << endl; + cout << "-------------------------------" << endl; + return EXIT_FAILURE ; + } + } + + cout << "Show all using getIJ :" << endl; + for (int i=1; i<=lengthValue ; i++) + { + int j; + try + { + cout << " - " ; + for (j=1;j<leadingValue+1;j++) + cout << myArray->getIJ(i,j) << " " ; + cout << endl ; + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au getIJ() i " << i << " j " << j << endl; + cout << "-------------------------------" << endl; + MESSAGE( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------------------" << endl; + cout << " Pb au getIJ() i " << i << " j " << j << endl; + cout << "-------------------------------" << endl; + return EXIT_FAILURE ; + } + } + + cout << "Show all using get and MED_NO_INTERLACE :" << endl; + try + { + int * NoInterlaceArray = myArray->get(MED_NO_INTERLACE) ; + for (int i=0; i<lengthValue ; i++) + { + cout << " - " ; + for (int j=0;j<leadingValue;j++) + cout << NoInterlaceArray[j*lengthValue+i] << " " ; + cout << endl ; + } + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au get " << endl; + cout << "-------------------------------" << endl; + MESSAGE( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "---------------" << endl; + cout << " Pb au get " << endl; + cout << "---------------" << endl; + return EXIT_FAILURE ; + } + + + cout << endl << endl << "Tests des fonctions Set " << endl; + + int * myNewInt = new int[SpaceDimension*NumberOfNodes]; + for (int i=0; i<SpaceDimension*NumberOfNodes; i++) + { + myNewInt[i]=i*10 ; + } + + try + { + myArray->set(MED_FULL_INTERLACE, myNewInt); + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au set " << endl; + cout << "-------------------------------" << endl; + MESSAGE( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "---------------" << endl; + cout << " Pb au set " << endl; + cout << "---------------" << endl; + return EXIT_FAILURE ; + } + delete [] myNewInt; + + cout << "Nouvelles valeurs (x10) : get avec Full interlace : " << endl; + int * myNewValue; + try + { + myNewValue = myArray->get(MED_FULL_INTERLACE) ; + ASSERT(myNewValue!= NULL); + } + catch ( const std::exception &e ) + { + cout << "-----------------" << endl; + cout << " Pb au get " << endl; + cout << "-----------------" << endl; + MESSAGE( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "---------------" << endl; + cout << " Pb au get " << endl; + cout << "---------------" << endl; + } + + cout << " - "; + for (int i=0; i<SpaceDimension*NumberOfNodes; i++) + cout << myNewValue[i]<< " " ; + cout << endl; + + + int * myNewLine = new int[SpaceDimension]; + for (int i = 0; i < SpaceDimension; i++) + myNewLine[i] = i * 100; + + try + { + myArray->setI(MED_FULL_INTERLACE, 1, myNewLine); + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au getLengthValue() " << endl; + cout << "-------------------------------" << endl; + MESSAGE( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "---------------" << endl; + cout << " Pb au setI " << endl; + cout << "---------------" << endl; + } + delete [] myNewLine; + + try + { + myNewValue = myArray->getI(MED_FULL_INTERLACE,1) ; + ASSERT(myNewValue!= NULL); + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au getLengthValue() " << endl; + cout << "-------------------------------" << endl; + MESSAGE( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "---------------" << endl; + cout << " Pb au getI " << endl; + cout << "---------------" << endl; + } + + cout << endl << " Nouvelles valeurs (x100) sur la 1ere ligne: get avec Full interlace : "; + cout << endl << " - "; + for (int i=0; i<SpaceDimension; i++) + cout << myNewValue[i]<< " " ; + cout << endl; + + try + { + myArray->setIJ(1,1,1992); + } + catch ( const std::exception &e ) + { + cout << "---------------------------" << endl; + cout << " Pb au setIJ() de 1 , 1 " << endl; + cout << "---------------------------" << endl; + MESSAGE( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-----------------------------" << endl; + cout << " Pb au setIJ() de 1 , 1 " << endl; + cout << "-----------------------------" << endl; + } + + cout << "Nouvelle valeur avec setIJ et getIJ" << endl; + cout << " - " << myArray->getIJ(1,1) << endl; + + delete myArray; + return EXIT_SUCCESS ; +} + +/* + inline medModeSwitch getMode() const ; + +*/ diff --git a/src/MEDMEMBinTest/tests/testUCellModel.cxx b/src/MEDMEMBinTest/tests/testUCellModel.cxx new file mode 100755 index 000000000..d9d1d97cc --- /dev/null +++ b/src/MEDMEMBinTest/tests/testUCellModel.cxx @@ -0,0 +1,372 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// File : testUCellModel.cxx +// Module : MED +// +#include <set> +#include <cstdlib> +#include "MEDMEM_Utilities.hxx" + +#include "MEDMEM_CellModel.hxx" +#include "MEDMEM_define.hxx" +#include "MEDMEM_DriversDef.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +#define MED_NBR_GEOMETRIE_MAILLE 15 + +void usage(char * name) +{ + cout << " " << name << endl; +} + +int main (int argc, char ** argv) +{ + + if (argc < 1) usage(argv[0]); + + + cout << "CELLMODEL Test" << endl ; + cout << "--------------" << endl; + + /* ----------------------------------------------------- + Construction de tous les types de cellmodel possibles + ----------------------------------------------------- + */ + + CELLMODEL * tous =new CELLMODEL[MED_NBR_GEOMETRIE_MAILLE ]; + const medGeometryElement allCellType[MED_NBR_GEOMETRIE_MAILLE ]= + {MED_POINT1, MED_SEG2, MED_SEG3, MED_TRIA3, + MED_QUAD4, MED_TRIA6, MED_QUAD8, MED_TETRA4, + MED_PYRA5, MED_PENTA6, MED_HEXA8, MED_TETRA10, + MED_PYRA13, MED_PENTA15, MED_HEXA20 }; + + for (int i=0; i<MED_NBR_GEOMETRIE_MAILLE ; i++) + { + tous[i]=CELLMODEL(allCellType[i]); + } + + /* ----------------------------------------------------- + Boucle sur tous les types de cellmodel possibles + - Chaque Méthode de cellmodel est appelee + ----------------------------------------------------- + */ + for (int i=0; i<MED_NBR_GEOMETRIE_MAILLE ; i++) + { + cout << endl; + cout << geoNames[tous[i].getType()] << endl; + cout << "__________________" << endl; + + try + { + cout << "CellModel de Nom : " << tous[i].getName() << endl; + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au getName() " << endl; + cout << "-------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------------------" << endl; + cout << " Pb au getName() " << endl; + cout << "-------------------------------" << endl; + return EXIT_FAILURE ; + }; + + try + { + cout << "Nb de Vertexes : " << tous[i].getNumberOfVertexes() << endl; + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au getNumberOfVertexes() " << endl; + cout << "-------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "---------------------------------------" << endl; + cout << " Pb au getNumberOfVertexes() " << endl; + cout << "---------------------------------------" << endl; + return EXIT_FAILURE ; + }; + + try + { + cout << "Nb de Noeuds : " << tous[i].getNumberOfNodes() << endl; + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au getNumberOfNodes() " << endl; + cout << "-------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "---------------------------------" << endl; + cout << " Pb au getNumberOfNodes() " << endl; + cout << "---------------------------------" << endl; + return EXIT_FAILURE ; + }; + + int dimension; + try + { + dimension=tous[i].getDimension(); + cout << "Dimension : " << dimension << endl; + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au getDimension() " << endl; + cout << "-------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------------------" << endl; + cout << " Pb au getDimension() " << endl; + cout << "-------------------------------" << endl; + return EXIT_FAILURE ; + } + + for (int dim=1; dim< dimension; dim++) + { + int dim2=dimension - dim; + cout << "Nb d elements de dimension " << dim << " : "; + + try + { + cout << tous[i].getNumberOfConstituents(dim)<< endl; + } + catch ( const std::exception &e ) + { + cout << "------------------------------------" << endl; + cout << " Pb au getNumberOfConstituents() " << endl; + cout << "------------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "------------------------------------" << endl; + cout << " Pb au getNumberOfConstituents() " << endl; + cout << "------------------------------------" << endl; + return EXIT_FAILURE ; + }; + } +/* + + try + { + int** v1=tous[i].getConstituents(dim2); + if ( v1.size() != tous[i].getNumberOfConstituents(dim2) ) + { + cout << "----------------------------" << endl; + cout << " Pb au getConstituents() " << endl; + cout << "----------------------------" << endl; + } + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au getConstituents() " << endl; + cout << "-------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "----------------------------" << endl; + cout << " Pb au getConstituents() " << endl; + cout << "----------------------------" << endl; + return EXIT_FAILURE ; + }; + + cout << "Types de ces elements " << endl; + + set <medGeometryElement> setGeomElt; + medGeometryElement * vt; + int taille; + try + { + vt=tous[i].getConstituentsType(dim2); + taille=tous[i].getNumberOfConstituents(dim2); + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au getConstituentsType() " << endl; + cout << "-------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "--------------------------------" << endl; + cout << " Pb au getConstituentsType() " << endl; + cout << "--------------------------------" << endl; + return EXIT_FAILURE ; + }; + for (int k=0; k<taille;k++) + { + try + { + medGeometryElement me=tous[i].getConstituentType(dim2,k+1); + if ( vt[k] != me ) + { + cout << "-------------------------------" << endl; + cout << " Pb au getConstituentType() " << endl; + cout << "-------------------------------" << endl; + } + setGeomElt.insert(me); + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au getConstituentType() " << endl; + cout << "-------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "--------------------------------" << endl; + cout << " Pb au getConstituentsType() " << endl; + cout << "--------------------------------" << endl; + return EXIT_FAILURE ; + } + } +*/ +/* + set <medGeometryElement>::iterator iter_s; + for (iter_s=setGeomElt.begin() ;iter_s!=setGeomElt.end();iter_s++) + { + cout << geoNames[(*iter_s)] << endl; + } + + cout << "Impression des coordonnées du 1er Element de ce type" << endl; + try + { + vector<int> v2=tous[i].getNodesConstituent(dim2,1); + for (int k=0; k<v2.size();k++) + { + cout << v2[k] << " "; + try + { + int verif=tous[i].getNodeConstituent(dim2,1,k+1); + if ( v2[k] != verif) + { + cout << "-------------------------------" << endl; + cout << " Pb au getNodeConstituent() " << endl; + cout << "-------------------------------" << endl; + } + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au getNodeConstituent() " << endl; + cout << "-------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------------------" << endl; + cout << " Pb au getNodeConstituent() " << endl; + cout << "-------------------------------" << endl; + return EXIT_FAILURE ; + } + } + cout << endl; + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au getNodeConstituent() " << endl; + cout << "-------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "--------------------------------" << endl; + cout << " Pb au getNodeConstituent() " << endl; + cout << "--------------------------------" << endl; + return EXIT_FAILURE ; + } +*/ + + cout << endl; +/* + if ( dimension > 1 ) + { + try + { + cout << "Informations particulieres - dimension " << dimension - 1 << endl; + set <medGeometryElement>::iterator iter_s; + for (iter_s=tous[i].getAllConstituentsType().begin() ; + iter_s!=tous[i].getAllConstituentsType().end();iter_s++) + { + cout << geoNames[*iter_s] << endl; + } + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << " Pb au getAllConstituentsType() " << endl; + cout << "-------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "------------------------------------" << endl; + cout << " Pb au getAllConstituentsType() " << endl; + cout << "------------------------------------" << endl; + return EXIT_FAILURE ; + } + } +*/ + + } + + delete[] tous ; + + return EXIT_SUCCESS ; +/* + Reste a Tester + // Return number of constituents foreach type (which dimension is _dimension-1). + map <medGeometryElement,int> getNumberOfConstituentsForeachType() const; +*/ +} diff --git a/src/MEDMEMBinTest/tests/testUCoordinate.cxx b/src/MEDMEMBinTest/tests/testUCoordinate.cxx new file mode 100755 index 000000000..7c775eec9 --- /dev/null +++ b/src/MEDMEMBinTest/tests/testUCoordinate.cxx @@ -0,0 +1,402 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// File : testUCoordinate.cxx +// Module : MED +// +#include <cstdlib> +#include <cmath> +#include "MEDMEM_Utilities.hxx" + +#include "MEDMEM_define.hxx" +#include "MEDMEM_Array.hxx" +#include "MEDMEM_Coordinate.hxx" +#include <string> + +using namespace std; +using namespace MEDMEM; + +void usage(char * name) +{ + cout << " " << name << endl; +} + +int main (int argc, char ** argv) +{ + + + if (argc < 1) usage(argv[0]); + + const double pouieme = 0.009; + + cout << "COORDINATE Test" << endl; + cout << "---------------" << endl; + + int SpaceDim = 3; + int NbOfNodes = 5; + + string * noms = new string[3]; + noms[0]=" X "; + noms[1]=" Y "; + noms[2]=" Z "; + + string units[3]; + units[0]=" m "; + units[1]=" m "; + units[2]=" m "; + + int * numbers=new int[5]; + for (int i=0; i< 5; i++) numbers[i] =10+i; + + MED_EN::medModeSwitch ModeFull=MED_EN::MED_FULL_INTERLACE; + MED_EN::medModeSwitch ModeNo=MED_EN::MED_NO_INTERLACE; + double coor[15] = {0,0,0,0,0,1,0,1,0,1,0,0,0.5,0.5,0.5} ; + ASSERT_MED(SpaceDim*NbOfNodes == 15); + + + cout << " - mode : MED_FULL_INTERLACE" << endl; + cout << " - dimension de l espace : " << SpaceDim << endl; + cout << " - nombre de noeuds : " << NbOfNodes << endl; + + double * coor1 = new double[SpaceDim*NbOfNodes]; + for( int k=0 ; k<SpaceDim*NbOfNodes ; k++ ) + coor1[k] = coor[k] ; + + MEDARRAY<double>* CoordinateArray = new MEDARRAY<double>(coor1,SpaceDim,NbOfNodes,ModeFull); + COORDINATE mycoo; + try + { + mycoo.setCoordinates(CoordinateArray); + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << "pb avec setCoordinates" << endl; + cout << "-------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------------------" << endl; + cout << "pb avec setCoordinates" << endl; + cout << "-------------------------------" << endl; + return EXIT_FAILURE ; + }; + + //--------------------------------------------------------------------// + // Tests des methodes // + // // + // - setCoordinatesNames // + // - setCoordinatesUnits // + // - setCoordinatesSystem // + // - setNodesNumbers // + // // + //--------------------------------------------------------------------// + try + { + mycoo.setCoordinatesNames(noms); + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << "pb avec setCoordinatesNames" << endl; + cout << "-------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------------------" << endl; + cout << "pb avec setCoordinatesNames" << endl; + cout << "-------------------------------" << endl; + return EXIT_FAILURE ; + }; + + try + { + mycoo.setCoordinatesUnits(units); + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << "pb avec setCoordinatesUnits" << endl; + cout << "-------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------------------" << endl; + cout << "pb avec setCoordinatesUnits" << endl; + cout << "-------------------------------" << endl; + return EXIT_FAILURE ; + }; + + try + { + mycoo.setCoordinatesSystem("cartesien"); + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << "pb avec setCoordinatesSystem" << endl; + cout << "-------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------------------" << endl; + cout << "pb avec setCoordinatesSystem" << endl; + cout << "-------------------------------" << endl; + return EXIT_FAILURE ; + }; + + try + { + mycoo.setNodesNumbers(numbers); + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << "pb avec setNodesNumbers" << endl; + cout << "-------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------------------" << endl; + cout << "pb avec setNodesNumbers" << endl; + cout << "-------------------------------" << endl; + return EXIT_FAILURE ; + }; + + //--------------------------------------------------------------------// + // Tests des methodes // + // // + // - getCoordinatesNames // + // - getCoordinatesUnits // + // - getCoordinatesUnit // + // - getCoordinatesSystem // + // - getNodesNumbers // + // // + //--------------------------------------------------------------------// + + cout << endl << " Relecture des Coordonnees" << endl << endl; + + try + { + cout << " Le systeme est : " << mycoo.getCoordinatesSystem() << endl; + } + catch ( const std::exception &e ) + { + cout << "-------------------------------" << endl; + cout << "pb avec getCoordinatesSystem" << endl; + cout << "-------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------------------" << endl; + cout << "pb avec getCoordinatesSystem" << endl; + cout << "-------------------------------" << endl; + return EXIT_FAILURE ; + }; + + const string * units2; + try + { + units2=mycoo.getCoordinatesUnits(); + for (int axe = 0; axe < SpaceDim; axe++) + { + try + { + string verif = mycoo.getCoordinateUnit(axe+1); + if (verif != units2[axe]) + cout << "Pb avec les noms des axes" << endl; + } + catch ( const std::exception &e ) + { + cout << "-------------------------" << endl; + cout << "pb avec getCoordinateUnit" << endl; + cout << "-------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------------" << endl; + cout << "pb avec getCoordinateUnit" << endl; + cout << "-------------------------" << endl; + return EXIT_FAILURE ; + }; + } + } + catch ( const std::exception &e ) + { + cout << "---------------------------" << endl; + cout << "pb avec getCoordinatesUnits" << endl; + cout << "---------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "---------------------------" << endl; + cout << "pb avec getCoordinatesUnits" << endl; + cout << "---------------------------" << endl; + return EXIT_FAILURE ; + }; + + const string * noms2; + try + { + noms2=mycoo.getCoordinatesNames(); + for (int axe = 0; axe < SpaceDim; axe++) + { + try + { + string verif = mycoo.getCoordinateName(axe+1); + if (verif != noms2[axe]) + cout << "Pb avec les noms des axes" << endl; + } + catch ( const std::exception &e ) + { + cout << "-------------------------" << endl; + cout << "pb avec getCoordinateName" << endl; + cout << "-------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------------" << endl; + cout << "pb avec getCoordinateName" << endl; + cout << "-------------------------" << endl; + return EXIT_FAILURE ; + }; + } + } + catch ( const std::exception &e ) + { + cout << "---------------------------" << endl; + cout << "pb avec getCoordinatesNames" << endl; + cout << "---------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "---------------------------" << endl; + cout << "pb avec getCoordinatesNames" << endl; + cout << "---------------------------" << endl; + return EXIT_FAILURE ; + }; + + + try + { + const double * coor2=mycoo.getCoordinates(ModeFull); + + for (int axe = 0; axe < SpaceDim; axe++) + { + + cout << "Coordonnees sur l'Axe : " << noms2[axe] ; + cout << " dont l unite est " << units2[axe] << endl; + + try + { + const double * coor3=mycoo.getCoordinateAxis(axe+1); + for (int num=0; num < NbOfNodes; num++) + { + try + { + const double d = mycoo.getCoordinate(num + 1,axe+1); + cout << d <<" , "; + ASSERT_MED(fabs(d - coor3[num]) < pouieme); + ASSERT_MED(fabs(d - coor2[(num * SpaceDim)+axe]) < pouieme); + ASSERT_MED(fabs(d - coor [(num * SpaceDim)+axe]) < pouieme); + } + catch ( const std::exception &e ) + { + cout << "----------------------" << endl; + cout << "pb avec getCoordinates" << endl; + cout << "----------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "----------------------" << endl; + cout << "pb avec getCoordinates" << endl; + cout << "----------------------" << endl; + return EXIT_FAILURE ; + }; + } + cout << endl; + } + catch ( const std::exception &e ) + { + cout << "-------------------------" << endl; + cout << "pb avec getCoordinateAxis" << endl; + cout << "-------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------------" << endl; + cout << "pb avec getCoordinateAxis" << endl; + cout << "-------------------------" << endl; + return EXIT_FAILURE ; + } + } + } + catch ( const std::exception &e ) + { + cout << "----------------------" << endl; + cout << "pb avec getCoordinates" << endl; + cout << "----------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "----------------------" << endl; + cout << "pb avec getCoordinates" << endl; + cout << "----------------------" << endl; + return EXIT_FAILURE ; + }; + + + delete [] noms ; + delete [] numbers; + delete [] coor1; + + delete CoordinateArray ; + + MESSAGE_MED("FIN normale du traitement"); + return EXIT_SUCCESS ; +} + diff --git a/src/MEDMEMBinTest/tests/testUGeoNameMeshEntities.cxx b/src/MEDMEMBinTest/tests/testUGeoNameMeshEntities.cxx new file mode 100755 index 000000000..4e2d7e4b8 --- /dev/null +++ b/src/MEDMEMBinTest/tests/testUGeoNameMeshEntities.cxx @@ -0,0 +1,74 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// File : testUGeoNameMeshEntities.cxx +// Module : MED +// +#include "MEDMEM_DriversDef.hxx" + +using namespace std; +void usage(char * name) +{ + cout << " " << name << endl; + cout << " " << "displays all avalaible geometry elements" << endl; + cout << " " << "display then all avalaible entities, and for each" << endl; + cout << " " << "all possible geomety element" << endl; + cout << endl; + exit(-1); +} + +int main (int argc, char ** argv) +{ + + if (argc < 1) usage(argv[0]); + + + cout << "GEO_NAME Test" << endl ; + cout << "-------------" << endl << endl; + MED_EN::GEO_NAME::const_iterator currentGeom; + for (currentGeom = MED_EN::geoNames.begin(); + currentGeom != MED_EN::geoNames.end(); + currentGeom++) + { + cout << (*currentGeom).second << endl; + }; + + MED_EN::MESH_ENTITIES::const_iterator currentEntity; + list<MED_EN::medGeometryElement>::const_iterator currentGeometry; + + cout << endl; + cout << "MESH_ENTITIES Test" << endl ; + cout << "------------------" << endl << endl; + for (currentEntity = MED_EN::meshEntities.begin(); + currentEntity != MED_EN::meshEntities.end(); + currentEntity++) + { + cout << (*((MED_EN::entNames).find((*currentEntity).first))).second <<endl; + for (currentGeometry = (*currentEntity).second.begin(); + currentGeometry != (*currentEntity).second.end(); + currentGeometry++) + { + cout << MED_EN::geoNames[(MED_EN::medGeometryElement)(*currentGeometry)] << endl; + } + cout << endl; + } + +} diff --git a/src/MEDMEMBinTest/tests/testUMedException.cxx b/src/MEDMEMBinTest/tests/testUMedException.cxx new file mode 100644 index 000000000..49c0091b0 --- /dev/null +++ b/src/MEDMEMBinTest/tests/testUMedException.cxx @@ -0,0 +1,55 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// File : testUMedException.cxx +// Module : MED +// +#include <cstdlib> +#include "MEDMEM_STRING.hxx" +#include "MEDMEM_Exception.hxx" + +using namespace std; +using namespace MEDMEM; + +int main (int argc, char ** argv) +{ + MEDEXCEPTION a = MEDEXCEPTION("test med exception"); + cout << a << endl;; + cout << a.what() << endl;; + + MEDEXCEPTION b(a); + cout << b << endl; + cout << b.what() << endl;; + + MEDEXCEPTION c("test med exception",argv[0],14); + cout << c << endl; + cout << c.what() << endl;; + + STRING msgErr; + msgErr << "ESSAI::ESSAI()! "<< 4 << "ieme essai "; + cout << MEDEXCEPTION (LOCALIZED(msgErr)).what() << endl ; + + const char * LOC = "toto" ; + cout << MEDEXCEPTION (LOCALIZED(STRING(LOC)<<" et titi")).what() << endl ; + + return EXIT_SUCCESS; + +}; diff --git a/src/MEDMEMBinTest/tests/testUModulusArray.cxx b/src/MEDMEMBinTest/tests/testUModulusArray.cxx new file mode 100644 index 000000000..faabc0025 --- /dev/null +++ b/src/MEDMEMBinTest/tests/testUModulusArray.cxx @@ -0,0 +1,426 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// File : testUModulusArray.cxx +// Module : MED +// +#include <cstdlib> +#include <exception> +#include "MEDMEM_Utilities.hxx" +#include "MEDMEM_ModulusArray.hxx" +using namespace std; +using namespace MEDMEM; + +int main (int argc, char ** argv) +{ + + using namespace std ; + + int array[5]={0,1,2,1,4} ; + MEDMODULUSARRAY modulusArray(5,array); + + cout << " ModulusArray : " << endl; + cout << " _______________" << endl; + for(int i=-10;i<15;i++) + { + cout <<" - A[" << i <<"]="<<modulusArray[i]<<endl; + } + cout << endl; + + // ------------ + // test compare + // ------------ + + int ret ; + int array2[5]={1,4,0,1,2} ; + MEDMODULUSARRAY modulusArray2(5,array2) ; + + cout << " Test compare : mêmes tableaux mêmes ordres ..." << endl; + + try + { + ret=modulusArray2.compare(modulusArray); + } + catch ( const std::exception &e ) + { + cout << "-----------------" << endl; + cout << " pb avec compare " << endl; + cout << "-----------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-----------------" << endl; + cout << " pb avec compare " << endl; + cout << "-----------------" << endl; + return EXIT_FAILURE ; + } + + if (ret!=1) + { + cout << "-----------------------------------------------------" << endl; + cout << " pb avec compare entre modulusArray et modulusArray2 " << endl; + cout << " Les deux tableaux sont identiques " << endl; + cout << "-----------------------------------------------------" << endl; + return EXIT_FAILURE ; + } + else + { + cout << " compare entre modulusArray et modulusArray2 : OK" << endl; + cout << endl; + } + + int array3[5]={1,2,1,0,4} ; + MEDMODULUSARRAY modulusArray3(5,array3) ; + + cout << " Test compare : mêmes tableaux ordres inverses ..." << endl; + + try + { + ret=modulusArray3.compare(modulusArray); + } + catch (const std::exception &e ) + { + cout << "-----------------" << endl; + cout << " pb avec compare " << endl; + cout << "-----------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-----------------" << endl; + cout << " pb avec compare " << endl; + cout << "-----------------" << endl; + return EXIT_FAILURE ; + } + + if (ret!=-1) + { + cout << "-----------------------------------------------------" << endl; + cout << " pb avec compare entre modulusArray et modulusArray3 " << endl; + cout << " Les deux tableaux sont inverses " << endl; + cout << "-----------------------------------------------------" << endl; + return EXIT_FAILURE ; + } + else + { + cout << " compare entre modulusArray et modulusArray3 : OK" << endl; + cout << endl; + } + + int array4[6]={1,2,1,0} ; + MEDMODULUSARRAY modulusArray4(4,array4) ; + + cout << " Test compare : Tableaux de differentes tailles ... " << endl; + try + { + ret=modulusArray4.compare(modulusArray); + } + catch (const std::exception &e ) + { + cout << "-----------------" << endl; + cout << " pb avec compare " << endl; + cout << "-----------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-----------------" << endl; + cout << " pb avec compare " << endl; + cout << "-----------------" << endl; + return EXIT_FAILURE ; + } + + if (ret!=0) + { + cout << "-----------------------------------------------------" << endl; + cout << " pb avec compare entre modulusArray et modulusArray4 " << endl; + cout << " Les deux n ont pas la meme taille " << endl; + cout << "-----------------------------------------------------" << endl; + return EXIT_FAILURE ; + } + else + { + cout << " compare entre modulusArray et modulusArray4 : OK" << endl; + cout << endl; + } + + int array5[5]={1,2,1,0,1} ; + MEDMODULUSARRAY modulusArray5(5,array5) ; + cout << " Test compare : tableaux differents de même taille ..." << endl; + try + { + ret=modulusArray5.compare(modulusArray); + } + catch (const std::exception &e ) + { + cout << "-----------------" << endl; + cout << " pb avec compare " << endl; + cout << "-----------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-----------------" << endl; + cout << " pb avec compare " << endl; + cout << "-----------------" << endl; + return EXIT_FAILURE ; + } + + if (ret!=0) + { + cout << "-----------------------------------------------------" << endl; + cout << " pb avec compare entre modulusArray et modulusArray5 " << endl; + cout << " Les deux tableaux sont differents " << endl; + cout << "-----------------------------------------------------" << endl; + return EXIT_FAILURE ; + } + else + { + cout << " compare entre modulusArray et modulusArray5 : OK" << endl; + cout << endl; + } + + // test small array : + // taille 1 + int array6[1]={1} ; + MEDMODULUSARRAY modulusArray6(1,array6); + + cout << " ModulusArray 1 : " << endl; + cout << " __________________" << endl; + + for(int i=-10;i<15;i++) + { + cout <<" - A[" << i <<"]="<<modulusArray6[i]<<endl; + } + cout << endl; + + int array7[1]={1} ; + MEDMODULUSARRAY modulusArray7(1,array7); + + cout << " Test compare : mêmes tableaux mêmes ordres ..." << endl; + try + { + ret=modulusArray6.compare(modulusArray7); + } + catch ( const std::exception &e ) + { + cout << "-----------------" << endl; + cout << " pb avec compare " << endl; + cout << "-----------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-----------------" << endl; + cout << " pb avec compare " << endl; + cout << "-----------------" << endl; + return EXIT_FAILURE ; + } + + if (ret!=1) + { + cout << "-----------------------------------------------------" << endl; + cout << " pb avec compare entre modulusArray6 et modulusArray7" << endl; + cout << " Les deux tableaux sont identiques " << endl; + cout << "-----------------------------------------------------" << endl; + return EXIT_FAILURE ; + } + else + { + cout << " compare entre modulusArray6 et modulusArray7 : OK" << endl ; + cout << endl; + } + + int array8[1]={2} ; + MEDMODULUSARRAY modulusArray8(1,array8); + + cout << " Test compare : tableaux differents "<< endl; + try + { + ret=modulusArray6.compare(modulusArray8); + } + catch ( const std::exception &e ) + { + cout << "-----------------" << endl; + cout << " pb avec compare " << endl; + cout << "-----------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-----------------" << endl; + cout << " pb avec compare " << endl; + cout << "-----------------" << endl; + return EXIT_FAILURE ; + } + + if (ret!=0) + { + cout << "-----------------------------------------------------" << endl; + cout << " pb avec compare entre modulusArray6 et modulusArray8" << endl; + cout << " Les deux tableaux sont differents" << endl; + cout << "-----------------------------------------------------" << endl; + return EXIT_FAILURE ; + } + else + { + cout << " compare entre modulusArray6 et modulusArray8 : OK" << endl; + cout << endl; + } + + + // 2 + int array60[2]={1,2} ; + MEDMODULUSARRAY modulusArray60(2,array60); + + + cout << " ModulusArray 2 : " << endl; + cout << " __________________" << endl; + + for(int i=-10;i<15;i++) + { + cout <<" - A[" << i <<"]="<<modulusArray60[i]<<endl; + } + cout << endl; + + int array70[2]={1,2} ; + MEDMODULUSARRAY modulusArray70(2,array70); + cout << " Test compare : mêmes tableaux mêmes ordres ..." << endl; + + try + { + ret=modulusArray60.compare(modulusArray70); + } + catch ( const std::exception &e ) + { + cout << "-----------------" << endl; + cout << " pb avec compare " << endl; + cout << "-----------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-----------------" << endl; + cout << " pb avec compare " << endl; + cout << "-----------------" << endl; + return EXIT_FAILURE ; + } + + if (ret!=1) + { + cout << "--------------------------------------------------------" << endl; + cout << " pb avec compare entre modulusArray60 et modulusArray70 " << endl; + cout << " Les deux tableaux sont identiques " << endl; + cout << "--------------------------------------------------------" << endl; + return EXIT_FAILURE ; + } + else + { + cout << " compare entre modulusArray60 et modulusArray70 : OK" << endl; + cout << endl; + } + + int array80[2]={2,2} ; + MEDMODULUSARRAY modulusArray80(2,array80); + + cout << " Test compare : tableaux differents ..." << endl; + + try + { + ret=modulusArray60.compare(modulusArray80); + } + catch ( const std::exception &e ) + { + cout << "-----------------" << endl; + cout << " pb avec compare " << endl; + cout << "-----------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-----------------" << endl; + cout << " pb avec compare " << endl; + cout << "-----------------" << endl; + return EXIT_FAILURE ; + } + + if (ret!=0) + { + cout << "--------------------------------------------------------" << endl; + cout << " pb avec compare entre modulusArray60 et modulusArray80 " << endl; + cout << " Les deux tableaux sont differents " << endl; + cout << "--------------------------------------------------------" << endl; + return EXIT_FAILURE ; + } + else + { + cout << " compare entre modulusArray60 et modulusArray80 : OK" << endl; + cout << endl; + } + + int array90[2]={2,1} ; + MEDMODULUSARRAY modulusArray90(2,array90); + cout << " Test compare : tableaux differents ordres inverses ..." << endl; + try + { + ret=modulusArray60.compare(modulusArray90); + } + catch ( const std::exception &e ) + { + cout << "-----------------" << endl; + cout << " pb avec compare " << endl; + cout << "-----------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-----------------" << endl; + cout << " pb avec compare " << endl; + cout << "-----------------" << endl; + return EXIT_FAILURE ; + } + + if (ret!=-1) + { + cout << "--------------------------------------------------------" << endl; + cout << " pb avec compare entre modulusArray60 et modulusArray90 " << endl; + cout << " Les deux tableaux sont differents " << endl; + cout << "--------------------------------------------------------" << endl; + return EXIT_FAILURE ; + } + else + { + cout << " compare entre modulusArray60 et modulusArray90 : OK" << endl; + cout << endl; + } + + return EXIT_SUCCESS ; +} diff --git a/src/MEDMEMBinTest/tests/testUPointerOf.cxx b/src/MEDMEMBinTest/tests/testUPointerOf.cxx new file mode 100644 index 000000000..6b32350e3 --- /dev/null +++ b/src/MEDMEMBinTest/tests/testUPointerOf.cxx @@ -0,0 +1,117 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// File : testUPointerOf.cxx +// Module : MED +// +#include "MEDMEM_Utilities.hxx" +#include "MEDMEM_PointerOf.hxx" +#include "MEDMEM_Exception.hxx" + +using namespace std; +using namespace MEDMEM; + + +int main (int argc, char ** argv) +{ + cout << "PointerOf Test" << endl ; + cout << "--------------" << endl; + + const int size=10; + PointerOf<int> P; + + // Creation d'un PointerOf de int + // et vérification de la methode set en essayant avec + // une taille nulle, négative puis positive + try + { + P.set(0); + ASSERT_MED((int *)P == NULL); + } + catch ( const std::exception &e ) + { + cout << "-------------------------" << endl; + cout << " pb avec set(taille = 0) " << endl; + cout << "-------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + + try + { + P.set(-1 * size); + ASSERT_MED((int *)P == NULL); + } + catch ( const std::exception &e ) + { + cout << "---------------------" << endl; + cout << " pb avec set(taille) " << endl; + cout << "---------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + + try + { + P.set(size); + ASSERT_MED((int *)P != NULL); + } + catch ( const std::exception &e ) + { + cout << "---------------------" << endl; + cout << " pb avec set(taille) " << endl; + cout << "---------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + for (int i=0; i < size; i++) + { + P[i]=i; + } + + PointerOf<int> P2(10); + + P2=P; + for (int i=0; i < size; i++) + { + SCRUTE_MED(P2[i]); + } + + int * p=new int [size]; + for (int i=0; i < size; i++) + { + p[i]=i*10; + } + + P2.set(p); + PointerOf<int> P3(p); + + for (int i=0; i < size; i++) + { + SCRUTE_MED(P2[i]); + SCRUTE_MED(P3[i]); + } + + const PointerOf<int> P4(p); + const PointerOf<int> P5(P4); + delete [] p; + +} diff --git a/src/MEDMEMBinTest/tests/testUSkyLineArray.cxx b/src/MEDMEMBinTest/tests/testUSkyLineArray.cxx new file mode 100644 index 000000000..118c00b0b --- /dev/null +++ b/src/MEDMEMBinTest/tests/testUSkyLineArray.cxx @@ -0,0 +1,239 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// File : testUSkyLineArray.cxx +// Module : MED +// +#include <cstdlib> +#include "MEDMEM_Utilities.hxx" +#include "MEDMEM_SkyLineArray.hxx" + +using namespace std; +using namespace MEDMEM; + +int main (int argc, char ** argv) +{ + + int NumberOfCell = 3 ; // 1 triangle,1 quadrangle,1 triangle + int Size = 10 ; // 10 nodes + + int * index = new int[NumberOfCell+1]; + index[0]=1; + index[1]=4; + index[2]=8; + index[3]=11; + + int * value = new int[Size]; + value[0]=1; // first + value[1]=2; + value[2]=5; + value[3]=2; // second + value[4]=3; + value[5]=5; + value[6]=6; + value[7]=3; // thirst + value[8]=4; + value[9]=6; + + MEDSKYLINEARRAY * myArray = new MEDSKYLINEARRAY(NumberOfCell,Size,index,value) ; + + const int * ArrayIndex ; + try + { + ArrayIndex = myArray->getIndex() ; + } + catch ( const std::exception &e ) + { + cout << "----------------" << endl; + cout << "pb avec getIndex" << endl; + cout << "----------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "----------------" << endl; + cout << "pb avec getIndex" << endl; + cout << "----------------" << endl; + return EXIT_FAILURE ; + } + + const int * ArrayValue ; + try + { + ArrayValue = myArray->getValue() ; + } + catch ( const std::exception &e ) + { + cout << "----------------" << endl; + cout << "pb avec getValue" << endl; + cout << "----------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "----------------" << endl; + cout << "pb avec getValue" << endl; + cout << "----------------" << endl; + return EXIT_FAILURE ; + } + + + try + { + ASSERT_MED(myArray->getNumberOf()==NumberOfCell); + cout << myArray->getNumberOf() << endl; + } + catch ( const std::exception &e ) + { + cout << "-------------------" << endl; + cout << "pb avec getNumberOf" << endl; + cout << "-------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------" << endl; + cout << "pb avec getNumberOf" << endl; + cout << "-------------------" << endl; + return EXIT_FAILURE ; + } + + try + { + ASSERT_MED(myArray->getLength()==Size); + cout << myArray->getLength() << endl; + } + catch ( const std::exception &e ) + { + cout << "-------------------" << endl; + cout << "pb avec getLength" << endl; + cout << "-------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------" << endl; + cout << "pb avec getLength" << endl; + cout << "-------------------" << endl; + return EXIT_FAILURE ; + } + + cout << "Show all :" << endl ; + for (int i=1; i< NumberOfCell+1 ; i++) + { + const int * cell; + try + { + cell = myArray->getI(i) ; + } + catch ( const std::exception &e ) + { + cout << "-----------------------------" << endl; + cout << "pb avec getI, valeur de i : " << i << endl; + cout << "-----------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------" << endl; + cout << "pb avec getI, valeur de i : " << i << endl; + cout << "-------------------" << endl; + return EXIT_FAILURE ; + } + + int numberof; + try + { + numberof= myArray->getNumberOfI(i) ; + ASSERT_MED(numberof==index[i]-index[i-1]); + } + catch ( const std::exception &e ) + { + cout << "----------------------------------" << endl; + cout << "pb avec getNumberOfI, valeur de i : " << i << endl; + cout << "----------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "----------------------------------" << endl; + cout << "pb avec getNumberOfI, valeur de i : " << i << endl; + cout << "----------------------------------" << endl; + return EXIT_FAILURE ; + } + + cout << " - " ; + for (int j=0;j<numberof;j++) + { + cout << cell[j] << " " ; + try + { + int verif=myArray->getIJ(i,j+1); + if (verif != cell[j]) + { + cout << "----------------------------------" << endl; + cout << " incoherence dans les valeurs : " << endl; + cout << " cell[" << j << "] : " << cell[j] << endl; + cout << " getIJ(" << i <<"," << j << ") : " << verif << endl; + cout << "----------------------------------" << endl; + return EXIT_FAILURE ; + } + } + catch ( const std::exception &e ) + { + cout << "----------------------------------" << endl; + cout << "pb avec getIJ, valeurs de i / j : " << i << " " << j<< endl; + cout << "----------------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "----------------------------------" << endl; + cout << "pb avec getIJ, valeurs de i / j : " << i << " " << j<< endl; + cout << "----------------------------------" << endl; + return EXIT_FAILURE ; + } + } + cout << endl ; + } + + delete[] index ; + delete[] value ; + + delete myArray; + MESSAGE_MED("FIN normale du traitement"); + return EXIT_SUCCESS ; + + +/* + MEDSKYLINEARRAY( const MEDSKYLINEARRAY &myArray ); + void setMEDSKYLINEARRAY( const med_int count, const med_int length, med_int* index , med_int* value ) ; + + +*/ +} diff --git a/src/MEDMEMBinTest/tests/testUUnit.cxx b/src/MEDMEMBinTest/tests/testUUnit.cxx new file mode 100755 index 000000000..5321a7f6d --- /dev/null +++ b/src/MEDMEMBinTest/tests/testUUnit.cxx @@ -0,0 +1,402 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// File : testUUnit.cxx +// Module : MED +// +#include <cstdlib> +#include <exception> + +#include "MEDMEM_Unit.hxx" +using namespace std; +using namespace MEDMEM; + +int main (int argc, char ** argv) +{ + + cout << "UNIT Test" << endl ; + cout << "---------" << endl; + + UNIT testu; + try + { + testu.setName("ForTesting") ; + } + catch ( const std::exception &e ) + { + cout << "-----------------" << endl; + cout << " pb avec setName " << endl; + cout << "-----------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-----------------" << endl; + cout << " pb avec setName " << endl; + cout << "-----------------" << endl; + return EXIT_FAILURE ; + } + + try + { + testu.setDescription("all values are setted 10") ; + } + catch ( const std::exception &e ) + { + cout << "------------------------" << endl; + cout << " pb avec setDescription " << endl; + cout << "------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "------------------------" << endl; + cout << " pb avec setDescription " << endl; + cout << "------------------------" << endl; + return EXIT_FAILURE ; + } + + try + { + testu.setMasse(10); + } + catch ( const std::exception &e ) + { + cout << "------------------" << endl; + cout << " pb avec setMasse " << endl; + cout << "------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "------------------" << endl; + cout << " pb avec setMasse " << endl; + cout << "------------------" << endl; + return EXIT_FAILURE ; + } + + try + { + testu.setLength(10); + } + catch ( const std::exception &e ) + { + cout << "-------------------" << endl; + cout << " pb avec setLength " << endl; + cout << "-------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------" << endl; + cout << " pb avec setLength " << endl; + cout << "-------------------" << endl; + return EXIT_FAILURE ; + } + + try + { + testu.setTime(10); + } + catch ( const std::exception &e ) + { + cout << "-----------------" << endl; + cout << " pb avec setTime " << endl; + cout << "-----------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-----------------" << endl; + cout << " pb avec setTime " << endl; + cout << "-----------------" << endl; + return EXIT_FAILURE ; + } + + try + { + testu.setTemperature(10); + } + catch ( const std::exception &e ) + { + cout << "------------------------" << endl; + cout << " pb avec setTemperature " << endl; + cout << "------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "------------------------" << endl; + cout << " pb avec setTemperature " << endl; + cout << "------------------------" << endl; + return EXIT_FAILURE ; + } + + try + { + testu.setMatterQuantity(10); + } + catch ( const std::exception &e ) + { + cout << "---------------------------" << endl; + cout << " pb avec setMatterQuantity " << endl; + cout << "---------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "---------------------------" << endl; + cout << " pb avec setMatterQuantity " << endl; + cout << "---------------------------" << endl; + return EXIT_FAILURE ; + } + + try + { + testu.setCurrentStrength(10) ; + } + catch ( const std::exception &e ) + { + cout << "---------------------------" << endl; + cout << " pb avec setCurrentStrengt " << endl; + cout << "---------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "---------------------------" << endl; + cout << " pb avec setCurrentStrengt " << endl; + cout << "---------------------------" << endl; + return EXIT_FAILURE ; + } + + try + { + testu.setLightIntensity(10) ; + } + catch ( const std::exception &e ) + { + cout << "---------------------------" << endl; + cout << " pb avec setLightIntensity " << endl; + cout << "---------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "---------------------------" << endl; + cout << " pb avec setLightIntensity " << endl; + cout << "---------------------------" << endl; + return EXIT_FAILURE ; + } + + + try + { + cout << testu.getName() << endl ; + } + catch ( const std::exception &e ) + { + cout << "-----------------" << endl; + cout << " pb avec getName " << endl; + cout << "-----------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-----------------" << endl; + cout << " pb avec getName " << endl; + cout << "-----------------" << endl; + return EXIT_FAILURE ; + } + + try + { + cout << testu.getDescription() << endl ; + } + catch ( const std::exception &e ) + { + cout << "------------------------" << endl; + cout << " pb avec getDescription " << endl; + cout << "------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "------------------------" << endl; + cout << " pb avec getDescription " << endl; + cout << "------------------------" << endl; + return EXIT_FAILURE ; + } + + try + { + cout << testu.getMasse() << endl ; + } + catch ( const std::exception &e ) + { + cout << "------------------" << endl; + cout << " pb avec getMasse " << endl; + cout << "------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "------------------" << endl; + cout << " pb avec getMasse " << endl; + cout << "------------------" << endl; + return EXIT_FAILURE ; + } + + try + { + cout << testu.getLength() << endl ; + } + catch ( const std::exception &e ) + { + cout << "-------------------" << endl; + cout << " pb avec getLength " << endl; + cout << "-------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-------------------" << endl; + cout << " pb avec getLength " << endl; + cout << "-------------------" << endl; + return EXIT_FAILURE ; + } + + try + { + cout << testu.getTime() << endl ; + } + catch ( const std::exception &e ) + { + cout << "-----------------" << endl; + cout << " pb avec getTime " << endl; + cout << "-----------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "-----------------" << endl; + cout << " pb avec getTime " << endl; + cout << "-----------------" << endl; + return EXIT_FAILURE ; + } + + try + { + cout << testu.getTemperature() << endl ; + } + catch ( const std::exception &e ) + { + cout << "------------------------" << endl; + cout << " pb avec getTemperature " << endl; + cout << "------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "------------------------" << endl; + cout << " pb avec getTemperature " << endl; + cout << "------------------------" << endl; + return EXIT_FAILURE ; + } + + try + { + cout << testu.getMatterQuantity() << endl ; + } + catch ( const std::exception &e ) + { + cout << "---------------------------" << endl; + cout << " pb avec getMatterQuantity " << endl; + cout << "---------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "---------------------------" << endl; + cout << " pb avec getMatterQuantity " << endl; + cout << "---------------------------" << endl; + return EXIT_FAILURE ; + } + + try + { + cout << testu.getCurrentStrength() << endl ; + } + catch ( const std::exception &e ) + { + cout << "----------------------------" << endl; + cout << " pb avec getCurrentStrength " << endl; + cout << "----------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "----------------------------" << endl; + cout << " pb avec getCurrentStrength " << endl; + cout << "----------------------------" << endl; + return EXIT_FAILURE ; + } + + try + { + cout << testu.getLightIntensity() << endl ; + } + catch ( const std::exception &e ) + { + cout << "---------------------------" << endl; + cout << " pb avec getLightIntensity " << endl; + cout << "---------------------------" << endl; + MESSAGE_MED( "catched exception : " << e.what() ) ; + return EXIT_FAILURE ; + } + catch (...) + { + cout << "---------------------------" << endl; + cout << " pb avec getLightIntensity " << endl; + cout << "---------------------------" << endl; + return EXIT_FAILURE ; + } + + return EXIT_SUCCESS ; + +} ; diff --git a/src/MEDMEMCppTest/BasicMainTest.hxx b/src/MEDMEMCppTest/BasicMainTest.hxx new file mode 100644 index 000000000..8ecf82f2b --- /dev/null +++ b/src/MEDMEMCppTest/BasicMainTest.hxx @@ -0,0 +1,90 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#ifndef _BASICMAINTEST_HXX_ +#define _BASICMAINTEST_HXX_ + +#include <cppunit/CompilerOutputter.h> +#include <cppunit/TestResult.h> +#include <cppunit/TestResultCollector.h> +#include <cppunit/TextTestProgressListener.h> +#include <cppunit/BriefTestProgressListener.h> +#include <cppunit/extensions/TestFactoryRegistry.h> +#include <cppunit/TestRunner.h> +#include <stdexcept> + +#include <iostream> +#include <fstream> + +// ============================================================================ +/*! + * Main program source for Unit Tests with cppunit package does not depend + * on actual tests, so we use the same for all partial unit tests. + */ +// ============================================================================ + +int main(int argc, char* argv[]) +{ + // --- Create the event manager and test controller + CPPUNIT_NS::TestResult controller; + + // --- Add a listener that colllects test result + CPPUNIT_NS::TestResultCollector result; + controller.addListener( &result ); + + // --- Add a listener that print dots as test run. +#ifdef WIN32 + CPPUNIT_NS::TextTestProgressListener progress; +#else + CPPUNIT_NS::BriefTestProgressListener progress; +#endif + controller.addListener( &progress ); + + // --- Get the top level suite from the registry + + CPPUNIT_NS::Test *suite = + CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest(); + + // --- Adds the test to the list of test to run + + CPPUNIT_NS::TestRunner runner; + runner.addTest( suite ); + runner.run( controller); + + // --- Print test in a compiler compatible format. + + std::ofstream testFile; + testFile.open("UnitTestsResult", std::ios::out | std::ios::trunc); + //CPPUNIT_NS::CompilerOutputter outputter( &result, std::cerr ); + CPPUNIT_NS::CompilerOutputter outputter( &result, testFile ); + outputter.write(); + + // --- Run the tests. + + bool wasSucessful = result.wasSuccessful(); + testFile.close(); + + // --- Return error code 1 if the one of test failed. + + return wasSucessful ? 0 : 1; +} + +#endif diff --git a/src/MEDMEMCppTest/MEDMEMTest.cxx b/src/MEDMEMCppTest/MEDMEMTest.cxx new file mode 100644 index 000000000..6d9f52d6e --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest.cxx @@ -0,0 +1,702 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_Group.hxx" +#include "MEDMEM_IndexCheckingPolicy.hxx" +#include "MEDMEM_MedFieldDriver.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Meshing.hxx" +#include "MEDMEM_STRING.hxx" + +#include <sstream> +#include <cmath> + +using namespace std; + +// ============================================================================ +/*! + * Set up the environment + */ +// ============================================================================ +void MEDMEMTest::setUp() +{ +} + +// ============================================================================ +/*! + * - delete + */ +// ============================================================================ +void MEDMEMTest::tearDown() +{ +} + +// #1: MEDMEM_Array.hxx \ +// #2: MEDMEM_ArrayConvert.hxx } MEDMEMTest_Array.cxx +// #3: MEDMEM_ArrayInterface.hxx (-) / +// #4: MEDMEM_AsciiFieldDriver.hxx } MEDMEMTest_AsciiFieldDriver.cxx +// #5: MEDMEM_CellModel.hxx } MEDMEMTest.cxx (-) +// #6: MEDMEM_Compatibility21_22.hxx } nothing to test +// #7: MEDMEM_Connectivity.hxx } MEDMEMTest_Connectivity.cxx +// #8: MEDMEM_Coordinate.hxx } MEDMEMTest_Coordinate.cxx +// #9: MEDMEM_DriverFactory.hxx } MEDMEMTest_DriverFactory.cxx +// #10: MEDMEM_DriversDef.hxx } MEDMEMTest.cxx (-) +// #11: MEDMEM_DriverTools.hxx } MEDMEMTest.cxx (-) +// #12: MEDMEM_Exception.hxx } MEDMEMTest_Exception.cxx +// #13: MEDMEM_Family.hxx } MEDMEMTest.cxx +// #14: MEDMEM_Field.hxx \ +// #15: MEDMEM_FieldConvert.hxx / MEDMEMTest_Field.cxx +// #16: MEDMEM_FieldForward.hxx } no methods to test +// #17: MEDMEM_Formulae.hxx } MEDMEMTest_Formulae.cxx +// #18: MEDMEM_GaussLocalization.hxx } MEDMEMTest_GaussLocalization.cxx +// #19: MEDMEM_GenDriver.hxx } abstract class; implemented methods are tested during its successors testing +// #20: MEDMEM_GibiMeshDriver.hxx } MEDMEMTest_GibiMeshDriver.cxx +// #21: MEDMEM_Grid.cxx } MEDMEMTest_Grid.cxx +// #22: MEDMEM_Group.cxx } MEDMEMTest_Group.cxx +// #23: MEDMEM_IndexCheckingPolicy.cxx } MEDMEMTest.cxx +// #24: MEDMEM_Init.cxx } MEDMEMTest.cxx +// #25: MEDMEM_InterlacingPolicy.hxx } MEDMEMTest.cxx (-) +// #26: MEDMEM_InterlacingTraits.hxx } MEDMEMTest.cxx (-) +// #27: MEDMEM_MedFieldDriver21.hxx } MEDMEMTest_MedFieldDriver21.cxx +// #28: MEDMEM_MedFieldDriver22.hxx } MEDMEMTest_MedFieldDriver22.cxx +// #29: MEDMEM_MedFieldDriver.hxx } MEDMEMTest.cxx (-) +// #30: MEDMEM_Med.hxx } MEDMEMTest_Med.cxx +// #31: MEDMEM_MedMedDriver21.hxx } MEDMEMTest_MedMedDriver21.cxx +// #32: MEDMEM_MedMedDriver22.hxx } MEDMEMTest_MedMedDriver22.cxx +// #33: MEDMEM_MedMedDriver.hxx } MEDMEMTest.cxx (-) +// #34: MEDMEM_MEDMEMchampLire.hxx } MEDMEMTest.cxx (-) +// #35: MEDMEM_MEDMEMgaussEcr.hxx } MEDMEMTest.cxx (-) +// #36: MEDMEM_MEDMEMprofilEcr.hxx } MEDMEMTest.cxx (-) +// #37: MEDMEM_MedMeshDriver21.hxx } MEDMEMTest_MedMeshDriver21.cxx +// #38: MEDMEM_MedMeshDriver22.hxx } MEDMEMTest_MedMeshDriver22.cxx +// #39: MEDMEM_MedMeshDriver.hxx } MEDMEMTest.cxx (-) +// #40: MEDMEM_MedVersion.hxx } MEDMEMTest_MedVersion.cxx +// #41: MEDMEM_Mesh.hxx \ +// #42: MEDMEM_Meshing.hxx / MEDMEMTest_MeshAndMeshing.cxx +// #43: MEDMEM_ModulusArray.hxx } MEDMEMTest_ModulusArray.cxx +// #44: MEDMEM_nArray.hxx } MEDMEMTest_nArray.cxx +// #45: MEDMEM_PointerOf.hxx } MEDMEMTest_PointerOf.cxx +// #46: MEDMEM_PolyhedronArray.hxx } MEDMEMTest_PolyhedronArray.cxx +// #47: MEDMEM_PorflowMeshDriver.hxx } MEDMEMTest_PorflowMeshDriver.cxx +// #48: MEDMEM_RCBase.hxx } MEDMEMTest.cxx (-) +// #49: MEDMEM_SetInterlacingType.hxx } MEDMEMTest.cxx (-) +// #50: MEDMEM_SkyLineArray.hxx } MEDMEMTest_SkyLineArray.cxx +// #51: MEDMEM_STRING.hxx } MEDMEMTest.cxx +// #52: MEDMEM_Support.hxx } MEDMEMTest_Support.cxx +// #53: MEDMEM_Tags.hxx } MEDMEMTest.cxx (-) +// #54: MEDMEM_TopLevel.hxx } MEDMEMTest_TopLevel.cxx +// #55: MEDMEM_TypeMeshDriver.hxx } MEDMEMTest.cxx +// #56: MEDMEM_Unit.hxx } MEDMEMTest_Unit.cxx +// #57: MEDMEM_VtkFieldDriver.hxx } MEDMEMTest_VtkFieldDriver.cxx +// #58: MEDMEM_VtkMedDriver.hxx } MEDMEMTest_VtkMedDriver.cxx +// #59: MEDMEM_VtkMeshDriver.hxx } MEDMEMTest_VtkMeshDriver.cxx +// #60: MEDMEM_medimport_src.hxx } MEDMEMTest.cxx (-) + + +/*! + * Check methods (not in spec), defined in MEDMEM_CellModel.hxx: + */ +//void MEDMEMTest::testCellModel() +//{ +// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); +//} + +/*! + * Check methods (not in spec), defined in MEDMEM_DriversDef.hxx: + */ +//void MEDMEMTest::testDriversDef() +//{ +// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); +//} + +/*! + * Check methods (not in spec), defined in MEDMEM_DriverTools.hxx: + */ +//void MEDMEMTest::testDriverTools() +//{ +// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); +//} + +/*! + * Check methods (4), defined in MEDMEM_IndexCheckingPolicy.hxx: + * class IndexCheckPolicy { + * (+) void checkMoreThanZero(const std::string & classname, int index) const; + * (+) void checkLessOrEqualThan(const std::string & classname, int max, int index) const; + * (+) void checkInInclusiveRange(const std::string & classname, int min, int max, int index) const; + * (+) void checkEquality(const std::string & classname, int a, int b) const; + * } + * class NoIndexCheckPolicy { + * (+) void checkMoreThanZero(const string &classname, int index) const; + * (+) void checkLessOrEqualThan(const std::string & classname, int max, int index) const; + * (+) void checkInInclusiveRange(const std::string & classname, int min, int max, int index) const; + * (+) void checkEquality(const std::string & classname, int a, int b) const; + * } + */ +void MEDMEMTest::testIndexCheckingPolicy() +{ + MEDMEM::IndexCheckPolicy do_check; + MEDMEM::NoIndexCheckPolicy no_check; + + int min = 3; + int max = 10; + + string aClassName ("MEDMEMTest::testIndexCheckingPolicy"); + + // IndexCheckPolicy: throw, if index does not satisfy criteria + CPPUNIT_ASSERT_THROW(do_check.checkMoreThanZero(aClassName, -1), MEDMEM::MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(do_check.checkLessOrEqualThan(aClassName, max, 13), MEDMEM::MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(do_check.checkInInclusiveRange(aClassName, min, max, 1), MEDMEM::MEDEXCEPTION); + // checkEquality() check that values are not equal + CPPUNIT_ASSERT_THROW(do_check.checkEquality(aClassName, 21, 21), MEDMEM::MEDEXCEPTION); + + // NoIndexCheckPolicy: do not throw, if index does not satisfy criteria + CPPUNIT_ASSERT_NO_THROW(no_check.checkMoreThanZero(aClassName, -1)); + CPPUNIT_ASSERT_NO_THROW(no_check.checkLessOrEqualThan(aClassName, max, 13)); + CPPUNIT_ASSERT_NO_THROW(no_check.checkInInclusiveRange(aClassName, min, max, 1)); + CPPUNIT_ASSERT_NO_THROW(no_check.checkEquality(aClassName, 21, 21)); + + // IndexCheckPolicy: do not throw, if index satisfy criteria + CPPUNIT_ASSERT_NO_THROW(do_check.checkMoreThanZero(aClassName, 5)); + CPPUNIT_ASSERT_NO_THROW(do_check.checkLessOrEqualThan(aClassName, max, 7)); + CPPUNIT_ASSERT_NO_THROW(do_check.checkInInclusiveRange(aClassName, min, max, 6)); + CPPUNIT_ASSERT_NO_THROW(do_check.checkEquality(aClassName, 21, 28)); + + // NoIndexCheckPolicy: do not throw, if index satisfy criteria + CPPUNIT_ASSERT_NO_THROW(no_check.checkMoreThanZero(aClassName, 5)); + CPPUNIT_ASSERT_NO_THROW(no_check.checkLessOrEqualThan(aClassName, max, 7)); + CPPUNIT_ASSERT_NO_THROW(no_check.checkInInclusiveRange(aClassName, min, max, 6)); + CPPUNIT_ASSERT_NO_THROW(no_check.checkEquality(aClassName, 21, 28)); +} + +/*! + * Check initialization, done in MEDMEM_Init.cxx: + * (-) MEDMEM::INIT init; + */ +void MEDMEMTest::testInit() +{ + // We cannot check here effect of initialization, done in MEDMEM_Init.cxx, + // because environment variable, set there, is visible only in libmedmem.la + // and its child processes (if any). + + // Check effect of MEDMEM_Init.cxx + //char* traceKind = getenv("SALOME_trace"); + //CPPUNIT_ASSERT(traceKind); +} + +/*! + * Check methods (not in spec), defined in MEDMEM_InterlacingPolicy.hxx: + */ +//void MEDMEMTest::testInterlacingPolicy() +//{ +// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); +//} + +/*! + * Check methods (not in spec), defined in MEDMEM_InterlacingTraits.hxx: + */ +//void MEDMEMTest::testInterlacingTraits() +//{ +// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); +//} + +/*! + * Check methods (not in spec), defined in MEDMEM_MedFieldDriver.hxx: + */ +//void MEDMEMTest::testMedFieldDriver() +//{ +// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); +//} + +/*! + * Check methods (not in spec), defined in MEDMEM_MedMedDriver.hxx: + */ +//void MEDMEMTest::testMedMedDriver() +//{ +// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); +//} + +/*! + * Check methods (not in spec), defined in MEDMEM_MEDMEMchampLire.hxx: + */ +//void MEDMEMTest::testMEDMEMchampLire() +//{ +// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); +//} + +/*! + * Check methods (not in spec), defined in MEDMEM_MEDMEMgaussEcr.hxx: + */ +//void MEDMEMTest::testMEDMEMgaussEcr() +//{ +// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); +//} + +/*! + * Check methods (not in spec), defined in MEDMEM_MEDMEMprofilEcr.hxx: + */ +//void MEDMEMTest::testMEDMEMprofilEcr() +//{ +// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); +//} + +/*! + * Check methods (not in spec), defined in MEDMEM_MedMeshDriver.hxx: + */ +//void MEDMEMTest::testMedMeshDriver() +//{ +// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); +//} + +/*! + * Check methods (not in spec), defined in MEDMEM_RCBase.hxx: + * class RCBASE { + * (reference counter presently disconnected in C++) virtual void addReference() const = 0; + * (reference counter presently disconnected in C++) virtual void removeReference() const = 0; + * } + */ +//void MEDMEMTest::testRCBase() +//{ +// // nothing to test +//} + +/*! + * Check methods (not in spec), defined in MEDMEM_SetInterlacingType.hxx: + */ +//void MEDMEMTest::testSetInterlacingType() +//{ +// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); +//} + +/*! + * Check methods (2), defined in MEDMEM_STRING.hxx: + * class STRING : public string { + * (+) STRING() + * (+) ~STRING() + * (+) operator const char * () const + * (+) template <class T> STRING(const T &valeur) + * (+) template <class T> STRING & operator<<(const T &valeur) + * } + */ +void MEDMEMTest::testSTRING() +{ + { + // empty constructor + MEDMEM::STRING medstr; + CPPUNIT_ASSERT(strcmp(medstr.c_str(), "") == 0); + + // template <class T> STRING & operator<<(const T &valeur) with T == char* + //medstr << <char*>"filling 1"; + medstr << "filling " << 1 << " !!!"; + CPPUNIT_ASSERT(strcmp(medstr.c_str(), "filling 1 !!!") == 0); + + // operator const char * () + CPPUNIT_ASSERT(strcmp((const char *)medstr, "filling 1 !!!") == 0); + CPPUNIT_ASSERT(strcmp( medstr, "filling 1 !!!") == 0); + } + + MEDMEM::MESH * aMesh1 = MEDMEMTest_createTestMesh(); + ostringstream ostr; + ostr << *aMesh1; + + { + // template <class T> STRING & operator<<(const T &valeur) with T == MEDMEM::MESH + MEDMEM::STRING medstr; + //medstr << <char*>"filling 1"; + medstr << *aMesh1; + CPPUNIT_ASSERT(strcmp(medstr, ostr.str().c_str()) == 0); + } + + { + // Constructor STRING(const T &valeur) with T == char* + //MEDMEM::STRING medstr<char*>("filling 2"); + MEDMEM::STRING medstr ("filling 2"); + CPPUNIT_ASSERT(strcmp(medstr.c_str(), "filling 2") == 0); + CPPUNIT_ASSERT(strcmp(medstr, "filling 2") == 0); + } + + { + // Constructor STRING(const T &valeur) with T == MEDMEM::MESH + MEDMEM::STRING medstr (*aMesh1); + CPPUNIT_ASSERT(strcmp(medstr, ostr.str().c_str()) == 0); + } + + delete aMesh1; +} + +/*! + * Check methods (not in spec), defined in MEDMEM_Tags.hxx: + */ +//void MEDMEMTest::testTags() +//{ +// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); +//} + +/*! + * Check methods (15), defined in MEDMEM_TypeMeshDriver.hxx: + * class TYPE_MESH_DRIVER : public GENDRIVER { + * (-) TYPE_MESH_DRIVER(); + * (-) TYPE_MESH_DRIVER(const string & fileName, MESH * ptrMesh, med_mode_acces accessMode); + * (-) TYPE_MESH_DRIVER(const TYPE_MESH_DRIVER & driver); + * (-) virtual ~TYPE_MESH_DRIVER(); + * (-) void open() throw (MEDEXCEPTION); + * (-) void close() throw (MEDEXCEPTION); + * (-) virtual void write(void) const = 0; + * (-) virtual void read (void) = 0; + * (-) void setMeshName(const string & meshName); + * (-) string getMeshName() const; + * } + * class TYPE_MESH_RDONLY_DRIVER : public virtual TYPE_MESH_DRIVER { + * (-) TYPE_MESH_RDONLY_DRIVER(); + * (-) TYPE_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh); + * (-) TYPE_MESH_RDONLY_DRIVER(const TYPE_MESH_RDONLY_DRIVER & driver); + * (-) virtual ~TYPE_MESH_RDONLY_DRIVER(); + * (-) void write(void) const throw (MEDEXCEPTION); + * (-) void read (void) throw (MEDEXCEPTION); + * } + * class TYPE_MESH_WRONLY_DRIVER : public virtual TYPE_MESH_DRIVER { + * (-) TYPE_MESH_WRONLY_DRIVER(); + * (-) TYPE_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh); + * (-) TYPE_MESH_WRONLY_DRIVER(const TYPE_MESH_WRONLY_DRIVER & driver); + * (-) virtual ~TYPE_MESH_WRONLY_DRIVER(); + * (-) void write(void) const throw (MEDEXCEPTION); + * (-) void read (void) throw (MEDEXCEPTION); + * } + * class TYPE_MESH_RDWR_DRIVER : public TYPE_MESH_RDONLY_DRIVER, public TYPE_MESH_WRONLY_DRIVER { + * (-) TYPE_MESH_RDWR_DRIVER(); + * (-) TYPE_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh); + * (-) TYPE_MESH_RDWR_DRIVER(const TYPE_MESH_RDWR_DRIVER & driver); + * (-) ~TYPE_MESH_RDWR_DRIVER(); + * (-) void write(void) const throw (MEDEXCEPTION); + * (-) void read (void) throw (MEDEXCEPTION); + * } + */ +void MEDMEMTest::testTypeMeshDriver() +{ + CPPUNIT_FAIL("TYPE_MESH_DRIVER: not implemented"); +} + +/*! + * Check methods (not in spec), defined in MEDMEM_medimport_src.hxx: + */ +//void MEDMEMTest::testmedimport_src() +//{ +// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); +//} + +//60 +//21 not in spec + +////////////////////////////////////// +// HELP METHODS, used in many tests // +////////////////////////////////////// + +/*! + * Create a mesh with certain filling + * .n4 + * | + * | + * n16,n12,n8.---------.n7,n11,n15 + * | | | + * | | | + * n5.----|----.----|----.n3 + * | | | + * | | | + * n17,n13,n9.---------.n10,n14,n18 + * | + * | + * .n6 + * + * .n19 (0,0,5) + * | + * | + * | + * | + * n16.--|-.----.n15 + * / |/ / + * . . . + * / /| / + * n17.----.----.n18 + * | + * | + * n12.--|-.----.n11 + * / |/ / + * . . . + * / /| / + * n13.----.----.n14 + * | + * | + * n8.--|-.----.n7 + * / |/ / + * . . . + * / /| / + * n9.----.----.n10 + * | .n4 (0,2,1) + * | / + * | . + * |/ + * n5.----.----.----.----.n3 (2,0,1) + * (-2,0,1) /n2 (0,0,1) + * . | + * / | + * .n6 | + * | + * | + * .n1 (0,0,0) + */ +MEDMEM::MESH * MEDMEMTest_createTestMesh () +{ + // MESH DATA + int SpaceDimension = 3; + int meshDimension = SpaceDimension; // because there 3D cells in the mesh + + // coordinates + int NumberOfNodes = 19; + + string Names[3] = { "X","Y","Z" }; + string Units[3] = { "cm","cm","cm" }; + + double Coordinates[57] = { + 0.0, 0.0, 0.0, // n1 + 0.0, 0.0, 1.0, // n2 + 2.0, 0.0, 1.0, // n3 + 0.0, 2.0, 1.0, // n4 + -2.0, 0.0, 1.0, // n5 + 0.0, -2.0, 1.0, // n6 + 1.0, 1.0, 2.0, // n7 + -1.0, 1.0, 2.0, // n8 + -1.0, -1.0, 2.0, // n9 + 1.0, -1.0, 2.0, // n10 + 1.0, 1.0, 3.0, // n11 + -1.0, 1.0, 3.0, // n12 + -1.0, -1.0, 3.0, // n13 + 1.0, -1.0, 3.0, // n14 + 1.0, 1.0, 4.0, // n15 + -1.0, 1.0, 4.0, // n16 + -1.0, -1.0, 4.0, // n17 + 1.0, -1.0, 4.0, // n18 + 0.0, 0.0, 5.0 // n19 + }; + + // cells connectivities + const int NumberOfCellTypes = 3; + MED_EN::medGeometryElement CellTypes[NumberOfCellTypes] = + {MED_EN::MED_TETRA4, MED_EN::MED_PYRA5, MED_EN::MED_HEXA8}; + const int NumberOfCells[NumberOfCellTypes] = {12, 2, 2}; + + int ConnectivityTetra[12 * 4] = { + 1,2,3,6, + 1,2,4,3, + 1,2,5,4, + 1,2,6,5, + 2,7,4,3, + 2,8,5,4, + 2,9,6,5, + 2,10,3,6, + 2,7,3,10, + 2,8,4,7, + 2,9,5,8, + 2,10,6,9 + }; + + int ConnectivityPyra[2 * 5] = { + 7,8,9,10,2, + 15,18,17,16,19 + }; + + int ConnectivityHexa[2 * 8] = { + 11,12,13,14,7,8,9,10, + 15,16,17,18,11,12,13,14 + }; + + // faces connectivities + const int NumberOfFaceTypes = 2; + MED_EN::medGeometryElement FaceTypes[NumberOfFaceTypes] = {MED_EN::MED_TRIA3, MED_EN::MED_QUAD4}; + const int NumberOfFaces[NumberOfFaceTypes] = {4, 4}; + + int ConnectivityTria[4 * 3] = { + 1,4,3, + 1,5,4, + 1,6,5, + 1,3,6 + }; + + int ConnectivityQua[4 * 4] = { + 7,8,9,10, + 11,12,13,14, + 11,7,8,12, + 12,8,9,13 + }; + + + // CREATE THE MESH + MEDMEM::MESHING* myMeshing = new MEDMEM::MESHING; + + myMeshing->setName("meshing"); + + myMeshing->setCoordinates(SpaceDimension, NumberOfNodes, Coordinates, + "CARTESIAN", MED_EN::MED_FULL_INTERLACE); + myMeshing->setCoordinatesNames(Names); + myMeshing->setCoordinatesUnits(Units); + + // define connectivities + myMeshing->setNumberOfTypes(NumberOfCellTypes, MED_EN::MED_CELL); + myMeshing->setTypes(CellTypes, MED_EN::MED_CELL); + myMeshing->setNumberOfElements(NumberOfCells, MED_EN::MED_CELL); + + myMeshing->setConnectivity(ConnectivityTetra, MED_EN::MED_CELL, MED_EN::MED_TETRA4); + myMeshing->setConnectivity(ConnectivityPyra, MED_EN::MED_CELL, MED_EN::MED_PYRA5); + myMeshing->setConnectivity(ConnectivityHexa, MED_EN::MED_CELL, MED_EN::MED_HEXA8); + + myMeshing->setNumberOfTypes(NumberOfFaceTypes, MED_EN::MED_FACE); + myMeshing->setTypes(FaceTypes, MED_EN::MED_FACE); + myMeshing->setNumberOfElements(NumberOfFaces, MED_EN::MED_FACE); + + myMeshing->setConnectivity(ConnectivityTria, MED_EN::MED_FACE, MED_EN::MED_TRIA3); + myMeshing->setConnectivity(ConnectivityQua, MED_EN::MED_FACE, MED_EN::MED_QUAD4); + + // mesh dimension + myMeshing->setMeshDimension(meshDimension); + + // edges connectivities + // not yet implemented : if set, results are unpredictable. + + // groups of nodes + { + MEDMEM::GROUP myGroup; + myGroup.setName("SomeNodes"); + myGroup.setMesh(myMeshing); + myGroup.setEntity(MED_EN::MED_NODE); + myGroup.setNumberOfGeometricType(1); + MED_EN::medGeometryElement myTypes[1] = {MED_EN::MED_NONE}; + myGroup.setGeometricType(myTypes); + const int myNumberOfElements[1] = {4}; + myGroup.setNumberOfElements(myNumberOfElements); + const int index[1+1] = {1,5}; + const int value[4] = {1,4,5,7}; + myGroup.setNumber(index,value); + myMeshing->addGroup(myGroup); + } + { + MEDMEM::GROUP myGroup; + myGroup.setName("OtherNodes"); + myGroup.setMesh(myMeshing); + myGroup.setEntity(MED_EN::MED_NODE); + myGroup.setNumberOfGeometricType(1); + MED_EN::medGeometryElement myTypes[1] = {MED_EN::MED_NONE}; + myGroup.setGeometricType(myTypes); + const int myNumberOfElements[1] = {3}; + myGroup.setNumberOfElements(myNumberOfElements); + const int index[1+1] = {1,4}; + const int value[3] = {2,3,6}; + myGroup.setNumber(index,value); + myMeshing->addGroup(myGroup); + } + + // groups of cells + { + MEDMEM::GROUP myGroup; + myGroup.setName("SomeCells"); + myGroup.setMesh(myMeshing); + myGroup.setEntity(MED_EN::MED_CELL); + myGroup.setNumberOfGeometricType(3); + MED_EN::medGeometryElement myTypes[3] = {MED_EN::MED_TETRA4,MED_EN::MED_PYRA5,MED_EN::MED_HEXA8}; + myGroup.setGeometricType(myTypes); + const int myNumberOfElements[3] = {4,1,2}; + myGroup.setNumberOfElements(myNumberOfElements); + const int index[3+1] = {1,5,6,8}; + const int value[4+1+2] = {2,7,8,12, 13, 15,16}; + myGroup.setNumber(index,value); + myMeshing->addGroup(myGroup); + } + { + MEDMEM::GROUP myGroup; + myGroup.setName("OtherCells"); + myGroup.setMesh(myMeshing); + myGroup.setEntity(MED_EN::MED_CELL); + myGroup.setNumberOfGeometricType(2); + MED_EN::medGeometryElement myTypes[] = {MED_EN::MED_TETRA4,MED_EN::MED_PYRA5}; + myGroup.setGeometricType(myTypes); + const int myNumberOfElements[] = {4,1}; + myGroup.setNumberOfElements(myNumberOfElements); + const int index[2+1] = {1,5,6}; + const int value[4+1] = {3,4,5,9, 14}; + myGroup.setNumber(index,value); + myMeshing->addGroup(myGroup); + } + + // groups of faces + { + MEDMEM::GROUP myGroup; + myGroup.setName("SomeFaces"); + myGroup.setMesh(myMeshing); + myGroup.setEntity(MED_EN::MED_FACE); + myGroup.setNumberOfGeometricType(2); + MED_EN::medGeometryElement myTypes[2] = {MED_EN::MED_TRIA3,MED_EN::MED_QUAD4}; + myGroup.setGeometricType(myTypes); + const int myNumberOfElements[2] = {2,3}; + myGroup.setNumberOfElements(myNumberOfElements); + const int index[2+1] = {1,3,6}; + const int value[2+3] = {2,4, 5,6,8}; + myGroup.setNumber(index,value); + myMeshing->addGroup(myGroup); + } + { + MEDMEM::GROUP myGroup; + myGroup.setName("OtherFaces"); + myGroup.setMesh(myMeshing); + myGroup.setEntity(MED_EN::MED_FACE); + myGroup.setNumberOfGeometricType(1); + MED_EN::medGeometryElement myTypes[1] = {MED_EN::MED_TRIA3}; + myGroup.setGeometricType(myTypes); + const int myNumberOfElements[1] = {2}; + myGroup.setNumberOfElements(myNumberOfElements); + const int index[1+1] = {1,3}; + const int value[2] = {1,3}; + myGroup.setNumber(index,value); + myMeshing->addGroup(myGroup); + } + + return myMeshing; +} + +/*! + * Tool to remove temporary files. + * Allows automatique removal of temporary files in case of test failure. + */ +MEDMEMTest_TmpFilesRemover::~MEDMEMTest_TmpFilesRemover() +{ + set<string>::iterator it = myTmpFiles.begin(); + for (; it != myTmpFiles.end(); it++) { + if (access((*it).data(), F_OK) == 0) + remove((*it).data()); + } + myTmpFiles.clear(); + //cout << "~MEDMEMTest_TmpFilesRemover()" << endl; +} + +bool MEDMEMTest_TmpFilesRemover::Register(const string theTmpFile) +{ + return (myTmpFiles.insert(theTmpFile)).second; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest.hxx b/src/MEDMEMCppTest/MEDMEMTest.hxx new file mode 100644 index 000000000..590c51440 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest.hxx @@ -0,0 +1,206 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#ifndef _MEDMEMTEST_HXX_ +#define _MEDMEMTEST_HXX_ + +#include <cppunit/extensions/HelperMacros.h> + +#include <set> +#include <string> +//#include <ostream> +#include <iostream> + +namespace MEDMEM { + class MESH; +}; + +class MEDMEMTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( MEDMEMTest ); + //0 + CPPUNIT_TEST( testArray ); + CPPUNIT_TEST( testArrayConvert ); + //CPPUNIT_TEST( testArrayInterface /* not in spec */ ); + CPPUNIT_TEST( testAsciiFieldDriver ); + //CPPUNIT_TEST( testCellModel /* not in spec */ ); + CPPUNIT_TEST( testConnectivity ); + CPPUNIT_TEST( testCoordinate ); + CPPUNIT_TEST( testDriverFactory ); + //CPPUNIT_TEST( testDriversDef /* not in spec */ ); + //10 + //CPPUNIT_TEST( testDriverTools /* not in spec */ ); + //CPPUNIT_TEST( testException /* not in spec */ ); + CPPUNIT_TEST( testFamily ); + CPPUNIT_TEST( testField ); + CPPUNIT_TEST( testFieldConvert ); + CPPUNIT_TEST( testFormulae ); + CPPUNIT_TEST( testGaussLocalization ); + CPPUNIT_TEST( testGibiMeshDriver ); + //20 + //CPPUNIT_TEST( testGrid ); + CPPUNIT_TEST( testGroup ); + CPPUNIT_TEST( testIndexCheckingPolicy ); + CPPUNIT_TEST( testInit /* cxx */ ); + //CPPUNIT_TEST( testInterlacingPolicy /* not in spec */ ); + //CPPUNIT_TEST( testInterlacingTraits /* not in spec */ ); + CPPUNIT_TEST( testMedFieldDriver21 ); + CPPUNIT_TEST( testMedFieldDriver22 ); + //CPPUNIT_TEST( testMedFieldDriver /* not in spec */ ); + CPPUNIT_TEST( testMed ); + //30 + CPPUNIT_TEST( testMedMedDriver21 ); + CPPUNIT_TEST( testMedMedDriver22 ); + //CPPUNIT_TEST( testMedMedDriver /* not in spec */ ); + //CPPUNIT_TEST( testMEDMEMchampLire /* not in spec */ ); + //CPPUNIT_TEST( testMEDMEMgaussEcr /* not in spec */ ); + //CPPUNIT_TEST( testMEDMEMprofilEcr /* not in spec */ ); + CPPUNIT_TEST( testMedMeshDriver21 ); + CPPUNIT_TEST( testMedMeshDriver22 ); + //CPPUNIT_TEST( testMedMeshDriver /* not in spec */ ); + CPPUNIT_TEST( testMedVersion ); + //40 + CPPUNIT_TEST( testMeshAndMeshing ); + CPPUNIT_TEST( testModulusArray ); + CPPUNIT_TEST( testnArray ); + CPPUNIT_TEST( testPointerOf ); + CPPUNIT_TEST( testPolyhedronArray ); + CPPUNIT_TEST( testPorflowMeshDriver ); + //CPPUNIT_TEST( testRCBase /* not in spec */ ); + //CPPUNIT_TEST( testSetInterlacingType /* not in spec */ ); + CPPUNIT_TEST( testSkyLineArray ); + //50 + CPPUNIT_TEST( testSTRING ); + CPPUNIT_TEST( testSupport ); + //CPPUNIT_TEST( testTags /* not in spec */ ); + //CPPUNIT_TEST( testTopLevel ); + // CPPUNIT_TEST( testTypeMeshDriver ); + CPPUNIT_TEST( testUnit ); + CPPUNIT_TEST( testVtkFieldDriver ); + CPPUNIT_TEST( testVtkMedDriver ); + CPPUNIT_TEST( testVtkMeshDriver ); + //CPPUNIT_TEST( testmedimport_src /* not in spec */ ); + //60 + CPPUNIT_TEST( testExtractor ); + CPPUNIT_TEST_SUITE_END(); + +public: + + void setUp(); + void tearDown(); + + void testArray(); + void testArrayConvert(); + //void testArrayInterface() /* not in spec */; + void testAsciiFieldDriver(); + //void testCellModel() /* not in spec */; + void testConnectivity(); + void testCoordinate(); + void testDriverFactory(); + //void testDriversDef() /* not in spec */; + //10 + //void testDriverTools() /* not in spec */; + void testException() /* not in spec */; + void testFamily(); + void testField(); + void testFieldConvert(); + void testFormulae(); + void testGaussLocalization(); + void testGibiMeshDriver(); + //20 + void testGrid(); + void testGroup(); + void testIndexCheckingPolicy(); + void testInit() /* cxx */; + //void testInterlacingPolicy() /* not in spec */; + //void testInterlacingTraits() /* not in spec */; + void testMedFieldDriver21(); + void testMedFieldDriver22(); + //void testMedFieldDriver /* not in spec */(); + void testMed(); + //30 + void testMedMedDriver21(); + void testMedMedDriver22(); + //void testMedMedDriver() /* not in spec */; + //void testMEDMEMchampLire() /* not in spec */; + //void testMEDMEMgaussEcr() /* not in spec */; + //void testMEDMEMprofilEcr() /* not in spec */; + void testMedMeshDriver21(); + void testMedMeshDriver22(); + //void testMedMeshDriver() /* not in spec */; + void testMedVersion(); + //40 + void testMeshAndMeshing(); + void testModulusArray(); + void testnArray(); + void testPointerOf(); + void testPolyhedronArray(); + void testPorflowMeshDriver(); + //void testRCBase() /* not in spec */; + //void testSetInterlacingType /* IMED_MESH_RDWR_DRIVER(driver), not in spec */(); + void testSkyLineArray(); + //50 + void testSTRING(); + void testSupport(); + //void testTags() /* not in spec */; + void testTopLevel(); + void testTypeMeshDriver(); + void testUnit(); + void testVtkFieldDriver(); + void testVtkMedDriver(); + void testVtkMeshDriver(); + //void testmedimport_src() /* not in spec */; + //60 + void testExtractor(); +}; + +// to create a mesh with certain filling +MEDMEM::MESH * MEDMEMTest_createTestMesh(); + +// to automatically remove temporary files from disk +class MEDMEMTest_TmpFilesRemover +{ +public: + MEDMEMTest_TmpFilesRemover() {} + ~MEDMEMTest_TmpFilesRemover(); + bool Register(const std::string theTmpFile); + +private: + std::set<std::string> myTmpFiles; +}; + +/*! + * Tool to print array to stream. + */ +template<class T> +void MEDMEMTest_DumpArray (std::ostream & stream, const T* array, const int length, const std::string text) +{ + stream << text << ": {"; + if (length > 0) { + stream << array[0]; + for (int i = 1; i < length; i++) { + stream << ", " << array[i]; + } + } + stream << "}" << std::endl; +}; + +#endif diff --git a/src/MEDMEMCppTest/MEDMEMTest_Array.cxx b/src/MEDMEMCppTest/MEDMEMTest_Array.cxx new file mode 100644 index 000000000..321a3f13d --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Array.cxx @@ -0,0 +1,677 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "MEDMEM_nArray.hxx" +#include "MEDMEM_ArrayConvert.hxx" +#include "MEDMEM_Array.hxx" +//#include "MEDMEM_ArrayInterface.hxx" +#include "MEDMEM_STRING.hxx" + +#include <sstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; + +// #1,2,3: MEDMEMTest_Array.cxx +// Check methods from MEDMEM_Array.hxx, MEDMEM_ArrayConvert.hxx, MEDMEM_ArrayInterface.hxx + +/*! + * Check methods (20), defined in MEDMEM_Array.hxx: + * template <class T> class MEDARRAY { + * (+) inline MEDARRAY(); + * (+) inline ~MEDARRAY(); + * (+) MEDARRAY (const int ld_values, const int length_values, + * const MED_EN::medModeSwitch mode=MED_EN::MED_FULL_INTERLACE); + * (+) MEDARRAY (T* values, const int ld_values, + * const int length_values, const MED_EN::medModeSwitch mode=MED_EN::MED_FULL_INTERLACE, + * bool shallowCopy=false, bool ownershipOfValues=false); + * (+) MEDARRAY (MEDARRAY const &m); + * (+) MEDARRAY (MEDARRAY const &m, bool copyOther); + * (+) MEDARRAY & operator = (const MEDARRAY & m); + * (+) MEDARRAY & shallowCopy(const MEDARRAY & m); + * (+) inline int getLeadingValue() const; + * (+) inline int getLengthValue() const; + * (+) const T * get (const MED_EN::medModeSwitch mode); + * (+) const T * getRow (const int i); + * (+) const T * getColumn (const int j); + * (+) const T getIJ (const int i, const int j) const; + * (+) inline MED_EN::medModeSwitch getMode() const; + * (+) void set (const MED_EN::medModeSwitch mode,const T* value); + * (+) void setI (const int i, const T* value); + * (+) void setJ (const int j, const T* value); + * (+) void setIJ (const int i, const int j, const T value); + * (+) void calculateOther(); + * (+) bool isOtherCalculated() const {return (const T*)_valuesOther != NULL;} + * (+) void clearOtherMode(); + * } + * + * Use code of MEDMEM/tests/testUArray.cxx, + * MEDMEM/test_MEDMEM_Array.cxx + */ +void MEDMEMTest::testArray() +{ + int SpaceDimension = 3; + int NumberOfNodes = 4; + + //////////// + // TEST 1 // + //////////// + + /* ---------------------------------------------------------- */ + /* */ + /* INITIALISATION */ + /* */ + /* - constructeur new MEDARRAY<int>(int,int,mode) */ + /* - get sur le pointeur MED_FULL_INTERLACE */ + /* - initialisation des valeurs (coordonnées ieme elt = I+1) */ + /* - get sur le pointeur MED_NO_INTERLACE */ + /* ---------------------------------------------------------- */ + + MEDARRAY<int> * myArrayfull = + new MEDARRAY<int> (SpaceDimension, NumberOfNodes, MED_EN::MED_FULL_INTERLACE); + CPPUNIT_ASSERT(myArrayfull != NULL); + + const int * myValues = myArrayfull->get(MED_EN::MED_FULL_INTERLACE); + CPPUNIT_ASSERT(myValues != NULL); + + for (int i = 0; i < NumberOfNodes; i++) { + for (int k = 0; k < SpaceDimension; k++) { + myArrayfull->setIJ(i+1, k+1, i+1); + } + } + + const int * myOthers = myArrayfull->get(MED_EN::MED_NO_INTERLACE); + CPPUNIT_ASSERT(myOthers != NULL); + + MEDARRAY<int> * myArrayno = new MEDARRAY<int>(SpaceDimension, NumberOfNodes, MED_EN::MED_NO_INTERLACE); + CPPUNIT_ASSERT(myArrayno != NULL); + const int * myValuesno = myArrayno->get(MED_EN::MED_NO_INTERLACE); + CPPUNIT_ASSERT(myValuesno != NULL); + + for (int k = 0; k < SpaceDimension; k++) { + for (int i = 0; i < NumberOfNodes; i++) { + myArrayno->setIJ(i+1, k+1, k+1); + } + } + + const int * myOthersno = myArrayno->get(MED_EN::MED_FULL_INTERLACE); + CPPUNIT_ASSERT(myOthersno != NULL); + + /* ---------------------------------------------------------- */ + /* */ + /* Tests des Fonctions Set */ + /* */ + /* - setI sur l'element 1 avec des coordonnees a 100 */ + /* - setJ sur l'element 1 avec des coordonnees a 100 */ + /* - setIJ sur (1,2) avec une coordonnee = 1992 */ + /* - set avec l ensemble des coordonnes remises à i */ + /* ---------------------------------------------------------- */ + + int * myNewLine = new int[SpaceDimension]; + for (int i = 0; i < SpaceDimension; i++) + myNewLine[i] = myValues[i] * 100; + try + { + myArrayfull->setI(1, myNewLine); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception in myArrayfull->setI()"); + } + + delete [] myNewLine; + + int * myNewCol = new int[NumberOfNodes]; + for (int i = 0; i < NumberOfNodes; i++) + myNewCol[i] = 100; + try + { + myArrayno->setJ(1, myNewCol); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception in myArrayno->setJ()"); + } + + delete [] myNewCol; + + try + { + myArrayfull->setIJ(1, 2, 1992); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception in myArrayfull->setIJ()"); + } + + try + { + myArrayno->setIJ(1, 2, 1992); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception in myArrayno->setIJ()"); + } + + int * mynewvalues = new int [ NumberOfNodes*SpaceDimension ]; + for (int i = 0; i < NumberOfNodes*SpaceDimension; i++) { + mynewvalues[i] = i; + } + try + { + myArrayfull->set(MED_EN::MED_FULL_INTERLACE, mynewvalues); + myValues = myArrayfull->get(MED_EN::MED_FULL_INTERLACE); + myOthers = myArrayfull->get(MED_EN::MED_NO_INTERLACE); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + myArrayno->set(MED_EN::MED_FULL_INTERLACE, mynewvalues); + myValuesno = myArrayfull->get(MED_EN::MED_FULL_INTERLACE); + myOthersno = NULL; + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + /* ---------------------------------------------------------- */ + /* */ + /* Tests des constructeurs */ + /* Tests des Fonctions Get */ + /* */ + /* ---------------------------------------------------------- */ + + // check sharing + MEDARRAY<int> * myArrayShare = new MEDARRAY<int>(*myArrayfull); + const int * sharevalues = myArrayShare->get(MED_EN::MED_FULL_INTERLACE); + const int * shareno = myArrayShare->get(MED_EN::MED_NO_INTERLACE); + + myArrayfull->setIJ(1, 2, 1993); + CPPUNIT_ASSERT(myArrayShare->getIJ(1,2) == 1993); + + myArrayShare->setIJ(1, 2, 1995); + CPPUNIT_ASSERT(myArrayfull->getIJ(1,2) == 1995); + + delete myArrayShare; + + // check no sharing + MEDARRAY<int> * myArrayShare2 = new MEDARRAY<int>(*myArrayfull, true); + sharevalues = myArrayShare2->get(MED_EN::MED_FULL_INTERLACE); + shareno = myArrayShare2->get(MED_EN::MED_NO_INTERLACE); + + myArrayfull->setIJ(1, 2, 18); + CPPUNIT_ASSERT(myArrayShare2->getIJ(1,2) == 1995); + myArrayShare2->setIJ(1, 2, 19); + CPPUNIT_ASSERT(myArrayfull->getIJ(1,2) == 18); + + // check myArrayno + myArrayno->set(MED_EN::MED_NO_INTERLACE, mynewvalues); + myArrayno->setIJ(2, 1, 1); + myValuesno = myArrayno->get(MED_EN::MED_NO_INTERLACE); + myOthersno = myArrayno->get(MED_EN::MED_FULL_INTERLACE); + + MEDARRAY<int> * myArrayShare3 = new MEDARRAY<int>(*myArrayno); + sharevalues = myArrayShare3->get(MED_EN::MED_FULL_INTERLACE); + shareno = myArrayShare3->get(MED_EN::MED_NO_INTERLACE); + + myArrayno->setIJ(1, 2, 1992); + CPPUNIT_ASSERT(myArrayShare3->getIJ(1,2) == 1992); + + myArrayShare3->setIJ(1, 2, 1995); + CPPUNIT_ASSERT(myArrayno->getIJ(1,2) == 1995); + + delete myArrayno; + delete [] mynewvalues; + delete myArrayfull; + delete myArrayShare2; + delete myArrayShare3; + + + //////////// + // TEST 2 // + //////////// + + MEDARRAY<int> * myArray = + new MEDARRAY<int> (SpaceDimension, NumberOfNodes, MED_EN::MED_FULL_INTERLACE); + + // - 1 1 1 + // - 2 2 2 + // - 3 3 3 + // - 4 4 4 + for (int i = 1; i <= NumberOfNodes; i++) + for (int j = 1; j <= SpaceDimension; j++) + myArray->setIJ(i, j, i); + + CPPUNIT_ASSERT(myArray->getLengthValue() == NumberOfNodes); + CPPUNIT_ASSERT(myArray->getLeadingValue() == SpaceDimension); + + int numberof = myArray->getLeadingValue(); // nb. of columns ~ space dimension + for (int i = 1; i <= myArray->getLengthValue(); i++) { + const int * node = myArray->getRow(i); + for (int j = 0; j < numberof; j++) { + CPPUNIT_ASSERT(node[j] == i); + } + } + + numberof = myArray->getLengthValue(); // nb. of rows ~ nb. of nodes + for (int i = 1; i <= myArray->getLeadingValue(); i++) { + const int * node = myArray->getColumn(i); + for (int j = 0; j < numberof; j++) { + CPPUNIT_ASSERT(node[j] == j + 1); + } + } + + numberof = myArray->getLeadingValue(); + for (int i = 1; i <= myArray->getLengthValue(); i++) { + for (int j = 1; j < numberof + 1; j++) { + CPPUNIT_ASSERT(myArray->getIJ(i,j) == i); + } + } + + numberof = myArray->getLeadingValue(); + int length = myArray->getLengthValue(); + const int * NoInterlaceArray = myArray->get(MED_EN::MED_NO_INTERLACE); + for (int i = 0; i < length; i++) { + for (int j = 0; j < numberof; j++) { + CPPUNIT_ASSERT(NoInterlaceArray[j*length+i] == i + 1); + } + } + + delete myArray; + + + //////////// + // TEST 3 // + //////////// + + // MEDARRAY (T* values, const int ld_values, + // const int length_values, const MED_EN::medModeSwitch mode=MED_EN::MED_FULL_INTERLACE, + // bool shallowCopy=false, bool ownershipOfValues=false); + + int ld = 7, nb = 4; + double rr = 13.0, h0 = 7.0; + double * aValues = new double [ld * nb]; + for (int nn = 0; nn < nb; nn++) { + aValues[nn*ld + 0] = nn; + aValues[nn*ld + 1] = rr * cos(nn * M_PI/4.); + aValues[nn*ld + 2] = rr * sin(nn * M_PI/4.); + aValues[nn*ld + 3] = h0 + nn; + aValues[nn*ld + 4] = 2.0 * rr * cos(nn * M_PI/4.); + aValues[nn*ld + 5] = 2.0 * rr * sin(nn * M_PI/4.); + aValues[nn*ld + 6] = h0 - nn; + } + + MEDARRAY<double> * aSpiral = + new MEDARRAY<double> (aValues, ld, nb, MED_EN::MED_FULL_INTERLACE, + /*shallowCopy=*/false, /*ownershipOfValues=*/false); + ///*shallowCopy=*/true, /*ownershipOfValues=*/true); + + if (aSpiral->isOtherCalculated()) + aSpiral->clearOtherMode(); + CPPUNIT_ASSERT(!aSpiral->isOtherCalculated()); + + CPPUNIT_ASSERT(aSpiral->getMode() == MED_EN::MED_FULL_INTERLACE); + aSpiral->calculateOther(); + CPPUNIT_ASSERT(aSpiral->getMode() == MED_EN::MED_FULL_INTERLACE); + CPPUNIT_ASSERT(aSpiral->getLeadingValue() == ld); + CPPUNIT_ASSERT(aSpiral->getLengthValue() == nb); + + //CPPUNIT_ASSERT_DOUBLES_EQUAL(expected, actual, delta); + double delta = 0.000001; + const double* comp5 = aSpiral->getColumn(5); + for (int nn = 0; nn < nb; nn++) { + const double* pnt = aSpiral->getRow(nn + 1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.0 * rr * cos(nn * M_PI/4.), pnt[4], delta); + CPPUNIT_ASSERT_DOUBLES_EQUAL(comp5[nn], pnt[4], delta); + } + + // Check operator= and method shallowCopy() + double c7n3 = aSpiral->getIJ(3, 7); + MEDARRAY<double> shc, cpy; + + //#ifdef ENABLE_FAULTS + // (BUG) MEDARRAY<T>::shallowCopy() usage leads to memory leaks, + // because on attemp to free both arrays we have Segmentation Fault + + // EAP: It's misusage of shallowcopy - BUT what is a correct usage ??? + // TODO: check ownership of qrgument + //???skl shc.shallowCopy(*aSpiral); + + // hangs up + //MEDARRAY<double> arr (10, 10); + //MEDARRAY<double> shc; + //shc.shallowCopy(arr); + + // Segmentation fault + //MEDARRAY<double>* arr = new MEDARRAY<double> (10, 10); + //MEDARRAY<double>* shc = new MEDARRAY<double> (10, 10); + //shc->shallowCopy(*arr); + //delete arr; + //delete shc; + //#endif + //#ifdef ENABLE_FORCED_FAILURES + // CPPUNIT_FAIL("MEDARRAY<T>::shallowCopy(): wrong memory management"); + //#endif + + cpy = *aSpiral; + + aSpiral->setIJ(3, 7, c7n3 * 2.0); + + //#ifdef ENABLE_FAULTS + //???skl CPPUNIT_ASSERT_DOUBLES_EQUAL(c7n3 * 2.0, shc.getIJ(3, 7), delta); + //#endif + + //CPPUNIT_ASSERT_DOUBLES_EQUAL(c7n3 * 2.0, cpy.getIJ(3, 7), delta); + CPPUNIT_ASSERT_DOUBLES_EQUAL(c7n3, cpy.getIJ(3, 7), delta); + +// #ifdef ENABLE_FORCED_FAILURES +// // Comments to deep copy constructor do not correspond to actual implementation +// CPPUNIT_FAIL("Comments to MEDARRAY<T> deep copy constructor do not correspond to actual implementation"); +// #endif + + aSpiral->clearOtherMode(); + //CPPUNIT_ASSERT_THROW(MEDARRAY<double> co (*aSpiral, true), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(MEDARRAY<double> co (*aSpiral, true)); + + // invalid cases + //double arr3 [3] = {1., 2., 3.}; + double arr4 [4] = {1., 2., 3., 4.}; + double arr7 [7] = {1., 2., 3., 4., 5., 6., 7.}; + CPPUNIT_ASSERT_THROW(aSpiral->getRow(0), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSpiral->getRow(nb + 1), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSpiral->getColumn(0), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSpiral->getColumn(ld + 1), MEDEXCEPTION); + //CPPUNIT_ASSERT_THROW(aSpiral->set(MED_EN::MED_FULL_INTERLACE, NULL), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSpiral->setI(-1, arr7), MEDEXCEPTION); + //CPPUNIT_ASSERT_THROW(aSpiral->setI(1, NULL), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSpiral->setJ(-1, arr4), MEDEXCEPTION); + //CPPUNIT_ASSERT_THROW(aSpiral->setJ(1, NULL), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSpiral->setIJ(-1, -1, 13.), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSpiral->setIJ(1, 0, 13.), MEDEXCEPTION); + //CPPUNIT_ASSERT_THROW(aSpiral->setI(1, arr3), MEDEXCEPTION); // user must control itself + + delete aSpiral; + + // check empty array + + MEDARRAY<double> anEmptyArray; + //CPPUNIT_ASSERT_NO_THROW(MEDARRAY<double> anArr1 (anEmptyArray)); // INTERRUPTION + //CPPUNIT_ASSERT_NO_THROW(MEDARRAY<double> anArr2 (anEmptyArray, false)); // fails + //CPPUNIT_ASSERT_NO_THROW(MEDARRAY<double> anArr4 = anEmptyArray); // INTERRUPTION + //MEDARRAY<double> anArr5; + //CPPUNIT_ASSERT_NO_THROW(anArr5.shallowCopy(anEmptyArray)); + + // invalid cases + CPPUNIT_ASSERT_THROW(anEmptyArray.get(MED_EN::MED_FULL_INTERLACE), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(anEmptyArray.get(MED_EN::MED_NO_INTERLACE), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(anEmptyArray.getRow(0), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(anEmptyArray.getRow(5), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(anEmptyArray.getColumn(0), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(anEmptyArray.getIJ(0, 0), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(anEmptyArray.getIJ(1, 1), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(anEmptyArray.set(MED_EN::MED_FULL_INTERLACE, aValues)); + CPPUNIT_ASSERT_THROW(anEmptyArray.setI(1, aValues), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(anEmptyArray.setIJ(0, 0, 3.), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(anEmptyArray.setIJ(1, 1, 3.), MEDEXCEPTION); + + CPPUNIT_ASSERT_THROW(MEDARRAY<double> bad (-1, 10), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(MEDARRAY<double> bad (10, -1), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(MEDARRAY<double> bad (-1, -1), MEDEXCEPTION); + + delete [] aValues; + + // construction with taking ownership of values + int ld1 = 7, nb1 = 4; + double * val1 = new double [ld * nb]; + for (int nn = 0; nn < nb1; nn++) { + for (int cc = 0; cc < ld1; cc++) { + val1[nn*ld1 + cc] = nn; + } + } + MEDARRAY<double> * arr1 = + new MEDARRAY<double> (val1, ld1, nb1, MED_EN::MED_FULL_INTERLACE, + /*shallowCopy=*/true, /*ownershipOfValues=*/true); + for (int nn = 1; nn <= nb1; nn++) { + for (int cc = 1; cc <= ld1; cc++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(nn - 1, arr1->getIJ(nn, cc), delta); + } + } + delete arr1; +} + +/*! + * Check methods (4), defined in MEDMEM_ArrayConvert.hxx: + * + * (+) Gauss NoInterlace->FullInterlace: + * template <class T, class CHECKING_POLICY > + * MEDMEM_Array<T, FullInterlaceGaussPolicy, CHECKING_POLICY> * + * ArrayConvert(const MEDMEM_Array< T, NoInterlaceGaussPolicy, CHECKING_POLICY > &array, T* values=0) + * + * (+) Gauss FullInterlace->NoInterlace: + * template <class T, class CHECKING_POLICY> + * MEDMEM_Array<T, NoInterlaceGaussPolicy, CHECKING_POLICY> * + * ArrayConvert(const MEDMEM_Array< T, FullInterlaceGaussPolicy, CHECKING_POLICY > &array, T* values=0) + * + * (+) NoGauss FullInterlace->NoInterlace: + * template <class T, class CHECKING_POLICY> + * MEDMEM_Array<T, NoInterlaceNoGaussPolicy, CHECKING_POLICY> * + * ArrayConvert(const MEDMEM_Array< T, FullInterlaceNoGaussPolicy, CHECKING_POLICY > &array, T* values=0) + * + * (+) NoGauss NoInterlace->FullInterlace: + * template <class T, class CHECKING_POLICY> + * MEDMEM_Array<T, FullInterlaceNoGaussPolicy, CHECKING_POLICY> * + * ArrayConvert(const MEDMEM_Array< T, NoInterlaceNoGaussPolicy, CHECKING_POLICY > &array, T* values=0) + * + * Use code of MEDMEM/test_MEDMEM_nArray.cxx + */ +void MEDMEMTest::testArrayConvert() +{ + // TEST n°1 : FullInterlaceNoGaussPolicy -> NoInterlaceNoGaussPolicy + + const int mdim = 2; + const int nbelem1 = 20; + + const double array1Ref[] = { 11 , 12 , 21 , 22 , 31 , 32 , 41 , 42 , 51 , 52 , + 61 , 62 , 71 , 72 , 81 , 82 , 91 , 92 , 101, 102, + 111, 112, 121, 122, 131, 132, 141, 142, 151, 152, + 161, 162, 171, 172, 181, 182, 191, 192, 201, 202 }; + + const double array2Ref[] = { 11 , 21 , 31 , 41 , 51 , 61 , 71 , 81 , 91 , 101, + 111, 121, 131, 141, 151, 161, 171, 181, 191, 201, + 12 , 22 , 32 , 42 , 52 , 62 , 72 , 82 , 92 , 102, + 112, 122, 132, 142, 152, 162, 172, 182, 192, 202 }; + + MEDMEM_Array<double> myArray1 (mdim, nbelem1); + + for (int i = 1; i <= nbelem1; i++) + for (int j = 1; j <= mdim; j++) + myArray1.setIJ(i, j, i*10+j); + + const double * myArray1Ptr = myArray1.getPtr(); + for (int i = 0; i < mdim*nbelem1; i++) + CPPUNIT_ASSERT(myArray1Ptr[i] == array1Ref[i]); + + MEDMEM_Array<double, NoInterlaceNoGaussPolicy> * myArray1cin = ArrayConvert(myArray1); + myArray1Ptr = myArray1cin->getPtr(); + int elemno = 0; + for (int j = 1; j <= mdim; j++) { + for (int i = 1; i <= nbelem1; i++) { + CPPUNIT_ASSERT(myArray1cin->getIJ(i,j) == array2Ref[elemno]); + CPPUNIT_ASSERT(myArray1Ptr[elemno] == array2Ref[elemno]); + elemno++; + } + } + + // TEST n°2 : NoInterlaceNoGaussPolicy -> FullInterlaceNoGaussPolicy + + MEDMEM_Array<double, NoInterlaceNoGaussPolicy> myArray2 (mdim, nbelem1); + + for (int i = 1; i <= nbelem1; i++) + for (int j = 1; j <= mdim; j++) + myArray2.setIJ(i, j, i*10+j); + + const double * myArray2Ptr = myArray2.getPtr(); + for (int i = 0; i < mdim*nbelem1; i++) + CPPUNIT_ASSERT(myArray2Ptr[i] == array2Ref[i]); + + MEDMEM_Array<double, FullInterlaceNoGaussPolicy> * myArray2cin = ArrayConvert(myArray2); + myArray2Ptr = myArray2cin->getPtr(); + elemno = 0; + for (int i = 1; i <= nbelem1; i++) { + for (int j = 1; j <= mdim; j++) { + CPPUNIT_ASSERT(myArray2cin->getIJ(i,j) == array1Ref[elemno]); + CPPUNIT_ASSERT(myArray2Ptr[elemno] == array1Ref[elemno]); + elemno++; + } + } + + // TEST n°3 : FullInterlaceGaussPolicy -> NoInterlaceGaussPolicy + + const int nbelem2 = 5; + const int nbtypegeo = 2; + const int nbelgeoc[nbtypegeo+1] = {1,3,6}; + const int nbgaussgeo[nbtypegeo+1] = {-1,2,3}; + + const double * myArray3Ptr = 0; + const double array3Ref[] = { 1.11, 1.12, 1.21, 1.22, + 2.11, 2.12, 2.21, 2.22, + 13.11, 13.12, 13.21, 13.22, 13.31, 13.32, + 14.11, 14.12, 14.21, 14.22, 14.31, 14.32, + 15.11, 15.12, 15.21, 15.22, 15.31, 15.32 }; + + const double array4Ref[] = { 1.11, 1.21, 2.11, 2.21, + 13.11, 13.21, 13.31, 14.11, 14.21, 14.31, + 15.11, 15.21, 15.31, + 1.12, 1.22, 2.12, 2.22, + 13.12, 13.22, 13.32, 14.12, 14.22, 14.32, + 15.12, 15.22, 15.32 }; + + MEDMEM_Array<double, FullInterlaceGaussPolicy> myArray3 + (mdim, nbelem2, nbtypegeo, nbelgeoc, nbgaussgeo); + + elemno = 1; + for (int ntyp = 1; ntyp <= nbtypegeo; ntyp++) { + for (int i = 0; i < (nbelgeoc[ntyp]-nbelgeoc[ntyp-1]); i++) { + for (int k = 1; k <= nbgaussgeo[ntyp]; k++) { + for (int j = 1; j <= mdim; j++) { + myArray3.setIJK(elemno, j, k, elemno+(ntyp-1)*10+0.1*k+0.01*j); + } + } + elemno++; + } + } + myArray3Ptr = myArray3.getPtr(); + for (int i = 0; i < myArray3.getArraySize(); i++) + CPPUNIT_ASSERT( abs(myArray3Ptr[i] - array3Ref[i]) < 10^-7); + + MEDMEM_Array<double, NoInterlaceGaussPolicy> * myArray3cin = ArrayConvert(myArray3); + myArray3Ptr = myArray3cin->getPtr(); + elemno = 0; + for (int j = 1; j <= mdim; j++) + for (int i = 1; i < nbelgeoc[nbtypegeo]; i++) + for (int k = 1; k <= myArray3cin->getNbGauss(i); k++) { + CPPUNIT_ASSERT( abs(myArray3cin->getIJK(i,j,k) - array4Ref[elemno]) < 10^-7); + CPPUNIT_ASSERT( abs(myArray3Ptr[elemno] - array4Ref[elemno]) < 10^-7); + elemno++; + } + + // TEST n°4 : NoInterlaceGaussPolicy -> FullInterlaceGaussPolicy + + const double * myArray4Ptr = 0; + + MEDMEM_Array<double, NoInterlaceGaussPolicy> myArray4 + (mdim, nbelem2, nbtypegeo, nbelgeoc, nbgaussgeo); + + elemno = 1; + for (int ntyp = 1; ntyp <= nbtypegeo; ntyp++) { + for (int i = 0; i < (nbelgeoc[ntyp]-nbelgeoc[ntyp-1]); i++) { + for (int k = 1; k <= nbgaussgeo[ntyp]; k++) { + for (int j = 1; j <= mdim; j++) { + myArray4.setIJK(elemno, j, k, elemno+(ntyp-1)*10+0.1*k+0.01*j); + } + } + elemno++; + } + } + myArray4Ptr = myArray4.getPtr(); + + for (int i = 0; i < myArray4.getArraySize(); i++) + CPPUNIT_ASSERT( abs(myArray4Ptr[i] - array4Ref[i]) < 10^-7); + + MEDMEM_Array<double, FullInterlaceGaussPolicy> * myArray4cin = ArrayConvert(myArray4); + myArray4Ptr = myArray4cin->getPtr(); + elemno = 0; + for (int i = 1; i < nbelgeoc[nbtypegeo]; i++) + for (int k = 1; k <= myArray4cin->getNbGauss(i); k++) + for (int j = 1; j <= mdim; j++) { + CPPUNIT_ASSERT( abs(myArray4cin->getIJK(i,j,k) - array3Ref[elemno]) < 10^-7); + CPPUNIT_ASSERT( abs(myArray4cin->getIJK(i,j,k) - myArray3.getIJK(i,j,k)) < 10^-7); + CPPUNIT_ASSERT( abs(myArray4Ptr[elemno] - array3Ref[elemno]) < 10^-7); + elemno++; + } +} + +/*! + * Check methods (not in spec), defined in MEDMEM_ArrayInterface.hxx: + */ +//void MEDMEMTest::testArrayInterface() +//{ +// CPPUNIT_FAIL("Case Not Implemented (not in spec)"); +//} diff --git a/src/MEDMEMCppTest/MEDMEMTest_Array_fault.cxx b/src/MEDMEMCppTest/MEDMEMTest_Array_fault.cxx new file mode 100644 index 000000000..24a336949 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Array_fault.cxx @@ -0,0 +1,71 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_Array.hxx" + +#include <cmath> + +using namespace std; +using namespace MEDMEM; + +/*! + * Check method shallowCopy() + */ +int main (int argc, char** argv) +{ + int ld = 7, nb = 4; + double rr = 13.0, h0 = 7.0; + double * aValues = new double [ld * nb]; + for (int nn = 0; nn < nb; nn++) { + aValues[nn*ld + 0] = nn; + aValues[nn*ld + 1] = rr * cos(nn * M_PI/4.); + aValues[nn*ld + 2] = rr * sin(nn * M_PI/4.); + aValues[nn*ld + 3] = h0 + nn; + aValues[nn*ld + 4] = 2.0 * rr * cos(nn * M_PI/4.); + aValues[nn*ld + 5] = 2.0 * rr * sin(nn * M_PI/4.); + aValues[nn*ld + 6] = h0 - nn; + } + + MEDARRAY<double> * aSpiral = + new MEDARRAY<double> (aValues, ld, nb, MED_EN::MED_FULL_INTERLACE, + /*shallowCopy=*/false, /*ownershipOfValues=*/false); + + // Check method shallowCopy() + MEDARRAY<double> shc; + + // (BUG) MEDARRAY<T>::shallowCopy() usage leads to memory leaks, + // because on attempt to free both arrays we have Segmentation Fault + shc.shallowCopy(*aSpiral); + + delete aSpiral; + + // hangs up + //MEDARRAY<double> arr (10, 10); + //MEDARRAY<double> shc; + //shc.shallowCopy(arr); + + // Segmentation fault + //MEDARRAY<double>* arr = new MEDARRAY<double> (10, 10); + //MEDARRAY<double>* shc = new MEDARRAY<double> (10, 10); + //shc->shallowCopy(*arr); + //delete arr; + //delete shc; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_AsciiFieldDriver.cxx b/src/MEDMEMCppTest/MEDMEMTest_AsciiFieldDriver.cxx new file mode 100644 index 000000000..209d40ad2 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_AsciiFieldDriver.cxx @@ -0,0 +1,282 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "MEDMEM_Compatibility21_22.hxx" +#include "MEDMEM_AsciiFieldDriver.hxx" +#include "MEDMEM_STRING.hxx" + +#include <stdio.h> + +#include <sstream> +#include <fstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; + +// #4: MEDMEM_AsciiFieldDriver.hxx } MEDMEMTest_AsciiFieldDriver.cxx + +/*! + * Check methods (8), defined in MEDMEM_AsciiFieldDriver.hxx: + * + * (+) template<int N,unsigned int CODE> void fill(double *a, const double *b) + * (+) template<int N> bool compare(const double* a, const double* b) + * (+) template<> void fill<-1,0x3>(double *a, const double *b); + * (+) template<> bool compare<-1>(const double *a, const double *b); + * + * template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY> + * class SDForSorting { + * (+) SDForSorting(const double *coords, const T* comp, int nbComponents); + * (+) SDForSorting(const SDForSorting& other); + * (+) ~SDForSorting(); + * (+) bool operator< (const SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>& other) const; + * (+) void writeLine(ofstream& file) const; + * } + * + * template <class T> + * class ASCII_FIELD_DRIVER : public GENDRIVER { + * + * //MUST BE PRIVATE as there is no possibility to set _ptrField after this constructor usage + * (-) template <class INTERLACING_TAG> ASCII_FIELD_DRIVER(); + * + * (+) template <class INTERLACING_TAG> + * ASCII_FIELD_DRIVER(const string & fileName, FIELD<T,INTERLACING_TAG> * ptrField, + * MED_EN::med_sort_direc direction=MED_EN::ASCENDING, const char *priority=""); + * (+) ASCII_FIELD_DRIVER(const ASCII_FIELD_DRIVER<T>& other); + * (+) void open() throw (MEDEXCEPTION); + * (+) void close(); + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void write(void) const throw (MEDEXCEPTION); + * (+) GENDRIVER* copy() const; + * } + */ +void MEDMEMTest::testAsciiFieldDriver() +{ + // read a mesh from a MED file + string datadir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + string filename = datadir + "/share/salome/resources/med/pointe.med"; + string meshname = "maa1"; + string fieldname = "fieldcelldoublescalar"; + + if (tmp_dir == "") + tmp_dir = "/tmp"; + string anyfile1 = tmp_dir + "/anyfile1"; + string SDFfilename = tmp_dir + "/myfile"; + ofstream aFile(SDFfilename.c_str()); + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(anyfile1); + aRemover.Register(SDFfilename); + + //Test SDForSorting class + { + double coord_1[10] = { 1.0, 2.0, + -1.0, 2.0, + 3.6, -8.7, + 10.0, -10.0, + 12.3, 9.3}; + + int comp_1[5] = {1, 3, 5, 7, 9}; + SDForSorting<int, 2, 48> aSDF_1(coord_1, comp_1, 5); + + SDForSorting<int, 2, 48> aSDFCpy_1 = SDForSorting<int, 2, 48>(aSDF_1); + CPPUNIT_ASSERT_EQUAL(aSDFCpy_1 < aSDF_1, false); + CPPUNIT_ASSERT_NO_THROW(aSDF_1.writeLine(aFile)); + } + + // Why functions + // template<> void MEDMEM::fill<-1,0x3>(double *a, const double *b) + // and + // template<> bool MEDMEM::compare<-1>(const double *a, const double *b) + // declared in MEDMEM_AsciiFieldDriver.hxx, + // are implemented in MEDMEM_DriverFactory.cxx? + + // template<int N,unsigned int CODE> void fill(double *a, const double *b) + { + // 0x3 = 110000 + double aa[3]; + double bb[3] = {1,2,3}; + + fill<2,198>(aa, bb); // ZYX // 11000110 // 012 + //MEDMEMTest_DumpArray<double>(cout, aa, 3, "aa filled with ZYX"); + CPPUNIT_ASSERT_EQUAL(aa[0], bb[0]); + CPPUNIT_ASSERT_EQUAL(aa[1], bb[1]); + CPPUNIT_ASSERT_EQUAL(aa[2], bb[2]); + + fill<2,210>(aa, bb); // ZXY // 11010010 // 102 + //MEDMEMTest_DumpArray<double>(cout, aa, 3, "aa filled with ZXY"); + CPPUNIT_ASSERT_EQUAL(aa[0], bb[1]); + CPPUNIT_ASSERT_EQUAL(aa[1], bb[0]); + CPPUNIT_ASSERT_EQUAL(aa[2], bb[2]); + + fill<2,228>(aa, bb); // XYZ // 11100100 // 210 + //MEDMEMTest_DumpArray<double>(cout, aa, 3, "aa filled with XYZ"); + CPPUNIT_ASSERT_EQUAL(aa[0], bb[2]); + CPPUNIT_ASSERT_EQUAL(aa[1], bb[1]); + CPPUNIT_ASSERT_EQUAL(aa[2], bb[0]); + } + + printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + printf("1\n"); + printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + // template<int N> bool compare(const double* a, const double* b) + { + { + // aa < bb + double aa[8] = {1,1,1,1,1,1,1,1}; + double bb[8] = {1,1,1,1,1,1,1,2}; + CPPUNIT_ASSERT(compare<7>(aa, bb)); + } + + { + // aa < bb + double aa[8] = {1,1,1,1,1,1,1,1}; + double bb[8] = {2,1,1,1,1,1,1,1}; + CPPUNIT_ASSERT(compare<7>(aa, bb)); + } + + { + // aa > bb + double aa[8] = {2,1,1,1,1,1,1,1}; + double bb[8] = {1,1,1,1,1,1,1,1}; + CPPUNIT_ASSERT(!compare<7>(aa, bb)); + } + + { + // aa == bb + double aa[8] = {1,1,1,1,1,1,1,1}; + double bb[8] = {1,1,1,1,1,1,1,1}; + CPPUNIT_ASSERT(!compare<7>(aa, bb)); + } + + { + // compare<-1> + double aa[8] = {2,1,1,1,1,1,1,1}; + double bb[8] = {1,1,1,1,1,1,1,1}; + CPPUNIT_ASSERT(!compare<-1>(aa, bb)); + } + } + + // Test ASCII_FIELD_DRIVER + FIELD<double> * aField1 = new FIELD<double> (MED_DRIVER, filename, fieldname); + const SUPPORT * aSupport = aField1->getSupport(); + MESH * aMesh = new MESH (MED_DRIVER, filename, aSupport->getMeshName()); + aSupport->setMesh(aMesh); + + // create an ASCII driver for a field + ASCII_FIELD_DRIVER<double> * aDriver1 = + new ASCII_FIELD_DRIVER<double> (anyfile1, aField1, MED_EN::ASCENDING, ""); + CPPUNIT_ASSERT(aDriver1); + + CPPUNIT_ASSERT(aDriver1->getFileName() == anyfile1); + CPPUNIT_ASSERT(aDriver1->getAccessMode() == MED_EN::WRONLY); + + // and write the field on disk + + // must throw because the file is not opened + + CPPUNIT_ASSERT_THROW(aDriver1->write(), MEDEXCEPTION); + + aDriver1->open(); + + // must throw because the file is opened + CPPUNIT_ASSERT_THROW(aDriver1->setFileName("anyfile2"), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aDriver1->setFileName(anyfile1), MEDEXCEPTION); + + CPPUNIT_ASSERT_THROW(aDriver1->open(), MEDEXCEPTION); + + + // must throw because it is a writeonly driver + CPPUNIT_ASSERT_THROW(aDriver1->read(), MEDEXCEPTION); + + aDriver1->write(); + aDriver1->close(); + + // must throw because the file is not opened + + CPPUNIT_ASSERT_THROW(aDriver1->write(), MEDEXCEPTION); + + //CPPUNIT_ASSERT_THROW(aDriver1->close(), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aDriver1->close()); // do not make troubles to the user + + // check priority definition + int spaceDimension = aMesh->getSpaceDimension(); + if (spaceDimension == 3) { + // good + CPPUNIT_ASSERT_NO_THROW(ASCII_FIELD_DRIVER<double> aDriver2 + ("anyfile2", aField1, MED_EN::ASCENDING, "XYZ")); + // too long + CPPUNIT_ASSERT_THROW(ASCII_FIELD_DRIVER<double> aDriver3 + ("anyfile3", aField1, MED_EN::ASCENDING, "XYZX"), MEDEXCEPTION); + // too short + CPPUNIT_ASSERT_THROW(ASCII_FIELD_DRIVER<double> aDriver4 + ("anyfile4", aField1, MED_EN::ASCENDING, "XY"), MEDEXCEPTION); + // invalid +//#ifdef ENABLE_FORCED_FAILURES + // (BUG) This assert fails because 'A'(and 'B', and 'C') < 'X' + CPPUNIT_ASSERT_THROW(ASCII_FIELD_DRIVER<double> aDriver5 + ("anyfile5", aField1, MED_EN::ASCENDING, "ABC"), MEDEXCEPTION); +//#endif + } + else if (spaceDimension == 2) { + // good + CPPUNIT_ASSERT_NO_THROW(ASCII_FIELD_DRIVER<double> aDriver2 + ("anyfile2", aField1, MED_EN::ASCENDING, "XY")); + // too long + CPPUNIT_ASSERT_THROW(ASCII_FIELD_DRIVER<double> aDriver3 + ("anyfile3", aField1, MED_EN::ASCENDING, "XYZ"), MEDEXCEPTION); + // too short + CPPUNIT_ASSERT_THROW(ASCII_FIELD_DRIVER<double> aDriver4 + ("anyfile4", aField1, MED_EN::ASCENDING, "X"), MEDEXCEPTION); + // invalid +//#ifdef ENABLE_FORCED_FAILURES + // (BUG) Invalid string is accepted for priority + CPPUNIT_ASSERT_THROW(ASCII_FIELD_DRIVER<double> aDriver5 + ("anyfile5", aField1, MED_EN::ASCENDING, "AB"), MEDEXCEPTION); +//#endif + } + else { + CPPUNIT_FAIL("Cannot test ASCII_FIELD_DRIVER because file pointe.med" + " contains mesh of wrong dimension: must be 2 or 3"); + } + + //Copy constructor + ASCII_FIELD_DRIVER<double> aDriver1_Cpy1 = ASCII_FIELD_DRIVER<double> (*aDriver1); + + //Test copy() function + ASCII_FIELD_DRIVER<double> *aDriver1_Cpy2 = (ASCII_FIELD_DRIVER<double>*)aDriver1->copy(); + + // free memory + delete aDriver1; + delete aField1; + delete aMesh; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_Connectivity.cxx b/src/MEDMEMCppTest/MEDMEMTest_Connectivity.cxx new file mode 100644 index 000000000..60724398a --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Connectivity.cxx @@ -0,0 +1,1749 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "MEDMEM_Connectivity.hxx" +#include "MEDMEM_define.hxx" +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" + +#include <sstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; + +// #7: MEDMEM_Connectivity.hxx } MEDMEMTest_Connectivity.cxx + +/*! + * Check methods (56), defined in MEDMEM_Connectivity.hxx: + * class CONNECTIVITY { + * (+) friend ostream & operator<<(ostream &os, CONNECTIVITY &connectivity); + * (+) CONNECTIVITY (MED_EN::medEntityMesh Entity=MED_EN::MED_CELL); + * (+) CONNECTIVITY (int numberOfTypes, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL); + * (+) CONNECTIVITY (const CONNECTIVITY & m); + * (+) virtual ~CONNECTIVITY (); + * (+) void setConstituent (CONNECTIVITY * Constituent) throw (MEDEXCEPTION); + * (+) void setGeometricTypes (const MED_EN::medGeometryElement * Types, + * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); + * (+) void setCount (const int * Count, const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); + * (+) void setNodal (const int * Connectivity, + * const MED_EN::medEntityMesh Entity, + * const MED_EN::medGeometryElement Type) throw (MEDEXCEPTION); + * (+) inline void setNumberOfNodes(int NumberOfNodes); + * (+) inline int getEntityDimension() const; + * (+) inline void setEntityDimension(int EntityDimension); + * ----------------------------------------------------------------------------------------------------- + * (+) void setPolygonsConnectivity(MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity, + * const int* PolygonsConnectivity, + * const int* PolygonsConnectivityIndex, + * int ConnectivitySize, int NumberOfPolygons); + * (+) void setPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType, + * const int* PolyhedronConnectivity, + * const int* PolyhedronIndex, int ConnectivitySize, + * int NumberOfPolyhedron, + * const int* PolyhedronFacesIndex= (int*) NULL, + * int NumberOfFaces=0); + * ----------------------------------------------------------------------------------------------------- + * (+) inline bool existConnectivity (MED_EN::medConnectivity connectivityType, + * MED_EN::medEntityMesh Entity) const; + * (+) virtual bool existPolygonsConnectivity(MED_EN::medConnectivity connectivityType, + * MED_EN::medEntityMesh Entity) const; + * (+) virtual bool existPolyhedronConnectivity(MED_EN::medConnectivity connectivityType, + * MED_EN::medEntityMesh Entity) const; + * + * (+) virtual void calculateConnectivity (MED_EN::medConnectivity connectivityType, + * MED_EN::medEntityMesh Entity); + * (?) virtual void updateFamily (const vector<FAMILY*>& myFamilies); + * + * (+) inline MED_EN::medEntityMesh getEntity() const; + * ----------------------------------------------------------------------------------------------------- + * (+) inline int getNumberOfTypes (MED_EN::medEntityMesh Entity) const; + * (+) int getNumberOfTypesWithPoly(MED_EN::medEntityMesh Entity) const; + * (+) const int * getConnectivityOfAnElementWithPoly + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity, int Number, int &lgth); + * (+) int getNumberOfPolyType() const; + * (+) int getNumberOfElementsWithPoly(MED_EN::medEntityMesh Entity, + * MED_EN::medGeometryElement Type) const; + * (+) int getNumberOfElementOfPolyType(MED_EN::medEntityMesh Entity) const; + * ----------------------------------------------------------------------------------------------------- + * (+) inline const MED_EN::medGeometryElement * getGeometricTypes + * (MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION); + * (+) MED_EN::medGeometryElement * getGeometricTypesWithPoly + * (MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION); + * ----------------------------------------------------------------------------------------------------- + * (+) MED_EN::medGeometryElement getElementType (MED_EN::medEntityMesh Entity, int Number) const; + * (+) MED_EN::medGeometryElement getElementTypeWithPoly + * (MED_EN::medEntityMesh Entity, int Number) const; + * ----------------------------------------------------------------------------------------------------- + * (+) inline MED_EN::medGeometryElement getPolyTypeRelativeTo() const; + * ----------------------------------------------------------------------------------------------------- + * (+) virtual inline const int * getGlobalNumberingIndex + * (MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION); + * ----------------------------------------------------------------------------------------------------- + * (+) virtual const int * getConnectivity (MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity, + * MED_EN::medGeometryElement Type); + * (+) virtual int getConnectivityLength (MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity, + * MED_EN::medGeometryElement Type); + * (+) virtual const int * getConnectivityIndex (MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity); + * ----------------------------------------------------------------------------------------------------- + * (+) virtual const int* getPolygonsConnectivity(MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity); + * (+) virtual const int* getPolygonsConnectivityIndex(MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity); + * (+) virtual int getNumberOfPolygons(MED_EN::medEntityMesh Entity=MED_EN::MED_ALL_ENTITIES) const; + * ----------------------------------------------------------------------------------------------------- + * (+) virtual const int* getPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType) const; + * (+) virtual const int* getPolyhedronFacesIndex() const; + * (+) virtual const int* getPolyhedronIndex(MED_EN::medConnectivity ConnectivityType) const; + * (+) virtual int getNumberOfPolyhedronFaces() const; + * (+) virtual int getNumberOfPolyhedron() const; + * (+) int *getNodesOfPolyhedron(int polyhedronId, int& lgthOfTab) const; + * (+) int **getNodesPerFaceOfPolyhedron(int polyhedronId, int& nbOfFaces, + * int* & nbOfNodesPerFaces) const; + * ----------------------------------------------------------------------------------------------------- + * (+) const CELLMODEL & getType (MED_EN::medGeometryElement Type) const; + * (+) const CELLMODEL * getCellsTypes (MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION); + * (+) string * getCellTypeNames (MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION); + * (+) int getNumberOfNodesInType (MED_EN::medGeometryElement Type) const; + * (+) int getNumberOfSubCellInType (MED_EN::medGeometryElement Type) const; + * ----------------------------------------------------------------------------------------------------- + * (+) virtual int getNumberOf (MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type) const; + * ----------------------------------------------------------------------------------------------------- + * (+) virtual const int* getValue (MED_EN::medConnectivity TypeConnectivity, + * MED_EN::medGeometryElement Type); + * (+) virtual const int* getValueIndex (MED_EN::medConnectivity TypeConnectivity); + * ----------------------------------------------------------------------------------------------------- + * (+) virtual inline const int* getReverseConnectivity (MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) throw (MEDEXCEPTION); + * (+) virtual inline const int* getReverseConnectivityIndex (MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) throw (MEDEXCEPTION); + * (NOT YET IMPLEMENTED!!!) const int* getNeighbourhood() const; + * (+) void invertConnectivityForAFace(int faceId, const int *nodalConnForFace, bool polygonFace=false); + * ----------------------------------------------------------------------------------------------------- + * (+) bool deepCompare(const CONNECTIVITY& other) const; + * + * Use code of MEDMEM/test_MEDMEM_PolyConnectivity.cxx + * MEDMEM/test_copie_connectivity.cxx + * } + */ +void showConnectivity(CONNECTIVITY * myConnectivity, + int MeshDimension, int NumberOfNodes, MED_EN::medEntityMesh Entity, + int NumberOfTypes) +{ + int entityDim = myConnectivity->getEntityDimension(); + CPPUNIT_ASSERT_EQUAL(MeshDimension, entityDim); //? + + //int nodesNb = myConnectivity->getNumberOfElements(MED_EN::MED_NODE, MED_EN::MED_NONE); + int nodesNb = myConnectivity->getNumberOfElementsWithPoly(MED_EN::MED_NODE, MED_EN::MED_NONE); + CPPUNIT_ASSERT_EQUAL(NumberOfNodes, nodesNb); //? + + // MED_EN::MED_CELL + MED_EN::medEntityMesh entity = myConnectivity->getEntity(); + CPPUNIT_ASSERT_EQUAL(Entity, entity); + + int typesNb = myConnectivity->getNumberOfTypes(Entity); + CPPUNIT_ASSERT_EQUAL(NumberOfTypes, typesNb); + + const MED_EN::medGeometryElement * Types = myConnectivity->getGeometricTypes(Entity); + + // Show Nodal Connectivity + cout << "Show Nodal Connectivity :" << endl; + for (int i = 0; i < NumberOfTypes; i++) { + cout << "For type " << Types[i] << " : " << endl; + int NumberOfElements = myConnectivity->getNumberOf(Entity, Types[i]); + const int * connectivity = + myConnectivity->getConnectivity(MED_EN::MED_NODAL, Entity, Types[i]); + int NomberOfNodesPerCell = Types[i]%100; + for (int j = 0; j < NumberOfElements; j++) { + cout << "Element " << j+1 << " : "; + for (int k = 0; k < NomberOfNodesPerCell; k++) { + cout << connectivity[j*NomberOfNodesPerCell + k] << " "; + } + cout << endl; + } + } + + // Show Reverse Nodal Connectivity + cout << "Show Reverse Nodal Connectivity :" << endl; + const int * ReverseNodalConnectivity = + myConnectivity->getReverseConnectivity(MED_EN::MED_NODAL, Entity); + const int * ReverseNodalConnectivityIndex = + myConnectivity->getReverseConnectivityIndex(MED_EN::MED_NODAL, Entity); + for (int i = 0; i < NumberOfNodes; i++) { + cout << "Node "<< i+1 << " : "; + for (int j = ReverseNodalConnectivityIndex[i]; j < ReverseNodalConnectivityIndex[i+1]; j++) + cout << ReverseNodalConnectivity[j-1] << " "; + cout << endl; + } + + // Show Descending Connectivity + cout << "Show Connectivity (Descending) :" << endl; + int NumberOfElements; + const int * connectivity; + const int * connectivity_index; + myConnectivity->calculateConnectivity(MED_EN::MED_DESCENDING, Entity); + try { + NumberOfElements = myConnectivity->getNumberOf(Entity, MED_EN::MED_ALL_ELEMENTS); + connectivity = myConnectivity->getConnectivity(MED_EN::MED_DESCENDING, Entity, + MED_EN::MED_ALL_ELEMENTS); + connectivity_index = myConnectivity->getConnectivityIndex(MED_EN::MED_DESCENDING, Entity); + } + catch (MEDEXCEPTION m) { + CPPUNIT_FAIL(m.what()); + } + + for (int j = 0; j < NumberOfElements; j++) { + cout << "Element " << j+1 << " : "; + for (int k = connectivity_index[j]; k < connectivity_index[j+1]; k++) + cout << connectivity[k-1] << " "; + cout << endl; + } + + // Get constituent entity type and quantity + int NumberOfConstituents = 0; + string constituent; + MED_EN::medEntityMesh constituentEntity; + + if (MeshDimension == 3) { + constituent = "Face"; + constituentEntity = MED_EN::MED_FACE; + } + + if (MeshDimension == 2) { + constituent = "Edge"; + constituentEntity = MED_EN::MED_EDGE; + } + + if (MeshDimension == 1) { + MESSAGE_MED("ERROR : MeshDimension = 1 !"); + MESSAGE_MED("We could not see Reverse Descending Connectivity."); + return; + } + + // Show Reverse Descending Connectivity + cout << "Show Reverse Descending Connectivity :" << endl; + const int * ReverseDescendingConnectivity = + myConnectivity->getReverseConnectivity(MED_EN::MED_DESCENDING, Entity); + const int * ReverseDescendingConnectivityIndex = + myConnectivity->getReverseConnectivityIndex(MED_EN::MED_DESCENDING, Entity); + + NumberOfConstituents = myConnectivity->getNumberOf(constituentEntity, MED_EN::MED_ALL_ELEMENTS); + for (int i = 0; i < NumberOfConstituents; i++) { + cout << constituent << i+1 << " : "; + for (int j = ReverseDescendingConnectivityIndex[i]; + j < ReverseDescendingConnectivityIndex[i+1]; j++) { + cout << ReverseDescendingConnectivity[j-1] << " "; + } + cout << endl; + } + + // Show <constituent> Nodal Connectivity + cout << "Show " << constituent << " Connectivity (Nodal) :" << endl; + const int * face_connectivity = + myConnectivity->getConnectivity(MED_EN::MED_NODAL, constituentEntity, MED_EN::MED_ALL_ELEMENTS); + const int * face_connectivity_index = + myConnectivity->getConnectivityIndex(MED_EN::MED_NODAL, constituentEntity); + for (int i = 0; i < NumberOfConstituents; i++) { + cout << constituent << i+1 << " : "; + for (int j = face_connectivity_index[i]; j < face_connectivity_index[i+1]; j++) + cout << face_connectivity[j-1] << " "; + cout << endl; + } +} + +///////////////////////////////////////// +// TEST 2: test_copie_connectivity.cxx // +///////////////////////////////////////// +void checkCopyConnectivity() +{ + string datadir = getenv("MED_ROOT_DIR"); + string filename = datadir + "/share/salome/resources/med/pointe.med"; + string meshname = "maa1"; + + //Construction d'un maillage + MESH * myMesh = new MESH(); + myMesh->setName(meshname); + MED_MESH_RDONLY_DRIVER myMeshDriver (filename, myMesh); + myMeshDriver.setMeshName(meshname); + myMeshDriver.open(); + myMeshDriver.read(); //A partir d'ici la connectivité est construite + myMeshDriver.close(); + + int aMeshDimension = myMesh->getMeshDimension(); + int aNumberOfNodes = myMesh->getNumberOfNodes(); + + const CONNECTIVITY * myConnectivity0 = myMesh->getConnectivityptr(); + CONNECTIVITY * myConnectivity1 = const_cast<CONNECTIVITY *>(myConnectivity0); + + // DATA: + MED_EN::medEntityMesh anEntity0 = myConnectivity0->getEntity(); + + int nbOfTypes = myConnectivity0->getNumberOfTypes(anEntity0); + + // Show + cout << "myConnectivity1 BEGIN" << endl; + cout << *myConnectivity1 << endl; + cout << "myConnectivity1 END" << endl; + showConnectivity(myConnectivity1, aMeshDimension, aNumberOfNodes, anEntity0, nbOfTypes); + cout << "myConnectivity1 END 2" << endl; + + ostringstream ostr1; + ostr1 << *myConnectivity1; + CPPUNIT_ASSERT(ostr1.str() != ""); + + // COPY + CONNECTIVITY * myConnectivity2 = new CONNECTIVITY(* myConnectivity0); + + // Compare + CPPUNIT_ASSERT(myConnectivity2->deepCompare(*myConnectivity0)); + + // Compare after deleting the initial connectivity + delete myMesh; + myMesh = NULL; + myConnectivity0 = NULL; + + MED_EN::medEntityMesh anEntity2 = myConnectivity2->getEntity(); + CPPUNIT_ASSERT_EQUAL(anEntity0, anEntity2); + + cout << "myConnectivity2 BEGIN" << endl; + cout << *myConnectivity2 << endl; + cout << "myConnectivity2 END" << endl; + showConnectivity(myConnectivity2, aMeshDimension, aNumberOfNodes, anEntity0, nbOfTypes); + cout << "myConnectivity2 END 2" << endl; + + ostringstream ostr2; + ostr2 << *myConnectivity2; + CPPUNIT_ASSERT(ostr1.str() == ostr2.str()); + + // ONE MORE COPY + CONNECTIVITY * myConnectivity3 = new CONNECTIVITY(* myConnectivity2); + delete myConnectivity2; + + MED_EN::medEntityMesh anEntity3 = myConnectivity3->getEntity(); + CPPUNIT_ASSERT_EQUAL(anEntity0, anEntity3); + + cout << "myConnectivity3 BEGIN" << endl; + cout << *myConnectivity3 << endl; + cout << "myConnectivity3 END" << endl; + showConnectivity(myConnectivity3, aMeshDimension, aNumberOfNodes, anEntity0, nbOfTypes); + cout << "myConnectivity3 END 2" << endl; + + ostringstream ostr3; + ostr3 << *myConnectivity3; + CPPUNIT_ASSERT_EQUAL(ostr1.str(), ostr3.str()); + + delete myConnectivity3; +} + +void createOrCheck (CONNECTIVITY * theC, string msg, bool create = false) +{ + // Preconditions: Entity and NumberOfTypes + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, MED_EN::MED_CELL, theC->getEntity()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfTypes(MED_EN::MED_CELL)); + + // EntityDimension + if (create) + // It would be good to set EntityDimension automatically for EDGEs and FACEs, + // and warn about not set EntityDimension for CELLs + // (or calculate it from given geometric types) + theC->setEntityDimension(3); + else + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, theC->getEntityDimension()); + + // NumberOfNodes + int nbNodes = 20; + + if (create) { + theC->setNumberOfNodes(nbNodes); + } + else { + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nbNodes, theC->getNumberOfElementsWithPoly + (MED_EN::MED_NODE, MED_EN::MED_NONE)); + } + + // GeometricTypes + MED_EN::medGeometryElement aCellTypes[2] = {MED_EN::MED_PYRA5, MED_EN::MED_HEXA8}; + + // this variable is needed in check mode (!create) + // because of bug with getGlobalNumberingIndex() method (see below) + bool triaFirst = true; + + if (create) { + theC->setGeometricTypes(aCellTypes, MED_EN::MED_CELL); + CPPUNIT_ASSERT_THROW(theC->setGeometricTypes(aCellTypes, MED_EN::MED_NODE), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->setGeometricTypes(aCellTypes, MED_EN::MED_FACE), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->setGeometricTypes(aCellTypes, MED_EN::MED_EDGE), MEDEXCEPTION); + } + else { + // CELLS: theC + const MED_EN::medGeometryElement * aCellTypesBack = theC->getGeometricTypes(MED_EN::MED_CELL); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aCellTypes[0], aCellTypesBack[0]); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aCellTypes[1], aCellTypesBack[1]); + + const CELLMODEL * aCellModels = theC->getCellsTypes(MED_EN::MED_CELL); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aCellTypes[0], aCellModels[0].getType()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aCellTypes[1], aCellModels[1].getType()); + + string * aCellTypesNames = theC->getCellTypeNames(MED_EN::MED_CELL); + CPPUNIT_ASSERT_MESSAGE(msg, aCellTypesNames[0] == "MED_PYRA5"); + CPPUNIT_ASSERT_MESSAGE(msg, aCellTypesNames[1] == "MED_HEXA8"); + + // FACES: theC->_constituent + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfTypes(MED_EN::MED_FACE)); + const MED_EN::medGeometryElement * aFaceTypesBack = theC->getGeometricTypes(MED_EN::MED_FACE); + triaFirst = (aFaceTypesBack[0] == MED_EN::MED_TRIA3 && aFaceTypesBack[1] == MED_EN::MED_QUAD4); + CPPUNIT_ASSERT_MESSAGE(msg, triaFirst || (aFaceTypesBack[1] == MED_EN::MED_TRIA3 && + aFaceTypesBack[0] == MED_EN::MED_QUAD4)); + + const CELLMODEL * aFaceModels = theC->getCellsTypes(MED_EN::MED_FACE); + bool case1 = (aFaceModels[0].getType() == MED_EN::MED_TRIA3 && + aFaceModels[1].getType() == MED_EN::MED_QUAD4); + bool case2 = (aFaceModels[1].getType() == MED_EN::MED_TRIA3 && + aFaceModels[0].getType() == MED_EN::MED_QUAD4); + CPPUNIT_ASSERT_MESSAGE(msg, case1 || case2); + + string * aFaceTypesNames = theC->getCellTypeNames(MED_EN::MED_FACE); + CPPUNIT_ASSERT_MESSAGE(msg, + (aFaceTypesNames[0] == "MED_TRIA3" && aFaceTypesNames[1] == "MED_QUAD4") || + (aFaceTypesNames[1] == "MED_TRIA3" && aFaceTypesNames[0] == "MED_QUAD4")); + + // EDGES: theC->_constituent->_constituent + //CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, theC->getNumberOfTypes(MED_EN::MED_EDGE)); + //const MED_EN::medGeometryElement * anEdgeTypesBack = theC->getGeometricTypes(MED_EN::MED_EDGE); + //const CELLMODEL * anEdgeModels = theC->getCellsTypes(MED_EN::MED_EDGE); + + // invalid cases + CPPUNIT_ASSERT_THROW(theC->getGeometricTypes(MED_EN::MED_NODE), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getGeometricTypes(MED_EN::MED_ALL_ENTITIES), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getCellsTypes(MED_EN::MED_NODE), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getCellTypeNames(MED_EN::MED_ALL_ENTITIES), MEDEXCEPTION); + } + + // Nodal Connectivity for standard types + int countCells[3] = {1, 3, 4}; // 2 PYRA5 and 1 HEXA8 + int nodesCells_PYRA5[10] = {2,3,4,5,1, 6,7,8,9,10}; + int nodesCells_HEXA8[8] = {2,3,4,5, 6,7,8,9}; + + // .1 + // + // 3.---------.4 + // /| /| + // / | / | + // / | / | + // 2.---------.5 | + // | | | | + // | 7.-----|---.8 + // | / | / + // | / | / + // |/ |/ + // 6.---------.9 + // + // .10 + + // cells index will be: {1, 6, 11, 19} + + if (create) { + theC->setCount(countCells, MED_EN::MED_CELL); + theC->setNodal(nodesCells_PYRA5, MED_EN::MED_CELL, MED_EN::MED_PYRA5); + theC->setNodal(nodesCells_HEXA8, MED_EN::MED_CELL, MED_EN::MED_HEXA8); + + // Invalid cases + CPPUNIT_ASSERT_THROW(theC->setCount(countCells, MED_EN::MED_NODE), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->setCount(countCells, MED_EN::MED_EDGE), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->setCount(countCells, MED_EN::MED_FACE), MEDEXCEPTION); + + CPPUNIT_ASSERT_THROW(theC->setNodal(nodesCells_PYRA5, MED_EN::MED_FACE, MED_EN::MED_PYRA5), MEDEXCEPTION); + } + else { + // CELLS(3D): theC + CPPUNIT_ASSERT_MESSAGE(msg, theC->existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL)); + CPPUNIT_ASSERT_MESSAGE(msg, theC->existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL)); + + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_PYRA5)); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, theC->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_HEXA8)); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, theC->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS)); + + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfElementsWithPoly(MED_EN::MED_CELL, + MED_EN::MED_PYRA5)); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, theC->getNumberOfElementsWithPoly(MED_EN::MED_CELL, + MED_EN::MED_HEXA8)); + + // sorted by geometric type (order is given by the typedef enum medGeometryElement) + const int * countCellsBack = theC->getGlobalNumberingIndex(MED_EN::MED_CELL); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, countCells[0], countCellsBack[0]); // 1: always + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, countCells[1], countCellsBack[1]); // 3: +2 PYRA5 + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, countCells[2], countCellsBack[2]); // 4: +1 HEXA8 + + // nodal connectivity length + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 18, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_CELL, + MED_EN::MED_ALL_ELEMENTS)); + + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 10, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_CELL, + MED_EN::MED_PYRA5)); + + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 8, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_CELL, + MED_EN::MED_HEXA8)); + + // nodal connectivity index + const int * connAllIndex = theC->getConnectivityIndex(MED_EN::MED_NODAL, MED_EN::MED_CELL); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, connAllIndex[0]); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, connAllIndex[1]); // +5 nodes of PYRA5 + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 11, connAllIndex[2]); // +5 nodes of PYRA5 + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 19, connAllIndex[3]); // +8 nodes of HEXA8 + + // nodal connectivity + const int * connAll = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL, + MED_EN::MED_ALL_ELEMENTS); + const int * connPYRA5 = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL, + MED_EN::MED_PYRA5); + const int * connHEXA8 = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL, + MED_EN::MED_HEXA8); + for (int i = 0; i < 10; i++) { + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_PYRA5[i], connPYRA5[i]); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_PYRA5[i], connAll[i]); + } + for (int i = 0; i < 8; i++) { + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_HEXA8[i], connHEXA8[i]); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_HEXA8[i], connAll[10 + i]); + } + + // descending connectivity length + // 10 faces in 2 pyra + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 10, theC->getConnectivityLength + (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_PYRA5)); + // 6 faces in 1 hexa + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, theC->getConnectivityLength + (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_HEXA8)); + // 10 + 6 faces + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 16, theC->getConnectivityLength + (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS)); + + // descending connectivity index + const int * descAllIndex = theC->getConnectivityIndex(MED_EN::MED_DESCENDING, MED_EN::MED_CELL); + + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, descAllIndex[0]); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, descAllIndex[1]); // +5 faces of PYRA5 + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 11, descAllIndex[2]); // +5 faces of PYRA5 + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 17, descAllIndex[3]); // +6 faces of HEXA8 + + // descending connectivity + { + const int * descAll = theC->getConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL, + MED_EN::MED_ALL_ELEMENTS); + const int * descPYRA5 = theC->getConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL, + MED_EN::MED_PYRA5); + const int * descHEXA8 = theC->getConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL, + MED_EN::MED_HEXA8); + for (int i = 0; i < 10; i++) { + CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(descPYRA5[i]) && labs(descPYRA5[i]) < 16); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, descAll[i], descPYRA5[i]); + } + for (int i = 0; i < 6; i++) { + CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(descHEXA8[i]) && labs(descHEXA8[i]) < 16); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, descAll[10 + i], descHEXA8[i]); + } + } + + // FACES: theC->_constituent + CPPUNIT_ASSERT_MESSAGE(msg, theC->existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE)); + //CPPUNIT_ASSERT_MESSAGE(msg, theC->existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_FACE)); + + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 8, theC->getNumberOf(MED_EN::MED_FACE, MED_EN::MED_TRIA3)); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, theC->getNumberOf(MED_EN::MED_FACE, MED_EN::MED_QUAD4)); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 14, theC->getNumberOf(MED_EN::MED_FACE, MED_EN::MED_ALL_ELEMENTS)); + + // sorted by geometric type + const int * countFacesBack = theC->getGlobalNumberingIndex(MED_EN::MED_FACE); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, countFacesBack[0]); // always + + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 9, countFacesBack[1]); // +8 TRIA3 + + // check correspondance with types + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, triaFirst ? 9 : 7, countFacesBack[1]); // +8 TRIA3 or +6 QUAD4 + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 15, countFacesBack[2]); // 1+8+6 + + // nodal connectivity length // 8*3 + 6*4 + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 48, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_FACE, + MED_EN::MED_ALL_ELEMENTS)); + + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 24, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_FACE, + MED_EN::MED_TRIA3)); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 24, theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_FACE, + MED_EN::MED_QUAD4)); + + // nodal connectivity index + const int * connFaceAllIndex = theC->getConnectivityIndex(MED_EN::MED_NODAL, MED_EN::MED_FACE); + { + CPPUNIT_ASSERT(triaFirst); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, connFaceAllIndex[0]); + int typeChangeIndex = triaFirst ? 8 : 6; + int nbNodes1 = triaFirst ? 3 : 4; + int nbNodes2 = triaFirst ? 4 : 3; + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 25, connFaceAllIndex[typeChangeIndex]); // + 3*8 or 4*6 + for (int i = 1; i < 14; i++) { + if (i < typeChangeIndex) + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1 + i*nbNodes1, connFaceAllIndex[i]); + else + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 25 + (i-typeChangeIndex)*nbNodes2, connFaceAllIndex[i]); + } + // + 3*8 nodes of TRIA3 + 4*6 nodes of QUAD4 + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 49, connFaceAllIndex[14]); + } + + // nodal connectivity + const int * connFaceAll = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE, + MED_EN::MED_ALL_ELEMENTS); + const int * connTRIA3 = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE, + MED_EN::MED_TRIA3); + const int * connQUAD4 = theC->getConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE, + MED_EN::MED_QUAD4); + for (int i = 0; i < 24; i++) { + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, connFaceAll[ i], triaFirst ? connTRIA3[i] : connQUAD4[i]); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, connFaceAll[24+i], triaFirst ? connQUAD4[i] : connTRIA3[i]); + } + + // EDGES: theC->_constituent->_constituent + //CPPUNIT_ASSERT_MESSAGE(msg, theC->existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_EDGE)); + + // Invalid cases + CPPUNIT_ASSERT_MESSAGE(msg, !theC->existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_NODE)); + CPPUNIT_ASSERT_MESSAGE(msg, !theC->existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_EDGE)); + CPPUNIT_ASSERT_MESSAGE(msg, !theC->existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_NODE)); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 0, theC->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_TETRA4)); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 0, theC->getNumberOfElementsWithPoly(MED_EN::MED_CELL, + MED_EN::MED_TETRA4)); + CPPUNIT_ASSERT_THROW(theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_CELL, + MED_EN::MED_TRIA3), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getConnectivityLength(MED_EN::MED_DESCENDING, MED_EN::MED_CELL, + MED_EN::MED_NONE), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getConnectivityLength(MED_EN::MED_NODAL, MED_EN::MED_FACE, + MED_EN::MED_POLYGON), MEDEXCEPTION); + } + + // 2 POLYHEDRA + const int nbPolyhedron = 2; + const int nbPolyFaces = 14; + const int nbPolyNodes = 52; + + int aPolyhedronIndex[nbPolyhedron + 1] = {1,8,15}; + + int aPolyhedronFacesIndex[nbPolyFaces + 1] = {1,7,10,14,17,20,24, 27,33,36,40,43,46,50,53}; + + int aPolyhedronNodalConnectivity[nbPolyNodes] = { + 11,15,19,20,17,13, 11,13,14, 14,13,17,18, 18,17,20, 11,14,15, 15,14,18,19, 19,18,20, + 11,13,17,20,19,15, 11,12,13, 13,12,16,17, 17,16,20, 11,15,12, 12,15,19,16, 16,19,20}; + + // .11 + // + // 13.---------.14 + // /|\ /| + // / | \ / | + // / | \ / | + // 12.---------.15 | + // | | | | + // | 17.-----|---.18 + // | / \ | / + // | / \ | / + // |/ \|/ + // 16.---------.19 + // + // .20 + + if (create) { + theC->setPolyhedronConnectivity(MED_EN::MED_NODAL, aPolyhedronNodalConnectivity, + aPolyhedronIndex, nbPolyNodes, nbPolyhedron, + aPolyhedronFacesIndex, nbPolyFaces); + } + else { + // CELLS(3D): theC + { + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, theC->getNumberOfPolyType()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, theC->getNumberOfTypesWithPoly(MED_EN::MED_CELL)); + + { + const MED_EN::medGeometryElement * aCellTypesBack = theC->getGeometricTypesWithPoly(MED_EN::MED_CELL); + CPPUNIT_ASSERT_MESSAGE(msg, ((aCellTypesBack[0] == MED_EN::MED_PYRA5 && + aCellTypesBack[1] == MED_EN::MED_HEXA8) || + (aCellTypesBack[0] == MED_EN::MED_HEXA8 && + aCellTypesBack[1] == MED_EN::MED_PYRA5))); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, MED_EN::MED_POLYHEDRA, aCellTypesBack[2]); + } + + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfElementOfPolyType(MED_EN::MED_CELL)); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfElementsWithPoly(MED_EN::MED_CELL, + MED_EN::MED_POLYHEDRA)); + //checking that 0 is returned if polygons are asked as cells instead of faces + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 0, theC->getNumberOfElementsWithPoly(MED_EN::MED_CELL, + MED_EN::MED_POLYGON)); + + + int nbCellAll = 5; // 2 (PYRA5) + 1 (HEXA8) + 2 (POLYHEDRA) + + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nbCellAll, theC->getNumberOfElementsWithPoly + (MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS)); + + + // first PYRA5 {1,2,3,4,5} + { + int len; + const int * c1 = theC->getConnectivityOfAnElementWithPoly + (MED_EN::MED_NODAL, MED_EN::MED_CELL, /*Number*/1, len); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 5, len); + for (int i = 0; i < len; i++) { + if (c1[i] < 1 || 5 < c1[i]) CPPUNIT_FAIL(msg); + } + } + + // first POLYHEDRA + // This throws "NODAL Connectivity required for a polyhedron" + // Why? Because for polyhedron this has no sence without index? + { + int len; + CPPUNIT_ASSERT_THROW(theC->getConnectivityOfAnElementWithPoly + (MED_EN::MED_NODAL, MED_EN::MED_CELL, /*Number*/4, len), MEDEXCEPTION); + } + + // cells descending connectivity + for (int i = 1; i <= nbCellAll; i++) { + int len; + const int * ci = theC->getConnectivityOfAnElementWithPoly + (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, /*Number*/i, len); + + MED_EN::medGeometryElement aCurElemTypeWithPoly = theC->getElementTypeWithPoly(MED_EN::MED_CELL, i); + + if (i <= 3) { // nb.standard cells = 3 + MED_EN::medGeometryElement aCurElemType = theC->getElementType(MED_EN::MED_CELL, i); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aCurElemType, aCurElemTypeWithPoly); + // sign of connectivity array value means element direction + for (int j = 0; j < len; j++) { + CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(ci[j]) && labs(ci[j]) <= 14); // nb.standard faces = 14 + } + } + else { + CPPUNIT_ASSERT_THROW(theC->getElementType(MED_EN::MED_CELL, i), MEDEXCEPTION); + for (int j = 0; j < len; j++) { + CPPUNIT_ASSERT_MESSAGE(msg, 14 < labs(ci[j]) && labs(ci[j]) <= 27); // nb.polygons = 13 + } + } + + switch (aCurElemTypeWithPoly) { + case MED_EN::MED_PYRA5: CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 5, len); break; + case MED_EN::MED_HEXA8: CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, len); break; + case MED_EN::MED_POLYHEDRA: CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 7, len); break; + default: + CPPUNIT_FAIL(msg); // wrong element type + } + } + + // Polyhedron-specific methods + { + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfPolyhedron()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 14, theC->getNumberOfPolyhedronFaces()); + + // Nodal + + // PolyhedronIndex: array of size (NumberOfPolyhedron + 1) + const int* polyhNodalIndex = theC->getPolyhedronIndex(MED_EN::MED_NODAL); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, polyhNodalIndex[0]); // always + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 8, polyhNodalIndex[1]); // +7 faces + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 15, polyhNodalIndex[2]); // +7 faces (= NumberOfPolyhedronFaces + 1) + + // PolyhedronFacesIndex: array of size (NumberOfPolyhedronFaces + 1) + const int* polyhFacesIndex = theC->getPolyhedronFacesIndex(); + // 1, 7,10,14,17,20,24,27, 33,36,40,43,46,50,53 + for (int i = 0; i <= 14; i++) { + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aPolyhedronFacesIndex[i], polyhFacesIndex[i]); + } + + // Polyhedron Nodal Connectivity: array of size (NumberOfPolyhedronNodes) + int nbPolyhNodes = polyhFacesIndex[14] - 1; + const int* polyhNodalConn = theC->getPolyhedronConnectivity(MED_EN::MED_NODAL); + // 11,15,19,20,17,13, 11,13,14, 14,13,17,18, 18,17,20, 11,14,15, 15,14,18,19, 19,18,20, + // 11,13,17,20,19,15, 11,12,13, 13,12,16,17, 17,16,20, 11,15,12, 12,15,19,16, 16,19,20 + for (int i = 0; i < nbPolyhNodes; i++) { + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aPolyhedronNodalConnectivity[i], polyhNodalConn[i]); + } + + // getNodesOfPolyhedron + int lenPolyh1nodes, lenPolyh2nodes; + int * polyh1nodes = theC->getNodesOfPolyhedron(/*polyhedronId*/3+1, lenPolyh1nodes); + int * polyh2nodes = theC->getNodesOfPolyhedron(/*polyhedronId*/3+2, lenPolyh2nodes); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 8, lenPolyh1nodes); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 8, lenPolyh2nodes); + + set<int> polyh1nodesCheck; + set<int> polyh2nodesCheck; + + polyh1nodesCheck.insert(11); + polyh1nodesCheck.insert(13); + polyh1nodesCheck.insert(14); + polyh1nodesCheck.insert(15); + polyh1nodesCheck.insert(17); + polyh1nodesCheck.insert(18); + polyh1nodesCheck.insert(19); + polyh1nodesCheck.insert(20); + + polyh2nodesCheck.insert(11); + polyh2nodesCheck.insert(12); + polyh2nodesCheck.insert(13); + polyh2nodesCheck.insert(15); + polyh2nodesCheck.insert(16); + polyh2nodesCheck.insert(17); + polyh2nodesCheck.insert(19); + polyh2nodesCheck.insert(20); + + for (int i = 0; i < 8; i++) { + CPPUNIT_ASSERT_MESSAGE(msg, polyh1nodesCheck.count(polyh1nodes[i])); + CPPUNIT_ASSERT_MESSAGE(msg, polyh2nodesCheck.count(polyh2nodes[i])); + } + delete [] polyh1nodes; + delete [] polyh2nodes; + + // getNodesPerFaceOfPolyhedron + int nbFaces1, nbFaces2; + int *nbNodes1, *nbNodes2; // len = nb.faces (7) + int ** polyh1nodesPerFace = + theC->getNodesPerFaceOfPolyhedron(/*polyhedronId*/3+1, nbFaces1, nbNodes1); + int ** polyh2nodesPerFace = + theC->getNodesPerFaceOfPolyhedron(/*polyhedronId*/3+2, nbFaces2, nbNodes2); + + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 7, nbFaces1); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 7, nbFaces2); + + int nbNodesCheck [7] = {6,3,4,3,3,4,3}; + for (int i = 0; i < 7; i++) { + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nbNodesCheck[i], nbNodes1[i]); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nbNodesCheck[i], nbNodes2[i]); + + int startNode1 = aPolyhedronFacesIndex[0 + i] - 1; + int startNode2 = aPolyhedronFacesIndex[7 + i] - 1; + for (int j = 0; j < nbNodesCheck[i]; j++) { + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aPolyhedronNodalConnectivity[startNode1 + j], + polyh1nodesPerFace[i][j]); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aPolyhedronNodalConnectivity[startNode2 + j], + polyh2nodesPerFace[i][j]); + } + } + + delete [] nbNodes1; + delete [] nbNodes2; + delete [] polyh1nodesPerFace; + delete [] polyh2nodesPerFace; + + // invalid polyhedron Id + + int lenPolyh3nodes; + int nbFaces3; + int *nbNodes3; + + CPPUNIT_ASSERT_THROW(theC->getNodesOfPolyhedron(1, lenPolyh3nodes), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getNodesOfPolyhedron(3+3, lenPolyh3nodes), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getNodesPerFaceOfPolyhedron + (/*polyhedronId*/1, nbFaces3, nbNodes3), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getNodesPerFaceOfPolyhedron + (/*polyhedronId*/3+3, nbFaces3, nbNodes3), MEDEXCEPTION); + + + // Descending + + // PolyhedronIndex: array of size (NumberOfPolyhedron + 1) + const int* polyhDesceIndex = theC->getPolyhedronIndex(MED_EN::MED_DESCENDING); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, polyhDesceIndex[0]); // always + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 8, polyhDesceIndex[1]); // +7 faces + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 15, polyhDesceIndex[2]); // +7 faces + + // Polyhedron Descending Connectivity: array of size (NumberOfPolyhedronFaces) + const int* polyhDesceConn = theC->getPolyhedronConnectivity(MED_EN::MED_DESCENDING); + // 15,16,17,18,19,20,21, -15,22,23,24,25,26,27 + for (int i = 0; i < 14; i++) { + // nb. poly faces = 13, because one face is common for two polyhedra + // nb. standard faces < poly-face id <= 27 (27 = 14 + 13) + CPPUNIT_ASSERT_MESSAGE(msg, 14 < labs(polyhDesceConn[i]) <= 27); + } + } // Polyhedron-specific methods + + // Polygon-specific methods + { + // Invalid cases: no polygons for MED_CELL in theC + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 0, theC->getNumberOfPolygons(MED_EN::MED_CELL)); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 0, theC->getNumberOfPolygons(/*MED_EN::MED_ALL_ENTITIES*/)); + CPPUNIT_ASSERT_THROW(theC->getPolygonsConnectivity(MED_EN::MED_DESCENDING, + MED_EN::MED_CELL), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getPolygonsConnectivity(MED_EN::MED_NODAL, + MED_EN::MED_ALL_ENTITIES), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getPolygonsConnectivityIndex(MED_EN::MED_NODAL, + MED_EN::MED_CELL), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getPolygonsConnectivityIndex(MED_EN::MED_DESCENDING, + MED_EN::MED_ALL_ENTITIES), MEDEXCEPTION); + } + } // CELLS: theC + + // FACES: theC->_constituent + { + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, theC->getNumberOfTypesWithPoly(MED_EN::MED_FACE)); + + const MED_EN::medGeometryElement * aFaceTypesBack = theC->getGeometricTypesWithPoly(MED_EN::MED_FACE); + CPPUNIT_ASSERT_MESSAGE(msg, ((aFaceTypesBack[0] == MED_EN::MED_TRIA3 && + aFaceTypesBack[1] == MED_EN::MED_QUAD4) || + (aFaceTypesBack[0] == MED_EN::MED_QUAD4 && + aFaceTypesBack[1] == MED_EN::MED_TRIA3))); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, MED_EN::MED_POLYGON, aFaceTypesBack[2]); + + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 13, theC->getNumberOfElementOfPolyType(MED_EN::MED_FACE)); + + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 0, theC->getNumberOfElementsWithPoly + (MED_EN::MED_FACE, MED_EN::MED_POLYHEDRA)); + + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 13, theC->getNumberOfElementsWithPoly + (MED_EN::MED_FACE, MED_EN::MED_POLYGON)); + + int nbFaAll = 27; // 6 (QUAD4) + 8 (TRIA3) + 13 (POLYGON) + + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nbFaAll, theC->getNumberOfElementsWithPoly + (MED_EN::MED_FACE, MED_EN::MED_ALL_ELEMENTS)); + + + bool isHexagon = false; + for (int i = 1; i <= nbFaAll; i++) { + int len; + const int * ci = theC->getConnectivityOfAnElementWithPoly(MED_EN::MED_NODAL, + MED_EN::MED_FACE, /*Number*/i, len); + MED_EN::medGeometryElement aCurElemTypeWithPoly = theC->getElementTypeWithPoly(MED_EN::MED_FACE, i); + + if (len == 6) { + CPPUNIT_ASSERT_MESSAGE(msg, !isHexagon); // because only one hexagon must exist + + // check nodes {11,15,19,20,17,13} + int nij; + for (int j = 0; j < len; j++) { + nij = ci[j]; + CPPUNIT_ASSERT_MESSAGE(msg, nij==11 || nij==15 || nij==19 || nij==20 || nij==17 || nij==13); + } + + isHexagon = true; + } + + if (i > 14) { // nb.standard faces = 14 + CPPUNIT_ASSERT_THROW(theC->getElementType(MED_EN::MED_FACE, i), MEDEXCEPTION); + } + else { + MED_EN::medGeometryElement aCurElemType = theC->getElementType(MED_EN::MED_FACE, i); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, aCurElemType, aCurElemTypeWithPoly); + } + + switch (aCurElemTypeWithPoly) { + case MED_EN::MED_TRIA3: CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, len); break; + case MED_EN::MED_QUAD4: CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 4, len); break; + case MED_EN::MED_POLYGON: CPPUNIT_ASSERT_MESSAGE(msg, len == 3 || len == 4 || len == 6); break; + default: + CPPUNIT_FAIL(msg); // wrong element type + } + } + CPPUNIT_ASSERT_MESSAGE(msg, isHexagon); // hexagon must exist + + // Polygon-specific methods + { + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 13, theC->getNumberOfPolygons(MED_EN::MED_FACE)); + + const int * pgIndx = theC->getPolygonsConnectivityIndex(MED_EN::MED_NODAL, MED_EN::MED_FACE); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 47, pgIndx[13]); // = length of pgConn + 1 + + const int * pgConn = theC->getPolygonsConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE); + + // face # 1: 11 15 19 20 17 13 + // face # 2: 11 13 14 + // face # 3: 14 13 17 18 + // face # 4: 18 17 20 + // face # 5: 11 14 15 + // face # 6: 15 14 18 19 + // face # 7: 19 18 20 + // face # 8: 11 12 13 + // face # 9: 13 12 16 17 + // face # 10: 17 16 20 + // face # 11: 11 15 12 + // face # 12: 12 15 19 16 + // face # 13: 16 19 20 + + for (int i = 0; i < 13; i++) { + int startNode = pgIndx[i]; + int finishNode = pgIndx[i+1]; + // check nodes uniqueness inside one polygon + set<int> curNodes; + for (int j = startNode; j < finishNode; j++) { + CPPUNIT_ASSERT_MESSAGE(msg, (curNodes.insert(pgConn[j - 1])).second); + } + } + + //CPPUNIT_ASSERT_THROW(theC->getPolygonsConnectivity(MED_EN::MED_DESCENDING, + // MED_EN::MED_FACE), MEDEXCEPTION); + //CPPUNIT_ASSERT_THROW(theC->getPolygonsConnectivityIndex(MED_EN::MED_DESCENDING, + // MED_EN::MED_FACE), MEDEXCEPTION); + } + } // FACES: theC->_constituent + + // EDGES: theC->_constituent->_constituent + //CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfTypesWithPoly(MED_EN::MED_EDGE)); + } + + if (create) { + // force _constituent computation + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfTypes(MED_EN::MED_FACE)); + + + //N-2 Connectivity not supported in MEDMEM + //CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, theC->getNumberOfTypes(MED_EN::MED_EDGE)); + + + cout << "^^^^^" << endl; + cout << *theC << endl; + cout << "^^^^^" << endl; + } + else { + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, MED_EN::MED_POLYHEDRA, theC->getPolyTypeRelativeTo()); + + // The following methods are not recursive, i.e. they return types + // of this connectivity, but do not return types of _constituent. + // And these methods do not work with poly-types. + + // getType + const CELLMODEL & aPYRA5_type = theC->getType(MED_EN::MED_PYRA5); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, MED_EN::MED_PYRA5, aPYRA5_type.getType()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 5, aPYRA5_type.getNumberOfVertexes()); + + const CELLMODEL & aHEXA8_type = theC->getType(MED_EN::MED_HEXA8); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 8, aHEXA8_type.getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 3, aHEXA8_type.getDimension()); + // nb. of sub-faces (nb. of constituents with dimension = 3 - 1) + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, aHEXA8_type.getNumberOfConstituents(1)); + + CPPUNIT_ASSERT_THROW(theC->getType(MED_EN::MED_TRIA3), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getType(MED_EN::MED_POLYGON), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getType(MED_EN::MED_POLYHEDRA), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getType(MED_EN::MED_NONE), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getType(MED_EN::MED_ALL_ELEMENTS), MEDEXCEPTION); + + // getNumberOfNodesInType + int nbNodesInPYRA5 = theC->getNumberOfNodesInType(MED_EN::MED_PYRA5); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 5, nbNodesInPYRA5); + + CPPUNIT_ASSERT_THROW(theC->getNumberOfNodesInType(MED_EN::MED_TRIA3), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getNumberOfNodesInType(MED_EN::MED_POLYGON), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getNumberOfNodesInType(MED_EN::MED_NONE), MEDEXCEPTION); + + // getNumberOfSubCellInType + int nbFacesInHEXA8 = theC->getNumberOfSubCellInType(MED_EN::MED_HEXA8); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, nbFacesInHEXA8); + + CPPUNIT_ASSERT_THROW(theC->getNumberOfSubCellInType(MED_EN::MED_QUAD4), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getNumberOfSubCellInType(MED_EN::MED_POLYHEDRA), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getNumberOfSubCellInType(MED_EN::MED_ALL_ELEMENTS), MEDEXCEPTION); + + // getValueIndex + const int* nodalIndex = theC->getValueIndex(MED_EN::MED_NODAL); + const int* desceIndex = theC->getValueIndex(MED_EN::MED_DESCENDING); + + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, nodalIndex[0]); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, nodalIndex[1]); // +5 nodes of PYRA5 + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 11, nodalIndex[2]); // +5 nodes of PYRA5 + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 19, nodalIndex[3]); // +8 nodes of HEXA8 + + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 1, desceIndex[0]); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 6, desceIndex[1]); // +5 faces of PYRA5 + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 11, desceIndex[2]); // +5 faces of PYRA5 + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 17, desceIndex[3]); // +6 faces of HEXA8 + + // getValue + const int* nodalValue = theC->getValue(MED_EN::MED_NODAL, MED_EN::MED_ALL_ELEMENTS); + const int* nodalPYRA5 = theC->getValue(MED_EN::MED_NODAL, MED_EN::MED_PYRA5); + const int* nodalHEXA8 = theC->getValue(MED_EN::MED_NODAL, MED_EN::MED_HEXA8); + + for (int i = 0; i < 10; i++) { + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_PYRA5[i], nodalPYRA5[i]); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_PYRA5[i], nodalValue[i]); + } + for (int i = 0; i < 8; i++) { + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_HEXA8[i], nodalHEXA8[i]); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, nodesCells_HEXA8[i], nodalValue[10 + i]); + } + + const int* desceValue = theC->getValue(MED_EN::MED_DESCENDING, MED_EN::MED_ALL_ELEMENTS); + const int* descePYRA5 = theC->getValue(MED_EN::MED_DESCENDING, MED_EN::MED_PYRA5); + const int* desceHEXA8 = theC->getValue(MED_EN::MED_DESCENDING, MED_EN::MED_HEXA8); + + for (int i = 0; i < 10; i++) { + CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(descePYRA5[i]) && labs(descePYRA5[i]) < 16); + + CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(desceValue[i]) && labs(desceValue[i]) < 16); + } + for (int i = 0; i < 6; i++) { + CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(desceHEXA8[i]) && labs(desceHEXA8[i]) < 16); + CPPUNIT_ASSERT_MESSAGE(msg, 0 < labs(desceValue[10 + i]) && labs(desceValue[10 + i]) < 16); + } + + CPPUNIT_ASSERT_THROW(theC->getValue(MED_EN::MED_NODAL, MED_EN::MED_QUAD4), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getValue(MED_EN::MED_NODAL, MED_EN::MED_POLYHEDRA), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getValue(MED_EN::MED_DESCENDING, MED_EN::MED_NONE), MEDEXCEPTION); + } +} + +void MEDMEMTest::testConnectivity() +{ + ////////////////////////////////////////////// + // TEST 1: test_MEDMEM_PolyConnectivity.cxx // + ////////////////////////////////////////////// + CONNECTIVITY myNodalConnectivity; // one type + CONNECTIVITY myDesceConnectivity; // one type + + myNodalConnectivity.setEntityDimension(3); + myDesceConnectivity.setEntityDimension(3); + + + //POLYGONS + const int NumberOfPolygons = 2; + const int ConnectivitySize = 12; + int PolygonsConnectivityIndex[NumberOfPolygons+1] = {1,7,13}; + + + + //Nodal + int PolygonsNodalConnectivity[ConnectivitySize] = {1,2,3,4,5,10,10,5,6,7,8,9}; + + // myNodalConnectivity.setPolygonsConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE, +// PolygonsNodalConnectivity, +// PolygonsConnectivityIndex, ConnectivitySize, +// NumberOfPolygons); + + //Descending + int PolygonsDescendingConnectivity[ConnectivitySize] = {1,2,3,4,11,10,11,5,6,7,8,9}; + + myDesceConnectivity.setPolygonsConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_FACE, + PolygonsDescendingConnectivity, + PolygonsConnectivityIndex, ConnectivitySize, + NumberOfPolygons); + + //POLYHEDRON + const int NumberOfPolyhedron = 2; + int PolyhedronIndex[NumberOfPolyhedron+1] = {1,10,20}; + + //Nodal + const int NumberOfFaces = 19; + const int NumberOfNodes = 74; + int PolyhedronFacesIndex[NumberOfFaces+1] = + {1,7,11,15,19,23,27,31,34,39,44,48,52,55,58,61,64,68,72,75}; + int PolyhedronNodalConnectivity[NumberOfNodes] = + {1,2,3,4,5,6,1,7,8,2,2,8,9,3,4,3,9,10,5,4, + 10,11,6,5,11,12,1,6,12,7,7,12,8,10,9,8,12,11,13,14, + 15,3,2,13,2,8,16,14,13,16,17,15,14,17,15,17,18,15,18,9, + 3,15,9,2,3,9,8,8,9,17,16,9,18,17}; + + myNodalConnectivity.setPolyhedronConnectivity(MED_EN::MED_NODAL, PolyhedronNodalConnectivity, + PolyhedronIndex, NumberOfNodes, NumberOfPolyhedron, + PolyhedronFacesIndex, NumberOfFaces); + + + //Descending + const int DescendingConnectivitySize = 19; + int PolyhedronDescendingConnectivity[DescendingConnectivitySize] = + {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,3,17,18}; + + myDesceConnectivity.setPolyhedronConnectivity(MED_EN::MED_DESCENDING, + PolyhedronDescendingConnectivity, + PolyhedronIndex, DescendingConnectivitySize, + NumberOfPolyhedron); + + cout << "Poly NodalConnectivity:" << endl; + cout << myNodalConnectivity; + cout << "Poly NodalConnectivity END" << endl; + cout << "Poly DescendingConnectivity:" << endl; + cout << myDesceConnectivity; + cout << "Poly DescendingConnectivity END" << endl; + + myNodalConnectivity.setNumberOfNodes(777); + CPPUNIT_ASSERT_EQUAL(777, myNodalConnectivity.getNumberOfElementsWithPoly + (MED_EN::MED_NODE, MED_EN::MED_NONE)); +// // Throws because _constituent is not calculated +// CPPUNIT_ASSERT_THROW(myNodalConnectivity.getNumberOfElementsWithPoly +// (MED_EN::MED_FACE, MED_EN::MED_NONE), MEDEXCEPTION); + +// // Returns zero, because EntityDimension is not set +// CPPUNIT_ASSERT_EQUAL(0, myNodalConnectivity.getNumberOfElementsWithPoly +// (MED_EN::MED_CELL, MED_EN::MED_POLYGON)); +// CPPUNIT_ASSERT_EQUAL(0, myNodalConnectivity.getNumberOfElementsWithPoly +// (MED_EN::MED_CELL, MED_EN::MED_POLYHEDRA)); + + // Throws because entity must differ from MED_NONE and MED_ALL_ELEMENTS + CPPUNIT_ASSERT_THROW(myNodalConnectivity.getNumberOfNodesInType(MED_EN::MED_NONE), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(myNodalConnectivity.getNumberOfNodesInType(MED_EN::MED_ALL_ELEMENTS), MEDEXCEPTION); + + // Throws because types are not defined + CPPUNIT_ASSERT_THROW(myNodalConnectivity.getNumberOfNodesInType(MED_EN::MED_ALL_ELEMENTS), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(myNodalConnectivity.getNumberOfNodesInType(MED_EN::MED_POLYGON), MEDEXCEPTION); + + + // does not throw any more exception because + // it is now possible to work on meshes with only polyhedric elements + CPPUNIT_ASSERT_NO_THROW(myNodalConnectivity.calculateConnectivity + (MED_EN::MED_DESCENDING, MED_EN::MED_CELL)); + + // existPolygonsConnectivity + CPPUNIT_ASSERT(!myNodalConnectivity.existPolygonsConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL)); + CPPUNIT_ASSERT(myNodalConnectivity.existPolygonsConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE)); + CPPUNIT_ASSERT(!myNodalConnectivity.existPolygonsConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL)); + + CPPUNIT_ASSERT(!myDesceConnectivity.existPolygonsConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL)); + CPPUNIT_ASSERT(myDesceConnectivity.existPolygonsConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_FACE)); + CPPUNIT_ASSERT(!myDesceConnectivity.existPolygonsConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL)); + + // existPolyhedronConnectivity + CPPUNIT_ASSERT(myNodalConnectivity.existPolyhedronConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL)); + CPPUNIT_ASSERT(!myNodalConnectivity.existPolyhedronConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE)); + CPPUNIT_ASSERT(myNodalConnectivity.existPolyhedronConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL)); + + CPPUNIT_ASSERT(!myDesceConnectivity.existPolyhedronConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL)); + CPPUNIT_ASSERT(!myDesceConnectivity.existPolyhedronConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_FACE)); + CPPUNIT_ASSERT(myDesceConnectivity.existPolyhedronConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL)); + + // setEntityDimension + // myNodalConnectivity and myDesceConnectivity is not good, because + // it contains cells of different dimension (2D and 3D) + // We set here EntityDimension for good work of below methods + + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_POLYHEDRA, myNodalConnectivity.getPolyTypeRelativeTo()); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_POLYHEDRA, myDesceConnectivity.getPolyTypeRelativeTo()); + + // Poly types + CPPUNIT_ASSERT_EQUAL(1, myNodalConnectivity.getNumberOfTypesWithPoly(MED_EN::MED_CELL)); + CPPUNIT_ASSERT_EQUAL(1, myDesceConnectivity.getNumberOfTypesWithPoly(MED_EN::MED_CELL)); + + CPPUNIT_ASSERT_EQUAL(1, myNodalConnectivity.getNumberOfTypesWithPoly(MED_EN::MED_FACE)); + CPPUNIT_ASSERT_EQUAL(0, myDesceConnectivity.getNumberOfTypesWithPoly(MED_EN::MED_EDGE)); + + CPPUNIT_ASSERT_EQUAL(1, myNodalConnectivity.getNumberOfPolyType()); + CPPUNIT_ASSERT_EQUAL(1, myDesceConnectivity.getNumberOfPolyType()); + + // getNumberOfElementsWithPoly + CPPUNIT_ASSERT_EQUAL(NumberOfPolyhedron, myNodalConnectivity.getNumberOfElementsWithPoly + (MED_EN::MED_CELL, MED_EN::MED_POLYHEDRA)); + CPPUNIT_ASSERT_EQUAL(0, myNodalConnectivity.getNumberOfElementsWithPoly + (MED_EN::MED_CELL, MED_EN::MED_POLYGON)); + //Minus 1 because 2,3,8,9 is a given twice in connectivity + CPPUNIT_ASSERT_EQUAL(NumberOfFaces-1, myNodalConnectivity.getNumberOfElementsWithPoly + (MED_EN::MED_FACE, MED_EN::MED_POLYGON)); + + CPPUNIT_ASSERT_EQUAL(NumberOfPolyhedron, myDesceConnectivity.getNumberOfElementsWithPoly + (MED_EN::MED_CELL, MED_EN::MED_POLYHEDRA)); + CPPUNIT_ASSERT_EQUAL(NumberOfPolygons, myDesceConnectivity.getNumberOfElementsWithPoly + (MED_EN::MED_FACE, MED_EN::MED_POLYGON)); + CPPUNIT_ASSERT_EQUAL(0, myDesceConnectivity.getNumberOfElementsWithPoly + (MED_EN::MED_CELL, MED_EN::MED_POLYGON)); + + // getNumberOfElementOfPolyType + CPPUNIT_ASSERT_EQUAL(NumberOfPolyhedron, + myNodalConnectivity.getNumberOfElementOfPolyType(MED_EN::MED_CELL)); + CPPUNIT_ASSERT_EQUAL(NumberOfFaces-1,myNodalConnectivity.getNumberOfElementOfPolyType(MED_EN::MED_FACE)); + + CPPUNIT_ASSERT_EQUAL(NumberOfPolygons, + myDesceConnectivity.getNumberOfElementOfPolyType(MED_EN::MED_CELL)); + CPPUNIT_ASSERT_EQUAL(NumberOfPolygons, myDesceConnectivity.getNumberOfElementOfPolyType(MED_EN::MED_FACE)); + + // getConnectivityOfAnElementWithPoly + { + int len_ph1; + CPPUNIT_ASSERT_THROW(myNodalConnectivity.getConnectivityOfAnElementWithPoly + (MED_EN::MED_NODAL, MED_EN::MED_CELL, /*Number*/1, len_ph1),MEDEXCEPTION); + + int len_pg1, len_pg2, len_pg3,i; + //first polyhedron + const int * dc_pg1 = myDesceConnectivity.getConnectivityOfAnElementWithPoly + (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, /*Number*/1, len_pg1); // {1,2,3,4,11,10} + CPPUNIT_ASSERT_EQUAL(9, len_pg1); + //second polyhedron + const int * dc_pg2 = myDesceConnectivity.getConnectivityOfAnElementWithPoly + (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, /*Number*/2, len_pg2); // {11,5,6,7,8,9} + CPPUNIT_ASSERT_EQUAL(10, len_pg2); + //first polygon + const int * dc_pg3 = myDesceConnectivity.getConnectivityOfAnElementWithPoly + (MED_EN::MED_DESCENDING, MED_EN::MED_FACE, /*Number*/2, len_pg3); // {11,5,6,7,8,9} + CPPUNIT_ASSERT_EQUAL(6, len_pg3); + + + for (i = 0; i < 6; i++) { + if (dc_pg1[i] < 1 || 10 < dc_pg1[i] || + dc_pg3[i] < 1 || 11 < dc_pg3[i]) + CPPUNIT_FAIL("Wrong connectivity returned"); + } + } + + // We reset here EntityDimension to check getConnectivityOfAnElementWithPoly() + //myNodalConnectivity.setEntityDimension(2); + //myDesceConnectivity.setEntityDimension(3); + + { + int len_pg1, len_pg2, i; + + CPPUNIT_ASSERT_THROW ( myNodalConnectivity.getConnectivityOfAnElementWithPoly + (MED_EN::MED_NODAL, MED_EN::MED_CELL, /*Number*/1, len_pg1),MEDEXCEPTION); + + const int * nc_pg1 = myNodalConnectivity.getConnectivityOfAnElementWithPoly + (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, /*Number*/1, len_pg1); // {1,2,3,4,5,10} + CPPUNIT_ASSERT_EQUAL(9, len_pg1); + const int * nc_pg2 = myNodalConnectivity.getConnectivityOfAnElementWithPoly + (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, /*Number*/2, len_pg2); // {10,5,6,7,8,9} + CPPUNIT_ASSERT_EQUAL(10, len_pg2); + + for (i = 0; i < 9; i++) { + if (nc_pg1[i] < 1 || 18 < nc_pg1[i] || + nc_pg2[i] < -3 || 18 < nc_pg2[i]) + CPPUNIT_FAIL("Wrong connectivity returned"); + } + + int len_ph1, len_ph2; + const int * dc_ph1 = myDesceConnectivity.getConnectivityOfAnElementWithPoly + (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, /*Number*/1, len_ph1); // {1,2,3,4,5,6,7,8,9} + CPPUNIT_ASSERT_EQUAL(9, len_ph1); + const int * dc_ph2 = myDesceConnectivity.getConnectivityOfAnElementWithPoly + (MED_EN::MED_DESCENDING, MED_EN::MED_CELL, /*Number*/2, len_ph2); // {10,11,12,13,14,15,16,3,17,18} + CPPUNIT_ASSERT_EQUAL(10, len_ph2); + + for (i = 0; i < 9; i++) { + if (dc_ph1[i] < 1 || 9 < dc_ph1[i]) + CPPUNIT_FAIL("Wrong connectivity returned"); + } + + for (i = 0; i < 10; i++) { + if ((dc_ph2[i] != 3 && dc_ph2[i] < 10) || 18 < dc_ph2[i]) + CPPUNIT_FAIL("Wrong connectivity returned"); + } + } + + //////////// + // TEST 2 // + //////////// + checkCopyConnectivity(); + + //////////// + // TEST 3 // + //////////// + + CONNECTIVITY aCells1 (/*numberOfTypes*/2, /*Entity*/MED_EN::MED_CELL); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_CELL, aCells1.getEntity()); + CPPUNIT_ASSERT_EQUAL(2, aCells1.getNumberOfTypes(MED_EN::MED_CELL)); + CPPUNIT_ASSERT_EQUAL(2, aCells1.getNumberOfTypesWithPoly(MED_EN::MED_CELL)); + + CONNECTIVITY aCells2 (/*numberOfTypes*/3/*, Entity=MED_EN::MED_CELL*/); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_CELL, aCells2.getEntity()); + CPPUNIT_ASSERT_EQUAL(3, aCells2.getNumberOfTypes(MED_EN::MED_CELL)); + CPPUNIT_ASSERT_EQUAL(3, aCells2.getNumberOfTypesWithPoly(MED_EN::MED_CELL)); + + CONNECTIVITY * anEdges1 = new CONNECTIVITY(/*numberOfTypes*/1, /*Entity*/MED_EN::MED_EDGE); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_EDGE, anEdges1->getEntity()); + CPPUNIT_ASSERT_EQUAL(1, anEdges1->getNumberOfTypes(MED_EN::MED_EDGE)); + CPPUNIT_ASSERT_EQUAL(1, anEdges1->getNumberOfTypesWithPoly(MED_EN::MED_EDGE)); + + CONNECTIVITY * anEdges2 = new CONNECTIVITY(/*numberOfTypes*/2, /*Entity*/MED_EN::MED_EDGE); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_EDGE, anEdges2->getEntity()); + CPPUNIT_ASSERT_EQUAL(2, anEdges2->getNumberOfTypes(MED_EN::MED_EDGE)); + CPPUNIT_ASSERT_EQUAL(2, anEdges2->getNumberOfTypesWithPoly(MED_EN::MED_EDGE)); + + CONNECTIVITY * aFaces1 = new CONNECTIVITY(/*numberOfTypes*/2, /*Entity*/MED_EN::MED_FACE); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces1->getEntity()); + CPPUNIT_ASSERT_EQUAL(2, aFaces1->getNumberOfTypes(MED_EN::MED_FACE)); + CPPUNIT_ASSERT_EQUAL(2, aFaces1->getNumberOfTypesWithPoly(MED_EN::MED_FACE)); + + // No need to delete anEdges1 and aFaces1, because they are owned by aCells1 + // (anEdges1 is owned by aFaces1 to be precise) + // No need to delete anEdges2, because they are owned by aCells2 + + // EntityDimension + // It would be good to set EntityDimension automatically for EDGEs and FACEs, + // and warn about not set EntityDimension for CELLs + // (or calculate it by given geometric types) + aCells1.setEntityDimension(3); + aCells2.setEntityDimension(2); // for 2D mesh + anEdges1->setEntityDimension(1); + anEdges2->setEntityDimension(1); + aFaces1->setEntityDimension(2); + + CPPUNIT_ASSERT_EQUAL(3, aCells1.getEntityDimension()); + CPPUNIT_ASSERT_EQUAL(2, aCells2.getEntityDimension()); + CPPUNIT_ASSERT_EQUAL(1, anEdges1->getEntityDimension()); + CPPUNIT_ASSERT_EQUAL(1, anEdges2->getEntityDimension()); + CPPUNIT_ASSERT_EQUAL(2, aFaces1->getEntityDimension()); + + // getPolyTypeRelativeTo + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_POLYHEDRA, aCells1.getPolyTypeRelativeTo()); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_POLYGON , aCells2.getPolyTypeRelativeTo()); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_POLYGON , aFaces1->getPolyTypeRelativeTo()); + // because there is no poly types for edges (2D entities) + CPPUNIT_ASSERT_THROW(anEdges1->getPolyTypeRelativeTo(), MEDEXCEPTION); + + // setConstituent + CPPUNIT_ASSERT_THROW(aCells1.setConstituent(&aCells2), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aCells1.setConstituent(anEdges1), MEDEXCEPTION); + + aCells1.setConstituent(aFaces1); + aCells1.setConstituent(anEdges1); + + CPPUNIT_ASSERT_EQUAL(1, aCells1.getNumberOfTypes(MED_EN::MED_EDGE)); + CPPUNIT_ASSERT_EQUAL(2, aCells1.getNumberOfTypes(MED_EN::MED_FACE)); + + aCells2.setConstituent(anEdges2); + CPPUNIT_ASSERT_EQUAL(2, aCells2.getNumberOfTypes(MED_EN::MED_EDGE)); + + // setGeometricTypes + MED_EN::medGeometryElement aCellTypes2D[3] = {MED_EN::MED_TRIA3, MED_EN::MED_QUAD4, MED_EN::MED_TRIA6}; + MED_EN::medGeometryElement aCellTypes3D[2] = {MED_EN::MED_PYRA5, MED_EN::MED_HEXA8}; + MED_EN::medGeometryElement anEdgeTypes1[1] = {MED_EN::MED_SEG2}; + MED_EN::medGeometryElement anEdgeTypes2[2] = {MED_EN::MED_SEG2, MED_EN::MED_SEG3}; + MED_EN::medGeometryElement aFaceTypes2[2] = + {MED_EN::MED_TRIA3, MED_EN::MED_QUAD4}; + + aCells1.setGeometricTypes(aCellTypes3D, MED_EN::MED_CELL); + aCells1.setGeometricTypes(aFaceTypes2, MED_EN::MED_FACE); + aCells1.setGeometricTypes(anEdgeTypes1, MED_EN::MED_EDGE); + CPPUNIT_ASSERT_THROW(aCells1.setGeometricTypes(anEdgeTypes1, MED_EN::MED_NODE), MEDEXCEPTION); + + aCells2.setGeometricTypes(aCellTypes2D, MED_EN::MED_CELL); + anEdges2->setGeometricTypes(anEdgeTypes2, MED_EN::MED_EDGE); + CPPUNIT_ASSERT_THROW(aCells2.setGeometricTypes(aFaceTypes2, MED_EN::MED_FACE), MEDEXCEPTION); + + // setCount + int countCell2D[4] = {1, 5, 6, 10}; + int countCell3D[3] = {1, 3, 4}; + int countEdges1[2] = {1, 21}; + int countEdges2[3] = {1, 13, 21}; + int countFaces1[3] = {1, 9, 15}; + + aCells1.setCount(countCell3D, MED_EN::MED_CELL); + aCells1.setCount(countEdges1, MED_EN::MED_EDGE); + aCells1.setCount(countFaces1, MED_EN::MED_FACE); + CPPUNIT_ASSERT_THROW(aCells1.setCount(countEdges1, MED_EN::MED_NODE), MEDEXCEPTION); + + aCells2.setCount(countCell2D, MED_EN::MED_CELL); + aCells2.setCount(countEdges2, MED_EN::MED_EDGE); + CPPUNIT_ASSERT_THROW(aCells2.setCount(countFaces1, MED_EN::MED_FACE), MEDEXCEPTION); + + // setNodal + + // aCells2 + int nodesCell2D_TRIA3[12] = {3,8,7, 10,7,13, 18,13,14, 11,14,8}; + int nodesCell2D_QUAD4[4] = {7,8,14,13}; + int nodesCell2D_TRIA6[24] = {1,2,3,7,10,6, 3,4,5,9,11,8, 11,15,20,19,18,14, 18,17,16,12,10,13}; + + aCells2.setNodal(nodesCell2D_TRIA3, MED_EN::MED_CELL, MED_EN::MED_TRIA3); + aCells2.setNodal(nodesCell2D_QUAD4, MED_EN::MED_CELL, MED_EN::MED_QUAD4); + aCells2.setNodal(nodesCell2D_TRIA6, MED_EN::MED_CELL, MED_EN::MED_TRIA6); + + int nodesEdges2_SEG2[24] = {3,8, 8,11, 11,14, 14,18, 18,13, 13,10, 10,7, + 7,3, 7,8, 8,14, 14,13, 13,7}; + int nodesEdges2_SEG3[24] = {1,2,3, 3,4,5, 5,9,11, 11,15,20, + 20,19,18, 18,17,16, 16,12,10, 10,6,1}; + + aCells2.setNodal(nodesEdges2_SEG2, MED_EN::MED_EDGE, MED_EN::MED_SEG2); + aCells2.setNodal(nodesEdges2_SEG3, MED_EN::MED_EDGE, MED_EN::MED_SEG3); + + // aCells1 + int nodesCell3D_PYRA5[10] = {5,4,3,2,1, 6,7,8,9,10}; + int nodesCell3D_HEXA8[8] = {2,3,4,5, 6,7,8,9}; + + aCells1.setNodal(nodesCell3D_PYRA5, MED_EN::MED_CELL, MED_EN::MED_PYRA5); + aCells1.setNodal(nodesCell3D_HEXA8, MED_EN::MED_CELL, MED_EN::MED_HEXA8); + + int nodesFaces1_TRIA3[24] = {1,2,3, 1,3,4, 1,4,5, 1,5,2, + 10,6,7, 10,7,8, 10,8,9, 10,9,6}; + int nodesFaces1_QUAD4[24] = {2,3,4,5, 6,7,8,9, 2,3,7,6, 5,4,8,9, 2,5,9,6, 3,4,8,7}; + int nodesFaces1_TRIA6[6] = {11,12,13,14,15,16}; + int nodesFaces1_QUAD8[8] = {15,14,13,17,18,19,20,21}; + + aCells1.setNodal(nodesFaces1_TRIA3, MED_EN::MED_FACE, MED_EN::MED_TRIA3); + aCells1.setNodal(nodesFaces1_QUAD4, MED_EN::MED_FACE, MED_EN::MED_QUAD4); + //aCells1.setNodal(nodesFaces1_TRIA6, MED_EN::MED_FACE, MED_EN::MED_TRIA6); + //aCells1.setNodal(nodesFaces1_QUAD8, MED_EN::MED_FACE, MED_EN::MED_QUAD8); + + int nodesEdges1_SEG2[40] = {1,2, 1,3, 1,4, 1,5, 10,6, 10,7, 10,8, 10,9, + 2,3, 3,4, 4,5, 5,2, 6,7, 7,8, 8,9, 9,6, + 2,6, 3,7, 4,8, 5,9}; + + aCells1.setNodal(nodesEdges1_SEG2, MED_EN::MED_EDGE, MED_EN::MED_SEG2); + + // setNumberOfNodes + aCells2.setNumberOfNodes(20); + anEdges2->setNumberOfNodes(20); + + aCells1.setNumberOfNodes(10); + anEdges1->setNumberOfNodes(10); + aFaces1->setNumberOfNodes(10); + + // existConnectivity + CPPUNIT_ASSERT(aCells1.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL)); + CPPUNIT_ASSERT(aCells1.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE)); + CPPUNIT_ASSERT(aCells1.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_EDGE)); + CPPUNIT_ASSERT(!aCells1.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_NODE)); + + CPPUNIT_ASSERT(!aCells1.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL)); + CPPUNIT_ASSERT(!aCells1.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_FACE)); + CPPUNIT_ASSERT(!aCells1.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_EDGE)); + CPPUNIT_ASSERT(!aCells1.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_NODE)); + + CPPUNIT_ASSERT(aCells2.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_CELL)); + CPPUNIT_ASSERT(!aCells2.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_FACE)); + CPPUNIT_ASSERT(aCells2.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_EDGE)); + CPPUNIT_ASSERT(!aCells2.existConnectivity(MED_EN::MED_NODAL, MED_EN::MED_NODE)); + + CPPUNIT_ASSERT(!aCells2.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL)); + CPPUNIT_ASSERT(!aCells2.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_FACE)); + CPPUNIT_ASSERT(!aCells2.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_EDGE)); + CPPUNIT_ASSERT(!aCells2.existConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_NODE)); + + // getNumberOfPolyType + CPPUNIT_ASSERT_EQUAL(0, aCells1.getNumberOfPolyType()); + CPPUNIT_ASSERT_EQUAL(0, aCells2.getNumberOfPolyType()); + + // getConnectivityOfAnElementWithPoly + { + int len_e1, len_e2, i; + const int * nc_e1 = aCells1.getConnectivityOfAnElementWithPoly + (MED_EN::MED_NODAL, MED_EN::MED_CELL, /*Number*/1, len_e1); + CPPUNIT_ASSERT_EQUAL(5, len_e1); // PYRA5 {1,2,3,4,5} + for (i = 0; i < len_e1; i++) { + if (nc_e1[i] < 1 || 5 < nc_e1[i]) + CPPUNIT_FAIL("Wrong node in element"); + } + + const int * nc_e2 = aCells2.getConnectivityOfAnElementWithPoly + (MED_EN::MED_NODAL, MED_EN::MED_CELL, /*Number*/2, len_e2); + CPPUNIT_ASSERT_EQUAL(3, len_e2); // TRIA3 {7,10,13} + for (i = 0; i < len_e2; i++) { + if (nc_e2[i] != 7 && nc_e2[i] != 10 && nc_e2[i] != 13) + CPPUNIT_FAIL("Wrong node in element"); + } + } + + //cout << "aCells2: " << endl; + //cout << aCells2 << endl; + + //cout << "aCells1:" << endl; + //cout << aCells1 << endl; + + // aCells1 (2 types) | + // | | + // aFaces1 (4 types) | aCells2 (3 types) + // | | | + // anEdges1 (1 type) | anEdges2 (2 types) + + MESH* mesh=new MESH(); //updateFamily method requires a pointer to the mesh + mesh->setConnectivityptr(&aCells1); + // updateFamily + { + FAMILY aFamilyOnFaces; + aFamilyOnFaces.setEntity(MED_EN::MED_FACE); + aFamilyOnFaces.setMeshName("Mesh 1"); + aFamilyOnFaces.setMesh(mesh); + aFamilyOnFaces.setName("Support On Faces 1"); + //aFamilyOnFaces.setAll(true); + + int nbTypesFam1 = 2; + MED_EN::medGeometryElement aSCTypes[4] = {MED_EN::MED_TRIA3, MED_EN::MED_QUAD4}; + int nbEltsSC[4] = {8,6}; + int indexSC[5] = {1,9,15}; // length = nb.types + 1 + int valueSC[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14}; // length = total nb. of elements + //int nbTypesFam1 = 1; + //MED_EN::medGeometryElement aSCTypes[1] = {MED_EN::MED_TRIA3}; + //int nbEltsSC[1] = {8}; + //int indexSC[2] = {1,9}; // length = nb.types + 1 + //int valueSC[8] = {1,3,5,7,9,11,13,15}; // length = total nb. of elements + + aFamilyOnFaces.setNumberOfGeometricType(nbTypesFam1); + aFamilyOnFaces.setGeometricType(aSCTypes); + aFamilyOnFaces.setNumberOfElements(nbEltsSC); + aFamilyOnFaces.setNumber(indexSC, valueSC); + + vector<FAMILY*> aFamsOnFaces (1); + aFamsOnFaces[0] = &aFamilyOnFaces; + +//#ifdef ENABLE_UPDATE_FAMILY + // Attention!!! By default ENABLE_UPDATE_FAMILY is not defined!!! + // I do not undestand, what this method should do + // and what I must give to it to obtain good result + + //cout << "aCells1:" << endl; + //cout << aCells1 << endl; + CPPUNIT_ASSERT_NO_THROW(aCells1.updateFamily(aFamsOnFaces)); + //cout << "aCells1:" << endl; + //cout << aCells1 << endl; +//#endif + } + + //////////// + // TEST 4 // + //////////// + CONNECTIVITY * c1 = new CONNECTIVITY(/*numberOfTypes*/2, MED_EN::MED_CELL); + createOrCheck(c1, "Creation", /*create*/true); + createOrCheck(c1, "Check just created", /*create*/false); + + CONNECTIVITY * c2 = new CONNECTIVITY(*c1); + createOrCheck(c2, "Check copy constructor", /*create*/false); + + // invertConnectivityForAFace + int nbFacesC2 = c2->getNumberOf(MED_EN::MED_FACE, MED_EN::MED_ALL_ELEMENTS); + for (int faceId = 1; faceId <= nbFacesC2; faceId++) { + //cout << "^^^^^ not inverted ^^^^^" << endl; + //showConnectivity(c2, 3, 20, MED_EN::MED_CELL, 2); + //cout << *c2 << endl; + //cout << "^^^^^ not inverted ^^^^^" << endl; + + // this face nodal connectivity before inversion: + int oldLen, newLen; + const int * oldConn = c2->getConnectivityOfAnElementWithPoly(MED_EN::MED_NODAL, + MED_EN::MED_FACE, faceId, oldLen); + + // descending connectivity before inversion: + int before_NumberOfElements = c2->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); + const int * before_connectivity_shared = + c2->getConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); + const int * before_connectivity_index = + c2->getConnectivityIndex(MED_EN::MED_DESCENDING, MED_EN::MED_CELL); + + // copy connectivity, because the pointer, returned by getConnectivity, + // will point to the same memory before and after inversion + int lenDC = before_connectivity_index[before_NumberOfElements] - 1; + int * before_connectivity = new int[lenDC]; + for (int i = 0; i < lenDC; i++) + before_connectivity[i] = before_connectivity_shared[i]; + + // reverse descending connectivity before inversion: + const int * before_ReverseDescendingConnectivity_shared = + c2->getReverseConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL); + const int * before_ReverseDescendingConnectivityIndex = + c2->getReverseConnectivityIndex(MED_EN::MED_DESCENDING, MED_EN::MED_CELL); + + int lenRDC = before_ReverseDescendingConnectivityIndex[nbFacesC2] - 1; + int * before_ReverseDescendingConnectivity = new int[lenRDC]; + for (int i = 0; i < lenRDC; i++) + before_ReverseDescendingConnectivity[i] = before_ReverseDescendingConnectivity_shared[i]; + + // perform inversion + int * newNodesForFace = new int[oldLen]; + if (oldLen == 3) { + newNodesForFace[0] = oldConn[1]; + newNodesForFace[1] = oldConn[0]; + newNodesForFace[2] = oldConn[2]; + } else { + newNodesForFace[0] = oldConn[2]; + newNodesForFace[1] = oldConn[1]; + newNodesForFace[2] = oldConn[0]; + newNodesForFace[3] = oldConn[3]; + } + c2->invertConnectivityForAFace(faceId, newNodesForFace, /*polygonFace*/false); + + //cout << "^^^^^ inverted ^^^^^" << endl; + //showConnectivity(c2, 3, 20, MED_EN::MED_CELL, 2); + //cout << *c2 << endl; + //cout << "^^^^^ inverted ^^^^^" << endl; + + // reverse descending connectivity after inversion: + const int * after_ReverseDescendingConnectivity = + c2->getReverseConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL); + const int * after_ReverseDescendingConnectivityIndex = + c2->getReverseConnectivityIndex(MED_EN::MED_DESCENDING, MED_EN::MED_CELL); + + // Faces, which are on bound (have one neighbouring), are not inverted. + bool isOnBound = false; + + //cout << "faceId = " << faceId << endl; + //cout << "oldLen = " << oldLen << endl; + for (int i = 0; i < nbFacesC2; i++) { + //cout << "i = " << i << endl; + int plus = after_ReverseDescendingConnectivityIndex[i] - 1; + // always two neighbourings + if ((i + 1) == faceId) { + // no second neighbouring + isOnBound = (before_ReverseDescendingConnectivity[plus + 1] == 0); + } + if ((i + 1) == faceId && oldLen == 4 && !isOnBound) { + CPPUNIT_ASSERT_EQUAL(before_ReverseDescendingConnectivity[plus + 0], + after_ReverseDescendingConnectivity[plus + 1]); + CPPUNIT_ASSERT_EQUAL(before_ReverseDescendingConnectivity[plus + 1], + after_ReverseDescendingConnectivity[plus + 0]); + } + else { + CPPUNIT_ASSERT_EQUAL(before_ReverseDescendingConnectivity[plus + 0], + after_ReverseDescendingConnectivity[plus + 0]); + CPPUNIT_ASSERT_EQUAL(before_ReverseDescendingConnectivity[plus + 1], + after_ReverseDescendingConnectivity[plus + 1]); + } + } + + // descending connectivity after inversion: + int after_NumberOfElements = c2->getNumberOf(MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); + const int * after_connectivity = + c2->getConnectivity(MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); + const int * after_connectivity_index = + c2->getConnectivityIndex(MED_EN::MED_DESCENDING, MED_EN::MED_CELL); + + CPPUNIT_ASSERT_EQUAL(before_NumberOfElements, after_NumberOfElements); + + for (int j = 0; j < before_NumberOfElements; j++) { + for (int k = after_connectivity_index[j]; k < after_connectivity_index[j+1]; k++) { + if (labs(before_connectivity[k-1]) == faceId && !isOnBound) { + CPPUNIT_ASSERT_EQUAL(before_connectivity[k-1], - after_connectivity[k-1]); + } + else { + CPPUNIT_ASSERT_EQUAL(before_connectivity[k-1], after_connectivity[k-1]); + } + } + } + + // this face nodal connectivity after inversion: + if (!isOnBound) { + const int * newConn = c2->getConnectivityOfAnElementWithPoly(MED_EN::MED_NODAL, + MED_EN::MED_FACE, faceId, newLen); + CPPUNIT_ASSERT_EQUAL(oldLen, newLen); + for (int i = 0; i < newLen; i++) { + CPPUNIT_ASSERT_EQUAL(newNodesForFace[i], newConn[i]); + } + } + delete [] newNodesForFace; + + delete [] before_connectivity; + delete [] before_ReverseDescendingConnectivity; + + // ATTENTION: invertConnectivityForAFace() is not tested on polygons!!! + } + + + delete c1; + delete c2; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_Connectivity_fault.cxx b/src/MEDMEMCppTest/MEDMEMTest_Connectivity_fault.cxx new file mode 100644 index 000000000..2c1d48396 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Connectivity_fault.cxx @@ -0,0 +1,140 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "MEDMEM_Connectivity.hxx" +#include "MEDMEM_define.hxx" +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" + +#include <sstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +using namespace std; +using namespace MEDMEM; + +void createOrCheck (CONNECTIVITY * theC, string msg, bool create = false) +{ + // Preconditions: Entity and NumberOfTypes + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, MED_EN::MED_CELL, theC->getEntity()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfTypes(MED_EN::MED_CELL)); + + // EntityDimension + if (create) + theC->setEntityDimension(3); + + // NumberOfNodes + int nbNodes = 20; + + if (create) { + theC->setNumberOfNodes(nbNodes); + } + + // GeometricTypes + MED_EN::medGeometryElement aCellTypes[2] = {MED_EN::MED_PYRA5, MED_EN::MED_HEXA8}; + + // this variable is needed in check mode (!create) + // because of bug with getGlobalNumberingIndex() method (see below) + bool triaFirst = true; + + if (create) { + theC->setGeometricTypes(aCellTypes, MED_EN::MED_CELL); + CPPUNIT_ASSERT_THROW(theC->setGeometricTypes(aCellTypes, MED_EN::MED_NODE), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->setGeometricTypes(aCellTypes, MED_EN::MED_FACE), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->setGeometricTypes(aCellTypes, MED_EN::MED_EDGE), MEDEXCEPTION); + } + + // Nodal Connectivity for standard types + int countCells[3] = {1, 3, 4}; // 2 PYRA5 and 1 HEXA8 + int nodesCells_PYRA5[10] = {2,3,4,5,1, 6,7,8,9,10}; + int nodesCells_HEXA8[8] = {2,3,4,5, 6,7,8,9}; + + if (create) { + theC->setCount(countCells, MED_EN::MED_CELL); + theC->setNodal(nodesCells_PYRA5, MED_EN::MED_CELL, MED_EN::MED_PYRA5); + theC->setNodal(nodesCells_HEXA8, MED_EN::MED_CELL, MED_EN::MED_HEXA8); + + // Invalid cases + CPPUNIT_ASSERT_THROW(theC->setCount(countCells, MED_EN::MED_NODE), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->setCount(countCells, MED_EN::MED_EDGE), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->setCount(countCells, MED_EN::MED_FACE), MEDEXCEPTION); + + CPPUNIT_ASSERT_THROW(theC->setNodal(nodesCells_PYRA5, MED_EN::MED_FACE, MED_EN::MED_PYRA5), MEDEXCEPTION); + } + + // 2 POLYHEDRA + const int nbPolyhedron = 2; + const int nbPolyFaces = 14; + const int nbPolyNodes = 52; + + int aPolyhedronIndex[nbPolyhedron + 1] = {1,8,15}; + + int aPolyhedronFacesIndex[nbPolyFaces + 1] = {1,7,10,14,17,20,24, 27,33,36,40,43,46,50,53}; + + int aPolyhedronNodalConnectivity[nbPolyNodes] = { + 11,15,19,20,17,13, 11,13,14, 14,13,17,18, 18,17,20, 11,14,15, 15,14,18,19, 19,18,20, + 11,13,17,20,19,15, 11,12,13, 13,12,16,17, 17,16,20, 11,15,12, 12,15,19,16, 16,19,20}; + + if (create) { + theC->setPolyhedronConnectivity(MED_EN::MED_NODAL, aPolyhedronNodalConnectivity, + aPolyhedronIndex, nbPolyNodes, nbPolyhedron, + aPolyhedronFacesIndex, nbPolyFaces); + } + else { + // CELLS(3D): theC + { + // Polyhedron-specific methods + { + // invalid polyhedron Id +//#ifdef ENABLE_FAULTS + int lenPolyh3nodes; + int nbFaces3; + int *nbNodes3; + // (BUG) Segmentation fault instead of MEDEXCEPTION + CPPUNIT_ASSERT_THROW(theC->getNodesOfPolyhedron(1, lenPolyh3nodes), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getNodesOfPolyhedron(3+3, lenPolyh3nodes), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getNodesPerFaceOfPolyhedron + (/*polyhedronId*/1, nbFaces3, nbNodes3), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theC->getNodesPerFaceOfPolyhedron + (/*polyhedronId*/3+3, nbFaces3, nbNodes3), MEDEXCEPTION); +//#endif + } // Polyhedron-specific methods + } // CELLS: theC + } + + if (create) { + // force _constituent computation + CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, 2, theC->getNumberOfTypes(MED_EN::MED_FACE)); + } +} + +int main (int argc, char** argv) +{ + CONNECTIVITY * c1 = new CONNECTIVITY(/*numberOfTypes*/2, MED_EN::MED_CELL); + createOrCheck(c1, "Creation", /*create*/true); + createOrCheck(c1, "Check just created", /*create*/false); +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_Coordinate.cxx b/src/MEDMEMCppTest/MEDMEMTest_Coordinate.cxx new file mode 100644 index 000000000..b11c744d3 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Coordinate.cxx @@ -0,0 +1,411 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/Message.h> +#include <cppunit/TestAssert.h> + +#include "MEDMEM_Array.hxx" +#include "MEDMEM_Coordinate.hxx" + +#include <sstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; + +// #8: MEDMEM_Coordinate.hxx } MEDMEMTest_Coordinate.cxx + +/*! + * Check methods (23), defined in MEDMEM_Coordinate.hxx: + * class COORDINATE { + * (+) COORDINATE(); + * (+) COORDINATE(int SpaceDimension, int NumberOfNodes, MED_EN::medModeSwitch Mode); + * (+) COORDINATE(int SpaceDimension,const string * CoordinateName, const string * CoordinateUnit); + * (+) COORDINATE(const COORDINATE & m); + * (+) virtual ~COORDINATE(); + * (+) void setCoordinates(MEDARRAY<double> *Coordinate,bool shallowCopy=false); + * (+) void setCoordinates(const MED_EN::medModeSwitch Mode, const double *Coordinate); + * (+) void setCoordinatesNames(const string * CoordinateName); + * (+) void setCoordinateName(const string CoordinateName, const int i); + * (+) void setCoordinatesUnits(const string * CoordinateUnit); + * (+) void setCoordinateUnit(const string CoordinateUnit, const int i); + * (+) void setCoordinatesSystem(const string CoordinateSystem); + * (+) void setNodesNumbers(const int * NodeNumber); + * (+) int getSpaceDimension() const; + * (+) int getNumberOfNodes() const; + * (+) virtual const int* getNodesNumbers() const; + * (+) string getCoordinatesSystem() const; + * (+) virtual const double * getCoordinates(MED_EN::medModeSwitch Mode); + * (+) virtual double getCoordinate(int Number,int Axis); + * (+) virtual const double * getCoordinateAxis(int Axis); + * (+) const string * getCoordinatesNames() const; + * (+) string getCoordinateName(int Axis) const; + * (+) const string * getCoordinatesUnits() const; + * (+) string getCoordinateUnit(int Axis) const; + * } + * + * Use code of MEDMEM/tests/testUCoordinate.cxx + * MEDMEM/test_copie_coordinate.cxx + */ +void MEDMEMTest::testCoordinate() +{ + ////////////////////////////////////////////// + // TEST 1: MEDMEM/tests/testUCoordinate.cxx // + ////////////////////////////////////////////// + { + const double pouieme = 0.009; + + int SpaceDim = 3; + int NbOfNodes = 5; + + string * noms = new string[3]; + noms[0] = " X "; + noms[1] = " Y "; + noms[2] = " Z "; + + string units[3]; + units[0] = " m "; + units[1] = " m "; + units[2] = " m "; + + int * numbers = new int[5]; + for (int i = 0; i < 5; i++) numbers[i] = 10 + i; + + double coor[15] = {0,0,0,0,0,1,0,1,0,1,0,0,0.5,0.5,0.5}; + CPPUNIT_ASSERT(SpaceDim * NbOfNodes == 15); + + double * coor1 = new double [SpaceDim*NbOfNodes]; + for (int k = 0; k < SpaceDim*NbOfNodes; k++) + coor1[k] = coor[k]; + + MEDARRAY<double>* CoordinateArray = + new MEDARRAY<double>(coor1, SpaceDim, NbOfNodes, MED_EN::MED_FULL_INTERLACE); + COORDINATE mycoo; + CPPUNIT_ASSERT_NO_THROW(mycoo.setCoordinates(CoordinateArray)); + + //--------------------------------------------------------------------// + // Tests des methodes // + // // + // - setCoordinatesNames // + // - setCoordinatesUnits // + // - setCoordinatesSystem // + // - setNodesNumbers // + // // + //--------------------------------------------------------------------// + + CPPUNIT_ASSERT_NO_THROW(mycoo.setCoordinatesNames(noms)); + CPPUNIT_ASSERT_NO_THROW(mycoo.setCoordinatesUnits(units)); + CPPUNIT_ASSERT_NO_THROW(mycoo.setCoordinatesSystem("cartesien")); + CPPUNIT_ASSERT_NO_THROW(mycoo.setNodesNumbers(numbers)); + + //--------------------------------------------------------------------// + // Tests des methodes // + // // + // - getCoordinatesNames // + // - getCoordinatesUnits // + // - getCoordinatesUnit // + // - getCoordinatesSystem // + // - getNodesNumbers // + // // + //--------------------------------------------------------------------// + CPPUNIT_ASSERT_NO_THROW(CPPUNIT_ASSERT(mycoo.getCoordinatesSystem() == "cartesien")); + + const string * units2; + try + { + units2 = mycoo.getCoordinatesUnits(); + for (int axe = 0; axe < SpaceDim; axe++) { + string verif = mycoo.getCoordinateUnit(axe+1); + CPPUNIT_ASSERT(verif == units2[axe]); + } + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + const string * noms2; + try + { + noms2 = mycoo.getCoordinatesNames(); + for (int axe = 0; axe < SpaceDim; axe++) { + string verif = mycoo.getCoordinateName(axe+1); + CPPUNIT_ASSERT(verif == noms2[axe]); + } + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + const double * coor2 = mycoo.getCoordinates(MED_EN::MED_FULL_INTERLACE); + + for (int axe = 0; axe < SpaceDim; axe++) { + const double * coor3 = mycoo.getCoordinateAxis(axe+1); + for (int num = 0; num < NbOfNodes; num++) { + const double d = mycoo.getCoordinate(num + 1, axe + 1); + CPPUNIT_ASSERT(fabs(d - coor3[num ]) < pouieme); + CPPUNIT_ASSERT(fabs(d - coor2[(num * SpaceDim)+axe]) < pouieme); + CPPUNIT_ASSERT(fabs(d - coor [(num * SpaceDim)+axe]) < pouieme); + } + } + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + delete [] noms; + delete [] numbers; + delete [] coor1; + + delete CoordinateArray; + } + + ////////////////////////////////////////////// + // TEST 2: MEDMEM/test_copie_coordinate.cxx // + ////////////////////////////////////////////// + { + const int numberofNodes = 5; + const int spaceDimension = 3; + const MED_EN::medModeSwitch mode = MED_EN::MED_FULL_INTERLACE; + + //construction tableau MEDARRAY des coordonnées + MEDARRAY<double> * myMedArray = new MEDARRAY<double>(spaceDimension, numberofNodes, mode); + for (int i = 1; i <= myMedArray->getLengthValue(); i++) { + for (int j = 1; j <= myMedArray->getLeadingValue(); j++) + myMedArray->setIJ(i, j, (double) i*j); + } + + //construction noms des coordonnées + string * myCoordinatesNames = new string[spaceDimension]; + if (spaceDimension >= 1) myCoordinatesNames[0] = "x"; + if (spaceDimension >= 2) myCoordinatesNames[1] = "y"; + if (spaceDimension >= 3) myCoordinatesNames[2] = "z"; + + //construction unités des coordonnées + string * myCoordinatesUnits = new string[spaceDimension]; + if (spaceDimension >= 1) myCoordinatesUnits[0] = "m"; + if (spaceDimension >= 2) myCoordinatesUnits[1] = "m"; + if (spaceDimension >= 3) myCoordinatesUnits[2] = "m"; + + //construction des indices des noeuds + int * myNodeNumber = new int[numberofNodes]; + for (int i = 0; i < numberofNodes; i++) + myNodeNumber[i] = numberofNodes - i - 1; + + //construction de l'objet COORDINATE + COORDINATE * myCoordinate = new COORDINATE(); + myCoordinate->setCoordinates(myMedArray); + myCoordinate->setCoordinatesNames(myCoordinatesNames); + myCoordinate->setCoordinatesUnits(myCoordinatesUnits); + myCoordinate->setNodesNumbers(myNodeNumber); + + delete myMedArray; + delete[] myCoordinatesNames; + delete[] myCoordinatesUnits; + delete[] myNodeNumber; + + COORDINATE * myCoordinate2 = new COORDINATE(* myCoordinate); + delete myCoordinate; + myCoordinate = NULL; + + // check copied coordinate + int _spaceDimension = myCoordinate2->getSpaceDimension(); + int _numberofNodes = myCoordinate2->getNumberOfNodes(); + CPPUNIT_ASSERT(_spaceDimension == spaceDimension); + CPPUNIT_ASSERT(_numberofNodes == numberofNodes); + + for (int i = 1; i <= _numberofNodes; i++) { + for (int j = 1; j <= _spaceDimension; j++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(i*j, myCoordinate2->getCoordinate(i, j), 0.000001); + } + } + + CPPUNIT_ASSERT(myCoordinate2->getCoordinateName(1) == "x"); + CPPUNIT_ASSERT(myCoordinate2->getCoordinateName(2) == "y"); + CPPUNIT_ASSERT(myCoordinate2->getCoordinateName(3) == "z"); + + CPPUNIT_ASSERT(myCoordinate2->getCoordinateUnit(1) == "m"); + CPPUNIT_ASSERT(myCoordinate2->getCoordinateUnit(2) == "m"); + CPPUNIT_ASSERT(myCoordinate2->getCoordinateUnit(3) == "m"); + + for (int i = 0; i < _numberofNodes; i++) + CPPUNIT_ASSERT(myCoordinate2->getNodesNumbers()[i] == _numberofNodes - i - 1); + + delete myCoordinate2; + } + + //////////// + // TEST 3 // + //////////// + { + // COORDINATE(int SpaceDimension, int NumberOfNodes, MED_EN::medModeSwitch Mode); + COORDINATE anEmptyC (2, 10, MED_EN::MED_FULL_INTERLACE); + CPPUNIT_ASSERT(anEmptyC.getSpaceDimension() == 2); + CPPUNIT_ASSERT(anEmptyC.getNumberOfNodes() == 10); + CPPUNIT_ASSERT(anEmptyC.getNodesNumbers() == NULL); + // ?: how to fill it with coordinates? + // 1. void setCoordinates(MEDARRAY<double> *Coordinate,bool shallowCopy=false); + // but this way we can override all three constructor parameters + // 2. void setCoordinates(const MED_EN::medModeSwitch Mode, const double *Coordinate); + // in this case we can override Mode + +//#ifdef ENABLE_FAULTS + // (BUG) Incoherence between setCoordinateName() and getCoordinateName() + //anEmptyC.setCoordinateName("alpha", 1); + //anEmptyC.setCoordinateName("betta", 2); + // (BUG) Incoherence between setCoordinateUnit() and getCoordinateUnit() + //anEmptyC.setCoordinateUnit("ttt", 1); + //anEmptyC.setCoordinateUnit("sss", 2); +//#else + anEmptyC.setCoordinateName("alpha", 0); + anEmptyC.setCoordinateName("betta", 1); + + anEmptyC.setCoordinateUnit("ttt", 0); + anEmptyC.setCoordinateUnit("sss", 1); +//#endif +//#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_FAIL("Incoherence between COORDINATE::setCoordinateName() and COORDINATE::getCoordinateName()"); + //CPPUNIT_FAIL("Incoherence between COORDINATE::setCoordinateUnit() and COORDINATE::getCoordinateUnit()"); +//#endif + + int len = 10 * 2; + double * cc = new double[len]; + for (int i = 0; i < len; i++) { + cc[i] = (double)(i + 1); + } + anEmptyC.setCoordinates(MED_EN::MED_NO_INTERLACE, cc); + + CPPUNIT_ASSERT(anEmptyC.getCoordinateName(1) == "alpha"); + CPPUNIT_ASSERT(anEmptyC.getCoordinateName(2) == "betta"); + CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(1) == "ttt"); + CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(2) == "sss"); + for (int nn = 1; nn <= 10; nn++) { + for (int aa = 1; aa <= 2; aa++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(nn + (aa - 1) * 10, anEmptyC.getCoordinate(nn, aa), 0.000001); + } + } + + CPPUNIT_ASSERT_THROW(anEmptyC.getCoordinate(0, 0), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(anEmptyC.getCoordinate(10, 10), MEDEXCEPTION); + + MEDARRAY<double> mcc (cc, 2, 10, MED_EN::MED_FULL_INTERLACE, false, false); + anEmptyC.setCoordinates(&mcc, false); + + // coordinates names and units are not changed + CPPUNIT_ASSERT(anEmptyC.getCoordinateName(1) == "alpha"); + CPPUNIT_ASSERT(anEmptyC.getCoordinateName(2) == "betta"); + CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(1) == "ttt"); + CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(2) == "sss"); + for (int nn = 1; nn <= 10; nn++) { + for (int aa = 1; aa <= 2; aa++) { + // coordinates changed + CPPUNIT_ASSERT_DOUBLES_EQUAL((nn - 1) * 2 + aa, anEmptyC.getCoordinate(nn, aa), 0.000001); + } + } + + delete [] cc; + +//#ifdef ENABLE_FAULTS + // (BUG) Segmentation Fault or Hang up after anEmptyC and mcc destruction, + // because array will be owned by two pointers (in mcc and in anEmptyC) after this call + //???skl anEmptyC.setCoordinates(&mcc, true); + // In other case (if we dynamically allocate mcc and do not free it) we will have memory leak. +//#endif +//#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_FAIL("Bug in COORDINATE::setCoordinates() in shallow copy mode"); +//#endif + } + + //////////// + // TEST 4 // + //////////// + { + // COORDINATE(int SpaceDimension,const string * CoordinateName, const string * CoordinateUnit); + string cnames [3] = {"al", "be", "ga"}; + string cunits [3] = {"kg", "mm", "s2"}; + COORDINATE anEmptyA (3, cnames, cunits); + + CPPUNIT_ASSERT(anEmptyA.getCoordinateName(1) == "al"); + CPPUNIT_ASSERT(anEmptyA.getCoordinateName(2) == "be"); + CPPUNIT_ASSERT(anEmptyA.getCoordinateName(3) == "ga"); + + CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(1) == "kg"); + CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(2) == "mm"); + CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(3) == "s2"); + + CPPUNIT_ASSERT_EQUAL(anEmptyA.getSpaceDimension(), 0); + CPPUNIT_ASSERT_EQUAL(anEmptyA.getNumberOfNodes(), 0); + + MEDARRAY<double> mcc (3, 7, MED_EN::MED_NO_INTERLACE); + anEmptyA.setCoordinates(&mcc, false); + + CPPUNIT_ASSERT_EQUAL(anEmptyA.getSpaceDimension(), 3); + CPPUNIT_ASSERT_EQUAL(anEmptyA.getNumberOfNodes(), 7); + + CPPUNIT_ASSERT(anEmptyA.getCoordinateName(1) == "al"); + CPPUNIT_ASSERT(anEmptyA.getCoordinateName(2) == "be"); + CPPUNIT_ASSERT(anEmptyA.getCoordinateName(3) == "ga"); + + CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(1) == "kg"); + CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(2) == "mm"); + CPPUNIT_ASSERT(anEmptyA.getCoordinateUnit(3) == "s2"); + + CPPUNIT_ASSERT_THROW(anEmptyA.getCoordinate(-1, 0), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(anEmptyA.getCoordinate(10, 10), MEDEXCEPTION); + + // No COORDINATE::operator=, but this is compilable + // good + //COORDINATE anEmptyB; + //COORDINATE anEmptyD (3, cnames, cunits); + //anEmptyB = anEmptyD; + //CPPUNIT_ASSERT(anEmptyB.getCoordinateName(1) == "al"); + + // bad (assert fails) + //COORDINATE anEmptyB; + // Object, created in this line, is destructed right after it. + //anEmptyB = COORDINATE(3, cnames, cunits); + // Now a pointer _coordinateName inside anEmptyB points to a desallocated memory zone + //CPPUNIT_ASSERT(anEmptyB.getCoordinateName(1) == "al"); + } +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_Coordinate_fault.cxx b/src/MEDMEMCppTest/MEDMEMTest_Coordinate_fault.cxx new file mode 100644 index 000000000..0fb2a574a --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Coordinate_fault.cxx @@ -0,0 +1,60 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_Array.hxx" +#include "MEDMEM_Coordinate.hxx" + +using namespace std; +using namespace MEDMEM; + +int main (int argc, char** argv) +{ + COORDINATE anEmptyC (2, 10, MED_EN::MED_FULL_INTERLACE); + + // (BUG) Incoherence between setCoordinateName() and getCoordinateName() + // C++ index notation is used in "set" methods, while in "get" methods indices start from 1. + anEmptyC.setCoordinateName("alpha", 1); + anEmptyC.setCoordinateName("betta", 2); + // (BUG) Incoherence between setCoordinateUnit() and getCoordinateUnit() + // C++ index notation is used in "set" methods, while in "get" methods indices start from 1. + anEmptyC.setCoordinateUnit("ttt", 1); + anEmptyC.setCoordinateUnit("sss", 2); + + //CPPUNIT_ASSERT(anEmptyC.getCoordinateName(1) == "alpha"); + //CPPUNIT_ASSERT(anEmptyC.getCoordinateName(2) == "betta"); + //CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(1) == "ttt"); + //CPPUNIT_ASSERT(anEmptyC.getCoordinateUnit(2) == "sss"); + + int len = 10 * 2; + double * cc = new double[len]; + for (int i = 0; i < len; i++) { + cc[i] = (double)(i + 1); + } + + MEDARRAY<double> mcc (cc, 2, 10, MED_EN::MED_FULL_INTERLACE, false, false); + delete [] cc; + + // (BUG) Bug in COORDINATE::setCoordinates() in shallow copy mode: + // Segmentation Fault or Hang up after anEmptyC and mcc destruction, + // because array will be owned by two pointers (in mcc and in anEmptyC) after this call + anEmptyC.setCoordinates(&mcc, true); + // In other case (if we dynamically allocate mcc and do not free it) we will have memory leak. +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_DriverFactory.cxx b/src/MEDMEMCppTest/MEDMEMTest_DriverFactory.cxx new file mode 100644 index 000000000..1edede406 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_DriverFactory.cxx @@ -0,0 +1,920 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/Message.h> +#include <cppunit/TestAssert.h> + +#include "MEDMEM_DriverFactory.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_GenDriver.hxx" +#include "MEDMEM_GibiMeshDriver.hxx" +#include "MEDMEM_MedFieldDriver21.hxx" +#include "MEDMEM_MedFieldDriver22.hxx" +#include "MEDMEM_MedFieldDriver.hxx" +#include "MEDMEM_Med.hxx" +#include "MEDMEM_MedMedDriver21.hxx" +#include "MEDMEM_MedMedDriver22.hxx" +#include "MEDMEM_MedMedDriver.hxx" +#include "MEDMEM_MedMeshDriver21.hxx" +#include "MEDMEM_MedMeshDriver22.hxx" +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_PorflowMeshDriver.hxx" +#include "MEDMEM_STRING.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_VtkFieldDriver.hxx" +#include "MEDMEM_VtkMedDriver.hxx" +#include "MEDMEM_VtkMeshDriver.hxx" + +#include <sstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; + +// #9: MEDMEM_DriverFactory.hxx } MEDMEMTest_DriverFactory.cxx + +/*! + * Check methods (11), defined in MEDMEM_DriverFactory.hxx: + * namespace DRIVERFACTORY { + * (+) MED_EN::medFileVersion getMedFileVersionForWriting(); + * (+) void setMedFileVersionForWriting(MED_EN::medFileVersion version); + * (+) driverTypes deduceDriverTypeFromFileName(const std::string & fileName); + * + * (+) GENDRIVER * buildDriverForMesh (driverTypes driverType, const std::string & fileName, + * MESH *mesh, const string & driverName, + * MED_EN::med_mode_acces access); + * (+) template<class T, class INTERLACING_TAG> + * GENDRIVER * buildDriverForField(driverTypes driverType, const std::string & fileName, + * FIELD<T,INTERLACING_TAG> *fielde, + * MED_EN::med_mode_acces access); + * (+) GENDRIVER * buildDriverForMed (driverTypes driverType, const std::string & fileName, + * MED *mede, + * MED_EN::med_mode_acces access); + * + * (+) GENDRIVER * buildMedDriverFromFile (const string & fileName, MED * const ptrMed, + * MED_EN::med_mode_acces access); + * (+) GENDRIVER * buildMeshDriverFromFile (const string & fileName, MESH * ptrMesh, + * MED_EN::med_mode_acces access); + * (+) template<class T, class INTERLACING_TAG> + * GENDRIVER * buildFieldDriverFromFile(const string & fileName, + * FIELD<T,INTERLACING_TAG> * ptrField, + * MED_EN::med_mode_acces access); + * + * (+) GENDRIVER * buildConcreteMedDriverForMesh(const std::string & fileName, MESH *mesh, + * const string & driverName, + * MED_EN::med_mode_acces access, + * MED_EN::medFileVersion version); + * (+) template<class T, class INTERLACING_TAG> + * GENDRIVER * buildConcreteMedDriverForField(const std::string & fileName, + * FIELD<T,INTERLACING_TAG> *fielde, + * MED_EN::med_mode_acces access, + * MED_EN::medFileVersion version); + * } + */ +void MEDMEMTest::testDriverFactory() +{ + /////////////////////////////////////////////////////////////////////// + // Test 1: getMedFileVersionForWriting & setMedFileVersionForWriting // + /////////////////////////////////////////////////////////////////////// + + // save current version preference + MED_EN::medFileVersion aVersionSaved = DRIVERFACTORY::getMedFileVersionForWriting(); + + // check version preference changing + MED_EN::medFileVersion aVersionToSet = + (aVersionSaved == MED_EN::V22) ? MED_EN::V21 : MED_EN::V22; + DRIVERFACTORY::setMedFileVersionForWriting(aVersionToSet); + CPPUNIT_ASSERT(aVersionToSet == DRIVERFACTORY::getMedFileVersionForWriting()); + + // restore default version preference + DRIVERFACTORY::setMedFileVersionForWriting(aVersionSaved); + + ////////////////////////////////////////// + // Test 2: deduceDriverTypeFromFileName // + ////////////////////////////////////////// + CPPUNIT_ASSERT(DRIVERFACTORY::deduceDriverTypeFromFileName("test.med") == MED_DRIVER); + CPPUNIT_ASSERT(DRIVERFACTORY::deduceDriverTypeFromFileName("t.st.sauve") == GIBI_DRIVER); + CPPUNIT_ASSERT(DRIVERFACTORY::deduceDriverTypeFromFileName("t.st.sauv") == GIBI_DRIVER); + CPPUNIT_ASSERT(DRIVERFACTORY::deduceDriverTypeFromFileName("t.st.cnc") == PORFLOW_DRIVER); + CPPUNIT_ASSERT(DRIVERFACTORY::deduceDriverTypeFromFileName("t.st.inp") == PORFLOW_DRIVER); + CPPUNIT_ASSERT(DRIVERFACTORY::deduceDriverTypeFromFileName("t.st.xyz") == PORFLOW_DRIVER); + CPPUNIT_ASSERT(DRIVERFACTORY::deduceDriverTypeFromFileName("t.st.vtk") == VTK_DRIVER); + CPPUNIT_ASSERT(DRIVERFACTORY::deduceDriverTypeFromFileName("t_st_med") == NO_DRIVER); + CPPUNIT_ASSERT(DRIVERFACTORY::deduceDriverTypeFromFileName("t.st.med1") == NO_DRIVER); + + //////////////////////////////////////////////////////// + // Test building drivers for different types of files // + //////////////////////////////////////////////////////// + GENDRIVER * aDriver = NULL; + + /////////////////////////////// + // Test 3: buildDriverForMed // + /////////////////////////////// + MED med; + + // 3.1: MED_DRIVER + + // rdonly + aDriver = DRIVERFACTORY::buildDriverForMed(MED_DRIVER, "anyfile", &med, MED_EN::RDONLY); +//#ifdef ENABLE_FORCED_FAILURES + // (BUG) See more details below for the same problem of MED_MESH_RDONLY_DRIVER + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT_EQUAL(MED_EN::RDONLY, aDriver->getAccessMode()); +//#endif + + MED_MED_RDONLY_DRIVER * aMedRDriverForMed = dynamic_cast<MED_MED_RDONLY_DRIVER *> (aDriver); + CPPUNIT_ASSERT(aMedRDriverForMed); + + delete aDriver; + + // wronly + aDriver = DRIVERFACTORY::buildDriverForMed(MED_DRIVER, "anyfile", &med, MED_EN::WRONLY); +//#ifdef ENABLE_FORCED_FAILURES + // (BUG) See more details below for the same problem of MED_MESH_RDONLY_DRIVER + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::WRONLY); +//#endif + + MED_MED_WRONLY_DRIVER * aMedWDriverForMed = dynamic_cast<MED_MED_WRONLY_DRIVER *> (aDriver); + CPPUNIT_ASSERT(aMedWDriverForMed); + + delete aDriver; + + // rdwr + aDriver = DRIVERFACTORY::buildDriverForMed(MED_DRIVER, "anyfile", &med, MED_EN::RDWR); +//#ifdef ENABLE_FORCED_FAILURES + // (BUG) See more details below for the same problem of MED_MESH_RDONLY_DRIVER + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); +//#endif + + MED_MED_RDWR_DRIVER * aMedRWDriverForMed = dynamic_cast<MED_MED_RDWR_DRIVER *> (aDriver); + CPPUNIT_ASSERT(aMedRWDriverForMed); + + delete aDriver; + + // 3.2: GIBI_DRIVER + + // rdonly + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMed(GIBI_DRIVER, "anyfile", &med, MED_EN::RDONLY), + MED_EXCEPTION); + // wronly + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMed(GIBI_DRIVER, "anyfile", &med, MED_EN::WRONLY), + MED_EXCEPTION); + // rdwr + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMed(GIBI_DRIVER, "anyfile", &med, MED_EN::RDWR), + MED_EXCEPTION); + + // 3.3: PORFLOW_DRIVER + + // rdonly + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMed(PORFLOW_DRIVER, "anyfile", &med, MED_EN::RDONLY), + MED_EXCEPTION); + // wronly + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMed(PORFLOW_DRIVER, "anyfile", &med, MED_EN::WRONLY), + MED_EXCEPTION); + // rdwr + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMed(PORFLOW_DRIVER, "anyfile", &med, MED_EN::RDWR), + MED_EXCEPTION); + + // 3.4: VTK_DRIVER + + // rdonly + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMed(VTK_DRIVER, "anyfile", &med, MED_EN::RDONLY), + MED_EXCEPTION); + + // wronly + aDriver = DRIVERFACTORY::buildDriverForMed(VTK_DRIVER, "anyfile", &med, MED_EN::WRONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + // next string is commented by skl since VTK driver is + // created without mode + //CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::WRONLY); + + VTK_MED_DRIVER * aVtkDriverForMed = dynamic_cast<VTK_MED_DRIVER *> (aDriver); + CPPUNIT_ASSERT(aVtkDriverForMed); + + delete aDriver; + + // rdwr + aDriver = DRIVERFACTORY::buildDriverForMed(VTK_DRIVER, "anyfile", &med, MED_EN::RDWR); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); + + aVtkDriverForMed = dynamic_cast<VTK_MED_DRIVER *> (aDriver); + CPPUNIT_ASSERT(aVtkDriverForMed); + + delete aDriver; + + // 3.5: ASCII_DRIVER + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMed(ASCII_DRIVER, "anyfile", &med, MED_EN::RDONLY), + MED_EXCEPTION); + + // 3.6: NO_DRIVER + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMed(NO_DRIVER, "anyfile", &med, MED_EN::RDONLY), + MED_EXCEPTION); + + //////////////////////////////// + // Test 4: buildDriverForMesh // + //////////////////////////////// + MESH mesh; + + // 4.1: MED_DRIVER + + // rdonly + aDriver = DRIVERFACTORY::buildDriverForMesh + (MED_DRIVER, "anyfile", &mesh, "my driver name", MED_EN::RDONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDONLY); + + + MED_MESH_RDONLY_DRIVER * aMedRDriverForMesh = dynamic_cast<MED_MESH_RDONLY_DRIVER *> (aDriver); + CPPUNIT_ASSERT(aMedRDriverForMesh); + CPPUNIT_ASSERT(aMedRDriverForMesh->getMeshName() == "my driver name"); + + + delete aDriver; + + // wronly + aDriver = DRIVERFACTORY::buildDriverForMesh + (MED_DRIVER, "anyfile", &mesh, "my driver name", MED_EN::WRONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::WRONLY); + + MED_MESH_WRONLY_DRIVER * aMedWDriverForMesh = dynamic_cast<MED_MESH_WRONLY_DRIVER *> (aDriver); + CPPUNIT_ASSERT(aMedWDriverForMesh); + CPPUNIT_ASSERT(aMedWDriverForMesh->getMeshName() == "my driver name"); + + delete aDriver; + + // rdwr + aDriver = DRIVERFACTORY::buildDriverForMesh + (MED_DRIVER, "anyfile", &mesh, "my driver name", MED_EN::RDWR); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); + + MED_MESH_RDWR_DRIVER * aMedRWDriverForMesh = dynamic_cast<MED_MESH_RDWR_DRIVER *> (aDriver); + CPPUNIT_ASSERT(aMedRWDriverForMesh); + CPPUNIT_ASSERT(aMedRWDriverForMesh->getMeshName() == "my driver name"); + + delete aDriver; + + // 4.2: GIBI_DRIVER + + // rdonly + aDriver = DRIVERFACTORY::buildDriverForMesh + (GIBI_DRIVER, "anyfile", &mesh, "my driver name", MED_EN::RDONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDONLY); + + GIBI_MESH_RDONLY_DRIVER * aGibiDriverForMesh = dynamic_cast<GIBI_MESH_RDONLY_DRIVER *> (aDriver); + CPPUNIT_ASSERT(aGibiDriverForMesh); + + delete aDriver; + + // wronly + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMesh(GIBI_DRIVER, "anyfile", &mesh, + "my driver name", MED_EN::WRONLY), + MED_EXCEPTION); + // rdwr + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMesh(GIBI_DRIVER, "anyfile", &mesh, + "my driver name", MED_EN::RDWR), + MED_EXCEPTION); + + // 4.3: PORFLOW_DRIVER + + // rdonly + aDriver = DRIVERFACTORY::buildDriverForMesh + (PORFLOW_DRIVER, "anyfile", &mesh, "my driver name", MED_EN::RDONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDONLY); + + PORFLOW_MESH_RDONLY_DRIVER * aPorflowDriverForMesh = dynamic_cast<PORFLOW_MESH_RDONLY_DRIVER *> (aDriver); + CPPUNIT_ASSERT(aPorflowDriverForMesh); + + delete aDriver; + + // wronly + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMesh(PORFLOW_DRIVER, "anyfile", &mesh, + "my driver name", MED_EN::WRONLY), + MED_EXCEPTION); + // rdwr + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMesh(PORFLOW_DRIVER, "anyfile", &mesh, + "my driver name", MED_EN::RDWR), + MED_EXCEPTION); + + // 4.4: VTK_DRIVER + + // rdonly + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMesh(VTK_DRIVER, "anyfile", &mesh, + "my driver name", MED_EN::RDONLY), + MED_EXCEPTION); + + // wronly + aDriver = DRIVERFACTORY::buildDriverForMesh + (VTK_DRIVER, "anyfile", &mesh, "my driver name", MED_EN::WRONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::WRONLY); + + VTK_MESH_DRIVER * aVtkDriverForMesh = dynamic_cast<VTK_MESH_DRIVER *> (aDriver); + CPPUNIT_ASSERT(aVtkDriverForMesh); + + delete aDriver; + + // rdwr + aDriver = DRIVERFACTORY::buildDriverForMesh + (VTK_DRIVER, "anyfile", &mesh, "my driver name", MED_EN::RDWR); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + // next string is commented by skl since VTK driver is + // created without mode + //CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); + + aVtkDriverForMesh = dynamic_cast<VTK_MESH_DRIVER *> (aDriver); + CPPUNIT_ASSERT(aVtkDriverForMesh); + + delete aDriver; + + // 4.5: ASCII_DRIVER + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMesh(ASCII_DRIVER, "anyfile", &mesh, + "my driver name", MED_EN::RDONLY), + MED_EXCEPTION); + + // 4.6: NO_DRIVER + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForMesh(NO_DRIVER, "anyfile", &mesh, + "my driver name", MED_EN::RDONLY), + MED_EXCEPTION); + + ///////////////////////////////// + // Test 5: buildDriverForField // + ///////////////////////////////// + FIELD<double> field; + + // 5.1: MED_DRIVER + + // rdonly + aDriver = DRIVERFACTORY::buildDriverForField(MED_DRIVER, "anyfile", &field, MED_EN::RDONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDONLY); + + MED_FIELD_RDONLY_DRIVER<double> * aMedRDriverForField = + dynamic_cast<MED_FIELD_RDONLY_DRIVER<double> *> (aDriver); + CPPUNIT_ASSERT(aMedRDriverForField); + + delete aDriver; + + // wronly + aDriver = DRIVERFACTORY::buildDriverForField(MED_DRIVER, "anyfile", &field, MED_EN::WRONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::WRONLY); + + MED_FIELD_WRONLY_DRIVER<double> * aMedWDriverForField = + dynamic_cast<MED_FIELD_WRONLY_DRIVER<double> *> (aDriver); + CPPUNIT_ASSERT(aMedWDriverForField); + + delete aDriver; + + // rdwr + aDriver = DRIVERFACTORY::buildDriverForField(MED_DRIVER, "anyfile", &field, MED_EN::RDWR); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); +//#ifdef ENABLE_FORCED_FAILURES + // (BUG) Wrong access mode (WRONLY) passed to parent class! + // confusion between MED_DRWR (defined as WRONLY in MEDMEM_define.hxx) + // and RDWR causes confusion in MEDMEM_MedFieldDriver22.hxx + CPPUNIT_ASSERT_EQUAL(MED_EN::RDWR,aDriver->getAccessMode()); +//#endif + + MED_FIELD_RDWR_DRIVER<double> * aMedRWDriverForField = + dynamic_cast<MED_FIELD_RDWR_DRIVER<double> *> (aDriver); + CPPUNIT_ASSERT(aMedRWDriverForField); + + delete aDriver; + + // 5.2: GIBI_DRIVER + + // rdonly + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(GIBI_DRIVER, "anyfile", &field, MED_EN::RDONLY), + MED_EXCEPTION); + // wronly + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(GIBI_DRIVER, "anyfile", &field, MED_EN::WRONLY), + MED_EXCEPTION); + // rdwr + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(GIBI_DRIVER, "anyfile", &field, MED_EN::RDWR), + MED_EXCEPTION); + + // 5.3: PORFLOW_DRIVER + + // rdonly + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(PORFLOW_DRIVER, "anyfile", + &field, MED_EN::RDONLY), + MED_EXCEPTION); + // wronly + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(PORFLOW_DRIVER, "anyfile", + &field, MED_EN::WRONLY), + MED_EXCEPTION); + // rdwr + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(PORFLOW_DRIVER, "anyfile", + &field, MED_EN::RDWR), + MED_EXCEPTION); + + // 5.4: VTK_DRIVER + + // rdonly + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(VTK_DRIVER, "anyfile", &field, MED_EN::RDONLY), + MED_EXCEPTION); + + // wronly + aDriver = DRIVERFACTORY::buildDriverForField(VTK_DRIVER, "anyfile", &field, MED_EN::WRONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::WRONLY); + + VTK_FIELD_DRIVER<double> * aVtkDriverForField = dynamic_cast<VTK_FIELD_DRIVER<double> *> (aDriver); + CPPUNIT_ASSERT(aVtkDriverForField); + + delete aDriver; + + // rdwr + aDriver = DRIVERFACTORY::buildDriverForField(VTK_DRIVER, "anyfile", &field, MED_EN::RDWR); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + // next string is commented by skl since VTK driver is + // created without mode + //CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); + + aVtkDriverForField = dynamic_cast<VTK_FIELD_DRIVER<double> *> (aDriver); + CPPUNIT_ASSERT(aVtkDriverForField); + + delete aDriver; + + // 5.5: ASCII_DRIVER + + // rdonly + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(ASCII_DRIVER, "anyfile", &field, MED_EN::RDONLY), + MED_EXCEPTION); + // rdwr + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(ASCII_DRIVER, "anyfile", &field, MED_EN::RDWR), + MED_EXCEPTION); + + // wronly + // it throws on empty field + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(ASCII_DRIVER, "anyfile", &field, MED_EN::WRONLY), + MED_EXCEPTION); + + // now try with valid field + string datadir = getenv("MED_ROOT_DIR"); + string filename = datadir + "/share/salome/resources/med/pointe.med"; + string meshname = "maa1"; + string fieldname = "fieldcelldoublescalar"; + FIELD<double> * aField1 = new FIELD<double> (MED_DRIVER, filename, fieldname); + const SUPPORT * aSupport = aField1->getSupport(); + MESH * aMesh = new MESH (MED_DRIVER, filename, aSupport->getMeshName()); + aSupport->setMesh(aMesh); + + aDriver = DRIVERFACTORY::buildDriverForField(ASCII_DRIVER, "anyfile", aField1, MED_EN::WRONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::WRONLY); + + // it works! + //aDriver->open(); + //aDriver->write(); + //aDriver->close(); + + ASCII_FIELD_DRIVER<double> * anAsciiDriverForField = + dynamic_cast<ASCII_FIELD_DRIVER<double> *> (aDriver); + CPPUNIT_ASSERT(anAsciiDriverForField); + + delete aDriver; + + delete aField1; + delete aMesh; + + // 5.6: NO_DRIVER + CPPUNIT_ASSERT_THROW(DRIVERFACTORY::buildDriverForField(NO_DRIVER, "anyfile", &field, MED_EN::RDONLY), + MED_EXCEPTION); + + //////////////////////////////////// + // Test 6: buildMedDriverFromFile // + //////////////////////////////////// + string aFileName1 = datadir + "/share/salome/resources/med/pointe.med"; + string aFileName2 = datadir + "/share/salome/resources/med/polyedres.med"; + medFileVersion version1, version2; + + try { + version1 = getMedFileVersion(aFileName1); + } catch (MEDEXCEPTION & ex) { + version1 = DRIVERFACTORY::globalMedFileVersionForWriting; + } + + try { + version2 = getMedFileVersion(aFileName2); + } catch (MEDEXCEPTION & ex) { + version2 = DRIVERFACTORY::globalMedFileVersionForWriting; + } + + // 6.1. Med file V2.1 + string aFileName21 = aFileName1; + if (version1 == MED_EN::V21 || version2 == MED_EN::V21) { + if (version1 == MED_EN::V22) + aFileName21 = aFileName2; + + // rdonly + aDriver = DRIVERFACTORY::buildMedDriverFromFile(aFileName21, &med, MED_EN::RDONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == aFileName21); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDONLY); + + MED_MED_RDONLY_DRIVER21 * aMedRDriverForMed21 = dynamic_cast<MED_MED_RDONLY_DRIVER21 *> (aDriver); + CPPUNIT_ASSERT(aMedRDriverForMed21); + + delete aDriver; + + // wronly + aDriver = DRIVERFACTORY::buildMedDriverFromFile(aFileName21, &med, MED_EN::WRONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == aFileName21); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::WRONLY); + + MED_MED_WRONLY_DRIVER21 * aMedWDriverForMed21 = dynamic_cast<MED_MED_WRONLY_DRIVER21 *> (aDriver); + CPPUNIT_ASSERT(aMedWDriverForMed21); + + delete aDriver; + + // rdwr + aDriver = DRIVERFACTORY::buildMedDriverFromFile(aFileName21, &med, MED_EN::RDWR); + CPPUNIT_ASSERT(aDriver->getFileName() == aFileName21); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); + + MED_MED_RDWR_DRIVER21 * aMedRWDriverForMed21 = dynamic_cast<MED_MED_RDWR_DRIVER21 *> (aDriver); + CPPUNIT_ASSERT(aMedRWDriverForMed21); + + delete aDriver; + } + + // 6.2. Med file V2.2 + string aFileName22 = aFileName2; + if (version2 == MED_EN::V22 || version1 == MED_EN::V22) { + if (version2 == MED_EN::V21) + aFileName22 = aFileName1; + + // rdonly + aDriver = DRIVERFACTORY::buildMedDriverFromFile(aFileName22, &med, MED_EN::RDONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == aFileName22); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDONLY); + + MED_MED_RDONLY_DRIVER22 * aMedRDriverForMed22 = dynamic_cast<MED_MED_RDONLY_DRIVER22 *> (aDriver); + CPPUNIT_ASSERT(aMedRDriverForMed22); + + delete aDriver; + + // wronly + aDriver = DRIVERFACTORY::buildMedDriverFromFile(aFileName22, &med, MED_EN::WRONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == aFileName22); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::WRONLY); + + MED_MED_WRONLY_DRIVER22 * aMedWDriverForMed22 = dynamic_cast<MED_MED_WRONLY_DRIVER22 *> (aDriver); + CPPUNIT_ASSERT(aMedWDriverForMed22); + + delete aDriver; + + // rdwr + aDriver = DRIVERFACTORY::buildMedDriverFromFile(aFileName22, &med, MED_EN::RDWR); + CPPUNIT_ASSERT(aDriver->getFileName() == aFileName22); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); + + MED_MED_RDWR_DRIVER22 * aMedRWDriverForMed22 = dynamic_cast<MED_MED_RDWR_DRIVER22 *> (aDriver); + CPPUNIT_ASSERT(aMedRWDriverForMed22); + + delete aDriver; + } + else { + CPPUNIT_FAIL("Cannot check building of drivers from file for V2.2"); + } + if (version1 != MED_EN::V21 && version2 != MED_EN::V21) { + CPPUNIT_FAIL("Cannot check building of drivers from file for V2.1"); + } + + ///////////////////////////////////// + // Test 7: buildMeshDriverFromFile // + ///////////////////////////////////// + + // 7.1. Med file V2.1 + if (version1 == MED_EN::V21 || version2 == MED_EN::V21) { + // rdonly + aDriver = DRIVERFACTORY::buildMeshDriverFromFile(aFileName21, &mesh, MED_EN::RDONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == aFileName21); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDONLY); + + MED_MESH_RDONLY_DRIVER21 * aMeshRDriverForMed21 = dynamic_cast<MED_MESH_RDONLY_DRIVER21 *> (aDriver); + CPPUNIT_ASSERT(aMeshRDriverForMed21); + + delete aDriver; + + // wronly + aDriver = DRIVERFACTORY::buildMeshDriverFromFile(aFileName21, &mesh, MED_EN::WRONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == aFileName21); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::WRONLY); + + MED_MESH_WRONLY_DRIVER21 * aMeshWDriverForMed21 = dynamic_cast<MED_MESH_WRONLY_DRIVER21 *> (aDriver); + CPPUNIT_ASSERT(aMeshWDriverForMed21); + + delete aDriver; + + // rdwr + aDriver = DRIVERFACTORY::buildMeshDriverFromFile(aFileName21, &mesh, MED_EN::RDWR); + CPPUNIT_ASSERT(aDriver->getFileName() == aFileName21); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); + + MED_MESH_RDWR_DRIVER21 * aMeshRWDriverForMed21 = dynamic_cast<MED_MESH_RDWR_DRIVER21 *> (aDriver); + CPPUNIT_ASSERT(aMeshRWDriverForMed21); + + delete aDriver; + } + + // 7.2. Med file V2.2 + if (version2 == MED_EN::V22 || version1 == MED_EN::V22) { + // rdonly + aDriver = DRIVERFACTORY::buildMeshDriverFromFile(aFileName22, &mesh, MED_EN::RDONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == aFileName22); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDONLY); + + MED_MESH_RDONLY_DRIVER22 * aMeshRDriverForMed22 = dynamic_cast<MED_MESH_RDONLY_DRIVER22 *> (aDriver); + CPPUNIT_ASSERT(aMeshRDriverForMed22); + + delete aDriver; + + // wronly + aDriver = DRIVERFACTORY::buildMeshDriverFromFile(aFileName22, &mesh, MED_EN::WRONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == aFileName22); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::WRONLY); + + MED_MESH_WRONLY_DRIVER22 * aMeshWDriverForMed22 = dynamic_cast<MED_MESH_WRONLY_DRIVER22 *> (aDriver); + CPPUNIT_ASSERT(aMeshWDriverForMed22); + + delete aDriver; + + // rdwr + aDriver = DRIVERFACTORY::buildMeshDriverFromFile(aFileName22, &mesh, MED_EN::RDWR); + CPPUNIT_ASSERT(aDriver->getFileName() == aFileName22); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); + + MED_MESH_RDWR_DRIVER22 * aMeshRWDriverForMed22 = dynamic_cast<MED_MESH_RDWR_DRIVER22 *> (aDriver); + CPPUNIT_ASSERT(aMeshRWDriverForMed22); + + delete aDriver; + } + + ////////////////////////////////////// + // Test 8: buildFieldDriverFromFile // + ////////////////////////////////////// + + // 8.1. Med file V2.1 + if (version1 == MED_EN::V21 || version2 == MED_EN::V21) { + // rdonly + aDriver = DRIVERFACTORY::buildFieldDriverFromFile(aFileName21, &field, MED_EN::RDONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == aFileName21); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDONLY); + + MED_FIELD_RDONLY_DRIVER21<double> * aFieldRDriverForMed21 = + dynamic_cast<MED_FIELD_RDONLY_DRIVER21<double> *> (aDriver); + CPPUNIT_ASSERT(aFieldRDriverForMed21); + + delete aDriver; + + // wronly + aDriver = DRIVERFACTORY::buildFieldDriverFromFile(aFileName21, &field, MED_EN::WRONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == aFileName21); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::WRONLY); + + MED_FIELD_WRONLY_DRIVER21<double> * aFieldWDriverForMed21 = + dynamic_cast<MED_FIELD_WRONLY_DRIVER21<double> *> (aDriver); + CPPUNIT_ASSERT(aFieldWDriverForMed21); + + delete aDriver; + + // rdwr + aDriver = DRIVERFACTORY::buildFieldDriverFromFile(aFileName21, &field, MED_EN::RDWR); + CPPUNIT_ASSERT(aDriver->getFileName() == aFileName21); + //CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); // see MEDMEM_define.hxx + + MED_FIELD_RDWR_DRIVER21<double> * aFieldRWDriverForMed21 = + dynamic_cast<MED_FIELD_RDWR_DRIVER21<double> *> (aDriver); + CPPUNIT_ASSERT(aFieldRWDriverForMed21); + + delete aDriver; + } + + // 8.2. Med file V2.2 + if (version2 == MED_EN::V22 || version1 == MED_EN::V22) { + // rdonly + aDriver = DRIVERFACTORY::buildFieldDriverFromFile(aFileName22, &field, MED_EN::RDONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == aFileName22); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDONLY); + + MED_FIELD_RDONLY_DRIVER22<double> * aFieldRDriverForMed22 = + dynamic_cast<MED_FIELD_RDONLY_DRIVER22<double> *> (aDriver); + CPPUNIT_ASSERT(aFieldRDriverForMed22); + + delete aDriver; + + // wronly + aDriver = DRIVERFACTORY::buildFieldDriverFromFile(aFileName22, &field, MED_EN::WRONLY); + CPPUNIT_ASSERT(aDriver->getFileName() == aFileName22); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::WRONLY); + + MED_FIELD_WRONLY_DRIVER22<double> * aFieldWDriverForMed22 = + dynamic_cast<MED_FIELD_WRONLY_DRIVER22<double> *> (aDriver); + CPPUNIT_ASSERT(aFieldWDriverForMed22); + + delete aDriver; + + // rdwr + aDriver = DRIVERFACTORY::buildFieldDriverFromFile(aFileName22, &field, MED_EN::RDWR); + CPPUNIT_ASSERT(aDriver->getFileName() == aFileName22); + //CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); // see MEDMEM_define.hxx + + MED_FIELD_RDWR_DRIVER22<double> * aFieldRWDriverForMed22 = + dynamic_cast<MED_FIELD_RDWR_DRIVER22<double> *> (aDriver); + CPPUNIT_ASSERT(aFieldRWDriverForMed22); + + delete aDriver; + } + + /////////////////////////////////////////// + // Test 9: buildConcreteMedDriverForMesh // + /////////////////////////////////////////// + + // 9.1. V2.1 + + // rdonly + aDriver = DRIVERFACTORY::buildConcreteMedDriverForMesh("anyfile", &mesh, "my driver name", + MED_EN::RDONLY, MED_EN::V21); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDONLY); + + MED_MESH_RDONLY_DRIVER21 * aMeshRDriverForMed21 = dynamic_cast<MED_MESH_RDONLY_DRIVER21 *> (aDriver); + CPPUNIT_ASSERT(aMeshRDriverForMed21); + CPPUNIT_ASSERT(aMeshRDriverForMed21->getMeshName() == "my driver name"); + + delete aDriver; + + // wronly + aDriver = DRIVERFACTORY::buildConcreteMedDriverForMesh("anyfile", &mesh, "my driver name", + MED_EN::WRONLY, MED_EN::V21); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::WRONLY); + + MED_MESH_WRONLY_DRIVER21 * aMeshWDriverForMed21 = dynamic_cast<MED_MESH_WRONLY_DRIVER21 *> (aDriver); + CPPUNIT_ASSERT(aMeshWDriverForMed21); + CPPUNIT_ASSERT(aMeshWDriverForMed21->getMeshName() == "my driver name"); + + delete aDriver; + + // rdwr + aDriver = DRIVERFACTORY::buildConcreteMedDriverForMesh("anyfile", &mesh, "my driver name", + MED_EN::RDWR, MED_EN::V21); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); + + MED_MESH_RDWR_DRIVER21 * aMeshRWDriverForMed21 = dynamic_cast<MED_MESH_RDWR_DRIVER21 *> (aDriver); + CPPUNIT_ASSERT(aMeshRWDriverForMed21); + CPPUNIT_ASSERT(aMeshRWDriverForMed21->getMeshName() == "my driver name"); + + delete aDriver; + + // 9.2. V2.2 + + // rdonly + aDriver = DRIVERFACTORY::buildConcreteMedDriverForMesh("anyfile", &mesh, "my driver name", + MED_EN::RDONLY, MED_EN::V22); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDONLY); + + MED_MESH_RDONLY_DRIVER22 * aMeshRDriverForMed22 = dynamic_cast<MED_MESH_RDONLY_DRIVER22 *> (aDriver); + CPPUNIT_ASSERT(aMeshRDriverForMed22); + CPPUNIT_ASSERT(aMeshRDriverForMed22->getMeshName() == "my driver name"); + + delete aDriver; + + // wronly + aDriver = DRIVERFACTORY::buildConcreteMedDriverForMesh("anyfile", &mesh, "my driver name", + MED_EN::WRONLY, MED_EN::V22); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::WRONLY); + + MED_MESH_WRONLY_DRIVER22 * aMeshWDriverForMed22 = dynamic_cast<MED_MESH_WRONLY_DRIVER22 *> (aDriver); + CPPUNIT_ASSERT(aMeshWDriverForMed22); + CPPUNIT_ASSERT(aMeshWDriverForMed22->getMeshName() == "my driver name"); + + delete aDriver; + + // rdwr + aDriver = DRIVERFACTORY::buildConcreteMedDriverForMesh("anyfile", &mesh, "my driver name", + MED_EN::RDWR, MED_EN::V22); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); + + MED_MESH_RDWR_DRIVER22 * aMeshRWDriverForMed22 = dynamic_cast<MED_MESH_RDWR_DRIVER22 *> (aDriver); + CPPUNIT_ASSERT(aMeshRWDriverForMed22); + CPPUNIT_ASSERT(aMeshRWDriverForMed22->getMeshName() == "my driver name"); + + delete aDriver; + + ///////////////////////////////////////////// + // Test 10: buildConcreteMedDriverForField // + ///////////////////////////////////////////// + + // 10.1. V2.1 + + // rdonly + aDriver = DRIVERFACTORY::buildConcreteMedDriverForField("anyfile", &field, MED_EN::RDONLY, MED_EN::V21); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDONLY); + + MED_FIELD_RDONLY_DRIVER21<double> * aFieldRDriverForMed21 = + dynamic_cast<MED_FIELD_RDONLY_DRIVER21<double> *> (aDriver); + CPPUNIT_ASSERT(aFieldRDriverForMed21); + + delete aDriver; + + // wronly + aDriver = DRIVERFACTORY::buildConcreteMedDriverForField("anyfile", &field, MED_EN::WRONLY, MED_EN::V21); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::WRONLY); + + MED_FIELD_WRONLY_DRIVER21<double> * aFieldWDriverForMed21 = + dynamic_cast<MED_FIELD_WRONLY_DRIVER21<double> *> (aDriver); + CPPUNIT_ASSERT(aFieldWDriverForMed21); + + delete aDriver; + + // rdwr + aDriver = DRIVERFACTORY::buildConcreteMedDriverForField("anyfile", &field, MED_EN::RDWR, MED_EN::V21); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + //CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); // see MEDMEM_define.hxx + + MED_FIELD_RDWR_DRIVER21<double> * aFieldRWDriverForMed21 = + dynamic_cast<MED_FIELD_RDWR_DRIVER21<double> *> (aDriver); + CPPUNIT_ASSERT(aFieldRWDriverForMed21); + + delete aDriver; + + // 10.2. V2.2 + + // rdonly + aDriver = DRIVERFACTORY::buildConcreteMedDriverForField("anyfile", &field, MED_EN::RDONLY, MED_EN::V22); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDONLY); + + MED_FIELD_RDONLY_DRIVER22<double> * aFieldRDriverForMed22 = + dynamic_cast<MED_FIELD_RDONLY_DRIVER22<double> *> (aDriver); + CPPUNIT_ASSERT(aFieldRDriverForMed22); + + delete aDriver; + + // wronly + aDriver = DRIVERFACTORY::buildConcreteMedDriverForField("anyfile", &field, MED_EN::WRONLY, MED_EN::V22); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::WRONLY); + + MED_FIELD_WRONLY_DRIVER22<double> * aFieldWDriverForMed22 = + dynamic_cast<MED_FIELD_WRONLY_DRIVER22<double> *> (aDriver); + CPPUNIT_ASSERT(aFieldWDriverForMed22); + + delete aDriver; + + // rdwr + aDriver = DRIVERFACTORY::buildConcreteMedDriverForField("anyfile", &field, MED_EN::RDWR, MED_EN::V22); + CPPUNIT_ASSERT(aDriver->getFileName() == "anyfile"); + //CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); + CPPUNIT_ASSERT(aDriver->getAccessMode() == MED_EN::RDWR); // see MEDMEM_define.hxx + + MED_FIELD_RDWR_DRIVER22<double> * aFieldRWDriverForMed22 = + dynamic_cast<MED_FIELD_RDWR_DRIVER22<double> *> (aDriver); + CPPUNIT_ASSERT(aFieldRWDriverForMed22); + + delete aDriver; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_Exception.cxx b/src/MEDMEMCppTest/MEDMEMTest_Exception.cxx new file mode 100644 index 000000000..26402a42b --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Exception.cxx @@ -0,0 +1,140 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_STRING.hxx" + +#include <sstream> +#include <cmath> +#include <cstring> + +using namespace std; +using namespace MEDMEM; + +// #12: MEDMEM_Exception.hxx } MEDMEMTest_Exception.cxx + +/*! + * Check methods (not in spec), defined in MEDMEM_Exception.hxx: + * (+) #define LOCALIZED(message) static_cast<const char *> (message) , __FILE__ , __LINE__ + * class MEDEXCEPTION : public std::exception { + * (+) MEDEXCEPTION(const char *text, const char *fileName=0, const unsigned int lineNumber=0); + * (+) MEDEXCEPTION(const MEDEXCEPTION &ex); + * (+) ~MEDEXCEPTION() throw (); + * (+) friend ostream & operator<< (ostream &os, const MEDEXCEPTION &ex); + * (+) virtual const char *what(void) const throw (); + * } + * class MED_DRIVER_NOT_FOUND_EXCEPTION : public MEDEXCEPTION { + * (+) MED_DRIVER_NOT_FOUND_EXCEPTION(const char *text, const char *fileName=0, + * const unsigned int lineNumber=0); + * (+) MED_DRIVER_NOT_FOUND_EXCEPTION(const MED_DRIVER_NOT_FOUND_EXCEPTION &ex); + * (+) ~MED_DRIVER_NOT_FOUND_EXCEPTION() throw(); + * } + * + * Use code of MEDMEM/tests/testUMedException.cxx + */ +void MEDMEMTest::testException() +{ + { + // test simple constructor + MEDEXCEPTION a = MEDEXCEPTION("test med exception"); + CPPUNIT_ASSERT(a.what()); + CPPUNIT_ASSERT(strcmp(a.what(), "MED Exception : test med exception") == 0); + + // test copy constructor + MEDEXCEPTION b (a); + CPPUNIT_ASSERT(b.what()); + CPPUNIT_ASSERT(strcmp(b.what(), "MED Exception : test med exception") == 0); + + // test dumping of exception in stream + ostringstream ostr; + ostr << b; + CPPUNIT_ASSERT(ostr.str() == "MED Exception : test med exception"); + } + + { + // test constructor from three arguments + MEDEXCEPTION c ("test med exception", "<file_name>.cxx", 14); + CPPUNIT_ASSERT(c.what()); + CPPUNIT_ASSERT(strcmp(c.what(), "MED Exception in <file_name>.cxx [14] : test med exception") == 0); + } + + { + // Test macro LOCALIZED + STRING msgErr; + msgErr << "ESSAI::ESSAI()! "<< 4 << "ieme essai "; + + const char* prefix = "MED Exception"; + const char* exctxt = static_cast<const char *>(msgErr); + const char* filen = __FILE__; + unsigned int linen = __LINE__ + 5; + const size_t len = strlen(prefix) + strlen(exctxt) + strlen(filen) + + (1 + int(log10(float(linen)))) + 10 + 1; + char* excmsg = new char [len]; + sprintf(excmsg, "%s in %s [%u] : %s", prefix, filen, linen, exctxt); + CPPUNIT_ASSERT(strcmp(MEDEXCEPTION(LOCALIZED(msgErr)).what(), excmsg) == 0); + + delete [] excmsg; + } + + { + // Test function STRING<< + const char * LOC = "toto"; + CPPUNIT_ASSERT(MEDEXCEPTION(LOCALIZED(STRING(LOC) << " et titi")).what()); + + // Test throw + MEDEXCEPTION d (LOCALIZED(STRING(LOC) << " et titi")); + const char* dtxt = d.what(); + try { + throw d; + } + catch (MEDEXCEPTION dc) { + CPPUNIT_ASSERT(strcmp(dc.what(), dtxt) == 0); + } + catch (...) { + CPPUNIT_FAIL("Unknown exception"); + } + } + + { + // Test MED_DRIVER_NOT_FOUND_EXCEPTION + MED_DRIVER_NOT_FOUND_EXCEPTION g ("mdnfe"); + try { + throw g; + } + catch (MED_DRIVER_NOT_FOUND_EXCEPTION mdnfe) { + CPPUNIT_ASSERT(strcmp(mdnfe.what(), g.what()) == 0); + } + catch (MEDEXCEPTION me) { + CPPUNIT_FAIL(me.what()); + } + catch (...) { + CPPUNIT_FAIL("Unknown exception"); + } + + // Copy constructor + MED_DRIVER_NOT_FOUND_EXCEPTION gcopy (g); + CPPUNIT_ASSERT(gcopy.what()); + CPPUNIT_ASSERT(strcmp(gcopy.what(), g.what()) == 0); + } +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_Extractor.cxx b/src/MEDMEMCppTest/MEDMEMTest_Extractor.cxx new file mode 100644 index 000000000..b153749b7 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Extractor.cxx @@ -0,0 +1,468 @@ +// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// File : MEDMEMTest_Extractor.cxx +// Created : Mon Dec 22 11:12:57 2008 +// Author : Edward AGAPOV (eap) + +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "MEDMEM_Extractor.hxx" +#include "MEDMEM_Meshing.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; + +//================================================================================ +/*! + * \brief test extractLine() + */ +//================================================================================ + +void test_extractLine( Extractor* extractor, + const double* coords, const double* direction, + int nbSegments, + const char* name, + const string& result_file) +{ + cout << name << endl; + FIELD<double>* resField =0; + CPPUNIT_ASSERT_NO_THROW( resField = extractor->extractLine(coords,direction)); + CPPUNIT_ASSERT( bool( resField ) == bool( nbSegments > 0 )); + + // store extracted field + if ( resField ) { + MESH* mesh = resField->getSupport()->getMesh(); + mesh->setName( name ); + int drv = mesh->addDriver( MED_DRIVER, result_file, name ); + mesh->write( drv ); + drv = resField->addDriver(MED_DRIVER, result_file, name ); + resField->write( drv ); + + CPPUNIT_ASSERT_EQUAL( nbSegments, resField->getSupport()->getNumberOfElements(MED_ALL_ELEMENTS)); + CPPUNIT_ASSERT_EQUAL( nbSegments+1, resField->getSupport()->getMesh()->getNumberOfNodes()); + } + + delete resField; +} + +void MEDMEMTest::testExtractor() +{ + // ======================= + // TEST 3D->2D extraction + // ======================= + + // read a mesh from a MED file + string datadir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP"); + string filename = datadir + "/share/salome/resources/med/pointe.med"; + string meshname = "maa1"; + string fieldname = "fieldcelldoublescalar"; + + if (tmp_dir == "") + tmp_dir = "/tmp"; + string result_file = tmp_dir + "/extracted_2D.med"; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(result_file); + + // field with no mesh + FIELD<double> * aField1 = new FIELD<double> (MED_DRIVER, filename, fieldname); + CPPUNIT_ASSERT_THROW( new Extractor(*aField1), MEDEXCEPTION); + + const SUPPORT * aSupport = aField1->getSupport(); + MESH * aMesh = new MESH (MED_DRIVER, filename, aSupport->getMeshName()); + aSupport->setMesh(aMesh); + + Extractor* extractor = 0; + CPPUNIT_ASSERT_NO_THROW( extractor = new Extractor(*aField1)); + + FIELD<double>* resField = 0; + double coords [3] = { 0,0,0 }; + { + // bad normal + double normal [3] = { 0,0,0 }; + CPPUNIT_ASSERT_THROW( extractor->extractPlane(coords,normal), MEDEXCEPTION); + } + double normal [3] = { 10,0,0 }; + { + // no intersection + double coords [3] = { 10,0,0 }; + CPPUNIT_ASSERT_NO_THROW( resField = extractor->extractPlane(coords,normal)); + CPPUNIT_ASSERT( !bool( resField )); + } + CPPUNIT_ASSERT_NO_THROW( resField = extractor->extractPlane(coords,normal )); + + //Copy file with mesh to result_file + string cp_file = "cp " + filename + " " + result_file; + system(cp_file.c_str()); + + // store extracted mesh + MESH* mesh = resField->getSupport()->getMesh(); + int drv = mesh->addDriver( MED_DRIVER, result_file, mesh->getName() ); + mesh->write( drv ); + CPPUNIT_ASSERT_EQUAL( 2, mesh->getNumberOfTypes(MED_CELL)); + CPPUNIT_ASSERT_EQUAL( 6, mesh->getNumberOfElements(MED_CELL, MED_TRIA3)); + CPPUNIT_ASSERT_EQUAL( 2, mesh->getNumberOfElements(MED_CELL, MED_QUAD4)); + + // store extracted field + drv = resField->addDriver(MED_DRIVER, result_file, resField->getName()); + resField->write( drv ); + + delete extractor; extractor=0; + delete aMesh; aMesh=0; + delete resField; resField=0; + delete aField1; aField1=0; + + // =================================================================================== + // TEST 2D->1D extraction in 3d space + // =================================== + + // create 3d shell + int SpaceDimension = 3 ; + int NumberOfNodes = 8 ; + double Coordinates[24] = { + 0.0, 0.0, 200, + 0.0, 0.0, 0.0, + 0.0, 200, 200, + 0.0, 200, 0.0, + 200, 0.0, 200, + 200, 0.0, 0.0, + 200, 200, 200, + 200, 200, 0.0 + }; + MESHING* myMeshing = new MESHING(); + myMeshing->setName("shell") ; + //myMeshing->setMeshDimension( 3 ); + + myMeshing->setCoordinates(SpaceDimension,NumberOfNodes,Coordinates, + "CARTESIAN",MED_FULL_INTERLACE); + string Names[3] = { "X","Y","Z" } ; + myMeshing->setCoordinatesNames(Names); + string Units[3] = { "cm","cm","cm" } ; + myMeshing->setCoordinatesUnits(Units) ; + + // define conectivities + + const int NumberOfTypes = 1; + medGeometryElement Types[NumberOfTypes] = {MED_TRIA3}; + const int NumberOfElements[NumberOfTypes] = {12}; + + myMeshing->setNumberOfTypes(NumberOfTypes,MED_CELL); + myMeshing->setTypes(Types,MED_CELL); + myMeshing->setNumberOfElements(NumberOfElements,MED_CELL); + + const int sizeTria = 12*3 ; + int ConnectivityTria[sizeTria]= { + 2, 5, 1, + 4, 1, 3, + 3, 1, 7, + 4, 8, 2, + 1, 5, 7, + 6, 5, 2, + 2, 8, 6, + 8, 7, 5, + 6, 8, 5, + 2, 1, 4, + 8, 4, 7, + 4, 3, 7 + }; + myMeshing->setConnectivity(ConnectivityTria,MED_CELL,MED_TRIA3); + myMeshing->setMeshDimension( 3 ); + + // store input mesh + + fieldname = "doubleOnTria"; + result_file = tmp_dir + "/extracted_1D.med"; + + // To remove tmp files from disk + aRemover.Register(result_file); + + drv = myMeshing->addDriver( MED_DRIVER, result_file, myMeshing->getName() ); + CPPUNIT_ASSERT_NO_THROW( myMeshing->write(drv) ); + + // Make input field + + aSupport = new SUPPORT( myMeshing ); + FIELD<double>* inField = new FIELD<double>( aSupport, 1 ); + inField->setName(fieldname); + string str = ""; + inField->setComponentsNames( &str ); + inField->setDescription( str ); + inField->setComponentsDescriptions( &str ); + inField->setMEDComponentsUnits( &str ); + + vector<double> value( NumberOfElements[0] ); + for ( int i = 0; i < value.size(); ++i ) + value[i] = double ( i % 10 ); + inField->setValue( &value[0] ); + + // store input field + drv = inField->addDriver(MED_DRIVER, result_file, fieldname); + inField->write(drv); + + // Extraction + { + double coords [3] = { 0,0,0 }; + double normal [3] = { -2, -2, 1 }; + CPPUNIT_ASSERT_NO_THROW( extractor = new Extractor(*inField)); + CPPUNIT_ASSERT_NO_THROW( resField = extractor->extractPlane(coords,normal)); + CPPUNIT_ASSERT( bool( resField )); + } + + // store extracted mesh + mesh = resField->getSupport()->getMesh(); + drv = mesh->addDriver( MED_DRIVER, result_file, mesh->getName() ); + mesh->write( drv ); + // CPPUNIT_ASSERT_EQUAL( 2, mesh->getNumberOfTypes(MED_CELL)); + // CPPUNIT_ASSERT_EQUAL( 6, mesh->getNumberOfElements(MED_CELL, MED_TRIA3)); + // CPPUNIT_ASSERT_EQUAL( 2, mesh->getNumberOfElements(MED_CELL, MED_QUAD4)); + + // store extracted field + drv = resField->addDriver(MED_DRIVER, result_file, resField->getName()); + resField->write( drv ); + cout << endl << "Write " << result_file << endl; + + delete aSupport; aSupport=0; + delete myMeshing; myMeshing=0; + delete inField; inField=0; + delete extractor; extractor=0; + delete resField; resField=0; + + // ====================================================================================== + // TEST 3D->1D extraction + // ======================= + + // create 3d 2x2x2 hexa box + myMeshing = new MESHING(); + { + SpaceDimension = 3 ; + NumberOfNodes = 27 ; + double Coordinates[27*3] = { + 0.0, 0.0, 200, + 0.0, 0.0, 0.0, + 0.0, 200, 200, + 0.0, 200, 0.0, + 200, 0.0, 200, + 200, 0.0, 0.0, + 200, 200, 200, + 200, 200, 0.0, + 0.0, 0.0, 100, + 0.0, 100, 200, + 0.0, 200, 100, + 0.0, 100, 0.0, + 200, 0.0, 100, + 200, 100, 200, + 200, 200, 100, + 200, 100, 0.0, + 100, 0.0, 0.0, + 100, 0.0, 200, + 100, 200, 0.0, + 100, 200, 200, + 0.0, 100, 100, + 200, 100, 100, + 100, 0.0, 100, + 100, 200, 100, + 100, 100, 0.0, + 100, 100, 200, + 100, 100, 100, + }; + myMeshing->setName("box") ; + //myMeshing->setMeshDimension( 3 ); + + myMeshing->setCoordinates(SpaceDimension,NumberOfNodes,Coordinates, + "CARTESIAN",MED_FULL_INTERLACE); + string Names[3] = { "X","Y","Z" } ; + myMeshing->setCoordinatesNames(Names); + string Units[3] = { "cm","cm","cm" } ; + myMeshing->setCoordinatesUnits(Units) ; + + // define conectivities + + const int NumberOfTypes = 1; + medGeometryElement Types[NumberOfTypes] = {MED_HEXA8}; + const int NumberOfElements[NumberOfTypes] = {8}; + + myMeshing->setNumberOfTypes(NumberOfTypes,MED_CELL); + myMeshing->setTypes(Types,MED_CELL); + myMeshing->setNumberOfElements(NumberOfElements,MED_CELL); + + int ConnectivityHex[8*8]= { + 9, 23, 18, 1, 21, 27, 26, 10, + 25, 16, 22, 27, 19, 8, 15, 24, + 27, 22, 14, 26, 24, 15, 7, 20, + 17, 6, 13, 23, 25, 16, 22, 27, + 21, 27, 26, 10, 11, 24, 20, 3, + 2, 17, 23, 9, 12, 25, 27, 21, + 23, 13, 5, 18, 27, 22, 14, 26, + 12, 25, 27, 21, 4, 19, 24, 11 + }; + myMeshing->setConnectivity(ConnectivityHex,MED_CELL,MED_HEXA8); + myMeshing->setMeshDimension( 3 ); + } + // store input mesh + + fieldname = "doubleOnHex"; + result_file = tmp_dir + "/extracted3D_1D.med"; + + // To remove tmp files from disk + aRemover.Register(result_file); + + drv = myMeshing->addDriver( MED_DRIVER, result_file, myMeshing->getName() ); + CPPUNIT_ASSERT_NO_THROW( myMeshing->write(drv) ); + + // Make input field + + aSupport = new SUPPORT( myMeshing ); + inField = new FIELD<double>( aSupport, 1 ); + inField->setName(fieldname); + inField->setComponentsNames( &str ); + inField->setDescription( str ); + inField->setComponentsDescriptions( &str ); + inField->setMEDComponentsUnits( &str ); + + value.resize( NumberOfElements[0] ); + for ( int i = 0; i < value.size(); ++i ) + value[i] = double (i+1); + inField->setValue( &value[0] ); + + // store input field + drv = inField->addDriver(MED_DRIVER, result_file, fieldname); + inField->write(drv); + cout << endl << "Write " << result_file << endl; + + // Extraction + + CPPUNIT_ASSERT_NO_THROW( extractor = new Extractor(*inField)); + { + // Test corner-corner intersection + double coords [3] = { 1, 1, 1 }; + double direct [3] = { 2, 2, 2 }; + test_extractLine( extractor, coords, direct, 2, "corner-corner", result_file ); + } + { + // Test corner-face intersection + double coords [3] = { 0,0,0 }; + double direct [3] = { 2, 1, 1 }; + test_extractLine( extractor, coords, direct, 2, "corner-face", result_file ); + } + { + // Test on-face intersection + double coords [3] = {-2, 0,-1 }; + double direct [3] = { 2, 0, 1 }; + test_extractLine( extractor, coords, direct, 2, "on-face", result_file ); + } + { + // Test between-cells intersection + double coords [3] = { 100,0,0 }; + double direct [3] = { 0, 2, 2 }; + test_extractLine( extractor, coords, direct, 2, "between-cells", result_file ); + } + { + // Test between-cells-entrance intersection + double coords [3] = { 100,0,0 }; + double direct [3] = { 1, 2, 2 }; + test_extractLine( extractor, coords, direct, 2, "between-cells-entrance", result_file ); + } + { + // Test edge-entrance intersection + double coords [3] = { 100,0,50 }; + double direct [3] = { 1, 2, 2 }; + test_extractLine( extractor, coords, direct, 3, "edge-entrance", result_file ); + } + { + // Test touch intersection - expect no result + double coords [3] = { 0,0,0 }; + double direct [3] = { 0, 2, -2 }; + test_extractLine( extractor, coords, direct, 0, "touch", result_file ); + } + { + // Test face-face intersection + double coords [3] = { 50,50,0 }; + double direct [3] = { 2, 2, 0 }; + test_extractLine( extractor, coords, direct, 2, "corner-corner-on", result_file ); + } + { + // Test face-face intersection + double coords [3] = { 50,50,0 }; + double direct [3] = { 2, 2, 2 }; + test_extractLine( extractor, coords, direct, 3, "face-face", result_file ); + } + { + // Test external edge intersection + double coords [3] = { 0, 0,200 }; + double direct [3] = { -1, 0, 0 }; + test_extractLine( extractor, coords, direct, 2, "external edge", result_file ); + } + { + // Test internal edge intersection + double coords [3] = {100,0,100 }; + double direct [3] = { 0, -2, 0 }; + test_extractLine( extractor, coords, direct, 2, "internal edge", result_file ); + } + + inField->setSupport(0); + delete aSupport; aSupport=0; + delete extractor; extractor=0; + delete myMeshing; myMeshing=0; + + // ====================================================================================== + // TEST 3D->1D extraction on a large model + // ======================================= + + // read a mesh + filename = datadir + "/share/salome/resources/med/geomMesh22.med"; + meshname = "GeomMesh"; + aMesh = new MESH (MED_DRIVER, filename, meshname); + aSupport = new SUPPORT( aMesh ); + + // make a field + int nbValues = aSupport->getNumberOfElements(MED_ALL_ELEMENTS); + inField->setSupport( aSupport ); + inField->allocValue( 1, nbValues ); + { + double* value = const_cast<double*>( inField->getValue() ); + for ( int i = 0; i < nbValues; ++i ) + value[i] = double ( i % 7 ); + } + // extract a field + CPPUNIT_ASSERT_NO_THROW( extractor = new Extractor(*inField)); + { + double coords [3] = { 20,0,10 }; + double direct [3] = { 1, 1,1.5 }; + CPPUNIT_ASSERT_NO_THROW( resField = extractor->extractLine(coords,direct)); + } + CPPUNIT_ASSERT( resField ); + CPPUNIT_ASSERT_EQUAL( 31, resField->getSupport()->getNumberOfElements(MED_ALL_ELEMENTS)); + CPPUNIT_ASSERT_EQUAL( 33, resField->getSupport()->getMesh()->getNumberOfNodes()); + + delete resField; resField=0; + delete aMesh; aMesh=0; + delete aSupport; aSupport=0; + delete inField; inField=0; +} + diff --git a/src/MEDMEMCppTest/MEDMEMTest_Family.cxx b/src/MEDMEMCppTest/MEDMEMTest_Family.cxx new file mode 100644 index 000000000..32dd0f072 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Family.cxx @@ -0,0 +1,496 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "MEDMEM_define.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Support.hxx" +#include "MEDMEM_Compatibility21_22.hxx" + +#include <sstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; + +// #13: MEDMEM_Family.hxx } MEDMEMTest_Family.cxx + +/*! + * Check methods (24), defined in MEDMEM_Family.hxx: + * class FAMILY : virtual public SUPPORT { + * (+) FAMILY(); + * (+) FAMILY(MESH* Mesh, int Identifier, string Name, + * int NumberOfAttribute, int *AttributeIdentifier, + * int *AttributeValue, string AttributeDescription, + * int NumberOfGroup, string GroupName, + * int * MEDArrayNodeFamily, int ** MEDArrayCellFamily, + * int ** MEDArrayFaceFamily, int ** MEDArrayEdgeFamily); + * (+) FAMILY(const FAMILY & m); + * (+) FAMILY(const SUPPORT & s); + * (+) virtual ~FAMILY(); + * + * // Does not work (Segmentation Fault of Hang up) + * (!) FAMILY & operator=(const FAMILY &fam); + * + * (+) friend ostream & operator<<(ostream &os, FAMILY &my); + * (+) friend ostream & operator<<(ostream &os, const FAMILY &my); + * + * (+) bool build(MED_EN::medEntityMesh Entity,int **FamilyNumber); + * + * (+) inline void setIdentifier (int Identifier); + * (+) inline void setNumberOfAttributes (int NumberOfAttribute); + * (+) inline void setAttributesIdentifiers (int * AttributeIdentifier); + * (+) inline void setAttributesValues (int * AttributeValue); + * (+) inline void setAttributesDescriptions (string * AttributeDescription); + * (+) inline void setNumberOfGroups (int NumberOfGroups); + * (+) inline void setGroupsNames (string * GroupName); + * + * (+) inline int getIdentifier() const; + * (+) inline int getNumberOfAttributes() const; + * (+) inline const int * getAttributesIdentifiers() const; + * (+) inline const int * getAttributesValues() const; + * (+) inline const string * getAttributesDescriptions() const; + * (+) inline int getNumberOfGroups() const; + * (+) inline const string * getGroupsNames() const; + * + * (+) inline int getAttributeIdentifier(int i) const; + * (+) inline int getAttributeValue(int i) const; + * (+) inline string getAttributeDescription(int i) const; + * (+) inline string getGroupName(int i) const; + * } + * + * Use code of MEDMEM/test_copie_family.cxx + */ +void check_support(const SUPPORT * theSupport, + string theName, string theDescr, MED_EN::medEntityMesh theEntity, int theNbTypes) +{ + string aName = theSupport->getName(); + string aDescr = theSupport->getDescription(); + MED_EN::medEntityMesh anEntity = theSupport->getEntity(); + int aNbGeomTypes = theSupport->getNumberOfTypes(); + + CPPUNIT_ASSERT_EQUAL(theName, aName); + CPPUNIT_ASSERT_EQUAL(theDescr, aDescr); + CPPUNIT_ASSERT_EQUAL(theEntity, anEntity); + CPPUNIT_ASSERT_EQUAL(theNbTypes, aNbGeomTypes); + + cout << " - Entities list : " << endl; + if (!(theSupport->isOnAllElements())) { + cout << " - NumberOfTypes : " << aNbGeomTypes << endl; + const MED_EN::medGeometryElement * Types = theSupport->getTypes(); + for (int j = 0; j < aNbGeomTypes; j++) { + cout << " * Type " << Types[j] << " : "; + int NumberOfElements = theSupport->getNumberOfElements(Types[j]); + const int * Number = theSupport->getNumber(Types[j]); + for (int k = 0; k < NumberOfElements; k++) + cout << Number[k] << " "; + cout << endl; + } + } else + cout << " Is on all entities !" << endl; +} + +void check_famille(const FAMILY * theFamily, + string theName, string theDescr, MED_EN::medEntityMesh theEntity, int theNbTypes, + int theID, int theNbAttributes, int theNbGroups) +{ + check_support(theFamily, theName, theDescr, theEntity, theNbTypes); + + // identifier + int id = theFamily->getIdentifier(); + int nbAttributes = theFamily->getNumberOfAttributes(); + int nbGroups = theFamily->getNumberOfGroups(); + + CPPUNIT_ASSERT_EQUAL(theID, id); + CPPUNIT_ASSERT_EQUAL(theNbAttributes, nbAttributes); + CPPUNIT_ASSERT_EQUAL(theNbGroups, nbGroups); + + // attributes + cout << " - Attributes (" << nbAttributes << ") :" << endl; + for (int j = 1; j < nbAttributes + 1; j++) + cout << " * " + << theFamily->getAttributeIdentifier(j) << " : " + << theFamily->getAttributeValue(j) << ", " + << theFamily->getAttributeDescription(j).c_str() << endl; + + // groups + cout << " - Groups (" << nbGroups << ") :" << endl; + for (int j = 1; j < nbGroups + 1; j++) + cout << " * " << theFamily->getGroupName(j).c_str() << endl; +} + +void MEDMEMTest::testFamily() +{ + /////////////////////////////////// + // TEST 1: test_copie_family.cxx // + /////////////////////////////////// + string datadir = getenv("MED_ROOT_DIR"); + string filename = datadir + "/share/salome/resources/med/pointe.med"; + string meshname = "maa1"; + + MESH * aMesh = new MESH(); + aMesh->setName(meshname); + MED_MESH_RDONLY_DRIVER aMeshDriver (filename, aMesh); + aMeshDriver.setMeshName(meshname); + aMeshDriver.open(); + aMeshDriver.read(); + aMeshDriver.close(); + + const FAMILY * aFamily1 = aMesh->getFamily(MED_EN::MED_NODE, 1); + + // SUPPORT attributes + string aName = aFamily1->getName(); + string aDescr = aFamily1->getDescription(); + MED_EN::medEntityMesh anEntity = aFamily1->getEntity(); + int aNbGeomTypes = aFamily1->getNumberOfTypes(); + + // FAMILY attributes + int id = aFamily1->getIdentifier(); + int nbAttributes = aFamily1->getNumberOfAttributes(); + int nbGroups = aFamily1->getNumberOfGroups(); + + // Dump + ostringstream ostr1; + ostr1 << *aFamily1; + CPPUNIT_ASSERT(ostr1.str() != ""); + + cout << "Show Family1 :" << endl; + check_famille(aFamily1, + aName, aDescr, anEntity, aNbGeomTypes, + id, nbAttributes, nbGroups); + + // Copy constructor + FAMILY * aFamily2 = new FAMILY (* aFamily1); + + // Dump + ostringstream ostr2; + ostr2 << *aFamily2; + CPPUNIT_ASSERT(ostr1.str() == ostr2.str()); + + // Compare supports + CPPUNIT_ASSERT(aFamily2->deepCompare(*aFamily1)); + + cout << "Show Family2 :" << endl; + check_famille(aFamily2, + aName, aDescr, anEntity, aNbGeomTypes, + id, nbAttributes, nbGroups); + + // One more copy + FAMILY * aFamily3 = new FAMILY (* aFamily2); + delete aFamily2; + + // Dump + ostringstream ostr3; + ostr3 << *aFamily3; + CPPUNIT_ASSERT(ostr1.str() == ostr3.str()); + + cout << "Show Family3 :" << endl; + check_famille(aFamily3, + aName, aDescr, anEntity, aNbGeomTypes, + id, nbAttributes, nbGroups); + + cout << "That's all" << endl; + + //////////// + // TEST 2 // + //////////// + { + // Prepare data + + // attributes + int newNumberOfAttribute = 3; + int * newAttributeIdentifier = new int[newNumberOfAttribute]; + int * newAttributeValue = new int[newNumberOfAttribute]; + string * newAttributeDescription = new string[newNumberOfAttribute]; + + char tmp [32]; + for (int i = 0; i < newNumberOfAttribute; i++) { + newAttributeIdentifier[i] = i+1; + newAttributeValue[i] = (i+1)*10; + sprintf(tmp, "Attribut N° %d", i+1); + newAttributeDescription[i] = tmp; + } + + // groups + int newNumberOfGroups = 4; + string * newGroups = new string[newNumberOfGroups]; + for (int i = 0; i < newNumberOfGroups; i++) { + sprintf(tmp, "Group N° %d", i+1); + newGroups[i] = tmp; + } + + // Change aFamily3 + + // attributes + aFamily3->setNumberOfAttributes(newNumberOfAttribute); + aFamily3->setAttributesIdentifiers(newAttributeIdentifier); + aFamily3->setAttributesValues(newAttributeValue); + aFamily3->setAttributesDescriptions(newAttributeDescription); + + // groups + aFamily3->setNumberOfGroups(newNumberOfGroups); + aFamily3->setGroupsNames(newGroups, /*giveOwnership = */true); + + // identifier + aFamily3->setIdentifier(77); + + // check new parameters of aFamily3 + + // attributes + CPPUNIT_ASSERT_EQUAL(newNumberOfAttribute, aFamily3->getNumberOfAttributes()); + const int * newAttributeIdentifierBack = aFamily3->getAttributesIdentifiers(); + const int * newAttributeValueBack = aFamily3->getAttributesValues(); + const string * newAttributeDescriptionBack = aFamily3->getAttributesDescriptions(); + for (int i = 1; i <= newNumberOfAttribute; i++) { + sprintf(tmp, "Attribut N° %d", i); + string descr (tmp); + + CPPUNIT_ASSERT_EQUAL(i , aFamily3->getAttributeIdentifier(i)); + CPPUNIT_ASSERT_EQUAL(i*10 , aFamily3->getAttributeValue(i)); + CPPUNIT_ASSERT_EQUAL(descr, aFamily3->getAttributeDescription(i)); + + CPPUNIT_ASSERT_EQUAL(i , newAttributeIdentifierBack[i - 1]); + CPPUNIT_ASSERT_EQUAL(i*10 , newAttributeValueBack[i - 1]); + CPPUNIT_ASSERT_EQUAL(descr, newAttributeDescriptionBack[i - 1]); + } + + // next string is commented since this pointer is shared + // by Family3 and in future during deleting of Family3 + // we recieve error + //delete [] newAttributeIdentifier; + //delete [] newAttributeValue; + delete [] newAttributeDescription; + + // groups + CPPUNIT_ASSERT_EQUAL(newNumberOfGroups, aFamily3->getNumberOfGroups()); + const string * newGroupsBack = aFamily3->getGroupsNames(); + for (int i = 1; i <= newNumberOfGroups; i++) { + sprintf(tmp, "Group N° %d", i); + string grp (tmp); + + CPPUNIT_ASSERT_EQUAL(grp, aFamily3->getGroupName(i)); + CPPUNIT_ASSERT_EQUAL(grp, newGroupsBack[i - 1]); + } + + // identifier + CPPUNIT_ASSERT_EQUAL(77, aFamily3->getIdentifier()); + } + + ///////////////////////////////////////////////////// + // TEST 3: check default constructor and operator= // + ///////////////////////////////////////////////////// + { + FAMILY aFamily4; + //#ifdef ENABLE_FAULTS + aFamily4 = (const FAMILY &)*aFamily3; + //#endif + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) Wrong implementation or usage of PointerOf<string>. + // Do not use memcpy() with array of std::string! + //TODO:: +// CPPUNIT_FAIL("Impossible to use FAMILY::operator= because of" +// " wrong implementation or usage of PointerOf<string>"); + /*{ + int nb = 3; + string * str = new string[nb]; + + char tmp_str [32]; + for (int i = 0; i < nb; i++) { + sprintf(tmp_str, "My String N° %d", i+1); + str[i] = tmp; + } + + // bad + string* _pointer; + _pointer = new string[3]; + // This is wrong, because class string is not simple type + // and can have pointers to some data, deallocated in it's destructor, + // which (data) will not be copied by this operation. + memcpy(_pointer, str, 3*sizeof(string)); + delete [] _pointer; + + // good + //PointerOf<int> p1 (1); + //PointerOf<int> p2 (20); + //p2 = newAttributeValue; + //p1.set(3, p2); + + // bad + //PointerOf<string> p1 (1); + //PointerOf<string> p2 (20); + //p2 = str; + //p1.set(3, p2); + + delete [] str; + } + */ + //#endif + } + + /////////////////////////////////////////////////// + // TEST 4: check construction from given support // + /////////////////////////////////////////////////// + { + SUPPORT s1 (*aFamily3); + FAMILY f1 (s1); + CPPUNIT_ASSERT_EQUAL(0, f1.getIdentifier()); + CPPUNIT_ASSERT_EQUAL(0, f1.getNumberOfAttributes()); + CPPUNIT_ASSERT_EQUAL(0, f1.getNumberOfGroups()); + CPPUNIT_ASSERT(s1.deepCompare(f1)); + } + + delete aFamily3; + delete aMesh; + + ///////////////////////////////////////////////////////////////// + // TEST 5: check constructor, designed to use with med driver. // + ///////////////////////////////////////////////////////////////// + { + MESH * aTestMesh = MEDMEMTest_createTestMesh(); + + // TestMesh families. Let's imagine that we would like to have + // the following nodes and elements distribution by families: + + // NumberOfNodes = 19; + int aNodeFamily[19] = {1, 1, 1, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 3, 3, 3}; + + // NumberOfCellTypes = 3; + // NumberOfCells[NumberOfCellTypes] = {12, 2, 2}; + int aCellType1Family[12] = {4,4,4,4,4,5,5,5,5,5,5,5}; + int aCellType2Family[ 2] = {5,6}; + int aCellType3Family[ 2] = {6,6}; + int * aCellFamily[3] = {aCellType1Family, aCellType2Family, aCellType3Family}; + + // NumberOfFaceTypes = 2; + // NumberOfFaces[NumberOfFaceTypes] = {4, 4}; + int aFaceType1Family[4] = {7,7,7,7}; + int aFaceType2Family[4] = {7,7,7,7}; + int * aFaceFamily[3] = {aFaceType1Family, aFaceType2Family}; + + // No edges in aTestMesh + int ** anEdgeFamily = NULL; + + // new families data + int attrId[2] = {1,2}; + int attrVa[2] = {7,8}; + + string attrDescr1 ("Attribute 1 description"); + string attrDescr2 ("Attribute 2 description"); + string attrDescrEmpty (MED_TAILLE_DESC - 23, ' '); + attrDescr1 += attrDescrEmpty; + attrDescr2 += attrDescrEmpty; + CPPUNIT_ASSERT(MED_TAILLE_DESC == attrDescr1.length()); + CPPUNIT_ASSERT(MED_TAILLE_DESC == attrDescr2.length()); + string attrDescr = attrDescr1 + attrDescr2; + + string groupName1 ("Group_1"); + string groupName2 ("Group_2"); + string groupName3 ("Group_3"); + string groupNameEmpty (MED_TAILLE_LNOM - 7, ' '); + groupName1 += groupNameEmpty; + groupName2 += groupNameEmpty; + groupName3 += groupNameEmpty; + CPPUNIT_ASSERT(MED_TAILLE_LNOM == groupName1.length()); + CPPUNIT_ASSERT(MED_TAILLE_LNOM == groupName2.length()); + CPPUNIT_ASSERT(MED_TAILLE_LNOM == groupName3.length()); + string groupNames = groupName1 + groupName2 + groupName3; + + // nodes family 1 + FAMILY aNodesF1 (aTestMesh, /*Identifier*/1, "Nodes 1", + /*NumberOfAttribute*/2, attrId, attrVa, attrDescr, + /*NumberOfGroup*/3, groupNames, + aNodeFamily, aCellFamily, aFaceFamily, anEdgeFamily); + + //cout << "Show aNodesF1 :" << endl; + //cout << aNodesF1 << endl; + + CPPUNIT_ASSERT_EQUAL(1, aNodesF1.getIdentifier()); + CPPUNIT_ASSERT(strcmp("Nodes 1", aNodesF1.getName().c_str()) == 0); + CPPUNIT_ASSERT(MED_EN::MED_NODE == aNodesF1.getEntity()); + CPPUNIT_ASSERT(!aNodesF1.isOnAllElements()); + CPPUNIT_ASSERT_EQUAL(7, aNodesF1.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + + CPPUNIT_ASSERT_EQUAL(2, aNodesF1.getNumberOfAttributes()); + CPPUNIT_ASSERT_EQUAL(1, aNodesF1.getAttributeIdentifier(1)); + CPPUNIT_ASSERT_EQUAL(2, aNodesF1.getAttributeIdentifier(2)); + CPPUNIT_ASSERT_EQUAL(7, aNodesF1.getAttributeValue(1)); + CPPUNIT_ASSERT_EQUAL(8, aNodesF1.getAttributeValue(2)); + CPPUNIT_ASSERT_EQUAL(attrDescr1, aNodesF1.getAttributeDescription(1)); + CPPUNIT_ASSERT_EQUAL(attrDescr2, aNodesF1.getAttributeDescription(2)); + + CPPUNIT_ASSERT_EQUAL(3, aNodesF1.getNumberOfGroups()); + CPPUNIT_ASSERT_EQUAL(groupName1, aNodesF1.getGroupName(1)); + CPPUNIT_ASSERT_EQUAL(groupName2, aNodesF1.getGroupName(2)); + CPPUNIT_ASSERT_EQUAL(groupName3, aNodesF1.getGroupName(3)); + + // faces family 7 + FAMILY aFacesF7 (aTestMesh, /*Identifier*/7, "Faces All", + /*NumberOfAttribute*/2, attrId, attrVa, attrDescr, + /*NumberOfGroup*/3, groupNames, + aNodeFamily, aCellFamily, aFaceFamily, anEdgeFamily); + + cout << "Show aFacesF7 :" << endl; + cout << aFacesF7 << endl; + + CPPUNIT_ASSERT_EQUAL(7, aFacesF7.getIdentifier()); + CPPUNIT_ASSERT(strcmp("Faces All", aFacesF7.getName().c_str()) == 0); + CPPUNIT_ASSERT(MED_EN::MED_FACE == aFacesF7.getEntity()); + + CPPUNIT_ASSERT_EQUAL(8, aTestMesh->getNumberOfElementsWithPoly(MED_EN::MED_FACE, + MED_EN::MED_ALL_ELEMENTS)); + CPPUNIT_ASSERT_EQUAL(8, aFacesF7.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + +//#ifdef ENABLE_FORCED_FAILURES + // ? (BUG) ? Why _isOnAllElts is set to true only for nodes and cells. What about faces? + // _isOnAllElts = true ; + // See MEDMEM_Family.cxx lines 118-119 and 386-387. + CPPUNIT_ASSERT(aFacesF7.isOnAllElements()); +//#endif + + CPPUNIT_ASSERT_EQUAL(2, aFacesF7.getNumberOfAttributes()); + CPPUNIT_ASSERT_EQUAL(1, aFacesF7.getAttributeIdentifier(1)); + CPPUNIT_ASSERT_EQUAL(2, aFacesF7.getAttributeIdentifier(2)); + CPPUNIT_ASSERT_EQUAL(7, aFacesF7.getAttributeValue(1)); + CPPUNIT_ASSERT_EQUAL(8, aFacesF7.getAttributeValue(2)); + CPPUNIT_ASSERT_EQUAL(attrDescr1, aFacesF7.getAttributeDescription(1)); + CPPUNIT_ASSERT_EQUAL(attrDescr2, aFacesF7.getAttributeDescription(2)); + + CPPUNIT_ASSERT_EQUAL(3, aFacesF7.getNumberOfGroups()); + CPPUNIT_ASSERT_EQUAL(groupName1, aFacesF7.getGroupName(1)); + CPPUNIT_ASSERT_EQUAL(groupName2, aFacesF7.getGroupName(2)); + CPPUNIT_ASSERT_EQUAL(groupName3, aFacesF7.getGroupName(3)); + + delete aTestMesh; + + // Method build() is not tested directly, but it is called from constructor, tested here + } +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_Family_fault.cxx b/src/MEDMEMCppTest/MEDMEMTest_Family_fault.cxx new file mode 100644 index 000000000..e2e672713 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Family_fault.cxx @@ -0,0 +1,90 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEM_define.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_Mesh.hxx" + +using namespace std; +using namespace MEDMEM; + +int main (int argc, char** argv) +{ + string datadir = getenv("MED_ROOT_DIR"); + string filename = datadir + "/share/salome/resources/med/pointe.med"; + string meshname = "maa1"; + + MESH * aMesh = new MESH(); + aMesh->setName(meshname); + MED_MESH_RDONLY_DRIVER aMeshDriver (filename, aMesh); + aMeshDriver.setMeshName(meshname); + aMeshDriver.open(); + aMeshDriver.read(); + aMeshDriver.close(); + + const FAMILY * aFamily1 = aMesh->getFamily(MED_EN::MED_NODE, 1); + + // check default constructor and operator= + FAMILY aFamily4; + + // (BUG) Wrong implementation or usage of PointerOf<string>. + // Do not use memcpy() with array of std::string! + // Impossible to use FAMILY::operator=! + aFamily4 = *aFamily1; + + /*{ + int nb = 3; + string * str = new string[nb]; + + char tmp_str [32]; + for (int i = 0; i < nb; i++) { + sprintf(tmp_str, "My String N° %d", i+1); + str[i] = tmp; + } + + // bad + string* _pointer; + _pointer = new string[3]; + // This is wrong, because class string is not simple type + // and can have pointers to some data, deallocated in it's destructor, + // which (data) will not be copied by this operation. + memcpy(_pointer, str, 3*sizeof(string)); + delete [] _pointer; + + // good + //PointerOf<int> p1 (1); + //PointerOf<int> p2 (20); + //p2 = newAttributeValue; + //p1.set(3, p2); + + // bad + //PointerOf<string> p1 (1); + //PointerOf<string> p2 (20); + //p2 = str; + //p1.set(3, p2); + + delete [] str; + } + */ + + delete aMesh; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_Field.cxx b/src/MEDMEMCppTest/MEDMEMTest_Field.cxx new file mode 100644 index 000000000..2a483eeae --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Field.cxx @@ -0,0 +1,1749 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "MEDMEM_FieldConvert.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Group.hxx" +#include "MEDMEM_Support.hxx" +#include <MEDMEM_VtkMeshDriver.hxx> +#include <MEDMEM_MedMeshDriver22.hxx> + + +#include <sstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; + +// #14,15: MEDMEMTest_Field.cxx +// Check methods from MEDMEM_Field.hxx, MEDMEM_FieldConvert.hxx + +/*! + * Check methods (48), defined in MEDMEM_Field.hxx: + * class FIELD_ { + * (+) FIELD_(); + * (+) FIELD_(const SUPPORT * Support, const int NumberOfComponents); + * (+) FIELD_(const FIELD_ &m); + * (+) virtual ~FIELD_(); + * (+) FIELD_& operator=(const FIELD_ &m); + * + * (-) virtual void rmDriver(int index=0); + * (-) virtual int addDriver(driverTypes driverType, + * const string & fileName="Default File Name.med", + * const string & driverFieldName="Default Field Nam", + * MED_EN::med_mode_acces access=MED_EN::MED_REMP); + * (-) virtual int addDriver(GENDRIVER & driver); + * + * (-) virtual void read (const GENDRIVER &); + * (-) virtual void read(int index=0); + * (-) virtual void openAppend(void); + * (-) virtual void write(const GENDRIVER &); + * (-) virtual void write(int index=0, const string & driverName=""); + * (-) virtual void writeAppend(const GENDRIVER &); + * (-) virtual void writeAppend(int index=0, const string & driverName=""); + * + * (+) inline void setName(const string Name); + * (+) inline string getName() const; + * (+) inline void setDescription(const string Description); + * (+) inline string getDescription() const; + * (+) inline const SUPPORT * getSupport() const; + * (+) inline void setSupport(const SUPPORT * support); + * (+) inline void setNumberOfComponents(const int NumberOfComponents); + * (+) inline int getNumberOfComponents() const; + * (+) inline void setNumberOfValues(const int NumberOfValues); + * (+) inline int getNumberOfValues() const; + * (+) inline void setComponentsNames(const string * ComponentsNames); + * (+) inline void setComponentName(int i, const string ComponentName); + * (+) inline const string * getComponentsNames() const; + * (+) inline string getComponentName(int i) const; + * (+) inline void setComponentsDescriptions(const string * ComponentsDescriptions); + * (+) inline void setComponentDescription(int i, const string ComponentDescription); + * (+) inline const string * getComponentsDescriptions() const; + * (+) inline string getComponentDescription(int i) const; + * (+) inline void setComponentsUnits(const UNIT * ComponentsUnits); + * (+) inline const UNIT * getComponentsUnits() const; + * (+) inline const UNIT * getComponentUnit(int i) const; + * (+) inline void setMEDComponentsUnits(const string * MEDComponentsUnits); + * (+) inline void setMEDComponentUnit(int i, const string MEDComponentUnit); + * (+) inline const string * getMEDComponentsUnits() const; + * (+) inline string getMEDComponentUnit(int i) const; + * + * (+) inline void setIterationNumber(int IterationNumber); + * (+) inline int getIterationNumber() const; + * (+) inline void setTime(double Time); + * (+) inline double getTime() const; + * (+) inline void setOrderNumber(int OrderNumber); + * (+) inline int getOrderNumber() const; + * + * (+) inline MED_EN::med_type_champ getValueType () const; + * (+) inline MED_EN::medModeSwitch getInterlacingType() const; + * (-) virtual inline bool getGaussPresence() const throw (MEDEXCEPTION); + * } + * + * template <class T, class INTERLACING_TAG> class FIELD : public FIELD_ { + * (+) FIELD(); + * (+) FIELD(const FIELD &m); + * (+) FIELD(const SUPPORT * Support, const int NumberOfComponents) throw (MEDEXCEPTION); + * (+) FIELD(driverTypes driverType, + * const string & fileName, const string & fieldDriverName, + * const int iterationNumber=-1, const int orderNumber=-1) throw (MEDEXCEPTION); + * (+) FIELD(const SUPPORT * Support, driverTypes driverType, + * const string & fileName="", const string & fieldName="", + * const int iterationNumber = -1, const int orderNumber = -1) throw (MEDEXCEPTION); + * (+) ~FIELD(); + * (+) FIELD & operator=(const FIELD &m); + * + * (+) const FIELD operator+(const FIELD& m) const; + * (+) const FIELD operator-(const FIELD& m) const; + * (+) const FIELD operator*(const FIELD& m) const; + * (+) const FIELD operator/(const FIELD& m) const; + * (+) const FIELD operator-() const; + * (+) FIELD& operator+=(const FIELD& m); + * (+) FIELD& operator-=(const FIELD& m); + * (+) FIELD& operator*=(const FIELD& m); + * (+) FIELD& operator/=(const FIELD& m); + * + * (+) static FIELD* add(const FIELD& m, const FIELD& n); + * (+) static FIELD* addDeep(const FIELD& m, const FIELD& n); + * (+) static FIELD* sub(const FIELD& m, const FIELD& n); + * (+) static FIELD* subDeep(const FIELD& m, const FIELD& n); + * (+) static FIELD* mul(const FIELD& m, const FIELD& n); + * (+) static FIELD* mulDeep(const FIELD& m, const FIELD& n); + * (+) static FIELD* div(const FIELD& m, const FIELD& n); + * (+) static FIELD* divDeep(const FIELD& m, const FIELD& n); + * + * (+) double normMax() const throw (MEDEXCEPTION); + * (+) double norm2() const throw (MEDEXCEPTION); + * + * (+) void applyLin(T a, T b); + * (+) template <T T_function(T)> void applyFunc(); + * (+) void applyPow(T scalar); + * + * (+) static FIELD* scalarProduct(const FIELD& m, const FIELD& n, bool deepCheck=false); + * + * (+) double normL2(int component, const FIELD<double,FullInterlace> * p_field_volume=NULL) const; + * (+) double normL2(const FIELD<double,FullInterlace> * p_field_volume=NULL) const; + * (+) double normL1(int component, const FIELD<double,FullInterlace> * p_field_volume=NULL) const; + * (+) double normL1(const FIELD<double,FullInterlace> * p_field_volume=NULL) const; + * + * (+) FIELD* extract(const SUPPORT *subSupport) const throw (MEDEXCEPTION); + * + * (EMPTY COMMENT, EMPTY IMPLEMENTATION!!!) void init (); + * + * (+) void rmDriver(int index=0); + * (+) int addDriver(driverTypes driverType, + * const string & fileName="Default File Name.med", + * const string & driverFieldName="Default Field Name", + * MED_EN::med_mode_acces access=MED_EN::MED_REMP); + * (+) int addDriver(GENDRIVER & driver); + * + * (+) void allocValue(const int NumberOfComponents); + * (+) void allocValue(const int NumberOfComponents, const int LengthValue); + * (+) void deallocValue(); + * + * (+) inline void read(int index=0); + * (+) inline void read(const GENDRIVER & genDriver); + * (+) inline void write(int index=0, const string & driverName = ""); + * (+) inline void write(const GENDRIVER &); + * (+) inline void writeAppend(int index=0, const string & driverName = ""); + * (+) inline void writeAppend(const GENDRIVER &); + * + * (+) inline MEDMEM_Array_ * getArray() const throw (MEDEXCEPTION); + * (+) inline ArrayGauss * getArrayGauss() const throw (MEDEXCEPTION); + * (+) inline ArrayNoGauss * getArrayNoGauss() const throw (MEDEXCEPTION); + * (+) inline bool getGaussPresence() const throw (MEDEXCEPTION); + * + * (+) inline int getValueLength() const throw (MEDEXCEPTION); + * (+) inline const T* getValue() const throw (MEDEXCEPTION); + * (+) inline const T* getRow(int i) const throw (MEDEXCEPTION); + * (+) inline const T* getColumn(int j) const throw (MEDEXCEPTION); + * (+) inline T getValueIJ(int i,int j) const throw (MEDEXCEPTION); + * (+) inline T getValueIJK(int i,int j,int k) const throw (MEDEXCEPTION); + * (+) bool getValueOnElement(int eltIdInSup,T* retValues) const throw (MEDEXCEPTION); + * + * (+) const int getNumberOfGeometricTypes() const throw (MEDEXCEPTION); + * + * (+) const GAUSS_LOCALIZATION<INTERLACING_TAG> & getGaussLocalization + * (MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION); + * (+) const GAUSS_LOCALIZATION<INTERLACING_TAG> * getGaussLocalizationPtr + * (MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION); + * (+) void setGaussLocalization(MED_EN::medGeometryElement geomElement, + * const GAUSS_LOCALIZATION<INTERLACING_TAG> & gaussloc); + * (+) const int * getNumberOfGaussPoints() const throw (MEDEXCEPTION); + * (+) const int getNumberOfGaussPoints + * (MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION); + * (+) const int getNbGaussI(int i) const throw (MEDEXCEPTION); + * + * (+) const int * getNumberOfElements() const throw (MEDEXCEPTION); + * (+) const MED_EN::medGeometryElement * getGeometricTypes() const throw (MEDEXCEPTION); + * (+) bool isOnAllElements() const throw (MEDEXCEPTION); + * + * (+) inline void setArray(MEDMEM_Array_ *value) throw (MEDEXCEPTION); + * (+) inline void setValue(T* value) throw (MEDEXCEPTION); + * (+) inline void setRow(int i, T* value) throw (MEDEXCEPTION); + * (+) inline void setColumn(int i, T* value) throw (MEDEXCEPTION); + * (+) inline void setValueIJ(int i, int j, T value) throw (MEDEXCEPTION); + * + * (NOT IMPLEMENTED!!!) void getVolume() const throw (MEDEXCEPTION); + * (NOT IMPLEMENTED!!!) void getArea() const throw (MEDEXCEPTION); + * (NOT IMPLEMENTED!!!) void getLength() const throw (MEDEXCEPTION); + * (NOT IMPLEMENTED!!!) void getNormal() const throw (MEDEXCEPTION); + * (NOT IMPLEMENTED!!!) void getBarycenter() const throw (MEDEXCEPTION); + * + * (+) void fillFromAnalytic(myFuncType f) throw (MEDEXCEPTION); + * } + * + * Use code of test_operation_fieldint.cxx + * test_operation_fielddouble.cxx + * test_copie_field_.cxx + * test_copie_fieldT.cxx + */ +void compareField_(const FIELD_ * theField_1, const FIELD_ * theField_2, bool isFIELD, bool isValue) +{ + // name, description, support + CPPUNIT_ASSERT_EQUAL(theField_1->getName(), theField_2->getName()); + CPPUNIT_ASSERT_EQUAL(theField_1->getDescription(), theField_2->getDescription()); + CPPUNIT_ASSERT_EQUAL(theField_1->getSupport(), theField_2->getSupport()); + + // components information + int aNbComps = theField_1->getNumberOfComponents(); + CPPUNIT_ASSERT_EQUAL(aNbComps, theField_2->getNumberOfComponents()); + + for (int i = 1; i <= aNbComps; i++) { + CPPUNIT_ASSERT_EQUAL(theField_1->getComponentName(i), theField_2->getComponentName(i)); + CPPUNIT_ASSERT_EQUAL(theField_1->getComponentDescription(i), theField_2->getComponentDescription(i)); + CPPUNIT_ASSERT_EQUAL(theField_1->getMEDComponentUnit(i), theField_2->getMEDComponentUnit(i)); + } + + // iteration information + CPPUNIT_ASSERT_EQUAL(theField_1->getIterationNumber(), theField_2->getIterationNumber()); + CPPUNIT_ASSERT_EQUAL(theField_1->getOrderNumber(), theField_2->getOrderNumber()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(theField_1->getTime(), theField_2->getTime(), 0.0000001); + + // Value + int nbOfValues = theField_1->getNumberOfValues(); + CPPUNIT_ASSERT_EQUAL(nbOfValues, theField_2->getNumberOfValues()); + + if (isFIELD) { + // Value type and Interlacing type + CPPUNIT_ASSERT_EQUAL(theField_1->getValueType(), theField_2->getValueType()); + CPPUNIT_ASSERT_EQUAL(theField_1->getInterlacingType(), theField_2->getInterlacingType()); + + // Gauss Presence + if (isValue) { + CPPUNIT_ASSERT_EQUAL(theField_1->getGaussPresence(), theField_2->getGaussPresence()); + } + else { + CPPUNIT_ASSERT_THROW(theField_1->getGaussPresence(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theField_2->getGaussPresence(), MEDEXCEPTION); + } + } + else { + CPPUNIT_ASSERT_THROW(theField_1->getGaussPresence(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theField_2->getGaussPresence(), MEDEXCEPTION); + } +} + +void checkField_(FIELD_ * theField_, const SUPPORT * theSupport, + MED_EN::med_type_champ theValueType, + MED_EN::medModeSwitch theInterlace) +{ + // name + const string aFieldName = "a_name_of_a_field"; + theField_->setName(aFieldName); + CPPUNIT_ASSERT_EQUAL(aFieldName, theField_->getName()); + + // description + const string aFieldDescr = "a_description_of_a_field"; + theField_->setDescription(aFieldDescr); + CPPUNIT_ASSERT_EQUAL(aFieldDescr, theField_->getDescription()); + + // support + theField_->setSupport(theSupport); + CPPUNIT_ASSERT(theField_->getSupport() == theSupport); + + // components information + int aNbComps = 3; + + string aCompsNames[3] = {"Vx", "Vy", "Vz"}; + string aCompsDescs[3] = {"vitesse selon x", "vitesse selon y", "vitesse selon z"}; + string aCompsUnits[3] = {"m.s-1", "m.s-1", "m.s-1"}; + + theField_->setNumberOfComponents(aNbComps); + CPPUNIT_ASSERT_EQUAL(aNbComps, theField_->getNumberOfComponents()); + + theField_->setComponentsNames(aCompsNames); + + //#ifdef ENABLE_FAULTS + try { + theField_->setNumberOfComponents(7); + // Segmentation fault here because array of components names is not resized + for (int i = 1; i <= 7; i++) { + theField_->setComponentName(i, "AnyComponent"); + } + } + catch (MEDEXCEPTION& ex) { + // Ok, it is good to have MEDEXCEPTION here + } + catch (...) { + CPPUNIT_FAIL("Unknown exception cought"); + } + // restore components names + theField_->setNumberOfComponents(aNbComps); + theField_->setComponentsNames(aCompsNames); + //#endif + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_FAIL("FIELD_::_componentsNames bad management"); + //#endif + + theField_->setComponentsDescriptions(aCompsDescs); + theField_->setMEDComponentsUnits(aCompsUnits); + + const string * aCompsNamesBack = theField_->getComponentsNames(); + const string * aCompsDescsBack = theField_->getComponentsDescriptions(); + const string * aCompsUnitsBack = theField_->getMEDComponentsUnits(); + for (int i = 1; i <= aNbComps; i++) { + CPPUNIT_ASSERT_EQUAL(aCompsNamesBack[i-1], theField_->getComponentName(i)); + CPPUNIT_ASSERT_EQUAL(aCompsNamesBack[i-1], aCompsNames[i-1]); + + CPPUNIT_ASSERT_EQUAL(aCompsDescsBack[i-1], theField_->getComponentDescription(i)); + CPPUNIT_ASSERT_EQUAL(aCompsDescsBack[i-1], aCompsDescs[i-1]); + + CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack[i-1], theField_->getMEDComponentUnit(i)); + CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack[i-1], aCompsUnits[i-1]); + } + + const string aCompName2 ("Name of second component"); + const string aCompDesc2 ("Description of second component"); + const string aCompUnit2 ("Unit of second MED component"); + + theField_->setComponentName(2, aCompName2); + theField_->setComponentDescription(2, aCompDesc2); + theField_->setMEDComponentUnit(2, aCompUnit2); + + const string * aCompsNamesBack2 = theField_->getComponentsNames(); + const string * aCompsDescsBack2 = theField_->getComponentsDescriptions(); + const string * aCompsUnitsBack2 = theField_->getMEDComponentsUnits(); + + CPPUNIT_ASSERT_EQUAL(aCompsNamesBack2[1], theField_->getComponentName(2)); + CPPUNIT_ASSERT_EQUAL(aCompsNamesBack2[1], aCompName2); + + CPPUNIT_ASSERT_EQUAL(aCompsDescsBack2[1], theField_->getComponentDescription(2)); + CPPUNIT_ASSERT_EQUAL(aCompsDescsBack2[1], aCompDesc2); + + CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack2[1], theField_->getMEDComponentUnit(2)); + CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack2[1], aCompUnit2); + + //#ifdef ENABLE_FAULTS + // (BUG) No index checking + // It's normal: performance reason + CPPUNIT_ASSERT_THROW(theField_->setComponentName(0, "str"), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theField_->setComponentName(aNbComps + 1, "str"), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theField_->setComponentDescription(0, "str"), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theField_->setComponentDescription(aNbComps + 1, "str"), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theField_->setMEDComponentUnit(0, "str"), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theField_->setMEDComponentUnit(aNbComps + 1, "str"), MEDEXCEPTION); + //#endif + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_FAIL("FIELD::setComponentXXX() does not check component index"); + //#endif + + // iteration information + int anIterNumber = 10; // set value to MED_NOPDT if undefined (default) + theField_->setIterationNumber(anIterNumber); + CPPUNIT_ASSERT_EQUAL(anIterNumber, theField_->getIterationNumber()); + + int anOrderNumber = 1; // set value to MED_NONOR if undefined (default) + theField_->setOrderNumber(anOrderNumber); + CPPUNIT_ASSERT_EQUAL(anOrderNumber, theField_->getOrderNumber()); + + double aTime = 3.435678; // in second + theField_->setTime(aTime); + CPPUNIT_ASSERT_DOUBLES_EQUAL(aTime, theField_->getTime(), 0.0000001); + + // Value + int nbOfValues = 10; + // dangerous method, because it does not reallocate values array + theField_->setNumberOfValues(nbOfValues); + CPPUNIT_ASSERT_EQUAL(nbOfValues, theField_->getNumberOfValues()); + + // Value type and Interlacing type + CPPUNIT_ASSERT_EQUAL(theValueType, theField_->getValueType()); + CPPUNIT_ASSERT_EQUAL(theInterlace, theField_->getInterlacingType()); +} + +template<class T, class INTERLACING_TAG> +void compareField(const FIELD<T, INTERLACING_TAG> * theField_1, + const FIELD<T, INTERLACING_TAG> * theField_2, bool isValue) +{ + // compare FIELD_ part + compareField_(theField_1, theField_2, /*isFIELD = */true, isValue); + + // compare FIELD part + // TO DO +} + +template<class T, class INTERLACING_TAG> +void checkField (FIELD<T, INTERLACING_TAG> * theField, const SUPPORT * theSupport) +{ + // check FIELD_ part + MED_EN::med_type_champ aValueType = SET_VALUE_TYPE<T>::_valueType; + MED_EN::medModeSwitch anInterlace = SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType; + checkField_(theField, theSupport, aValueType, anInterlace); + + // check FIELD part + + // filling by support charackteristics (NOT IMPLEMENTED METHODS!!!): + // value type must be MED_REEL64 (i.e. a FIELD<double>) for these methods, + // nb. of components must be equal 1 (for Volume, Area, Length) or + // space dimension (for Normal, Barycenter, ) + { + MESH* aMesh = theSupport->getMesh(); + int spaceDim = 3; + if (aMesh) spaceDim = aMesh->getSpaceDimension(); + theField->deallocValue(); + theField->allocValue(/*NumberOfComponents = */spaceDim + 1); + + // 0020142: [CEA 315] Unused function in MEDMEM::FIELD + // getVolume() etc. does nothing + // +// CPPUNIT_ASSERT_THROW(theField->getVolume(), MEDEXCEPTION); +// CPPUNIT_ASSERT_THROW(theField->getArea(), MEDEXCEPTION); +// CPPUNIT_ASSERT_THROW(theField->getLength(), MEDEXCEPTION); +// if (aMesh) { +// CPPUNIT_ASSERT_THROW(theField->getNormal(), MEDEXCEPTION); +// CPPUNIT_ASSERT_THROW(theField->getBarycenter(), MEDEXCEPTION); +// } + + theField->deallocValue(); + theField->allocValue(/*NumberOfComponents = */1); + // 0020142: [CEA 315] Unused function in MEDMEM::FIELD + // getVolume() etc. does nothing +// if (aValueType == MED_EN::MED_REEL64) { +// CPPUNIT_ASSERT_NO_THROW(theField->getVolume()); +// CPPUNIT_ASSERT_NO_THROW(theField->getArea()); +// CPPUNIT_ASSERT_NO_THROW(theField->getLength()); +// } +// else { +// CPPUNIT_ASSERT_THROW(theField->getVolume(), MEDEXCEPTION); +// CPPUNIT_ASSERT_THROW(theField->getArea(), MEDEXCEPTION); +// CPPUNIT_ASSERT_THROW(theField->getLength(), MEDEXCEPTION); +// } + + if (aMesh) { + theField->deallocValue(); + theField->allocValue(/*NumberOfComponents = */spaceDim); + // 0020142: [CEA 315] Unused function in MEDMEM::FIELD + // getVolume() etc. does nothing +// if (aValueType == MED_EN::MED_REEL64) { +// CPPUNIT_ASSERT_NO_THROW(theField->getNormal()); +// CPPUNIT_ASSERT_NO_THROW(theField->getBarycenter()); +// } +// else { +// CPPUNIT_ASSERT_THROW(theField->getNormal(), MEDEXCEPTION); +// CPPUNIT_ASSERT_THROW(theField->getBarycenter(), MEDEXCEPTION); +// } + } + } + + // values + theField->deallocValue(); + theField->allocValue(/*NumberOfComponents = */2); + int nbElemSupport = theSupport->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS); + CPPUNIT_ASSERT_EQUAL(nbElemSupport, theField->getNumberOfValues()); + + //#ifdef ENABLE_FAULTS + // (BUG) FIELD::deallocValue() does not nullify _value pointer, + // that is why there can be failures in other methods + // (even if simply call deallocValue() two times) + theField->deallocValue(); + CPPUNIT_ASSERT_THROW(theField->getGaussPresence(), MEDEXCEPTION); + //#endif + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_FAIL("FIELD::deallocValue() does not nullify _value pointer"); + //#endif + + // copy constructor + FIELD<T, INTERLACING_TAG> aField_copy1 (*theField); + compareField(theField, &aField_copy1, /*isValue = */false); + //compareField(theField, &aField_copy1, /*isValue = */true); + + // operator= + //#ifdef ENABLE_FAULTS + // (BUG) This fails (Segmentation fault) if not set: + // _componentsNames or _componentsDescriptions, or _componentsUnits, or _MEDComponentsUnits + FIELD<T, INTERLACING_TAG> aField_copy2; + aField_copy2 = *theField; + compareField(theField, &aField_copy2, /*isValue = */false); + //compareField(theField, &aField_copy2, /*isValue = */true); + //#endif + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_FAIL("FIELD_::operator=() fails if _componentsUnits is not set"); + //#endif +} + +template<class T> +FIELD<T> * createFieldOnGroup(MESH* theMesh, const GROUP* theGroup, + const string theName, const string theDescr) +{ + FIELD<T> * aFieldOnGroup = new FIELD<T> (theGroup, /*NumberOfComponents = */2); + + aFieldOnGroup->setName(theName); + aFieldOnGroup->setDescription(theDescr); + + string aCompsNames[2] = {"Pos", "Neg"}; + string aCompsDescs[2] = {"+", "-"}; + string aCompsUnits[2] = {"unit1", "unit2"}; + + aFieldOnGroup->setComponentsNames(aCompsNames); + aFieldOnGroup->setComponentsDescriptions(aCompsDescs); + aFieldOnGroup->setMEDComponentsUnits(aCompsUnits); + + return aFieldOnGroup; +} + +double plus13 (double val) +{ + return val + 13; +} + +// function to calculate field values from coordinates of an element +// typedef void (*myFuncType)(const double * temp, T* output); +// size of temp array = space dim = 3 +// size of output array = nb. comps = 2 +void proj2d (const double * temp, double* output) +{ + // dimetric projection with coefficients: + // 1.0 along Oy and Oz, 0.5 along Ox + // + // ^ z (y_) + // | + // | + // .----> y (x_) + // / + // L x + // + // x_ = y - x * sqrt(2.) / 4. + // y_ = z - x * sqrt(2.) / 4. + + double dx = temp[0] * std::sqrt(2.) / 4.; + output[0] = temp[1] - dx; + output[1] = temp[2] - dx; +} + +void testDrivers() +{ + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if (tmp_dir == "") + tmp_dir = "/tmp"; + + string filename_rd = data_dir + "/share/salome/resources/med/pointe.med"; + string filename_wr = tmp_dir + "/myMedFieldfile.med"; + string filename_support_wr = tmp_dir + "/myMedSupportFiledfile.med"; + string filename22_rd = data_dir + "/share/salome/resources/med/pointe_import22.med"; + string filenamevtk_wr = tmp_dir + "/myMedFieldfile22.vtk"; + string cp_file = "cp " + filename_rd + " " + filename_wr; + + string fieldname_celldouble_rd = "fieldcelldoublescalar"; + string fieldname_celldouble_wr = fieldname_celldouble_rd + "_cpy"; + string fieldname_nodeint_rd = "fieldnodeint"; + string fieldname_nodeint_wr = fieldname_nodeint_rd + "_cpy"; + string fieldname_nodeint_wr1 = fieldname_nodeint_rd + "_cpy1"; + string meshname = "maa1"; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filename_wr); + aRemover.Register(filenamevtk_wr); + aRemover.Register(filename_support_wr); + + //Copy file + system(cp_file.c_str()); + + FIELD<int> aInvalidField; + //must throw becase only VTK_DRIVER or MED_DRIVER may be specified as driverType for FIELD + CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(NO_DRIVER, filename_rd, fieldname_nodeint_rd), + MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(GIBI_DRIVER, filename_rd, fieldname_nodeint_rd), + MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(PORFLOW_DRIVER, filename_rd, fieldname_nodeint_rd), + MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(ASCII_DRIVER, filename_rd, fieldname_nodeint_rd), + MEDEXCEPTION); + + ////////////////// + //TestRead Part// + ////////////////// + FIELD<double> *aField_1 = NULL; + CPPUNIT_ASSERT_NO_THROW(aField_1 = new FIELD<double>(MED_DRIVER, filename_rd, + fieldname_celldouble_rd)); + + //Test read(int index) method + int IdDriver_rd = aField_1->addDriver(MED_DRIVER,filename_rd,fieldname_celldouble_rd); + // TODO: throw if read for the second time + // (BUG) Cannot open file, but file exist + CPPUNIT_ASSERT_THROW(aField_1->read(IdDriver_rd),MEDEXCEPTION); + + //Test read(GENDRIVER & genDriver) method + //Creation a Driver + MED_FIELD_RDONLY_DRIVER21<int> *aMedRdFieldDriver21_1 = + new MED_FIELD_RDONLY_DRIVER21<int>(); + aMedRdFieldDriver21_1->setFileName(filename_rd); + //Creation a Field + FIELD<int> *aField_2 = new FIELD<int>(); + aField_2->setName(fieldname_nodeint_rd); + aField_2->addDriver(*aMedRdFieldDriver21_1); + aField_2->read(*aMedRdFieldDriver21_1); + + /////////////////// + //Test Write Part// + /////////////////// + int IdDriver; + MESH *aMesh = new MESH(MED_DRIVER,filename_rd,meshname); + SUPPORT *aSupport = new SUPPORT(aMesh, "aSupport",MED_CELL); + FIELD<int> *aFieldSupport; + //#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aFieldSupport = + new FIELD<int>(aSupport, MED_DRIVER,filename_rd, + fieldname_nodeint_rd), MEDMEM::MEDEXCEPTION); + aSupport = new SUPPORT(aMesh, "aSupport",MED_NODE); + CPPUNIT_ASSERT_NO_THROW(aFieldSupport = + new FIELD<int>(aSupport, MED_DRIVER, filename_rd, + fieldname_nodeint_rd)); + //(BUG) Can not open file + MED_FIELD_WRONLY_DRIVER21<int> * aFieldWrDriver21 = + new MED_FIELD_WRONLY_DRIVER21<int>(filename_support_wr,aFieldSupport); + aFieldWrDriver21->setFieldName(aFieldSupport->getName() + "_copy"); + CPPUNIT_ASSERT_NO_THROW(IdDriver= aFieldSupport->addDriver(*aFieldWrDriver21)); + CPPUNIT_ASSERT_NO_THROW(aFieldSupport->write(IdDriver)); + delete aFieldSupport; + delete aFieldWrDriver21; + //#endif + + //Create fileds + FIELD<double> * aField_3 = new FIELD<double>(); + MED_FIELD_RDONLY_DRIVER21<double> *aMedRdFieldDriver21_2 = + new MED_FIELD_RDONLY_DRIVER21<double>(filename_rd, aField_3); + aMedRdFieldDriver21_2->open(); + aMedRdFieldDriver21_2->setFieldName(fieldname_celldouble_rd); + aMedRdFieldDriver21_2->read(); + aMedRdFieldDriver21_2->close(); + + //Test write(int index) method + //Add drivers to FIELDs + int IdDriver1 = -1; + try + { + IdDriver1 = aField_3->addDriver(MED_DRIVER,filename_wr,fieldname_celldouble_wr); + } + catch(MEDEXCEPTION &e) + { + e.what(); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + //Trying call write(int index) method with incorrect index + //#ifdef ENABLE_FAULTS + CPPUNIT_ASSERT_THROW(aField_3->write(IdDriver1+1, fieldname_celldouble_wr),MEDEXCEPTION); + // => Segmentation fault + //#endif + + //Write field to file + //#ifdef ENABLE_FAULTS + try + { + aField_3->write(IdDriver1, fieldname_celldouble_wr); + // => Segmentation fault + } + catch(MEDEXCEPTION &e) + { + e.what(); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + //#endif + + CPPUNIT_ASSERT_NO_THROW(aField_3->rmDriver(IdDriver1)); + + //Test write(const GENDRIVER &); + //Create a driver + MED_FIELD_WRONLY_DRIVER21<int> *aMedWrFieldDriver21 = + new MED_FIELD_WRONLY_DRIVER21<int>(); + aMedWrFieldDriver21->setFileName(filename_wr); + aField_2->setName(fieldname_nodeint_wr1); + //Add driver to a field + aField_2->addDriver(*aMedWrFieldDriver21); + + try + { + aField_2->write(*aMedWrFieldDriver21); + } + catch(MEDEXCEPTION &e) + { + e.what(); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test writeAppend(int index) method + //Create a vtk file + MESH * aMesh_1 = new MESH(); + MED_MESH_RDONLY_DRIVER22 *aMedMeshRdDriver22 = new MED_MESH_RDONLY_DRIVER22(filename22_rd, aMesh_1); + aMedMeshRdDriver22->open(); + aMedMeshRdDriver22->setMeshName(meshname); + aMedMeshRdDriver22->read(); + aMedMeshRdDriver22->close(); + VTK_MESH_DRIVER *aVtkDriver = new VTK_MESH_DRIVER(filenamevtk_wr, aMesh_1); + aVtkDriver->open(); + aVtkDriver->write(); + aVtkDriver->close(); + + //Create a field + FIELD<int> * aField_4 = new FIELD<int>(); + MED_FIELD_RDONLY_DRIVER22<int> *aMedRdFieldDriver22 = + new MED_FIELD_RDONLY_DRIVER22<int>(filename22_rd, aField_4); + aMedRdFieldDriver22->open(); + aMedRdFieldDriver22->setFieldName(fieldname_nodeint_rd); + aMedRdFieldDriver22->read(); + aMedRdFieldDriver22->close(); + + //Add Driver to a field + int IdDriver2; + try + { + IdDriver2 = aField_4->addDriver(VTK_DRIVER, filenamevtk_wr ,fieldname_nodeint_wr); + } + catch(MEDEXCEPTION &e) + { + e.what(); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + //#ifdef ENABLE_FAULTS + //Trying call writeAppend() method with incorrect index + CPPUNIT_ASSERT_THROW(aField_4->writeAppend(IdDriver2+1,fieldname_nodeint_wr),MEDEXCEPTION); + // => Segmentation fault + //#endif + + //#ifdef ENABLE_FAULTS + // (BUG) => Segmentation fault + CPPUNIT_ASSERT_THROW(aField_4->writeAppend(IdDriver2, fieldname_nodeint_wr),MEDEXCEPTION); + //#endif + + //Test writeAppend(const GENDRIVER &) method + aField_4->setName(fieldname_nodeint_wr1); + + //Add driver to a field + //#ifdef ENABLE_FAULTS + //Create a driver + VTK_FIELD_DRIVER<int> *aVtkFieldDriver = new VTK_FIELD_DRIVER<int>(filenamevtk_wr, aField_4); + CPPUNIT_ASSERT_NO_THROW(aField_4->addDriver(*aVtkFieldDriver)); + //(BUG) => Segmentation fault after addDriver(const GENDRIVER &) + CPPUNIT_ASSERT_THROW(aField_4->writeAppend(*aVtkFieldDriver),MEDEXCEPTION); + //#endif + + + //Delete objects + delete aField_1; + delete aMedRdFieldDriver21_1; + delete aField_2; + delete aField_3; + delete aMedRdFieldDriver21_2; + delete aField_4; + delete aMedMeshRdDriver22; + delete aMedWrFieldDriver21; + delete aVtkDriver; + delete aMesh; + delete aMesh_1; + delete aMedRdFieldDriver22; + delete aSupport; +} + +void MEDMEMTest::testField() +{ + SUPPORT anEmptySupport; + //////////////////// + // TEST 1: FIELD_ // + //////////////////// + FIELD_ aField_; + + // check set/get methods + MED_EN::med_type_champ aValueType = MED_EN::MED_UNDEFINED_TYPE; + MED_EN::medModeSwitch anInterlace = MED_EN::MED_UNDEFINED_INTERLACE; + checkField_(&aField_, &anEmptySupport, aValueType, anInterlace); + + // copy constructor + // This fails (Segmentation fault) if not set: + // _componentsNames or _componentsDescriptions, or _MEDComponentsUnits + FIELD_ aField_copy1 (aField_); + compareField_(&aField_, &aField_copy1, /*isFIELD = */false, /*isValue = */false); + + // operator= + //#ifdef ENABLE_FAULTS + // (BUG) This fails (Segmentation fault) if not set: + // _componentsNames or _componentsDescriptions, or _componentsUnits, or _MEDComponentsUnits + // (BUG) Code duplication with copyGlobalInfo(), called from copy constructor + FIELD_ aField_copy2; + aField_copy2 = aField_; + compareField_(&aField_, &aField_copy2, /*isFIELD = */false, /*isValue = */false); + //#endif + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_FAIL("FIELD_::operator=() fails if _componentsUnits is not set"); + //#endif + + // following test is commented since method + // setTotalNumberOfElements() is removed. + /* + // construction on a given support + { + anEmptySupport.setTotalNumberOfElements(11); + // CASE1: + FIELD_ aField_case1 (&anEmptySupport, 10); + // CASE2: + // Invalid API usage +// FIELD_ aField_case2; +// aField_case2.setSupport(&anEmptySupport); +// aField_case2.setNumberOfComponents(10); + +// #ifdef ENABLE_FORCED_FAILURES +// CPPUNIT_ASSERT_EQUAL_MESSAGE("No correspondance between CASE1 and CASE2", +// aField_case1.getNumberOfValues(), +// aField_case2.getNumberOfValues()); +// #endif + } + */ + + //////////////////////// + // TEST 2: FIELD<int> // + //////////////////////// + FIELD<int> aFieldInt; + checkField(&aFieldInt, &anEmptySupport); + + //////////////////////////////////////// + // TEST 3: FIELD<double, NoInterlace> // + //////////////////////////////////////// + MESH * aMesh = MEDMEMTest_createTestMesh(); + const GROUP* aGroup = aMesh->getGroup(MED_EN::MED_FACE, 1); + + FIELD<double, NoInterlace> aFieldDouble; + checkField(&aFieldDouble, aGroup); + + ////////////////////////////////////////// + // TEST 4: FIELD<double, FullInterlace> // + ////////////////////////////////////////// + FIELD<double> * aFieldOnGroup1 = createFieldOnGroup<double>(aMesh, aGroup, "Linear", "N"); + FIELD<double> * aFieldOnGroup2 = createFieldOnGroup<double>(aMesh, aGroup, "Quadratic", "N**2"); + + int nbVals = aFieldOnGroup1->getNumberOfValues(); + CPPUNIT_ASSERT(nbVals); + + // numbers of elements in group, + // they are needed in method FIELD::setValueIJ() + const int *anElems = aGroup->getnumber()->getValue(); + double eucl1 = 0., eucl2 = 0.; + + for (int i = 1; i <= nbVals; i++) { + aFieldOnGroup1->setValueIJ(anElems[i-1], 1, (double)i); + aFieldOnGroup1->setValueIJ(anElems[i-1], 2, (double)(-i)); + + aFieldOnGroup2->setValueIJ(anElems[i-1], 1, (double)i*i); + aFieldOnGroup2->setValueIJ(anElems[i-1], 2, (double)(-i*i)); + + eucl1 += 2. * i * i; + eucl2 += 2. * i * i * i * i; + } + + // out of bound (inexisting 33-th component of last element) + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->setValueIJ(anElems[nbVals-1], 33, 10.), MEDEXCEPTION); + + // normMax + CPPUNIT_ASSERT_DOUBLES_EQUAL(nbVals, aFieldOnGroup1->normMax(), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(nbVals*nbVals, aFieldOnGroup2->normMax(), 0.000001); + + // norm2 + CPPUNIT_ASSERT_DOUBLES_EQUAL(std::sqrt(eucl1), aFieldOnGroup1->norm2(), 0.000001); // 10.4881 + CPPUNIT_ASSERT_DOUBLES_EQUAL(std::sqrt(eucl2), aFieldOnGroup2->norm2(), 0.000001); // 44.2493 + + // check getXXX methods + CPPUNIT_ASSERT(!aFieldOnGroup1->getGaussPresence()); + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getArrayGauss(), MEDEXCEPTION); + MEDMEM_ArrayInterface<double, FullInterlace,NoGauss>::Array * anArrayNoGauss = + aFieldOnGroup1->getArrayNoGauss(); + + MEDMEM_Array_ * aMEDMEM_Array_ = aFieldOnGroup1->getArray(); + MEDMEM_ArrayInterface<double, FullInterlace,NoGauss>::Array * aMEDMEM_Array_conv = + static_cast<MEDMEM_ArrayInterface<double, FullInterlace,NoGauss>::Array *>(aMEDMEM_Array_); + + const double * aValues = aFieldOnGroup1->getValue(); + + // out of range + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getColumn(3), MEDEXCEPTION); + // cannot get column in FullInterlace + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getColumn(1), MEDEXCEPTION); + + for (int i = 1; i <= nbVals; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , aFieldOnGroup1->getValueIJK(anElems[i-1], 1, 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), aFieldOnGroup1->getValueIJK(anElems[i-1], 2, 1), 0.000001); + + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , aValues[(i-1)*2 + 0], 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), aValues[(i-1)*2 + 1], 0.000001); + + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , anArrayNoGauss->getIJ(i, 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), anArrayNoGauss->getIJ(i, 2), 0.000001); + + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , aMEDMEM_Array_conv->getIJ(i, 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), aMEDMEM_Array_conv->getIJ(i, 2), 0.000001); + + const double* row_i = aFieldOnGroup1->getRow(anElems[i-1]); + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , row_i[0], 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), row_i[1], 0.000001); + + double vals_i [2]; + aFieldOnGroup1->getValueOnElement(anElems[i-1], vals_i); + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , vals_i[0], 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), vals_i[1], 0.000001); + } + + // modify all values of aFieldOnGroup2 by formula a*x + b (a = 2, b = 3) + aFieldOnGroup2->applyLin(2., 3.); + for (int i = 1; i <= nbVals; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(3. + 2.*i*i, aFieldOnGroup2->getValueIJ(anElems[i-1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3. - 2.*i*i, aFieldOnGroup2->getValueIJ(anElems[i-1], 2), 0.000001); + } + + // apply function plus13() to aFieldOnGroup1 + aFieldOnGroup1->applyFunc<plus13>(); + for (int i = 1; i <= nbVals; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); + } + + // scalarProduct + FIELD<double, FullInterlace> * aScalarProduct = + FIELD<double, FullInterlace>::scalarProduct(*aFieldOnGroup1, *aFieldOnGroup2, /*deepCheck = */true); + CPPUNIT_ASSERT_EQUAL(nbVals, aScalarProduct->getNumberOfValues()); + CPPUNIT_ASSERT_EQUAL(1, aScalarProduct->getNumberOfComponents()); + for (int i = 1; i <= nbVals; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(78. + 4.*i*i*i, //(3. + 2.*i*i)*(13 + i) + (3. - 2.*i*i)*(13 - i) + aScalarProduct->getValueIJ(anElems[i-1], 1), 0.000001); + } + + // fillFromAnalytic + aFieldOnGroup2->fillFromAnalytic(proj2d); + + double bary [3]; + double outp [2]; + const SUPPORT * aSupp = aFieldOnGroup2->getSupport(); + FIELD<double,FullInterlace> * barycenter = aMesh->getBarycenter(aSupp); + for (int i = 1; i <= nbVals; i++) { + bary[0] = barycenter->getValueIJ(anElems[i-1], 1); + bary[1] = barycenter->getValueIJ(anElems[i-1], 2); + bary[2] = barycenter->getValueIJ(anElems[i-1], 3); + + proj2d(bary, outp); + + //cout << "barycenter (" << bary[0] << ", " << bary[1] << ", " << bary[2] << ")" << endl; + //cout << "proj2d (" << outp[0] << ", " << outp[1] << ")" << endl; + + //bary (-0.666667, 0.666667, 0.666667) -> outp ( 0.902369, 0.902369) + //bary ( 0.666667, -0.666667, 0.666667) -> outp (-0.902369, 0.430964) + //bary ( 0. , 0. , 2. ) -> outp ( 0. , 2. ) + //bary ( 0. , 0. , 3. ) -> outp ( 0. , 3. ) + //bary (-1. , 0. , 2.5 ) -> outp ( 0.353553, 2.85355 ) + + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) in FIELD::fillFromAnalytic() in case of support, different from nodes: + // barycenterField in FullInterlace, but values extracted like from NoInterlace + // TODO: fix MEDMEM_Field:3483 - code should depend on interlace + CPPUNIT_ASSERT_DOUBLES_EQUAL(outp[0], aFieldOnGroup2->getValueIJ(anElems[i-1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(outp[1], aFieldOnGroup2->getValueIJ(anElems[i-1], 2), 0.000001); + //#endif + + // currently it gives values, that are wrong: + //aFieldOnGroup2 row1 ( 0.902369, 0.235702) + //aFieldOnGroup2 row2 (-0.235702, 2.7643 ) + //aFieldOnGroup2 row3 (-0.235702, -1.2357 ) + //aFieldOnGroup2 row4 ( 1.7643 , -0.235702) + //aFieldOnGroup2 row5 ( 0.235702, 2.7357 ) + } + + // info about support (Group1) + CPPUNIT_ASSERT(!aFieldOnGroup1->isOnAllElements()); // because we build Group1 so + int nbTypes = aFieldOnGroup1->getNumberOfGeometricTypes(); + //CPPUNIT_ASSERT(nbTypes); + CPPUNIT_ASSERT_EQUAL(2, nbTypes); + const int * nbElemsInEachType = aFieldOnGroup1->getNumberOfElements(); + const MED_EN::medGeometryElement * aGeomTypes = aFieldOnGroup1->getGeometricTypes(); + + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_TRIA3, aGeomTypes[0]); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_QUAD4, aGeomTypes[1]); + + // GAUSS + + // now we have no gauss localization in aFieldOnGroup1 + CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA3)); + CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_QUAD4)); + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA6), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(), MEDEXCEPTION); + + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalization(MED_EN::MED_TRIA3), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_TRIA3), MEDEXCEPTION); + + CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNbGaussI(anElems[0])); + + // set a gauss localization into aFieldOnGroup1 + double cooRef[6] = {1.,1., 2.,4., 3.,9.}; // xy xy xy + double cooGauss[10] = {7.,7., 6.,6., 5.,5., 4.,3., 2.,1.}; // x1,y1 x2,y2 x3,y3 x4,y4 x5,y5 + double wg[5] = {1., 2., 3., 4., 5.}; + GAUSS_LOCALIZATION<> gl1 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef, cooGauss, wg); + + aFieldOnGroup1->setGaussLocalization(MED_EN::MED_TRIA3, gl1); + + // now we have a gauss localization for MED_TRIA3 type + CPPUNIT_ASSERT_EQUAL(5, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA3)); + CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_QUAD4)); + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA6), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(), MEDEXCEPTION); + + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalization(MED_EN::MED_QUAD4), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_QUAD4), MEDEXCEPTION); + + GAUSS_LOCALIZATION<> gl1Back = aFieldOnGroup1->getGaussLocalization(MED_EN::MED_TRIA3); + const GAUSS_LOCALIZATION<> * gl1BackPtr = aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_TRIA3); + + CPPUNIT_ASSERT(gl1 == gl1Back); + CPPUNIT_ASSERT(gl1 == *gl1BackPtr); + + CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNbGaussI(anElems[0])); + + // sub-support of Group1 on one (first) geometric type + SUPPORT * aSubSupport1 = new SUPPORT(aMesh, "Sub-Support 1 of Group1", MED_EN::MED_FACE); + aSubSupport1->setAll(false); + + int nbTypes1 = 1; + int nbElemsInEachType1[1]; + nbElemsInEachType1[0] = nbElemsInEachType[0]; + int nbElems1 = nbElemsInEachType1[0]; + MED_EN::medGeometryElement aGeomTypes1[1]; + aGeomTypes1[0] = aGeomTypes[0]; + int * anElems1 = new int[nbElems1]; + for (int i = 0; i < nbElems1; i++) { + anElems1[i] = anElems[i]; + } + + aSubSupport1->setpartial("Support for sub-field 1 on one type of elements", + nbTypes1, nbElems1, aGeomTypes1, nbElemsInEachType1, anElems1); + + //cout << "aSubSupport1:" << endl; + //cout << *aSubSupport1 << endl; + + // extract sub-field on aSubSupport1 + FIELD<double, FullInterlace> * aSubField1 = aFieldOnGroup1->extract(aSubSupport1); + CPPUNIT_ASSERT_EQUAL(nbElems1 * /*NumberOfComponents = */2, aSubField1->getValueLength()); + + // aSubField1: + // elt\comp | 1 | 2 + //-------------------- + // 1 | 14 | 12 + // 2 | 15 | 11 + + // check normL2() and normL1() + FIELD<double>* anAreaField = aMesh->getArea(aSubSupport1); + double area1 = anAreaField->getValueIJ(anElems1[0], 1); + double area2 = anAreaField->getValueIJ(anElems1[1], 1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.44949, area1, 0.00001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.44949, area2, 0.00001); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(210.5, aSubField1->normL2(1), 0.00001); // (14*14 + 15*15)/2 + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) FIELD::normL2(int component, const FIELD * p_field_volume): + // component is not taken into account + //TODO:: implement for each interlace w/o conversion + CPPUNIT_ASSERT_DOUBLES_EQUAL(132.5, aSubField1->normL2(2), 0.00001); // (12*12 + 11*11)/2 + //#endif + CPPUNIT_ASSERT_DOUBLES_EQUAL(343.0, aSubField1->normL2() , 0.00001); // 210.5 + 132.5 + + CPPUNIT_ASSERT_DOUBLES_EQUAL(14.5, aSubField1->normL1(1), 0.00001); // (14 + 15)/2 + CPPUNIT_ASSERT_DOUBLES_EQUAL(11.5, aSubField1->normL1(2), 0.00001); // (12 + 11)/2 + CPPUNIT_ASSERT_DOUBLES_EQUAL(26.0, aSubField1->normL1() , 0.00001); // 14.5 + 11.5 + + double aNewArea [2] = {1., 0.}; // only first element will be taken into account + anAreaField->setValue(aNewArea); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(196.0, aSubField1->normL2(1, anAreaField), 0.00001); // 14*14/1 + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) FIELD::normL2(int component, const FIELD * p_field_volume): + // component is not taken into account + //TODO:: implement for each interlace w/o conversion + CPPUNIT_ASSERT_DOUBLES_EQUAL(144.0, aSubField1->normL2(2, anAreaField), 0.00001); // 12*12/1 + //#endif + CPPUNIT_ASSERT_DOUBLES_EQUAL(340.0, aSubField1->normL2(anAreaField) , 0.00001); // 196 + 144 + + CPPUNIT_ASSERT_DOUBLES_EQUAL(14.0, aSubField1->normL1(1, anAreaField), 0.00001); // 14/1 + CPPUNIT_ASSERT_DOUBLES_EQUAL(12.0, aSubField1->normL1(2, anAreaField), 0.00001); // 12/1 + CPPUNIT_ASSERT_DOUBLES_EQUAL(26.0, aSubField1->normL1(anAreaField) , 0.00001); // 14 + 12 + + // applyPow + aSubField1->applyPow(2.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(196., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); // 14*14 + CPPUNIT_ASSERT_DOUBLES_EQUAL(144., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); // 12*12 + CPPUNIT_ASSERT_DOUBLES_EQUAL(225., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); // 15*15 + CPPUNIT_ASSERT_DOUBLES_EQUAL(121., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); // 11*11 + + // setArray (NoGauss) + MEDMEM_ArrayInterface<double,FullInterlace,NoGauss>::Array * aNewArrayNoGauss = + new MEDMEM_ArrayInterface<double,FullInterlace,NoGauss>::Array(/*dim*/2, /*nbelem*/2); + aNewArrayNoGauss->setIJ(1, 1, 4.); + aNewArrayNoGauss->setIJ(1, 2, 2.); + aNewArrayNoGauss->setIJ(2, 1, 5.); + aNewArrayNoGauss->setIJ(2, 2, 1.); + aSubField1->setArray(aNewArrayNoGauss); + // no need to delete aNewArrayNoGauss, because it will be deleted + // in destructor or in deallocValue() method of aSubField1 + + CPPUNIT_ASSERT_DOUBLES_EQUAL(4., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); + + // setRow + double row[2] = {-1., -3.}; + aSubField1->setRow(anElems1[0], row); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-3., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 5., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); + // out of range + CPPUNIT_ASSERT_THROW(aSubField1->setRow(3, row), MEDEXCEPTION); + + // setColumn + double col[2] = {-7., -9.}; + aSubField1->setColumn(1, col); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-7., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-3., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) in MEDMEM_Array::setColumn() + // WAIT FOR DECISION + CPPUNIT_ASSERT_DOUBLES_EQUAL(-9., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); + //#endif + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); + // out of range + CPPUNIT_ASSERT_THROW(aSubField1->setColumn(3, col), MEDEXCEPTION); + + // setArray (Gauss) + { + int nbelgeoc[2] = {1, 3}; // 3 - 1 = two elements for the first (and the only) type + int nbgaussgeo[2] = {0, 1}; // one gauss point per each element + MEDMEM_ArrayInterface<double,FullInterlace,Gauss>::Array * aNewArrayGauss = + new MEDMEM_ArrayInterface<double,FullInterlace,Gauss>::Array + (/*dim*/2, /*nbelem*/2, /*nbtypegeo*/1, /*nbelgeoc*/nbelgeoc, /*nbgaussgeo*/nbgaussgeo); + + //#ifdef ENABLE_FAULTS + aNewArrayGauss->setIJ(1, 1, -4.); + aNewArrayGauss->setIJ(1, 2, -2.); + aNewArrayGauss->setIJ(2, 1, -5.); + aNewArrayGauss->setIJ(2, 2, -1.); + //#endif + //#ifdef ENABLE_FORCED_FAILURES + // ? (BUG) in FullInterlaceGaussPolicy::getIndex(int i,int j) + // FullInterlaceGaussPolicy::getIndex(2,2) returns 4!!! + //CPPUNIT_FAIL("? Bug in FullInterlaceGaussPolicy::getIndex(int i,int j) ?"); + //#endif + + aNewArrayGauss->setIJK(1, 1, 1, -4.); + aNewArrayGauss->setIJK(1, 2, 1, -2.); + aNewArrayGauss->setIJK(2, 1, 1, -5.); + aNewArrayGauss->setIJK(2, 2, 1, -1.); + + aSubField1->setArray(aNewArrayGauss); + // no need to delete aNewArrayGauss, because it will be deleted + // in destructor or in deallocValue() method of aSubField1 + + //#ifdef ENABLE_FAULTS + CPPUNIT_ASSERT_DOUBLES_EQUAL(-4., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-2., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-5., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); + //#endif + //#ifdef ENABLE_FORCED_FAILURES + // ? (BUG) in FullInterlaceGaussPolicy::getIndex(int i,int j) + // Must be : return _G[i-1]-1 + (j-1); + // Instead of: return _G[i-1]-1 + (j-1)*_dim; + // TODO: THINK YOUR-SELF + //CPPUNIT_FAIL("? Bug in FullInterlaceGaussPolicy::getIndex(int i,int j) ?"); + //#endif + + CPPUNIT_ASSERT_DOUBLES_EQUAL(-4., aSubField1->getValueIJK(anElems1[0], 1, 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-2., aSubField1->getValueIJK(anElems1[0], 2, 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-5., aSubField1->getValueIJK(anElems1[1], 1, 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., aSubField1->getValueIJK(anElems1[1], 2, 1), 0.000001); + } + + // alloc/dealloc; compatibility of new size with support + try { + aSubField1->deallocValue(); + aSubField1->allocValue(/*NumberOfComponents*/2, /*LengthValue*/5); + //#ifdef ENABLE_FAULTS + // (BUG) No compatibility between Support and allocated value + //aSubField1->normL1(); + CPPUNIT_ASSERT_THROW(aSubField1->normL1(),MEDEXCEPTION); + //#endif + //#ifdef ENABLE_FORCED_FAILURES + // TODO: FIX to throw an EXCEPTION + // CPPUNIT_FAIL("Error: no compatibility between Support and allocated value"); + //#endif + } + catch (MEDEXCEPTION & ex) { + // normal behaviour + } + catch (...) { + CPPUNIT_FAIL("Error: no compatibility between Support and allocated value"); + } + + // check that aFieldOnGroup1 is not changed after aSubField1 modifications + for (int i = 1; i <= nbVals; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); + } + + // reset aFieldOnGroup2 values for simple control of operators results + for (int i = 1; i <= nbVals; i++) { + aFieldOnGroup2->setValueIJ(anElems[i-1], 1, i*i); + aFieldOnGroup2->setValueIJ(anElems[i-1], 2, -i*i); + } + + int len = aFieldOnGroup1->getValueLength(); + const double * val1 = aFieldOnGroup1->getValue(); + const double * val2 = aFieldOnGroup2->getValue(); + const double * val_res; + + // operators and add, sub, mul, div + + // + + FIELD<double> aSum = *aFieldOnGroup1 + *aFieldOnGroup2; + aSum.setName(aFieldOnGroup1->getName()); + aSum.setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, &aSum, true, true); + val_res = aSum.getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val2[i], val_res[i], 0.000001); + } + + // - + FIELD<double> aDifference = *aFieldOnGroup1 - *aFieldOnGroup2; + aDifference.setName(aFieldOnGroup1->getName()); + aDifference.setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, &aDifference, true, true); + val_res = aDifference.getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] - val2[i], val_res[i], 0.000001); + } + + // - (unary) + FIELD<double> aNegative = - *aFieldOnGroup1; + aNegative.setName(aFieldOnGroup1->getName()); + aNegative.setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, &aNegative, true, true); + val_res = aNegative.getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(- val1[i], val_res[i], 0.000001); + } + + // * + FIELD<double> aProduct = (*aFieldOnGroup1) * (*aFieldOnGroup2); + aProduct.setName(aFieldOnGroup1->getName()); + aProduct.setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, &aProduct, true, true); + val_res = aProduct.getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] * val2[i], val_res[i], 0.000001); + } + + // / + FIELD<double> aQuotient = *aFieldOnGroup1 / *aFieldOnGroup2; + aQuotient.setName(aFieldOnGroup1->getName()); + aQuotient.setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, &aQuotient, true, true); + val_res = aQuotient.getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] / val2[i], val_res[i], 0.000001); + } + + double val22 = aFieldOnGroup2->getValueIJ(anElems[2], 2); + aFieldOnGroup2->setValueIJ(anElems[2], 2, 0.); + + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 / *aFieldOnGroup2, MEDEXCEPTION); + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) is it up to user to control validity of data to avoid division on zero? + // YES: USER SHOULD CARE OF IT + //CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 /= *aFieldOnGroup2, MEDEXCEPTION); + //#endif + CPPUNIT_ASSERT_THROW(FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); + + // restore value + aFieldOnGroup2->setValueIJ(anElems[2], 2, val22); + + // restore values + for (int i = 1; i <= nbVals; i++) { + aFieldOnGroup1->setValueIJ(anElems[i-1], 1, 13 + i); + aFieldOnGroup1->setValueIJ(anElems[i-1], 2, 13 - i); + } + + // static methods + FIELD<double> * aPtr; + + // add + aPtr = FIELD<double>::add(*aFieldOnGroup1, *aFieldOnGroup2); + aPtr->setName(aFieldOnGroup1->getName()); + aPtr->setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, aPtr, true, true); + val_res = aPtr->getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val2[i], val_res[i], 0.000001); + } + delete aPtr; + + // sub + aPtr = FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup2); + aPtr->setName(aFieldOnGroup1->getName()); + aPtr->setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, aPtr, true, true); + val_res = aPtr->getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] - val2[i], val_res[i], 0.000001); + } + delete aPtr; + + // mul + aPtr = FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup2); + aPtr->setName(aFieldOnGroup1->getName()); + aPtr->setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, aPtr, true, true); + val_res = aPtr->getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] * val2[i], val_res[i], 0.000001); + } + delete aPtr; + + // div + aPtr = FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2); + aPtr->setName(aFieldOnGroup1->getName()); + aPtr->setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, aPtr, true, true); + val_res = aPtr->getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] / val2[i], val_res[i], 0.000001); + } + delete aPtr; + + // addDeep + aPtr = FIELD<double>::addDeep(*aFieldOnGroup1, *aFieldOnGroup2); + aPtr->setName(aFieldOnGroup1->getName()); + aPtr->setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, aPtr, true, true); + val_res = aPtr->getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val2[i], val_res[i], 0.000001); + } + delete aPtr; + + // subDeep + aPtr = FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup2); + aPtr->setName(aFieldOnGroup1->getName()); + aPtr->setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, aPtr, true, true); + val_res = aPtr->getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] - val2[i], val_res[i], 0.000001); + } + delete aPtr; + + // mulDeep + aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup2); + aPtr->setName(aFieldOnGroup1->getName()); + aPtr->setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, aPtr, true, true); + val_res = aPtr->getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] * val2[i], val_res[i], 0.000001); + } + delete aPtr; + + // divDeep + aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2); + aPtr->setName(aFieldOnGroup1->getName()); + aPtr->setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, aPtr, true, true); + val_res = aPtr->getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] / val2[i], val_res[i], 0.000001); + } + delete aPtr; + + // += + *aFieldOnGroup1 += *aFieldOnGroup2; + for (int i = 1; i <= nbVals; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i + i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i - i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); + } + + // -= + *aFieldOnGroup1 -= *aFieldOnGroup2; + for (int i = 1; i <= nbVals; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); + } + + // *= + *aFieldOnGroup1 *= *aFieldOnGroup2; + for (int i = 1; i <= nbVals; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL( (13 + i)*i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-(13 - i)*i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); + } + + // /= + *aFieldOnGroup1 /= *aFieldOnGroup2; + for (int i = 1; i <= nbVals; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); + } + + // check case of different operands: support + MESH * aMeshOneMore = MEDMEMTest_createTestMesh(); + const GROUP* aGroupOneMore = aMeshOneMore->getGroup(MED_EN::MED_FACE, 1); + FIELD<double> * aFieldOnGroup3 = + createFieldOnGroup<double>(aMeshOneMore, aGroupOneMore, "Test_Diff_Mesh", "test"); + for (int i = 1; i <= nbVals; i++) { + aFieldOnGroup3->setValueIJ(anElems[i-1], 1, 2*i); + aFieldOnGroup3->setValueIJ(anElems[i-1], 2, 3*i); + } + const double * val3 = aFieldOnGroup3->getValue(); + + //CPPUNIT_ASSERT_NO_THROW(); + try { + aPtr = FIELD<double>::addDeep(*aFieldOnGroup1, *aFieldOnGroup3); + aPtr->setName(aFieldOnGroup1->getName()); + aPtr->setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, aPtr, true, true); + val_res = aPtr->getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val3[i], val_res[i], 0.000001); + } + delete aPtr; + + aPtr = FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup3); + delete aPtr; + aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup3); + delete aPtr; + aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup3); + delete aPtr; + } + catch (MEDEXCEPTION & ex) { + CPPUNIT_FAIL(ex.what()); + } + catch (...) { + CPPUNIT_FAIL("Unknown exception in FIELD::xxxDeep()"); + } + + CPPUNIT_ASSERT_THROW(FIELD<double>::add(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION); + + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 + *aFieldOnGroup3, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 - *aFieldOnGroup3, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 * *aFieldOnGroup3, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 / *aFieldOnGroup3, MEDEXCEPTION); + + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 += *aFieldOnGroup3, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 -= *aFieldOnGroup3, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 *= *aFieldOnGroup3, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 /= *aFieldOnGroup3, MEDEXCEPTION); + + // check case of different operands: MEDComponentsUnits + aFieldOnGroup1->setMEDComponentUnit(1, "unit3"); + + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 + *aFieldOnGroup2, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 - *aFieldOnGroup2, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 += *aFieldOnGroup2, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 -= *aFieldOnGroup2, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(FIELD<double>::add(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(FIELD<double>::addDeep(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); + + //CPPUNIT_ASSERT_NO_THROW(); + try { + aPtr = FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup2); + delete aPtr; + aPtr = FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2); + delete aPtr; + aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup2); + delete aPtr; + aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2); + delete aPtr; + + *aFieldOnGroup1 *= *aFieldOnGroup2; + *aFieldOnGroup1 /= *aFieldOnGroup2; + + FIELD<double> aPr = *aFieldOnGroup1 * *aFieldOnGroup2; + FIELD<double> aQu = *aFieldOnGroup1 / *aFieldOnGroup2; + } + catch (MEDEXCEPTION & ex) { + CPPUNIT_FAIL(ex.what()); + } + catch (...) { + CPPUNIT_FAIL("Unknown exception"); + } + + // restore MED units + aFieldOnGroup1->setMEDComponentUnit(1, "unit1"); + + // check case of different operands: valueType + //FIELD<int> * aFieldOnGroup4 = + // createFieldOnGroup<int>(aMeshOneMore, aGroupOneMore, "Test_Diff_Mesh", "test"); + // + //CPPUNIT_ASSERT_THROW(FIELD<double>::add(*aFieldOnGroup4, *aFieldOnGroup3), MEDEXCEPTION); + //CPPUNIT_ASSERT_THROW(*aFieldOnGroup4 - *aFieldOnGroup3, MEDEXCEPTION); + //CPPUNIT_ASSERT_THROW(*aFieldOnGroup4 *= *aFieldOnGroup3, MEDEXCEPTION); + //delete aFieldOnGroup4; + + // check case of different operands: numberOfComponents + //#ifdef ENABLE_FAULTS + // (BUG) Cannot allocate value of higher dimension because of _componentsTypes reinitialization + aFieldOnGroup1->deallocValue(); + //CPPUNIT_ASSERT_THROW(aFieldOnGroup1->allocValue(/*dim*/5), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aFieldOnGroup1->allocValue(/*dim*/5)); + //#endif + //#ifdef ENABLE_FORCED_FAILURES + // YES THERE MUST BE AN EXCEPTION + // CPPUNIT_FAIL("Segmentation fault on attempt to allocate value of higher dimension." + // " Must be MEDEXCEPTION instead. And on attempt to change nb.components" + // " must be the same behaviour."); + //#endif + aFieldOnGroup1->setNumberOfComponents(5); + + CPPUNIT_ASSERT_THROW(FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 * *aFieldOnGroup2, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 /= *aFieldOnGroup2, MEDEXCEPTION); + + // check case of different operands: numberOfValues + aFieldOnGroup1->deallocValue(); + aFieldOnGroup1->allocValue(2, nbVals + 1); + // be carefull: aFieldOnGroup1 reallocated and contains random values + + CPPUNIT_ASSERT_THROW(FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 / *aFieldOnGroup2, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 += *aFieldOnGroup2, MEDEXCEPTION); + + // restore aFieldOnGroup1 + aFieldOnGroup1->deallocValue(); + aFieldOnGroup1->allocValue(2, nbVals); + // be carefull: aFieldOnGroup1 reallocated and contains random values + + delete aSubSupport1; + delete [] anElems1; + + delete aScalarProduct; + delete aSubField1; + delete anAreaField; + delete barycenter; + delete aFieldOnGroup1; + delete aFieldOnGroup2; + delete aFieldOnGroup3; + + delete aMesh; + delete aMeshOneMore; + + ///////////////////// + // TEST 5: Drivers // + ///////////////////// + testDrivers(); +} + +/*! + * Check methods (2), defined in MEDMEM_FieldConvert.hxx: + * (+) template <class T> FIELD<T,FullInterlace> * FieldConvert(const FIELD<T,NoInterlace> & field); + * (+) template <class T> FIELD<T,NoInterlace> * FieldConvert(const FIELD<T,FullInterlace> & field); + */ +void MEDMEMTest::testFieldConvert() +{ + // create an empty integer field 2x10 + FIELD<int, FullInterlace> * aField_FING = new FIELD<int, FullInterlace> (); + + aField_FING->setName("Field_FING"); + aField_FING->setDescription("Field full interlace no gauss"); + + aField_FING->setNumberOfComponents(2); + aField_FING->setNumberOfValues(10); + + string aCompsNames[2] = {"Pos", "Neg"}; + string aCompsDescs[2] = {"+", "-"}; + string aMEDCompsUnits[2] = {"unit1", "unit2"}; + UNIT aCompsUnits[2]; + + aCompsUnits[0] = UNIT("u1", "descr1"); + aCompsUnits[1] = UNIT("u2", "descr2"); + + aField_FING->setComponentsNames(aCompsNames); + aField_FING->setComponentsDescriptions(aCompsDescs); + aField_FING->setMEDComponentsUnits(aMEDCompsUnits); + aField_FING->setComponentsUnits(aCompsUnits); + + // check UNITs (for testField()) + const UNIT * aCompsUnitsBack = aField_FING->getComponentsUnits(); + CPPUNIT_ASSERT(aCompsUnits[0].getName() == aCompsUnitsBack[0].getName()); + CPPUNIT_ASSERT(aCompsUnits[1].getName() == aCompsUnitsBack[1].getName()); + + const UNIT * aCompUnitBack1 = aField_FING->getComponentUnit(1); + const UNIT * aCompUnitBack2 = aField_FING->getComponentUnit(2); + CPPUNIT_ASSERT(aCompsUnits[0].getName() == aCompUnitBack1->getName()); + CPPUNIT_ASSERT(aCompsUnits[1].getName() == aCompUnitBack2->getName()); + + // create one more field by copy + FIELD<int, FullInterlace> * aField_FIGG = new FIELD<int, FullInterlace> (*aField_FING); + + // values + int values_FING[20] = { 7,- 7, 14,-14, 21,-21, 28,-28, 35,-35, + 42,-42, 49,-49, 56,-56, 63,-63, 70,-70}; + + ///////////////////// + // TEST 1: NoGauss // + ///////////////////// + + MEDMEM_ArrayInterface<int,FullInterlace,NoGauss>::Array * anArray_FING = + new MEDMEM_ArrayInterface<int,FullInterlace,NoGauss>::Array + (values_FING, /*dim*/2, /*nbelem*/10, /*shallowCopy*/false, /*ownershipOfValues*/false); + aField_FING->setArray(anArray_FING); + // no need to delete anArray_FING, because it will be deleted in destructor of aField_FING + + // 1. FullInterlace -> NoInterlace + FIELD<int, NoInterlace> * aField_NING = FieldConvert(*aField_FING); + const int * values_NING = aField_NING->getValue(); + + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 2; j++) { + CPPUNIT_ASSERT_EQUAL(values_FING[2*i + j], values_NING[10*j + i]); + } + } + + // 2. NoInterlace -> FullInterlace + FIELD<int, FullInterlace> * aField_FING_conv = FieldConvert(*aField_NING); + const int * values_FING_conv = aField_FING_conv->getValue(); + + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 2; j++) { + CPPUNIT_ASSERT_EQUAL(values_FING_conv[2*i + j], values_FING[2*i + j]); + CPPUNIT_ASSERT_EQUAL(values_FING_conv[2*i + j], values_NING[10*j + i]); + } + } + + delete aField_FING; + delete aField_NING; + delete aField_FING_conv; + + /////////////////// + // TEST 2: Gauss // + /////////////////// + int nbelgeoc[2] = {1, 11}; + int nbgaussgeo[2] = {-1, 1}; + MEDMEM_ArrayInterface<int,FullInterlace,Gauss>::Array * anArray_FIGG = + new MEDMEM_ArrayInterface<int,FullInterlace,Gauss>::Array + (values_FING, /*dim*/2, /*nbelem*/10, /*nbtypegeo*/1, /*nbelgeoc*/nbelgeoc, + /*nbgaussgeo*/nbgaussgeo, /*shallowCopy*/false, /*ownershipOfValues*/false); + aField_FIGG->setArray(anArray_FIGG); + // no need to delete anArray_FIGG, because it will be deleted in destructor of aField_FIGG + + // 1. FullInterlace -> NoInterlace + FIELD<int, NoInterlace> * aField_NIGG = FieldConvert(*aField_FIGG); + const int * values_NIGG = aField_NIGG->getValue(); + + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 2; j++) { + CPPUNIT_ASSERT_EQUAL(values_FING[2*i + j], values_NIGG[10*j + i]); + } + } + + // 2. NoInterlace -> FullInterlace + FIELD<int, FullInterlace> * aField_FIGG_conv = FieldConvert(*aField_NIGG); + const int * values_FIGG_conv = aField_FIGG_conv->getValue(); + + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 2; j++) { + CPPUNIT_ASSERT_EQUAL(values_FIGG_conv[2*i + j], values_FING[2*i + j]); + CPPUNIT_ASSERT_EQUAL(values_FIGG_conv[2*i + j], values_NIGG[10*j + i]); + } + } + + delete aField_FIGG; + delete aField_NIGG; + delete aField_FIGG_conv; + + //#ifdef ENABLE_FAULTS + // (BUG) in FieldConvert(), concerning FIELD_::operator= + { + // create an empty integer field 2x10 + FIELD<int, FullInterlace> * aField = new FIELD<int, FullInterlace> (); + + aField->setName("aField"); + aField->setDescription("Field full interlace no gauss"); + + aField->setNumberOfComponents(2); + aField->setNumberOfValues(10); + + aField->setComponentsNames(aCompsNames); + aField->setComponentsDescriptions(aCompsDescs); + aField->setMEDComponentsUnits(aMEDCompsUnits); + + MEDMEM_ArrayInterface<int,FullInterlace,NoGauss>::Array * anArray = + new MEDMEM_ArrayInterface<int,FullInterlace,NoGauss>::Array + (values_FING, /*dim*/2, /*nbelem*/10, /*shallowCopy*/false, /*ownershipOfValues*/false); + aField->setArray(anArray); + // no need to delete anArray, because it will be deleted in destructor of aField + + FIELD<int, NoInterlace> * aField_conv = FieldConvert(*aField); + } + //#endif + //#ifdef ENABLE_FORCED_FAILURES + // STD::vector + //CPPUNIT_FAIL("FieldConvert() fails if _componentsUnits is not set, because it calls FIELD_::operator="); + //#endif +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_Field_fault.cxx b/src/MEDMEMCppTest/MEDMEMTest_Field_fault.cxx new file mode 100644 index 000000000..56da5ad2a --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Field_fault.cxx @@ -0,0 +1,1554 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "MEDMEM_FieldConvert.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Group.hxx" +#include "MEDMEM_Support.hxx" +#include <MEDMEM_VtkMeshDriver.hxx> +#include <MEDMEM_MedMeshDriver22.hxx> + + +#include <sstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; + +// #14,15: MEDMEMTest_Field.cxx +// Check methods from MEDMEM_Field.hxx, MEDMEM_FieldConvert.hxx + +/*! + * Check methods (48), defined in MEDMEM_Field.hxx: + * class FIELD_ { + * (+) FIELD_(); + * (+) FIELD_(const SUPPORT * Support, const int NumberOfComponents); + * (+) FIELD_(const FIELD_ &m); + * (+) virtual ~FIELD_(); + * (+) FIELD_& operator=(const FIELD_ &m); + * + * (-) virtual void rmDriver(int index=0); + * (-) virtual int addDriver(driverTypes driverType, + * const string & fileName="Default File Name.med", + * const string & driverFieldName="Default Field Nam", + * MED_EN::med_mode_acces access=MED_EN::MED_REMP); + * (-) virtual int addDriver(GENDRIVER & driver); + * + * (-) virtual void read (const GENDRIVER &); + * (-) virtual void read(int index=0); + * (-) virtual void openAppend(void); + * (-) virtual void write(const GENDRIVER &); + * (-) virtual void write(int index=0, const string & driverName=""); + * (-) virtual void writeAppend(const GENDRIVER &); + * (-) virtual void writeAppend(int index=0, const string & driverName=""); + * + * (+) inline void setName(const string Name); + * (+) inline string getName() const; + * (+) inline void setDescription(const string Description); + * (+) inline string getDescription() const; + * (+) inline const SUPPORT * getSupport() const; + * (+) inline void setSupport(const SUPPORT * support); + * (+) inline void setNumberOfComponents(const int NumberOfComponents); + * (+) inline int getNumberOfComponents() const; + * (+) inline void setNumberOfValues(const int NumberOfValues); + * (+) inline int getNumberOfValues() const; + * (+) inline void setComponentsNames(const string * ComponentsNames); + * (+) inline void setComponentName(int i, const string ComponentName); + * (+) inline const string * getComponentsNames() const; + * (+) inline string getComponentName(int i) const; + * (+) inline void setComponentsDescriptions(const string * ComponentsDescriptions); + * (+) inline void setComponentDescription(int i, const string ComponentDescription); + * (+) inline const string * getComponentsDescriptions() const; + * (+) inline string getComponentDescription(int i) const; + * (+) inline void setComponentsUnits(const UNIT * ComponentsUnits); + * (+) inline const UNIT * getComponentsUnits() const; + * (+) inline const UNIT * getComponentUnit(int i) const; + * (+) inline void setMEDComponentsUnits(const string * MEDComponentsUnits); + * (+) inline void setMEDComponentUnit(int i, const string MEDComponentUnit); + * (+) inline const string * getMEDComponentsUnits() const; + * (+) inline string getMEDComponentUnit(int i) const; + * + * (+) inline void setIterationNumber(int IterationNumber); + * (+) inline int getIterationNumber() const; + * (+) inline void setTime(double Time); + * (+) inline double getTime() const; + * (+) inline void setOrderNumber(int OrderNumber); + * (+) inline int getOrderNumber() const; + * + * (+) inline MED_EN::med_type_champ getValueType () const; + * (+) inline MED_EN::medModeSwitch getInterlacingType() const; + * (-) virtual inline bool getGaussPresence() const throw (MEDEXCEPTION); + * } + * + * template <class T, class INTERLACING_TAG> class FIELD : public FIELD_ { + * (+) FIELD(); + * (+) FIELD(const FIELD &m); + * (+) FIELD(const SUPPORT * Support, const int NumberOfComponents) throw (MEDEXCEPTION); + * (+) FIELD(driverTypes driverType, + * const string & fileName, const string & fieldDriverName, + * const int iterationNumber=-1, const int orderNumber=-1) throw (MEDEXCEPTION); + * (+) FIELD(const SUPPORT * Support, driverTypes driverType, + * const string & fileName="", const string & fieldName="", + * const int iterationNumber = -1, const int orderNumber = -1) throw (MEDEXCEPTION); + * (+) ~FIELD(); + * (+) FIELD & operator=(const FIELD &m); + * + * (+) const FIELD operator+(const FIELD& m) const; + * (+) const FIELD operator-(const FIELD& m) const; + * (+) const FIELD operator*(const FIELD& m) const; + * (+) const FIELD operator/(const FIELD& m) const; + * (+) const FIELD operator-() const; + * (+) FIELD& operator+=(const FIELD& m); + * (+) FIELD& operator-=(const FIELD& m); + * (+) FIELD& operator*=(const FIELD& m); + * (+) FIELD& operator/=(const FIELD& m); + * + * (+) static FIELD* add(const FIELD& m, const FIELD& n); + * (+) static FIELD* addDeep(const FIELD& m, const FIELD& n); + * (+) static FIELD* sub(const FIELD& m, const FIELD& n); + * (+) static FIELD* subDeep(const FIELD& m, const FIELD& n); + * (+) static FIELD* mul(const FIELD& m, const FIELD& n); + * (+) static FIELD* mulDeep(const FIELD& m, const FIELD& n); + * (+) static FIELD* div(const FIELD& m, const FIELD& n); + * (+) static FIELD* divDeep(const FIELD& m, const FIELD& n); + * + * (+) double normMax() const throw (MEDEXCEPTION); + * (+) double norm2() const throw (MEDEXCEPTION); + * + * (+) void applyLin(T a, T b); + * (+) template <T T_function(T)> void applyFunc(); + * (+) void applyPow(T scalar); + * + * (+) static FIELD* scalarProduct(const FIELD& m, const FIELD& n, bool deepCheck=false); + * + * (+) double normL2(int component, const FIELD<double,FullInterlace> * p_field_volume=NULL) const; + * (+) double normL2(const FIELD<double,FullInterlace> * p_field_volume=NULL) const; + * (+) double normL1(int component, const FIELD<double,FullInterlace> * p_field_volume=NULL) const; + * (+) double normL1(const FIELD<double,FullInterlace> * p_field_volume=NULL) const; + * + * (+) FIELD* extract(const SUPPORT *subSupport) const throw (MEDEXCEPTION); + * + * (EMPTY COMMENT, EMPTY IMPLEMENTATION!!!) void init (); + * + * (+) void rmDriver(int index=0); + * (+) int addDriver(driverTypes driverType, + * const string & fileName="Default File Name.med", + * const string & driverFieldName="Default Field Name", + * MED_EN::med_mode_acces access=MED_EN::MED_REMP); + * (+) int addDriver(GENDRIVER & driver); + * + * (+) void allocValue(const int NumberOfComponents); + * (+) void allocValue(const int NumberOfComponents, const int LengthValue); + * (+) void deallocValue(); + * + * (+) inline void read(int index=0); + * (+) inline void read(const GENDRIVER & genDriver); + * (+) inline void write(int index=0, const string & driverName = ""); + * (+) inline void write(const GENDRIVER &); + * (+) inline void writeAppend(int index=0, const string & driverName = ""); + * (+) inline void writeAppend(const GENDRIVER &); + * + * (+) inline MEDMEM_Array_ * getArray() const throw (MEDEXCEPTION); + * (+) inline ArrayGauss * getArrayGauss() const throw (MEDEXCEPTION); + * (+) inline ArrayNoGauss * getArrayNoGauss() const throw (MEDEXCEPTION); + * (+) inline bool getGaussPresence() const throw (MEDEXCEPTION); + * + * (+) inline int getValueLength() const throw (MEDEXCEPTION); + * (+) inline const T* getValue() const throw (MEDEXCEPTION); + * (+) inline const T* getRow(int i) const throw (MEDEXCEPTION); + * (+) inline const T* getColumn(int j) const throw (MEDEXCEPTION); + * (+) inline T getValueIJ(int i,int j) const throw (MEDEXCEPTION); + * (+) inline T getValueIJK(int i,int j,int k) const throw (MEDEXCEPTION); + * (+) bool getValueOnElement(int eltIdInSup,T* retValues) const throw (MEDEXCEPTION); + * + * (+) const int getNumberOfGeometricTypes() const throw (MEDEXCEPTION); + * + * (+) const GAUSS_LOCALIZATION<INTERLACING_TAG> & getGaussLocalization + * (MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION); + * (+) const GAUSS_LOCALIZATION<INTERLACING_TAG> * getGaussLocalizationPtr + * (MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION); + * (+) void setGaussLocalization(MED_EN::medGeometryElement geomElement, + * const GAUSS_LOCALIZATION<INTERLACING_TAG> & gaussloc); + * (+) const int * getNumberOfGaussPoints() const throw (MEDEXCEPTION); + * (+) const int getNumberOfGaussPoints + * (MED_EN::medGeometryElement geomElement) const throw (MEDEXCEPTION); + * (+) const int getNbGaussI(int i) const throw (MEDEXCEPTION); + * + * (+) const int * getNumberOfElements() const throw (MEDEXCEPTION); + * (+) const MED_EN::medGeometryElement * getGeometricTypes() const throw (MEDEXCEPTION); + * (+) bool isOnAllElements() const throw (MEDEXCEPTION); + * + * (+) inline void setArray(MEDMEM_Array_ *value) throw (MEDEXCEPTION); + * (+) inline void setValue(T* value) throw (MEDEXCEPTION); + * (+) inline void setRow(int i, T* value) throw (MEDEXCEPTION); + * (+) inline void setColumn(int i, T* value) throw (MEDEXCEPTION); + * (+) inline void setValueIJ(int i, int j, T value) throw (MEDEXCEPTION); + * + * (NOT IMPLEMENTED!!!) void getVolume() const throw (MEDEXCEPTION); + * (NOT IMPLEMENTED!!!) void getArea() const throw (MEDEXCEPTION); + * (NOT IMPLEMENTED!!!) void getLength() const throw (MEDEXCEPTION); + * (NOT IMPLEMENTED!!!) void getNormal() const throw (MEDEXCEPTION); + * (NOT IMPLEMENTED!!!) void getBarycenter() const throw (MEDEXCEPTION); + * + * (+) void fillFromAnalytic(myFuncType f) throw (MEDEXCEPTION); + * } + * + * Use code of test_operation_fieldint.cxx + * test_operation_fielddouble.cxx + * test_copie_field_.cxx + * test_copie_fieldT.cxx + */ +void compareField_(const FIELD_ * theField_1, const FIELD_ * theField_2, bool isFIELD, bool isValue) +{ + // name, description, support + CPPUNIT_ASSERT_EQUAL(theField_1->getName(), theField_2->getName()); + CPPUNIT_ASSERT_EQUAL(theField_1->getDescription(), theField_2->getDescription()); + CPPUNIT_ASSERT_EQUAL(theField_1->getSupport(), theField_2->getSupport()); + + // components information + int aNbComps = theField_1->getNumberOfComponents(); + CPPUNIT_ASSERT_EQUAL(aNbComps, theField_2->getNumberOfComponents()); + + for (int i = 1; i <= aNbComps; i++) { + CPPUNIT_ASSERT_EQUAL(theField_1->getComponentName(i), theField_2->getComponentName(i)); + CPPUNIT_ASSERT_EQUAL(theField_1->getComponentDescription(i), theField_2->getComponentDescription(i)); + CPPUNIT_ASSERT_EQUAL(theField_1->getMEDComponentUnit(i), theField_2->getMEDComponentUnit(i)); + } + + // iteration information + CPPUNIT_ASSERT_EQUAL(theField_1->getIterationNumber(), theField_2->getIterationNumber()); + CPPUNIT_ASSERT_EQUAL(theField_1->getOrderNumber(), theField_2->getOrderNumber()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(theField_1->getTime(), theField_2->getTime(), 0.0000001); + + // Value + int nbOfValues = theField_1->getNumberOfValues(); + CPPUNIT_ASSERT_EQUAL(nbOfValues, theField_2->getNumberOfValues()); + + if (isFIELD) { + // Value type and Interlacing type + CPPUNIT_ASSERT_EQUAL(theField_1->getValueType(), theField_2->getValueType()); + CPPUNIT_ASSERT_EQUAL(theField_1->getInterlacingType(), theField_2->getInterlacingType()); + + // Gauss Presence + if (isValue) { + CPPUNIT_ASSERT_EQUAL(theField_1->getGaussPresence(), theField_2->getGaussPresence()); + } + else { + CPPUNIT_ASSERT_THROW(theField_1->getGaussPresence(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theField_2->getGaussPresence(), MEDEXCEPTION); + } + } + else { + CPPUNIT_ASSERT_THROW(theField_1->getGaussPresence(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theField_2->getGaussPresence(), MEDEXCEPTION); + } +} + +void checkField_(FIELD_ * theField_, const SUPPORT * theSupport, + MED_EN::med_type_champ theValueType, + MED_EN::medModeSwitch theInterlace) +{ + // name + const string aFieldName = "a_name_of_a_field"; + theField_->setName(aFieldName); + CPPUNIT_ASSERT_EQUAL(aFieldName, theField_->getName()); + + // description + const string aFieldDescr = "a_description_of_a_field"; + theField_->setDescription(aFieldDescr); + CPPUNIT_ASSERT_EQUAL(aFieldDescr, theField_->getDescription()); + + // support + theField_->setSupport(theSupport); + CPPUNIT_ASSERT(theField_->getSupport() == theSupport); + + // components information + int aNbComps = 3; + + string aCompsNames[3] = {"Vx", "Vy", "Vz"}; + string aCompsDescs[3] = {"vitesse selon x", "vitesse selon y", "vitesse selon z"}; + string aCompsUnits[3] = {"m.s-1", "m.s-1", "m.s-1"}; + + theField_->setNumberOfComponents(aNbComps); + CPPUNIT_ASSERT_EQUAL(aNbComps, theField_->getNumberOfComponents()); + + theField_->setComponentsNames(aCompsNames); + +//#ifdef ENABLE_FAULTS + try { + theField_->setNumberOfComponents(7); + // Segmentation fault here because array of components names is not resized + for (int i = 1; i <= 7; i++) { + theField_->setComponentName(i, "AnyComponent"); + } + } + catch (MEDEXCEPTION& ex) { + // Ok, it is good to have MEDEXCEPTION here + } + catch (...) { + CPPUNIT_FAIL("Unknown exception cought"); + } + // restore components names + theField_->setNumberOfComponents(aNbComps); + theField_->setComponentsNames(aCompsNames); +//#endif +//#ifdef ENABLE_FORCED_FAILURES +// CPPUNIT_FAIL("FIELD_::_componentsNames bad management"); +//#endif + + theField_->setComponentsDescriptions(aCompsDescs); + theField_->setMEDComponentsUnits(aCompsUnits); + + const string * aCompsNamesBack = theField_->getComponentsNames(); + const string * aCompsDescsBack = theField_->getComponentsDescriptions(); + const string * aCompsUnitsBack = theField_->getMEDComponentsUnits(); + for (int i = 1; i <= aNbComps; i++) { + CPPUNIT_ASSERT_EQUAL(aCompsNamesBack[i-1], theField_->getComponentName(i)); + CPPUNIT_ASSERT_EQUAL(aCompsNamesBack[i-1], aCompsNames[i-1]); + + CPPUNIT_ASSERT_EQUAL(aCompsDescsBack[i-1], theField_->getComponentDescription(i)); + CPPUNIT_ASSERT_EQUAL(aCompsDescsBack[i-1], aCompsDescs[i-1]); + + CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack[i-1], theField_->getMEDComponentUnit(i)); + CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack[i-1], aCompsUnits[i-1]); + } + + const string aCompName2 ("Name of second component"); + const string aCompDesc2 ("Description of second component"); + const string aCompUnit2 ("Unit of second MED component"); + + theField_->setComponentName(2, aCompName2); + theField_->setComponentDescription(2, aCompDesc2); + theField_->setMEDComponentUnit(2, aCompUnit2); + + const string * aCompsNamesBack2 = theField_->getComponentsNames(); + const string * aCompsDescsBack2 = theField_->getComponentsDescriptions(); + const string * aCompsUnitsBack2 = theField_->getMEDComponentsUnits(); + + CPPUNIT_ASSERT_EQUAL(aCompsNamesBack2[1], theField_->getComponentName(2)); + CPPUNIT_ASSERT_EQUAL(aCompsNamesBack2[1], aCompName2); + + CPPUNIT_ASSERT_EQUAL(aCompsDescsBack2[1], theField_->getComponentDescription(2)); + CPPUNIT_ASSERT_EQUAL(aCompsDescsBack2[1], aCompDesc2); + + CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack2[1], theField_->getMEDComponentUnit(2)); + CPPUNIT_ASSERT_EQUAL(aCompsUnitsBack2[1], aCompUnit2); + +//#ifdef ENABLE_FAULTS + // (BUG) No index checking + CPPUNIT_ASSERT_THROW(theField_->setComponentName(0, "str"), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theField_->setComponentName(aNbComps + 1, "str"), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theField_->setComponentDescription(0, "str"), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theField_->setComponentDescription(aNbComps + 1, "str"), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theField_->setMEDComponentUnit(0, "str"), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(theField_->setMEDComponentUnit(aNbComps + 1, "str"), MEDEXCEPTION); +//#endif +//#ifdef ENABLE_FORCED_FAILURES +// CPPUNIT_FAIL("FIELD::setComponentXXX() does not check component index"); +//#endif + + // iteration information + int anIterNumber = 10; // set value to MED_NOPDT if undefined (default) + theField_->setIterationNumber(anIterNumber); + CPPUNIT_ASSERT_EQUAL(anIterNumber, theField_->getIterationNumber()); + + int anOrderNumber = 1; // set value to MED_NONOR if undefined (default) + theField_->setOrderNumber(anOrderNumber); + CPPUNIT_ASSERT_EQUAL(anOrderNumber, theField_->getOrderNumber()); + + double aTime = 3.435678; // in second + theField_->setTime(aTime); + CPPUNIT_ASSERT_DOUBLES_EQUAL(aTime, theField_->getTime(), 0.0000001); + + // Value + int nbOfValues = 10; + // dangerous method, because it does not reallocate values array + theField_->setNumberOfValues(nbOfValues); + CPPUNIT_ASSERT_EQUAL(nbOfValues, theField_->getNumberOfValues()); + + // Value type and Interlacing type + CPPUNIT_ASSERT_EQUAL(theValueType, theField_->getValueType()); + CPPUNIT_ASSERT_EQUAL(theInterlace, theField_->getInterlacingType()); +} + +template<class T, class INTERLACING_TAG> +void compareField(const FIELD<T, INTERLACING_TAG> * theField_1, + const FIELD<T, INTERLACING_TAG> * theField_2, bool isValue) +{ + // compare FIELD_ part + compareField_(theField_1, theField_2, /*isFIELD = */true, isValue); + + // compare FIELD part + // TO DO +} + +template<class T, class INTERLACING_TAG> +void checkField (FIELD<T, INTERLACING_TAG> * theField, const SUPPORT * theSupport) +{ + // check FIELD_ part + MED_EN::med_type_champ aValueType = SET_VALUE_TYPE<T>::_valueType; + MED_EN::medModeSwitch anInterlace = SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType; + checkField_(theField, theSupport, aValueType, anInterlace); + + // check FIELD part + + // filling by support charackteristics (NOT IMPLEMENTED METHODS!!!): + // value type must be MED_REEL64 (i.e. a FIELD<double>) for these methods, + // nb. of components must be equal 1 (for Volume, Area, Length) or + // space dimension (for Normal, Barycenter, ) + { + MESH* aMesh = theSupport->getMesh(); + int spaceDim = 3; + if (aMesh) spaceDim = aMesh->getSpaceDimension(); + theField->deallocValue(); + theField->allocValue(/*NumberOfComponents = */spaceDim + 1); + + // 0020142: [CEA 315] Unused function in MEDMEM::FIELD + // getVolume() etc. does nothing +// CPPUNIT_ASSERT_THROW(theField->getVolume(), MEDEXCEPTION); +// CPPUNIT_ASSERT_THROW(theField->getArea(), MEDEXCEPTION); +// CPPUNIT_ASSERT_THROW(theField->getLength(), MEDEXCEPTION); +// if (aMesh) { +// CPPUNIT_ASSERT_THROW(theField->getNormal(), MEDEXCEPTION); +// CPPUNIT_ASSERT_THROW(theField->getBarycenter(), MEDEXCEPTION); +// } + + theField->deallocValue(); + theField->allocValue(/*NumberOfComponents = */1); + // 0020142: [CEA 315] Unused function in MEDMEM::FIELD + // getVolume() etc. does nothing +// if (aValueType == MED_EN::MED_REEL64) { +// CPPUNIT_ASSERT_NO_THROW(theField->getVolume()); +// CPPUNIT_ASSERT_NO_THROW(theField->getArea()); +// CPPUNIT_ASSERT_NO_THROW(theField->getLength()); +// } +// else { +// CPPUNIT_ASSERT_THROW(theField->getVolume(), MEDEXCEPTION); +// CPPUNIT_ASSERT_THROW(theField->getArea(), MEDEXCEPTION); +// CPPUNIT_ASSERT_THROW(theField->getLength(), MEDEXCEPTION); +// } + + if (aMesh) { + theField->deallocValue(); + theField->allocValue(/*NumberOfComponents = */spaceDim); + // 0020142: [CEA 315] Unused function in MEDMEM::FIELD + // getVolume() etc. does nothing +// if (aValueType == MED_EN::MED_REEL64) { +// CPPUNIT_ASSERT_NO_THROW(theField->getNormal()); +// CPPUNIT_ASSERT_NO_THROW(theField->getBarycenter()); +// } +// else { +// CPPUNIT_ASSERT_THROW(theField->getNormal(), MEDEXCEPTION); +// CPPUNIT_ASSERT_THROW(theField->getBarycenter(), MEDEXCEPTION); +// } + } + } + + // values + theField->deallocValue(); + theField->allocValue(/*NumberOfComponents = */2); + int nbElemSupport = theSupport->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS); + CPPUNIT_ASSERT_EQUAL(nbElemSupport, theField->getNumberOfValues()); + +//#ifdef ENABLE_FAULTS + // (BUG) FIELD::deallocValue() does not nullify _value pointer, + // that is why there can be failures in other methods + // (even if simply call deallocValue() two times) + theField->deallocValue(); + theField->getGaussPresence(); +//#endif +//#ifdef ENABLE_FORCED_FAILURES +// CPPUNIT_FAIL("FIELD::deallocValue() does not nullify _value pointer"); +//#endif + + // copy constructor + FIELD<T, INTERLACING_TAG> aField_copy1 (*theField); + //compareField(theField, &aField_copy1, /*isValue = */false); + compareField(theField, &aField_copy1, /*isValue = */true); + + // operator= +//#ifdef ENABLE_FAULTS + // (BUG) This fails (Segmentation fault) if not set: + // _componentsNames or _componentsDescriptions, or _componentsUnits, or _MEDComponentsUnits + FIELD<T, INTERLACING_TAG> aField_copy2; + aField_copy2 = *theField; + //compareField(theField, &aField_copy2, /*isValue = */false); + compareField(theField, &aField_copy2, /*isValue = */true); +//#endif +//#ifdef ENABLE_FORCED_FAILURES +// CPPUNIT_FAIL("FIELD_::operator=() fails if _componentsUnits is not set"); +//#endif +} + +template<class T> +FIELD<T> * createFieldOnGroup(MESH* theMesh, const GROUP* theGroup, + const string theName, const string theDescr) +{ + FIELD<T> * aFieldOnGroup = new FIELD<T> (theGroup, /*NumberOfComponents = */2); + + aFieldOnGroup->setName(theName); + aFieldOnGroup->setDescription(theDescr); + + string aCompsNames[2] = {"Pos", "Neg"}; + string aCompsDescs[2] = {"+", "-"}; + string aCompsUnits[2] = {"unit1", "unit2"}; + + aFieldOnGroup->setComponentsNames(aCompsNames); + aFieldOnGroup->setComponentsDescriptions(aCompsDescs); + aFieldOnGroup->setMEDComponentsUnits(aCompsUnits); + + return aFieldOnGroup; +} + +double plus13 (double val) +{ + return val + 13; +} + +// function to calculate field values from coordinates of an element +// typedef void (*myFuncType)(const double * temp, T* output); +// size of temp array = space dim = 3 +// size of output array = nb. comps = 2 +void proj2d (const double * temp, double* output) +{ + // dimetric projection with coefficients: + // 1.0 along Oy and Oz, 0.5 along Ox + // + // ^ z (y_) + // | + // | + // .----> y (x_) + // / + // L x + // + // x_ = y - x * sqrt(2.) / 4. + // y_ = z - x * sqrt(2.) / 4. + + double dx = temp[0] * std::sqrt(2.) / 4.; + output[0] = temp[1] - dx; + output[1] = temp[2] - dx; +} + +void testDrivers() +{ + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if (tmp_dir == "") + tmp_dir = "/tmp"; + + string filename_rd = data_dir + "/share/salome/resources/med/pointe.med"; + string filename_wr = tmp_dir + "/myMedFieldfile.med"; + string filename_support_wr = tmp_dir + "/myMedSupportFiledfile.med"; + string filename22_rd = data_dir + "/share/salome/resources/med/pointe_import22.med"; + string filenamevtk_wr = tmp_dir + "/myMedFieldfile22.vtk"; + string cp_file = "cp " + filename_rd + " " + filename_wr; + + string fieldname_celldouble_rd = "fieldcelldoublescalar"; + string fieldname_celldouble_wr = fieldname_celldouble_rd + "_cpy"; + string fieldname_nodeint_rd = "fieldnodeint"; + string fieldname_nodeint_wr = fieldname_nodeint_rd + "_cpy"; + string fieldname_nodeint_wr1 = fieldname_nodeint_rd + "_cpy1"; + string meshname = "maa1"; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filename_wr); + aRemover.Register(filenamevtk_wr); + aRemover.Register(filename_support_wr); + + //Copy file + system(cp_file.c_str()); + + FIELD<int> aInvalidField; + //must throw becase only VTK_DRIVER or MED_DRIVER may be specified as driverType for FIELD + CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(NO_DRIVER, filename_rd, fieldname_nodeint_rd), + MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(GIBI_DRIVER, filename_rd, fieldname_nodeint_rd), + MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(PORFLOW_DRIVER, filename_rd, fieldname_nodeint_rd), + MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aInvalidField = FIELD<int>(ASCII_DRIVER, filename_rd, fieldname_nodeint_rd), + MEDEXCEPTION); + + ////////////////// + //TestRead Part// + ////////////////// + FIELD<double> *aField_1 = NULL; + CPPUNIT_ASSERT_NO_THROW(aField_1 = new FIELD<double>(MED_DRIVER, filename_rd, fieldname_celldouble_rd)); + + //Test read(int index) method + int IdDriver_rd = aField_1->addDriver(MED_DRIVER,filename_rd,fieldname_celldouble_rd); +//#ifdef ENABLE_FORCED_FAILURES + // (BUG) Cannot open file, but file exist + CPPUNIT_ASSERT_NO_THROW(aField_1->read(IdDriver_rd)); +//#endif + + //Test read(GENDRIVER & genDriver) method + //Creation a Driver + MED_FIELD_RDONLY_DRIVER21<int> *aMedRdFieldDriver21_1 = + new MED_FIELD_RDONLY_DRIVER21<int>(); + //Creation a Field + FIELD<int> *aField_2 = new FIELD<int>(); + aField_2->setName(fieldname_nodeint_rd); + aField_2->addDriver(*aMedRdFieldDriver21_1); + aField_2->read(*aMedRdFieldDriver21_1); + + /////////////////// + //Test Write Part// + /////////////////// + int IdDriver; + MESH *aMesh = new MESH(MED_DRIVER,filename_rd,meshname); + SUPPORT *aSupport = new SUPPORT(aMesh, "aSupport",MED_CELL); + FIELD<int> *aFieldSupport; +//#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_NO_THROW(aFieldSupport = + new FIELD<int>(aSupport, MED_DRIVER,filename_support_wr,fieldname_nodeint_rd)); + //(BUG) Can not open file + MED_FIELD_WRONLY_DRIVER21<int> * aFieldWrDriver21 = + new MED_FIELD_WRONLY_DRIVER21<int>(filename_support_wr,aFieldSupport); + aFieldWrDriver21->setFieldName(aFieldSupport->getName() + "_copy"); + CPPUNIT_ASSERT_NO_THROW(IdDriver= aFieldSupport->addDriver(*aFieldWrDriver21)); + CPPUNIT_ASSERT_NO_THROW(aFieldSupport->write(IdDriver)); + delete aFieldSupport; + delete aFieldWrDriver21; +//#endif + + //Create fileds + FIELD<double> * aField_3 = new FIELD<double>(); + MED_FIELD_RDONLY_DRIVER21<double> *aMedRdFieldDriver21_2 = + new MED_FIELD_RDONLY_DRIVER21<double>(filename_rd, aField_3); + aMedRdFieldDriver21_2->open(); + aMedRdFieldDriver21_2->setFieldName(fieldname_celldouble_rd); + aMedRdFieldDriver21_2->read(); + aMedRdFieldDriver21_2->close(); + + //Test write(int index) method + //Add drivers to FIELDs + int IdDriver1 = -1; + try + { + IdDriver1 = aField_3->addDriver(MED_DRIVER,filename_wr,fieldname_celldouble_wr); + } + catch(MEDEXCEPTION &e) + { + e.what(); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + //Trying call write(int index) method with incorrect index +//#ifdef ENABLE_FAULTS + CPPUNIT_ASSERT_THROW(aField_3->write(IdDriver1+1, fieldname_celldouble_wr),MEDEXCEPTION); + // => Segmentation fault +//#endif + + //Write field to file +//#ifdef ENABLE_FAULTS + try + { + aField_3->write(IdDriver1, fieldname_celldouble_wr); + // => Segmentation fault + } + catch(MEDEXCEPTION &e) + { + e.what(); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } +//#endif + + CPPUNIT_ASSERT_NO_THROW(aField_3->rmDriver(IdDriver1)); + + //Test write(const GENDRIVER &); + //Create a driver + MED_FIELD_WRONLY_DRIVER21<int> *aMedWrFieldDriver21 = + new MED_FIELD_WRONLY_DRIVER21<int>(); + aMedWrFieldDriver21->setFileName(filename_wr); + aField_2->setName(fieldname_nodeint_wr1); + //Add driver to a field + aField_2->addDriver(*aMedWrFieldDriver21); + + try + { + aField_2->write(*aMedWrFieldDriver21); + } + catch(MEDEXCEPTION &e) + { + e.what(); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test writeAppend(int index) method + //Create a vtk file + MESH * aMesh_1 = new MESH(); + MED_MESH_RDONLY_DRIVER22 *aMedMeshRdDriver22 = new MED_MESH_RDONLY_DRIVER22(filename22_rd, aMesh_1); + aMedMeshRdDriver22->open(); + aMedMeshRdDriver22->setMeshName(meshname); + aMedMeshRdDriver22->read(); + aMedMeshRdDriver22->close(); + VTK_MESH_DRIVER *aVtkDriver = new VTK_MESH_DRIVER(filenamevtk_wr, aMesh_1); + aVtkDriver->open(); + aVtkDriver->write(); + aVtkDriver->close(); + + //Create a field + FIELD<int> * aField_4 = new FIELD<int>(); + MED_FIELD_RDONLY_DRIVER22<int> *aMedRdFieldDriver22 = + new MED_FIELD_RDONLY_DRIVER22<int>(filename22_rd, aField_2); + aMedRdFieldDriver22->open(); + aMedRdFieldDriver22->setFieldName(fieldname_nodeint_rd); + aMedRdFieldDriver22->read(); + aMedRdFieldDriver22->close(); + + //Add Driver to a field + int IdDriver2; + try + { + IdDriver2 = aField_4->addDriver(VTK_DRIVER, filenamevtk_wr ,fieldname_nodeint_wr); + } + catch(MEDEXCEPTION &e) + { + e.what(); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } +//#ifdef ENABLE_FAULTS + //Trying call writeAppend() method with incorrect index + CPPUNIT_ASSERT_THROW(aField_4->writeAppend(IdDriver2+1,fieldname_nodeint_wr),MEDEXCEPTION); + // => Segmentation fault +//#endif + +//#ifdef ENABLE_FAULTS + // (BUG) => Segmentation fault + CPPUNIT_ASSERT_NO_THROW(aField_4->writeAppend(IdDriver2, fieldname_nodeint_wr)); +//#endif + + //Test writeAppend(const GENDRIVER &) method + aField_4->setName(fieldname_nodeint_wr1); + + //Add driver to a field +//#ifdef ENABLE_FAULTS + //Create a driver + VTK_FIELD_DRIVER<int> *aVtkFieldDriver = new VTK_FIELD_DRIVER<int>(filenamevtk_wr, aField_4); + CPPUNIT_ASSERT_NO_THROW(aField_4->addDriver(*aVtkFieldDriver)); + //(BUG) => Segmentation fault after addDriver(const GENDRIVER &) + CPPUNIT_ASSERT_NO_THROW(aField_4->writeAppend(*aVtkFieldDriver)); +//#endif + + + //Delete objects + delete aField_1; + delete aMedRdFieldDriver21_1; + delete aField_2; + delete aField_3; + delete aMedRdFieldDriver21_2; + delete aField_4; + delete aMedMeshRdDriver22; + delete aMedWrFieldDriver21; + delete aVtkDriver; + delete aMesh; + delete aMesh_1; + delete aMedRdFieldDriver22; + delete aSupport; +} + +void MEDMEMTest_testField() +{ + SUPPORT anEmptySupport; + //////////////////// + // TEST 1: FIELD_ // + //////////////////// + FIELD_ aField_; + + // check set/get methods + MED_EN::med_type_champ aValueType = MED_EN::MED_UNDEFINED_TYPE; + MED_EN::medModeSwitch anInterlace = MED_EN::MED_UNDEFINED_INTERLACE; + checkField_(&aField_, &anEmptySupport, aValueType, anInterlace); + + // copy constructor + // This fails (Segmentation fault) if not set: + // _componentsNames or _componentsDescriptions, or _MEDComponentsUnits + FIELD_ aField_copy1 (aField_); + compareField_(&aField_, &aField_copy1, /*isFIELD = */false, /*isValue = */false); + + // operator= +//#ifdef ENABLE_FAULTS + // (BUG) This fails (Segmentation fault) if not set: + // _componentsNames or _componentsDescriptions, or _componentsUnits, or _MEDComponentsUnits + // (BUG) Code duplication with copyGlobalInfo(), called from copy constructor + FIELD_ aField_copy2; + aField_copy2 = aField_; + compareField_(&aField_, &aField_copy2, /*isFIELD = */false, /*isValue = */false); +//#endif +//#ifdef ENABLE_FORCED_FAILURES +// CPPUNIT_FAIL("FIELD_::operator=() fails if _componentsUnits is not set"); +//#endif + + // following test is commented since method + // setTotalNumberOfElements() is removed. + /* + // construction on a given support + { + anEmptySupport.setTotalNumberOfElements(11); + // CASE1: + FIELD_ aField_case1 (&anEmptySupport, 10); + // CASE2: + FIELD_ aField_case2; + aField_case2.setSupport(&anEmptySupport); + aField_case2.setNumberOfComponents(10); + +#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_EQUAL_MESSAGE("No correspondance between CASE1 and CASE2", + aField_case1.getNumberOfValues(), + aField_case2.getNumberOfValues()); +#endif + } + */ + + //////////////////////// + // TEST 2: FIELD<int> // + //////////////////////// + FIELD<int> aFieldInt; + checkField(&aFieldInt, &anEmptySupport); + + //////////////////////////////////////// + // TEST 3: FIELD<double, NoInterlace> // + //////////////////////////////////////// + MESH * aMesh = MEDMEMTest_createTestMesh(); + const GROUP* aGroup = aMesh->getGroup(MED_EN::MED_FACE, 1); + + FIELD<double, NoInterlace> aFieldDouble; + checkField(&aFieldDouble, aGroup); + + ////////////////////////////////////////// + // TEST 4: FIELD<double, FullInterlace> // + ////////////////////////////////////////// + FIELD<double> * aFieldOnGroup1 = createFieldOnGroup<double>(aMesh, aGroup, "Linear", "N"); + FIELD<double> * aFieldOnGroup2 = createFieldOnGroup<double>(aMesh, aGroup, "Quadratic", "N**2"); + + int nbVals = aFieldOnGroup1->getNumberOfValues(); + CPPUNIT_ASSERT(nbVals); + + // numbers of elements in group, + // they are needed in method FIELD::setValueIJ() + const int *anElems = aGroup->getnumber()->getValue(); + double eucl1 = 0., eucl2 = 0.; + + for (int i = 1; i <= nbVals; i++) { + aFieldOnGroup1->setValueIJ(anElems[i-1], 1, (double)i); + aFieldOnGroup1->setValueIJ(anElems[i-1], 2, (double)(-i)); + + aFieldOnGroup2->setValueIJ(anElems[i-1], 1, (double)i*i); + aFieldOnGroup2->setValueIJ(anElems[i-1], 2, (double)(-i*i)); + + eucl1 += 2. * i * i; + eucl2 += 2. * i * i * i * i; + } + + // out of bound (inexisting 33-th component of last element) + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->setValueIJ(anElems[nbVals-1], 33, 10.), MEDEXCEPTION); + + // normMax + CPPUNIT_ASSERT_DOUBLES_EQUAL(nbVals, aFieldOnGroup1->normMax(), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(nbVals*nbVals, aFieldOnGroup2->normMax(), 0.000001); + + // norm2 + CPPUNIT_ASSERT_DOUBLES_EQUAL(std::sqrt(eucl1), aFieldOnGroup1->norm2(), 0.000001); // 10.4881 + CPPUNIT_ASSERT_DOUBLES_EQUAL(std::sqrt(eucl2), aFieldOnGroup2->norm2(), 0.000001); // 44.2493 + + // check getXXX methods + CPPUNIT_ASSERT(!aFieldOnGroup1->getGaussPresence()); + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getArrayGauss(), MEDEXCEPTION); + MEDMEM_ArrayInterface<double, FullInterlace,NoGauss>::Array * anArrayNoGauss = + aFieldOnGroup1->getArrayNoGauss(); + + MEDMEM_Array_ * aMEDMEM_Array_ = aFieldOnGroup1->getArray(); + MEDMEM_ArrayInterface<double, FullInterlace,NoGauss>::Array * aMEDMEM_Array_conv = + static_cast<MEDMEM_ArrayInterface<double, FullInterlace,NoGauss>::Array *>(aMEDMEM_Array_); + + const double * aValues = aFieldOnGroup1->getValue(); + + // out of range + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getColumn(3), MEDEXCEPTION); + // cannot get column in FullInterlace + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getColumn(1), MEDEXCEPTION); + + for (int i = 1; i <= nbVals; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , aFieldOnGroup1->getValueIJK(anElems[i-1], 1, 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), aFieldOnGroup1->getValueIJK(anElems[i-1], 2, 1), 0.000001); + + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , aValues[(i-1)*2 + 0], 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), aValues[(i-1)*2 + 1], 0.000001); + + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , anArrayNoGauss->getIJ(i, 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), anArrayNoGauss->getIJ(i, 2), 0.000001); + + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , aMEDMEM_Array_conv->getIJ(i, 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), aMEDMEM_Array_conv->getIJ(i, 2), 0.000001); + + const double* row_i = aFieldOnGroup1->getRow(anElems[i-1]); + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , row_i[0], 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), row_i[1], 0.000001); + + double vals_i [2]; + aFieldOnGroup1->getValueOnElement(anElems[i-1], vals_i); + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i , vals_i[0], 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)(-i), vals_i[1], 0.000001); + } + + // modify all values of aFieldOnGroup2 by formula a*x + b (a = 2, b = 3) + aFieldOnGroup2->applyLin(2., 3.); + for (int i = 1; i <= nbVals; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(3. + 2.*i*i, aFieldOnGroup2->getValueIJ(anElems[i-1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3. - 2.*i*i, aFieldOnGroup2->getValueIJ(anElems[i-1], 2), 0.000001); + } + + // apply function plus13() to aFieldOnGroup1 + aFieldOnGroup1->applyFunc<plus13>(); + for (int i = 1; i <= nbVals; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); + } + + // scalarProduct + FIELD<double, FullInterlace> * aScalarProduct = + FIELD<double, FullInterlace>::scalarProduct(*aFieldOnGroup1, *aFieldOnGroup2, /*deepCheck = */true); + CPPUNIT_ASSERT_EQUAL(nbVals, aScalarProduct->getNumberOfValues()); + CPPUNIT_ASSERT_EQUAL(1, aScalarProduct->getNumberOfComponents()); + for (int i = 1; i <= nbVals; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(78. + 4.*i*i*i, //(3. + 2.*i*i)*(13 + i) + (3. - 2.*i*i)*(13 - i) + aScalarProduct->getValueIJ(anElems[i-1], 1), 0.000001); + } + + // fillFromAnalytic + aFieldOnGroup2->fillFromAnalytic(proj2d); + + double bary [3]; + double outp [2]; + const SUPPORT * aSupp = aFieldOnGroup2->getSupport(); + FIELD<double,FullInterlace> * barycenter = aMesh->getBarycenter(aSupp); + for (int i = 1; i <= nbVals; i++) { + bary[0] = barycenter->getValueIJ(anElems[i-1], 1); + bary[1] = barycenter->getValueIJ(anElems[i-1], 2); + bary[2] = barycenter->getValueIJ(anElems[i-1], 3); + + proj2d(bary, outp); + + //cout << "barycenter (" << bary[0] << ", " << bary[1] << ", " << bary[2] << ")" << endl; + //cout << "proj2d (" << outp[0] << ", " << outp[1] << ")" << endl; + + //bary (-0.666667, 0.666667, 0.666667) -> outp ( 0.902369, 0.902369) + //bary ( 0.666667, -0.666667, 0.666667) -> outp (-0.902369, 0.430964) + //bary ( 0. , 0. , 2. ) -> outp ( 0. , 2. ) + //bary ( 0. , 0. , 3. ) -> outp ( 0. , 3. ) + //bary (-1. , 0. , 2.5 ) -> outp ( 0.353553, 2.85355 ) + +//#ifdef ENABLE_FORCED_FAILURES + // (BUG) in FIELD::fillFromAnalytic() in case of support, different from nodes: + // barycenterField in FullInterlace, but values extracted like from NoInterlace + CPPUNIT_ASSERT_DOUBLES_EQUAL(outp[0], aFieldOnGroup2->getValueIJ(anElems[i-1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(outp[1], aFieldOnGroup2->getValueIJ(anElems[i-1], 2), 0.000001); +//#endif + + // currently it gives values, that are wrong: + //aFieldOnGroup2 row1 ( 0.902369, 0.235702) + //aFieldOnGroup2 row2 (-0.235702, 2.7643 ) + //aFieldOnGroup2 row3 (-0.235702, -1.2357 ) + //aFieldOnGroup2 row4 ( 1.7643 , -0.235702) + //aFieldOnGroup2 row5 ( 0.235702, 2.7357 ) + } + + // info about support (Group1) + CPPUNIT_ASSERT(!aFieldOnGroup1->isOnAllElements()); // because we build Group1 so + int nbTypes = aFieldOnGroup1->getNumberOfGeometricTypes(); + //CPPUNIT_ASSERT(nbTypes); + CPPUNIT_ASSERT_EQUAL(2, nbTypes); + const int * nbElemsInEachType = aFieldOnGroup1->getNumberOfElements(); + const MED_EN::medGeometryElement * aGeomTypes = aFieldOnGroup1->getGeometricTypes(); + + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_TRIA3, aGeomTypes[0]); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_QUAD4, aGeomTypes[1]); + + // GAUSS + + // now we have no gauss localization in aFieldOnGroup1 + CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA3)); + CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_QUAD4)); + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA6), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(), MEDEXCEPTION); + + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalization(MED_EN::MED_TRIA3), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_TRIA3), MEDEXCEPTION); + + CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNbGaussI(anElems[0])); + + // set a gauss localization into aFieldOnGroup1 + double cooRef[6] = {1.,1., 2.,4., 3.,9.}; // xy xy xy + double cooGauss[10] = {7.,7., 6.,6., 5.,5., 4.,3., 2.,1.}; // x1,y1 x2,y2 x3,y3 x4,y4 x5,y5 + double wg[5] = {1., 2., 3., 4., 5.}; + GAUSS_LOCALIZATION<> gl1 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef, cooGauss, wg); + + aFieldOnGroup1->setGaussLocalization(MED_EN::MED_TRIA3, gl1); + + // now we have a gauss localization for MED_TRIA3 type + CPPUNIT_ASSERT_EQUAL(5, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA3)); + CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_QUAD4)); + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(MED_EN::MED_TRIA6), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getNumberOfGaussPoints(), MEDEXCEPTION); + + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalization(MED_EN::MED_QUAD4), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_QUAD4), MEDEXCEPTION); + + GAUSS_LOCALIZATION<> gl1Back = aFieldOnGroup1->getGaussLocalization(MED_EN::MED_TRIA3); + const GAUSS_LOCALIZATION<> * gl1BackPtr = aFieldOnGroup1->getGaussLocalizationPtr(MED_EN::MED_TRIA3); + + CPPUNIT_ASSERT(gl1 == gl1Back); + CPPUNIT_ASSERT(gl1 == *gl1BackPtr); + + CPPUNIT_ASSERT_EQUAL(1, aFieldOnGroup1->getNbGaussI(anElems[0])); + + // sub-support of Group1 on one (first) geometric type + SUPPORT * aSubSupport1 = new SUPPORT(aMesh, "Sub-Support 1 of Group1", MED_EN::MED_FACE); + aSubSupport1->setAll(false); + + int nbTypes1 = 1; + int nbElemsInEachType1[1]; + nbElemsInEachType1[0] = nbElemsInEachType[0]; + int nbElems1 = nbElemsInEachType1[0]; + MED_EN::medGeometryElement aGeomTypes1[1]; + aGeomTypes1[0] = aGeomTypes[0]; + int * anElems1 = new int[nbElems1]; + for (int i = 0; i < nbElems1; i++) { + anElems1[i] = anElems[i]; + } + + aSubSupport1->setpartial("Support for sub-field 1 on one type of elements", + nbTypes1, nbElems1, aGeomTypes1, nbElemsInEachType1, anElems1); + + //cout << "aSubSupport1:" << endl; + //cout << *aSubSupport1 << endl; + + // extract sub-field on aSubSupport1 + FIELD<double, FullInterlace> * aSubField1 = aFieldOnGroup1->extract(aSubSupport1); + CPPUNIT_ASSERT_EQUAL(nbElems1 * /*NumberOfComponents = */2, aSubField1->getValueLength()); + + // aSubField1: + // elt\comp | 1 | 2 + //-------------------- + // 1 | 14 | 12 + // 2 | 15 | 11 + + // check normL2() and normL1() + FIELD<double>* anAreaField = aMesh->getArea(aSubSupport1); + double area1 = anAreaField->getValueIJ(anElems1[0], 1); + double area2 = anAreaField->getValueIJ(anElems1[1], 1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.44949, area1, 0.00001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.44949, area2, 0.00001); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(210.5, aSubField1->normL2(1), 0.00001); // (14*14 + 15*15)/2 +//#ifdef ENABLE_FORCED_FAILURES + // (BUG) FIELD::normL2(int component, const FIELD * p_field_volume): + // component is not taken into account + CPPUNIT_ASSERT_DOUBLES_EQUAL(132.5, aSubField1->normL2(2), 0.00001); // (12*12 + 11*11)/2 +//#endif + CPPUNIT_ASSERT_DOUBLES_EQUAL(343.0, aSubField1->normL2() , 0.00001); // 210.5 + 132.5 + + CPPUNIT_ASSERT_DOUBLES_EQUAL(14.5, aSubField1->normL1(1), 0.00001); // (14 + 15)/2 + CPPUNIT_ASSERT_DOUBLES_EQUAL(11.5, aSubField1->normL1(2), 0.00001); // (12 + 11)/2 + CPPUNIT_ASSERT_DOUBLES_EQUAL(26.0, aSubField1->normL1() , 0.00001); // 14.5 + 11.5 + + double aNewArea [2] = {1., 0.}; // only first element will be taken into account + anAreaField->setValue(aNewArea); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(196.0, aSubField1->normL2(1, anAreaField), 0.00001); // 14*14/1 +//#ifdef ENABLE_FORCED_FAILURES + // (BUG) FIELD::normL2(int component, const FIELD * p_field_volume): + // component is not taken into account + CPPUNIT_ASSERT_DOUBLES_EQUAL(144.0, aSubField1->normL2(2, anAreaField), 0.00001); // 12*12/1 +//#endif + CPPUNIT_ASSERT_DOUBLES_EQUAL(340.0, aSubField1->normL2(anAreaField) , 0.00001); // 196 + 144 + + CPPUNIT_ASSERT_DOUBLES_EQUAL(14.0, aSubField1->normL1(1, anAreaField), 0.00001); // 14/1 + CPPUNIT_ASSERT_DOUBLES_EQUAL(12.0, aSubField1->normL1(2, anAreaField), 0.00001); // 12/1 + CPPUNIT_ASSERT_DOUBLES_EQUAL(26.0, aSubField1->normL1(anAreaField) , 0.00001); // 14 + 12 + + // applyPow + aSubField1->applyPow(2.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(196., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); // 14*14 + CPPUNIT_ASSERT_DOUBLES_EQUAL(144., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); // 12*12 + CPPUNIT_ASSERT_DOUBLES_EQUAL(225., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); // 15*15 + CPPUNIT_ASSERT_DOUBLES_EQUAL(121., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); // 11*11 + + // setArray (NoGauss) + MEDMEM_ArrayInterface<double,FullInterlace,NoGauss>::Array * aNewArrayNoGauss = + new MEDMEM_ArrayInterface<double,FullInterlace,NoGauss>::Array(/*dim*/2, /*nbelem*/2); + aNewArrayNoGauss->setIJ(1, 1, 4.); + aNewArrayNoGauss->setIJ(1, 2, 2.); + aNewArrayNoGauss->setIJ(2, 1, 5.); + aNewArrayNoGauss->setIJ(2, 2, 1.); + aSubField1->setArray(aNewArrayNoGauss); + // no need to delete aNewArrayNoGauss, because it will be deleted + // in destructor or in deallocValue() method of aSubField1 + + CPPUNIT_ASSERT_DOUBLES_EQUAL(4., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); + + // setRow + double row[2] = {-1., -3.}; + aSubField1->setRow(anElems1[0], row); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-3., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 5., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); + // out of range + CPPUNIT_ASSERT_THROW(aSubField1->setRow(3, row), MEDEXCEPTION); + + // setColumn + double col[2] = {-7., -9.}; + aSubField1->setColumn(1, col); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-7., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-3., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); +//#ifdef ENABLE_FORCED_FAILURES + // (BUG) in MEDMEM_Array::setColumn() + CPPUNIT_ASSERT_DOUBLES_EQUAL(-9., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); +//#endif + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); + // out of range + CPPUNIT_ASSERT_THROW(aSubField1->setColumn(3, col), MEDEXCEPTION); + + // setArray (Gauss) + { + int nbelgeoc[2] = {1, 3}; // 3 - 1 = two elements for the first (and the only) type + int nbgaussgeo[2] = {-1, 1}; // one gauss point per each element + MEDMEM_ArrayInterface<double,FullInterlace,Gauss>::Array * aNewArrayGauss = + new MEDMEM_ArrayInterface<double,FullInterlace,Gauss>::Array + (/*dim*/2, /*nbelem*/2, /*nbtypegeo*/1, /*nbelgeoc*/nbelgeoc, /*nbgaussgeo*/nbgaussgeo); + +//#ifdef ENABLE_FAULTS + aNewArrayGauss->setIJ(1, 1, -4.); + aNewArrayGauss->setIJ(1, 2, -2.); + aNewArrayGauss->setIJ(2, 1, -5.); + aNewArrayGauss->setIJ(2, 2, -1.); +//#endif +//#ifdef ENABLE_FORCED_FAILURES + // ? (BUG) in FullInterlaceGaussPolicy::getIndex(int i,int j) + // FullInterlaceGaussPolicy::getIndex(2,2) returns 4!!! +// CPPUNIT_FAIL("? Bug in FullInterlaceGaussPolicy::getIndex(int i,int j) ?"); +//#endif + + aNewArrayGauss->setIJK(1, 1, 1, -4.); + aNewArrayGauss->setIJK(1, 2, 1, -2.); + aNewArrayGauss->setIJK(2, 1, 1, -5.); + aNewArrayGauss->setIJK(2, 2, 1, -1.); + + aSubField1->setArray(aNewArrayGauss); + // no need to delete aNewArrayGauss, because it will be deleted + // in destructor or in deallocValue() method of aSubField1 + +//#ifdef ENABLE_FAULTS + CPPUNIT_ASSERT_DOUBLES_EQUAL(-4., aSubField1->getValueIJ(anElems1[0], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-2., aSubField1->getValueIJ(anElems1[0], 2), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-5., aSubField1->getValueIJ(anElems1[1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., aSubField1->getValueIJ(anElems1[1], 2), 0.000001); +//#endif +//#ifdef ENABLE_FORCED_FAILURES + // ? (BUG) in FullInterlaceGaussPolicy::getIndex(int i,int j) + // Must be : return _G[i-1]-1 + (j-1); + // Instead of: return _G[i-1]-1 + (j-1)*_dim; +// CPPUNIT_FAIL("? Bug in FullInterlaceGaussPolicy::getIndex(int i,int j) ?"); +//#endif + + CPPUNIT_ASSERT_DOUBLES_EQUAL(-4., aSubField1->getValueIJK(anElems1[0], 1, 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-2., aSubField1->getValueIJK(anElems1[0], 2, 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-5., aSubField1->getValueIJK(anElems1[1], 1, 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., aSubField1->getValueIJK(anElems1[1], 2, 1), 0.000001); + } + + // alloc/dealloc; compatibility of new size with support + try { + aSubField1->deallocValue(); + aSubField1->allocValue(/*NumberOfComponents*/2, /*LengthValue*/5); +//#ifdef ENABLE_FAULTS + // (BUG) No compatibility between Support and allocated value + aSubField1->normL1(); +//#endif +//#ifdef ENABLE_FORCED_FAILURES +// CPPUNIT_FAIL("Error: no compatibility between Support and allocated value"); +//#endif + } + catch (MEDEXCEPTION & ex) { + // normal behaviour + } + catch (...) { + CPPUNIT_FAIL("Error: no compatibility between Support and allocated value"); + } + + // check that aFieldOnGroup1 is not changed after aSubField1 modifications + for (int i = 1; i <= nbVals; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); + } + + // reset aFieldOnGroup2 values for simple control of operators results + for (int i = 1; i <= nbVals; i++) { + aFieldOnGroup2->setValueIJ(anElems[i-1], 1, i*i); + aFieldOnGroup2->setValueIJ(anElems[i-1], 2, -i*i); + } + + int len = aFieldOnGroup1->getValueLength(); + const double * val1 = aFieldOnGroup1->getValue(); + const double * val2 = aFieldOnGroup2->getValue(); + const double * val_res; + + // operators and add, sub, mul, div + + // + + FIELD<double> aSum = *aFieldOnGroup1 + *aFieldOnGroup2; + aSum.setName(aFieldOnGroup1->getName()); + aSum.setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, &aSum, true, true); + val_res = aSum.getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val2[i], val_res[i], 0.000001); + } + + // - + FIELD<double> aDifference = *aFieldOnGroup1 - *aFieldOnGroup2; + aDifference.setName(aFieldOnGroup1->getName()); + aDifference.setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, &aDifference, true, true); + val_res = aDifference.getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] - val2[i], val_res[i], 0.000001); + } + + // - (unary) + FIELD<double> aNegative = - *aFieldOnGroup1; + aNegative.setName(aFieldOnGroup1->getName()); + aNegative.setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, &aNegative, true, true); + val_res = aNegative.getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(- val1[i], val_res[i], 0.000001); + } + + // * + FIELD<double> aProduct = (*aFieldOnGroup1) * (*aFieldOnGroup2); + aProduct.setName(aFieldOnGroup1->getName()); + aProduct.setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, &aProduct, true, true); + val_res = aProduct.getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] * val2[i], val_res[i], 0.000001); + } + + // / + FIELD<double> aQuotient = *aFieldOnGroup1 / *aFieldOnGroup2; + aQuotient.setName(aFieldOnGroup1->getName()); + aQuotient.setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, &aQuotient, true, true); + val_res = aQuotient.getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] / val2[i], val_res[i], 0.000001); + } + + double val22 = aFieldOnGroup2->getValueIJ(anElems[2], 2); + aFieldOnGroup2->setValueIJ(anElems[2], 2, 0.); + + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 / *aFieldOnGroup2, MEDEXCEPTION); +//#ifdef ENABLE_FORCED_FAILURES + // (BUG) is it up to user to control validity of data to avoid division on zero? + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 /= *aFieldOnGroup2, MEDEXCEPTION); +//#endif + CPPUNIT_ASSERT_THROW(FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); + + // restore value + aFieldOnGroup2->setValueIJ(anElems[2], 2, val22); + + // restore values + for (int i = 1; i <= nbVals; i++) { + aFieldOnGroup1->setValueIJ(anElems[i-1], 1, 13 + i); + aFieldOnGroup1->setValueIJ(anElems[i-1], 2, 13 - i); + } + + // static methods + FIELD<double> * aPtr; + + // add + aPtr = FIELD<double>::add(*aFieldOnGroup1, *aFieldOnGroup2); + aPtr->setName(aFieldOnGroup1->getName()); + aPtr->setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, aPtr, true, true); + val_res = aPtr->getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val2[i], val_res[i], 0.000001); + } + delete aPtr; + + // sub + aPtr = FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup2); + aPtr->setName(aFieldOnGroup1->getName()); + aPtr->setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, aPtr, true, true); + val_res = aPtr->getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] - val2[i], val_res[i], 0.000001); + } + delete aPtr; + + // mul + aPtr = FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup2); + aPtr->setName(aFieldOnGroup1->getName()); + aPtr->setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, aPtr, true, true); + val_res = aPtr->getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] * val2[i], val_res[i], 0.000001); + } + delete aPtr; + + // div + aPtr = FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2); + aPtr->setName(aFieldOnGroup1->getName()); + aPtr->setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, aPtr, true, true); + val_res = aPtr->getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] / val2[i], val_res[i], 0.000001); + } + delete aPtr; + + // addDeep + aPtr = FIELD<double>::addDeep(*aFieldOnGroup1, *aFieldOnGroup2); + aPtr->setName(aFieldOnGroup1->getName()); + aPtr->setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, aPtr, true, true); + val_res = aPtr->getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val2[i], val_res[i], 0.000001); + } + delete aPtr; + + // subDeep + aPtr = FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup2); + aPtr->setName(aFieldOnGroup1->getName()); + aPtr->setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, aPtr, true, true); + val_res = aPtr->getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] - val2[i], val_res[i], 0.000001); + } + delete aPtr; + + // mulDeep + aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup2); + aPtr->setName(aFieldOnGroup1->getName()); + aPtr->setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, aPtr, true, true); + val_res = aPtr->getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] * val2[i], val_res[i], 0.000001); + } + delete aPtr; + + // divDeep + aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2); + aPtr->setName(aFieldOnGroup1->getName()); + aPtr->setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, aPtr, true, true); + val_res = aPtr->getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] / val2[i], val_res[i], 0.000001); + } + delete aPtr; + + // += + *aFieldOnGroup1 += *aFieldOnGroup2; + for (int i = 1; i <= nbVals; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i + i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i - i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); + } + + // -= + *aFieldOnGroup1 -= *aFieldOnGroup2; + for (int i = 1; i <= nbVals; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); + } + + // *= + *aFieldOnGroup1 *= *aFieldOnGroup2; + for (int i = 1; i <= nbVals; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL( (13 + i)*i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-(13 - i)*i*i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); + } + + // /= + *aFieldOnGroup1 /= *aFieldOnGroup2; + for (int i = 1; i <= nbVals; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 + i, aFieldOnGroup1->getValueIJ(anElems[i-1], 1), 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(13 - i, aFieldOnGroup1->getValueIJ(anElems[i-1], 2), 0.000001); + } + + // check case of different operands: support + MESH * aMeshOneMore = MEDMEMTest_createTestMesh(); + const GROUP* aGroupOneMore = aMeshOneMore->getGroup(MED_EN::MED_FACE, 1); + FIELD<double> * aFieldOnGroup3 = + createFieldOnGroup<double>(aMeshOneMore, aGroupOneMore, "Test_Diff_Mesh", "test"); + for (int i = 1; i <= nbVals; i++) { + aFieldOnGroup3->setValueIJ(anElems[i-1], 1, 2*i); + aFieldOnGroup3->setValueIJ(anElems[i-1], 2, 3*i); + } + const double * val3 = aFieldOnGroup3->getValue(); + + //CPPUNIT_ASSERT_NO_THROW(); + try { + aPtr = FIELD<double>::addDeep(*aFieldOnGroup1, *aFieldOnGroup3); + aPtr->setName(aFieldOnGroup1->getName()); + aPtr->setDescription(aFieldOnGroup1->getDescription()); + compareField_(aFieldOnGroup1, aPtr, true, true); + val_res = aPtr->getValue(); + for (int i = 0; i < len; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(val1[i] + val3[i], val_res[i], 0.000001); + } + delete aPtr; + + aPtr = FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup3); + delete aPtr; + aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup3); + delete aPtr; + aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup3); + delete aPtr; + } + catch (MEDEXCEPTION & ex) { + CPPUNIT_FAIL(ex.what()); + } + catch (...) { + CPPUNIT_FAIL("Unknown exception in FIELD::xxxDeep()"); + } + + CPPUNIT_ASSERT_THROW(FIELD<double>::add(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup3), MEDEXCEPTION); + + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 + *aFieldOnGroup3, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 - *aFieldOnGroup3, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 * *aFieldOnGroup3, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 / *aFieldOnGroup3, MEDEXCEPTION); + + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 += *aFieldOnGroup3, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 -= *aFieldOnGroup3, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 *= *aFieldOnGroup3, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 /= *aFieldOnGroup3, MEDEXCEPTION); + + // check case of different operands: MEDComponentsUnits + aFieldOnGroup1->setMEDComponentUnit(1, "unit3"); + + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 + *aFieldOnGroup2, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 - *aFieldOnGroup2, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 += *aFieldOnGroup2, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(*aFieldOnGroup1 -= *aFieldOnGroup2, MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(FIELD<double>::add(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(FIELD<double>::sub(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(FIELD<double>::addDeep(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(FIELD<double>::subDeep(*aFieldOnGroup1, *aFieldOnGroup2), MEDEXCEPTION); + + //CPPUNIT_ASSERT_NO_THROW(); + try { + aPtr = FIELD<double>::mul(*aFieldOnGroup1, *aFieldOnGroup2); + delete aPtr; + aPtr = FIELD<double>::div(*aFieldOnGroup1, *aFieldOnGroup2); + delete aPtr; + aPtr = FIELD<double>::mulDeep(*aFieldOnGroup1, *aFieldOnGroup2); + delete aPtr; + aPtr = FIELD<double>::divDeep(*aFieldOnGroup1, *aFieldOnGroup2); + delete aPtr; + + *aFieldOnGroup1 *= *aFieldOnGroup2; + *aFieldOnGroup1 /= *aFieldOnGroup2; + + FIELD<double> aPr = *aFieldOnGroup1 * *aFieldOnGroup2; + FIELD<double> aQu = *aFieldOnGroup1 / *aFieldOnGroup2; + } + catch (MEDEXCEPTION & ex) { + CPPUNIT_FAIL(ex.what()); + } + catch (...) { + CPPUNIT_FAIL("Unknown exception"); + } + + // restore MED units + aFieldOnGroup1->setMEDComponentUnit(1, "unit1"); + + // check case of different operands: numberOfComponents +//#ifdef ENABLE_FAULTS + // (BUG) Cannot allocate value of higher dimension because of _componentsTypes reinitialization + // Must be MEDEXCEPTION instead. And on attempt to change nb.components must be the same behaviour. + aFieldOnGroup1->deallocValue(); + CPPUNIT_ASSERT_THROW(aFieldOnGroup1->allocValue(/*dim*/5), MEDEXCEPTION); +//#endif + + delete aSubSupport1; + delete [] anElems1; + + delete aScalarProduct; + delete aSubField1; + delete anAreaField; + delete barycenter; + delete aFieldOnGroup1; + delete aFieldOnGroup2; + delete aFieldOnGroup3; + + delete aMesh; + delete aMeshOneMore; + + ///////////////////// + // TEST 5: Drivers // + ///////////////////// + testDrivers(); +} + +int main (int argc, char** argv) +{ + MEDMEMTest_testField(); +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_Formulae.cxx b/src/MEDMEMCppTest/MEDMEMTest_Formulae.cxx new file mode 100644 index 000000000..49531dac3 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Formulae.cxx @@ -0,0 +1,622 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "VolSurfFormulae.hxx" +#include "MEDMEM_STRING.hxx" +#include "MEDMEM_Exception.hxx" + +#include <iostream> +#include <sstream> +#include <cmath> +#include <cfloat> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; + +// #17: MEDMEM_Formulae.hxx } MEDMEMTest_Formulae.cxx + +/*! + * Check methods (13), defined in MEDMEM_Formulae.hxx: + * + * (+) inline void CalculateBarycenterDyn(const double **pts, int nbPts, int dim, double *bary); + * + * (+) inline double CalculateAreaForPolyg(const double **coords, int nbOfPtsInPolygs, int spaceDim); + * (+) inline double CalculateAreaForTria(const double *p1, const double *p2, + * const double *p3, int spaceDim); + * (+) inline double CalculateAreaForQuad(const double *p1, const double *p2, + * const double *p3, const double *p4, int spaceDim); + * + * (+) inline void CalculateNormalForTria(const double *p1, const double *p2, + * const double *p3, double *normal); + * (+) inline void CalculateNormalForQuad(const double *p1, const double *p2, + * const double *p3, const double *p4, double *normal); + * (+) inline void CalculateNormalForPolyg(const double **coords, int nbOfPtsInPolygs, double *normal); + * + * (+) inline double CalculateVolumeForTetra(const double *p1, const double *p2, + * const double *p3, const double *p4); + * (+) inline double CalculateVolumeForPyra(const double *p1, const double *p2, + * const double *p3, const double *p4, const double *p5); + * (+) inline double CalculateVolumeForPenta(const double *p1, const double *p2, const double *p3, + * const double *p4, const double *p5, const double *p6); + * (+) inline double CalculateVolumeForHexa(const double *pt1, const double *pt2, const double *pt3, + * const double *pt4, const double *pt5, const double *pt6, + * const double *pt7, const double *pt8); + * (+) inline double CalculateVolumeForPolyh(const double ***pts, const int *nbOfNodesPerFaces, + * int nbOfFaces, const double *bary); + * + * (+) template<int N> inline double addComponentsOfVec(const double **pts, int rk); + * (+) template<> inline double addComponentsOfVec<1>(const double **pts, int rk); + * + * (+) template<int N, int DIM> inline void CalculateBarycenter(const double **pts, double *bary); + * (-) template<> inline void CalculateBarycenter<2,0>(const double **pts, double *bary); + * (-) template<> inline void CalculateBarycenter<3,0>(const double **pts, double *bary); + * (-) template<> inline void CalculateBarycenter<4,0>(const double **pts, double *bary); + * (-) template<> inline void CalculateBarycenter<5,0>(const double **pts, double *bary); + * (-) template<> inline void CalculateBarycenter<6,0>(const double **pts, double *bary); + * (-) template<> inline void CalculateBarycenter<7,0>(const double **pts, double *bary); + * (-) template<> inline void CalculateBarycenter<8,0>(const double **pts, double *bary); + */ +void MEDMEMTest::testFormulae() +{ + double val; + + // ^y + // | + // *3 + // 4 | + // .*. . . . . . *6,7 + // | + // . .8* . . . . . + // | 5 2,9 + // . . . .*. * . . + // 1| + // -.-.-*-.-.-.-.-.-->x + // | + + // S_12634 = (3 + (3+4.8)*2 + 4.8 + 1.5*4)/2 = 1.5 + 7.8 + 2.4 + 3 = 14.7 + // S_143652 = S_14362 - S_625 = 14.7 - 2 * 1.5 / 2 = 13.2 + + double xy1[2] = { 0.0, 0.0}; + double xy2[2] = { 3.0, 1.0}; + double xy3[2] = { 0.0, 4.0}; + double xy4[2] = {-1.5, 3.0}; + double xy5[2] = { 1.5, 1.0}; + double xy6[2] = { 4.8, 3.0}; + + double xyz1[3] = { 0.0, 0.0, 0.0}; + double xyz2[3] = { 3.0, 1.0, 4.0}; // cos(alpha) = 3/5 + double xyz3[3] = { 0.0, 4.0, 0.0}; + double xyz4[3] = {-1.5, 3.0, -2.0}; // z4 = z2 * x4 / x2 = - 4 * 1.5 / 3 + double xyz5[3] = { 1.5, 1.0, 2.0}; // z5 = z2 * x5 / x2 = 4 * 1.5 / 3 + double xyz6[3] = { 4.8, 3.0, 6.4}; // z6 = z2 * x6 / x2 = 4 * 4.8 / 3 + double xyz7[3] = { 4.8, 3.0, 0.0}; + double xyz8[3] = { 0.0, 2.0, 0.0}; + double xyz9[3] = { 3.0, 1.0, 0.0}; + + // S_3d = S_2d * 5.0 / 3.0 + + /////////////////////////// + // CalculateAreaForPolyg // + /////////////////////////// + { + // 2D: Convex polygon + const double * poly_2d_cc[5] = {xy1, xy2, xy6, xy3, xy4}; + const double * poly_2d_cw[5] = {xy1, xy4, xy3, xy6, xy2}; + + // counter-clockwise + val = INTERP_KERNEL::calculateAreaForPolyg(poly_2d_cc, /*nbOfPtsInPolygs*/5, /*dim*/2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-14.7, val, 0.000001); + + // clockwise + val = INTERP_KERNEL::calculateAreaForPolyg(poly_2d_cw, /*nbOfPtsInPolygs*/5, /*dim*/2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(14.7, val, 0.000001); + + // 2D: Non-convex polygon + const double * poly_2d_nc[6] = {xy1, xy4, xy3, xy6, xy5, xy2}; + val = INTERP_KERNEL::calculateAreaForPolyg(poly_2d_nc, /*nbOfPtsInPolygs*/6, /*dim*/2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(13.2, val, 0.000001); + + // 3D: Convex polygon + const double * poly_3d_cc[5] = {xyz1, xyz2, xyz6, xyz3, xyz4}; + + val = INTERP_KERNEL::calculateAreaForPolyg(poly_3d_cc, /*nbOfPtsInPolygs*/5, /*dim*/3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(24.5, val, 0.000001); + + // 3D: Non-convex polygon + const double * poly_3d_nc[6] = {xyz1, xyz4, xyz3, xyz6, xyz5, xyz2}; + val = INTERP_KERNEL::calculateAreaForPolyg(poly_3d_nc, /*nbOfPtsInPolygs*/6, /*dim*/3); + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) Wrong area calculation for non-convex polygons in 3D space, + // because area of triangle is always positive + // It's a spec + //CPPUNIT_ASSERT_DOUBLES_EQUAL(22.0, val, 0.000001); + CPPUNIT_ASSERT( abs(22.0-val)>0.000001 ); + //#endif + } + + ////////////////////////// + // CalculateAreaForTria // + ////////////////////////// + { + // 2D: counter-clockwise + val = INTERP_KERNEL::calculateAreaForTria(xy1, xy2, xy3, /*dim*/2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.0, val, 0.000001); + + // 2D: clockwise + val = INTERP_KERNEL::calculateAreaForTria(xy2, xy1, xy3, /*dim*/2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6.0, val, 0.000001); + + // 3D + val = INTERP_KERNEL::calculateAreaForTria(xyz1, xyz2, xyz3, /*dim*/3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(10.0, val, 0.000001); + + // Invalid (three points on one line) + val = INTERP_KERNEL::calculateAreaForTria(xyz1, xyz8, xyz3, /*dim*/3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, val, 0.000001); + } + + ////////////////////////// + // CalculateAreaForQuad // + ////////////////////////// + { + // 2D: Convex quadrangle + + // counter-clockwise + val = INTERP_KERNEL::calculateAreaForQuad(xy1, xy2, xy3, xy4, /*dim*/2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-9.0, val, 0.000001); + + // clockwise + val = INTERP_KERNEL::calculateAreaForQuad(xy2, xy1, xy4, xy3, /*dim*/2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0, val, 0.000001); + + // wrong order + CPPUNIT_ASSERT_NO_THROW(INTERP_KERNEL::calculateAreaForQuad(xy2, xy1, xy3, xy4, /*dim*/2)); + + // 2D: Non-convex quadrangle + + // counter-clockwise + val = INTERP_KERNEL::calculateAreaForQuad(xy1, xy2, xy3, xy5, /*dim*/2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.0, val, 0.000001); + + // clockwise + val = INTERP_KERNEL::calculateAreaForQuad(xy1, xy5, xy3, xy2, /*dim*/2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0, val, 0.000001); + + // 3D: Convex quadrangle + + // good order + val = INTERP_KERNEL::calculateAreaForQuad(xyz1, xyz2, xyz3, xyz4, /*dim*/3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.0, val, 0.000001); + + // wrong order + CPPUNIT_ASSERT_NO_THROW(INTERP_KERNEL::calculateAreaForQuad(xyz1, xyz4, xyz2, xyz3, /*dim*/3)); + + // 3D: Non-convex quadrangle + val = INTERP_KERNEL::calculateAreaForQuad(xyz1, xyz2, xyz3, xyz5, /*dim*/3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.0, val, 0.000001); + + // 3D: Non-planar quadrangle + double xyz7[3] = {-1.5, 3.0, 2.0}; + CPPUNIT_ASSERT_NO_THROW(INTERP_KERNEL::calculateAreaForQuad(xyz1, xyz2, xyz3, xyz7, /*dim*/3)); + } + + //////////////////////////// + // CalculateNormalForTria // + //////////////////////////// + { + double tria_normal [3]; + + // Triangle in plane XOY, normal is opposit to axis Z + INTERP_KERNEL::calculateNormalForTria(xyz1, xyz3, xyz7, tria_normal); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, tria_normal[0], 0.0000001); // Nx + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, tria_normal[1], 0.0000001); // Ny + CPPUNIT_ASSERT(tria_normal[2] < -0.0000001); // Nz + + // Triangle in plane XOY, normal co-directed with axis Z + INTERP_KERNEL::calculateNormalForTria(xyz1, xyz7, xyz3, tria_normal); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, tria_normal[0], 0.0000001); // Nx + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, tria_normal[1], 0.0000001); // Ny + CPPUNIT_ASSERT(tria_normal[2] > 0.0000001); // Nz + + // Triangle in 3D + INTERP_KERNEL::calculateNormalForTria(xyz1, xyz3, xyz6, tria_normal); + double koeff = tria_normal[0]/12.8; + //CPPUNIT_ASSERT_DOUBLES_EQUAL(12.8, tria_normal[0], 0.0000001); // Nx + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0 , tria_normal[1], 0.0000001); // Ny + CPPUNIT_ASSERT_DOUBLES_EQUAL(-9.6 * koeff, tria_normal[2], 0.0000001); // Nz + + // Invalid Triangle (three points on one line) + CPPUNIT_ASSERT_NO_THROW(INTERP_KERNEL::calculateNormalForTria(xyz1, xyz8, xyz3, tria_normal)); + //MEDMEMTest_DumpArray<double>(cout, tria_normal, 3, "Invalid Triangle normal"); + //Invalid Triangle normal: {0, 0, 0} + } + + //////////////////////////// + // CalculateNormalForQuad // + //////////////////////////// + { + double quad_normal [3]; + + // Quadrangle in plane XOY, normal is opposit to axis Z + INTERP_KERNEL::calculateNormalForQuad(xyz1, xyz3, xyz7, xyz9, quad_normal); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, quad_normal[0], 0.0000001); // Nx + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, quad_normal[1], 0.0000001); // Ny + CPPUNIT_ASSERT(quad_normal[2] < -0.0000001); // Nz + + // Quadrangle in plane XOY, normal co-directed with axis Z + INTERP_KERNEL::calculateNormalForQuad(xyz1, xyz9, xyz7, xyz3, quad_normal); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, quad_normal[0], 0.0000001); // Nx + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, quad_normal[1], 0.0000001); // Ny + CPPUNIT_ASSERT(quad_normal[2] > 0.0000001); // Nz + + // Quadrangle in 3D + INTERP_KERNEL::calculateNormalForQuad(xyz1, xyz3, xyz6, xyz2, quad_normal); + //MEDMEMTest_DumpArray<double>(cout, quad_normal, 3, "Quadrangle in 3D normal"); + double koeff = quad_normal[0]/15.6; + //CPPUNIT_ASSERT_DOUBLES_EQUAL(15.6, quad_normal[0], 0.0000001); // Nx + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0 , quad_normal[1], 0.0000001); // Ny + CPPUNIT_ASSERT_DOUBLES_EQUAL(-11.7 * koeff, quad_normal[2], 0.0000001); // Nz + + // Invalid Quadrangle (four points on one line) + CPPUNIT_ASSERT_NO_THROW(INTERP_KERNEL::calculateNormalForQuad(xyz1, xyz8, xyz3, xyz3, quad_normal)); + //MEDMEMTest_DumpArray<double>(cout, quad_normal, 3, "Invalid Quadrangle normal"); + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) division on zero in CalculateNormalForQuad(), if quadrangle is singular + //Invalid Quadrangle normal: {nan, nan, nan} + // Spec. Wait for an improvement + // CPPUNIT_ASSERT(quad_normal[0] < DBL_MAX); + // CPPUNIT_ASSERT(quad_normal[1] < DBL_MAX); + // CPPUNIT_ASSERT(quad_normal[2] < DBL_MAX); + //#endif + } + + ///////////////////////////// + // CalculateNormalForPolyg // + ///////////////////////////// + { + double poly_normal [3]; + const double * polygon_cc[4] = {xyz1, xyz3, xyz7, xyz9}; + const double * polygon_er[4] = {xyz1, xyz8, xyz3, xyz7}; + const double * polygon_cw[4] = {xyz1, xyz9, xyz7, xyz3}; + const double * polygon_3d[4] = {xyz1, xyz3, xyz6, xyz2}; + const double * polygon_si[4] = {xyz1, xyz8, xyz3, xyz3}; + + // Polygon in plane XOY, normal is opposit to axis Z + INTERP_KERNEL::calculateNormalForPolyg(polygon_cc, /*nbOfPtsInPolygs*/4, poly_normal); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, poly_normal[0], 0.0000001); // Nx + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, poly_normal[1], 0.0000001); // Ny + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) Normal for polygon is wrong. Confired to be a bug + CPPUNIT_ASSERT_DOUBLES_EQUAL(-11.7, poly_normal[2], 0.0000001); // Nz + //#endif + + // Polygon in plane XOY, normal co-directed with axis Z + INTERP_KERNEL::calculateNormalForPolyg(polygon_cw, /*nbOfPtsInPolygs*/4, poly_normal); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, poly_normal[0], 0.0000001); // Nx + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, poly_normal[1], 0.0000001); // Ny + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) Normal for polygon is wrong. Confired to be a bug + CPPUNIT_ASSERT_DOUBLES_EQUAL(11.7, poly_normal[2], 0.0000001); // Nz + //#endif + + // Polygon in plane XOY, normal is opposit to axis Z, first three points lay on one line + //CPPUNIT_ASSERT_THROW(CalculateNormalForPolyg(polygon_er, /*nbOfPtsInPolygs*/4, + // poly_normal),MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(INTERP_KERNEL::calculateNormalForPolyg(polygon_er, /*nbOfPtsInPolygs*/4, + poly_normal)); + //CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, poly_normal[0], 0.0000001); // Nx + //CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, poly_normal[1], 0.0000001); // Ny + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) Normal for polygon is wrong if first (three) points are on one line + // Spec, can be improved + // CPPUNIT_ASSERT(poly_normal[2] < -0.0000001); // Nz + //#endif + + // Polygon in 3D + INTERP_KERNEL::calculateNormalForPolyg(polygon_3d, /*nbOfPtsInPolygs*/4, poly_normal); + double koeff = poly_normal[0]/15.6; + //CPPUNIT_ASSERT_DOUBLES_EQUAL(15.6, poly_normal[0], 0.0000001); // Nx + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0 , poly_normal[1], 0.0000001); // Ny + CPPUNIT_ASSERT_DOUBLES_EQUAL(-11.7 * koeff, poly_normal[2], 0.0000001); // Nz + + // Invalid Polygon (four points on one line) + CPPUNIT_ASSERT_THROW(INTERP_KERNEL::calculateNormalForPolyg(polygon_si, /*nbOfPtsInPolygs*/4, + poly_normal),exception); + //MEDMEMTest_DumpArray<double>(cout, poly_normal, 3, "Invalid Polygon normal"); + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) division on zero in CalculateNormalForPolyg(), if polygon is singular + //Invalid Polygon normal: {nan, nan, nan} + // Cinfirmed to be a bug + //CPPUNIT_ASSERT(poly_normal[0] < DBL_MAX); + //CPPUNIT_ASSERT(poly_normal[1] < DBL_MAX); + //CPPUNIT_ASSERT(poly_normal[2] < DBL_MAX); + //#endif + } + + ///////////////////////////// + // CalculateVolumeForTetra // + ///////////////////////////// + { + // good + val = INTERP_KERNEL::calculateVolumeForTetra(xyz1, xyz3, xyz7, xyz5); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6.4, val, 0.000001); + + // reversed + val = INTERP_KERNEL::calculateVolumeForTetra(xyz1, xyz7, xyz3, xyz5); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.4, val, 0.000001); + + // good + val = INTERP_KERNEL::calculateVolumeForTetra(xyz1, xyz7, xyz3, xyz4); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6.4, val, 0.000001); + + // reversed + val = INTERP_KERNEL::calculateVolumeForTetra(xyz1, xyz3, xyz7, xyz4); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.4, val, 0.000001); + + // singular (in plane) + val = INTERP_KERNEL::calculateVolumeForTetra(xyz1, xyz3, xyz7, xyz9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, val, 0.000001); + } + + //////////////////////////// + // CalculateVolumeForPyra // + //////////////////////////// + { + // good + val = INTERP_KERNEL::calculateVolumeForPyra(xyz1, xyz3, xyz7, xyz9, xyz5); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8, val, 0.000001); + + // reversed + val = INTERP_KERNEL::calculateVolumeForPyra(xyz1, xyz9, xyz7, xyz3, xyz5); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-7.8, val, 0.000001); + + // good + val = INTERP_KERNEL::calculateVolumeForPyra(xyz1, xyz9, xyz7, xyz3, xyz4); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8, val, 0.000001); + + // reversed + val = INTERP_KERNEL::calculateVolumeForPyra(xyz1, xyz3, xyz7, xyz9, xyz4); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-7.8, val, 0.000001); + + // singular (in plane) + val = INTERP_KERNEL::calculateVolumeForPyra(xyz1, xyz3, xyz7, xyz9, xyz8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, val, 0.000001); + } + + ///////////////////////////// + // CalculateVolumeForPenta // + ///////////////////////////// + { + double top1[3] = {xyz1[0], xyz1[1], xyz1[2] + 10.0}; + double top3[3] = {xyz3[0], xyz3[1], xyz3[2] + 10.0}; + double top7[3] = {xyz7[0], xyz7[1], xyz7[2] + 10.0}; + + // good + val = INTERP_KERNEL::calculateVolumeForPenta(xyz1, xyz3, xyz7, top1, top3, top7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(96.0, val, 0.000001); + + // reversed + val = INTERP_KERNEL::calculateVolumeForPenta(xyz1, xyz7, xyz3, top1, top7, top3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-96.0, val, 0.000001); + + // good + top1[0] = top1[0] + 7.0; + top3[0] = top3[0] + 7.0; + top7[0] = top7[0] + 7.0; + + val = INTERP_KERNEL::calculateVolumeForPenta(xyz1, xyz3, xyz7, top1, top3, top7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(96.0, val, 0.000001); + + // reversed + val = INTERP_KERNEL::calculateVolumeForPenta(xyz1, xyz7, xyz3, top1, top7, top3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-96.0, val, 0.000001); + + // singular (in plane) + top1[2] = top1[2] - 10.0; + top3[2] = top3[2] - 10.0; + top7[2] = top7[2] - 10.0; + + val = INTERP_KERNEL::calculateVolumeForPenta(xyz1, xyz3, xyz7, top1, top3, top7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, val, 0.000001); + } + + //////////////////////////// + // CalculateVolumeForHexa // + //////////////////////////// + { + double top1[3] = {xyz1[0], xyz1[1], xyz1[2] + 10.0}; + double top3[3] = {xyz3[0], xyz3[1], xyz3[2] + 10.0}; + double top7[3] = {xyz7[0], xyz7[1], xyz7[2] + 10.0}; + double top9[3] = {xyz9[0], xyz9[1], xyz9[2] + 10.0}; + + // good + val = INTERP_KERNEL::calculateVolumeForHexa(xyz1, xyz3, xyz7, xyz9, top1, top3, top7, top9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(117.0, val, 0.000001); + + // reversed + val = INTERP_KERNEL::calculateVolumeForHexa(xyz1, xyz9, xyz7, xyz3, top1, top9, top7, top3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-117.0, val, 0.000001); + + // good + top1[0] = top1[0] + 7.0; + top3[0] = top3[0] + 7.0; + top7[0] = top7[0] + 7.0; + top9[0] = top9[0] + 7.0; + + val = INTERP_KERNEL::calculateVolumeForHexa(xyz1, xyz3, xyz7, xyz9, top1, top3, top7, top9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(117.0, val, 0.000001); + + // reversed + val = INTERP_KERNEL::calculateVolumeForHexa(xyz1, xyz9, xyz7, xyz3, top1, top9, top7, top3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-117.0, val, 0.000001); + + // singular (in plane) + top1[2] = top1[2] - 10.0; + top3[2] = top3[2] - 10.0; + top7[2] = top7[2] - 10.0; + top9[2] = top9[2] - 10.0; + + val = INTERP_KERNEL::calculateVolumeForHexa(xyz1, xyz3, xyz7, xyz9, top1, top3, top7, top9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, val, 0.000001); + } + + ///////////////////////////// + // CalculateVolumeForPolyh // + ///////////////////////////// + // inline double CalculateVolumeForPolyh(const double ***pts, const int *nbOfNodesPerFaces, + // int nbOfFaces, const double *bary); + { + int nbFaces = 4; + int nbOfNodesPerFaces[4] = {3,3,3,3}; + + const double * nodes[4] = {xyz1, xyz7, xyz3, xyz5}; + double bary[3]; + INTERP_KERNEL::calculateBarycenterDyn(nodes, 4, /*dim*/3, bary); + + // good + const double * fa1[3] = {xyz1, xyz7, xyz3}; + const double * fa2[3] = {xyz1, xyz3, xyz5}; + const double * fa3[3] = {xyz3, xyz7, xyz5}; + const double * fa4[3] = {xyz7, xyz1, xyz5}; + const double ** polyh[4] = {fa1, fa2, fa3, fa4}; + + val = INTERP_KERNEL::calculateVolumeForPolyh(polyh, nbOfNodesPerFaces, nbFaces, bary); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.4, val, 0.000001); + + // reversed + //const double * fa1_r[3] = {xyz1, xyz3, xyz7}; + //const double * fa2_r[3] = {xyz3, xyz1, xyz5}; + //const double * fa3_r[3] = {xyz7, xyz3, xyz5}; + //const double * fa4_r[3] = {xyz1, xyz7, xyz5}; + //const double ** polyh_r[4] = {fa1_r, fa2_r, fa3_r, fa4_r}; + // + //val = CalculateVolumeForPolyh(polyh_r, nbOfNodesPerFaces, nbFaces, bary); + //CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.4, val, 0.000001); + + // singular (in plane) + const double * nodes_si[4] = {xyz1, xyz7, xyz3, xyz9}; + double bary_si[3]; + INTERP_KERNEL::calculateBarycenterDyn(nodes_si, 4, /*dim*/3, bary_si); + + const double * fa1_si[3] = {xyz1, xyz7, xyz3}; + const double * fa2_si[3] = {xyz1, xyz3, xyz9}; + const double * fa3_si[3] = {xyz3, xyz7, xyz9}; + const double * fa4_si[3] = {xyz7, xyz1, xyz9}; + const double ** polyh_si[4] = {fa1_si, fa2_si, fa3_si, fa4_si}; + + val = INTERP_KERNEL::calculateVolumeForPolyh(polyh_si, nbOfNodesPerFaces, nbFaces, bary_si); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, val, 0.000001); + } + + //////////////////////// + // addComponentsOfVec // + //////////////////////// + { + // five points + const double * pts[5] = {xyz2, xyz1, xyz3, xyz4, xyz5}; + + val = INTERP_KERNEL::addComponentsOfVec<5>(pts, 0); // x + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0, val, 0.000001); + + val = INTERP_KERNEL::addComponentsOfVec<5>(pts, 1); // y + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0, val, 0.000001); + + val = INTERP_KERNEL::addComponentsOfVec<5>(pts, 2); // z + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0, val, 0.000001); + + // one point: xyz2 + val = INTERP_KERNEL::addComponentsOfVec<1>(pts, 0); // x + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0, val, 0.000001); + + val = INTERP_KERNEL::addComponentsOfVec<1>(pts, 1); // y + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, val, 0.000001); + + val = INTERP_KERNEL::addComponentsOfVec<1>(pts, 2); // z + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0, val, 0.000001); + } + + //////////////////////////// + // CalculateBarycenterDyn // + //////////////////////////// + { + // five points + const double * pts[5] = {xyz2, xyz1, xyz3, xyz4, xyz5}; + double bary_3d[3]; + double bary_2d[2]; + + INTERP_KERNEL::calculateBarycenterDyn(pts, /*nbPts*/5, /*dim*/3, bary_3d); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0/5.0, bary_3d[0], 0.000001); // x + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0/5.0, bary_3d[1], 0.000001); // y + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0/5.0, bary_3d[2], 0.000001); // z + + INTERP_KERNEL::calculateBarycenterDyn(pts, /*nbPts*/5, /*dim*/2, bary_2d); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0/5.0, bary_2d[0], 0.000001); // x + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0/5.0, bary_2d[1], 0.000001); // y + + // one point: xyz2 + INTERP_KERNEL::calculateBarycenterDyn(pts, /*nbPts*/1, /*dim*/3, bary_3d); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0, bary_3d[0], 0.000001); // x + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, bary_3d[1], 0.000001); // y + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0, bary_3d[2], 0.000001); // z + } + + ///////////////////////// + // CalculateBarycenter // + ///////////////////////// + // template<int N, int DIM> inline void CalculateBarycenter(const double **pts, double *bary); + // template<> inline void CalculateBarycenter<2,0>(const double **pts, double *bary); + // template<> inline void CalculateBarycenter<3,0>(const double **pts, double *bary); + // template<> inline void CalculateBarycenter<4,0>(const double **pts, double *bary); + // template<> inline void CalculateBarycenter<5,0>(const double **pts, double *bary); + // template<> inline void CalculateBarycenter<6,0>(const double **pts, double *bary); + // template<> inline void CalculateBarycenter<7,0>(const double **pts, double *bary); + // template<> inline void CalculateBarycenter<8,0>(const double **pts, double *bary); + { + // five points + const double * pts[5] = {xyz2, xyz1, xyz3, xyz4, xyz5}; + double bary_3d[3]; + double bary_2d[2]; + + INTERP_KERNEL::calculateBarycenter<5,3>(pts, bary_3d); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0/5.0, bary_3d[0], 0.000001); // x + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0/5.0, bary_3d[1], 0.000001); // y + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0/5.0, bary_3d[2], 0.000001); // z + + INTERP_KERNEL::calculateBarycenter<5,2>(pts, bary_2d); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0/5.0, bary_2d[0], 0.000001); // x + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0/5.0, bary_2d[1], 0.000001); // y + + // one point: xyz2 : NOT IMPLEMENTED!!! + //CalculateBarycenter<1,3>(pts, bary_3d); + //CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0, bary_3d[0], 0.000001); + //CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, bary_3d[1], 0.000001); + //CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0, bary_3d[2], 0.000001); + } +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_GaussLocalization.cxx b/src/MEDMEMCppTest/MEDMEMTest_GaussLocalization.cxx new file mode 100644 index 000000000..b94a5a3e5 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_GaussLocalization.cxx @@ -0,0 +1,209 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "MEDMEM_GaussLocalization.hxx" +#include "MEDMEM_STRING.hxx" + +#include <sstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; + +// #18: MEDMEM_GaussLocalization.hxx } MEDMEMTest.cxx + +/*! + * Check methods (13), defined in MEDMEM_GaussLocalization.hxx: + * class GAUSS_LOCALIZATION_ { + * (+) virtual MED_EN::medModeSwitch getInterlacingType() const; + * (+) virtual ~GAUSS_LOCALIZATION_(); + * } + * (+) template <class INTERLACING_TAG=FullInterlace> class GAUSS_LOCALIZATION; + * + * (+) template <class INTERLACING_TAG> ostream & operator<< + * (ostream &os, const GAUSS_LOCALIZATION<INTERLACING_TAG> &loc); + * + * template <class INTERLACING_TAG> class GAUSS_LOCALIZATION : public GAUSS_LOCALIZATION_ { + * (+) GAUSS_LOCALIZATION() throw (MEDEXCEPTION); + * (+) GAUSS_LOCALIZATION(const string & locName, + * const MED_EN::medGeometryElement typeGeo, + * const int nGauss, + * const ArrayNoGauss & cooRef, + * const ArrayNoGauss & cooGauss, + * const vector<double> & wg) throw (MEDEXCEPTION); + * (+) GAUSS_LOCALIZATION(const string & locName, + * const MED_EN::medGeometryElement typeGeo, + * const int nGauss, + * const double * const cooRef, + * const double * const cooGauss, + * const double * const wg) throw (MEDEXCEPTION); + * (+) virtual ~GAUSS_LOCALIZATION(); + * + * (+) GAUSS_LOCALIZATION & operator=(const GAUSS_LOCALIZATION & gaussLoc); + * (+) bool operator == (const GAUSS_LOCALIZATION &loc) const; + * + * (+) string getName() const; + * (+) MED_EN::medGeometryElement getType() const; + * + * (+) int getNbGauss() const; + * (+) ArrayNoGauss getRefCoo () const; + * (+) ArrayNoGauss getGsCoo () const; + * (+) vector <double> getWeight () const; + * + * (+) inline MED_EN::medModeSwitch getInterlacingType() const; + * } + */ +void MEDMEMTest::testGaussLocalization() +{ + // GAUSS_LOCALIZATION_ + GAUSS_LOCALIZATION_ aGL_; + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_UNDEFINED_INTERLACE, aGL_.getInterlacingType()); + + // GAUSS_LOCALIZATION empty constructor and InterlaceType + GAUSS_LOCALIZATION<> anEmptyGL1; + MED_EN::medModeSwitch aDefaultInterlaceType = anEmptyGL1.getInterlacingType(); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FULL_INTERLACE, aDefaultInterlaceType); + + GAUSS_LOCALIZATION<NoInterlace> anEmptyGL2; + MED_EN::medModeSwitch anInterlaceType2 = anEmptyGL2.getInterlacingType(); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_NO_INTERLACE, anInterlaceType2); + + // Construction from C++ arrays + double cooRef[6] = {1.,1., 2.,4., 3.,9.}; // xy xy xy + double cooGauss[10] = {7.,7., 6.,6., 5.,5., 4.,3., 2.,1.}; // x1,y1 x2,y2 x3,y3 x4,y4 x5,y5 + double wg[5] = {1., 2., 3., 4., 5.}; + + GAUSS_LOCALIZATION<> gl1 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef, cooGauss, wg); + GAUSS_LOCALIZATION<> gl2 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef, cooGauss, wg); + + // getXXX + CPPUNIT_ASSERT(gl1.getName() == "GL1"); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_TRIA3, gl1.getType()); + CPPUNIT_ASSERT_EQUAL(5, gl1.getNbGauss()); + + GAUSS_LOCALIZATION<>::ArrayNoGauss cooRefBack = gl1.getRefCoo(); + GAUSS_LOCALIZATION<>::ArrayNoGauss cooGaussBack = gl1.getGsCoo(); + vector<double> wgBack = gl1.getWeight(); + + double * cooRefBack_ptr = cooRefBack.getPtr(); + double * cooGaussBack_ptr = cooGaussBack.getPtr(); + + // (BUG)Reading uninitialized memory here + // TODO fix + for (int i = 0; i < 10; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(cooRef[i%6], cooRefBack_ptr[i%6], 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(cooGauss[i], cooGaussBack_ptr[i], 0.000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL(wg[i%5] , wgBack[i%5] , 0.000001); + } + + // Operators == and = + CPPUNIT_ASSERT(gl1 == gl2); + CPPUNIT_ASSERT_EQUAL(gl1, gl2); + + GAUSS_LOCALIZATION<> gl1_c; + gl1_c = gl1; + + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) Badly copyed arrays as a result of operator= usage + CPPUNIT_ASSERT_EQUAL(gl1, gl1_c); + // Invalid read of size 8 + // at 0x342B157A: MEDMEM::MEDMEM_Array<double, MEDMEM::FullInterlaceNoGaussPolicy, MEDMEM::IndexCheckPolicy>::operator==(MEDMEM::MEDMEM_Array<double, MEDMEM::FullInterlaceNoGaussPolicy, MEDMEM::IndexCheckPolicy> const&) const (MEDMEM_nArray.hxx:255) + // by 0x342A1CDA: MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace>::operator==(MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace> const&) const (MEDMEM_GaussLocalization.hxx:175) + // by 0x34315F98: CppUnit::assertion_traits<MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace> >::equal(MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace> const&, MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace> const&) (TestAssert.h:40) + // by 0x34314D35: void CppUnit::assertEquals<MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace> >(MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace> const&, MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace> const&, CppUnit::SourceLine, std::string const&) (TestAssert.h:62) + // by 0x34311D6F: MEDMEMTest::testGaussLocalization() (MEDMEMTest_GaussLocalization.cxx:132) + // Address 0x35B5FC98 is 0 bytes inside a block of size 48 free'd + // at 0x3414CD61: operator delete[](void*) (vg_replace_malloc.c:161) + // by 0x341D88CA: MEDMEM::PointerOf<double>::~PointerOf() (MEDMEM_PointerOf.hxx:141) + // by 0x341D56C7: MEDMEM::MEDMEM_Array<double, MEDMEM::FullInterlaceNoGaussPolicy, MEDMEM::IndexCheckPolicy>::~MEDMEM_Array() (MEDMEM_nArray.hxx:52) + // by 0x34314F58: MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace>::operator=(MEDMEM::GAUSS_LOCALIZATION<MEDMEM::FullInterlace> const&) (MEDMEM_GaussLocalization.hxx:166) + // by 0x34311CCC: MEDMEMTest::testGaussLocalization() (MEDMEMTest_GaussLocalization.cxx:128) + //#endif + + // same name, type and nb.gauss, but different coords or weights + double cooRef_ch[6] = {1.,1., 2.,8., 3.,9.}; + double cooGauss_ch[10] = {7.,8., 6.,6., 5.,5., 4.,3., 2.,1.}; + double wg_ch[5] = {1., 2., 8., 4., 5.}; + + GAUSS_LOCALIZATION<> gl3 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef_ch, cooGauss, wg); + GAUSS_LOCALIZATION<> gl4 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef, cooGauss_ch, wg); + GAUSS_LOCALIZATION<> gl5 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef, cooGauss, wg_ch); + + CPPUNIT_ASSERT(!(gl1 == gl3)); + CPPUNIT_ASSERT(!(gl1 == gl4)); + CPPUNIT_ASSERT(!(gl1 == gl5)); + + // different name or type, or nb.gauss + double cooRef_quad[8] = {1.,1., 2.,4., 3.,9., 4., 16.}; + double cooGauss_4[8] = {7.,8., 6.,6., 5.,5., 4.,3.}; + double wg_4[4] = {1., 2., 8., 4.}; + + GAUSS_LOCALIZATION<> gl6 ("GL6", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef, cooGauss, wg); + GAUSS_LOCALIZATION<> gl7 ("GL1", MED_EN::MED_QUAD4, /*nGauss*/5, cooRef_quad, cooGauss, wg); + GAUSS_LOCALIZATION<> gl8 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/4, cooRef, cooGauss_4, wg_4); + + CPPUNIT_ASSERT(!(gl1 == gl6)); + CPPUNIT_ASSERT(!(gl1 == gl7)); + CPPUNIT_ASSERT(!(gl1 == gl8)); + + // Operator << + ostringstream ostr1; + ostr1 << gl1; + CPPUNIT_ASSERT(ostr1.str() != ""); + + ostringstream ostr2; + ostr2 << gl2; + CPPUNIT_ASSERT_EQUAL(ostr1.str(), ostr2.str()); + + // Construction from ArrayNoGauss and vector<double> + GAUSS_LOCALIZATION<> gl9 ("GL1", MED_EN::MED_TRIA3, /*nGauss*/5, cooRefBack, cooGaussBack, wgBack); + CPPUNIT_ASSERT(gl1 == gl9); + + // NoInterlace + double cooRef_ni[6] = {1.,2.,3., 1.,4.,9.}; // xxx yyy + double cooGauss_ni[10] = {7.,6.,5.,4.,2., 7.,6.,5.,3.,1.}; // x1,x2,x3,x4,x5 y1,y2,y3,y4,y5 + + GAUSS_LOCALIZATION<NoInterlace> gl10 ("GL10", MED_EN::MED_TRIA3, /*nGauss*/5, cooRef_ni, cooGauss_ni, wg); + + GAUSS_LOCALIZATION<NoInterlace>::ArrayNoGauss cooRefBack_ni = gl10.getRefCoo(); + GAUSS_LOCALIZATION<NoInterlace>::ArrayNoGauss cooGaussBack_ni = gl10.getGsCoo(); + + for (int i = 1; i <= 3; i++) { // nb. nodes + for (int j = 1; j <= 2; j++) { // dim + CPPUNIT_ASSERT_DOUBLES_EQUAL(cooRefBack.getIJ(i, j), cooRefBack_ni.getIJ(i, j), 0.000001); + } + } + + for (int i = 1; i <= 5; i++) { // nGauss + for (int j = 1; j <= 2; j++) { // dim + CPPUNIT_ASSERT_DOUBLES_EQUAL(cooGaussBack.getIJ(i, j), cooGaussBack_ni.getIJ(i, j), 0.000001); + } + } +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_GibiMeshDriver.cxx b/src/MEDMEMCppTest/MEDMEMTest_GibiMeshDriver.cxx new file mode 100644 index 000000000..5e58e0f17 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_GibiMeshDriver.cxx @@ -0,0 +1,514 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include <MEDMEM_GibiMeshDriver.hxx> +#include <MEDMEM_Mesh.hxx> +#include <MEDMEM_Med.hxx> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +/*! + * Check methods (31), defined in MEDMEM_GibiMeshDriver.hxx: + * class GIBI_MESH_DRIVER : public GENDRIVER { + * (+) GIBI_MESH_DRIVER(); + * (+) GIBI_MESH_DRIVER(const string & fileName, MESH * ptrMesh, MED_EN::med_mode_acces accessMode); + * (+) GIBI_MESH_DRIVER(const GIBI_MESH_DRIVER & driver); + * (+) virtual ~GIBI_MESH_DRIVER(); + * (+) virtual void write(void) const = 0; + * (+) virtual void read (void) = 0; + * (+) void setMeshName(const string & meshName); + * (+) string getMeshName() const; + * (+) static MED_EN::medGeometryElement gibi2medGeom(size_t gibiTypeNb); + * (+) static int med2gibiGeom(MED_EN::medGeometryElement medGeomType); + * } + * class GIBI_MESH_RDONLY_DRIVER : public virtual GIBI_MESH_DRIVER { + * (+) GIBI_MESH_RDONLY_DRIVER(); + * (+) GIBI_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh); + * (+) GIBI_MESH_RDONLY_DRIVER(const GIBI_MESH_RDONLY_DRIVER & driver); + * (+) virtual ~GIBI_MESH_RDONLY_DRIVER(); + * (+) void write(void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void open(); + * (+) void close(); + * } + * class GIBI_MESH_WRONLY_DRIVER : public virtual GIBI_MESH_DRIVER { + * (+) GIBI_MESH_WRONLY_DRIVER(); + * (+) GIBI_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh); + * (+) GIBI_MESH_WRONLY_DRIVER(const GIBI_MESH_WRONLY_DRIVER & driver); + * (+) virtual ~GIBI_MESH_WRONLY_DRIVER(); + * (+) void write(void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void open(); + * (+) void close(); + * } + * class GIBI_MESH_RDWR_DRIVER : public GIBI_MESH_RDONLY_DRIVER, public GIBI_MESH_WRONLY_DRIVER { + * (+) GIBI_MESH_RDWR_DRIVER(); + * (+) GIBI_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh); + * (+) GIBI_MESH_RDWR_DRIVER(const GIBI_MESH_RDWR_DRIVER & driver); + * (+) ~GIBI_MESH_RDWR_DRIVER(); + * (+) void write(void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void open(); + * (+) void close(); + * } + * class GIBI_MED_RDONLY_DRIVER : public GIBI_MESH_RDONLY_DRIVER { + * (+) GIBI_MED_RDONLY_DRIVER(); + * (+) GIBI_MED_RDONLY_DRIVER(const string & fileName, MED * ptrMed); + * (+) GIBI_MED_RDONLY_DRIVER(const GIBI_MED_RDONLY_DRIVER & driver); + * (+) virtual ~GIBI_MED_RDONLY_DRIVER(); + * (+) void read (void) throw (MEDEXCEPTION); + * } + * class GIBI_MED_WRONLY_DRIVER : public GIBI_MESH_WRONLY_DRIVER { + * (+) GIBI_MED_WRONLY_DRIVER(); + * (+) GIBI_MED_WRONLY_DRIVER(const string & fileName, MED * ptrMed, MESH * ptrMesh); + * (+) GIBI_MED_WRONLY_DRIVER(const GIBI_MED_WRONLY_DRIVER & driver); + * (+) virtual ~GIBI_MED_WRONLY_DRIVER(); + * (+) void write(void) const throw (MEDEXCEPTION); + * } + */ + +void MEDMEMTest::testGibiMeshDriver() +{ + MESH *aMesh = new MESH(); + MESH *aMesh_NULL = NULL; + MESH *aMesh_2 = new MESH(); + MED *aMed = new MED(); + MED *aMed_1 = NULL; + + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + + string filename_rd = data_dir + "/share/salome/resources/med/Darcy3_3D_H_10x10x10.sauve"; + string filenamemed_rd = data_dir + "/share/salome/resources/med/elle_3D_HPr_10x10x10.sauve"; + string filename_wr = tmp_dir + "/myWr_Darcy3_3D_H_10x10x10.sauve"; + string tmpfile = tmp_dir + "/tmp.sauve"; + string tmpfile_rdwr = tmp_dir + "/rdwr_tmp.sauve"; + string filenamemed_wr = tmp_dir + "/myWrMed_elle_3D_HPr_10x10x10.sauve"; + string tmpfilemed = tmp_dir + "/tmpmed.sauve"; + string meshname = "Darcy3_3D_H_10x10x10"; + string newmeshname = "new" + meshname; + string fileNotExistsName_rd = "notExists.sauve"; + string fileNotExistsName_wr = "/path_not_exists/file_not_exists.sauve"; + string filename_rdwr = tmp_dir + "/myRdWr_Darcy3_3D_H_10x10x10.sauve"; + string fcopy = "cp " + filename_rd + " " + filename_rdwr; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filename_wr); + aRemover.Register(tmpfile); + aRemover.Register(tmpfilemed); + aRemover.Register(filenamemed_wr); + aRemover.Register(tmpfile_rdwr); + aRemover.Register(filename_rdwr); + + //Test gibi2medGeom() and med2gibiGeom() methods + size_t aSize = 17; + CPPUNIT_ASSERT_EQUAL(GIBI_MESH_DRIVER::gibi2medGeom(aSize), MED_PENTA15); + CPPUNIT_ASSERT_EQUAL(GIBI_MESH_DRIVER::med2gibiGeom(MED_PENTA15), 17); + + //---------------------------Test GIBI MESH READ ONLY part--------------------------------// + { + { + //Creation of an incorrect read only driver + GIBI_MESH_RDONLY_DRIVER *aInvalidGibiRdDriver = + new GIBI_MESH_RDONLY_DRIVER(fileNotExistsName_rd, aMesh); + + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidGibiRdDriver->open(), MEDEXCEPTION); + + delete aInvalidGibiRdDriver; + } + + //Creation a correct Gibi read only driver (normal constructor) + GIBI_MESH_RDONLY_DRIVER *aGibiRdDriver = + new GIBI_MESH_RDONLY_DRIVER(filename_rd, aMesh); + + //Check driver + CPPUNIT_ASSERT(aGibiRdDriver); + + //Trying read mesh from file, if file is not open + CPPUNIT_ASSERT_THROW(aGibiRdDriver->read(), MEDEXCEPTION); + + //Test open() method + CPPUNIT_ASSERT_NO_THROW(aGibiRdDriver->open()); + + //Trying open file secondary. + //#ifdef ENABLE_FORCED_FAILURES + //This case is not work, seems it BUG + // SHOULD THROW + //CPPUNIT_ASSERT_THROW(aGibiRdDriver->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aGibiRdDriver->open()); + //#endif + + //Test setMeshName() and getMeshName() methods + CPPUNIT_ASSERT_NO_THROW(aGibiRdDriver->setMeshName(meshname)); + CPPUNIT_ASSERT_EQUAL(meshname, aGibiRdDriver->getMeshName()); + + //Test read() method + CPPUNIT_ASSERT_NO_THROW(aGibiRdDriver->read()); + // Source and destination overlap in memcpy(0x35DBF040, 0x35DBF06D, 101) + // at 0x3414D97E: memcpy (mac_replace_strmem.c:113) + // by 0x3492EDE9: MEDMEM::GIBI_MESH_RDONLY_DRIVER::getLine(char*&) (MEDMEM_GibiMeshDriver.cxx:942) + // by 0x349407FD: MEDMEM::GIBI_MESH_RDONLY_DRIVER::getNextLine(char*&, bool) (MEDMEM_GibiMeshDriver.hxx:168) + // by 0x349268B1: MEDMEM::GIBI_MESH_RDONLY_DRIVER::readFile(MEDMEM::_intermediateMED*, bool) (MEDMEM_GibiMeshDriver.cxx:209) + // by 0x3492F58B: MEDMEM::GIBI_MESH_RDONLY_DRIVER::read() (MEDMEM_GibiMeshDriver.cxx:1058) + // by 0x3436DEA6: MEDMEMTest::testGibiMeshDriver() (MEDMEMTest_GibiMeshDriver.cxx:168) + + //Trying fill not empty mesh + CPPUNIT_ASSERT_THROW(aGibiRdDriver->read(), MEDEXCEPTION); + + //Test write() method for GIBI READ ONLY driver + CPPUNIT_ASSERT_THROW(aGibiRdDriver->write(), MEDEXCEPTION); + + //Check Mesh + CPPUNIT_ASSERT(aMesh); + + //Test close method + CPPUNIT_ASSERT_NO_THROW(aGibiRdDriver->close()); + + //Default constructor + { + GIBI_MESH_RDONLY_DRIVER aGibiRdDriverCpy_1; + } + + //Test copy constructor and operator==(), defined in GENDRIVER class + { + GIBI_MESH_RDONLY_DRIVER aGibiRdDriverCpy_2 (*aGibiRdDriver); + CPPUNIT_ASSERT(aGibiRdDriverCpy_2.GENDRIVER::operator==(*aGibiRdDriver)); + + //Test (friend ostream & operator <<) defined GENDRIVER class + ostringstream rostr1, rostr2; + rostr1 << *aGibiRdDriver; + rostr2 << aGibiRdDriverCpy_2; + CPPUNIT_ASSERT(rostr1.str() != ""); + CPPUNIT_ASSERT(rostr1.str() == rostr2.str()); + } + + delete aGibiRdDriver; + } + + //-------------------------------Test GIBI WRITE ONLY part------------------------------// + { + { + //Creation a incorrect gibi write only driver + GIBI_MESH_WRONLY_DRIVER *aInvalidGibiWrDriver = + new GIBI_MESH_WRONLY_DRIVER(fileNotExistsName_wr, aMesh); + + //Trying open non existing file + CPPUNIT_ASSERT_THROW(aInvalidGibiWrDriver->open(), MEDEXCEPTION); + + delete aInvalidGibiWrDriver; + } + + //Trying write empty mesh + { + GIBI_MESH_WRONLY_DRIVER *aTmpGibiWrDriver = + new GIBI_MESH_WRONLY_DRIVER(tmpfile, aMesh_NULL); + aTmpGibiWrDriver->open(); + + CPPUNIT_ASSERT_THROW(aTmpGibiWrDriver->write(),MEDEXCEPTION); + aTmpGibiWrDriver->close(); + + delete aTmpGibiWrDriver; + } + + //Creation a correct gibi write only drivers + GIBI_MESH_WRONLY_DRIVER *aGibiWrDriver = + new GIBI_MESH_WRONLY_DRIVER(filename_wr, aMesh); + + //Check driver + CPPUNIT_ASSERT(aGibiWrDriver); + + //Trying write mesh to file, if file is not open + CPPUNIT_ASSERT_THROW(aGibiWrDriver->write(), MEDEXCEPTION); + + //Test open() method + CPPUNIT_ASSERT_NO_THROW(aGibiWrDriver->open()); + + //Trying open file secondary. + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) No exception on attempt to open an opened file for the second time + //CPPUNIT_ASSERT_THROW(aGibiWrDriver->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aGibiWrDriver->open()); + //#endif + + //Test setMeshName() and getMeshName() methods + CPPUNIT_ASSERT_NO_THROW(aGibiWrDriver->setMeshName(newmeshname)); + CPPUNIT_ASSERT_EQUAL(newmeshname, aGibiWrDriver->getMeshName()); + + //Test write() method + CPPUNIT_ASSERT_NO_THROW(aGibiWrDriver->write()); + + //Test read() method for GIBI WRITE ONLY driver + CPPUNIT_ASSERT_THROW(aGibiWrDriver->read(), MEDEXCEPTION); + + //Test close method + CPPUNIT_ASSERT_NO_THROW(aGibiWrDriver->close()); + + //Default constructor + GIBI_MESH_WRONLY_DRIVER aGibiWrDriverCpy_1; + + //Test copy constructor + GIBI_MESH_WRONLY_DRIVER aGibiWrDriverCpy_2 (*aGibiWrDriver); + + //Test (bool operator ==) defined GENDRIVER class + CPPUNIT_ASSERT(aGibiWrDriverCpy_2.GENDRIVER::operator==(*aGibiWrDriver)); + + //Test (friend ostream & operator <<) defined GENDRIVER class + ostringstream wostr1, wostr2; + wostr1 << *aGibiWrDriver; + wostr2 << aGibiWrDriverCpy_2; + CPPUNIT_ASSERT(wostr1.str() != ""); + CPPUNIT_ASSERT(wostr1.str() == wostr2.str()); + + delete aGibiWrDriver; + } + + //-------------------------------Test GIBI READ/WRITE part---------------------------------// + { + //Copy file + system(fcopy.c_str()); + + { + //Creation a incorrect gibi read/write driver + GIBI_MESH_RDWR_DRIVER *aInvalidGibiRdWrDriver = + new GIBI_MESH_RDWR_DRIVER(fileNotExistsName_wr, aMesh_2); + + //Trying read/write from not existing file + CPPUNIT_ASSERT_THROW(aInvalidGibiRdWrDriver->read(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aInvalidGibiRdWrDriver->write(), MEDEXCEPTION); + + delete aInvalidGibiRdWrDriver; + } + + //Trying write empty mesh + { + GIBI_MESH_RDWR_DRIVER *aTmpGibiRdWrDriver = + new GIBI_MESH_RDWR_DRIVER(tmpfile_rdwr, aMesh_NULL); + CPPUNIT_ASSERT_THROW(aTmpGibiRdWrDriver->write(), MEDEXCEPTION); + delete aTmpGibiRdWrDriver; + } + + //Creation a correct read/write driver + GIBI_MESH_RDWR_DRIVER *aGibiRdWrDriver = + new GIBI_MESH_RDWR_DRIVER(filename_rdwr, aMesh_2); + + //Test open/close methods + CPPUNIT_ASSERT_NO_THROW(aGibiRdWrDriver->open()); + CPPUNIT_ASSERT_NO_THROW(aGibiRdWrDriver->close()); + + //Check driver + CPPUNIT_ASSERT(aGibiRdWrDriver); + + //Test read() method + CPPUNIT_ASSERT_NO_THROW(aGibiRdWrDriver->read()); + + //Check Mesh + CPPUNIT_ASSERT(aMesh); + + //Trying fill not empty mesh + CPPUNIT_ASSERT_THROW(aGibiRdWrDriver->read(),MEDEXCEPTION); + + //Test write() method + aGibiRdWrDriver->setMeshName(newmeshname); + CPPUNIT_ASSERT_NO_THROW(aGibiRdWrDriver->write()); + + //Default constructor + GIBI_MESH_RDWR_DRIVER aGibiRdWrDriverCpy_1; + + //Test copy constructor + GIBI_MESH_RDWR_DRIVER aGibiRdWrDriverCpy_2 (*aGibiRdWrDriver); + + //Test (bool operator ==) + CPPUNIT_ASSERT(aGibiRdWrDriverCpy_2.GENDRIVER::operator==(*aGibiRdWrDriver)); + + //Test (ostream & operator <<) + ostringstream rwostr1, rwostr2; + rwostr1 << *aGibiRdWrDriver; + rwostr2 << aGibiRdWrDriverCpy_2; + CPPUNIT_ASSERT(rwostr1.str() != ""); + CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + delete aGibiRdWrDriver; + } + + //----------------------------Test GIBI_MED_RDONLY_DRIVER---------------------------- + { + { + GIBI_MED_RDONLY_DRIVER *aInvalidMedGibiRdDriver = + new GIBI_MED_RDONLY_DRIVER(fileNotExistsName_rd, aMed); + + //Trying open not exising file + CPPUNIT_ASSERT_THROW(aInvalidMedGibiRdDriver->open(), MEDEXCEPTION); + + delete aInvalidMedGibiRdDriver; + } + + //Creation a correct Gibi read only driver (normal constructor) + GIBI_MED_RDONLY_DRIVER *aGibiMedRdDriver = + new GIBI_MED_RDONLY_DRIVER(filenamemed_rd, aMed); + + //Check driver + CPPUNIT_ASSERT(aGibiMedRdDriver); + + //Trying read mesh from file, if file is not open + CPPUNIT_ASSERT_THROW(aGibiMedRdDriver->read(), MEDEXCEPTION); + + //Test open() method + CPPUNIT_ASSERT_NO_THROW(aGibiMedRdDriver->open()); + + //#ifdef ENABLE_FORCED_FAILURES + //Trying open file secondary. + //CPPUNIT_ASSERT_THROW(aGibiMedRdDriver->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aGibiMedRdDriver->open()); + //This case is not work, seems it BUG + //#endif + + //Test read() method + CPPUNIT_ASSERT_NO_THROW(aGibiMedRdDriver->read()); + + //Test write() method for GIBI MED READ ONLY driver + CPPUNIT_ASSERT_THROW(aGibiMedRdDriver->write(), MEDEXCEPTION); + + //Check Med + CPPUNIT_ASSERT(aMed); + + //Test close method + CPPUNIT_ASSERT_NO_THROW(aGibiMedRdDriver->close()); + + //Default constructor + GIBI_MED_RDONLY_DRIVER aGibiMedRdDriverCpy_1; + + //Test (bool operator ==) defined in GENDRIVER class + CPPUNIT_ASSERT(! aGibiMedRdDriverCpy_1.GENDRIVER::operator==(*aGibiMedRdDriver)); + + //Test copy constructor + // commented since this test is not important + //GIBI_MED_RDONLY_DRIVER aGibiMedRdDriverCpy_2 (*aGibiMedRdDriver); + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) Copy constructor of GIBI_MED_RDONLY_DRIVER is not implemented + // Small importance + //CPPUNIT_ASSERT(aGibiMedRdDriverCpy_2.GENDRIVER::operator==(*aGibiMedRdDriver)); + //#endif + + //Test (friend ostream & operator <<) defined in GENDRIVER class + // commented since this test is not important + //ostringstream medrostr1, medrostr2; + //medrostr1 << *aGibiMedRdDriver; + //medrostr2 << aGibiMedRdDriverCpy_2; + //CPPUNIT_ASSERT(medrostr1.str() != ""); + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) Copy constructor of GIBI_MED_RDONLY_DRIVER is not implemented + //CPPUNIT_ASSERT(medrostr1.str() == medrostr2.str()); + //#endif + + delete aGibiMedRdDriver; + } + + //----------------------------Test GIBI MED WRITE ONLY part----------------------------------// + { + { + //Creation a incorrect gibi med write only driver + GIBI_MED_WRONLY_DRIVER *aInvalidGibiMedWrDriver = + new GIBI_MED_WRONLY_DRIVER(fileNotExistsName_wr, aMed, aMesh); + + //Trying open non existing file + CPPUNIT_ASSERT_THROW(aInvalidGibiMedWrDriver->open(), MEDEXCEPTION); + + delete aInvalidGibiMedWrDriver; + } + + //Trying create gibi med write only driver with null MED and MESH + CPPUNIT_ASSERT_THROW(new GIBI_MED_WRONLY_DRIVER(tmpfilemed, aMed_1, aMesh_NULL), MEDEXCEPTION); + + //Creation a correct gibi med write only drivers + GIBI_MED_WRONLY_DRIVER *aGibiMedWrDriver = + new GIBI_MED_WRONLY_DRIVER(filenamemed_wr, aMed, aMesh); + + //Check driver + CPPUNIT_ASSERT(aGibiMedWrDriver); + + //Trying write mesh to file, if file is not open + CPPUNIT_ASSERT_THROW(aGibiMedWrDriver->write(), MEDEXCEPTION); + + //Test open() method + CPPUNIT_ASSERT_NO_THROW(aGibiMedWrDriver->open()); + + //Trying open file secondary. + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) Exception is generated, but second call to open() function breaks driver + //CPPUNIT_ASSERT_THROW(aGibiMedWrDriver->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aGibiMedWrDriver->open()); + //#endif + + //Test write() method + CPPUNIT_ASSERT_NO_THROW(aGibiMedWrDriver->write()); + + //Test read() method for GIBI MED WRITE ONLY driver + CPPUNIT_ASSERT_THROW(aGibiMedWrDriver->read(), MEDEXCEPTION); + + //Test close method + CPPUNIT_ASSERT_NO_THROW(aGibiMedWrDriver->close()); + + //Default constructor + GIBI_MED_WRONLY_DRIVER aGibiMedWrDriverCpy_1; + + //Test copy constructor + { + GIBI_MED_WRONLY_DRIVER aGibiMedWrDriverCpy_2 (*aGibiMedWrDriver); + + //Test (bool operator ==) defined in GENDRIVER class + // commented since this test is not important + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) Copy constructor of GIBI_MED_WRONLY_DRIVER is not implemented!!! + //CPPUNIT_ASSERT(aGibiMedWrDriverCpy_2.GENDRIVER::operator==(*aGibiMedWrDriver)); + //#endif + + //Test (friend ostream & operator <<) defined GENDRIVER class + // commented since this test is not important + //ostringstream medwostr1, medwostr2; + //medwostr1 << *aGibiMedWrDriver; + //medwostr2 << aGibiMedWrDriverCpy_2; + //CPPUNIT_ASSERT(medwostr1.str() != ""); + //#ifdef ENABLE_FORCED_FAILURES + // Copy constructor of GIBI_MED_WRONLY_DRIVER is not implemented!!! + //CPPUNIT_ASSERT(medwostr1.str() == medwostr2.str()); + //#endif + } + + delete aGibiMedWrDriver; + } + + //Delete all objects + delete aMesh; + delete aMesh_2; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_Grid.cxx b/src/MEDMEMCppTest/MEDMEMTest_Grid.cxx new file mode 100644 index 000000000..410a84d22 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Grid.cxx @@ -0,0 +1,707 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "MEDMEM_define.hxx" +#include "MEDMEM_Grid.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Med.hxx" +#include "MEDMEM_MedMedDriver.hxx" +#include "MEDMEM_MedMeshDriver.hxx" + +#include <sstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + + +/*! + * Check methods (44), defined in MEDMEM_Grid.hxx: + * class GRID: public MESH { + * (+) GRID(); + * (+) GRID(const MED_EN::med_grid_type type); + * (BUG:operator=() not implemented but init() not called) GRID(const GRID &m); + * (+) GRID(driverTypes driverType, const string & fileName="",const string & meshName=""); + * (+) GRID(const std::vector<std::vector<double> >& xyz_array, + * const std::vector<std::string>& coord_name, + * const std::vector<std::string>& coord_unit, + * const MED_EN::med_grid_type type=MED_EN::MED_CARTESIAN); + * (NOT IMPLEMENTED) GRID & operator=(const GRID &m); + * (+) virtual ~GRID(); + * (+) virtual void init(); + * (tested together with getCoordinateptr() as it is called + * internally from there first of all. + * Moreover, fillCoordinates should be made private to avoid + * ambiguity druing in GRID class usage.) void fillCoordinates() const; + * (tested together with getConnectivityptr()) void fillConnectivity() const; + * (+) inline void makeUnstructured();//fill coordinates and connectivity of MESH + * (+) void fillMeshAfterRead(); + * (+) void writeUnstructured(int index=0, const string & driverName = ""); + * (+) void read(int index=0); + * (+) inline int getNodeNumber(const int i, const int j=0, const int k=0) const; + * (+) inline int getCellNumber(const int i, const int j=0, const int k=0) const; + * (+) int getEdgeNumber + * (const int Axis, const int i, const int j=0, const int k=0) const throw (MEDEXCEPTION); + * (+) int getFaceNumber + * (const int Axis, const int i, const int j=0, const int k=0) const throw (MEDEXCEPTION); + * (+) void getNodePosition(const int Number, int& i, int& j, int& k) const throw (MEDEXCEPTION); + * (+) void getCellPosition(const int Number, int& i, int& j, int& k) const throw (MEDEXCEPTION); + * (+) void getEdgePosition + * (const int Number, int& Axis, int& i, int& j, int& k) const throw (MEDEXCEPTION); + * (+) void getFacePosition + * (const int Number, int& Axis, int& i, int& j, int& k) const throw (MEDEXCEPTION); + * (+) inline MED_EN::med_grid_type getGridType() const; + * (+) int getArrayLength(const int Axis) const throw (MEDEXCEPTION); + * (+) const double getArrayValue (const int Axis, const int i) const throw (MEDEXCEPTION); + * (+) inline const COORDINATE * getCoordinateptr() const; + * (+) inline const double * getCoordinates(MED_EN::medModeSwitch Mode) const; + * (+) inline const double getCoordinate(int Number,int Axis) const; + * (+) inline int getNumberOfTypes(MED_EN::medEntityMesh Entity) const; + * (+) inline int getNumberOfTypesWithPoly(MED_EN::medEntityMesh Entity) const; + * (+) inline const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const; + * (+) MED_EN::medGeometryElement * getTypesWithPoly(MED_EN::medEntityMesh Entity) const; + * (+) inline const CELLMODEL * getCellsTypes(MED_EN::medEntityMesh Entity) const; + * (+) const int * getGlobalNumberingIndex(MED_EN::medEntityMesh Entity) const; + * (+) inline int getNumberOfElements + * (MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type) const; + * (+) inline int getNumberOfElementsWithPoly + * (MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type) const; + * (+) inline bool existConnectivity + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; + * (+) inline MED_EN::medGeometryElement getElementType + * (MED_EN::medEntityMesh Entity, int Number) const; + * (+) inline MED_EN::medGeometryElement getElementTypeWithPoly + * (MED_EN::medEntityMesh Entity, int Number) const; + * (+) inline void calculateConnectivity(MED_EN::medModeSwitch Mode, + * MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity) const; + * (+) inline const CONNECTIVITY* getConnectivityptr() const; + * (+) inline const int * getConnectivity + * (MED_EN::medModeSwitch Mode, MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type) const; + * (+) inline const int * getConnectivityIndex(MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity) const; + * (+) inline const int * getReverseConnectivity(MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; + * (+) inline const int * getReverseConnectivityIndex(MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; + * (+) inline void setGridType(MED_EN::med_grid_type gridType); + * } + */ +void MEDMEMTest::testGrid() +{ + string datadir = getenv("MED_ROOT_DIR"); + string filename = datadir + "/share/salome/resources/med/test19.med" ; + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if (tmp_dir == "") + tmp_dir = "/tmp"; + string filenameout21 = tmp_dir + "/myGridWrite_grid21.med"; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filenameout21); + + // Remove file in advance to ensure it does not exist at the moment of writing, + // because files are not removed by the MEDMEMTest_TmpFilesRemover in case of + // Segmentation Fault (in previous tests execution). + { + MEDMEMTest_TmpFilesRemover aRemover1; + aRemover1.Register(filenameout21); + } + + MED * myMed = new MED() ; + MED_MED_RDONLY_DRIVER myMeshDriver (filename, myMed); + myMeshDriver.open(); + myMeshDriver.readFileStruct(); + myMeshDriver.close(); + + int nbMeshes = myMed->getNumberOfMeshes(); + CPPUNIT_ASSERT(nbMeshes); + + deque<string> mesh_names = myMed->getMeshNames(); + CPPUNIT_ASSERT(mesh_names.size() != 0); + + ////////////////////////////// + // test1 "CARTESIAN GRID" // + ////////////////////////////// + { + MESH* myMesh = myMed->getMesh(mesh_names[0]); + myMesh->read(); + + CPPUNIT_ASSERT(myMesh != NULL); + CPPUNIT_ASSERT(myMesh->getIsAGrid()); + + GRID* myGrid = dynamic_cast<GRID*>(myMesh); + CPPUNIT_ASSERT(myGrid); + + CPPUNIT_ASSERT_THROW(myGrid->getArrayLength(0), MEDEXCEPTION); + + int I, J, K; + CPPUNIT_ASSERT_NO_THROW(I = myGrid->getArrayLength(1)); + CPPUNIT_ASSERT_NO_THROW(J = myGrid->getArrayLength(2)); + CPPUNIT_ASSERT_NO_THROW(K = myGrid->getArrayLength(3)); + + CPPUNIT_ASSERT(I); + CPPUNIT_ASSERT(J); + + med_grid_type grid_type = myGrid->getGridType(); + CPPUNIT_ASSERT_MESSAGE("Wrong grid type", grid_type == MED_CARTESIAN); + + const double * coordinates = myGrid->getCoordinates(MED_FULL_INTERLACE); + int SpaceDimension = myGrid->getSpaceDimension(); + for (int axe = 0; axe < SpaceDimension; axe++) { + for (int num = 0; num < myGrid->getNumberOfNodes(); num++) { + double coordinate; + CPPUNIT_ASSERT_NO_THROW(coordinate = myGrid->getCoordinate(num + 1, axe + 1)); + //cout << "coordinate = " << coordinate << endl; + CPPUNIT_ASSERT(fabs(coordinate - coordinates[(num * SpaceDimension)+axe]) < 0.001); + } + } + + int nbTypesCell = myGrid->getNumberOfTypes(MED_CELL); + CPPUNIT_ASSERT(nbTypesCell == 1); + + const medGeometryElement* types; + CPPUNIT_ASSERT_NO_THROW(types = myGrid->getTypes(MED_CELL)); + //#ifdef ENABLE_FORCED_FAILURES + // Compilation warning about GRID::getTypes(): + // "inline function + // `virtual const MED_EN::medGeometryElement* MEDMEM::GRID::getTypes(MED_EN::medEntityMesh) const' + // used but never defined". + // In MEDMEM_Grid.hxx: + // inline const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const; + // But implemented in MEDMEM_Grid.cxx: + // const MED_EN::medGeometryElement * GRID::getTypes(MED_EN::medEntityMesh entity) const + // + // EAP: inline removed + //CPPUNIT_FAIL("Problem with GRID::getTypes() method implementation."); + //#endif + CPPUNIT_ASSERT(types[0] == MED_QUAD4); + + int nbElem = 0; + CPPUNIT_ASSERT_NO_THROW(nbElem = myGrid->getNumberOfElements(MED_CELL,types[0])); + CPPUNIT_ASSERT(nbElem); + + int nbNodes = myGrid->getNumberOfNodes(); + CPPUNIT_ASSERT(nbNodes); + + int ijkNode[3]; + int NodeNumber; + for (int nbNode = 1; nbNode <= nbNodes; nbNode++) { + CPPUNIT_ASSERT_NO_THROW(myGrid->getNodePosition(nbNode, ijkNode[0], ijkNode[1], ijkNode[2])); + CPPUNIT_ASSERT_NO_THROW(NodeNumber = myGrid->getNodeNumber(ijkNode[0], ijkNode[1], ijkNode[2])); + CPPUNIT_ASSERT(NodeNumber == nbNode); + } + + int nbCells = myGrid->getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS); + CPPUNIT_ASSERT(nbCells); + + int ijkCell[3]; + int CellNumber; + for (int nbCell = 1; nbCell <= nbCells; nbCell++) { + CPPUNIT_ASSERT_NO_THROW(myGrid->getCellPosition(nbCell, ijkCell[0], ijkCell[1], ijkCell[2])); + CPPUNIT_ASSERT_NO_THROW(CellNumber = myGrid->getCellNumber(ijkCell[0], ijkCell[1], ijkCell[2])); + CPPUNIT_ASSERT(CellNumber == nbCell); + } + + int nbEdges = myGrid->getNumberOfElements(MED_EDGE, MED_ALL_ELEMENTS); + CPPUNIT_ASSERT(nbEdges); + + int ijkAxisEdge[4]; + int EdgeNumber; + for (int nbEdge = 1; nbEdge <= nbEdges; nbEdge++) { + CPPUNIT_ASSERT_NO_THROW(myGrid->getEdgePosition(nbEdge, ijkAxisEdge[0], ijkAxisEdge[1], + ijkAxisEdge[2], ijkAxisEdge[3])); + CPPUNIT_ASSERT_NO_THROW(EdgeNumber = myGrid->getEdgeNumber(ijkAxisEdge[0], ijkAxisEdge[1], + ijkAxisEdge[2], ijkAxisEdge[3])); + CPPUNIT_ASSERT(EdgeNumber == nbEdge); + } + + int nbFaces = myGrid->getNumberOfElements(MED_FACE, MED_ALL_ELEMENTS); + CPPUNIT_ASSERT(nbFaces == 0); + + //#ifdef ENABLE_FORCED_FAILURES + // To remove getFacePosition() from API + //CPPUNIT_FAIL("ERROR: nbFaces == 0, but getFacePosition(AnyNumber, ...) - return position(i,j,k)"); + //#endif + int ijkAxisFace[4]; + CPPUNIT_ASSERT_NO_THROW(myGrid->getFacePosition(6, ijkAxisFace[0], ijkAxisFace[1], + ijkAxisFace[2], ijkAxisFace[3])); + CPPUNIT_ASSERT(ijkAxisFace[0]); + CPPUNIT_ASSERT(ijkAxisFace[1]); + CPPUNIT_ASSERT(ijkAxisFace[2]); + + /*int FaceNumber; + for(int nbFace = 1; nbFace <= nbFaces; nbFace++) + { + CPPUNIT_ASSERT_NO_THROW( myGrid->getFacePosition(nbFace, ijkAxisFace[0], ijkAxisFace[1], + ijkAxisFace[2], ijkAxisFace[3])); + CPPUNIT_ASSERT_NO_THROW( EdgeNumber = myGrid->getEdgeNumber(ijkAxisFace[0], ijkAxisFace[1], + ijkAxisFace[2], ijkAxisFace[3])); + CPPUNIT_ASSERT(FaceNumber == nbFace); + }*/ + + bool existConnect = false; + CPPUNIT_ASSERT_NO_THROW(existConnect = myGrid->existConnectivity(MED_NODAL, MED_CELL)); + if (!existConnect) { + CPPUNIT_ASSERT_NO_THROW(myGrid->calculateConnectivity(MED_FULL_INTERLACE, MED_NODAL, MED_CELL)); + CPPUNIT_ASSERT(myGrid->existConnectivity(MED_NODAL, MED_CELL)); + } + + const int* Connectivity; + const int* connectivity_index; + CPPUNIT_ASSERT_NO_THROW(Connectivity = myGrid->getConnectivity(MED_FULL_INTERLACE, MED_NODAL, + MED_CELL, types[0])); + CPPUNIT_ASSERT_NO_THROW(connectivity_index = myGrid->getConnectivityIndex(MED_NODAL, MED_CELL)); + cout << "Nodal connectivity" << endl; + for (int j = 0; j < nbElem; j++) { + cout << "Element "<< j+1 << " : "; + for (int k = connectivity_index[j]; k < connectivity_index[j+1]; k++) + cout << Connectivity[k-1] << " "; + cout << endl; + } + + const int * ReverseNodalConnectivity; + const int * ReverseConnectivityIndex; + CPPUNIT_ASSERT_NO_THROW(ReverseNodalConnectivity = myGrid->getReverseConnectivity(MED_NODAL)); + CPPUNIT_ASSERT_NO_THROW(ReverseConnectivityIndex = myGrid->getReverseConnectivityIndex(MED_NODAL)); + for (int i = 0; i < nbNodes; i++) { + cout << "Node "<< i+1 << " : "; + for (int j = ReverseConnectivityIndex[i]; j < ReverseConnectivityIndex[i+1]; j++) + cout << ReverseNodalConnectivity[j-1] << " "; + cout << endl; + } + + const int* myGlobalNbIdx; + CPPUNIT_ASSERT_NO_THROW(myGlobalNbIdx = myGrid->getGlobalNumberingIndex(MED_CELL)); + for (int i = 0; i <= nbTypesCell; i++) { + if (i == nbTypesCell) { + CPPUNIT_ASSERT_THROW(myGrid->getElementType(MED_CELL, myGlobalNbIdx[i]), MEDEXCEPTION); + break; + } + medGeometryElement aElem, geomPolyElem; + CPPUNIT_ASSERT_NO_THROW(aElem = myGrid->getElementType(MED_CELL, myGlobalNbIdx[i])); + CPPUNIT_ASSERT_NO_THROW(geomPolyElem = myGrid->getElementTypeWithPoly(MED_CELL, myGlobalNbIdx[i])); + CPPUNIT_ASSERT(types[0] == aElem); + CPPUNIT_ASSERT(geomPolyElem == aElem); + } + + CPPUNIT_ASSERT_NO_THROW(existConnect = myGrid->existConnectivity(MED_DESCENDING, MED_CELL)); + if (!existConnect) { + CPPUNIT_ASSERT_NO_THROW(myGrid->calculateConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, MED_CELL)); + CPPUNIT_ASSERT(myGrid->existConnectivity(MED_DESCENDING, MED_CELL)); + } + + const int* ConnectivityDes; + const int* connectivity_index_des; + CPPUNIT_ASSERT_NO_THROW(ConnectivityDes = myGrid->getConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, + MED_CELL, MED_ALL_ELEMENTS)); + CPPUNIT_ASSERT_NO_THROW(connectivity_index_des = + myGrid->getConnectivityIndex(MED_DESCENDING, MED_CELL)); + cout<<"Descending connectivity"<<endl; + for (int j = 0; j < nbElem; j++) { + cout << "Element "<< j+1 << " : "; + for (int k = connectivity_index_des[j]; k < connectivity_index_des[j+1]; k++) + cout << ConnectivityDes[k-1] << " "; + cout << endl; + } + + const int * ReverseDesConnectivity; + const int * ReverseConnectivityIndexDes; + CPPUNIT_ASSERT_NO_THROW(ReverseDesConnectivity = myGrid->getReverseConnectivity(MED_DESCENDING)); + CPPUNIT_ASSERT_NO_THROW(ReverseConnectivityIndexDes = + myGrid->getReverseConnectivityIndex(MED_DESCENDING)); + for (int i = 0; i < nbNodes; i++) { + cout << "Node "<< i+1 << " : "; + for (int j = ReverseConnectivityIndexDes[i]; j < ReverseConnectivityIndexDes[i+1]; j++) + cout << ReverseDesConnectivity[j-1] << " "; + cout << endl; + } + + //TEST POLY + { + int nbPolytypes; + //test getNumberOfTypesWithPoly() - a grid has one type + CPPUNIT_ASSERT_NO_THROW(nbPolytypes = myGrid->getNumberOfTypesWithPoly(MED_CELL)); + CPPUNIT_ASSERT(nbPolytypes == 1 ); + + const MED_EN::medGeometryElement * PolyTypes, *Types; + CPPUNIT_ASSERT_NO_THROW(PolyTypes = myGrid->getTypesWithPoly(MED_CELL)); + CPPUNIT_ASSERT_NO_THROW(Types = myGrid->getTypes(MED_CELL)); + CPPUNIT_ASSERT_EQUAL(PolyTypes[nbPolytypes-1],Types[nbPolytypes-1]); + + for (int t = 0; t < nbPolytypes; t++) { + int nbElPoly, nbEl; + CPPUNIT_ASSERT_NO_THROW(nbElPoly = myGrid->getNumberOfElementsWithPoly(MED_CELL, PolyTypes[t])); + CPPUNIT_ASSERT_NO_THROW(nbEl = myGrid->getNumberOfElements(MED_CELL, PolyTypes[t])); + CPPUNIT_ASSERT(nbElPoly == nbEl); + } + } + } + + ////////////////////////////// + // test2 "MED_BODY_FITTED" // + ////////////////////////////// + { + MESH* myMesh1 = myMed->getMesh(mesh_names[1]); + myMesh1->read(); + + CPPUNIT_ASSERT(myMesh1 != NULL); + CPPUNIT_ASSERT(myMesh1->getIsAGrid()); + + GRID* myGrid1 = dynamic_cast<GRID*>(myMesh1); + CPPUNIT_ASSERT(myGrid1); + + int I, J, K; + CPPUNIT_ASSERT_NO_THROW(I = myGrid1->getArrayLength(1)); + CPPUNIT_ASSERT_NO_THROW(J = myGrid1->getArrayLength(2)); + CPPUNIT_ASSERT_NO_THROW(K = myGrid1->getArrayLength(3)); + + CPPUNIT_ASSERT(I == 2); + CPPUNIT_ASSERT(J == 2); + + med_grid_type grid_type = myGrid1->getGridType(); + CPPUNIT_ASSERT_MESSAGE("Wrong grid type", grid_type == MED_BODY_FITTED); + + int nbTypesCell = myGrid1->getNumberOfTypes(MED_CELL); + CPPUNIT_ASSERT(nbTypesCell == 1); + + const medGeometryElement* types1; + CPPUNIT_ASSERT_NO_THROW( types1 = myGrid1->getTypes(MED_CELL) ); + CPPUNIT_ASSERT( types1[0] == MED_QUAD4); + + int nbElem; + CPPUNIT_ASSERT_NO_THROW(nbElem = myGrid1->getNumberOfElements(MED_CELL, types1[0])); + CPPUNIT_ASSERT(nbElem); + + const int* BodyConnectivity; + const int* body_connectivity_index; + int ijkNodeBody[3]; + CPPUNIT_ASSERT_NO_THROW(BodyConnectivity = myGrid1->getConnectivity(MED_FULL_INTERLACE, MED_NODAL, + MED_CELL, types1[0])); + CPPUNIT_ASSERT_NO_THROW(body_connectivity_index = myGrid1->getConnectivityIndex(MED_NODAL, MED_CELL)); + cout<<"Nodal connectivity"<<endl; + for (int j = 0; j < nbElem; j++) { + cout << "Element "<< j+1 << " : "; + for (int k = body_connectivity_index[j]; k < body_connectivity_index[j+1]; k++){ + CPPUNIT_ASSERT_NO_THROW(myGrid1->getNodePosition(BodyConnectivity[k-1], ijkNodeBody[0], + ijkNodeBody[1], ijkNodeBody[2])); + cout << BodyConnectivity[k-1] << " "; + } + cout << endl; + } + } + + /////////////////////////////////////////////////// + // test3 "maa1" which in fact is not a pure GRID // + /////////////////////////////////////////////////// + { + MESH* myMesh2 = NULL; + + myMesh2 = myMed->getMesh(mesh_names[2]); + myMesh2->read(); + + CPPUNIT_ASSERT(myMesh2 != NULL); + CPPUNIT_ASSERT(!(myMesh2->getIsAGrid())); + } + + delete myMed; + + //////////////////////////// + // test4 create new GRID // + //////////////////////////// + + // Default constructor and destructor + { + GRID* myGrid2 = new GRID(); + CPPUNIT_ASSERT(myGrid2->getIsAGrid()); + CPPUNIT_ASSERT(myGrid2->getGridType() == MED_CARTESIAN); + CPPUNIT_ASSERT(!myGrid2->getArrayLength(1)); + CPPUNIT_ASSERT(!myGrid2->getArrayLength(2)); + CPPUNIT_ASSERT(!myGrid2->getArrayLength(3)); + delete myGrid2; + } + + // Constructor with grid type, setGridType() + { + GRID* myGrid2 = new GRID(MED_POLAR); + CPPUNIT_ASSERT(myGrid2->getGridType() == MED_POLAR); + myGrid2->setGridType(MED_CARTESIAN); + CPPUNIT_ASSERT(myGrid2->getGridType() == MED_CARTESIAN); + delete myGrid2; + } + + // Constructor with coordinate values, getArrayValue(), init() + { + vector<vector<double> > xyz; + const int nbCoords = 3; + xyz.resize(nbCoords); + for ( int i = 0; i < nbCoords; i++ ) + { + xyz[i].resize(i + 2); + for ( int j = 0; j < i + 2; j++ ) + xyz[i][j] = j; + } + vector<string> Coord_Names; + Coord_Names.resize(nbCoords); + Coord_Names[0] = "X"; + Coord_Names[1] = "Y"; + Coord_Names[2] = "Z"; + + vector<string> Coord_Units; + Coord_Units.resize(nbCoords); + for(int i = 0; i < 3; i++) + Coord_Units[i] = "cm"; + + GRID* myGrid2; + + try{ + myGrid2 = new GRID(xyz, Coord_Names, Coord_Units, MED_CARTESIAN); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + // testing getCoordinateptr() and fillCoordinates() + // We fill a map of all possible coordinate triples. + // After iteration through all coordinates, this map should contain only "true" as data. + // "true" in some map element during iteration means duplicated node position. + // "false" in some map element after iteration means empty node position. + map<int, bool> found; + for ( int i1 = 0; i1 < xyz[0].size(); i1++ ) + for ( int i2 = 0; i2 < xyz[1].size(); i2++ ) + for ( int i3 = 0; i3 < xyz[2].size(); i3++ ) + found[int(xyz[0][i1] * 100 + xyz[1][i2] * 10 + xyz[2][i3])] = false; + + COORDINATE* coords = (COORDINATE*)myGrid2->getCoordinateptr(); + CPPUNIT_ASSERT(coords); + for (int num = 0; num < myGrid2->getNumberOfNodes(); num++) { + int x = int(coords->getCoordinate(num + 1, 1)); + int y = int(coords->getCoordinate(num + 1, 2)); + int z = int(coords->getCoordinate(num + 1, 3)); + CPPUNIT_ASSERT(!found[x * 100 + y * 10 + z]); + found[x * 100 + y * 10 + z] = true; + } + + for ( map<int, bool>::iterator it = found.begin(); it != found.end(); it++ ) + CPPUNIT_ASSERT((*it).second); + + // Testing fillConnectivity() and getConnectivityptr() + // Basic testing: presence of connectivity arrays, element types and number of elements + CONNECTIVITY* conn = (CONNECTIVITY*)myGrid2->getConnectivityptr(); + CPPUNIT_ASSERT(conn); + bool hasFaces = myGrid2->getArrayLength(3), hasEdges = myGrid2->getArrayLength(2); + medGeometryElement aCellGeometry; + if (hasFaces) aCellGeometry = MED_HEXA8; + else if (hasEdges) aCellGeometry = MED_QUAD4; + else aCellGeometry = MED_SEG2; + CPPUNIT_ASSERT(conn->getElementType(MED_CELL, 1) == aCellGeometry); + CPPUNIT_ASSERT(conn->existConnectivity(MED_NODAL, MED_CELL)); + CPPUNIT_ASSERT(conn->existConnectivity(MED_DESCENDING, MED_CELL)); + //test getCellsTypes + CELLMODEL* cellmodel = (CELLMODEL*)myGrid2->getCellsTypes(MED_CELL); + CPPUNIT_ASSERT(cellmodel); + + int nbCells, nbFaces, nbEdges; + + int iLen = myGrid2->getArrayLength(1); + int jLen = myGrid2->getArrayLength(2); + int kLen = myGrid2->getArrayLength(3); + int iLenMin1 = myGrid2->getArrayLength(1)-1; + int jLenMin1 = myGrid2->getArrayLength(2)-1; + int kLenMin1 = myGrid2->getArrayLength(3)-1; + const int* aCellCount = conn->getGlobalNumberingIndex(MED_CELL); + nbCells = iLenMin1 * jLenMin1 * kLenMin1; + CPPUNIT_ASSERT(aCellCount[1] - 1 == nbCells); + + if (hasFaces){ + CPPUNIT_ASSERT(conn->getElementType(MED_FACE, 1) == MED_QUAD4); + nbFaces = iLen * jLenMin1 * kLenMin1; + nbFaces += jLen * kLenMin1 * iLenMin1; + nbFaces += kLen * iLenMin1 * jLenMin1; + const int* aFaceCount = conn->getGlobalNumberingIndex(MED_FACE); + CPPUNIT_ASSERT(aFaceCount[1] - 1 == nbFaces); + CPPUNIT_ASSERT(conn->existConnectivity(MED_NODAL, MED_FACE)); + //test getCellsTypes + CELLMODEL* cellmodelF = (CELLMODEL*)myGrid2->getCellsTypes(MED_FACE); + CPPUNIT_ASSERT(cellmodelF); + } + if (hasEdges){ + CPPUNIT_ASSERT(conn->getElementType(MED_EDGE, 1) == MED_SEG2); + if (kLen) { // 3d grid + nbEdges = iLenMin1 * jLen * kLen; + nbEdges += jLenMin1 * kLen * iLen; + nbEdges += kLenMin1 * iLen * jLen; + } + else if (jLen) { // 2d + nbEdges = iLenMin1 * jLen; + nbEdges += jLenMin1 * iLen; + } + const int* anEdgeCount = conn->getGlobalNumberingIndex(MED_EDGE); + CPPUNIT_ASSERT(anEdgeCount[1] - 1 == nbEdges); + CPPUNIT_ASSERT(conn->existConnectivity(MED_NODAL, MED_EDGE)); + //test getCellsTypes + CELLMODEL* cellmodelE = (CELLMODEL*)myGrid2->getCellsTypes(MED_EDGE); + CPPUNIT_ASSERT(cellmodelE); + + } + + // Testing getArrayValue() + for ( int ii = 1; ii <= nbCoords; ii++ ) + for ( int jj = 0; jj < ii + 1; jj++ ) + CPPUNIT_ASSERT(myGrid2->getArrayValue(ii, jj) == xyz[ii - 1][jj]); + + CPPUNIT_ASSERT_THROW(myGrid2->getArrayValue(nbCoords + 1, 0), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(myGrid2->getArrayValue(1, myGrid2->getArrayLength(1) + 1), MEDEXCEPTION); + myGrid2->setGridType(MED_POLAR); + + //testing read/write functions + + // add new driver + int idGridV21; + + try + { + idGridV21 = myGrid2->addDriver(MED_DRIVER,filenameout21); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + // write this driver to file as an unstructured mesh + CPPUNIT_ASSERT_NO_THROW(myGrid2->writeUnstructured(idGridV21)); + + GRID* myGrid3 = new GRID(); + // add new driver for myGrid3 + int driver; + CPPUNIT_ASSERT_NO_THROW(driver = myGrid3->addDriver(MED_DRIVER, filenameout21)); + + //#ifdef ENABLE_FORCED_FAILURES + // ? (BUG) ? "The mesh dimension |-1| seems to be incorrect for + // the mesh : |Default Mesh Name|" + // TO CHECK writing CAREFULLY + // !!!!!!!!! Mesh was written as UNSTRUCTURED + // changed on THROW accoding to EAP + CPPUNIT_ASSERT_THROW(myGrid3->read(driver),MEDEXCEPTION); + //CPPUNIT_ASSERT_NO_THROW(myGrid3->read(driver)); + + // Testing getArrayValue() + //for ( int ii = 1; ii <= nbCoords; ii++ ) + // for ( int jj = 0; jj < ii + 1; jj++ ) + // CPPUNIT_ASSERT(myGrid3->getArrayValue(ii, jj) == xyz[ii - 1][jj]); + + //CPPUNIT_ASSERT(myGrid3->getGridType() == MED_POLAR); + //#endif + + delete myGrid3; + + //test init() + CPPUNIT_ASSERT_NO_THROW(myGrid2->init()); + CPPUNIT_ASSERT(myGrid2->getGridType() == MED_CARTESIAN); + CPPUNIT_ASSERT(myGrid2->getArrayLength(1) == 0); + CPPUNIT_ASSERT(myGrid2->getArrayLength(2) == 0); + CPPUNIT_ASSERT(myGrid2->getArrayLength(3) == 0); + //#ifdef ENABLE_FAULTS + // (BUG) Segmentation Fault + myGrid2->makeUnstructured(); + //#endif + //#ifdef ENABLE_FORCED_FAILURES + // TODO: fix it - unstructured mesh should be simply empty, actually useless + //CPPUNIT_FAIL("ERROR:makeUnstructured() - there is no check if grid is empty or not"); + //#endif + + delete myGrid2; + } + + //#ifdef ENABLE_FORCED_FAILURES + { + GRID* myGrid2; + // ? (BUG) ? MED Exception in /dn20/salome/jfa/V3/SRC/MED_SRC/src/MEDMEM/MEDMEM_MedM + //eshDriver21.cxx [430] : MED_MESH_RDONLY_DRIVER21::getCOORDINATE() : The number + //of nodes |0| seems to be incorrect for the mesh : |bodyfitted| + // Not clear what is wrong + CPPUNIT_ASSERT_NO_THROW(myGrid2 = new GRID(MED_DRIVER, filename, mesh_names[1])); + + // Check if something has been read - full mesh data testing is above + CPPUNIT_ASSERT(myGrid2->getSpaceDimension()); + CPPUNIT_ASSERT(myGrid2->getNumberOfNodes()); + CPPUNIT_ASSERT(myGrid2->getNumberOfTypes(MED_CELL) == 1); + const medGeometryElement* types2; + CPPUNIT_ASSERT_NO_THROW(types2 = myGrid2->getTypes(MED_CELL)); + int nbElem; + CPPUNIT_ASSERT_NO_THROW(nbElem = myGrid2->getNumberOfElements(MED_CELL,types2[0])); + CPPUNIT_ASSERT(nbElem); + delete myGrid2; + } + //#endif + + { + GRID* myGrid4 = new GRID(); + filename = datadir + "/share/salome/resources/med/pointe.med"; + myGrid4->setName("maa1"); + MED_MESH_RDONLY_DRIVER myMeshDriver(filename, myGrid4); + myMeshDriver.setMeshName("maa1"); + + // add new driver for myGrid4 + int driver; + CPPUNIT_ASSERT_NO_THROW(driver = myGrid4->addDriver(myMeshDriver)); + + // ??? ERROR:myGrid4->fillMeshAfterRead()- this method is incomplete: + // currently it only resets _is_coordinates_filled and _is_connectivity_filled + // flags that leads to grid reconstruction + + // MED Exception : MED_MESH_RDONLY_DRIVER21::getGRID() : The number + // of nodes |-1| seems to be incorrect for the mesh : |maa1| + // But this exception seems to be correct reaction on attempt + // to read a grid from a file, which does not contain it. + CPPUNIT_ASSERT_THROW(myGrid4->read(driver), MEDEXCEPTION); + //CPPUNIT_ASSERT_NO_THROW(myGrid4->read(driver)); + /*CPPUNIT_ASSERT(myGrid4->getArrayLength(1) == 0); + CPPUNIT_ASSERT(myGrid4->getArrayLength(2) == 0); + CPPUNIT_ASSERT(myGrid4->getArrayLength(3) == 0); + myGrid4->fillMeshAfterRead(); + CPPUNIT_ASSERT(myGrid4->getArrayLength(1) != 0); + CPPUNIT_ASSERT(myGrid4->getArrayLength(2) != 0); + CPPUNIT_ASSERT(myGrid4->getArrayLength(3) != 0);*/ + + delete myGrid4; + } +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_Grid_fault.cxx b/src/MEDMEMCppTest/MEDMEMTest_Grid_fault.cxx new file mode 100644 index 000000000..58b39ef10 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Grid_fault.cxx @@ -0,0 +1,702 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "MEDMEM_define.hxx" +#include "MEDMEM_Grid.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Med.hxx" +#include "MEDMEM_MedMedDriver.hxx" +#include "MEDMEM_MedMeshDriver.hxx" + +#include <sstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + + +/*! + * Check methods (44), defined in MEDMEM_Grid.hxx: + * class GRID: public MESH { + * (+) GRID(); + * (+) GRID(const MED_EN::med_grid_type type); + * (BUG:operator=() not implemented but init() not called) GRID(const GRID &m); + * (+) GRID(driverTypes driverType, const string & fileName="",const string & meshName=""); + * (+) GRID(const std::vector<std::vector<double> >& xyz_array, + * const std::vector<std::string>& coord_name, + * const std::vector<std::string>& coord_unit, + * const MED_EN::med_grid_type type=MED_EN::MED_CARTESIAN); + * (NOT IMPLEMENTED) GRID & operator=(const GRID &m); + * (+) virtual ~GRID(); + * (+) virtual void init(); + * (tested together with getCoordinateptr() as it is called + * internally from there first of all. + * Moreover, fillCoordinates should be made private to avoid + * ambiguity druing in GRID class usage.) void fillCoordinates() const; + * (tested together with getConnectivityptr()) void fillConnectivity() const; + * (+) inline void makeUnstructured();//fill coordinates and connectivity of MESH + * (+) void fillMeshAfterRead(); + * (+) void writeUnstructured(int index=0, const string & driverName = ""); + * (+) void read(int index=0); + * (+) inline int getNodeNumber(const int i, const int j=0, const int k=0) const; + * (+) inline int getCellNumber(const int i, const int j=0, const int k=0) const; + * (+) int getEdgeNumber + * (const int Axis, const int i, const int j=0, const int k=0) const throw (MEDEXCEPTION); + * (+) int getFaceNumber + * (const int Axis, const int i, const int j=0, const int k=0) const throw (MEDEXCEPTION); + * (+) void getNodePosition(const int Number, int& i, int& j, int& k) const throw (MEDEXCEPTION); + * (+) void getCellPosition(const int Number, int& i, int& j, int& k) const throw (MEDEXCEPTION); + * (+) void getEdgePosition + * (const int Number, int& Axis, int& i, int& j, int& k) const throw (MEDEXCEPTION); + * (+) void getFacePosition + * (const int Number, int& Axis, int& i, int& j, int& k) const throw (MEDEXCEPTION); + * (+) inline MED_EN::med_grid_type getGridType() const; + * (+) int getArrayLength(const int Axis) const throw (MEDEXCEPTION); + * (+) const double getArrayValue (const int Axis, const int i) const throw (MEDEXCEPTION); + * (+) inline const COORDINATE * getCoordinateptr() const; + * (+) inline const double * getCoordinates(MED_EN::medModeSwitch Mode) const; + * (+) inline const double getCoordinate(int Number,int Axis) const; + * (+) inline int getNumberOfTypes(MED_EN::medEntityMesh Entity) const; + * (+) inline int getNumberOfTypesWithPoly(MED_EN::medEntityMesh Entity) const; + * (+) inline const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const; + * (+) MED_EN::medGeometryElement * getTypesWithPoly(MED_EN::medEntityMesh Entity) const; + * (+) inline const CELLMODEL * getCellsTypes(MED_EN::medEntityMesh Entity) const; + * (+) const int * getGlobalNumberingIndex(MED_EN::medEntityMesh Entity) const; + * (+) inline int getNumberOfElements + * (MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type) const; + * (+) inline int getNumberOfElementsWithPoly + * (MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type) const; + * (+) inline bool existConnectivity + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; + * (+) inline MED_EN::medGeometryElement getElementType + * (MED_EN::medEntityMesh Entity, int Number) const; + * (+) inline MED_EN::medGeometryElement getElementTypeWithPoly + * (MED_EN::medEntityMesh Entity, int Number) const; + * (+) inline void calculateConnectivity(MED_EN::medModeSwitch Mode, + * MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity) const; + * (+) inline const CONNECTIVITY* getConnectivityptr() const; + * (+) inline const int * getConnectivity + * (MED_EN::medModeSwitch Mode, MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type) const; + * (+) inline const int * getConnectivityIndex(MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity) const; + * (+) inline const int * getReverseConnectivity(MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; + * (+) inline const int * getReverseConnectivityIndex(MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; + * (+) inline void setGridType(MED_EN::med_grid_type gridType); + * } + */ +void MEDMEMTest_testGrid() +{ + string datadir = getenv("MED_ROOT_DIR"); + string filename = datadir + "/share/salome/resources/med/test19.med" ; + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if (tmp_dir == "") + tmp_dir = "/tmp"; + string filenameout21 = tmp_dir + "/myGridWrite_grid21.med"; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filenameout21); + + // Remove file in advance to ensure it does not exist at the moment of writing, + // because files are not removed by the MEDMEMTest_TmpFilesRemover in case of + // Segmentation Fault (in previous tests execution). + { + MEDMEMTest_TmpFilesRemover aRemover1; + aRemover1.Register(filenameout21); + } + + MED * myMed = new MED() ; + MED_MED_RDONLY_DRIVER myMeshDriver (filename, myMed); + myMeshDriver.open(); + myMeshDriver.readFileStruct(); + myMeshDriver.close(); + + int nbMeshes = myMed->getNumberOfMeshes(); + CPPUNIT_ASSERT(nbMeshes); + + deque<string> mesh_names = myMed->getMeshNames(); + CPPUNIT_ASSERT(mesh_names.size() != 0); + + ////////////////////////////// + // test1 "CARTESIAN GRID" // + ////////////////////////////// + { + MESH* myMesh = myMed->getMesh(mesh_names[0]); + myMesh->read(); + + CPPUNIT_ASSERT(myMesh != NULL); + CPPUNIT_ASSERT(myMesh->getIsAGrid()); + + GRID* myGrid = dynamic_cast<GRID*>(myMesh); + CPPUNIT_ASSERT(myGrid); + + CPPUNIT_ASSERT_THROW(myGrid->getArrayLength(0), MEDEXCEPTION); + + int I, J, K; + CPPUNIT_ASSERT_NO_THROW(I = myGrid->getArrayLength(1)); + CPPUNIT_ASSERT_NO_THROW(J = myGrid->getArrayLength(2)); + CPPUNIT_ASSERT_NO_THROW(K = myGrid->getArrayLength(3)); + + CPPUNIT_ASSERT(I); + CPPUNIT_ASSERT(J); + + med_grid_type grid_type = myGrid->getGridType(); + CPPUNIT_ASSERT_MESSAGE("Wrong grid type", grid_type == MED_CARTESIAN); + + const double * coordinates = myGrid->getCoordinates(MED_FULL_INTERLACE); + int SpaceDimension = myGrid->getSpaceDimension(); + for (int axe = 0; axe < SpaceDimension; axe++) { + for (int num = 0; num < myGrid->getNumberOfNodes(); num++) { + double coordinate; + CPPUNIT_ASSERT_NO_THROW(coordinate = myGrid->getCoordinate(num + 1, axe + 1)); + //cout << "coordinate = " << coordinate << endl; + CPPUNIT_ASSERT(fabs(coordinate - coordinates[(num * SpaceDimension)+axe]) < 0.001); + } + } + + int nbTypesCell = myGrid->getNumberOfTypes(MED_CELL); + CPPUNIT_ASSERT(nbTypesCell == 1); + + const medGeometryElement* types; + CPPUNIT_ASSERT_NO_THROW(types = myGrid->getTypes(MED_CELL)); +//#ifdef ENABLE_FORCED_FAILURES + // Compilation warning about GRID::getTypes(): + // "inline function + // `virtual const MED_EN::medGeometryElement* MEDMEM::GRID::getTypes(MED_EN::medEntityMesh) const' + // used but never defined". + // In MEDMEM_Grid.hxx: + // inline const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const; + // But implemented in MEDMEM_Grid.cxx: + // const MED_EN::medGeometryElement * GRID::getTypes(MED_EN::medEntityMesh entity) const +// CPPUNIT_FAIL("Problem with GRID::getTypes() method implementation."); +//#endif + CPPUNIT_ASSERT(types[0] == MED_QUAD4); + + int nbElem = 0; + CPPUNIT_ASSERT_NO_THROW(nbElem = myGrid->getNumberOfElements(MED_CELL,types[0])); + CPPUNIT_ASSERT(nbElem); + + int nbNodes = myGrid->getNumberOfNodes(); + CPPUNIT_ASSERT(nbNodes); + + int ijkNode[3]; + int NodeNumber; + for (int nbNode = 1; nbNode <= nbNodes; nbNode++) { + CPPUNIT_ASSERT_NO_THROW(myGrid->getNodePosition(nbNode, ijkNode[0], ijkNode[1], ijkNode[2])); + CPPUNIT_ASSERT_NO_THROW(NodeNumber = myGrid->getNodeNumber(ijkNode[0], ijkNode[1], ijkNode[2])); + CPPUNIT_ASSERT(NodeNumber == nbNode); + } + + int nbCells = myGrid->getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS); + CPPUNIT_ASSERT(nbCells); + + int ijkCell[3]; + int CellNumber; + for (int nbCell = 1; nbCell <= nbCells; nbCell++) { + CPPUNIT_ASSERT_NO_THROW(myGrid->getCellPosition(nbCell, ijkCell[0], ijkCell[1], ijkCell[2])); + CPPUNIT_ASSERT_NO_THROW(CellNumber = myGrid->getCellNumber(ijkCell[0], ijkCell[1], ijkCell[2])); + CPPUNIT_ASSERT(CellNumber == nbCell); + } + + int nbEdges = myGrid->getNumberOfElements(MED_EDGE, MED_ALL_ELEMENTS); + CPPUNIT_ASSERT(nbEdges); + + int ijkAxisEdge[4]; + int EdgeNumber; + for (int nbEdge = 1; nbEdge <= nbEdges; nbEdge++) { + CPPUNIT_ASSERT_NO_THROW(myGrid->getEdgePosition(nbEdge, ijkAxisEdge[0], ijkAxisEdge[1], + ijkAxisEdge[2], ijkAxisEdge[3])); + CPPUNIT_ASSERT_NO_THROW(EdgeNumber = myGrid->getEdgeNumber(ijkAxisEdge[0], ijkAxisEdge[1], + ijkAxisEdge[2], ijkAxisEdge[3])); + CPPUNIT_ASSERT(EdgeNumber == nbEdge); + } + + int nbFaces = myGrid->getNumberOfElements(MED_FACE, MED_ALL_ELEMENTS); + CPPUNIT_ASSERT(nbFaces == 0); + +//#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_FAIL("ERROR: nbFaces == 0, but getFacePosition(AnyNumber, ...) - return position(i,j,k)"); +//#endif + int ijkAxisFace[4]; + CPPUNIT_ASSERT_NO_THROW(myGrid->getFacePosition(6, ijkAxisFace[0], ijkAxisFace[1], + ijkAxisFace[2], ijkAxisFace[3])); + CPPUNIT_ASSERT(ijkAxisFace[0]); + CPPUNIT_ASSERT(ijkAxisFace[1]); + CPPUNIT_ASSERT(ijkAxisFace[2]); + + /*int FaceNumber; + for(int nbFace = 1; nbFace <= nbFaces; nbFace++) + { + CPPUNIT_ASSERT_NO_THROW( myGrid->getFacePosition(nbFace, ijkAxisFace[0], ijkAxisFace[1], + ijkAxisFace[2], ijkAxisFace[3])); + CPPUNIT_ASSERT_NO_THROW( EdgeNumber = myGrid->getEdgeNumber(ijkAxisFace[0], ijkAxisFace[1], + ijkAxisFace[2], ijkAxisFace[3])); + CPPUNIT_ASSERT(FaceNumber == nbFace); + }*/ + + bool existConnect = false; + CPPUNIT_ASSERT_NO_THROW(existConnect = myGrid->existConnectivity(MED_NODAL, MED_CELL)); + if (!existConnect) { + CPPUNIT_ASSERT_NO_THROW(myGrid->calculateConnectivity(MED_FULL_INTERLACE, MED_NODAL, MED_CELL)); + CPPUNIT_ASSERT(myGrid->existConnectivity(MED_NODAL, MED_CELL)); + } + + const int* Connectivity; + const int* connectivity_index; + CPPUNIT_ASSERT_NO_THROW(Connectivity = myGrid->getConnectivity(MED_FULL_INTERLACE, MED_NODAL, + MED_CELL, types[0])); + CPPUNIT_ASSERT_NO_THROW(connectivity_index = myGrid->getConnectivityIndex(MED_NODAL, MED_CELL)); + cout << "Nodal connectivity" << endl; + for (int j = 0; j < nbElem; j++) { + cout << "Element "<< j+1 << " : "; + for (int k = connectivity_index[j]; k < connectivity_index[j+1]; k++) + cout << Connectivity[k-1] << " "; + cout << endl; + } + + const int * ReverseNodalConnectivity; + const int * ReverseConnectivityIndex; + CPPUNIT_ASSERT_NO_THROW(ReverseNodalConnectivity = myGrid->getReverseConnectivity(MED_NODAL)); + CPPUNIT_ASSERT_NO_THROW(ReverseConnectivityIndex = myGrid->getReverseConnectivityIndex(MED_NODAL)); + for (int i = 0; i < nbNodes; i++) { + cout << "Node "<< i+1 << " : "; + for (int j = ReverseConnectivityIndex[i]; j < ReverseConnectivityIndex[i+1]; j++) + cout << ReverseNodalConnectivity[j-1] << " "; + cout << endl; + } + + const int* myGlobalNbIdx; + CPPUNIT_ASSERT_NO_THROW(myGlobalNbIdx = myGrid->getGlobalNumberingIndex(MED_CELL)); + for (int i = 0; i <= nbTypesCell; i++) { + if (i == nbTypesCell) { + CPPUNIT_ASSERT_THROW(myGrid->getElementType(MED_CELL, myGlobalNbIdx[i]), MEDEXCEPTION); + break; + } + medGeometryElement aElem, geomPolyElem; + CPPUNIT_ASSERT_NO_THROW(aElem = myGrid->getElementType(MED_CELL, myGlobalNbIdx[i])); + CPPUNIT_ASSERT_NO_THROW(geomPolyElem = myGrid->getElementTypeWithPoly(MED_CELL, myGlobalNbIdx[i])); + CPPUNIT_ASSERT(types[0] == aElem); + CPPUNIT_ASSERT(geomPolyElem == aElem); + } + + CPPUNIT_ASSERT_NO_THROW(existConnect = myGrid->existConnectivity(MED_DESCENDING, MED_CELL)); + if (!existConnect) { + CPPUNIT_ASSERT_NO_THROW(myGrid->calculateConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, MED_CELL)); + CPPUNIT_ASSERT(myGrid->existConnectivity(MED_DESCENDING, MED_CELL)); + } + + const int* ConnectivityDes; + const int* connectivity_index_des; + CPPUNIT_ASSERT_NO_THROW(ConnectivityDes = myGrid->getConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, + MED_CELL, MED_ALL_ELEMENTS)); + CPPUNIT_ASSERT_NO_THROW(connectivity_index_des = + myGrid->getConnectivityIndex(MED_DESCENDING, MED_CELL)); + cout<<"Descending connectivity"<<endl; + for (int j = 0; j < nbElem; j++) { + cout << "Element "<< j+1 << " : "; + for (int k = connectivity_index_des[j]; k < connectivity_index_des[j+1]; k++) + cout << ConnectivityDes[k-1] << " "; + cout << endl; + } + + const int * ReverseDesConnectivity; + const int * ReverseConnectivityIndexDes; + CPPUNIT_ASSERT_NO_THROW(ReverseDesConnectivity = myGrid->getReverseConnectivity(MED_DESCENDING)); + CPPUNIT_ASSERT_NO_THROW(ReverseConnectivityIndexDes = + myGrid->getReverseConnectivityIndex(MED_DESCENDING)); + for (int i = 0; i < nbNodes; i++) { + cout << "Node "<< i+1 << " : "; + for (int j = ReverseConnectivityIndexDes[i]; j < ReverseConnectivityIndexDes[i+1]; j++) + cout << ReverseDesConnectivity[j-1] << " "; + cout << endl; + } + + //TEST POLY + { + int nbPolytypes; + //test getNumberOfTypesWithPoly() - a grid has one type + CPPUNIT_ASSERT_NO_THROW(nbPolytypes = myGrid->getNumberOfTypesWithPoly(MED_CELL)); + CPPUNIT_ASSERT(nbPolytypes == 1 ); + + const MED_EN::medGeometryElement * PolyTypes, *Types; + CPPUNIT_ASSERT_NO_THROW(PolyTypes = myGrid->getTypesWithPoly(MED_CELL)); + CPPUNIT_ASSERT_NO_THROW(Types = myGrid->getTypes(MED_CELL)); + CPPUNIT_ASSERT_EQUAL(PolyTypes[nbPolytypes-1],Types[nbPolytypes-1]); + + for (int t = 0; t < nbPolytypes; t++) { + int nbElPoly, nbEl; + CPPUNIT_ASSERT_NO_THROW(nbElPoly = myGrid->getNumberOfElementsWithPoly(MED_CELL, PolyTypes[t])); + CPPUNIT_ASSERT_NO_THROW(nbEl = myGrid->getNumberOfElements(MED_CELL, PolyTypes[t])); + CPPUNIT_ASSERT(nbElPoly == nbEl); + } + } + } + + ////////////////////////////// + // test2 "MED_BODY_FITTED" // + ////////////////////////////// + { + MESH* myMesh1 = myMed->getMesh(mesh_names[1]); + myMesh1->read(); + + CPPUNIT_ASSERT(myMesh1 != NULL); + CPPUNIT_ASSERT(myMesh1->getIsAGrid()); + + GRID* myGrid1 = dynamic_cast<GRID*>(myMesh1); + CPPUNIT_ASSERT(myGrid1); + + int I, J, K; + CPPUNIT_ASSERT_NO_THROW(I = myGrid1->getArrayLength(1)); + CPPUNIT_ASSERT_NO_THROW(J = myGrid1->getArrayLength(2)); + CPPUNIT_ASSERT_NO_THROW(K = myGrid1->getArrayLength(3)); + + CPPUNIT_ASSERT(I == 2); + CPPUNIT_ASSERT(J == 2); + + med_grid_type grid_type = myGrid1->getGridType(); + CPPUNIT_ASSERT_MESSAGE("Wrong grid type", grid_type == MED_BODY_FITTED); + + int nbTypesCell = myGrid1->getNumberOfTypes(MED_CELL); + CPPUNIT_ASSERT(nbTypesCell == 1); + + const medGeometryElement* types1; + CPPUNIT_ASSERT_NO_THROW( types1 = myGrid1->getTypes(MED_CELL) ); + CPPUNIT_ASSERT( types1[0] == MED_QUAD4); + + int nbElem; + CPPUNIT_ASSERT_NO_THROW(nbElem = myGrid1->getNumberOfElements(MED_CELL, types1[0])); + CPPUNIT_ASSERT(nbElem); + + const int* BodyConnectivity; + const int* body_connectivity_index; + int ijkNodeBody[3]; + CPPUNIT_ASSERT_NO_THROW(BodyConnectivity = myGrid1->getConnectivity(MED_FULL_INTERLACE, MED_NODAL, + MED_CELL, types1[0])); + CPPUNIT_ASSERT_NO_THROW(body_connectivity_index = myGrid1->getConnectivityIndex(MED_NODAL, MED_CELL)); + cout<<"Nodal connectivity"<<endl; + for (int j = 0; j < nbElem; j++) { + cout << "Element "<< j+1 << " : "; + for (int k = body_connectivity_index[j]; k < body_connectivity_index[j+1]; k++){ + CPPUNIT_ASSERT_NO_THROW(myGrid1->getNodePosition(BodyConnectivity[k-1], ijkNodeBody[0], + ijkNodeBody[1], ijkNodeBody[2])); + cout << BodyConnectivity[k-1] << " "; + } + cout << endl; + } + } + + /////////////////////////////////////////////////// + // test3 "maa1" which in fact is not a pure GRID // + /////////////////////////////////////////////////// + { + MESH* myMesh2 = NULL; + + myMesh2 = myMed->getMesh(mesh_names[2]); + myMesh2->read(); + + CPPUNIT_ASSERT(myMesh2 != NULL); + CPPUNIT_ASSERT(!(myMesh2->getIsAGrid())); + } + + delete myMed; + + //////////////////////////// + // test4 create new GRID // + //////////////////////////// + + // Default constructor and destructor + { + GRID* myGrid2 = new GRID(); + CPPUNIT_ASSERT(myGrid2->getIsAGrid()); + CPPUNIT_ASSERT(myGrid2->getGridType() == MED_CARTESIAN); + CPPUNIT_ASSERT(!myGrid2->getArrayLength(1)); + CPPUNIT_ASSERT(!myGrid2->getArrayLength(2)); + CPPUNIT_ASSERT(!myGrid2->getArrayLength(3)); + delete myGrid2; + } + + // Constructor with grid type, setGridType() + { + GRID* myGrid2 = new GRID(MED_POLAR); + CPPUNIT_ASSERT(myGrid2->getGridType() == MED_POLAR); + myGrid2->setGridType(MED_CARTESIAN); + CPPUNIT_ASSERT(myGrid2->getGridType() == MED_CARTESIAN); + delete myGrid2; + } + + // Constructor with coordinate values, getArrayValue(), init() + { + vector<vector<double> > xyz; + const int nbCoords = 3; + xyz.resize(nbCoords); + for ( int i = 0; i < nbCoords; i++ ) + { + xyz[i].resize(i + 2); + for ( int j = 0; j < i + 2; j++ ) + xyz[i][j] = j; + } + vector<string> Coord_Names; + Coord_Names.resize(nbCoords); + Coord_Names[0] = "X"; + Coord_Names[1] = "Y"; + Coord_Names[2] = "Z"; + + vector<string> Coord_Units; + Coord_Units.resize(nbCoords); + for(int i = 0; i < 3; i++) + Coord_Units[i] = "cm"; + + GRID* myGrid2; + + try{ + myGrid2 = new GRID(xyz, Coord_Names, Coord_Units, MED_CARTESIAN); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + // testing getCoordinateptr() and fillCoordinates() + // We fill a map of all possible coordinate triples. + // After iteration through all coordinates, this map should contain only "true" as data. + // "true" in some map element during iteration means duplicated node position. + // "false" in some map element after iteration means empty node position. + map<int, bool> found; + for ( int i1 = 0; i1 < xyz[0].size(); i1++ ) + for ( int i2 = 0; i2 < xyz[1].size(); i2++ ) + for ( int i3 = 0; i3 < xyz[2].size(); i3++ ) + found[int(xyz[0][i1] * 100 + xyz[1][i2] * 10 + xyz[2][i3])] = false; + + COORDINATE* coords = (COORDINATE*)myGrid2->getCoordinateptr(); + CPPUNIT_ASSERT(coords); + for (int num = 0; num < myGrid2->getNumberOfNodes(); num++) { + int x = int(coords->getCoordinate(num + 1, 1)); + int y = int(coords->getCoordinate(num + 1, 2)); + int z = int(coords->getCoordinate(num + 1, 3)); + CPPUNIT_ASSERT(!found[x * 100 + y * 10 + z]); + found[x * 100 + y * 10 + z] = true; + } + + for ( map<int, bool>::iterator it = found.begin(); it != found.end(); it++ ) + CPPUNIT_ASSERT((*it).second); + + // Testing fillConnectivity() and getConnectivityptr() + // Basic testing: presence of connectivity arrays, element types and number of elements + CONNECTIVITY* conn = (CONNECTIVITY*)myGrid2->getConnectivityptr(); + CPPUNIT_ASSERT(conn); + bool hasFaces = myGrid2->getArrayLength(3), hasEdges = myGrid2->getArrayLength(2); + medGeometryElement aCellGeometry; + if (hasFaces) aCellGeometry = MED_HEXA8; + else if (hasEdges) aCellGeometry = MED_QUAD4; + else aCellGeometry = MED_SEG2; + CPPUNIT_ASSERT(conn->getElementType(MED_CELL, 1) == aCellGeometry); + CPPUNIT_ASSERT(conn->existConnectivity(MED_NODAL, MED_CELL)); + CPPUNIT_ASSERT(conn->existConnectivity(MED_DESCENDING, MED_CELL)); + //test getCellsTypes + CELLMODEL* cellmodel = (CELLMODEL*)myGrid2->getCellsTypes(MED_CELL); + CPPUNIT_ASSERT(cellmodel); + + int nbCells, nbFaces, nbEdges; + + int iLen = myGrid2->getArrayLength(1); + int jLen = myGrid2->getArrayLength(2); + int kLen = myGrid2->getArrayLength(3); + int iLenMin1 = myGrid2->getArrayLength(1)-1; + int jLenMin1 = myGrid2->getArrayLength(2)-1; + int kLenMin1 = myGrid2->getArrayLength(3)-1; + const int* aCellCount = conn->getGlobalNumberingIndex(MED_CELL); + nbCells = iLenMin1 * jLenMin1 * kLenMin1; + CPPUNIT_ASSERT(aCellCount[1] - 1 == nbCells); + + if (hasFaces){ + CPPUNIT_ASSERT(conn->getElementType(MED_FACE, 1) == MED_QUAD4); + nbFaces = iLen * jLenMin1 * kLenMin1; + nbFaces += jLen * kLenMin1 * iLenMin1; + nbFaces += kLen * iLenMin1 * jLenMin1; + const int* aFaceCount = conn->getGlobalNumberingIndex(MED_FACE); + CPPUNIT_ASSERT(aFaceCount[1] - 1 == nbFaces); + CPPUNIT_ASSERT(conn->existConnectivity(MED_NODAL, MED_FACE)); + //test getCellsTypes + CELLMODEL* cellmodelF = (CELLMODEL*)myGrid2->getCellsTypes(MED_FACE); + CPPUNIT_ASSERT(cellmodelF); + } + if (hasEdges){ + CPPUNIT_ASSERT(conn->getElementType(MED_EDGE, 1) == MED_SEG2); + if (kLen) { // 3d grid + nbEdges = iLenMin1 * jLen * kLen; + nbEdges += jLenMin1 * kLen * iLen; + nbEdges += kLenMin1 * iLen * jLen; + } + else if (jLen) { // 2d + nbEdges = iLenMin1 * jLen; + nbEdges += jLenMin1 * iLen; + } + const int* anEdgeCount = conn->getGlobalNumberingIndex(MED_EDGE); + CPPUNIT_ASSERT(anEdgeCount[1] - 1 == nbEdges); + CPPUNIT_ASSERT(conn->existConnectivity(MED_NODAL, MED_EDGE)); + //test getCellsTypes + CELLMODEL* cellmodelE = (CELLMODEL*)myGrid2->getCellsTypes(MED_EDGE); + CPPUNIT_ASSERT(cellmodelE); + + } + + // Testing getArrayValue() + for ( int ii = 1; ii <= nbCoords; ii++ ) + for ( int jj = 0; jj < ii + 1; jj++ ) + CPPUNIT_ASSERT(myGrid2->getArrayValue(ii, jj) == xyz[ii - 1][jj]); + + CPPUNIT_ASSERT_THROW(myGrid2->getArrayValue(nbCoords + 1, 0), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(myGrid2->getArrayValue(1, myGrid2->getArrayLength(1) + 1), MEDEXCEPTION); + myGrid2->setGridType(MED_POLAR); + + //testing read/write functions + + // add new driver + int idGridV21; + + try + { + idGridV21 = myGrid2->addDriver(MED_DRIVER,filenameout21); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + // write this driver to file as an unstructured mesh + CPPUNIT_ASSERT_NO_THROW(myGrid2->writeUnstructured(idGridV21)); + + GRID* myGrid3 = new GRID(); + // add new driver for myGrid3 + int driver; + CPPUNIT_ASSERT_NO_THROW(driver = myGrid3->addDriver(MED_DRIVER, filenameout21)); + +//#ifdef ENABLE_FORCED_FAILURES + // ? (BUG) ? "The mesh dimension |-1| seems to be incorrect for the mesh : |Default Mesh Name|" + CPPUNIT_ASSERT_NO_THROW(myGrid3->read(driver)); + + // Testing getArrayValue() + for ( int ii = 1; ii <= nbCoords; ii++ ) + for ( int jj = 0; jj < ii + 1; jj++ ) + CPPUNIT_ASSERT(myGrid3->getArrayValue(ii, jj) == xyz[ii - 1][jj]); + + CPPUNIT_ASSERT(myGrid3->getGridType() == MED_POLAR); +//#endif + + delete myGrid3; + + //test init() + CPPUNIT_ASSERT_NO_THROW(myGrid2->init()); + CPPUNIT_ASSERT(myGrid2->getGridType() == MED_CARTESIAN); + CPPUNIT_ASSERT(myGrid2->getArrayLength(1) == 0); + CPPUNIT_ASSERT(myGrid2->getArrayLength(2) == 0); + CPPUNIT_ASSERT(myGrid2->getArrayLength(3) == 0); +//#ifdef ENABLE_FAULTS + // (BUG) Segmentation Fault + myGrid2->makeUnstructured(); +//#endif +//#ifdef ENABLE_FORCED_FAILURES +// CPPUNIT_FAIL("ERROR:makeUnstructured() - there is no check if grid is empty or not"); +//#endif + + delete myGrid2; + } + +//#ifdef ENABLE_FORCED_FAILURES + { + GRID* myGrid2; + // ? (BUG) ? MED Exception in /dn20/salome/jfa/V3/SRC/MED_SRC/src/MEDMEM/MEDMEM_MedM + //eshDriver21.cxx [430] : MED_MESH_RDONLY_DRIVER21::getCOORDINATE() : The number + //of nodes |0| seems to be incorrect for the mesh : |bodyfitted| + CPPUNIT_ASSERT_NO_THROW(myGrid2 = new GRID(MED_DRIVER, filename, mesh_names[1])); + + // Check if something has been read - full mesh data testing is above + CPPUNIT_ASSERT(myGrid2->getSpaceDimension()); + CPPUNIT_ASSERT(myGrid2->getNumberOfNodes()); + CPPUNIT_ASSERT(myGrid2->getNumberOfTypes(MED_CELL) == 1); + const medGeometryElement* types2; + CPPUNIT_ASSERT_NO_THROW(types2 = myGrid2->getTypes(MED_CELL)); + int nbElem; + CPPUNIT_ASSERT_NO_THROW(nbElem = myGrid2->getNumberOfElements(MED_CELL,types2[0])); + CPPUNIT_ASSERT(nbElem); + delete myGrid2; + } +//#endif + + { + GRID* myGrid4 = new GRID(); + filename = datadir + "/share/salome/resources/med/pointe.med"; + myGrid4->setName("maa1"); + MED_MESH_RDONLY_DRIVER myMeshDriver(filename, myGrid4); + myMeshDriver.setMeshName("maa1"); + + // add new driver for myGrid4 + int driver; + CPPUNIT_ASSERT_NO_THROW(driver = myGrid4->addDriver(myMeshDriver)); + + // ??? ERROR:myGrid4->fillMeshAfterRead()- this method is incomplete: + // currently it only resets _is_coordinates_filled and _is_connectivity_filled + // flags that leads to grid reconstruction + + // MED Exception : MED_MESH_RDONLY_DRIVER21::getGRID() : The number + // of nodes |-1| seems to be incorrect for the mesh : |maa1| + // But this exception seems to be correct reaction on attempt + // to read a grid from a file, which does not contain it. + CPPUNIT_ASSERT_THROW(myGrid4->read(driver), MEDEXCEPTION); + //CPPUNIT_ASSERT_NO_THROW(myGrid4->read(driver)); + /*CPPUNIT_ASSERT(myGrid4->getArrayLength(1) == 0); + CPPUNIT_ASSERT(myGrid4->getArrayLength(2) == 0); + CPPUNIT_ASSERT(myGrid4->getArrayLength(3) == 0); + myGrid4->fillMeshAfterRead(); + CPPUNIT_ASSERT(myGrid4->getArrayLength(1) != 0); + CPPUNIT_ASSERT(myGrid4->getArrayLength(2) != 0); + CPPUNIT_ASSERT(myGrid4->getArrayLength(3) != 0);*/ + + delete myGrid4; + } +} + +int main (int argc, char** argv) +{ + MEDMEMTest_testGrid(); +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_Group.cxx b/src/MEDMEMCppTest/MEDMEMTest_Group.cxx new file mode 100644 index 000000000..80aaaa45d --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Group.cxx @@ -0,0 +1,150 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/Message.h> +#include <cppunit/TestAssert.h> + +#include "MEDMEM_Group.hxx" +#include "MEDMEM_define.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_MedMeshDriver.hxx" + +#include <sstream> +#include <cmath> + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +/*! + * Check methods (10), defined in MEDMEM_Group.hxx: + * class GROUP : virtual public SUPPORT { + * (+) GROUP(); + * (+) GROUP(const string & name, const list<FAMILY*> & family) throw (MEDEXCEPTION); + * (+) GROUP(const GROUP & m); + * (+) virtual ~GROUP(); + * (+) GROUP & operator=(const GROUP &group); + * (+) friend ostream & operator<<(ostream &os, GROUP &my); + * (+) inline void setNumberOfFamilies(int numberOfFamilies); + * (+) inline void setFamilies(vector<FAMILY*> Family); + * (+) inline int getNumberOfFamilies() const; + * (+) inline vector<FAMILY*> getFamilies() const; + * (+) inline FAMILY * getFamily(int i) const; + * } + */ +void MEDMEMTest::testGroup() +{ + string datadir = getenv("MED_ROOT_DIR"); + string filename = datadir + "/share/salome/resources/med/pointe.med" ; + string meshname = "maa1"; + + MESH * myMesh= new MESH() ; + myMesh->setName(meshname); + MED_MESH_RDONLY_DRIVER myMeshDriver(filename,myMesh); + myMeshDriver.setMeshName(meshname); + myMeshDriver.open(); + myMeshDriver.read(); + myMeshDriver.close(); + + const GROUP * myGroup = myMesh->getGroup(MED_NODE,1); + CPPUNIT_ASSERT(myGroup != NULL); + + int NumberOfFamillies = myGroup->getNumberOfFamilies(); + CPPUNIT_ASSERT(NumberOfFamillies != 0); + + vector<FAMILY*> aFamilies = myGroup->getFamilies(); + CPPUNIT_ASSERT(NumberOfFamillies == aFamilies.size()); + list<FAMILY*> aList; + + for (int j=1;j<=NumberOfFamillies;j++) + { + try{ + aList.push_back(myGroup->getFamily(j)); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT_EQUAL(myGroup->getFamily(j)->getName(), aFamilies[j-1]->getName()); + } + + GROUP* myGroup2 = new GROUP(*myGroup); + + cout<<*myGroup2<<endl; + ostringstream os; + os << *myGroup2; + CPPUNIT_ASSERT(os.str() != ""); + + GROUP myGroup3; + try{ + myGroup3 = *myGroup2; + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_EQUAL(myGroup3, *myGroup2); + + GROUP myGroup4; + const GROUP * Group = myMesh->getGroup(MED_NODE,2); + CPPUNIT_ASSERT(Group != NULL); + + int NumberOfFamillies1 = Group->getNumberOfFamilies(); + CPPUNIT_ASSERT(NumberOfFamillies1 != 0); + if(NumberOfFamillies1) + { + myGroup4.setNumberOfFamilies(NumberOfFamillies1); + myGroup4.setFamilies(Group->getFamilies()); + for(int i = 1; i <= myGroup4.getNumberOfFamilies(); i++ ) + { + CPPUNIT_ASSERT_EQUAL(myGroup4.getFamily(i), Group->getFamily(i)); + } + } + + if(aList.size()) + { + try{ + GROUP myGroup5("newFamily", aList); + cout<< myGroup5 <<endl; + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + } + + delete myGroup2; + delete myMesh ; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_Med.cxx b/src/MEDMEMCppTest/MEDMEMTest_Med.cxx new file mode 100644 index 000000000..9701d4ca5 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Med.cxx @@ -0,0 +1,447 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "MEDMEM_Med.hxx" + +#include <sstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +// #30: MEDMEM_Med.hxx } MEDMEMTest_Med.cxx + +/*! + * Check methods (26), defined in MEDMEM_Med.hxx: + * class MED { + * (+) MED(); + * (+) MED (driverTypes driverType, const string & fileName); + * (+) ~MED(); + * (+) void addField (FIELD_ * const ptrField) throw (MED_EXCEPTION); + * (+) void addMesh (MESH * const ptrMesh) throw (MED_EXCEPTION); + * (+) int addDriver (driverTypes driverType, const string & fileName, + * MED_EN::med_mode_acces access=MED_EN::MED_REMP); + * (+) int addDriver (GENDRIVER & driver); + * (+) void rmDriver (int index=0) throw (MEDEXCEPTION); + * (+) void readFileStruct(int index=0) throw (MEDEXCEPTION); + * (+) void read (int index=0) throw (MEDEXCEPTION); + * (+) void writeFrom (int index=0) throw (MEDEXCEPTION); + * (+) void write (int index=0) throw (MEDEXCEPTION); + * (+) int getNumberOfMeshes (void) const; + * (+) int getNumberOfFields (void) const; + * (+) void getMeshNames (string * meshNames) const throw (MEDEXCEPTION); + * (+) deque<string> getMeshNames () const; + * (+) MESH * getMesh (const string & meshName) const throw (MEDEXCEPTION); + * (+) MESH * getMesh (const FIELD_ * const field) const throw (MEDEXCEPTION); + * (+) void getFieldNames (string * fieldNames) const throw (MEDEXCEPTION); + * (+) deque<string> getFieldNames () const; + * (+) deque<DT_IT_> getFieldIteration (const string & fieldName) const throw (MEDEXCEPTION); + * (+) FIELD_ * getField (const string & fieldName, const int dt, + * const int it) const throw (MEDEXCEPTION); + * (NOT COMPILABLE!!!) template<class T> FIELD<T> * getFieldT + * (const string & fieldName, const int dt, const int it) const throw (MEDEXCEPTION); + * (+) FIELD_ * getField2 (const string & fieldName, double time, int it=0) const throw (MEDEXCEPTION); + * (+) const map<MED_EN::medEntityMesh,SUPPORT *> & getSupports + * (const string & meshName) const throw (MEDEXCEPTION); + * (+) SUPPORT * getSupport (const string & meshName, + * MED_EN::medEntityMesh entity) const throw (MEDEXCEPTION); + * (-, as it is temporary and called from driver after Med object reading from file) void updateSupport (); + * } + */ +void MEDMEMTest::testMed() +{ + string datadir = getenv("MED_ROOT_DIR"); + string filename = datadir + "/share/salome/resources/med/pointe.med"; + + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if (tmp_dir == "") + tmp_dir = "/tmp"; + + string filenameout21 = tmp_dir + "/myMedWrite_pointe21.med"; + string filenameout21_from = tmp_dir + "/myMedWrite_pointe21_from.med"; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filenameout21); + aRemover.Register(filenameout21_from); + + MED* myMed = new MED(MED_DRIVER, filename); + //read all objects in the file + CPPUNIT_ASSERT_NO_THROW(myMed->read()); + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) Memory problem in MED::updateSupport()! + // Invalid read of size 4 + // at 0x34548AD6: std::_Rb_tree_decrement(std::_Rb_tree_node_base*) (in /usr/lib/libstdc++.so.6.0.1) + // by 0x34876722: std::_Rb_tree_iterator<std::pair<long const, MEDMEM::SUPPORT*> >::operator--(int) (stl_tree.h:203) + // by 0x348733BE: MEDMEM::MED::updateSupport() (MEDMEM_Med.cxx:805) + // Address 0x35C67598 is 0 bytes inside a block of size 24 free'd + // at 0x3414CBD5: operator delete(void*) (vg_replace_malloc.c:155) + // ... + // by 0x348766EB: std::map<long, MEDMEM::SUPPORT*, std::less<long>, std::allocator<std::pair<long const, MEDMEM::SUPPORT*> > >::erase(std::_Rb_tree_iterator<std::pair<long const, MEDMEM::SUPPORT*> >) (stl_map.h:410) + // by 0x348733A3: MEDMEM::MED::updateSupport() (MEDMEM_Med.cxx:804) + //CPPUNIT_FAIL("Memory problem in MED::updateSupport(): removing map item while iterating on this map."); + + // Seems to be fixed - to check, BUT THERE ARE OTHER PROBLEMS REPORTED BY VALGRIND + //#endif + + //getNumberOfMeshes + int nbMeshes, nbFields; + try{ + nbMeshes = myMed->getNumberOfMeshes(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT(nbMeshes); + + //getMeshNames + deque<string> mesh_names, field_names; + try{ + mesh_names = myMed->getMeshNames(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT(mesh_names.size() != 0); + + //getNumberOfFields + try{ + nbFields = myMed->getNumberOfFields(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT(nbFields); + + //getFieldNames + try{ + field_names = myMed->getFieldNames(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT(field_names.size() != 0); + + string field_names_1[nbFields]; + string mesh_names_1[nbMeshes]; + //get field and mesh names + try{ + myMed->getMeshNames(mesh_names_1); + myMed->getFieldNames(field_names_1); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + // Ensure what it's impossible to get mesh object by empty or non-existent name + CPPUNIT_ASSERT_THROW(myMed->getMesh(""), MEDEXCEPTION); + + //compare mesh names, produced by two different methods + for(int nb = 0; nb < nbMeshes; nb++ ) + { + MESH* myMesh; + CPPUNIT_ASSERT(mesh_names_1[nb] == mesh_names[nb]); + CPPUNIT_ASSERT_NO_THROW(myMesh = myMed->getMesh(mesh_names[nb])); + //ensure mesh is not empty + CPPUNIT_ASSERT(myMesh->getSpaceDimension() != MED_INVALID); + CPPUNIT_ASSERT(myMesh->getNumberOfNodes() != MED_INVALID); + CPPUNIT_ASSERT(myMesh->getCoordinateptr() != NULL); + } + + // Ensure what it's impossible to get field object by empty or non-existent name + CPPUNIT_ASSERT_THROW(myMed->getField("", 0, 0),MEDEXCEPTION); + + // Cycle by amount of fields + // Compare field names produced by two different methods + // Get field object with help of getField(...) and getField2(...) + for(int nb = 0; nb < nbFields; nb++ ) + { + CPPUNIT_ASSERT(field_names_1[nb] == field_names[nb]); + deque<DT_IT_> myFIter; + CPPUNIT_ASSERT_NO_THROW(myFIter = myMed->getFieldIteration(field_names[nb])); + CPPUNIT_ASSERT(myFIter.size()); + for(int nbIter = 0; nbIter < myFIter.size(); nbIter++) + { + FIELD_ *myField, *myField2; + CPPUNIT_ASSERT_NO_THROW(myField = myMed->getField (field_names[nb], myFIter[nbIter].dt, myFIter[nbIter].it)); + CPPUNIT_ASSERT_NO_THROW(myField2 = myMed->getField2(field_names[nb], myField->getTime())); + CPPUNIT_ASSERT(myField==myField2); + //compare two fields + CPPUNIT_ASSERT(myField->getNumberOfComponents() == myField2->getNumberOfComponents()); + CPPUNIT_ASSERT(myField->getNumberOfValues() == myField2->getNumberOfValues()); + CPPUNIT_ASSERT(myField->getSupport() == myField2->getSupport()); + CPPUNIT_ASSERT(myField->getValueType() == myField2->getValueType()); + CPPUNIT_ASSERT(myField->getDescription() == myField2->getDescription()); + + med_type_champ type = myField->getValueType(); + switch (type) + { + case MED_INT32: + { + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) ERROR in MEDMEM_Med.hxx line 153: FIELD_ retUp=getField(fieldName,dt,it); + // But getField returns FIELD_* + //CPPUNIT_FAIL("Error in MED::getFieldT(const string & fieldName, const int dt, const int it)"); + // Fixed: * added + //#endif + // not compilable + //FIELD<int> *myFieldT; + //CPPUNIT_ASSERT_NO_THROW(myFieldT = myMed->getFieldT<int>(field_names[nb], myFIter[nbIter].dt, myFIter[nbIter].it)) + // PROBLEM NOT REPRODUCED + } + break; + case MED_REEL64: + { + // not compilable + //FIELD<double> *myFieldT; + //CPPUNIT_ASSERT_NO_THROW(myFieldT = myMed->getFieldT<double>(field_names[nb], myFIter[nbIter].dt, myFIter[nbIter].it)) + // PROBLEM NOT REPRODUCED + } + break; + } + } + } + + // For each mesh get a map + for(int nb = 0; nb < nbMeshes; nb++ ) + { + map<MED_EN::medEntityMesh,SUPPORT *> myMapSupports; + CPPUNIT_ASSERT_NO_THROW(myMapSupports = myMed->getSupports(mesh_names[nb])); + map<MED_EN::medEntityMesh,SUPPORT *>::const_iterator myMapSupportsIter = myMapSupports.begin(); + for( ; myMapSupportsIter != myMapSupports.end(); myMapSupportsIter++ ) + { + SUPPORT* mySupport; + CPPUNIT_ASSERT_NO_THROW(mySupport = myMed->getSupport(mesh_names[nb], (*myMapSupportsIter).first)); + CPPUNIT_ASSERT_EQUAL(mySupport, (*myMapSupportsIter).second); + CPPUNIT_ASSERT(mySupport->deepCompare(*(*myMapSupportsIter).second)); + } + } + + // add new driver + int idMedV21; + + try + { + idMedV21 = myMed->addDriver(MED_DRIVER,filenameout21); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + // write to file + CPPUNIT_ASSERT_NO_THROW(myMed->write(idMedV21)); + // check, that the file is created on disk + CPPUNIT_ASSERT(access(filenameout21.data(), F_OK) == 0); + + // writeFrom + CPPUNIT_ASSERT_THROW(myMed->writeFrom(idMedV21 + 1000), MEDEXCEPTION); // invalid driver index + int idMedV21_from = myMed->addDriver(MED_DRIVER, filenameout21_from); + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) MED::writeFrom(int) always throws MEDEXCEPTION. + // ? missed 'else' clause before throw ? + CPPUNIT_ASSERT_NO_THROW(myMed->writeFrom(idMedV21_from)); + // simple fix + //#endif + // check, that the file is created on disk + //#ifdef ENABLE_FORCED_FAILURES + // ? (BUG) The file is not created. + CPPUNIT_ASSERT(access(filenameout21_from.data(), F_OK) == 0); + // NOT a bug. writeFrom() should be removed from API + //#endif + + // remove driver from med + CPPUNIT_ASSERT_NO_THROW(myMed->rmDriver(idMedV21)); + //#ifdef ENABLE_FORCED_FAILURES + //ERROR: driver withER22::write() : "; + //index idMedV21 has not been removed + // Why driver removal is commented out? + // ensure exception is raised on second attempt to remove driver + CPPUNIT_ASSERT_THROW(myMed->rmDriver(idMedV21),MEDEXCEPTION); + // Fixed + //#endif + + //create empty MED object + MED* myEmptyMed = new MED(); + // create new driver for med object + // and add driver to med + int idDriver; + GENDRIVER *driver = DRIVERFACTORY::buildDriverForMed(MED_DRIVER,filename,myEmptyMed,RDONLY); + try{ + idDriver = myEmptyMed->addDriver(*driver); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT(idDriver == 0); + + // trying to read file with non-existent index of driver + // read file and create empty object + CPPUNIT_ASSERT_NO_THROW(myEmptyMed->readFileStruct()); + + //getNumberOfMeshes + int nbEmptyMeshes, nbEmptyFields; + try{ + nbEmptyMeshes = myEmptyMed->getNumberOfMeshes(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT(nbEmptyMeshes == nbMeshes); + + //getMeshNames + deque<string> empty_mesh_names, empty_field_names; + try{ + empty_mesh_names = myEmptyMed->getMeshNames(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT(empty_mesh_names.size() != 0); + + //getNumberOfFields + try{ + nbEmptyFields = myEmptyMed->getNumberOfFields(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT(nbFields == nbEmptyFields); + + //getFieldNames + try{ + empty_field_names = myEmptyMed->getFieldNames(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT(empty_field_names.size() != 0); + + //compare mesh names, produced by two different methods + for(int nb = 0; nb < nbMeshes; nb++ ) + { + MESH* myMesh; + CPPUNIT_ASSERT(empty_mesh_names[nb] == mesh_names[nb]); + CPPUNIT_ASSERT_NO_THROW(myMesh = myEmptyMed->getMesh(empty_mesh_names[nb])); + //MESH* myMesh1 = myMed->getMesh(mesh_names[nb]); + CPPUNIT_ASSERT(!myMesh->deepCompare(*(myMed->getMesh(mesh_names[nb])))); + //ensure mesh is empty + CPPUNIT_ASSERT(myMesh->getSpaceDimension() == MED_INVALID); + CPPUNIT_ASSERT(myMesh->getNumberOfNodes() == MED_INVALID); + CPPUNIT_ASSERT(myMesh->getCoordinateptr() == NULL); + } + + // trying to add null mesh pointer + CPPUNIT_ASSERT_THROW(myEmptyMed->addMesh(NULL), MEDEXCEPTION); + + //create a mesh + MESH * aMesh = MEDMEMTest_createTestMesh(); + // and add it + CPPUNIT_ASSERT_NO_THROW(myEmptyMed->addMesh(aMesh)); + + //compare two meshes + CPPUNIT_ASSERT(aMesh->deepCompare(*(myEmptyMed->getMesh("meshing")))); + + // add null field, exception should be raised + CPPUNIT_ASSERT_THROW(myEmptyMed->addField(NULL), MEDEXCEPTION); + // + FIELD_* myEmptyField = new FIELD_(); + // add empty field, ensure exception is raised + CPPUNIT_ASSERT_THROW(myEmptyMed->addField(myEmptyField), MEDEXCEPTION); + //set field name + myEmptyField->setName("myField"); + + // set support + SUPPORT* aSupport = new SUPPORT(myEmptyMed->getMesh("meshing"), "Support On Cells"); + myEmptyField->setSupport(aSupport); + + CPPUNIT_ASSERT_NO_THROW(myEmptyMed->addField(myEmptyField)); + + CPPUNIT_ASSERT(aSupport->deepCompare(*(myEmptyMed->getSupport("meshing",MED_CELL)))); + CPPUNIT_ASSERT(aMesh->deepCompare(*(myEmptyMed->getMesh("meshing")))); + + delete myMed; + delete myEmptyMed; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_MedFieldDriver21.cxx b/src/MEDMEMCppTest/MEDMEMTest_MedFieldDriver21.cxx new file mode 100644 index 000000000..4b46e08b0 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_MedFieldDriver21.cxx @@ -0,0 +1,667 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include <MEDMEM_Field.hxx> +#include <MEDMEM_MedFieldDriver21.hxx> +#include "MEDMEM_MedMeshDriver.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +/*! + * Check methods (17), defined in MEDMEM_MedFieldDriver21.hxx: + * template <class T> class MED_FIELD_DRIVER21 : public virtual MED_FIELD_DRIVER<T> { + * (+) MED_FIELD_DRIVER21(); + * (+) template <class INTERLACING_TAG> MED_FIELD_DRIVER21(const string & fileName, + * FIELD<T, INTERLACING_TAG> * ptrField, MED_EN::med_mode_acces accessMode); + * (+) MED_FIELD_DRIVER21(const MED_FIELD_DRIVER21 & fieldDriver); + * (+) virtual ~MED_FIELD_DRIVER21(); + * (+) void open() throw (MEDEXCEPTION); + * (+) void close(); + * } + * template <class T> class MED_FIELD_RDONLY_DRIVER21 : public virtual MED_FIELD_DRIVER21<T>, + * public virtual IMED_FIELD_RDONLY_DRIVER<T> { + * (+) MED_FIELD_RDONLY_DRIVER21(); + * (+) template <class INTERLACING_TAG> MED_FIELD_RDONLY_DRIVER21 + * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField); + * (+) MED_FIELD_RDONLY_DRIVER21(const MED_FIELD_RDONLY_DRIVER21 & fieldDriver); + * (+) virtual ~MED_FIELD_RDONLY_DRIVER21(); + * (+) void write(void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * } + * template <class T> class MED_FIELD_WRONLY_DRIVER21 : public virtual MED_FIELD_DRIVER21<T>, + * public virtual IMED_FIELD_WRONLY_DRIVER<T> { + * (+) MED_FIELD_WRONLY_DRIVER21(); + * (+) template <class INTERLACING_TAG> MED_FIELD_WRONLY_DRIVER21 + * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField); + * (+) MED_FIELD_WRONLY_DRIVER21(const MED_FIELD_WRONLY_DRIVER21 & fieldDriver); + * (+) virtual ~MED_FIELD_WRONLY_DRIVER21(); + * (+) void write(void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * } + * template <class T> class MED_FIELD_RDWR_DRIVER21 : public MED_FIELD_RDONLY_DRIVER21<T>, + * public MED_FIELD_WRONLY_DRIVER21<T>, public IMED_FIELD_RDWR_DRIVER<T> { + * (+) MED_FIELD_RDWR_DRIVER21(); + * (+) template <class INTERLACING_TAG> MED_FIELD_RDWR_DRIVER21 + * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField); + * (+) MED_FIELD_RDWR_DRIVER21(const MED_FIELD_RDWR_DRIVER21 & fieldDriver); + * (+) ~MED_FIELD_RDWR_DRIVER21(); + * (+) void write(void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * } + */ +void MEDMEMTest::testMedFieldDriver21() +{ + FIELD<int> *aField = new FIELD<int> (); + FIELD<int> *aField_1 = new FIELD<int> (); + FIELD<double> *aField_2 = new FIELD<double> (); + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if (tmp_dir == "") + tmp_dir = "/tmp"; + string filename_rd = data_dir + "/share/salome/resources/med/pointe.med"; + string filenameWithOutFileds = data_dir + "/share/salome/resources/med/Mistrat.med"; + string fileldnotexist = "anyfield"; + string fieldname = "fieldnodeint"; + string fieldname_cpy = fieldname + "_cpy"; + string fileNotExist_rd = "notExist.med"; + string emptyfilename = ""; + + string filename_wr = tmp_dir + "/myWrField_pointe21.med"; + string cp_file_wr = "cp " + filename_rd + " " + filename_wr; + string fileNotExist_wr = "/path_not_exist/file_not_exist.med"; + string emptyfile_wr = tmp_dir + "/myWrField_pointe_empty21.med"; + string other_file = data_dir + "/share/salome/resources/med/fra.med"; + string other_file_wr = tmp_dir + "/myWRfrab.med"; + string cp_other_file = "cp " + other_file + " " + other_file_wr; + + string filename_rdwr = tmp_dir + "/myRdWrField_pointe21.med"; + string cp_file_rdwr = "cp " + filename_rd + " " + filename_rdwr; + string emptyfile_rdwr = tmp_dir + "/myRdWrField_pointe_empty21.med"; + string fieldnameDouble = "fieldcelldoublescalar"; + string fieldnameDouble_cpy = fieldnameDouble + "_cpy"; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filename_wr); + aRemover.Register(emptyfile_wr); + aRemover.Register(other_file_wr); + aRemover.Register(filename_rdwr); + aRemover.Register(emptyfile_rdwr); + + //--------------------------Test READ ONLY part------------------------------// + + ///////////////////////////////////// + // TEST1: Open not existing file // + ///////////////////////////////////// + + //Creation Invalid Read Only MedFieldDriver21 (file not exist) + MED_FIELD_RDONLY_DRIVER21<int> *aInvalidMedRdFieldDriver21_1 = + new MED_FIELD_RDONLY_DRIVER21<int>(fileNotExist_rd, aField); + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedRdFieldDriver21_1->open(), MEDEXCEPTION); + + ////////////////////////////////////////////// + // TEST2: Open file with empty file name /// + ////////////////////////////////////////////// + + //Creation Invalid Read Only MedFieldDriver21 (empty file name) + MED_FIELD_RDONLY_DRIVER21<int> *aInvalidMedRdFieldDriver21_2 = + new MED_FIELD_RDONLY_DRIVER21<int>(emptyfilename, aField); + //Trying file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedRdFieldDriver21_2->open(), MEDEXCEPTION); + + ///////////////////////////////////////////////////// + // TEST3: Reading field from file without fields // + ///////////////////////////////////////////////////// + MED_FIELD_RDONLY_DRIVER21<int> *aInvalidMedRdFieldDriver21_3 = + new MED_FIELD_RDONLY_DRIVER21<int>(filenameWithOutFileds, aField); + aInvalidMedRdFieldDriver21_3->open(); + aInvalidMedRdFieldDriver21_3->setFieldName(fieldname); + //Trying read field from file + CPPUNIT_ASSERT_THROW(aInvalidMedRdFieldDriver21_3->read(), MEDEXCEPTION); + aInvalidMedRdFieldDriver21_3->close(); + + //////////////////////// + // TEST4: Main test // + //////////////////////// + //Creation correct Read Only MedFieldDriver21 + MED_FIELD_RDONLY_DRIVER21<int> *aMedRdFieldDriver21 = + new MED_FIELD_RDONLY_DRIVER21<int>(filename_rd, aField); + + //Check driver + CPPUNIT_ASSERT(aMedRdFieldDriver21); + + //Trying read field before open file + CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->read(),MEDEXCEPTION); + + //Test open() method + try + { + aMedRdFieldDriver21->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //#ifdef ENABLE_FORCED_FAILURES + //Trying open file secondary. + //CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->open(), MEDEXCEPTION); + // CPPUNIT_ASSERT_NO_THROW(aMedRdFieldDriver21->open()); + // (BUG) No exception in this case + //#endif + + //Trying read field form file if it name is empty + CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->read(), MEDEXCEPTION); + //CPPUNIT_ASSERT_NO_THROW(aMedRdFieldDriver21->read(), MEDEXCEPTION); + + //Test setFieldName() and getFieldName() + try + { + aMedRdFieldDriver21->setFieldName(fileldnotexist); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT_EQUAL(fileldnotexist, aMedRdFieldDriver21->getFieldName()); + + //Trying read not existing field from file + CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->read(), MEDEXCEPTION); + + //Test read() method + aMedRdFieldDriver21->setFieldName(fieldname); + try + { + aMedRdFieldDriver21->read(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test write() method for READ ONLY driver + CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->write(), MEDEXCEPTION); + + //Test close() method + try + { + aMedRdFieldDriver21->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_FIELD_RDONLY_DRIVER21<int> aMedRdFieldDriver21Cpy_1; + + //Test (void operator =) defined in GENDRIVER class in MEDMEM_GenDriver.hxx + aMedRdFieldDriver21Cpy_1 = *aMedRdFieldDriver21; + + //Test (bool operator ==) defined GENDRIVER class in MEDMEM_GenDriver.hxx + CPPUNIT_ASSERT(aMedRdFieldDriver21Cpy_1 == *aMedRdFieldDriver21); + + //Test copy constructor + MED_FIELD_RDONLY_DRIVER21<int> aMedRdFieldDriver21Cpy_2 (*aMedRdFieldDriver21); + CPPUNIT_ASSERT_EQUAL(aMedRdFieldDriver21Cpy_2, *aMedRdFieldDriver21); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream rostr1, rostr2; + rostr1<<aMedRdFieldDriver21Cpy_1; + rostr2<<aMedRdFieldDriver21Cpy_2; + CPPUNIT_ASSERT(rostr1.str() != ""); + CPPUNIT_ASSERT(rostr1.str() == rostr2.str()); + + + //--------------------------Test WRITE ONLY part------------------------------// + + //Copy file + //system(cp_other_file.c_str()); + system(cp_file_wr.c_str()); + + ///////////////////////////////////// + // TEST1: Open not existing file // + ///////////////////////////////////// + + //Creation Invalid Write Only MedFieldDriver21 (file not exist) + MED_FIELD_WRONLY_DRIVER21<int> *aInvalidMedWrFieldDriver21_1 = + new MED_FIELD_WRONLY_DRIVER21<int>(fileNotExist_wr, aField_1); + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver21_1->open(), MEDEXCEPTION); + + ///////////////////////////////////////////// + // TEST2: Open file with empty file name // + ///////////////////////////////////////////// + //Creation Invalid Write Only MedFieldDriver21 (empty file name) + MED_FIELD_WRONLY_DRIVER21<int> *aInvalidMedWrFieldDriver21_2 = + new MED_FIELD_WRONLY_DRIVER21<int>(emptyfilename, aField_1); + //Trying open not existing file and file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver21_2->open(), MEDEXCEPTION); + + /////////////////////////////////////////////////////// + // TEST3: Writing field in empty file without mesh // -- no problem + /////////////////////////////////////////////////////// + //Creation Write Only MedFieldDriver21 + MED_FIELD_WRONLY_DRIVER21<int> *aInvalidMedWrFieldDriver21_3 = + new MED_FIELD_WRONLY_DRIVER21<int>(emptyfile_wr, aField); + + aInvalidMedWrFieldDriver21_3->open(); + //#ifdef ENABLE_FAULTS + CPPUNIT_ASSERT_NO_THROW(aInvalidMedWrFieldDriver21_3->write()); + //=>Segmentation fault in this case + //#endif + + ////////////////////////////////////////////// + // TEST4: Writing field in the other file // + ////////////////////////////////////////////// + + //Creation Write Only MedFieldDriver21 + MED_FIELD_WRONLY_DRIVER21<int> *aInvalidMedWrFieldDriver21_4 = + new MED_FIELD_WRONLY_DRIVER21<int>(other_file_wr, aField); + aInvalidMedWrFieldDriver21_4->open(); + //#ifdef ENABLE_FAULTS + CPPUNIT_ASSERT_NO_THROW(aInvalidMedWrFieldDriver21_4->write()); + aInvalidMedWrFieldDriver21_4->close(); + //=>Segmentation fault in this case + //#endif + + //////////////////////// + // TEST5: Main test // + //////////////////////// + + //Creation correct Write Only MedFieldDriver21 + MED_FIELD_WRONLY_DRIVER21<int> *aMedWrFieldDriver21 = + new MED_FIELD_WRONLY_DRIVER21<int>(filename_wr, aField); + + //Check driver + CPPUNIT_ASSERT(aMedWrFieldDriver21); + + //Trying write field before open file + //#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedWrFieldDriver21->write(),MEDEXCEPTION); + //CPPUNIT_ASSERT_NO_THROW(aMedWrFieldDriver21->write()); + // (BUG) No exception in this case + //#endif + + //Test open() method + try + { + aMedWrFieldDriver21->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //#ifdef ENABLE_FORCED_FAILURES + //Trying open file secondary. + //CPPUNIT_ASSERT_THROW(aMedWrFieldDriver21->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aMedWrFieldDriver21->open()); + // (BUG) No exception in this case + //#endif + + //Test setFieldName() and getFieldName + aField->setName(fieldname_cpy); + try + { + aMedWrFieldDriver21->setFieldName(fieldname_cpy); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT_EQUAL(fieldname_cpy, aMedWrFieldDriver21->getFieldName()); + + // there must be exception as mesh is not yet read + // !!!!!!! mesh is not needed for writing !!!!!!! + //CPPUNIT_ASSERT_THROW(aMedWrFieldDriver21->write(),MEDEXCEPTION); + + try { + aMedWrFieldDriver21->write(); + + MESH* aMesh = new MESH(); + aMesh->setName("maa1"); + MED_MESH_RDONLY_DRIVER aMeshDriver (filename_rd, aMesh); + aMeshDriver.setMeshName("maa1"); + aMeshDriver.open(); + aMeshDriver.read(); + aMeshDriver.close(); + SUPPORT* sup = new SUPPORT(aMesh); + aField->setSupport(sup); + } + catch(MEDEXCEPTION &e) { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) { + CPPUNIT_FAIL("Unknown exception"); + } + + //MESH* mesh(MED_DRIVER,); + //aMedWrFieldDriver21->getSupport()->setMesh(mesh);//read(),MEDEXCEPTION); + + //#ifdef ENABLE_FAULTS + //Test write() method + try + { + aMedWrFieldDriver21->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + //=>Segmentation fault in this case + //#endif + + //Test read() method for Write only part + CPPUNIT_ASSERT_THROW(aMedWrFieldDriver21->read(),MEDEXCEPTION); + + //Test close() method + try + { + aMedWrFieldDriver21->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_FIELD_WRONLY_DRIVER21<int> aMedWrFieldDriver21Cpy_1; + + //Test (void operator =) defined in GENDRIVER class + aMedWrFieldDriver21Cpy_1 = *aMedWrFieldDriver21; + + //Test (bool operator ==) defined in GENDRIVER class + CPPUNIT_ASSERT(aMedWrFieldDriver21Cpy_1.GENDRIVER::operator==(*aMedWrFieldDriver21)); + + //Test copy constructor + MED_FIELD_WRONLY_DRIVER21<int> aMedWrFieldDriver21Cpy_2 (*aMedWrFieldDriver21); + CPPUNIT_ASSERT_EQUAL(aMedWrFieldDriver21Cpy_2, *aMedWrFieldDriver21); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream wostr1, wostr2; + wostr1 << aMedWrFieldDriver21Cpy_1; + wostr2 << aMedWrFieldDriver21Cpy_2; + CPPUNIT_ASSERT(wostr1.str() != ""); + CPPUNIT_ASSERT(wostr1.str() == wostr2.str()); + + + //--------------------------Test READ/WRITE part------------------------------// + + //Copy files + system(cp_file_rdwr.c_str()); + ///////////////////////////////////// + // TEST1: Open not existing file // + ///////////////////////////////////// + + //Creation Invalid Read/Write MedFieldDriver21 (file not exist) + MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_1 = + new MED_FIELD_RDWR_DRIVER21<int>(fileNotExist_wr, aField_1); + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_1->open(), MEDEXCEPTION); + + ///////////////////////////////////////////// + // TEST2: Open file with empty file name // + ///////////////////////////////////////////// + //Creation Invalid Read/Write MedFieldDriver21 (empty file name) + MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_2 = + new MED_FIELD_RDWR_DRIVER21<int>(emptyfilename, aField_1); + //Trying open not existing file and file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_2->open(), MEDEXCEPTION); + + ///////////////////////////////////////////////////// + // TEST3: Reading field from file without fields // + ///////////////////////////////////////////////////// + MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_3 = + new MED_FIELD_RDWR_DRIVER21<int>(filenameWithOutFileds, aField_1); + aInvalidMedRdWrFieldDriver21_3->open(); + aInvalidMedRdWrFieldDriver21_3->setFieldName(fieldname); + //Trying read field from file + CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_3->read(), MEDEXCEPTION); + aInvalidMedRdWrFieldDriver21_3->close(); + + /////////////////////////////////////////////////////// + // TEST4: Writing field in empty file without mesh // + /////////////////////////////////////////////////////// + //Creation Invalid Read/Write MedFieldDriver21 + MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_4 = + new MED_FIELD_RDWR_DRIVER21<int>(emptyfile_rdwr, aField); + + aInvalidMedRdWrFieldDriver21_4->open(); + //#ifdef ENABLE_FAULTS + // CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_4->write(), MEDEXCEPTION); + //=>Segmentation fault in this case + //#endif + + //VB : I don't quite understand the test, because, if the + //file is already open, it is the open method that should fail. + // as it is of little importance for the whole test base, + //I remove it altogether + +// ////////////////////////////////////////////// +// // TEST6: Writing field in the other file // +// ////////////////////////////////////////////// +// //Creation Invalid Read/Write MedFieldDriver21 +// MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_5 = +// new MED_FIELD_RDWR_DRIVER21<int>(other_file_wr, aField); +// aInvalidMedRdWrFieldDriver21_5->open(); +// //#ifdef ENABLE_FAULTS +// CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_5->write(), MEDEXCEPTION); +// //=>Segmentation fault in this case +// //#endif + + //////////////////////// + // TEST7: Main test // + //////////////////////// + + //Creation correct Read/Write MedFieldDriver21 + MED_FIELD_RDWR_DRIVER21<double> *aMedRdWrFieldDriver21 = + new MED_FIELD_RDWR_DRIVER21<double>(filename_rdwr, aField_2); + + //Check driver + CPPUNIT_ASSERT(aMedRdWrFieldDriver21); + + //Trying read/write field before open file + CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->read(),MEDEXCEPTION); + //#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->write(),MEDEXCEPTION); + //(BUG) No exception in this case + //#endif + + //Test open() method + try + { + aMedRdWrFieldDriver21->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //#ifdef ENABLE_FORCED_FAILURES + //Trying open file secondary. + // CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->open(), MEDEXCEPTION); + // (BUG) No exception in this case + //#endif + + //Trying read field from file if field name is empty + CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->read(), MEDEXCEPTION); + + //Test setFieldName() and getFieldName + try + { + aMedRdWrFieldDriver21->setFieldName(fileldnotexist); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT_EQUAL(fileldnotexist, aMedRdWrFieldDriver21->getFieldName()); + + //Trying read not existing field from file + // CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->read(), MEDEXCEPTION); + + //Test read() method + + aMedRdWrFieldDriver21->setFieldName(fieldnameDouble); + aMedRdWrFieldDriver21->open(); + try + { + aMedRdWrFieldDriver21->read(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying write field in the file with empty name + aField_2->setName(emptyfilename); + aMedRdWrFieldDriver21->setFieldName(emptyfilename); + CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->write(), MEDEXCEPTION); + + //Test write() method + aField_2->setName(fieldnameDouble_cpy); + aMedRdWrFieldDriver21->setFieldName(fieldnameDouble_cpy); + //#ifdef ENABLE_FAULTS + try + { + aMedRdWrFieldDriver21->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + //=>Segmentation fault in this case + //#endif + + //Test close() method + try + { + aMedRdWrFieldDriver21->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_FIELD_RDWR_DRIVER21<double> aMedRdWrFieldDriver21Cpy_1; + + //Test (void operator =) defined in GENDRIVER class + aMedRdWrFieldDriver21Cpy_1 = *aMedRdWrFieldDriver21; + + //Test (bool operator ==) defined in GENDRIVER class + CPPUNIT_ASSERT(aMedRdWrFieldDriver21Cpy_1.GENDRIVER::operator==(*aMedRdWrFieldDriver21)); + + //Test copy constructor + MED_FIELD_RDWR_DRIVER21<double> aMedRdWrFieldDriver21Cpy_2 (*aMedRdWrFieldDriver21); + CPPUNIT_ASSERT_EQUAL(aMedRdWrFieldDriver21Cpy_2, *aMedRdWrFieldDriver21); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream rwostr1, rwostr2; + rwostr1 << aMedRdWrFieldDriver21Cpy_1; + rwostr2 << aMedRdWrFieldDriver21Cpy_2; + CPPUNIT_ASSERT(rwostr1.str() != ""); + CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + //Delete all objects + delete aField; + delete aField_1; + delete aField_2; + + delete aInvalidMedRdFieldDriver21_1; + delete aInvalidMedRdFieldDriver21_2; + delete aInvalidMedRdFieldDriver21_3; + delete aMedRdFieldDriver21; + + delete aInvalidMedWrFieldDriver21_1; + delete aInvalidMedWrFieldDriver21_2; + delete aInvalidMedWrFieldDriver21_3; + delete aInvalidMedWrFieldDriver21_4; + delete aMedWrFieldDriver21; + + delete aInvalidMedRdWrFieldDriver21_1; + delete aInvalidMedRdWrFieldDriver21_2; + delete aInvalidMedRdWrFieldDriver21_3; + delete aInvalidMedRdWrFieldDriver21_4; + // delete aInvalidMedRdWrFieldDriver21_5; + delete aMedRdWrFieldDriver21; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_MedFieldDriver21_fault.cxx b/src/MEDMEMCppTest/MEDMEMTest_MedFieldDriver21_fault.cxx new file mode 100644 index 000000000..03d9b0842 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_MedFieldDriver21_fault.cxx @@ -0,0 +1,632 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include <MEDMEM_Field.hxx> +#include <MEDMEM_MedFieldDriver21.hxx> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +/*! + * Check methods (17), defined in MEDMEM_MedFieldDriver21.hxx: + * template <class T> class MED_FIELD_DRIVER21 : public virtual MED_FIELD_DRIVER<T> { + * (+) MED_FIELD_DRIVER21(); + * (+) template <class INTERLACING_TAG> MED_FIELD_DRIVER21(const string & fileName, + * FIELD<T, INTERLACING_TAG> * ptrField, MED_EN::med_mode_acces accessMode); + * (+) MED_FIELD_DRIVER21(const MED_FIELD_DRIVER21 & fieldDriver); + * (+) virtual ~MED_FIELD_DRIVER21(); + * (+) void open() throw (MEDEXCEPTION); + * (+) void close(); + * } + * template <class T> class MED_FIELD_RDONLY_DRIVER21 : public virtual MED_FIELD_DRIVER21<T>, + * public virtual IMED_FIELD_RDONLY_DRIVER<T> { + * (+) MED_FIELD_RDONLY_DRIVER21(); + * (+) template <class INTERLACING_TAG> MED_FIELD_RDONLY_DRIVER21 + * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField); + * (+) MED_FIELD_RDONLY_DRIVER21(const MED_FIELD_RDONLY_DRIVER21 & fieldDriver); + * (+) virtual ~MED_FIELD_RDONLY_DRIVER21(); + * (+) void write(void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * } + * template <class T> class MED_FIELD_WRONLY_DRIVER21 : public virtual MED_FIELD_DRIVER21<T>, + * public virtual IMED_FIELD_WRONLY_DRIVER<T> { + * (+) MED_FIELD_WRONLY_DRIVER21(); + * (+) template <class INTERLACING_TAG> MED_FIELD_WRONLY_DRIVER21 + * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField); + * (+) MED_FIELD_WRONLY_DRIVER21(const MED_FIELD_WRONLY_DRIVER21 & fieldDriver); + * (+) virtual ~MED_FIELD_WRONLY_DRIVER21(); + * (+) void write(void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * } + * template <class T> class MED_FIELD_RDWR_DRIVER21 : public MED_FIELD_RDONLY_DRIVER21<T>, + * public MED_FIELD_WRONLY_DRIVER21<T>, public IMED_FIELD_RDWR_DRIVER<T> { + * (+) MED_FIELD_RDWR_DRIVER21(); + * (+) template <class INTERLACING_TAG> MED_FIELD_RDWR_DRIVER21 + * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField); + * (+) MED_FIELD_RDWR_DRIVER21(const MED_FIELD_RDWR_DRIVER21 & fieldDriver); + * (+) ~MED_FIELD_RDWR_DRIVER21(); + * (+) void write(void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * } + */ +void MEDMEMTest_testMedFieldDriver21() +{ + FIELD<int> *aField = new FIELD<int> (); + FIELD<int> *aField_1 = new FIELD<int> (); + FIELD<double> *aField_2 = new FIELD<double> (); + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if (tmp_dir == "") + tmp_dir = "/tmp"; + string filename_rd = data_dir + "/share/salome/resources/med/pointe.med"; + string filenameWithOutFileds = data_dir + "/share/salome/resources/med/Mistrat.med"; + string fileldnotexist = "anyfield"; + string fieldname = "fieldnodeint"; + string fieldname_cpy = fieldname + "_cpy"; + string fileNotExist_rd = "notExist.med"; + string emptyfilename = ""; + + string filename_wr = tmp_dir + "/myWrField_pointe21.med"; + string cp_file_wr = "cp " + filename_rd + " " + filename_wr; + string fileNotExist_wr = "/path_not_exist/file_not_exist.med"; + string emptyfile_wr = tmp_dir + "/myWrField_pointe_empty21.med"; + string other_file = data_dir + "/share/salome/resources/med/fra.med"; + string other_file_wr = tmp_dir + "/myWRfra.med"; + string cp_other_file = "cp " + other_file + " " + other_file_wr; + + string filename_rdwr = tmp_dir + "/myRdWrField_pointe21.med"; + string cp_file_rdwr = "cp " + filename_rd + " " + filename_rdwr; + string emptyfile_rdwr = tmp_dir + "/myRdWrField_pointe_empty21.med"; + string fieldnameDouble = "fieldnodedouble"; + string fieldnameDouble_cpy = fieldnameDouble + "_cpy"; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filename_wr); + aRemover.Register(emptyfile_wr); + aRemover.Register(other_file_wr); + aRemover.Register(filename_rdwr); + aRemover.Register(emptyfile_rdwr); + + //--------------------------Test READ ONLY part------------------------------// + + ///////////////////////////////////// + // TEST1: Open not existing file // + ///////////////////////////////////// + + //Creation Invalid Read Only MedFieldDriver21 (file not exist) + MED_FIELD_RDONLY_DRIVER21<int> *aInvalidMedRdFieldDriver21_1 = + new MED_FIELD_RDONLY_DRIVER21<int>(fileNotExist_rd, aField); + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedRdFieldDriver21_1->open(), MEDEXCEPTION); + + ////////////////////////////////////////////// + // TEST2: Open file with empty file name /// + ////////////////////////////////////////////// + + //Creation Invalid Read Only MedFieldDriver21 (empty file name) + MED_FIELD_RDONLY_DRIVER21<int> *aInvalidMedRdFieldDriver21_2 = + new MED_FIELD_RDONLY_DRIVER21<int>(emptyfilename, aField); + //Trying file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedRdFieldDriver21_2->open(), MEDEXCEPTION); + + ///////////////////////////////////////////////////// + // TEST3: Reading field from file without fields // + ///////////////////////////////////////////////////// + MED_FIELD_RDONLY_DRIVER21<int> *aInvalidMedRdFieldDriver21_3 = + new MED_FIELD_RDONLY_DRIVER21<int>(filenameWithOutFileds, aField); + aInvalidMedRdFieldDriver21_3->open(); + aInvalidMedRdFieldDriver21_3->setFieldName(fieldname); + //Trying read field from file + CPPUNIT_ASSERT_THROW(aInvalidMedRdFieldDriver21_3->read(), MEDEXCEPTION); + aInvalidMedRdFieldDriver21_3->close(); + + //////////////////////// + // TEST4: Main test // + //////////////////////// + //Creation correct Read Only MedFieldDriver21 + MED_FIELD_RDONLY_DRIVER21<int> *aMedRdFieldDriver21 = + new MED_FIELD_RDONLY_DRIVER21<int>(filename_rd, aField); + + //Check driver + CPPUNIT_ASSERT(aMedRdFieldDriver21); + + //Trying read field before open file + CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->read(),MEDEXCEPTION); + + //Test open() method + try + { + aMedRdFieldDriver21->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + +//#ifdef ENABLE_FORCED_FAILURES + //Trying open file secondary. + CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->open(), MEDEXCEPTION); + // (BUG) No exception in this case +//#endif + + //Trying read field form file if it name is empty + CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->read(), MEDEXCEPTION); + + //Test setFieldName() and getFieldName() + try + { + aMedRdFieldDriver21->setFieldName(fileldnotexist); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT_EQUAL(fileldnotexist, aMedRdFieldDriver21->getFieldName()); + + //Trying read not existing field from file + CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->read(), MEDEXCEPTION); + + //Test read() method + aMedRdFieldDriver21->setFieldName(fieldname); + try + { + aMedRdFieldDriver21->read(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test write() method for READ ONLY driver + CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->write(), MEDEXCEPTION); + + //Test close() method + try + { + aMedRdFieldDriver21->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_FIELD_RDONLY_DRIVER21<int> aMedRdFieldDriver21Cpy_1; + + //Test (void operator =) defined in GENDRIVER class in MEDMEM_GenDriver.hxx + aMedRdFieldDriver21Cpy_1 = *aMedRdFieldDriver21; + + //Test (bool operator ==) defined GENDRIVER class in MEDMEM_GenDriver.hxx + CPPUNIT_ASSERT(aMedRdFieldDriver21Cpy_1 == *aMedRdFieldDriver21); + + //Test copy constructor + MED_FIELD_RDONLY_DRIVER21<int> aMedRdFieldDriver21Cpy_2 (*aMedRdFieldDriver21); + CPPUNIT_ASSERT_EQUAL(aMedRdFieldDriver21Cpy_2, *aMedRdFieldDriver21); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream rostr1, rostr2; + rostr1<<aMedRdFieldDriver21Cpy_1; + rostr2<<aMedRdFieldDriver21Cpy_2; + CPPUNIT_ASSERT(rostr1.str() != ""); + CPPUNIT_ASSERT(rostr1.str() == rostr2.str()); + + + //--------------------------Test WRITE ONLY part------------------------------// + + //Copy file + system(cp_other_file.c_str()); + system(cp_file_wr.c_str()); + + ///////////////////////////////////// + // TEST1: Open not existing file // + ///////////////////////////////////// + + //Creation Invalid Write Only MedFieldDriver21 (file not exist) + MED_FIELD_WRONLY_DRIVER21<int> *aInvalidMedWrFieldDriver21_1 = + new MED_FIELD_WRONLY_DRIVER21<int>(fileNotExist_wr, aField_1); + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver21_1->open(), MEDEXCEPTION); + + ///////////////////////////////////////////// + // TEST2: Open file with empty file name // + ///////////////////////////////////////////// + //Creation Invalid Write Only MedFieldDriver21 (empty file name) + MED_FIELD_WRONLY_DRIVER21<int> *aInvalidMedWrFieldDriver21_2 = + new MED_FIELD_WRONLY_DRIVER21<int>(emptyfilename, aField_1); + //Trying open not existing file and file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver21_2->open(), MEDEXCEPTION); + + /////////////////////////////////////////////////////// + // TEST3: Writing field in empty file without mesh // + /////////////////////////////////////////////////////// + //Creation Invalid Write Only MedFieldDriver21 + MED_FIELD_WRONLY_DRIVER21<int> *aInvalidMedWrFieldDriver21_3 = + new MED_FIELD_WRONLY_DRIVER21<int>(emptyfile_wr, aField); + + aInvalidMedWrFieldDriver21_3->open(); +//#ifdef ENABLE_FAULTS + CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver21_3->write(), MEDEXCEPTION); + //=>Segmentation fault in this case +//#endif + + ////////////////////////////////////////////// + // TEST4: Writing field in the other file // + ////////////////////////////////////////////// + + //Creation Invalid Write Only MedFieldDriver21 + MED_FIELD_WRONLY_DRIVER21<int> *aInvalidMedWrFieldDriver21_4 = + new MED_FIELD_WRONLY_DRIVER21<int>(other_file_wr, aField); + aInvalidMedWrFieldDriver21_4->open(); +//#ifdef ENABLE_FAULTS + CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver21_4->write(), MEDEXCEPTION); + //=>Segmentation fault in this case +//#endif + + //////////////////////// + // TEST5: Main test // + //////////////////////// + + //Creation correct Write Only MedFieldDriver21 + MED_FIELD_WRONLY_DRIVER21<int> *aMedWrFieldDriver21 = + new MED_FIELD_WRONLY_DRIVER21<int>(filename_wr, aField); + + //Check driver + CPPUNIT_ASSERT(aMedWrFieldDriver21); + + //Trying write field before open file +//#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedWrFieldDriver21->write(),MEDEXCEPTION); + // (BUG) No exception in this case +//#endif + + //Test open() method + try + { + aMedWrFieldDriver21->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + +//#ifdef ENABLE_FORCED_FAILURES + //Trying open file secondary. + CPPUNIT_ASSERT_THROW(aMedWrFieldDriver21->open(), MEDEXCEPTION); + // (BUG) No exception in this case +//#endif + + //Test setFieldName() and getFieldName + aField->setName(fieldname_cpy); + try + { + aMedWrFieldDriver21->setFieldName(fieldname_cpy); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT_EQUAL(fieldname_cpy, aMedWrFieldDriver21->getFieldName()); + +//#ifdef ENABLE_FAULTS + //Test write() method + try + { + aMedWrFieldDriver21->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + //=>Segmentation fault in this case +//#endif + + //Test read() method for Write only part + CPPUNIT_ASSERT_THROW(aMedWrFieldDriver21->read(),MEDEXCEPTION); + + //Test close() method + try + { + aMedWrFieldDriver21->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_FIELD_WRONLY_DRIVER21<int> aMedWrFieldDriver21Cpy_1; + + //Test (void operator =) defined in GENDRIVER class + //aMedWrFieldDriver21Cpy_1 = *aMedWrFieldDriver21; + + //Test (bool operator ==) defined in GENDRIVER class + CPPUNIT_ASSERT(aMedWrFieldDriver21Cpy_1.GENDRIVER::operator==(*aMedWrFieldDriver21)); + + //Test copy constructor + MED_FIELD_WRONLY_DRIVER21<int> aMedWrFieldDriver21Cpy_2 (*aMedWrFieldDriver21); + CPPUNIT_ASSERT_EQUAL(aMedWrFieldDriver21Cpy_2, *aMedWrFieldDriver21); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream wostr1, wostr2; + wostr1 << aMedWrFieldDriver21Cpy_1; + wostr2 << aMedWrFieldDriver21Cpy_2; + CPPUNIT_ASSERT(wostr1.str() != ""); + CPPUNIT_ASSERT(wostr1.str() == wostr2.str()); + + + //--------------------------Test READ/WRITE part------------------------------// + + //Copy files + system(cp_file_rdwr.c_str()); + ///////////////////////////////////// + // TEST1: Open not existing file // + ///////////////////////////////////// + + //Creation Invalid Read/Write MedFieldDriver21 (file not exist) + MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_1 = + new MED_FIELD_RDWR_DRIVER21<int>(fileNotExist_wr, aField_1); + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_1->open(), MEDEXCEPTION); + + ///////////////////////////////////////////// + // TEST2: Open file with empty file name // + ///////////////////////////////////////////// + //Creation Invalid Read/Write MedFieldDriver21 (empty file name) + MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_2 = + new MED_FIELD_RDWR_DRIVER21<int>(emptyfilename, aField_1); + //Trying open not existing file and file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_2->open(), MEDEXCEPTION); + + ///////////////////////////////////////////////////// + // TEST3: Reading field from file without fields // + ///////////////////////////////////////////////////// + MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_3 = + new MED_FIELD_RDWR_DRIVER21<int>(filenameWithOutFileds, aField_1); + aInvalidMedRdWrFieldDriver21_3->open(); + aInvalidMedRdWrFieldDriver21_3->setFieldName(fieldname); + //Trying read field from file + CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_3->read(), MEDEXCEPTION); + aInvalidMedRdWrFieldDriver21_3->close(); + + /////////////////////////////////////////////////////// + // TEST4: Writing field in empty file without mesh // + /////////////////////////////////////////////////////// + //Creation Invalid Read/Write MedFieldDriver21 + MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_4 = + new MED_FIELD_RDWR_DRIVER21<int>(emptyfile_rdwr, aField); + + aInvalidMedRdWrFieldDriver21_4->open(); +//#ifdef ENABLE_FAULTS + CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_4->write(), MEDEXCEPTION); + //=>Segmentation fault in this case +//#endif + + ////////////////////////////////////////////// + // TEST6: Writing field in the other file // + ////////////////////////////////////////////// + //Creation Invalid Read/Write MedFieldDriver21 + MED_FIELD_RDWR_DRIVER21<int> *aInvalidMedRdWrFieldDriver21_5 = + new MED_FIELD_RDWR_DRIVER21<int>(other_file_wr, aField); + aInvalidMedRdWrFieldDriver21_5->open(); +//#ifdef ENABLE_FAULTS + CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver21_5->write(), MEDEXCEPTION); + //=>Segmentation fault in this case +//#endif + + //////////////////////// + // TEST7: Main test // + //////////////////////// + + //Creation correct Read/Write MedFieldDriver21 + MED_FIELD_RDWR_DRIVER21<double> *aMedRdWrFieldDriver21 = + new MED_FIELD_RDWR_DRIVER21<double>(filename_rdwr, aField_2); + + //Check driver + CPPUNIT_ASSERT(aMedRdWrFieldDriver21); + + //Trying read/write field before open file + CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->read(),MEDEXCEPTION); +//#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->write(),MEDEXCEPTION); + //(BUG) No exception in this case +//#endif + + //Test open() method + try + { + aMedRdWrFieldDriver21->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + +//#ifdef ENABLE_FORCED_FAILURES + //Trying open file secondary. + CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->open(), MEDEXCEPTION); + // (BUG) No exception in this case +//#endif + + //Trying read field from file if field name is empty + CPPUNIT_ASSERT_THROW(aMedRdFieldDriver21->read(), MEDEXCEPTION); + + //Test setFieldName() and getFieldName + try + { + aMedRdWrFieldDriver21->setFieldName(fileldnotexist); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT_EQUAL(fileldnotexist, aMedRdWrFieldDriver21->getFieldName()); + + //Trying read not existing field from file + CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->read(), MEDEXCEPTION); + + //Test read() method + aMedRdWrFieldDriver21->setFieldName(fieldnameDouble); + try + { + aMedRdWrFieldDriver21->read(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying write field in the file with empty name + aField_2->setName(emptyfilename); + aMedRdWrFieldDriver21->setFieldName(emptyfilename); + CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver21->write(), MEDEXCEPTION); + + //Test write() method + aField_2->setName(fieldnameDouble_cpy); + aMedRdWrFieldDriver21->setFieldName(fieldnameDouble_cpy); +//#ifdef ENABLE_FAULTS + try + { + aMedRdWrFieldDriver21->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + //=>Segmentation fault in this case +//#endif + + //Test close() method + try + { + aMedRdWrFieldDriver21->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_FIELD_RDWR_DRIVER21<double> aMedRdWrFieldDriver21Cpy_1; + + //Test (void operator =) defined in GENDRIVER class + //aMedRdWrFieldDriver21Cpy_1 = *aMedRdWrFieldDriver21; + + //Test (bool operator ==) defined in GENDRIVER class + CPPUNIT_ASSERT(aMedRdWrFieldDriver21Cpy_1.GENDRIVER::operator==(*aMedRdWrFieldDriver21)); + + //Test copy constructor + MED_FIELD_RDWR_DRIVER21<double> aMedRdWrFieldDriver21Cpy_2 (*aMedRdWrFieldDriver21); + CPPUNIT_ASSERT_EQUAL(aMedRdWrFieldDriver21Cpy_2, *aMedRdWrFieldDriver21); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream rwostr1, rwostr2; + rwostr1 << aMedRdWrFieldDriver21Cpy_1; + rwostr2 << aMedRdWrFieldDriver21Cpy_2; + CPPUNIT_ASSERT(rwostr1.str() != ""); + CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + //Delete all objects + delete aField; + delete aField_1; + delete aField_2; + + delete aInvalidMedRdFieldDriver21_1; + delete aInvalidMedRdFieldDriver21_2; + delete aInvalidMedRdFieldDriver21_3; + delete aMedRdFieldDriver21; + + delete aInvalidMedWrFieldDriver21_1; + delete aInvalidMedWrFieldDriver21_2; + delete aInvalidMedWrFieldDriver21_3; + delete aInvalidMedWrFieldDriver21_4; + delete aMedWrFieldDriver21; + + delete aInvalidMedRdWrFieldDriver21_1; + delete aInvalidMedRdWrFieldDriver21_2; + delete aInvalidMedRdWrFieldDriver21_3; + delete aInvalidMedRdWrFieldDriver21_4; + delete aInvalidMedRdWrFieldDriver21_5; + delete aMedRdWrFieldDriver21; +} + +int main (int argc, char** argv) +{ + MEDMEMTest_testMedFieldDriver21(); +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_MedFieldDriver22.cxx b/src/MEDMEMCppTest/MEDMEMTest_MedFieldDriver22.cxx new file mode 100644 index 000000000..d087563ea --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_MedFieldDriver22.cxx @@ -0,0 +1,626 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include <MEDMEM_Field.hxx> +#include <MEDMEM_MedFieldDriver22.hxx> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +/*! + * Check methods (17), defined in MEDMEM_MedFieldDriver22.hxx: + * template <class T> class MED_FIELD_DRIVER22 : public virtual MED_FIELD_DRIVER<T> { + * (+) MED_FIELD_DRIVER22(); + * (+) template <class INTERLACING_TAG> MED_FIELD_DRIVER22(const string & fileName, + * FIELD<T, INTERLACING_TAG> * ptrField, MED_EN::med_mode_acces accessMode); + * (+) MED_FIELD_DRIVER22(const MED_FIELD_DRIVER22 & fieldDriver); + * (+) virtual ~MED_FIELD_DRIVER22(); + * (+) void open() throw (MEDEXCEPTION); + * (+) void close(); + * } + * template <class T> class MED_FIELD_RDONLY_DRIVER22 : public virtual MED_FIELD_DRIVER22<T>, + * public virtual IMED_FIELD_RDONLY_DRIVER<T> { + * (+) MED_FIELD_RDONLY_DRIVER22(); + * (+) template <class INTERLACING_TAG> MED_FIELD_RDONLY_DRIVER22 + * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField); + * (+) MED_FIELD_RDONLY_DRIVER22(const MED_FIELD_RDONLY_DRIVER22 & fieldDriver); + * (+) virtual ~MED_FIELD_RDONLY_DRIVER22(); + * (+) void write(void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * } + * template <class T> class MED_FIELD_WRONLY_DRIVER22 : public virtual MED_FIELD_DRIVER22<T>, + * public virtual IMED_FIELD_WRONLY_DRIVER<T> { + * (+) MED_FIELD_WRONLY_DRIVER22(); + * (+) template <class INTERLACING_TAG> MED_FIELD_WRONLY_DRIVER22 + * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField); + * (+) MED_FIELD_WRONLY_DRIVER22(const MED_FIELD_WRONLY_DRIVER22 & fieldDriver); + * (+) virtual ~MED_FIELD_WRONLY_DRIVER22(); + * (+) void write(void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * } + * template <class T> class MED_FIELD_RDWR_DRIVER22 : public MED_FIELD_RDONLY_DRIVER22<T>, + * public MED_FIELD_WRONLY_DRIVER22<T>, public IMED_FIELD_RDWR_DRIVER<T> { + * (+) MED_FIELD_RDWR_DRIVER22(); + * (+) template <class INTERLACING_TAG> MED_FIELD_RDWR_DRIVER22 + * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField); + * (+) MED_FIELD_RDWR_DRIVER22(const MED_FIELD_RDWR_DRIVER22 & fieldDriver); + * (+) ~MED_FIELD_RDWR_DRIVER22(); + * (+) void write(void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * } + */ +void MEDMEMTest::testMedFieldDriver22() +{ + FIELD<int> *aField = new FIELD<int> (); + FIELD<int> *aField_1 = new FIELD<int> (); + FIELD<double> *aField_2 = new FIELD<double> (); + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if (tmp_dir == "") + tmp_dir = "/tmp"; + string filename_rd = data_dir + "/share/salome/resources/med/pointe_import22.med"; + string filenameWithOutFileds = data_dir + "/share/salome/resources/med/mesh_import22.med"; + string fileldnotexist = "anyfield"; + string fieldname = "fieldnodeint"; + string fieldname_cpy = fieldname + "_cpy"; + string fileNotExist_rd = "notExist22.med"; + string emptyfilename = ""; + + string filename_wr = tmp_dir + "/myWrField_pointe22.med"; + string cp_file_wr = "cp " + filename_rd + " " + filename_wr; + string fileNotExist_wr = "/path_not_exist/file_not_exist.med"; + string emptyfile_wr = tmp_dir + "/myWrField_pointe_empty22.med"; + string other_file = data_dir + "/share/salome/resources/med/cube_hexa8_import22.med"; + string other_file_wr = tmp_dir + "/myWRcube_hexa8_import22.med"; + string cp_other_file = "cp " + other_file + " " + other_file_wr; + + string filename_rdwr = tmp_dir + "/myRdWrField_pointe22.med"; + string cp_file_rdwr = "cp " + filename_rd + " " + filename_rdwr; + string emptyfile_rdwr = tmp_dir + "/myRdWrField_pointe_empty22.med"; + string fieldnameDouble = "fieldnodedouble"; + string fieldnameDouble_cpy = fieldnameDouble + "_cpy"; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filename_wr); + aRemover.Register(emptyfile_wr); + aRemover.Register(other_file_wr); + aRemover.Register(filename_rdwr); + aRemover.Register(emptyfile_rdwr); + + //--------------------------Test READ ONLY part------------------------------// + + ///////////////////////////////////// + // TEST1: Open not existing file // + ///////////////////////////////////// + + //Creation Invalid Read Only MedFieldDriver22 (file not exist) + MED_FIELD_RDONLY_DRIVER22<int> *aInvalidMedRdFieldDriver22_1 = + new MED_FIELD_RDONLY_DRIVER22<int>(fileNotExist_rd, aField); + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedRdFieldDriver22_1->open(), MEDEXCEPTION); + + ////////////////////////////////////////////// + // TEST2: Open file with empty file name /// + ////////////////////////////////////////////// + + //Creation Invalid Read Only MedFieldDriver22 (empty file name) + MED_FIELD_RDONLY_DRIVER22<int> *aInvalidMedRdFieldDriver22_2 = + new MED_FIELD_RDONLY_DRIVER22<int>(emptyfilename, aField); + //Trying file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedRdFieldDriver22_2->open(), MEDEXCEPTION); + + ///////////////////////////////////////////////////// + // TEST3: Reading field from file without fields // + ///////////////////////////////////////////////////// + MED_FIELD_RDONLY_DRIVER22<int> *aInvalidMedRdFieldDriver22_3 = + new MED_FIELD_RDONLY_DRIVER22<int>(filenameWithOutFileds, aField); + aInvalidMedRdFieldDriver22_3->open(); + aInvalidMedRdFieldDriver22_3->setFieldName(fieldname); + //Trying read field from file + CPPUNIT_ASSERT_THROW(aInvalidMedRdFieldDriver22_3->read(), MEDEXCEPTION); + aInvalidMedRdFieldDriver22_3->close(); + + //////////////////////// + // TEST4: Main test // + //////////////////////// + //Creation correct Read Only MedFieldDriver22 + MED_FIELD_RDONLY_DRIVER22<int> *aMedRdFieldDriver22 = + new MED_FIELD_RDONLY_DRIVER22<int>(filename_rd, aField); + + //Check driver + CPPUNIT_ASSERT(aMedRdFieldDriver22); + + //Trying read field before open file + CPPUNIT_ASSERT_THROW(aMedRdFieldDriver22->read(),MEDEXCEPTION); + + //Test open() method + try + { + aMedRdFieldDriver22->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //#ifdef ENABLE_FORCED_FAILURES + //Trying open file secondary. + //CPPUNIT_ASSERT_THROW(aMedRdFieldDriver22->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aMedRdFieldDriver22->open()); + // (BUG) No exception in this case + //#endif + + //Trying read field form file if it name is empty + CPPUNIT_ASSERT_THROW(aMedRdFieldDriver22->read(), MEDEXCEPTION); + + //Test setFieldName() and getFieldName() + try + { + aMedRdFieldDriver22->setFieldName(fileldnotexist); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT_EQUAL(fileldnotexist, aMedRdFieldDriver22->getFieldName()); + + //Trying read not existing field from file + CPPUNIT_ASSERT_THROW(aMedRdFieldDriver22->read(), MEDEXCEPTION); + + //Test read() method + aMedRdFieldDriver22->setFieldName(fieldname); + try + { + aMedRdFieldDriver22->read(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test write() method for READ ONLY driver + CPPUNIT_ASSERT_THROW(aMedRdFieldDriver22->write(), MEDEXCEPTION); + + //Test close() method + try + { + aMedRdFieldDriver22->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_FIELD_RDONLY_DRIVER22<int> aMedRdFieldDriver22Cpy_1; + + //Test (void operator =) defined in GENDRIVER class in MEDMEM_GenDriver.hxx + aMedRdFieldDriver22Cpy_1 = *aMedRdFieldDriver22; + + //Test (bool operator ==) defined GENDRIVER class in MEDMEM_GenDriver.hxx + CPPUNIT_ASSERT(aMedRdFieldDriver22Cpy_1 == *aMedRdFieldDriver22); + + //Test copy constructorg + MED_FIELD_RDONLY_DRIVER22<int> aMedRdFieldDriver22Cpy_2 (*aMedRdFieldDriver22); + CPPUNIT_ASSERT_EQUAL(aMedRdFieldDriver22Cpy_2, *aMedRdFieldDriver22); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream rostr1, rostr2; + rostr1<<aMedRdFieldDriver22Cpy_1; + rostr2<<aMedRdFieldDriver22Cpy_2; + CPPUNIT_ASSERT(rostr1.str() != ""); + CPPUNIT_ASSERT(rostr1.str() == rostr2.str()); + + + //--------------------------Test WRITE ONLY part------------------------------// + + //Copy file + system(cp_other_file.c_str()); + system(cp_file_wr.c_str()); + + ///////////////////////////////////// + // TEST1: Open not existing file // + ///////////////////////////////////// + + //Creation Invalid Write Only MedFieldDriver22 (file not exist) + MED_FIELD_WRONLY_DRIVER22<int> *aInvalidMedWrFieldDriver22_1 = + new MED_FIELD_WRONLY_DRIVER22<int>(fileNotExist_wr, aField_1); + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver22_1->open(), MEDEXCEPTION); + + ///////////////////////////////////////////// + // TEST2: Open file with empty file name // + ///////////////////////////////////////////// + //Creation Invalid Write Only MedFieldDriver22 (empty file name) + MED_FIELD_WRONLY_DRIVER22<int> *aInvalidMedWrFieldDriver22_2 = + new MED_FIELD_WRONLY_DRIVER22<int>(emptyfilename, aField_1); + //Trying open not existing file and file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver22_2->open(), MEDEXCEPTION); + + /////////////////////////////////////////////////////// + // TEST3: Writing field in empty file without mesh // + /////////////////////////////////////////////////////// + //Creation Invalid Write Only MedFieldDriver22 + MED_FIELD_WRONLY_DRIVER22<int> *aInvalidMedWrFieldDriver22_3 = + new MED_FIELD_WRONLY_DRIVER22<int>(emptyfile_wr, aField); + + aInvalidMedWrFieldDriver22_3->open(); + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver22_3->write(), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aInvalidMedWrFieldDriver22_3->write()); + //(Bug) No Exception in this case + aInvalidMedWrFieldDriver22_3->close(); + //#endif + + ////////////////////////////////////////////// + // TEST4: Writing field in the other file // + ////////////////////////////////////////////// + + //Creation Invalid Write Only MedFieldDriver22 + MED_FIELD_WRONLY_DRIVER22<int> *aInvalidMedWrFieldDriver22_4 = + new MED_FIELD_WRONLY_DRIVER22<int>(other_file_wr, aField); + aInvalidMedWrFieldDriver22_4->open(); + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_ASSERT_THROW(aInvalidMedWrFieldDriver22_4->write(), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aInvalidMedWrFieldDriver22_4->write()); + //(Bug) No Exception in this case + //#endif + + //////////////////////// + // TEST5: Main test // + //////////////////////// + + //Creation correct Write Only MedFieldDriver22 + MED_FIELD_WRONLY_DRIVER22<int> *aMedWrFieldDriver22 = + new MED_FIELD_WRONLY_DRIVER22<int>(filename_wr, aField); + + //Check driver + CPPUNIT_ASSERT(aMedWrFieldDriver22); + + //Trying write field before open file + //#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedWrFieldDriver22->write(),MEDEXCEPTION); + // (BUG) No exception in this case + //#endif + + //Test open() method + try + { + aMedWrFieldDriver22->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //#ifdef ENABLE_FORCED_FAILURES + //Trying open file secondary. + //CPPUNIT_ASSERT_THROW(aMedWrFieldDriver22->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aMedWrFieldDriver22->open()); + // (BUG) No exception in this case + //#endif + + //Test setFieldName() and getFieldName + aField->setName(fieldname_cpy); + try + { + aMedWrFieldDriver22->setFieldName(fieldname_cpy); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT_EQUAL(fieldname_cpy, aMedWrFieldDriver22->getFieldName()); + + //Test write() method + try + { + aMedWrFieldDriver22->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test read() method for Write only part + CPPUNIT_ASSERT_THROW(aMedWrFieldDriver22->read(),MEDEXCEPTION); + + //Test close() method + try + { + aMedWrFieldDriver22->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_FIELD_WRONLY_DRIVER22<int> aMedWrFieldDriver22Cpy_1; + + //Test (void operator =) defined in GENDRIVER class + aMedWrFieldDriver22Cpy_1 = *aMedWrFieldDriver22; + + //Test (bool operator ==) defined in GENDRIVER class + CPPUNIT_ASSERT(aMedWrFieldDriver22Cpy_1.GENDRIVER::operator==(*aMedWrFieldDriver22)); + + //Test copy constructor + MED_FIELD_WRONLY_DRIVER22<int> aMedWrFieldDriver22Cpy_2 (*aMedWrFieldDriver22); + CPPUNIT_ASSERT_EQUAL(aMedWrFieldDriver22Cpy_2, *aMedWrFieldDriver22); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream wostr1, wostr2; + wostr1 << aMedWrFieldDriver22Cpy_1; + wostr2 << aMedWrFieldDriver22Cpy_2; + CPPUNIT_ASSERT(wostr1.str() != ""); + CPPUNIT_ASSERT(wostr1.str() == wostr2.str()); + + + //--------------------------Test READ/WRITE part------------------------------// + + //Copy files + system(cp_file_rdwr.c_str()); + ///////////////////////////////////// + // TEST1: Open not existing file // + ///////////////////////////////////// + + //Creation Invalid Read/Write MedFieldDriver22 (file not exist) + MED_FIELD_RDWR_DRIVER22<int> *aInvalidMedRdWrFieldDriver22_1 = + new MED_FIELD_RDWR_DRIVER22<int>(fileNotExist_wr, aField_1); + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver22_1->open(), MEDEXCEPTION); + + ///////////////////////////////////////////// + // TEST2: Open file with empty file name // + ///////////////////////////////////////////// + //Creation Invalid Read/Write MedFieldDriver22 (empty file name) + MED_FIELD_RDWR_DRIVER22<int> *aInvalidMedRdWrFieldDriver22_2 = + new MED_FIELD_RDWR_DRIVER22<int>(emptyfilename, aField_1); + //Trying open not existing file and file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver22_2->open(), MEDEXCEPTION); + + ///////////////////////////////////////////////////// + // TEST3: Reading field from file without fields // + ///////////////////////////////////////////////////// + MED_FIELD_RDWR_DRIVER22<int> *aInvalidMedRdWrFieldDriver22_3 = + new MED_FIELD_RDWR_DRIVER22<int>(filenameWithOutFileds, aField_1); + aInvalidMedRdWrFieldDriver22_3->open(); + aInvalidMedRdWrFieldDriver22_3->setFieldName(fieldname); + //Trying read field from file + CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver22_3->read(), MEDEXCEPTION); + aInvalidMedRdWrFieldDriver22_3->close(); + + /////////////////////////////////////////////////////// + // TEST4: Writing field in empty file without mesh // + /////////////////////////////////////////////////////// + + //Creation Invalid Read/Write MedFieldDriver22 + MED_FIELD_RDWR_DRIVER22<int> *aInvalidMedRdWrFieldDriver22_4 = + new MED_FIELD_RDWR_DRIVER22<int>(emptyfile_rdwr, aField); + + aInvalidMedRdWrFieldDriver22_4->open(); + //#ifdef ENABLE_FORCED_FAILURES + // CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver22_4->write(), MEDEXCEPTION); + // (BUG) No exception in this case + //#endif + + ////////////////////////////////////////////// + // TEST6: Writing field in the other file // + ////////////////////////////////////////////// + + //Creation Invalid Read/Write MedFieldDriver22 + MED_FIELD_RDWR_DRIVER22<int> *aInvalidMedRdWrFieldDriver22_5 = + new MED_FIELD_RDWR_DRIVER22<int>(other_file_wr, aField); + aInvalidMedRdWrFieldDriver22_5->open(); + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_ASSERT_THROW(aInvalidMedRdWrFieldDriver22_5->write(), MEDEXCEPTION); + // (BUG) No exception in this case + //#endif + + //////////////////////// + // TEST7: Main test // + //////////////////////// + + //Creation correct Read/Write MedFieldDriver22 + MED_FIELD_RDWR_DRIVER22<double> *aMedRdWrFieldDriver22 = + new MED_FIELD_RDWR_DRIVER22<double>(filename_rdwr, aField_2); + + //Check driver + CPPUNIT_ASSERT(aMedRdWrFieldDriver22); + + //Trying read/write field before open file + CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver22->read(),MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver22->write(),MEDEXCEPTION); + + //Test open() method + try + { + aMedRdWrFieldDriver22->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //#ifdef ENABLE_FORCED_FAILURES + //Trying open file secondary. + //CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver22->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aMedRdWrFieldDriver22->open()); + // (BUG) No exception in this case + //#endif + + //Trying read field from file if field name is empty + CPPUNIT_ASSERT_THROW(aMedRdFieldDriver22->read(), MEDEXCEPTION); + + //Test setFieldName() and getFieldName + try + { + aMedRdWrFieldDriver22->setFieldName(fileldnotexist); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT_EQUAL(fileldnotexist, aMedRdWrFieldDriver22->getFieldName()); + + //Trying read not existing field from file + CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver22->read(), MEDEXCEPTION); + + //Test read() method + aMedRdWrFieldDriver22->setFieldName(fieldnameDouble); + try + { + aMedRdWrFieldDriver22->read(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying write field in the file with empty name + aField_2->setName(emptyfilename); + aMedRdWrFieldDriver22->setFieldName(emptyfilename); + CPPUNIT_ASSERT_THROW(aMedRdWrFieldDriver22->write(), MEDEXCEPTION); + + //Test write() method + aField_2->setName(fieldnameDouble_cpy); + aMedRdWrFieldDriver22->setFieldName(fieldnameDouble_cpy); + try + { + aMedRdWrFieldDriver22->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test close() method + try + { + aMedRdWrFieldDriver22->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_FIELD_RDWR_DRIVER22<double> aMedRdWrFieldDriver22Cpy_1; + + //Test (void operator =) defined in GENDRIVER class + aMedRdWrFieldDriver22Cpy_1 = *aMedRdWrFieldDriver22; + + //Test (bool operator ==) defined in GENDRIVER class + CPPUNIT_ASSERT(aMedRdWrFieldDriver22Cpy_1.GENDRIVER::operator==(*aMedRdWrFieldDriver22)); + + //Test copy constructor + MED_FIELD_RDWR_DRIVER22<double> aMedRdWrFieldDriver22Cpy_2 (*aMedRdWrFieldDriver22); + CPPUNIT_ASSERT_EQUAL(aMedRdWrFieldDriver22Cpy_2, *aMedRdWrFieldDriver22); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream rwostr1, rwostr2; + rwostr1 << aMedRdWrFieldDriver22Cpy_1; + rwostr2 << aMedRdWrFieldDriver22Cpy_2; + CPPUNIT_ASSERT(rwostr1.str() != ""); + CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + //Delete all objects + delete aField; + delete aField_1; + delete aField_2; + + delete aInvalidMedRdFieldDriver22_1; + delete aInvalidMedRdFieldDriver22_2; + delete aInvalidMedRdFieldDriver22_3; + delete aMedRdFieldDriver22; + + delete aInvalidMedWrFieldDriver22_1; + delete aInvalidMedWrFieldDriver22_2; + delete aInvalidMedWrFieldDriver22_3; + delete aInvalidMedWrFieldDriver22_4; + delete aMedWrFieldDriver22; + + delete aInvalidMedRdWrFieldDriver22_1; + delete aInvalidMedRdWrFieldDriver22_2; + delete aInvalidMedRdWrFieldDriver22_3; + delete aInvalidMedRdWrFieldDriver22_4; + delete aInvalidMedRdWrFieldDriver22_5; + delete aMedRdWrFieldDriver22; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_MedMedDriver21.cxx b/src/MEDMEMCppTest/MEDMEMTest_MedMedDriver21.cxx new file mode 100644 index 000000000..dca27767a --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_MedMedDriver21.cxx @@ -0,0 +1,537 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include <MEDMEM_Compatibility21_22.hxx> +#include <MEDMEM_MedMedDriver21.hxx> +#include <MEDMEM_Med.hxx> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +/*! + * Check methods (21), defined in MEDMEM_MedMedDriver21.hxx: + * class MED_MED_DRIVER21 : public virtual MED_MED_DRIVER { + * (+) MED_MED_DRIVER21(); + * (+) MED_MED_DRIVER21(const string & fileName, MED * const ptrMed); + * (+) MED_MED_DRIVER21(const string & fileName, MED * const ptrMed, + * MED_EN::med_mode_acces accessMode); + * (+) MED_MED_DRIVER21(const MED_MED_DRIVER21 & driver); + * (+) virtual ~MED_MED_DRIVER21(); + * (+) void open() throw (MEDEXCEPTION); + * (+) void close(); + * (+) virtual void write (void) const; + * (+) virtual void writeFrom (void) const; + * (+) virtual void read (void); + * (+) virtual void readFileStruct (void); + * } + * class MED_MED_RDONLY_DRIVER21 : public virtual IMED_MED_RDONLY_DRIVER, + * public virtual MED_MED_DRIVER21 { + * (+) MED_MED_RDONLY_DRIVER21(); + * (+) MED_MED_RDONLY_DRIVER21(const string & fileName, MED * const ptrMed); + * (+) MED_MED_RDONLY_DRIVER21(const MED_MED_RDONLY_DRIVER21 & driver); + * (+) virtual ~MED_MED_RDONLY_DRIVER21(); + * (+) void write (void) const throw (MEDEXCEPTION); + * (+) void writeFrom (void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void readFileStruct (void) throw (MEDEXCEPTION); + * } + * class MED_MED_WRONLY_DRIVER21 : public virtual IMED_MED_WRONLY_DRIVER, + * public virtual MED_MED_DRIVER21 { + * (+) MED_MED_WRONLY_DRIVER21(); + * (+) MED_MED_WRONLY_DRIVER21(const string & fileName, MED * const ptrMed); + * (+) MED_MED_WRONLY_DRIVER21(const MED_MED_WRONLY_DRIVER21 & driver); + * (+) virtual ~MED_MED_WRONLY_DRIVER21(); + * (+) void write (void) const throw (MEDEXCEPTION); + * (+) void writeFrom (void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void readFileStruct (void) throw (MEDEXCEPTION); + * } + * class MED_MED_RDWR_DRIVER21 : public MED_MED_RDONLY_DRIVER21, + * public MED_MED_WRONLY_DRIVER21, + * public IMED_MED_RDWR_DRIVER { + * (+) MED_MED_RDWR_DRIVER21(); + * (+) MED_MED_RDWR_DRIVER21(const string & fileName, MED * const ptrMed); + * (+) MED_MED_RDWR_DRIVER21(const MED_MED_RDWR_DRIVER21 & driver); + * (+) ~MED_MED_RDWR_DRIVER21(); + * (+) void write (void) const throw (MEDEXCEPTION); + * (+) void writeFrom (void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void readFileStruct (void) throw (MEDEXCEPTION); + * } + */ +void MEDMEMTest::testMedMedDriver21() { + MED *aMed = new MED(); + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if(tmp_dir == "") + tmp_dir = "/tmp"; + + string filename_rd = data_dir + "/share/salome/resources/med/pointe.med"; + string emptyfilename = ""; + string filename_wr = tmp_dir + "/myMedWr_pointe21.med"; + string fileNotExistsName_rd = "notExists.med"; + string fileNotExistsName_wr = "/path_not_exists/file_not_exists.med"; + string filename_rdwr = tmp_dir + "/myMedRdWr_pointe21.med"; + string fcopy = "cp " + filename_rd + " " + filename_rdwr; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filename_wr); + aRemover.Register(filename_rdwr); + + //Copy file in the TMP dir for testing READ/WRITE case + system(fcopy.data()); + + //-------------------------------Test READ_ONLY part------------------------------------------------------- + //Creation incorrect Med_Med read only driver (file is not exist) + MED_MED_RDONLY_DRIVER21 *aInvalidMedMedRdDriver21 = new MED_MED_RDONLY_DRIVER21(fileNotExistsName_rd, aMed); + + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedMedRdDriver21->open(),MEDEXCEPTION); + + //Creation incorrect Med_Med read only driver (with empty file name) + MED_MED_RDONLY_DRIVER21 *aInvalidMedMedRdDriver21_1 = new MED_MED_RDONLY_DRIVER21(emptyfilename, aMed); + + //Trying open file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedMedRdDriver21_1->open(),MEDEXCEPTION); + + + //Creation a correct Med_Med read only driver (normal constructor) + MED_MED_RDONLY_DRIVER21 *aMedMedRdDriver21 = new MED_MED_RDONLY_DRIVER21(filename_rd, aMed); + + //Check driver + CPPUNIT_ASSERT(aMedMedRdDriver21); + + //Trying read mesh from file, if file is not open + // !!!!!!!! Med driver does NOT NEED open() before read() but only before readFileStruct() !!!! + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->read(), MEDEXCEPTION); + //CPPUNIT_ASSERT_NO_THROW(aMedMedRdDriver21->read()); + // (BUG) No exception in this case. + // so here everything is read + //#endif + + CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->readFileStruct(),MEDEXCEPTION); + + //Test open() method + try + { + aMedMedRdDriver21->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying open() file twice + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->open(),MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aMedMedRdDriver21->open()); + //(BUG) No exception in this case. + //#endif + + //Test read() method + try + { + aMedMedRdDriver21->read(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test read() method + try + { + aMedMedRdDriver21->readFileStruct(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test write() and WriteFrom() methods for READ_ONLY part + CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->write(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->writeFrom(), MEDEXCEPTION); + + //Check MED + CPPUNIT_ASSERT(aMed); + + //Test close() method + try + { + aMedMedRdDriver21->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_MED_RDONLY_DRIVER21 aMedMedRdDriver21Cpy_1; + + //Test (void operator =) defined in GENDRIVER class + //aMedMedRdDriver21Cpy_1 = *aMedMedRdDriver21; + + //Test copy constructor + //#ifdef ENABLE_FAULTS + MED_MED_RDONLY_DRIVER21 aMedMedRdDriver21Cpy_2 (*aMedMedRdDriver21); + // (BUG) => Segmentation fault, because _concreteMedDrv is NULL + // Process terminating with default action of signal 11 (SIGSEGV) + // Access not within mapped region at address 0x0 + // at 0x34881A7A: MEDMEM::MED_MED_DRIVER::MED_MED_DRIVER(MEDMEM::MED_MED_DRIVER const&) (MEDMEM_MedMedDriver.cxx:56) + // by 0x34A07786: MEDMEM::MED_MED_RDONLY_DRIVER21::MED_MED_RDONLY_DRIVER21(MEDMEM::MED_MED_RDONLY_DRIVER21 const&) (MEDMEM_MedMedDriver21.cxx:179) + // by 0x343A02AD: MEDMEMTest::testMedMedDriver21() (MEDMEMTest_MedMedDriver21.cxx:219) + //#endif + + //CPPUNIT_ASSERT_EQUAL(aMedMedRdDriver21Cpy_2, *aMedMedRdDriver21); + + //Test (bool operator ==) defined in GENDRIVER class in MEDMEM_GenDriver.hxx + //CPPUNIT_ASSERT(aMedMedRdDriver21Cpy_2.GENDRIVER::operator==(*aMedMedRdDriver21)); + + //Test (friend ostream & operator <<) defined GENDRIVER class + //ostringstream rwostr1, rwostr2; + //rwostr1<<aMedMedRdDriver21Cpy_1; + //rwostr2<<aMedMedRdDriver21Cpy_2; + //CPPUNIT_ASSERT(rwostr1.str() != ""); + //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + //-------------------------------Test WRITE_ONLY part------------------------------------------------------- + //Creation incorrect Med_Med write only driver (file is not exist) + MED_MED_WRONLY_DRIVER21 *aInvalidMedMedWrDriver21 = new MED_MED_WRONLY_DRIVER21(fileNotExistsName_wr, aMed); + + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedMedWrDriver21->open(),MEDEXCEPTION); + + //Creation incorrect Med_Med write only driver (with empty file name) + MED_MED_WRONLY_DRIVER21 *aInvalidMedMedWrDriver21_1 = new MED_MED_WRONLY_DRIVER21(emptyfilename, aMed); + + //Trying open file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedMedWrDriver21_1->open(),MEDEXCEPTION); + + + //Creation a correct Med_Med write only driver (normal constructor) + MED_MED_WRONLY_DRIVER21 *aMedMedWrDriver21 = new MED_MED_WRONLY_DRIVER21(filename_wr, aMed); + + //Check driver + CPPUNIT_ASSERT(aMedMedWrDriver21); + + + //Trying write mesh to file, if file is not open + // !!!!!!!! Med driver does NOT NEED open() before neither writeFrom() nor before write() !!!! + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_ASSERT_THROW(aMedMedWrDriver21->writeFrom(),MEDEXCEPTION); + // (BUG) No exception in this case + //#endif + + //#ifdef ENABLE_FAULTS + //CPPUNIT_ASSERT_THROW(aMedMedWrDriver21->write(), MEDEXCEPTION); + //(BUG) => Segmentation fault + //#endif + + //Test open() method + try + { + // (not necessary) + aMedMedWrDriver21->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying open() file twice + //#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_NO_THROW(aMedMedWrDriver21->open()); + //(BUG) No exception in this case. + //#endif + + //Test writeFrom() method + try + { + aMedMedWrDriver21->writeFrom(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //#ifdef ENABLE_FAULTS + //Test write() method + try + { + aMedMedWrDriver21->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + // (BUG) => terminate called after throwing an instance of 'std::length_error' + // what(): basic_string::_S_create + //#endif + + //Test close method + try + { + aMedMedWrDriver21->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_MED_WRONLY_DRIVER21 aMedMedWrDriver21Cpy_1; + + //Test (void operator =) defined in GENDRIVER class + //aMedMedWrDriver21Cpy_1 = *aMedMedWrDriver21; + + //Test copy constructor + //#ifdef ENABLE_FAULTS + MED_MED_WRONLY_DRIVER21 aMedMedWrDriver21Cpy_2 (*aMedMedWrDriver21); + // (BUG) => Segmentation fault + //#endif + //CPPUNIT_ASSERT_EQUAL(aMedMedWrDriver21Cpy_2, *aMedMedWrDriver21); + + //Test (bool operator ==) defined in GENDRIVER class + //CPPUNIT_ASSERT(aMedMedWrDriver21Cpy_2.GENDRIVER::operator==(*aMedMedWrDriver21)); + + //Test (friend ostream & operator <<) defined GENDRIVER class + //ostringstream rwostr1, rwostr2; + //rwostr1<<aMedMedWrDriver21Cpy_1; + //rwostr2<<aMedMedWrDriver21Cpy_2; + //CPPUNIT_ASSERT(rwostr1.str() != ""); + //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + +//-------------------------------Test READ/WRITE part------------------------------------------------------- + //Creation incorrect Med_Med read/write driver (file is not exist) + MED_MED_RDWR_DRIVER21 *aInvalidMedMedRdWrDriver21 = new MED_MED_RDWR_DRIVER21(fileNotExistsName_wr, aMed); + + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedMedRdWrDriver21->open(),MEDEXCEPTION); + + //Creation incorrect Med_Med read/write driver (with empty file name) + MED_MED_RDWR_DRIVER21 *aInvalidMedMedRdWrDriver21_1 = new MED_MED_RDWR_DRIVER21(emptyfilename, aMed); + + //Trying open file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedMedRdWrDriver21_1->open(),MEDEXCEPTION); + + + //Creation a correct Med_Med read/write driver (normal constructor) + MED_MED_RDWR_DRIVER21 *aMedMedRdWrDriver21 = new MED_MED_RDWR_DRIVER21(filename_rdwr, aMed); + + //Check driver + CPPUNIT_ASSERT(aMedMedRdWrDriver21); + + //Trying read MED from file if it is not open + // !!!!!!!! Med driver does NOT NEED open() before read() but only before readFileStruct() !!!! + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver21->read(), MEDEXCEPTION); + // (BUG) No exception in this case. + //#endif + + CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver21->readFileStruct(),MEDEXCEPTION); + + //Trying write mesh to file, if file is not open + // !!!!!!!! Med driver does NOT NEED open() before writeFrom() but only before write() !!!! + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver21->writeFrom(),MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aMedMedRdWrDriver21->writeFrom()); + // (BUG) => No exception in this case + //#endif + + //#ifdef ENABLE_FAULTS + // !!!!!!! It does not throught since nothing has been yet read, so no attempts to write + //CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver21->write(),MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aMedMedRdWrDriver21->write()); + //(BUG) => Crash + //#endif + + //Test open() method + try + { + aMedMedRdWrDriver21->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying open() file twice + //!!!! do not make troubles for the user + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver21->open(),MEDEXCEPTION); + //(BUG) No exception in this case. + //#endif + + //Test readFileStruct() method + try + { + aMedMedRdWrDriver21->readFileStruct(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test read() method + try + { + aMedMedRdWrDriver21->read(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test writeFrom() method + try + { + aMedMedRdWrDriver21->writeFrom(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //#ifdef ENABLE_FAULTS + //Test write() method + try + { + aMedMedRdWrDriver21->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + //#endif + + //Test close() method + try + { + aMedMedRdWrDriver21->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_MED_RDWR_DRIVER21 aMedMedRdWrDriver21Cpy_1; + + //Test copy constructor + //#ifdef ENABLE_FAULTS + MED_MED_RDWR_DRIVER21 aMedMedRdWrDriver21Cpy_2 (*aMedMedRdWrDriver21); + // (BUG) => Segmentation fault + //#endif + //CPPUNIT_ASSERT_EQUAL(aMedMedRdWrDriver21Cpy_2, *aMedMedRdWrDriver21); + + //Test (bool operator ==) defined in GENDRIVER class + //CPPUNIT_ASSERT(aMedMedRdWrDriver21Cpy_2.GENDRIVER::operator==(*aMedMedRdWrDriver21)); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + //ostringstream rwostr1, rwostr2; + //rwostr1<<aMedMedRdWrDriver21Cpy_1; + //rwostr2<<aMedMedRdWrDriver21Cpy_2; + //CPPUNIT_ASSERT(rwostr1.str() != ""); + //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + //Delete all objects + delete aMed; + delete aInvalidMedMedRdDriver21; + delete aInvalidMedMedRdDriver21_1; + delete aMedMedRdDriver21; + + delete aInvalidMedMedWrDriver21; + delete aInvalidMedMedWrDriver21_1; + delete aMedMedWrDriver21; + + delete aInvalidMedMedRdWrDriver21; + delete aInvalidMedMedRdWrDriver21_1; + delete aMedMedRdWrDriver21; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_MedMedDriver21_fault.cxx b/src/MEDMEMCppTest/MEDMEMTest_MedMedDriver21_fault.cxx new file mode 100644 index 000000000..151ff85a2 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_MedMedDriver21_fault.cxx @@ -0,0 +1,530 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include <MEDMEM_Compatibility21_22.hxx> +#include <MEDMEM_MedMedDriver21.hxx> +#include <MEDMEM_Med.hxx> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +/*! + * Check methods (21), defined in MEDMEM_MedMedDriver21.hxx: + * class MED_MED_DRIVER21 : public virtual MED_MED_DRIVER { + * (+) MED_MED_DRIVER21(); + * (+) MED_MED_DRIVER21(const string & fileName, MED * const ptrMed); + * (+) MED_MED_DRIVER21(const string & fileName, MED * const ptrMed, + * MED_EN::med_mode_acces accessMode); + * (+) MED_MED_DRIVER21(const MED_MED_DRIVER21 & driver); + * (+) virtual ~MED_MED_DRIVER21(); + * (+) void open() throw (MEDEXCEPTION); + * (+) void close(); + * (+) virtual void write (void) const; + * (+) virtual void writeFrom (void) const; + * (+) virtual void read (void); + * (+) virtual void readFileStruct (void); + * } + * class MED_MED_RDONLY_DRIVER21 : public virtual IMED_MED_RDONLY_DRIVER, + * public virtual MED_MED_DRIVER21 { + * (+) MED_MED_RDONLY_DRIVER21(); + * (+) MED_MED_RDONLY_DRIVER21(const string & fileName, MED * const ptrMed); + * (+) MED_MED_RDONLY_DRIVER21(const MED_MED_RDONLY_DRIVER21 & driver); + * (+) virtual ~MED_MED_RDONLY_DRIVER21(); + * (+) void write (void) const throw (MEDEXCEPTION); + * (+) void writeFrom (void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void readFileStruct (void) throw (MEDEXCEPTION); + * } + * class MED_MED_WRONLY_DRIVER21 : public virtual IMED_MED_WRONLY_DRIVER, + * public virtual MED_MED_DRIVER21 { + * (+) MED_MED_WRONLY_DRIVER21(); + * (+) MED_MED_WRONLY_DRIVER21(const string & fileName, MED * const ptrMed); + * (+) MED_MED_WRONLY_DRIVER21(const MED_MED_WRONLY_DRIVER21 & driver); + * (+) virtual ~MED_MED_WRONLY_DRIVER21(); + * (+) void write (void) const throw (MEDEXCEPTION); + * (+) void writeFrom (void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void readFileStruct (void) throw (MEDEXCEPTION); + * } + * class MED_MED_RDWR_DRIVER21 : public MED_MED_RDONLY_DRIVER21, + * public MED_MED_WRONLY_DRIVER21, + * public IMED_MED_RDWR_DRIVER { + * (+) MED_MED_RDWR_DRIVER21(); + * (+) MED_MED_RDWR_DRIVER21(const string & fileName, MED * const ptrMed); + * (+) MED_MED_RDWR_DRIVER21(const MED_MED_RDWR_DRIVER21 & driver); + * (+) ~MED_MED_RDWR_DRIVER21(); + * (+) void write (void) const throw (MEDEXCEPTION); + * (+) void writeFrom (void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void readFileStruct (void) throw (MEDEXCEPTION); + * } + */ +void MEDMEMTest_testMedMedDriver21() { + MED *aMed = new MED(); + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if(tmp_dir == "") + tmp_dir = "/tmp"; + + string filename_rd = data_dir + "/share/salome/resources/med/pointe.med"; + string emptyfilename = ""; + string filename_wr = tmp_dir + "/myMedWr_pointe21.med"; + string fileNotExistsName_rd = "notExists.med"; + string fileNotExistsName_wr = "/path_not_exists/file_not_exists.med"; + string filename_rdwr = tmp_dir + "/myMedRdWr_pointe21.med"; + string fcopy = "cp " + filename_rd + " " + filename_rdwr; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filename_wr); + aRemover.Register(filename_rdwr); + + //Copy file in the TMP dir for testing READ/WRITE case + system(fcopy.data()); + + //-------------------------------Test READ_ONLY part------------------------------------------------------- + //Creation incorrect Med_Med read only driver (file is not exist) + MED_MED_RDONLY_DRIVER21 *aInvalidMedMedRdDriver21 = new MED_MED_RDONLY_DRIVER21(fileNotExistsName_rd, aMed); + + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedMedRdDriver21->open(),MEDEXCEPTION); + + //Creation incorrect Med_Med read only driver (with empty file name) + MED_MED_RDONLY_DRIVER21 *aInvalidMedMedRdDriver21_1 = new MED_MED_RDONLY_DRIVER21(emptyfilename, aMed); + + //Trying open file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedMedRdDriver21_1->open(),MEDEXCEPTION); + + + //Creation a correct Med_Med read only driver (normal constructor) + MED_MED_RDONLY_DRIVER21 *aMedMedRdDriver21 = new MED_MED_RDONLY_DRIVER21(filename_rd, aMed); + + //Check driver + CPPUNIT_ASSERT(aMedMedRdDriver21); + + //Trying read mesh from file, if file is not open +//#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->read(), MEDEXCEPTION); + // (BUG) No exception in this case. +//#endif + + CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->readFileStruct(),MEDEXCEPTION); + + //Test open() method + try + { + aMedMedRdDriver21->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying open() file twice +//#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->open(),MEDEXCEPTION); + //(BUG) No exception in this case. +//#endif + + //Test read() method + try + { + aMedMedRdDriver21->read(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test read() method + try + { + aMedMedRdDriver21->readFileStruct(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test write() and WriteFrom() methods for READ_ONLY part + CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->write(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->writeFrom(), MEDEXCEPTION); + + //Check MED + CPPUNIT_ASSERT(aMed); + + //Test close() method + try + { + aMedMedRdDriver21->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_MED_RDONLY_DRIVER21 aMedMedRdDriver21Cpy_1; + + //Test (void operator =) defined in GENDRIVER class + //aMedMedRdDriver21Cpy_1 = *aMedMedRdDriver21; + + //Test copy constructor +//#ifdef ENABLE_FAULTS + MED_MED_RDONLY_DRIVER21 aMedMedRdDriver21Cpy_2 (*aMedMedRdDriver21); + // (BUG) => Segmentation fault, because _concreteMedDrv is NULL + // Process terminating with default action of signal 11 (SIGSEGV) + // Access not within mapped region at address 0x0 + // at 0x34881A7A: MEDMEM::MED_MED_DRIVER::MED_MED_DRIVER(MEDMEM::MED_MED_DRIVER const&) (MEDMEM_MedMedDriver.cxx:56) + // by 0x34A07786: MEDMEM::MED_MED_RDONLY_DRIVER21::MED_MED_RDONLY_DRIVER21(MEDMEM::MED_MED_RDONLY_DRIVER21 const&) (MEDMEM_MedMedDriver21.cxx:179) + // by 0x343A02AD: MEDMEMTest::testMedMedDriver21() (MEDMEMTest_MedMedDriver21.cxx:219) +//#endif + + //CPPUNIT_ASSERT_EQUAL(aMedMedRdDriver21Cpy_2, *aMedMedRdDriver21); + + //Test (bool operator ==) defined in GENDRIVER class in MEDMEM_GenDriver.hxx + //CPPUNIT_ASSERT(aMedMedRdDriver21Cpy_2.GENDRIVER::operator==(*aMedMedRdDriver21)); + + //Test (friend ostream & operator <<) defined GENDRIVER class + //ostringstream rwostr1, rwostr2; + //rwostr1<<aMedMedRdDriver21Cpy_1; + //rwostr2<<aMedMedRdDriver21Cpy_2; + //CPPUNIT_ASSERT(rwostr1.str() != ""); + //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + //-------------------------------Test WRITE_ONLY part------------------------------------------------------- + //Creation incorrect Med_Med write only driver (file is not exist) + MED_MED_WRONLY_DRIVER21 *aInvalidMedMedWrDriver21 = new MED_MED_WRONLY_DRIVER21(fileNotExistsName_wr, aMed); + + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedMedWrDriver21->open(),MEDEXCEPTION); + + //Creation incorrect Med_Med write only driver (with empty file name) + MED_MED_WRONLY_DRIVER21 *aInvalidMedMedWrDriver21_1 = new MED_MED_WRONLY_DRIVER21(emptyfilename, aMed); + + //Trying open file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedMedWrDriver21_1->open(),MEDEXCEPTION); + + + //Creation a correct Med_Med write only driver (normal constructor) + MED_MED_WRONLY_DRIVER21 *aMedMedWrDriver21 = new MED_MED_WRONLY_DRIVER21(filename_wr, aMed); + + //Check driver + CPPUNIT_ASSERT(aMedMedWrDriver21); + + + //Trying write mesh to file, if file is not open +//#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedMedWrDriver21->writeFrom(),MEDEXCEPTION); + // (BUG) No exception in this case +//#endif + +//#ifdef ENABLE_FAULTS + CPPUNIT_ASSERT_THROW(aMedMedWrDriver21->write(), MEDEXCEPTION); + //(BUG) => Segmentation fault +//#endif + + //Test open() method + try + { + aMedMedWrDriver21->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying open() file twice +//#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedMedWrDriver21->open(),MEDEXCEPTION); + //(BUG) No exception in this case. +//#endif + + //Test writeFrom() method + try + { + aMedMedWrDriver21->writeFrom(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + +//#ifdef ENABLE_FAULTS + //Test write() method + try + { + aMedMedWrDriver21->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + // (BUG) => terminate called after throwing an instance of 'std::length_error' + // what(): basic_string::_S_create +//#endif + + //Test close method + try + { + aMedMedWrDriver21->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_MED_WRONLY_DRIVER21 aMedMedWrDriver21Cpy_1; + + //Test (void operator =) defined in GENDRIVER class + //aMedMedWrDriver21Cpy_1 = *aMedMedWrDriver21; + + //Test copy constructor +//#ifdef ENABLE_FAULTS + MED_MED_WRONLY_DRIVER21 aMedMedWrDriver21Cpy_2 (*aMedMedWrDriver21); + // (BUG) => Segmentation fault +//#endif + //CPPUNIT_ASSERT_EQUAL(aMedMedWrDriver21Cpy_2, *aMedMedWrDriver21); + + //Test (bool operator ==) defined in GENDRIVER class + //CPPUNIT_ASSERT(aMedMedWrDriver21Cpy_2.GENDRIVER::operator==(*aMedMedWrDriver21)); + + //Test (friend ostream & operator <<) defined GENDRIVER class + //ostringstream rwostr1, rwostr2; + //rwostr1<<aMedMedWrDriver21Cpy_1; + //rwostr2<<aMedMedWrDriver21Cpy_2; + //CPPUNIT_ASSERT(rwostr1.str() != ""); + //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + +//-------------------------------Test READ/WRITE part------------------------------------------------------- + //Creation incorrect Med_Med read/write driver (file is not exist) + MED_MED_RDWR_DRIVER21 *aInvalidMedMedRdWrDriver21 = new MED_MED_RDWR_DRIVER21(fileNotExistsName_wr, aMed); + + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedMedRdWrDriver21->open(),MEDEXCEPTION); + + //Creation incorrect Med_Med read/write driver (with empty file name) + MED_MED_RDWR_DRIVER21 *aInvalidMedMedRdWrDriver21_1 = new MED_MED_RDWR_DRIVER21(emptyfilename, aMed); + + //Trying open file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedMedRdWrDriver21_1->open(),MEDEXCEPTION); + + + //Creation a correct Med_Med read/write driver (normal constructor) + MED_MED_RDWR_DRIVER21 *aMedMedRdWrDriver21 = new MED_MED_RDWR_DRIVER21(filename_rdwr, aMed); + + //Check driver + CPPUNIT_ASSERT(aMedMedRdWrDriver21); + + //Trying read MED from file if it is not open +//#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->read(), MEDEXCEPTION); + // (BUG) No exception in this case. +//#endif + + CPPUNIT_ASSERT_THROW(aMedMedRdDriver21->readFileStruct(),MEDEXCEPTION); + + //Trying write mesh to file, if file is not open +//#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver21->writeFrom(),MEDEXCEPTION); + // (BUG) => No exception in this case +//#endif + +//#ifdef ENABLE_FAULTS + CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver21->write(), MEDEXCEPTION); + //(BUG) => Crash +//#endif + + //Test open() method + try + { + aMedMedRdWrDriver21->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying open() file twice +//#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver21->open(),MEDEXCEPTION); + //(BUG) No exception in this case. +//#endif + + //Test readFileStruct() method + try + { + aMedMedRdWrDriver21->readFileStruct(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test read() method + try + { + aMedMedRdWrDriver21->read(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test writeFrom() method + try + { + aMedMedRdWrDriver21->writeFrom(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + +//#ifdef ENABLE_FAULTS + //Test write() method + try + { + aMedMedRdWrDriver21->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } +//#endif + + //Test close() method + try + { + aMedMedRdWrDriver21->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_MED_RDWR_DRIVER21 aMedMedRdWrDriver21Cpy_1; + + //Test copy constructor +//#ifdef ENABLE_FAULTS + MED_MED_RDWR_DRIVER21 aMedMedRdWrDriver21Cpy_2 (*aMedMedRdWrDriver21); + // (BUG) => Segmentation fault +//#endif + //CPPUNIT_ASSERT_EQUAL(aMedMedRdWrDriver21Cpy_2, *aMedMedRdWrDriver21); + + //Test (bool operator ==) defined in GENDRIVER class + //CPPUNIT_ASSERT(aMedMedRdWrDriver21Cpy_2.GENDRIVER::operator==(*aMedMedRdWrDriver21)); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + //ostringstream rwostr1, rwostr2; + //rwostr1<<aMedMedRdWrDriver21Cpy_1; + //rwostr2<<aMedMedRdWrDriver21Cpy_2; + //CPPUNIT_ASSERT(rwostr1.str() != ""); + //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + //Delete all objects + delete aMed; + delete aInvalidMedMedRdDriver21; + delete aInvalidMedMedRdDriver21_1; + delete aMedMedRdDriver21; + + delete aInvalidMedMedWrDriver21; + delete aInvalidMedMedWrDriver21_1; + delete aMedMedWrDriver21; + + delete aInvalidMedMedRdWrDriver21; + delete aInvalidMedMedRdWrDriver21_1; + delete aMedMedRdWrDriver21; +} + +int main (int argc, char** argv) +{ + MEDMEMTest_testMedMedDriver21(); +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_MedMedDriver22.cxx b/src/MEDMEMCppTest/MEDMEMTest_MedMedDriver22.cxx new file mode 100644 index 000000000..111d4b0b3 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_MedMedDriver22.cxx @@ -0,0 +1,530 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include <MEDMEM_Compatibility21_22.hxx> +#include <MEDMEM_MedMedDriver22.hxx> +#include <MEDMEM_Med.hxx> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +/*! + * Check methods (21), defined in MEDMEM_MedMedDriver22.hxx: + * class MED_MED_DRIVER22 : public virtual MED_MED_DRIVER { + * (+) MED_MED_DRIVER22(); + * (+) MED_MED_DRIVER22(const string & fileName, MED * const ptrMed); + * (+) MED_MED_DRIVER22(const string & fileName, MED * const ptrMed, + * MED_EN::med_mode_acces accessMode); + * (+) MED_MED_DRIVER22(const MED_MED_DRIVER22 & driver); + * (+) virtual ~MED_MED_DRIVER22(); + * (+) void open() throw (MEDEXCEPTION); + * (+) void close(); + * (+) virtual void write (void) const; + * (+) virtual void writeFrom (void) const; + * (+) virtual void read (void); + * (+) virtual void readFileStruct (void); + * } + * class MED_MED_RDONLY_DRIVER22 : public virtual IMED_MED_RDONLY_DRIVER, + * public virtual MED_MED_DRIVER22 { + * (+) MED_MED_RDONLY_DRIVER22(); + * (+) MED_MED_RDONLY_DRIVER22(const string & fileName, MED * const ptrMed); + * (+) MED_MED_RDONLY_DRIVER22(const MED_MED_RDONLY_DRIVER22 & driver); + * (+) virtual ~MED_MED_RDONLY_DRIVER22(); + * (+) void write (void) const throw (MEDEXCEPTION); + * (+) void writeFrom (void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void readFileStruct (void) throw (MEDEXCEPTION); + * } + * class MED_MED_WRONLY_DRIVER22 : public virtual IMED_MED_WRONLY_DRIVER, + * public virtual MED_MED_DRIVER22 { + * (+) MED_MED_WRONLY_DRIVER22(); + * (+) MED_MED_WRONLY_DRIVER22(const string & fileName, MED * const ptrMed); + * (+) MED_MED_WRONLY_DRIVER22(const MED_MED_WRONLY_DRIVER22 & driver); + * (+) virtual ~MED_MED_WRONLY_DRIVER22(); + * (+) void write (void) const throw (MEDEXCEPTION); + * (+) void writeFrom (void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void readFileStruct (void) throw (MEDEXCEPTION); + * } + * class MED_MED_RDWR_DRIVER22 : public virtual MED_MED_RDONLY_DRIVER22, + * public virtual MED_MED_WRONLY_DRIVER22, + * public virtual IMED_MED_RDWR_DRIVER { + * (+) MED_MED_RDWR_DRIVER22(); + * (+) MED_MED_RDWR_DRIVER22(const string & fileName, MED * const ptrMed); + * (+) MED_MED_RDWR_DRIVER22(const MED_MED_RDWR_DRIVER22 & driver); + * (+) ~MED_MED_RDWR_DRIVER22(); + * (+) void write (void) const throw (MEDEXCEPTION); + * (+) void writeFrom (void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void readFileStruct (void) throw (MEDEXCEPTION); + * } + */ +void MEDMEMTest::testMedMedDriver22() { + MED *aMed = new MED(); + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if(tmp_dir == "") + tmp_dir = "/tmp"; + + string filename_rd = data_dir + "/share/salome/resources/med/pointe_import22.med"; + string emptyfilename = ""; + string filename_wr = tmp_dir + "/myMedWr_pointe22.med"; + string fileNotExistsName_rd = "notExists.med"; + string fileNotExistsName_wr = "/path_not_exists/file_not_exists.med"; + string filename_rdwr = tmp_dir + "/myMedRdWr_pointe22.med"; + string fcopy = "cp " + filename_rd + " " + filename_rdwr; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filename_wr); + aRemover.Register(filename_rdwr); + + //Copy file in the TMP dir for testing READ/WRITE case + system(fcopy.data()); + + //-------------------------------Test READ_ONLY part------------------------------------------------------- + //Creation incorrect Med_Med read only driver (file is not exist) + MED_MED_RDONLY_DRIVER22 *aInvalidMedMedRdDriver22 = new MED_MED_RDONLY_DRIVER22(fileNotExistsName_rd, aMed); + + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedMedRdDriver22->open(),MEDEXCEPTION); + + //Creation incorrect Med_Med read only driver (with empty file name) + MED_MED_RDONLY_DRIVER22 *aInvalidMedMedRdDriver22_1 = new MED_MED_RDONLY_DRIVER22(emptyfilename, aMed); + + //Trying open file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedMedRdDriver22_1->open(),MEDEXCEPTION); + + + //Creation a correct Med_Med read only driver (normal constructor) + MED_MED_RDONLY_DRIVER22 *aMedMedRdDriver22 = new MED_MED_RDONLY_DRIVER22(filename_rd, aMed); + + //Check driver + CPPUNIT_ASSERT(aMedMedRdDriver22); + + //Trying read mesh from file, if file is not open + // !!!!!!!! Med driver does NOT NEED open() before read() but only before readFileStruct() !!!! + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->read(), MEDEXCEPTION); + //CPPUNIT_ASSERT_NO_THROW(aMedMedRdDriver22->read()); + // (BUG) No exception in this case. + //#endif + + CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->readFileStruct(),MEDEXCEPTION); + + //Test open() method + try + { + aMedMedRdDriver22->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying open() file twice + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->open(),MEDEXCEPTION); + // CPPUNIT_ASSERT_NO_THROW(aMedMedRdDriver22->open()); + //(BUG) No exception in this case. + //#endif + + //Test read() method + try + { + aMedMedRdDriver22->read(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test read() method + try + { + aMedMedRdDriver22->readFileStruct(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test write() and WriteFrom() methods for READ_ONLY part + CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->write(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->writeFrom(), MEDEXCEPTION); + + //Check MED + CPPUNIT_ASSERT(aMed); + + //Test close() method + try + { + aMedMedRdDriver22->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_MED_RDONLY_DRIVER22 aMedMedRdDriver22Cpy_1; + + //Test (void operator =) defined in GENDRIVER class + //aMedMedRdDriver22Cpy_1 = *aMedMedRdDriver22; + + //Test copy constructor + //#ifdef ENABLE_FAULTS + MED_MED_RDONLY_DRIVER22 aMedMedRdDriver22Cpy_2 (*aMedMedRdDriver22); + // (BUG) => Segmentation fault, because _concreteMedDrv is NULL + //#endif + //CPPUNIT_ASSERT_EQUAL(aMedMedRdDriver22Cpy_2, *aMedMedRdDriver22); + + //Test (bool operator ==) defined in GENDRIVER class in MEDMEM_GenDriver.hxx + //CPPUNIT_ASSERT(aMedMedRdDriver22Cpy_2.GENDRIVER::operator==(*aMedMedRdDriver22)); + + //Test (friend ostream & operator <<) defined GENDRIVER class + //ostringstream rwostr1, rwostr2; + //rwostr1<<aMedMedRdDriver22Cpy_1; + //rwostr2<<aMedMedRdDriver22Cpy_2; + //CPPUNIT_ASSERT(rwostr1.str() != ""); + //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + //-------------------------------Test WRITE_ONLY part------------------------------------------------------- + //Creation incorrect Med_Med write only driver (file is not exist) + MED_MED_WRONLY_DRIVER22 *aInvalidMedMedWrDriver22 = new MED_MED_WRONLY_DRIVER22(fileNotExistsName_wr, aMed); + + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedMedWrDriver22->open(),MEDEXCEPTION); + + //Creation incorrect Med_Med write only driver (with empty file name) + MED_MED_WRONLY_DRIVER22 *aInvalidMedMedWrDriver22_1 = new MED_MED_WRONLY_DRIVER22(emptyfilename, aMed); + + //Trying open file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedMedWrDriver22_1->open(),MEDEXCEPTION); + + + //Creation a correct Med_Med write only driver (normal constructor) + MED_MED_WRONLY_DRIVER22 *aMedMedWrDriver22 = new MED_MED_WRONLY_DRIVER22(filename_wr, aMed); + + //Check driver + CPPUNIT_ASSERT(aMedMedWrDriver22); + + + //Trying write mesh to file, if file is not open + // !!!!!!!! Med driver does NOT NEED open() before writeFrom() and write() !!!! + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_ASSERT_THROW(aMedMedWrDriver22->writeFrom(),MEDEXCEPTION); + // (BUG) No exception in this case + //#endif + + //#ifdef ENABLE_FAULTS + // !!!!!!!! Med driver does NOT NEED open() before writeFrom() and write() !!!! + // CPPUNIT_ASSERT_THROW(aMedMedWrDriver22->write(), MEDEXCEPTION); + //(BUG) => Segmentation fault + //#endif + + //Test open() method + try + { + aMedMedWrDriver22->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying open() file twice + //#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_NO_THROW(aMedMedWrDriver22->open()); + //(BUG) No exception in this case. + //#endif + + //Test writeFrom() method + try + { + aMedMedWrDriver22->writeFrom(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //#ifdef ENABLE_FAULTS + //Test write() method + try + { + aMedMedWrDriver22->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + // (BUG) => terminate called after throwing an instance of 'std::length_error' + // what(): basic_string::_S_create + //#endif + + //Test close method + try + { + aMedMedWrDriver22->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_MED_WRONLY_DRIVER22 aMedMedWrDriver22Cpy_1; + + //Test (void operator =) defined in GENDRIVER class + //aMedMedWrDriver22Cpy_1 = *aMedMedWrDriver22; + + //Test copy constructor + //#ifdef ENABLE_FAULTS + MED_MED_WRONLY_DRIVER22 aMedMedWrDriver22Cpy_2 (*aMedMedWrDriver22); + // (BUG) => Segmentation fault + //#endif + //CPPUNIT_ASSERT_EQUAL(aMedMedWrDriver22Cpy_2, *aMedMedWrDriver22); + + //Test (bool operator ==) defined in GENDRIVER class + //CPPUNIT_ASSERT(aMedMedWrDriver22Cpy_2.GENDRIVER::operator==(*aMedMedWrDriver22)); + + //Test (friend ostream & operator <<) defined GENDRIVER class + //ostringstream rwostr1, rwostr2; + //rwostr1<<aMedMedWrDriver22Cpy_1; + //rwostr2<<aMedMedWrDriver22Cpy_2; + //CPPUNIT_ASSERT(rwostr1.str() != ""); + //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + +//-------------------------------Test READ/WRITE part------------------------------------------------------- + //Creation incorrect Med_Med read/write driver (file is not exist) + MED_MED_RDWR_DRIVER22 *aInvalidMedMedRdWrDriver22 = new MED_MED_RDWR_DRIVER22(fileNotExistsName_wr, aMed); + + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedMedRdWrDriver22->open(),MEDEXCEPTION); + + //Creation incorrect Med_Med read/write driver (with empty file name) + MED_MED_RDWR_DRIVER22 *aInvalidMedMedRdWrDriver22_1 = new MED_MED_RDWR_DRIVER22(emptyfilename, aMed); + + //Trying open file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedMedRdWrDriver22_1->open(),MEDEXCEPTION); + + + //Creation a correct Med_Med read/write driver (normal constructor) + MED_MED_RDWR_DRIVER22 *aMedMedRdWrDriver22 = new MED_MED_RDWR_DRIVER22(filename_rdwr, aMed); + + //Check driver + CPPUNIT_ASSERT(aMedMedRdWrDriver22); + + //Trying read MED from file if it is not open + // !!!!!!!! Med driver does NOT NEED open() before read() but only before readFileStruct() !!!! + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver22->read(), MEDEXCEPTION); + // (BUG) No exception in this case. + //#endif + + CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver22->readFileStruct(),MEDEXCEPTION); + + //Trying write mesh to file, if file is not open + // !!!!!!!! Med driver does NOT NEED open() before writeFrom() but only before write() !!!! + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver22->writeFrom(),MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aMedMedRdWrDriver22->writeFrom()); + // (BUG) => No exception in this case + //#endif + + //#ifdef ENABLE_FAULTS + // !!!!!!! It does not throught since nothing has been yet read, so no attempts to write + //CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver22->write(), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aMedMedRdWrDriver22->write()); + //(BUG) => Crash + //#endif + + //Test open() method + try + { + aMedMedRdWrDriver22->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying open() file twice + //!!!! do not make troubles for the user + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver22->open(),MEDEXCEPTION); + //(BUG) No exception in this case. + //#endif + + //Test readFileStruct() method + try + { + aMedMedRdWrDriver22->readFileStruct(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test read() method + try + { + aMedMedRdWrDriver22->read(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test writeFrom() method + try + { + aMedMedRdWrDriver22->writeFrom(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //#ifdef ENABLE_FAULTS + //Test write() method + try + { + aMedMedRdWrDriver22->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + //#endif + + //Test close() method + try + { + aMedMedRdWrDriver22->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_MED_RDWR_DRIVER22 aMedMedRdWrDriver22Cpy_1; + + //Test copy constructor + //#ifdef ENABLE_FAULTS + MED_MED_RDWR_DRIVER22 aMedMedRdWrDriver22Cpy_2 (*aMedMedRdWrDriver22); + // (BUG) => Segmentation fault + //#endif + //CPPUNIT_ASSERT_EQUAL(aMedMedRdWrDriver22Cpy_2, *aMedMedRdWrDriver22); + + //Test (bool operator ==) defined in GENDRIVER class + //CPPUNIT_ASSERT(aMedMedRdWrDriver22Cpy_2.GENDRIVER::operator==(*aMedMedRdWrDriver22)); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + //ostringstream rwostr1, rwostr2; + //rwostr1<<aMedMedRdWrDriver22Cpy_1; + //rwostr2<<aMedMedRdWrDriver22Cpy_2; + //CPPUNIT_ASSERT(rwostr1.str() != ""); + //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + //Delete all objects + delete aMed; + delete aInvalidMedMedRdDriver22; + delete aInvalidMedMedRdDriver22_1; + delete aMedMedRdDriver22; + + delete aInvalidMedMedWrDriver22; + delete aInvalidMedMedWrDriver22_1; + delete aMedMedWrDriver22; + + delete aInvalidMedMedRdWrDriver22; + delete aInvalidMedMedRdWrDriver22_1; + delete aMedMedRdWrDriver22; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_MedMedDriver22_fault.cxx b/src/MEDMEMCppTest/MEDMEMTest_MedMedDriver22_fault.cxx new file mode 100644 index 000000000..2fa98fe06 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_MedMedDriver22_fault.cxx @@ -0,0 +1,524 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include <MEDMEM_Compatibility21_22.hxx> +#include <MEDMEM_MedMedDriver22.hxx> +#include <MEDMEM_Med.hxx> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +/*! + * Check methods (21), defined in MEDMEM_MedMedDriver22.hxx: + * class MED_MED_DRIVER22 : public virtual MED_MED_DRIVER { + * (+) MED_MED_DRIVER22(); + * (+) MED_MED_DRIVER22(const string & fileName, MED * const ptrMed); + * (+) MED_MED_DRIVER22(const string & fileName, MED * const ptrMed, + * MED_EN::med_mode_acces accessMode); + * (+) MED_MED_DRIVER22(const MED_MED_DRIVER22 & driver); + * (+) virtual ~MED_MED_DRIVER22(); + * (+) void open() throw (MEDEXCEPTION); + * (+) void close(); + * (+) virtual void write (void) const; + * (+) virtual void writeFrom (void) const; + * (+) virtual void read (void); + * (+) virtual void readFileStruct (void); + * } + * class MED_MED_RDONLY_DRIVER22 : public virtual IMED_MED_RDONLY_DRIVER, + * public virtual MED_MED_DRIVER22 { + * (+) MED_MED_RDONLY_DRIVER22(); + * (+) MED_MED_RDONLY_DRIVER22(const string & fileName, MED * const ptrMed); + * (+) MED_MED_RDONLY_DRIVER22(const MED_MED_RDONLY_DRIVER22 & driver); + * (+) virtual ~MED_MED_RDONLY_DRIVER22(); + * (+) void write (void) const throw (MEDEXCEPTION); + * (+) void writeFrom (void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void readFileStruct (void) throw (MEDEXCEPTION); + * } + * class MED_MED_WRONLY_DRIVER22 : public virtual IMED_MED_WRONLY_DRIVER, + * public virtual MED_MED_DRIVER22 { + * (+) MED_MED_WRONLY_DRIVER22(); + * (+) MED_MED_WRONLY_DRIVER22(const string & fileName, MED * const ptrMed); + * (+) MED_MED_WRONLY_DRIVER22(const MED_MED_WRONLY_DRIVER22 & driver); + * (+) virtual ~MED_MED_WRONLY_DRIVER22(); + * (+) void write (void) const throw (MEDEXCEPTION); + * (+) void writeFrom (void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void readFileStruct (void) throw (MEDEXCEPTION); + * } + * class MED_MED_RDWR_DRIVER22 : public virtual MED_MED_RDONLY_DRIVER22, + * public virtual MED_MED_WRONLY_DRIVER22, + * public virtual IMED_MED_RDWR_DRIVER { + * (+) MED_MED_RDWR_DRIVER22(); + * (+) MED_MED_RDWR_DRIVER22(const string & fileName, MED * const ptrMed); + * (+) MED_MED_RDWR_DRIVER22(const MED_MED_RDWR_DRIVER22 & driver); + * (+) ~MED_MED_RDWR_DRIVER22(); + * (+) void write (void) const throw (MEDEXCEPTION); + * (+) void writeFrom (void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void readFileStruct (void) throw (MEDEXCEPTION); + * } + */ +void MEDMEMTest_testMedMedDriver22() { + MED *aMed = new MED(); + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if(tmp_dir == "") + tmp_dir = "/tmp"; + + string filename_rd = data_dir + "/share/salome/resources/med/pointe_import22.med"; + string emptyfilename = ""; + string filename_wr = tmp_dir + "/myMedWr_pointe22.med"; + string fileNotExistsName_rd = "notExists.med"; + string fileNotExistsName_wr = "/path_not_exists/file_not_exists.med"; + string filename_rdwr = tmp_dir + "/myMedRdWr_pointe22.med"; + string fcopy = "cp " + filename_rd + " " + filename_rdwr; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filename_wr); + aRemover.Register(filename_rdwr); + + //Copy file in the TMP dir for testing READ/WRITE case + system(fcopy.data()); + + //-------------------------------Test READ_ONLY part------------------------------------------------------- + //Creation incorrect Med_Med read only driver (file is not exist) + MED_MED_RDONLY_DRIVER22 *aInvalidMedMedRdDriver22 = new MED_MED_RDONLY_DRIVER22(fileNotExistsName_rd, aMed); + + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedMedRdDriver22->open(),MEDEXCEPTION); + + //Creation incorrect Med_Med read only driver (with empty file name) + MED_MED_RDONLY_DRIVER22 *aInvalidMedMedRdDriver22_1 = new MED_MED_RDONLY_DRIVER22(emptyfilename, aMed); + + //Trying open file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedMedRdDriver22_1->open(),MEDEXCEPTION); + + + //Creation a correct Med_Med read only driver (normal constructor) + MED_MED_RDONLY_DRIVER22 *aMedMedRdDriver22 = new MED_MED_RDONLY_DRIVER22(filename_rd, aMed); + + //Check driver + CPPUNIT_ASSERT(aMedMedRdDriver22); + + //Trying read mesh from file, if file is not open +//#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->read(), MEDEXCEPTION); + // (BUG) No exception in this case. +//#endif + + CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->readFileStruct(),MEDEXCEPTION); + + //Test open() method + try + { + aMedMedRdDriver22->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying open() file twice +//#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->open(),MEDEXCEPTION); + //(BUG) No exception in this case. +//#endif + + //Test read() method + try + { + aMedMedRdDriver22->read(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test read() method + try + { + aMedMedRdDriver22->readFileStruct(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test write() and WriteFrom() methods for READ_ONLY part + CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->write(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->writeFrom(), MEDEXCEPTION); + + //Check MED + CPPUNIT_ASSERT(aMed); + + //Test close() method + try + { + aMedMedRdDriver22->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_MED_RDONLY_DRIVER22 aMedMedRdDriver22Cpy_1; + + //Test (void operator =) defined in GENDRIVER class + //aMedMedRdDriver22Cpy_1 = *aMedMedRdDriver22; + + //Test copy constructor +//#ifdef ENABLE_FAULTS + MED_MED_RDONLY_DRIVER22 aMedMedRdDriver22Cpy_2 (*aMedMedRdDriver22); + // (BUG) => Segmentation fault, because _concreteMedDrv is NULL +//#endif + //CPPUNIT_ASSERT_EQUAL(aMedMedRdDriver22Cpy_2, *aMedMedRdDriver22); + + //Test (bool operator ==) defined in GENDRIVER class in MEDMEM_GenDriver.hxx + //CPPUNIT_ASSERT(aMedMedRdDriver22Cpy_2.GENDRIVER::operator==(*aMedMedRdDriver22)); + + //Test (friend ostream & operator <<) defined GENDRIVER class + //ostringstream rwostr1, rwostr2; + //rwostr1<<aMedMedRdDriver22Cpy_1; + //rwostr2<<aMedMedRdDriver22Cpy_2; + //CPPUNIT_ASSERT(rwostr1.str() != ""); + //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + //-------------------------------Test WRITE_ONLY part------------------------------------------------------- + //Creation incorrect Med_Med write only driver (file is not exist) + MED_MED_WRONLY_DRIVER22 *aInvalidMedMedWrDriver22 = new MED_MED_WRONLY_DRIVER22(fileNotExistsName_wr, aMed); + + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedMedWrDriver22->open(),MEDEXCEPTION); + + //Creation incorrect Med_Med write only driver (with empty file name) + MED_MED_WRONLY_DRIVER22 *aInvalidMedMedWrDriver22_1 = new MED_MED_WRONLY_DRIVER22(emptyfilename, aMed); + + //Trying open file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedMedWrDriver22_1->open(),MEDEXCEPTION); + + + //Creation a correct Med_Med write only driver (normal constructor) + MED_MED_WRONLY_DRIVER22 *aMedMedWrDriver22 = new MED_MED_WRONLY_DRIVER22(filename_wr, aMed); + + //Check driver + CPPUNIT_ASSERT(aMedMedWrDriver22); + + + //Trying write mesh to file, if file is not open +//#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedMedWrDriver22->writeFrom(),MEDEXCEPTION); + // (BUG) No exception in this case +//#endif + +//#ifdef ENABLE_FAULTS + CPPUNIT_ASSERT_THROW(aMedMedWrDriver22->write(), MEDEXCEPTION); + //(BUG) => Segmentation fault +//#endif + + //Test open() method + try + { + aMedMedWrDriver22->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying open() file twice +//#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedMedWrDriver22->open(),MEDEXCEPTION); + //(BUG) No exception in this case. +//#endif + + //Test writeFrom() method + try + { + aMedMedWrDriver22->writeFrom(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + +//#ifdef ENABLE_FAULTS + //Test write() method + try + { + aMedMedWrDriver22->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + // (BUG) => terminate called after throwing an instance of 'std::length_error' + // what(): basic_string::_S_create +//#endif + + //Test close method + try + { + aMedMedWrDriver22->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_MED_WRONLY_DRIVER22 aMedMedWrDriver22Cpy_1; + + //Test (void operator =) defined in GENDRIVER class + //aMedMedWrDriver22Cpy_1 = *aMedMedWrDriver22; + + //Test copy constructor +//#ifdef ENABLE_FAULTS + MED_MED_WRONLY_DRIVER22 aMedMedWrDriver22Cpy_2 (*aMedMedWrDriver22); + // (BUG) => Segmentation fault +//#endif + //CPPUNIT_ASSERT_EQUAL(aMedMedWrDriver22Cpy_2, *aMedMedWrDriver22); + + //Test (bool operator ==) defined in GENDRIVER class + //CPPUNIT_ASSERT(aMedMedWrDriver22Cpy_2.GENDRIVER::operator==(*aMedMedWrDriver22)); + + //Test (friend ostream & operator <<) defined GENDRIVER class + //ostringstream rwostr1, rwostr2; + //rwostr1<<aMedMedWrDriver22Cpy_1; + //rwostr2<<aMedMedWrDriver22Cpy_2; + //CPPUNIT_ASSERT(rwostr1.str() != ""); + //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + +//-------------------------------Test READ/WRITE part------------------------------------------------------- + //Creation incorrect Med_Med read/write driver (file is not exist) + MED_MED_RDWR_DRIVER22 *aInvalidMedMedRdWrDriver22 = new MED_MED_RDWR_DRIVER22(fileNotExistsName_wr, aMed); + + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidMedMedRdWrDriver22->open(),MEDEXCEPTION); + + //Creation incorrect Med_Med read/write driver (with empty file name) + MED_MED_RDWR_DRIVER22 *aInvalidMedMedRdWrDriver22_1 = new MED_MED_RDWR_DRIVER22(emptyfilename, aMed); + + //Trying open file with empty name + CPPUNIT_ASSERT_THROW(aInvalidMedMedRdWrDriver22_1->open(),MEDEXCEPTION); + + + //Creation a correct Med_Med read/write driver (normal constructor) + MED_MED_RDWR_DRIVER22 *aMedMedRdWrDriver22 = new MED_MED_RDWR_DRIVER22(filename_rdwr, aMed); + + //Check driver + CPPUNIT_ASSERT(aMedMedRdWrDriver22); + + //Trying read MED from file if it is not open +//#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->read(), MEDEXCEPTION); + // (BUG) No exception in this case. +//#endif + + CPPUNIT_ASSERT_THROW(aMedMedRdDriver22->readFileStruct(),MEDEXCEPTION); + + //Trying write mesh to file, if file is not open +//#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver22->writeFrom(),MEDEXCEPTION); + // (BUG) => No exception in this case +//#endif + +//#ifdef ENABLE_FAULTS + CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver22->write(), MEDEXCEPTION); + //(BUG) => Crash +//#endif + + //Test open() method + try + { + aMedMedRdWrDriver22->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying open() file twice +//#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(aMedMedRdWrDriver22->open(),MEDEXCEPTION); + //(BUG) No exception in this case. +//#endif + + //Test readFileStruct() method + try + { + aMedMedRdWrDriver22->readFileStruct(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test read() method + try + { + aMedMedRdWrDriver22->read(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test writeFrom() method + try + { + aMedMedRdWrDriver22->writeFrom(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + +//#ifdef ENABLE_FAULTS + //Test write() method + try + { + aMedMedRdWrDriver22->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } +//#endif + + //Test close() method + try + { + aMedMedRdWrDriver22->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Default constructor + MED_MED_RDWR_DRIVER22 aMedMedRdWrDriver22Cpy_1; + + //Test copy constructor +//#ifdef ENABLE_FAULTS + MED_MED_RDWR_DRIVER22 aMedMedRdWrDriver22Cpy_2 (*aMedMedRdWrDriver22); + // (BUG) => Segmentation fault +//#endif + //CPPUNIT_ASSERT_EQUAL(aMedMedRdWrDriver22Cpy_2, *aMedMedRdWrDriver22); + + //Test (bool operator ==) defined in GENDRIVER class + //CPPUNIT_ASSERT(aMedMedRdWrDriver22Cpy_2.GENDRIVER::operator==(*aMedMedRdWrDriver22)); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + //ostringstream rwostr1, rwostr2; + //rwostr1<<aMedMedRdWrDriver22Cpy_1; + //rwostr2<<aMedMedRdWrDriver22Cpy_2; + //CPPUNIT_ASSERT(rwostr1.str() != ""); + //CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + //Delete all objects + delete aMed; + delete aInvalidMedMedRdDriver22; + delete aInvalidMedMedRdDriver22_1; + delete aMedMedRdDriver22; + + delete aInvalidMedMedWrDriver22; + delete aInvalidMedMedWrDriver22_1; + delete aMedMedWrDriver22; + + delete aInvalidMedMedRdWrDriver22; + delete aInvalidMedMedRdWrDriver22_1; + delete aMedMedRdWrDriver22; +} + +int main (int argc, char** argv) +{ + MEDMEMTest_testMedMedDriver22(); +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_MedMeshDriver21.cxx b/src/MEDMEMCppTest/MEDMEMTest_MedMeshDriver21.cxx new file mode 100644 index 000000000..ecbe0bdfa --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_MedMeshDriver21.cxx @@ -0,0 +1,539 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include <MEDMEM_MedMeshDriver21.hxx> +#include <MEDMEM_Mesh.hxx> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; + +/*! + * Check methods (13), defined in MEDMEM_MedMeshDriver21.hxx: + * class MED_MESH_DRIVER21 : public virtual MED_MESH_DRIVER { + * (+) MED_MESH_DRIVER21(); + * (+) MED_MESH_DRIVER21(const string & fileName, MESH * ptrMesh, MED_EN::med_mode_acces accessMode); + * (+) MED_MESH_DRIVER21(const MED_MESH_DRIVER21 & driver); + * (+) virtual ~MED_MESH_DRIVER21(); + * (+) void open(); + * (+) void close(); + * } + * class MED_MESH_RDONLY_DRIVER21 : public virtual IMED_MESH_RDONLY_DRIVER, + * public virtual MED_MESH_DRIVER21 { + * (+) MED_MESH_RDONLY_DRIVER21(); + * (+) MED_MESH_RDONLY_DRIVER21(const string & fileName, MESH * ptrMesh); + * (+) MED_MESH_RDONLY_DRIVER21(const MED_MESH_RDONLY_DRIVER21 & driver); + * (+) virtual ~MED_MESH_RDONLY_DRIVER21(); + * (+) void read (void); + * } + * class MED_MESH_WRONLY_DRIVER21 : public virtual IMED_MESH_WRONLY_DRIVER, + * public virtual MED_MESH_DRIVER21 { + * (+) MED_MESH_WRONLY_DRIVER21(); + * (+) MED_MESH_WRONLY_DRIVER21(const string & fileName, MESH * ptrMesh); + * (+) MED_MESH_WRONLY_DRIVER21(const MED_MESH_WRONLY_DRIVER21 & driver); + * (+) virtual ~MED_MESH_WRONLY_DRIVER21(); + * (+) void write(void) const; + * } + * class MED_MESH_RDWR_DRIVER21 : public IMED_MESH_RDWR_DRIVER, + * public MED_MESH_RDONLY_DRIVER21, public MED_MESH_WRONLY_DRIVER21 { + * (+) MED_MESH_RDWR_DRIVER21(); + * (+) MED_MESH_RDWR_DRIVER21(const string & fileName, MESH * ptrMesh); + * (+) MED_MESH_RDWR_DRIVER21(const MED_MESH_RDWR_DRIVER21 & driver); + * (+) ~MED_MESH_RDWR_DRIVER21(); + * (+) void write(void) const; + * (+) void read (void); + * } + */ +void MEDMEMTest::testMedMeshDriver21() +{ + MESH *aMesh = new MESH(); + MESH *aMesh_1 = new MESH(); + + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if (tmp_dir == "") tmp_dir = "/tmp"; + + string filename_rd = data_dir + "/share/salome/resources/med/pointe.med"; + string filename_wr = tmp_dir + "/myWr_pointe21.med"; + string tmpfile = tmp_dir + "/tmp.med"; + string meshname = "maa1"; + string newmeshname = "new" + meshname; + string fileNotExistsName_rd = "notExists.med"; + string fileNotExistsName_wr = "/path_not_exists/file_not_exists.med"; + string filename_rdwr = tmp_dir + "/myRdWr_pointe22.med"; + char* longmeshname = new char[MED_TAILLE_NOM+2]; + string fcopy = "cp " + filename_rd + " " + filename_rdwr; + for (int i = 0; i<MED_TAILLE_NOM+2; ++i) + longmeshname[i] = 'a'; + + //Copy file in the TMP dir for testing READ/WRITE case + system(fcopy.data()); + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filename_wr); + aRemover.Register(filename_rdwr); + aRemover.Register(tmpfile); + + //----------------------------------Test READ ONLY part---------------------------------------------------// + + //Creation a incorrect read only driver + MED_MESH_RDONLY_DRIVER21 *aInvalidRdDriver21 = new MED_MESH_RDONLY_DRIVER21(fileNotExistsName_rd, aMesh); + + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidRdDriver21->open(), MEDEXCEPTION); + + //Creation a correct read only driver (normal constructor) + MED_MESH_RDONLY_DRIVER21 *aRdDriver21 = new MED_MESH_RDONLY_DRIVER21(filename_rd, aMesh); + + //Check driver + CPPUNIT_ASSERT(aRdDriver21); + + //Trying read mesh from file, if file is not open + CPPUNIT_ASSERT_THROW(aRdDriver21->read(), MEDEXCEPTION); + + //Test open() method + try + { + aRdDriver21->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + //#ifdef ENABLE_FORCED_FAILURES + //Trying open file secondary. + //CPPUNIT_ASSERT_THROW(aRdDriver21->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aRdDriver21->open()); + //This case is not work, seems it BUG + + //Trying read mesh from file, if mesh name is not set, i.e. empty + CPPUNIT_ASSERT_THROW(aRdDriver21->read(), MEDEXCEPTION); + //No correct exception in this case + + //Trying read mesh from file with very long name + //aRdDriver21->setMeshName(longmeshname); + CPPUNIT_ASSERT_THROW(aRdDriver21->read(), MEDEXCEPTION); + //No correct exception in this case + //#endif + + //Set correct Mesh name + //Test setMeshName() and getMeshName() methods + try + { + aRdDriver21->setMeshName(meshname); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_EQUAL(meshname, aRdDriver21->getMeshName()); + + + //Test read() method + try + { + aRdDriver21->read(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test write() method for READ ONLY driver + CPPUNIT_ASSERT_THROW(aRdDriver21->write(), MEDEXCEPTION); + + //Check Mesh + CPPUNIT_ASSERT(aMesh); + + //Default constructor + MED_MESH_RDONLY_DRIVER21 aRdDriver21Cpy_1; + + //Test (void operator =) defined in GENDRIVER class in MEDMEM_GenDriver.hxx + //aRdDriver21Cpy_1 = *aRdDriver21; + + //Test (bool operator ==) defined GENDRIVER class in MEDMEM_GenDriver.hxx + CPPUNIT_ASSERT(aRdDriver21Cpy_1.GENDRIVER::operator==(*aRdDriver21)); + + //Test copy constructor + MED_MESH_RDONLY_DRIVER21 aRdDriver21Cpy_2 (aRdDriver21Cpy_1); + CPPUNIT_ASSERT_EQUAL(aRdDriver21Cpy_2, *aRdDriver21); + + //Test close() method + try + { + aRdDriver21->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying read mesh from copy closed driver + CPPUNIT_ASSERT_THROW(aRdDriver21Cpy_1.read(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aRdDriver21Cpy_2.read(), MEDEXCEPTION); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream rostr1, rostr2; + rostr1<<aRdDriver21Cpy_1; + rostr2<<aRdDriver21Cpy_2; + CPPUNIT_ASSERT(rostr1.str() != ""); + CPPUNIT_ASSERT(rostr1.str() == rostr2.str()); + + + //----------------------------------Test WRITE ONLY part------------------------------------------// + + //Creation a incorrect write only driver + MED_MESH_WRONLY_DRIVER21 *aInvalidWrDriver21 = new MED_MESH_WRONLY_DRIVER21(fileNotExistsName_wr, aMesh); + + //Trying open non existing file + CPPUNIT_ASSERT_THROW(aInvalidWrDriver21->open(), MEDEXCEPTION); + + //Trying write empty mesh + MED_MESH_WRONLY_DRIVER21 *aTmpWrDriver21 = new MED_MESH_WRONLY_DRIVER21(tmpfile, aMesh_1); + + //#ifdef ENABLE_FORCED_FAILURES + aTmpWrDriver21->open(); + aTmpWrDriver21->setMeshName("EmptyMesh"); + CPPUNIT_ASSERT_THROW(aTmpWrDriver21->write(),MEDEXCEPTION); + aTmpWrDriver21->close(); + //Unknown exception in this case + //#endif + + //Creation a correct write only driver + MED_MESH_WRONLY_DRIVER21 *aWrDriver21 = new MED_MESH_WRONLY_DRIVER21(filename_wr, aMesh); + + //Check driver + CPPUNIT_ASSERT(aWrDriver21); + + //Trying write mesh to file, if file is not open + CPPUNIT_ASSERT_THROW(aWrDriver21->write(), MEDEXCEPTION); + + //Test open() method + try + { + aWrDriver21->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //#ifdef ENABLE_FORCED_FAILURES + //Trying open file secondary. + //CPPUNIT_ASSERT_THROW(aWrDriver21->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aWrDriver21->open()); + //This case is not work, seems it BUG + //#endif + + //#ifdef ENABLE_FORCED_FAILURES + //Test case: trying write mesh to file, if mesh name is not set, i.e empty + aMesh->setName(""); + aWrDriver21->setMeshName(""); + CPPUNIT_ASSERT_THROW(aWrDriver21->write(), MEDEXCEPTION); + //No exception in this case + + //Trying write mesh to file with very long name + aWrDriver21->setMeshName(longmeshname); + CPPUNIT_ASSERT_THROW(aWrDriver21->write(), MEDEXCEPTION); + //No exception in this case + //#endif + + //Set initialy mesh name + aMesh->setName(meshname); + //Test setMeshName() and getMeshName() methods + try + { + aWrDriver21->setMeshName(meshname); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_EQUAL(meshname, aWrDriver21->getMeshName()); + + //Test write() method + try + { + aWrDriver21->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test read() method for WRITE ONLY driver + CPPUNIT_ASSERT_THROW(aWrDriver21->read(), MEDEXCEPTION); + + //Default constructor + MED_MESH_WRONLY_DRIVER21 aWrDriver21Cpy_1; + + //Test (void operator =) defined in GENDRIVER class + //aWrDriver21Cpy_1 = *aWrDriver21; + + //Test (bool operator ==) defined GENDRIVER class + CPPUNIT_ASSERT(aWrDriver21Cpy_1.GENDRIVER::operator==(*aWrDriver21)); + + //Test copy constructor + MED_MESH_WRONLY_DRIVER21 aWrDriver21Cpy_2 (aWrDriver21Cpy_1); + CPPUNIT_ASSERT_EQUAL(aWrDriver21Cpy_2 , *aWrDriver21); + + try + { + aWrDriver21->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test case: Trying write mesh using copy closed driver + CPPUNIT_ASSERT_THROW(aWrDriver21Cpy_1.write(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aWrDriver21Cpy_2.write(), MEDEXCEPTION); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream wostr1, wostr2; + wostr1<<aWrDriver21Cpy_1; + wostr2<<aWrDriver21Cpy_2; + CPPUNIT_ASSERT(wostr1.str() != ""); + CPPUNIT_ASSERT(wostr1.str() == wostr2.str()); + + + //----------------------------------Test READ / WRITE part------------------------------------------// + + //Creation a incorrect read/write driver + MED_MESH_RDWR_DRIVER21 *aInvalidRdWrDriver21 = new MED_MESH_RDWR_DRIVER21(fileNotExistsName_wr, aMesh_1); + + //Test case: trying open non existing file + CPPUNIT_ASSERT_THROW(aInvalidRdWrDriver21->open(), MEDEXCEPTION); + + //Creation a correct read/write driver + MED_MESH_RDWR_DRIVER21 *aRdWrDriver21 = new MED_MESH_RDWR_DRIVER21(filename_rdwr, aMesh_1); + + //Check driver + CPPUNIT_ASSERT(aRdWrDriver21); + + //Test case: trying write mesh to file, if file is not open + CPPUNIT_ASSERT_THROW(aRdWrDriver21->write(), MEDEXCEPTION); + + //Test case: trying read mesh from file, if file is not open + CPPUNIT_ASSERT_THROW(aRdWrDriver21->read(), MEDEXCEPTION); + + //Test open() method + try + { + aRdWrDriver21->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //#ifdef ENABLE_FORCED_FAILURES + //Test case: trying open file secondary. + CPPUNIT_ASSERT_NO_THROW(aRdWrDriver21->open()); + //This case is not work, seems it BUG + //#endif + + //#ifdef ENABLE_FORCED_FAILURES + //Set mesh name + aMesh_1->setName("EmptyMesh"); + aRdWrDriver21->setMeshName("EmptyMesh"); + + //Trying write in file empty mesh + CPPUNIT_ASSERT_THROW(aRdWrDriver21->write(),MEDEXCEPTION); + //No exception in this case, seems it BUG + //#endif + + //Set initialy mesh name + aMesh_1->setName(meshname); + //Test setMeshName() and getMeshName() methods + try + { + aRdWrDriver21->setMeshName(meshname); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_EQUAL(meshname, aRdWrDriver21->getMeshName()); + + // Test read() method + try + { + aRdWrDriver21->read(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying read mesh from file, if mesh name is not set, i.e. empty + //#ifdef ENABLE_FORCED_FAILURES + aRdWrDriver21->setMeshName(""); + aMesh_1->setName(""); + CPPUNIT_ASSERT_THROW(aRdWrDriver21->read(), MEDEXCEPTION); + //No correct exception in this case + + //Trying write mesh to file, if mesh name is not set, i.e empty + CPPUNIT_ASSERT_THROW(aRdWrDriver21->write(), MEDEXCEPTION); + //No correct exception in this case + + //Trying read mesh from file with very long name + aRdWrDriver21->setMeshName(longmeshname); + aMesh_1->setName(longmeshname); + CPPUNIT_ASSERT_THROW(aRdWrDriver21->read(), MEDEXCEPTION); + //No correct exception in this case + + //Trying write mesh to file with very long name + CPPUNIT_ASSERT_THROW(aRdWrDriver21->write(), MEDEXCEPTION); + //No correct exception in this case + //#endif + + //Test write() method + aRdWrDriver21->setMeshName(newmeshname); + aMesh_1->setName(newmeshname); + try + { + aRdWrDriver21->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Check Mesh + CPPUNIT_ASSERT(aMesh_1); + + //Default constructor + MED_MESH_RDWR_DRIVER21 aRdWrDriver21Cpy_1; + + //Test (void operator =) defined in GENDRIVER class + aRdWrDriver21Cpy_1 = *aRdWrDriver21; + + //Test (bool operator ==) defined GENDRIVER class + CPPUNIT_ASSERT(aRdWrDriver21Cpy_1.GENDRIVER::operator==(*aRdWrDriver21)); + + //Test copy constructor + MED_MESH_RDWR_DRIVER21 aRdWrDriver21Cpy_2 (aRdWrDriver21Cpy_1); + CPPUNIT_ASSERT_EQUAL(aRdWrDriver21Cpy_2, *aRdWrDriver21); + + try + { + aRdWrDriver21->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test case: trying read/write mesh using copy closed driver + CPPUNIT_ASSERT_THROW(aRdWrDriver21Cpy_1.read(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aRdWrDriver21Cpy_2.read(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aRdWrDriver21Cpy_1.write(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aRdWrDriver21Cpy_2.write(), MEDEXCEPTION); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream rwostr1, rwostr2; + rwostr1<<aRdWrDriver21Cpy_1; + rwostr2<<aRdWrDriver21Cpy_2; + CPPUNIT_ASSERT(rwostr1.str() != ""); + CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + //Delete all objects + delete longmeshname; + + delete aInvalidRdDriver21; + delete aRdDriver21; + + delete aInvalidWrDriver21; + delete aWrDriver21; + delete aTmpWrDriver21; + + delete aInvalidRdWrDriver21; + delete aRdWrDriver21; + + delete aMesh; + delete aMesh_1; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_MedMeshDriver22.cxx b/src/MEDMEMCppTest/MEDMEMTest_MedMeshDriver22.cxx new file mode 100644 index 000000000..53d7c14b7 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_MedMeshDriver22.cxx @@ -0,0 +1,530 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include <MEDMEM_MedMeshDriver22.hxx> +#include <MEDMEM_Mesh.hxx> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; + +/*! + * Check methods (13), defined in MEDMEM_MedMeshDriver22.hxx: + * class MED_MESH_DRIVER22 : public virtual MED_MESH_DRIVER { + * (+) MED_MESH_DRIVER22(); + * (+) MED_MESH_DRIVER22(const string & fileName, MESH * ptrMesh, MED_EN::med_mode_acces accessMode); + * (+) MED_MESH_DRIVER22(const MED_MESH_DRIVER22 & driver); + * (+) virtual ~MED_MESH_DRIVER22(); + * (+) void open(); + * (+) void close(); + * } + * class MED_MESH_RDONLY_DRIVER22 : public virtual IMED_MESH_RDONLY_DRIVER, + * public virtual MED_MESH_DRIVER22 { + * (+) MED_MESH_RDONLY_DRIVER22(); + * (+) MED_MESH_RDONLY_DRIVER22(const string & fileName, MESH * ptrMesh); + * (+) MED_MESH_RDONLY_DRIVER22(const MED_MESH_RDONLY_DRIVER22 & driver); + * (+) virtual ~MED_MESH_RDONLY_DRIVER22(); + * (+) void read (void); + * } + * class MED_MESH_WRONLY_DRIVER22 : public virtual IMED_MESH_WRONLY_DRIVER, + * public virtual MED_MESH_DRIVER22 { + * (+) MED_MESH_WRONLY_DRIVER22(); + * (+) MED_MESH_WRONLY_DRIVER22(const string & fileName, MESH * ptrMesh); + * (+) MED_MESH_WRONLY_DRIVER22(const MED_MESH_WRONLY_DRIVER22 & driver); + * (+) virtual ~MED_MESH_WRONLY_DRIVER22(); + * (+) void write(void) const; + * } + * class MED_MESH_RDWR_DRIVER22 : public IMED_MESH_RDWR_DRIVER, + * public MED_MESH_RDONLY_DRIVER22, public MED_MESH_WRONLY_DRIVER22 { + * (+) MED_MESH_RDWR_DRIVER22(); + * (+) MED_MESH_RDWR_DRIVER22(const string & fileName, MESH * ptrMesh); + * (+) MED_MESH_RDWR_DRIVER22(const MED_MESH_RDWR_DRIVER22 & driver); + * (+) ~MED_MESH_RDWR_DRIVER22(); + * (+) void write(void) const; + * (+) void read (void); + * } + */ +void MEDMEMTest::testMedMeshDriver22() +{ + MESH *aMesh = new MESH(); + MESH *aMesh_1 = new MESH(); + + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if (tmp_dir == "") tmp_dir = "/tmp"; + + string filename_rd = data_dir + "/share/salome/resources/med/pointe_import22.med"; + string filename_wr = tmp_dir + "/myWr_pointe22.med"; + string tmpfile = tmp_dir + "/tmp.med"; + string meshname = "maa1"; + string newmeshname = "new" + meshname; + string fileNotExistsName_rd = "notExists.med"; + string fileNotExistsName_wr = "/path_not_exists/file_not_exists.med"; + string filename_rdwr = tmp_dir + "/myRdWr_pointe22.med"; + char* longmeshname = new char[MED_TAILLE_NOM+2]; + string fcopy = "cp " + filename_rd + " " + filename_rdwr; + for (int i = 0; i<MED_TAILLE_NOM+2; ++i) + longmeshname[i] = 'a'; + + //Copy file in the TMP dir for testing READ/WRITE case + system(fcopy.data()); + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filename_wr); + aRemover.Register(filename_rdwr); + aRemover.Register(tmpfile); + + //----------------------------------Test READ ONLY part---------------------------------------------------// + + //Creation a incorrect read only driver + MED_MESH_RDONLY_DRIVER22 *aInvalidRdDriver22 = new MED_MESH_RDONLY_DRIVER22(fileNotExistsName_rd, aMesh); + + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidRdDriver22->open(), MEDEXCEPTION); + + //Creation a correct read only driver (normal constructor) + MED_MESH_RDONLY_DRIVER22 *aRdDriver22 = new MED_MESH_RDONLY_DRIVER22(filename_rd, aMesh); + + //Check driver + CPPUNIT_ASSERT(aRdDriver22); + + //Trying read mesh from file, if file is not open + CPPUNIT_ASSERT_THROW(aRdDriver22->read(), MEDEXCEPTION); + + //Test open() method + try + { + aRdDriver22->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //#ifdef ENABLE_FORCED_FAILURES + //Trying open file secondary. + //CPPUNIT_ASSERT_THROW(aRdDriver22->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aRdDriver22->open()); + //This case is not work, seems it BUG + //#endif + + //Trying read mesh from file, if mesh name is not set, i.e. empty + CPPUNIT_ASSERT_THROW(aRdDriver22->read(), MEDEXCEPTION); + + //Trying read mesh from file with very long name + aRdDriver22->setMeshName(longmeshname); + CPPUNIT_ASSERT_THROW(aRdDriver22->read(), MEDEXCEPTION); + + //Set correct Mesh name + //Test setMeshName() and getMeshName() methods + try + { + aRdDriver22->setMeshName(meshname); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_EQUAL(meshname, aRdDriver22->getMeshName()); + + + //Test read() method + try + { + aRdDriver22->read(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test write() method for READ ONLY driver + CPPUNIT_ASSERT_THROW(aRdDriver22->write(), MEDEXCEPTION); + + //Check Mesh + CPPUNIT_ASSERT(aMesh); + + //Default constructor + MED_MESH_RDONLY_DRIVER22 aRdDriver22Cpy_1; + + //Test (void operator =) defined in GENDRIVER class in MEDMEM_GenDriver.hxx + //aRdDriver22Cpy_1 = *aRdDriver22; + + //Test (bool operator ==) defined GENDRIVER class in MEDMEM_GenDriver.hxx + CPPUNIT_ASSERT(aRdDriver22Cpy_1.GENDRIVER::operator==(*aRdDriver22)); + + //Test copy constructor + MED_MESH_RDONLY_DRIVER22 aRdDriver22Cpy_2 (aRdDriver22Cpy_1); + CPPUNIT_ASSERT_EQUAL(aRdDriver22Cpy_2, *aRdDriver22); + + //Test close() method + try + { + aRdDriver22->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying read mesh from copy closed driver + CPPUNIT_ASSERT_THROW(aRdDriver22Cpy_1.read(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aRdDriver22Cpy_2.read(), MEDEXCEPTION); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream rostr1, rostr2; + rostr1<<aRdDriver22Cpy_1; + rostr2<<aRdDriver22Cpy_2; + CPPUNIT_ASSERT(rostr1.str() != ""); + CPPUNIT_ASSERT(rostr1.str() == rostr2.str()); + + + //----------------------------------Test WRITE ONLY part------------------------------------------// + + //Creation a incorrect write only driver + MED_MESH_WRONLY_DRIVER22 *aInvalidWrDriver22 = new MED_MESH_WRONLY_DRIVER22(fileNotExistsName_wr, aMesh); + + //Trying open non existing file + CPPUNIT_ASSERT_THROW(aInvalidWrDriver22->open(), MEDEXCEPTION); + + //Trying write empty mesh + MED_MESH_WRONLY_DRIVER22 *aTmpWrDriver22 = new MED_MESH_WRONLY_DRIVER22(tmpfile, aMesh_1); + + //#ifdef ENABLE_FORCED_FAILURES + aTmpWrDriver22->open(); + aTmpWrDriver22->setMeshName("EmptyMesh"); + CPPUNIT_ASSERT_THROW(aTmpWrDriver22->write(),MEDEXCEPTION); + aTmpWrDriver22->close(); + //Unknown exception in this case + //#endif + + //Creation a correct write only driver + MED_MESH_WRONLY_DRIVER22 *aWrDriver22 = new MED_MESH_WRONLY_DRIVER22(filename_wr, aMesh); + + //Check driver + CPPUNIT_ASSERT(aWrDriver22); + + //Trying write mesh to file, if file is not open + CPPUNIT_ASSERT_THROW(aWrDriver22->write(), MEDEXCEPTION); + + //Test open() method + try + { + aWrDriver22->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //#ifdef ENABLE_FORCED_FAILURES + //Trying open file secondary. + //CPPUNIT_ASSERT_THROW(aWrDriver22->open(), MEDEXCEPTION); + //This case is not work, seems it BUG + //#endif + + //Test case: trying write mesh to file, if mesh name is not set, i.e empty + aMesh->setName(""); + aWrDriver22->setMeshName(""); + CPPUNIT_ASSERT_THROW(aWrDriver22->write(), MEDEXCEPTION); + + //Trying write mesh to file with very long name + aWrDriver22->setMeshName(longmeshname); + CPPUNIT_ASSERT_THROW(aWrDriver22->write(), MEDEXCEPTION); + + //Set initialy mesh name + aMesh->setName(meshname); + //Test setMeshName() and getMeshName() methods + try + { + aWrDriver22->setMeshName(meshname); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_EQUAL(meshname, aWrDriver22->getMeshName()); + + // aWrDriver22->open(); + //Test write() method + try + { + aWrDriver22->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test read() method for WRITE ONLY driver + CPPUNIT_ASSERT_THROW(aWrDriver22->read(), MEDEXCEPTION); + + //Default constructor + MED_MESH_WRONLY_DRIVER22 aWrDriver22Cpy_1; + + //Test (void operator =) defined in GENDRIVER class + //aWrDriver22Cpy_1 = *aWrDriver22; + + //Test (bool operator ==) defined GENDRIVER class + CPPUNIT_ASSERT(aWrDriver22Cpy_1.GENDRIVER::operator==(*aWrDriver22)); + + //Test copy constructor + MED_MESH_WRONLY_DRIVER22 aWrDriver22Cpy_2 (aWrDriver22Cpy_1); + CPPUNIT_ASSERT_EQUAL(aWrDriver22Cpy_2 , *aWrDriver22); + + try + { + aWrDriver22->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test case: Trying write mesh using copy closed driver + CPPUNIT_ASSERT_THROW(aWrDriver22Cpy_1.write(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aWrDriver22Cpy_2.write(), MEDEXCEPTION); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream wostr1, wostr2; + wostr1<<aWrDriver22Cpy_1; + wostr2<<aWrDriver22Cpy_2; + CPPUNIT_ASSERT(wostr1.str() != ""); + CPPUNIT_ASSERT(wostr1.str() == wostr2.str()); + + + //----------------------------------Test READ / WRITE part------------------------------------------// + + //Creation a incorrect read/write driver + MED_MESH_RDWR_DRIVER22 *aInvalidRdWrDriver22 = new MED_MESH_RDWR_DRIVER22(fileNotExistsName_wr, aMesh_1); + + //Test case: trying open non existing file + CPPUNIT_ASSERT_THROW(aInvalidRdWrDriver22->open(), MEDEXCEPTION); + + //Creation a correct read/write driver + MED_MESH_RDWR_DRIVER22 *aRdWrDriver22 = new MED_MESH_RDWR_DRIVER22(filename_rdwr, aMesh_1); + + //Check driver + CPPUNIT_ASSERT(aRdWrDriver22); + + //Test case: trying write mesh to file, if file is not open + CPPUNIT_ASSERT_THROW(aRdWrDriver22->write(), MEDEXCEPTION); + + //Test case: trying read mesh from file, if file is not open + CPPUNIT_ASSERT_THROW(aRdWrDriver22->read(), MEDEXCEPTION); + + //Test open() method + try + { + aRdWrDriver22->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //#ifdef ENABLE_FORCED_FAILURES + //Test case: trying open file secondary. + //CPPUNIT_ASSERT_THROW(aRdWrDriver22->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aRdWrDriver22->open()); + //This case is not work, seems it BUG + //#endif + + //#ifdef ENABLE_FORCED_FAILURES + //Set mesh name + aMesh_1->setName("EmptyMesh"); + aRdWrDriver22->setMeshName("EmptyMesh"); + //Trying write in file empty mesh + CPPUNIT_ASSERT_THROW(aRdWrDriver22->write(),MEDEXCEPTION); + //No exception in this case, seems it BUG + //#endif + + //Set initialy mesh name + aMesh_1->setName(meshname); + //Test setMeshName() and getMeshName() methods + try + { + aRdWrDriver22->setMeshName(meshname); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_EQUAL(meshname, aRdWrDriver22->getMeshName()); + + //Test read() method + try + { + aRdWrDriver22->read(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Trying read mesh from file, if mesh name is not set, i.e. empty + aRdWrDriver22->setMeshName(""); + aMesh_1->setName(""); + CPPUNIT_ASSERT_THROW(aRdWrDriver22->read(), MEDEXCEPTION); + + //Trying write mesh to file, if mesh name is not set, i.e empty + CPPUNIT_ASSERT_THROW(aRdWrDriver22->write(), MEDEXCEPTION); + + //Trying read mesh from file with very long name + aRdWrDriver22->setMeshName(longmeshname); + aMesh_1->setName(longmeshname); + CPPUNIT_ASSERT_THROW(aRdWrDriver22->read(), MEDEXCEPTION); + + //Trying write mesh to file with very long name + CPPUNIT_ASSERT_THROW(aRdWrDriver22->write(), MEDEXCEPTION); + + //Test write() method + aRdWrDriver22->setMeshName(newmeshname); + aMesh_1->setName(newmeshname); + try + { + aRdWrDriver22->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Check Mesh + CPPUNIT_ASSERT(aMesh_1); + + //Default constructor + MED_MESH_RDWR_DRIVER22 aRdWrDriver22Cpy_1; + + //Test (void operator =) defined in GENDRIVER class + aRdWrDriver22Cpy_1= *aRdWrDriver22; + + //Test (bool operator ==) defined GENDRIVER class + CPPUNIT_ASSERT(aRdWrDriver22Cpy_1.GENDRIVER::operator==(*aRdWrDriver22)); + + //Test copy constructor + MED_MESH_RDWR_DRIVER22 aRdWrDriver22Cpy_2 (aRdWrDriver22Cpy_1); + // CPPUNIT_ASSERT(aRdWrDriver22Cpy_2.GENDRIVER::operator==( *aRdWrDriver22)); + + try + { + aRdWrDriver22->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test case: trying read/write mesh using copy closed driver + CPPUNIT_ASSERT_THROW(aRdWrDriver22Cpy_1.read(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aRdWrDriver22Cpy_2.read(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aRdWrDriver22Cpy_1.write(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aRdWrDriver22Cpy_2.write(), MEDEXCEPTION); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream rwostr1, rwostr2; + rwostr1<<aRdWrDriver22Cpy_1; + rwostr2<<aRdWrDriver22Cpy_2; + cout << aRdWrDriver22Cpy_1; + cout << aRdWrDriver22Cpy_2; + CPPUNIT_ASSERT(rwostr1.str() != ""); + CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + //Delete all objects + delete []longmeshname; + + delete aInvalidRdDriver22; + delete aRdDriver22; + + delete aInvalidWrDriver22; + delete aWrDriver22; + + delete aInvalidRdWrDriver22; + delete aRdWrDriver22; + delete aTmpWrDriver22; + + delete aMesh; + delete aMesh_1; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_MedVersion.cxx b/src/MEDMEMCppTest/MEDMEMTest_MedVersion.cxx new file mode 100644 index 000000000..012fbb028 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_MedVersion.cxx @@ -0,0 +1,83 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include <cstdlib> +#include <exception> + +#include <MEDMEM_MedVersion.hxx> +#include "MEDMEM_Compatibility21_22.hxx" + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +/*! + * Check methods (not in spec), defined in MEDMEM_MedVersion.hxx: + * (+) MED_EN::medFileVersion getMedFileVersion(const string & fileName) throw (MEDEXCEPTION); + * (+) int getMedAccessMode(MED_EN::med_mode_acces mode, + * MED_EN::medFileVersion medVersion) throw (MEDEXCEPTION); + */ + +void MEDMEMTest::testMedVersion() +{ + string filename = getenv("MED_ROOT_DIR"); + filename += "/share/salome/resources/med/pointe.med"; + string notExistFileName = "anyfile"; + medFileVersion myFileVersion; + medFileVersion myEmptyFileVersion; + + // Test - getMedFileVersion + CPPUNIT_ASSERT_THROW(getMedFileVersion(notExistFileName),MEDEXCEPTION); + + try + { + myFileVersion = getMedFileVersion(filename); + CPPUNIT_ASSERT(myFileVersion == V21); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch(...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test - getMedAccessMode + CPPUNIT_ASSERT_THROW(getMedAccessMode(RDWR,myEmptyFileVersion),MEDEXCEPTION); + + try + { + CPPUNIT_ASSERT_EQUAL(med_2_1::MED_ECRI/*REMP*/, + (med_2_1::med_mode_acces)getMedAccessMode(RDWR,myFileVersion)); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch(...) + { + CPPUNIT_FAIL("Unknown exception"); + } +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_MeshAndMeshing.cxx b/src/MEDMEMCppTest/MEDMEMTest_MeshAndMeshing.cxx new file mode 100644 index 000000000..fee32e4f0 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_MeshAndMeshing.cxx @@ -0,0 +1,1923 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/Message.h> +#include <cppunit/TestAssert.h> +#include "MEDMEM_Meshing.hxx" +#include "MEDMEM_Group.hxx" +#include "MEDMEM_define.hxx" +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_Grid.hxx" + +#include "MEDMEM_Med.hxx" +#include "MEDMEM_MedMeshDriver22.hxx" + +#include <sstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +double dmax(double x, double y) { return (x>y)?x:y;} + +double dmin(double x, double y) { return (x>y)?y:x;} + +void addMedFacesGroup (MESHING& meshing, int nFaces, const int *groupValue, + string groupName, const MED_EN::medGeometryElement *mytypes, + const int *index, const int *myNumberOfElements, int nbOfGeomTypes) +{ + GROUP faces; + faces.setName(groupName); + faces.setMesh(&meshing); + faces.setEntity(MED_EN::MED_FACE); + faces.setNumberOfGeometricType(nbOfGeomTypes); + faces.setGeometricType(mytypes); + faces.setNumberOfElements(myNumberOfElements); + faces.setNumber(index, groupValue); + meshing.addGroup(faces); +} + +void addMedFacesGroupAll (MESHING& meshing, string groupName) +{ + GROUP faces; + faces.setName(groupName); + faces.setMesh(&meshing); + faces.setEntity(MED_EN::MED_FACE); + meshing.addGroup(faces); +} + +/*! + * Check methods (18), defined in MEDMEM_Meshing.hxx: + * class MESHING: public MESH { + * (+) MESHING(); + * (+) ~MESHING(); + * (+) void setSpaceDimension (const int SpaceDimension); + * (+) void setMeshDimension (const int MeshDimension); + * (+) void setNumberOfNodes (const int NumberOfNodes); + * (+) void setCoordinates (const int SpaceDimension, const int NumberOfNodes, + * const double * Coordinates, + * const string System, const MED_EN::medModeSwitch Mode); + * (+) void setCoordinatesSystem(const string System) throw (MEDEXCEPTION); + * (+) void setCoordinatesNames (const string * names); + * (+) void setCoordinateName (const string name, const int i); + * (+) void setCoordinatesUnits (const string * units); + * (+) void setCoordinateUnit (const string unit, const int i); + * (+) void setNumberOfTypes (const int NumberOfTypes, + * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); + * (+) void setTypes (const MED_EN::medGeometryElement * Types, + * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); + * (+) void setNumberOfElements (const int * NumberOfElements, + * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); + * (+) void setConnectivity (const int * Connectivity, const MED_EN::medEntityMesh Entity, + * const MED_EN::medGeometryElement Type) throw (MEDEXCEPTION); + * (+) void setPolygonsConnectivity (const int * ConnectivityIndex, const int * ConnectivityValue, + * int nbOfPolygons, + * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); + * (+) void setPolyhedraConnectivity (const int * PolyhedronIndex, const int * FacesIndex, + * const int * Nodes, int nbOfPolyhedra, + * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); + * (NOT YET IMPLEMENTED!!!) void setConnectivities (const int * ConnectivityIndex, + * const int * ConnectivityValue, + * const MED_EN::medConnectivity ConnectivityType, + * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); + * (+) void addGroup (const GROUP & Group) throw (MEDEXCEPTION); + * } + */ + +/*! + * Check methods (87), defined in MEDMEM_Mesh.hxx: + * class MESH : public RCBASE { + * (+) void init(); + * (+) MESH(); + * (+) MESH(MESH &m); + * (+) MESH & operator=(const MESH &m); + * (+) virtual bool operator==(const MESH& other) const; + * (+) virtual bool deepCompare(const MESH& other) const; + * (+) MESH(driverTypes driverType, const string & fileName="", + * const string & meshName="") throw (MEDEXCEPTION); + * (+) virtual ~MESH(); + * (+) friend ostream & operator<<(ostream &os, const MESH &my); + * (+) int addDriver(driverTypes driverType, + * const string & fileName="Default File Name.med", + * const string & driverName="Default Mesh Name", + * MED_EN::med_mode_acces access=MED_EN::MED_REMP); + * (+) int addDriver(GENDRIVER & driver); + * (+) void rmDriver(int index=0); + * (+) virtual void read(int index=0); + * (must be private) inline void read(const GENDRIVER & genDriver); + * (+) inline void write(int index=0, const string & driverName = ""); + * (must be private) inline void write(const GENDRIVER & genDriver); + * (+) inline void setName(string name); + * (+) inline void setDescription(string description); + * (+) inline string getName() const; + * (+) inline string getDescription() const; + * (+) inline int getSpaceDimension() const; + * (+) inline int getMeshDimension() const; + * (+) inline bool getIsAGrid(); + * (+) inline int getNumberOfNodes() const; + * (+) virtual inline const COORDINATE * getCoordinateptr() const; + * (+) inline string getCoordinatesSystem() const; + * (+) virtual inline const double * getCoordinates(MED_EN::medModeSwitch Mode) const; + * (+) virtual inline const double getCoordinate(int Number,int Axis) const; + * (+) inline const string * getCoordinatesNames() const; + * (+) inline const string * getCoordinatesUnits() const; + * (+) virtual inline int getNumberOfTypes(MED_EN::medEntityMesh Entity) const; + * (+) virtual int getNumberOfTypesWithPoly(MED_EN::medEntityMesh Entity) const; + * (+) virtual inline const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const; + * (+) virtual MED_EN::medGeometryElement * getTypesWithPoly(MED_EN::medEntityMesh Entity) const; + * (+) virtual inline const CELLMODEL * getCellsTypes(MED_EN::medEntityMesh Entity) const; + * (+) virtual inline string * getCellTypeNames(MED_EN::medEntityMesh Entity) const; + * (+) virtual const int * getGlobalNumberingIndex(MED_EN::medEntityMesh Entity) const; + * (+) virtual inline int getNumberOfElements(MED_EN::medEntityMesh Entity, + * MED_EN::medGeometryElement Type) const; + * (+) virtual int getNumberOfElementsWithPoly(MED_EN::medEntityMesh Entity, + * MED_EN::medGeometryElement Type) const; + * (+) virtual inline bool existConnectivity(MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity) const; + * (+) inline bool existPolygonsConnectivity(MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity) const; + * (+) inline bool existPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity) const; + * (+) virtual inline MED_EN::medGeometryElement getElementType + * (MED_EN::medEntityMesh Entity, int Number) const; + * (+) virtual inline MED_EN::medGeometryElement getElementTypeWithPoly + * (MED_EN::medEntityMesh Entity, int Number) const; + * (+) virtual inline void calculateConnectivity(MED_EN::medModeSwitch Mode, + * MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity) const; + * (+) virtual inline int getConnectivityLength(MED_EN::medModeSwitch Mode, + * MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity, + * MED_EN::medGeometryElement Type) const; + * (+) virtual inline const int * getConnectivity(MED_EN::medModeSwitch Mode, + * MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity, + * MED_EN::medGeometryElement Type) const; + * (+) virtual inline const int * getConnectivityIndex + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; + * (+) inline int getPolygonsConnectivityLength + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; + * (+) inline const int * getPolygonsConnectivity + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; + * (+) inline const int * getPolygonsConnectivityIndex + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; + * (+) inline int getNumberOfPolygons(MED_EN::medEntityMesh Entity=MED_EN::MED_ALL_ENTITIES) const; + * (+) inline int getPolyhedronConnectivityLength(MED_EN::medConnectivity ConnectivityType) const; + * (+) inline const int * getPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType) const; + * (+) inline const int * getPolyhedronFacesIndex() const; + * (+) inline const int * getPolyhedronIndex(MED_EN::medConnectivity ConnectivityType) const; + * (+) inline int getNumberOfPolyhedronFaces() const; + * (+) inline int getNumberOfPolyhedron() const; + * (+) virtual int getElementNumber(MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type, + * int * connectivity) const; + * (+) virtual inline int getReverseConnectivityLength + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; + * (+) virtual inline const int * getReverseConnectivity + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; + * (+) virtual inline int getReverseConnectivityIndexLength + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; + * (+) virtual inline const int * getReverseConnectivityIndex + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; + * (+) virtual int getNumberOfFamilies(MED_EN::medEntityMesh Entity) const; + * (+) virtual inline const vector<FAMILY*> getFamilies(MED_EN::medEntityMesh Entity) const; + * (+) virtual inline const FAMILY* getFamily(MED_EN::medEntityMesh Entity,int i) const; + * (+) virtual int getNumberOfGroups(MED_EN::medEntityMesh Entity) const; + * (+) virtual inline const vector<GROUP*> getGroups(MED_EN::medEntityMesh Entity) const; + * (+) virtual inline const GROUP* getGroup(MED_EN::medEntityMesh Entity,int i) const; + * (+) virtual inline const CONNECTIVITY* getConnectivityptr() const; + * (+) virtual SUPPORT * getBoundaryElements(MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); + * (+) SUPPORT * getSkin(const SUPPORT * Support3D) throw (MEDEXCEPTION); + * (+) virtual FIELD<double>* getVolume (const SUPPORT * Support) const throw (MEDEXCEPTION); + * (+) virtual FIELD<double>* getArea (const SUPPORT * Support) const throw (MEDEXCEPTION); + * (+) virtual FIELD<double>* getLength (const SUPPORT * Support) const throw (MEDEXCEPTION); + * (+) virtual FIELD<double>* getNormal (const SUPPORT * Support) const throw (MEDEXCEPTION); + * (+) virtual FIELD<double>* getBarycenter (const SUPPORT * Support) const throw (MEDEXCEPTION); + * (+) static SUPPORT * mergeSupports(const vector<SUPPORT *> Supports) throw (MEDEXCEPTION); + * (+) static SUPPORT * intersectSupports(const vector<SUPPORT *> Supports) throw (MEDEXCEPTION); + * (+) void createFamilies(); + * (+) SUPPORT *buildSupportOnNodeFromElementList + * (const list<int>& listOfElt, MED_EN::medEntityMesh entity) const throw (MEDEXCEPTION); + * (do the same thing as buildSupportOnNodeFromElementList except that a SUPPORT is not created) void fillSupportOnNodeFromElementList + * (const list<int>& listOfElt, SUPPORT *supportToFill) const throw (MEDEXCEPTION); + * (+) SUPPORT *buildSupportOnElementsFromElementList + * (const list<int>& listOfElt, MED_EN::medEntityMesh entity) const throw (MEDEXCEPTION); + * (+) int getElementContainingPoint(const double *coord); + * (+) vector< vector<double> > getBoundingBox() const; + * (+) template<class T> static + * FIELD<T> * mergeFields(const vector< FIELD<T> * > & others, bool meshCompare=false); + * (Presently disconnected in C++) virtual void addReference() const; + * (Presently disconnected in C++) virtual void removeReference() const; + * } + */ +void MEDMEMTest::testMeshAndMeshing() +{ + string datadir = getenv("MED_ROOT_DIR"); + string filename = datadir + "/share/salome/resources/med/pointe.med"; + string meshname = "maa1"; + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if (tmp_dir == "") + tmp_dir = "/tmp"; + string filenameout21 = tmp_dir + "/myMeshWrite4_pointe21.med"; + string filename_profiles_wr = tmp_dir + "/myMedProfilesFieldfile.med"; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filenameout21); + aRemover.Register(filename_profiles_wr); + + //////////// + // TEST 1 // + //////////// + + MESH * myMesh= new MESH(); + myMesh->setName("FIRST_MESH"); + CPPUNIT_ASSERT(myMesh != NULL); + + //test operator << + //#ifdef ENABLE_FAULTS + CPPUNIT_ASSERT_NO_THROW(cout << *myMesh << endl); + //#endif + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_FAIL("ERROR: operator << : if mesh is empty then attempt" + // " to get values from null object causes error"); + //#endif + + //test operator = + MESH myMesh1 = *myMesh; + + //deepCompare + //#ifdef ENABLE_FAULTS + bool isEqual = false; + CPPUNIT_ASSERT_NO_THROW(isEqual = myMesh1.deepCompare(*myMesh)); + CPPUNIT_ASSERT(isEqual); + //#endif + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_FAIL("ERROR: deepCompare(...) fails if mesh is empty"); + //#endif + + //ensure it imposible to compare meshes + MESH *myMeshPointer = myMesh; + //test operator == + CPPUNIT_ASSERT(*myMeshPointer == *myMesh); + + delete myMesh; + + //set a MESH object + MESHING myMeshing; + myMeshing.setName("meshing"); + // define coordinates + + int SpaceDimension = 3; + int NumberOfNodes = 19; + double Coordinates[57] = { + 0.0, 0.0, 0.0, + 0.0, 0.0, 1.0, + 2.0, 0.0, 1.0, + 0.0, 2.0, 1.0, + -2.0, 0.0, 1.0, + 0.0, -2.0, 1.0, + 1.0, 1.0, 2.0, + -1.0, 1.0, 2.0, + -1.0, -1.0, 2.0, + 1.0, -1.0, 2.0, + 1.0, 1.0, 3.0, + -1.0, 1.0, 3.0, + -1.0, -1.0, 3.0, + 1.0, -1.0, 3.0, + 1.0, 1.0, 4.0, + -1.0, 1.0, 4.0, + -1.0, -1.0, 4.0, + 1.0, -1.0, 4.0, + 0.0, 0.0, 5.0 + }; + try + { + myMeshing.setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,"CARTESIAN",MED_FULL_INTERLACE); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + string Names[3] = { "X","Y","Z" }; + try + { + myMeshing.setCoordinatesNames(Names); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + string Units[3] = { "cm","cm","cm" }; + try + { + myMeshing.setCoordinatesUnits(Units); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + // define conectivities + + // cell part + + const int NumberOfTypes = 3; + medGeometryElement Types[NumberOfTypes] = {MED_TETRA4,MED_PYRA5,MED_HEXA8}; + const int NumberOfElements[NumberOfTypes] = {12,2,2}; + + CPPUNIT_ASSERT_NO_THROW(myMeshing.setNumberOfTypes(NumberOfTypes,MED_CELL)); + + CPPUNIT_ASSERT_NO_THROW(myMeshing.setTypes(Types,MED_CELL)); + + CPPUNIT_ASSERT_NO_THROW(myMeshing.setNumberOfElements(NumberOfElements,MED_CELL)); + + const int sizeTetra = 12*4; + int ConnectivityTetra[sizeTetra]= + { + 1,2,3,6, + 1,2,4,3, + 1,2,5,4, + 1,2,6,5, + 2,7,4,3, + 2,8,5,4, + 2,9,6,5, + 2,10,3,6, + 2,7,3,10, + 2,8,4,7, + 2,9,5,8, + 2,10,6,9 + }; + + CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityTetra,MED_CELL,MED_TETRA4)); + + int ConnectivityPyra[2*5]= + { + 7,8,9,10,2, + 15,18,17,16,19 + }; + + CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityPyra,MED_CELL,MED_PYRA5)); + + int ConnectivityHexa[2*8]= + { + 11,12,13,14,7,8,9,10, + 15,16,17,18,11,12,13,14 + }; + + CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityHexa,MED_CELL,MED_HEXA8)); + + // face part + const int NumberOfFacesTypes = 2; + medGeometryElement FacesTypes[NumberOfFacesTypes] = {MED_TRIA3,MED_QUAD4}; + const int NumberOfFacesElements[NumberOfFacesTypes] = {4,4}; + + CPPUNIT_ASSERT_NO_THROW(myMeshing.setNumberOfTypes(NumberOfFacesTypes,MED_FACE)); + CPPUNIT_ASSERT_NO_THROW(myMeshing.setTypes(FacesTypes,MED_FACE)); + CPPUNIT_ASSERT_NO_THROW(myMeshing.setNumberOfElements(NumberOfFacesElements,MED_FACE)); + const int nbTria = 4; + const int sizeTria = nbTria*3; + int ConnectivityTria[sizeTria]= + { + 1,4,3, + 1,5,4, + 1,6,5, + 1,3,6 + }; + + CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityTria,MED_FACE,MED_TRIA3)); + const int nbQua = 4; + int ConnectivityQua[nbQua*4]= + { + 7,8,9,10, + 11,12,13,14, + 11,7,8,12, + 12,8,9,13 + }; + + CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityQua,MED_FACE,MED_QUAD4)); + + int meshDimension = SpaceDimension; // because there 3D cells in the mesh + try + { + myMeshing.setMeshDimension(meshDimension); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + // edge part + + // not yet implemented : if set, results are unpredictable. + + // Some groups : + + // Node : + { + GROUP myGroup; + myGroup.setName("SomeNodes"); + myGroup.setMesh(&myMeshing); + myGroup.setEntity(MED_NODE); + myGroup.setNumberOfGeometricType(1); + medGeometryElement myTypes[1] = {MED_NONE}; + myGroup.setGeometricType(myTypes); + const int myNumberOfElements[1] = {4}; + myGroup.setNumberOfElements(myNumberOfElements); + const int index[1+1] = {1,5}; + const int value[4]= { 1,4,5,7}; + myGroup.setNumber(index,value); + CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); + } + { + GROUP myGroup; + myGroup.setName("OtherNodes"); + myGroup.setMesh(&myMeshing); + myGroup.setEntity(MED_NODE); + myGroup.setNumberOfGeometricType(1); + medGeometryElement myTypes[1] = {MED_NONE}; + myGroup.setGeometricType(myTypes); + const int myNumberOfElements[1] = {3}; + myGroup.setNumberOfElements(myNumberOfElements); + const int index[1+1] = {1,4}; + const int value[3]= { 2,3,6}; + myGroup.setNumber(index,value); + CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); + } + + // Cell : + { + GROUP myGroup; + myGroup.setName("SomeCells"); + myGroup.setMesh(&myMeshing); + myGroup.setEntity(MED_CELL); + myGroup.setNumberOfGeometricType(3); + medGeometryElement myTypes[3] = {MED_TETRA4,MED_PYRA5,MED_HEXA8}; + myGroup.setGeometricType(myTypes); + const int myNumberOfElements[3] = {4,1,2}; + myGroup.setNumberOfElements(myNumberOfElements); + const int index[3+1] = {1,5,6,8}; + const int value[4+1+2]= + { + 2,7,8,12, + 13, + 15,16 + }; + myGroup.setNumber(index,value); + CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); + } + { + GROUP myGroup; + myGroup.setName("OtherCells"); + myGroup.setMesh(&myMeshing); + myGroup.setEntity(MED_CELL); + myGroup.setNumberOfGeometricType(2); + medGeometryElement myTypes[] = {MED_TETRA4,MED_PYRA5}; + myGroup.setGeometricType(myTypes); + const int myNumberOfElements[] = {4,1}; + myGroup.setNumberOfElements(myNumberOfElements); + const int index[2+1] = {1,5,6}; + const int value[4+1]= + { + 3,4,5,9, + 14 + }; + myGroup.setNumber(index,value); + CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); + } + + // Face : + { + GROUP myGroup; + myGroup.setName("SomeFaces"); + myGroup.setMesh(&myMeshing); + myGroup.setEntity(MED_FACE); + myGroup.setNumberOfGeometricType(2); + medGeometryElement myTypes[2] = {MED_TRIA3,MED_QUAD4}; + myGroup.setGeometricType(myTypes); + const int myNumberOfElements[2] = {2,3}; + myGroup.setNumberOfElements(myNumberOfElements); + const int index[2+1] = {1,3,6}; + const int value[2+3]= + { + 2,4, + 5,6,8 + }; + myGroup.setNumber(index,value); + CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); + } + { + GROUP myGroup; + myGroup.setName("OtherFaces"); + myGroup.setMesh(&myMeshing); + myGroup.setEntity(MED_FACE); + myGroup.setNumberOfGeometricType(1); + medGeometryElement myTypes[1] = {MED_TRIA3}; + myGroup.setGeometricType(myTypes); + const int myNumberOfElements[1] = {2}; + myGroup.setNumberOfElements(myNumberOfElements); + const int index[1+1] = {1,3}; + const int value[2]= + { + 1,3 + }; + myGroup.setNumber(index,value); + CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); + } + + //test Mesh(MESH &m) + { + MESH * myMesh2 = new MESH( myMeshing ); + CPPUNIT_ASSERT(myMesh2->deepCompare(myMeshing)); + + cout<<*myMesh2<<endl; + ostringstream os; + os << * myMesh2; + CPPUNIT_ASSERT(os.str() != ""); + + CPPUNIT_ASSERT_EQUAL(myMesh2->getName(),(string)"meshing"); + CPPUNIT_ASSERT((myMesh2->getDescription()).size() == 0); + myMesh2->setDescription("This class contains all information related to a 'meshing' mesh "); + CPPUNIT_ASSERT((myMesh2->getDescription()).size() != 0); + + CPPUNIT_ASSERT(myMesh2->getSpaceDimension() == SpaceDimension); + CPPUNIT_ASSERT(myMesh2->getMeshDimension() == meshDimension); + CPPUNIT_ASSERT(myMesh2->getNumberOfNodes() == NumberOfNodes); + + const COORDINATE* coord = myMesh2->getCoordinateptr(); + try + { + CPPUNIT_ASSERT(myMesh2->getCoordinatesSystem() != "catresian"); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + const string * units; + try + { + units = myMesh2->getCoordinatesUnits(); + for (int axe = 0; axe < SpaceDimension; axe++) { + string verif = coord->getCoordinateUnit(axe+1); + CPPUNIT_ASSERT(verif == units[axe]); + } + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + const string * noms; + try + { + noms = myMesh2->getCoordinatesNames(); + for (int axe = 0; axe < SpaceDimension; axe++) { + string verif = coord->getCoordinateName(axe+1); + CPPUNIT_ASSERT(verif == noms[axe]); + } + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + const double * coor2 = myMesh2->getCoordinates(MED_FULL_INTERLACE); + + for (int axe = 0; axe < SpaceDimension; axe++) { + try + { + for (int num = 0; num < NumberOfNodes; num++) { + try + { + const double d = myMesh2->getCoordinate(num + 1, axe + 1); + CPPUNIT_ASSERT(fabs(d - coor2[(num * SpaceDimension)+axe]) < 0.001); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + } + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + } + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + const CONNECTIVITY * myConnectivity = myMesh2->getConnectivityptr(); + + // MED_EN::MED_CELL + MED_EN::medEntityMesh entity = myConnectivity->getEntity(); + CPPUNIT_ASSERT_EQUAL(MED_CELL, entity); + + int typesNb; + CPPUNIT_ASSERT_NO_THROW(typesNb= myConnectivity->getNumberOfTypes(entity)); + CPPUNIT_ASSERT_EQUAL(NumberOfTypes, typesNb); + + const MED_EN::medGeometryElement * Types1; + CPPUNIT_ASSERT_NO_THROW(Types1 = myMesh2->getTypes(entity)); + + medConnectivity myMedConnect; + bool existConnect = false; + if (myMesh2->existConnectivity(MED_NODAL, entity)) + { + existConnect = true; + myMedConnect = MED_NODAL; + } + else if(myMesh2->existConnectivity(MED_DESCENDING, entity)) + { + existConnect = true; + myMedConnect = MED_DESCENDING; + } + + for(int t = 0; t < NumberOfTypes; t++ ) + { + CPPUNIT_ASSERT_EQUAL(Types1[t], Types[t]); + int NumberOfElements1 = 0; + CPPUNIT_ASSERT_NO_THROW(NumberOfElements1 = myMesh2->getNumberOfElements(entity, Types1[t])); + CPPUNIT_ASSERT_EQUAL(NumberOfElements1, NumberOfElements[t]); + if(existConnect) + { + const int * connectivity; + const int * connectivity_index; + CPPUNIT_ASSERT_NO_THROW(connectivity = myMesh2->getConnectivity + (MED_FULL_INTERLACE, myMedConnect, entity, Types1[t])); + connectivity_index = myMesh2->getConnectivityIndex(myMedConnect, entity); + for (int j = 0; j < NumberOfElements1; j++) { + cout<<"!!!!!!!!!!!!!!!"<<endl; + for (int k = connectivity_index[j]; k < connectivity_index[j+1]; k++) + cout << connectivity[k-1] << " "; + cout << endl; + } + } + } + + const CELLMODEL* myCellModel = myMesh2->getCellsTypes(entity); + string* TypeNames; + CPPUNIT_ASSERT_NO_THROW(TypeNames = myMesh2->getCellTypeNames(entity)); + + for(int k = 0; k < NumberOfTypes; k++ ) + { + CPPUNIT_ASSERT_EQUAL(TypeNames[k], myCellModel[k].getName()); + } + delete [] TypeNames; + + const int* myGlobalNbIdx; + CPPUNIT_ASSERT_NO_THROW(myGlobalNbIdx = myMesh2->getGlobalNumberingIndex(MED_FACE)); + for(int i = 0; i <= NumberOfFacesTypes; i++) + { + if(i == NumberOfFacesTypes) + { + CPPUNIT_ASSERT_EQUAL(myGlobalNbIdx[i],nbTria+nbQua+1); + CPPUNIT_ASSERT_THROW(myMesh2->getElementType(MED_FACE, myGlobalNbIdx[i]), MEDEXCEPTION); + break; + } + cout<<"Global number of first element of each geom type : "<<myGlobalNbIdx[i]<<endl; + } + + { + const int * ReverseNodalConnectivity; + + // Show Reverse Nodal Connectivity + //#ifndef ENABLE_FAULTS + // (BUG) CONNECTIVITY::_numberOfNodes is not set + ((CONNECTIVITY*)myConnectivity)->setNumberOfNodes(NumberOfNodes); + //#endif + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_FAIL("ERROR in CONNECTIVITY::calculateReverseNodalConnectivity()" + // " because myMesh2->_connectivity->_numberOfNodes is not set"); + //#endif + + CPPUNIT_ASSERT_NO_THROW(ReverseNodalConnectivity = myMesh2->getReverseConnectivity(MED_NODAL, entity)); + CPPUNIT_ASSERT_NO_THROW(myMesh2->getReverseConnectivityLength(MED_NODAL, entity)); + const int * ReverseNodalConnectivityIndex = myMesh2->getReverseConnectivityIndex(MED_NODAL, entity); + const int ReverseIdxLength = myMesh2->getReverseConnectivityIndexLength(MED_NODAL, entity); + CPPUNIT_ASSERT(ReverseIdxLength == NumberOfNodes+1); + for (int i = 0; i < NumberOfNodes; i++) { + cout << "Node "<< i+1 << " : "; + for (int j = ReverseNodalConnectivityIndex[i]; j < ReverseNodalConnectivityIndex[i+1]; j++) + cout << ReverseNodalConnectivity[j-1] << " "; + cout << endl; + } + + // Show Descending Connectivity + int NumberOfElements1; + const int * connectivity; + const int * connectivity_index; + myMesh2->calculateConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, entity); + try { + NumberOfElements1 = myMesh2->getNumberOfElements(entity, MED_ALL_ELEMENTS); + connectivity = myMesh2->getConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, entity, MED_ALL_ELEMENTS); + connectivity_index = myMesh2->getConnectivityIndex(MED_DESCENDING, entity); + } + catch (MEDEXCEPTION m) { + CPPUNIT_FAIL(m.what()); + } + + for (int j = 0; j < NumberOfElements1; j++) { + cout << "Element " << j+1 << " : "; + for (int k = connectivity_index[j]; k < connectivity_index[j+1]; k++) + cout << connectivity[k-1] << " "; + cout << endl; + } + + // getElementNumber + if (myMesh2->existConnectivity(MED_NODAL, MED_FACE)) { + int myTr[3] = {1,5,4}; + CPPUNIT_ASSERT_NO_THROW(myMesh2->getElementNumber(MED_NODAL,MED_FACE,MED_TRIA3,myTr)); + } + } + + //test family and group + int NumberOfGroups; + CPPUNIT_ASSERT_THROW(myMesh2->getNumberOfGroups(MED_ALL_ENTITIES), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(NumberOfGroups = myMesh2->getNumberOfGroups(MED_CELL)); + CPPUNIT_ASSERT_EQUAL(NumberOfGroups, 2); + vector<GROUP*> groups; + CPPUNIT_ASSERT_NO_THROW(groups = myMesh2->getGroups(MED_CELL)); + CPPUNIT_ASSERT(groups.size() != 0); + for(int nb = 1; nb <= NumberOfGroups; nb++ ) + { + const GROUP* group; + CPPUNIT_ASSERT_NO_THROW(group = myMesh2->getGroup(MED_CELL, nb)); + CPPUNIT_ASSERT_EQUAL(group->getName(), groups[nb-1]->getName()); + } + + int NumberOfFamilies; + CPPUNIT_ASSERT_NO_THROW(NumberOfFamilies = myMesh2->getNumberOfFamilies(MED_CELL)); + CPPUNIT_ASSERT_MESSAGE("Current mesh hasn't Families", NumberOfFamilies == 0); + + //create families - it's not possible to create, becase not all entities are defined + // EAP: the problem has been fixed for ENSIGHT Industrialization project + CPPUNIT_ASSERT_NO_THROW( myMesh2->createFamilies() ); + + /*CPPUNIT_ASSERT_NO_THROW(NumberOfFamilies = myMesh2->getNumberOfFamilies(MED_CELL)); + CPPUNIT_ASSERT( NumberOfFamilies != 0);*/ + + delete myMesh2; + } + + ////////////////////////////////////////////////////////////// + // TEST 2: Polygon and Polyhedron(only NODAL connectivity) // + ///////////////////////////////////////////////////////////// + + double CoordinatesPoly[57] = { + 2.0, 3.0, 2.0, + 3.0, 2.0, 2.0, + 4.0, 1.0, 2.0, + 2.0, 0.0, 2.0, + 0.0, 1.0, 2.0, + 1.0, 2.0, 2.0, + 2.0, 3.0, 1.0, + 3.0, 2.0, 0.0, + 4.0, 1.0, 0.0, + 2.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 1.0, 2.0, 0.0, + 5.0, 3.0, 2.0, + 7.0, 2.0, 2.0, + 6.0, 0.0, 2.0, + 6.0, 3.0, 0.0, + 7.0, 2.0, 0.0, + 6.0, 0.0, -1.0, + 5.0, 1.0, -3.0}; + + const int REFnodalConnOfFaces[74] = { + 1, 2, 3, 4, 5, 6, // Polyhedron 1 + 1, 7, 8, 2, + 2, 8, 9, 3, + 4, 3, 9, 10, + 5, 4, 10, 11, + 6, 5, 11, 12, + 1, 6, 12, 7, + 7, 12, 8, + 10, 9, 8, 12, 11, + + 13, 14, 15, 3, 2, // Polyhedron 2 + 13, 2, 8, 16, + 14, 13, 16, 17, + 15, 14, 17, + 15, 17, 18, + 15, 18, 9, + 3, 15, 9, + 2, 3, 9, 8, + 8, 9, 17, 16, + 9, 18, 17}; + const int NumberOfFaces = 19; + const int NumberOfPolyhedron = 2; + const int nbOfPolygons = 2; + const int REFfacesIndex[NumberOfFaces+1] = { + 1, 7, 11, 15, 19, 23, 27, 31, 34, + 39, 44, 48, 52, 55, 58, 61, 64, 68, 72, 75}; + + const int REFpolyIndex[NumberOfPolyhedron+1] = {1, 10, 20}; + + double PolygonCoordinates[27] = { + 2.0, 3.0, 12.0, + 3.0, 2.0, 12.0, + 4.0, 1.0, 12.0, + 2.0, 0.0, 12.0, + 0.0, 1.0, 12.0, + 1.0, 2.0, 12.0, + 5.0, 3.0, 12.0, + 7.0, 2.0, 12.0, + 6.0, 0.0, 12.0}; + + const int REFpolygonFaces[11] = { + 1, 2, 3, 4, 5, 6, // Polygon 1 + 7, 8, 9, 3, 2}; // Polygon 2 + + const int REFpolygonIndex[nbOfPolygons+1] = {1, 7, 12}; + + MESHING myMeshingPoly; + myMeshingPoly.setName("meshingpoly"); + + int MeshDimension = 3; + + const int NbOfTypes = 1; + medGeometryElement TypesPoly[NbOfTypes] = {MED_TETRA4}; + const int NbOfElements[NbOfTypes] = {1}; + + CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setNumberOfTypes(NbOfTypes, MED_CELL)); + + try + { + myMeshingPoly.setCoordinates(SpaceDimension, NumberOfNodes, CoordinatesPoly, + "CARTESIAN", MED_FULL_INTERLACE); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + myMeshingPoly.setSpaceDimension(SpaceDimension); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + myMeshingPoly.setMeshDimension(MeshDimension); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setTypes(TypesPoly, MED_CELL)); + CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setNumberOfElements(NbOfElements, MED_CELL)); + + string Unit ="cm"; + for(int i = 0; i < SpaceDimension; i++ ) + { + try + { + myMeshingPoly.setCoordinateName(Names[i],i); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + try + { + myMeshingPoly.setCoordinateUnit(Unit, i); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + } + + int ConnectivityTetraPoly[4*1]= + { + 17, 9, 18, 19 + }; + + CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setConnectivity(ConnectivityTetraPoly, MED_CELL, MED_TETRA4)); + + CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setPolyhedraConnectivity(REFpolyIndex, REFfacesIndex, + REFnodalConnOfFaces, NumberOfPolyhedron, MED_CELL)); + + bool PolyConn = false; + CPPUNIT_ASSERT_NO_THROW(PolyConn = myMeshingPoly.existPolyhedronConnectivity(MED_NODAL, MED_CELL)); + if(PolyConn) + { + CPPUNIT_ASSERT_EQUAL(myMeshingPoly.getNumberOfPolyhedron(),NumberOfPolyhedron); + CPPUNIT_ASSERT_EQUAL(myMeshingPoly.getNumberOfPolyhedronFaces(),NumberOfFaces); + CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.getPolyhedronConnectivityLength(MED_NODAL)); + const int * PolyConn; + const int * PolyFaceIdx; + const int * PolyIdx; + CPPUNIT_ASSERT_NO_THROW(PolyConn = myMeshingPoly.getPolyhedronConnectivity(MED_NODAL)); + CPPUNIT_ASSERT_NO_THROW(PolyFaceIdx = myMeshingPoly.getPolyhedronFacesIndex()); + CPPUNIT_ASSERT_NO_THROW(PolyIdx = myMeshingPoly.getPolyhedronIndex(MED_NODAL)); + for(int i = 0; i<NumberOfPolyhedron; i++) + { + int FaceIdxBegin = PolyIdx[i]; + int FaceIdxEnd = PolyIdx[i+1]; + for(int k = FaceIdxBegin; k < FaceIdxEnd; k++) + { + int IdxBegin = PolyFaceIdx[k-1]; + int IdxEnd = PolyFaceIdx[k]; + for(int j = IdxBegin; j < IdxEnd; j++ ) + CPPUNIT_ASSERT_EQUAL(PolyConn[j-1],REFnodalConnOfFaces[j-1]); + } + } + } + + MESHING myPolygonMeshing; + myPolygonMeshing.setName("PolygonMeshing"); + + medGeometryElement PolygonTypes[NbOfTypes] = {MED_TRIA3}; + const int PolygonNumberOfElements[NbOfTypes] = {2}; + + CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setNumberOfTypes(NbOfTypes, MED_CELL)); + + try + { + myPolygonMeshing.setCoordinates(SpaceDimension, NumberOfNodes, PolygonCoordinates, + "CARTESIAN", MED_FULL_INTERLACE); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + NumberOfNodes = 9; + SpaceDimension = 3; + MeshDimension = 2; + + myPolygonMeshing.setSpaceDimension(SpaceDimension); + CPPUNIT_ASSERT(myPolygonMeshing.getSpaceDimension() == 3); + myPolygonMeshing.setMeshDimension(MeshDimension); + CPPUNIT_ASSERT(myPolygonMeshing.getMeshDimension() == 2); + myPolygonMeshing.setNumberOfNodes(NumberOfNodes); + CPPUNIT_ASSERT(myPolygonMeshing.getNumberOfNodes() == 9); + CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setTypes(PolygonTypes, MED_CELL)); + CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setNumberOfElements(PolygonNumberOfElements, MED_CELL)); + CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setCoordinatesSystem("CARTESIAN")); + + try + { + myPolygonMeshing.setCoordinatesNames(Names); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + myPolygonMeshing.setCoordinatesUnits(Units); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + const int sizeTri = 3*2; + int ConnectivityTri[sizeTri]= + { + 1, 7, 2, 3, 9, 4 + }; + + CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setConnectivity(ConnectivityTri, MED_CELL, MED_TRIA3)); + CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setPolygonsConnectivity + (REFpolygonIndex, REFpolygonFaces, nbOfPolygons, MED_CELL)); + + bool PolygonConn = false; + CPPUNIT_ASSERT_NO_THROW(PolygonConn = myPolygonMeshing.existPolygonsConnectivity(MED_NODAL, MED_CELL)); + if(PolygonConn) + { + int Polytypes; + CPPUNIT_ASSERT_NO_THROW(Polytypes = myPolygonMeshing.getNumberOfTypesWithPoly(MED_CELL)); + CPPUNIT_ASSERT(NbOfTypes != Polytypes); + + const MED_EN::medGeometryElement * PolyTypes; + CPPUNIT_ASSERT_NO_THROW(PolyTypes = myPolygonMeshing.getTypesWithPoly(MED_CELL)); + CPPUNIT_ASSERT_EQUAL(PolyTypes[NbOfTypes],MED_POLYGON); + + for(int t = 0; t < Polytypes; t++) + { + CPPUNIT_ASSERT_NO_THROW( myPolygonMeshing.getNumberOfElementsWithPoly(MED_CELL, PolyTypes[t])); + } + + medGeometryElement geomPolyElem; + CPPUNIT_ASSERT_NO_THROW(geomPolyElem = myPolygonMeshing.getElementTypeWithPoly(MED_CELL, 1)); + CPPUNIT_ASSERT_EQUAL(geomPolyElem, MED_TRIA3); + + CPPUNIT_ASSERT_EQUAL(myPolygonMeshing.getNumberOfPolygons(),nbOfPolygons); + CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.getPolygonsConnectivityLength(MED_NODAL,MED_CELL)); + const int * PolygonConn; + const int * PolygonIdx; + CPPUNIT_ASSERT_THROW(PolygonConn = myMeshingPoly.getPolygonsConnectivity(MED_NODAL,MED_CELL),MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(PolygonIdx = myMeshingPoly.getPolygonsConnectivityIndex(MED_NODAL,MED_CELL),MEDEXCEPTION); + } + + ///////////////////////////////////////////////////// + // TEST : SUPPORT* sup = new SUPPORT(myMeshPointe) // + ///////////////////////////////////////////////////// + + //#ifdef ENABLE_FAULTS + { + MESH * myMeshPointe = new MESH(); + myMeshPointe->setName(meshname); + MED_MESH_RDONLY_DRIVER myMeshDriver (filename, myMeshPointe); + myMeshDriver.setMeshName(meshname); + myMeshDriver.open(); + myMeshDriver.read(); + myMeshDriver.close(); + + SUPPORT* sup = new SUPPORT(myMeshPointe); + delete sup; + delete myMeshPointe; + } + //#endif + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_FAIL("ERROR: can not create SUPPORT on mesh, read from pointe.med"); + //#endif + + //////////////////////////////////////////////////////// + // TEST 3: test MESH on MEDMEMTest::createTestMesh()// + /////////////////////////////////////////////////////// + + MESH* myMesh3 = MEDMEMTest_createTestMesh(); + + int MeshDim = myMesh3->getMeshDimension(); + medEntityMesh constituentEntity; + if (MeshDim==3) { + constituentEntity = MED_CELL; + } + if (MeshDim==2) { + constituentEntity = MED_FACE; + } + if (MeshDim==1) { + constituentEntity = MED_EDGE; + } + + int SpaceDim = myMesh3->getSpaceDimension(); + + // Show Reverse Nodal Connectivity + const int* ReverseNodalConnectivity; + const int* ReverseNodalConnectivityIndex; + int ReverseLength; + int ReverseIdxLength; + + CONNECTIVITY* myConnectivity3 = (CONNECTIVITY*)myMesh3->getConnectivityptr(); + myConnectivity3->setNumberOfNodes(myMesh3->getNumberOfNodes()); + + CPPUNIT_ASSERT_NO_THROW(ReverseNodalConnectivity= myMesh3->getReverseConnectivity(MED_NODAL, MED_CELL)); + CPPUNIT_ASSERT_NO_THROW(ReverseLength = myMesh3->getReverseConnectivityLength(MED_NODAL, MED_CELL)); + CPPUNIT_ASSERT_NO_THROW(ReverseNodalConnectivityIndex = myMesh3->getReverseConnectivityIndex(MED_NODAL, MED_CELL)); + CPPUNIT_ASSERT_NO_THROW(ReverseIdxLength = myMesh3->getReverseConnectivityIndexLength(MED_NODAL, MED_CELL)); + CPPUNIT_ASSERT(ReverseIdxLength == myMesh3->getNumberOfNodes()+1); + + for (int i = 0; i < myMesh3->getNumberOfNodes(); i++) { + cout << "Node "<< i+1 << " : "; + for (int j = ReverseNodalConnectivityIndex[i]; j < ReverseNodalConnectivityIndex[i+1]; j++) + cout << ReverseNodalConnectivity[j-1] << " "; + cout << endl; + } + + // Show Descending Connectivity + int NumberOfElements1; + const int * connectivity; + const int * connectivity_index; + myMesh3->calculateConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, MED_EN::MED_CELL); + try { + NumberOfElements1 = myMesh3->getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS); + connectivity = myMesh3->getConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, MED_CELL, MED_ALL_ELEMENTS); + connectivity_index = myMesh3->getConnectivityIndex(MED_DESCENDING, MED_CELL); + } + catch (MEDEXCEPTION m) { + CPPUNIT_FAIL(m.what()); + } + + for (int j = 0; j < NumberOfElements1; j++) { + cout << "Element " << j+1 << " : "; + for (int k = connectivity_index[j]; k < connectivity_index[j+1]; k++) + cout << connectivity[k-1] << " "; + cout << endl; + } + + //test 3D mesh + for(int ind = SpaceDim; ind > 1; ind-- ) + { + int NumberOfElem = myMesh3->getNumberOfElements (constituentEntity,MED_ALL_ELEMENTS); + if(NumberOfElem < 1) continue; + + SUPPORT * sup = (SUPPORT*) NULL; + sup = new SUPPORT(myMesh3,"",constituentEntity); + + if (ind == 2) + { + // test of normal(for 1d or 2d elements) + FIELD<double>* normal; + CPPUNIT_ASSERT_NO_THROW(normal = myMesh3->getNormal(sup)); + + double normal_square, norm; + double maxnorm=0.; + double minnorm=0.; + double tmp_value; + for (int i = 1; i<=NumberOfElem; i++) { + normal_square = 0.; + cout << "Normal " << i << " "; + for (int j=1; j<=SpaceDim; j++) { + tmp_value = normal->getValueIJ(i,j); + normal_square += tmp_value*tmp_value; + cout << tmp_value << " "; + } + norm = sqrt(normal_square); + maxnorm = dmax(maxnorm,norm); + minnorm = dmin(minnorm,norm); + cout << ", Norm = " << norm << endl; + } + cout << "Max Norm " << maxnorm << " Min Norm " << minnorm << endl; + delete normal; + + // test of area(for 2d elements) + FIELD<double>* area; + CPPUNIT_ASSERT_NO_THROW(area = myMesh3->getArea(sup)); + + double maxarea,minarea,areatot; + maxarea = 0.; + minarea = 0.; + areatot = 0.0; + for (int i = 1; i<=NumberOfElem;i++) + { + cout << "Area " << i << " " << area->getValueIJ(i,1) << endl; + maxarea = dmax(maxarea,area->getValueIJ(i,1)); + minarea = dmin(minarea,area->getValueIJ(i,1)); + areatot = areatot + area->getValueIJ(i,1); + } + + cout << "Max Area " << maxarea << " Min Area " << minarea << endl; + cout << "Support Area " << areatot << endl; + + delete area; + } + + // test of barycenter(for 3d and 2d elements) + FIELD<double>* barycenter; + CPPUNIT_ASSERT_NO_THROW(barycenter = myMesh3->getBarycenter(sup)); + + CPPUNIT_ASSERT_NO_THROW(NumberOfElem = myMesh3->getNumberOfElements(constituentEntity,MED_ALL_ELEMENTS)); + + for (int i = 1; i<=NumberOfElem;i++) + { + if (ind == 3) + cout << "Barycenter " << i << " " << barycenter->getValueIJ(i,1) << " " << barycenter->getValueIJ(i,2) << " " << barycenter->getValueIJ(i,3) << endl; + + if (ind == 2) + cout << "Barycenter " << i << " " << barycenter->getValueIJ(i,1) << " " << barycenter->getValueIJ(i,2) << endl; + } + delete barycenter; + + // test of volume(for 3d elements) + if (ind == 3) + { + FIELD<double>* volume; + CPPUNIT_ASSERT_NO_THROW(volume= myMesh3->getVolume(sup)); + + double maxvol,minvol,voltot; + maxvol = 0.; + minvol = 0.; + voltot = 0.0; + for (int i = 1; i<=NumberOfElem;i++) + { + cout << "Volume " << i << " " << volume->getValueIJ(i,1) << endl; + maxvol = dmax(maxvol,volume->getValueIJ(i,1)); + minvol = dmin(minvol,volume->getValueIJ(i,1)); + voltot = voltot + volume->getValueIJ(i,1); + } + + cout << "Max Volume " << maxvol << " Min Volume " << minvol << endl; + cout << "Support Volume " << voltot << endl; + + delete volume; + + // test of skin + SUPPORT *skin; + CPPUNIT_ASSERT_NO_THROW(skin = myMesh3->getSkin(sup)); + + //test mergeSupports and intersectSupports. vactor contains only 1 elements + vector<SUPPORT *> myVectSup; + myVectSup.push_back(skin); + + //method return a copy of skin object + SUPPORT *copyMergeSkin; + CPPUNIT_ASSERT_NO_THROW(copyMergeSkin = myMesh3->mergeSupports(myVectSup)); + try{ + CPPUNIT_ASSERT(copyMergeSkin->deepCompare(*skin)); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //method return a copy of skin object + SUPPORT *copyIntersectSkin; + CPPUNIT_ASSERT_NO_THROW(copyIntersectSkin = myMesh3->intersectSupports(myVectSup)); + try{ + CPPUNIT_ASSERT(copyIntersectSkin->deepCompare(*skin)); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + delete skin; + delete copyMergeSkin; + delete copyIntersectSkin; + } + + constituentEntity++; + } + + + // Testing length and normal vectors on 1d elements + { + // coordinates + int NumberOfNodes3 = 4; + + string Names3[3] = { "X","Y","Z" }; + string Units3[3] = { "cm","cm","cm" }; + + double Coordinates3[4*2] = {0.0, 0.0, // n1 + 1.0, 1.0, // n2 + 0.0, 1.0, // n3 + 1.0, 0.0}; // n4 + + const int NumberOfEdgeTypes = 1; + MED_EN::medGeometryElement EdgeTypes[NumberOfEdgeTypes] = {MED_SEG2}; + const int NumberOfEdges[NumberOfEdgeTypes] = {4}; + int ConnectivityEdge[4*2] = {1,2, 2,3, 3,4, 4,1}; + + // CREATE THE MESH + MEDMEM::MESHING* myMeshing3 = new MEDMEM::MESHING; + myMeshing3->setName("meshing3"); + myMeshing3->setCoordinates(/*SpaceDimension*/2, NumberOfNodes3, Coordinates3, + "CARTESIAN", MED_EN::MED_FULL_INTERLACE); + myMeshing3->setCoordinatesNames(Names3); + myMeshing3->setCoordinatesUnits(Units3); + + // define connectivities + // cell part + const int NumberOfTypes3 = 1; + medGeometryElement Types3[NumberOfTypes3] = {MED_QUAD4}; + const int NumberOfElements3[NumberOfTypes3] = {1}; + + myMeshing3->setNumberOfTypes(NumberOfTypes3,MED_CELL); + myMeshing3->setTypes(Types3,MED_CELL); + myMeshing3->setNumberOfElements(NumberOfElements3,MED_CELL); + + int Connectivityquad[1*4] = {1,2,3,4}; + + myMeshing3->setConnectivity(Connectivityquad,MED_CELL,MED_QUAD4); + + myMeshing3->setNumberOfTypes(NumberOfEdgeTypes, MED_EDGE); + myMeshing3->setTypes(EdgeTypes, MED_EDGE); + myMeshing3->setNumberOfElements(NumberOfEdges, MED_EDGE); + + myMeshing3->setConnectivity(ConnectivityEdge, MED_EDGE, MED_SEG2); + + // mesh dimension + myMeshing3->setMeshDimension(2); + + //test 2D mesh + int NumberOfElem = myMeshing3->getNumberOfElements (MED_EDGE, MED_ALL_ELEMENTS); + + SUPPORT * sup = new SUPPORT (myMeshing3, "", MED_EDGE); + + // test of normal(for 1d or 2d elements) + FIELD<double>* normal; + CPPUNIT_ASSERT_NO_THROW(normal = myMeshing3->getNormal(sup)); + + double normal_square, norm; + double maxnorm=0.; + double minnorm=0.; + double tmp_value; + for (int i = 1; i<=NumberOfElem; i++) { + normal_square = 0.; + cout << "Normal " << i << " "; + for (int j=1; j<=/*SpaceDimension*/2; j++) { + tmp_value = normal->getValueIJ(i,j); + normal_square += tmp_value*tmp_value; + cout << tmp_value << " "; + } + norm = sqrt(normal_square); + maxnorm = dmax(maxnorm,norm); + minnorm = dmin(minnorm,norm); + cout << ", Norm = " << norm << endl; + } + cout << "Max Norm " << maxnorm << " Min Norm " << minnorm << endl; + + // test of length(for 1d elements) + FIELD<double>* length; + CPPUNIT_ASSERT_NO_THROW(length = myMeshing3->getLength(sup)); + + double length_value,maxlength,minlength; + maxlength = 0; + minlength = 0; + for (int i = 1; i<=NumberOfElem;i++) { + length_value = length->getValueIJ(i,1); + cout << "Length " << i << " " << length_value << endl; + maxlength = dmax(maxlength,length_value); + minlength = dmin(minlength,length_value); + } + cout << "Max Length " << maxlength << " Min Length " << minlength << endl; + + vector< FIELD<double> *> myVectField1; + myVectField1.push_back(normal); + myVectField1.push_back(length); + CPPUNIT_ASSERT_NO_THROW(myMeshing3->mergeFields(myVectField1)); + + delete normal; + delete length; + delete sup; + + //#ifdef ENABLE_FAULTS + { + // (BUG) Segmentation fault if vector is empty + vector<SUPPORT *> myVectSupEmpty; + CPPUNIT_ASSERT_THROW(myMesh3->mergeSupports(myVectSupEmpty), MEDEXCEPTION); + } + //#endif + + // test mergeFields method: Fields have the same value type + //intersectSupports and mergeSupports methods + { + SUPPORT * sup1 = new SUPPORT (myMeshing3, "", MED_EDGE); + SUPPORT * sup2 = new SUPPORT (myMeshing3, "", MED_EDGE); + MED_EN::medGeometryElement gtEdges[1] = {MED_SEG2}; + int nbEdges1[1] = {1}; + int edges1[1] = {1}; + int nbEdges2[1] = {2}; + int edges2[2] = {2,3}; + sup1->setpartial("description 1", 1, 1, gtEdges, nbEdges1, edges1); + sup2->setpartial("description 1", 1, 2, gtEdges, nbEdges2, edges2); + + vector<SUPPORT *> myVectSup3; + myVectSup3.push_back(sup1); + myVectSup3.push_back(sup2); + //method return a MergeSup on the union of all SUPPORTs in Supports. + SUPPORT *MergeSup; + CPPUNIT_ASSERT_NO_THROW(MergeSup = myMesh3->mergeSupports(myVectSup3)); + cout << *MergeSup << endl; + delete MergeSup; + + //method return a intersection of all SUPPORTs in IntersectSup + SUPPORT *IntersectSup; + CPPUNIT_ASSERT_NO_THROW(IntersectSup = myMesh3->intersectSupports(myVectSup3)); + if (IntersectSup != NULL) cout<< *IntersectSup <<endl; + delete IntersectSup; + + FIELD<double> * length1 = myMeshing3->getLength(sup1); + FIELD<double> * length2 = myMeshing3->getLength(sup2); + + vector< FIELD<double> *> myVect12; + myVect12.push_back(length1); + myVect12.push_back(length2); + + FIELD<double> * length12; + CPPUNIT_ASSERT_NO_THROW(length12 = myMeshing3->mergeFields(myVect12)); + delete length12; + + delete sup1; + delete sup2; + delete length1; + delete length2; + } + } + + ///////////////////////////////////////////////////////// + // TEST 4: test MESH constructed from file pointe.med // + //////////////////////////////////////////////////////// + MESH * myMesh4 = new MESH(); + myMesh4->setName(meshname); + MED_MESH_RDONLY_DRIVER myMeshDriver (filename, myMesh4); + myMeshDriver.setMeshName(meshname); + + //Mesh has no driver->segmentation violation + //CPPUNIT_ASSERT_THROW(myMesh4->read(), MEDEXCEPTION); + + //Add an existing MESH driver. + int myDriver4; + CPPUNIT_ASSERT_NO_THROW(myDriver4 = myMesh4->addDriver(myMeshDriver)); + + //read all objects in the file + CPPUNIT_ASSERT_NO_THROW(myMesh4->read(myDriver4)); + + if (myMesh4->getIsAGrid()) { + GRID* myGrid = dynamic_cast<GRID*>(myMesh4); + CPPUNIT_ASSERT(myGrid); + } + + //myDriver4->DRONLY->can't write + CPPUNIT_ASSERT_THROW(myMesh4->write(myDriver4), MEDEXCEPTION); + + // add new driver + int idMeshV21; + CPPUNIT_ASSERT_NO_THROW(idMeshV21 = myMesh4->addDriver(MED_DRIVER,filenameout21)); + + //Write all the content of the MESH using driver referenced by the integer handler index. + CPPUNIT_ASSERT_NO_THROW(myMesh4->write(idMeshV21)); + + // remove driver from mesh + CPPUNIT_ASSERT_NO_THROW(myMesh4->rmDriver(myDriver4)); + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_FAIL("ERROR: driver with index idMedV21 has not been removed"); + //#endif + // ensure exception is raised on second attempt to remove driver + //CPPUNIT_ASSERT_THROW(myMesh4->rmDriver(myDriver4),MEDEXCEPTION); + + // Create a MESH object using a MESH driver of type MED_DRIVER associated with file fileName. + MESH* myMesh5; + CPPUNIT_ASSERT_NO_THROW(myMesh5 = new MESH(MED_DRIVER, filename, meshname)); + if(myMesh5->getIsAGrid()){ + GRID* myGrid = dynamic_cast<GRID*>(myMesh4); + CPPUNIT_ASSERT(myGrid); + } + + //ensure two meshes constracted from one file in two different ways are equal + CPPUNIT_ASSERT(myMesh5->deepCompare(*myMesh4)); + + int myDriver6; + MESH* myMesh6 = new MESH(); + try{ + myDriver6 = myMesh6->addDriver(MED_DRIVER, filename, meshname, RDONLY); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try{ + myMesh6->read(myDriver6); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //ensure two meshes constracted from one file in two different ways are equal + CPPUNIT_ASSERT(myMesh6->deepCompare(*myMesh4)); + + //test FAMILY + int NumberOfFamilies4; + CPPUNIT_ASSERT_NO_THROW(NumberOfFamilies4 = myMesh6->getNumberOfFamilies(MED_CELL)); + CPPUNIT_ASSERT_MESSAGE("Current mesh hasn't Families", NumberOfFamilies4 != 0); + + vector<FAMILY*> families4; + CPPUNIT_ASSERT_NO_THROW(families4 = myMesh6->getFamilies(MED_CELL)); + CPPUNIT_ASSERT(families4.size() == NumberOfFamilies4); + for(int nb = 1; nb <= NumberOfFamilies4; nb++ ) + { + const FAMILY* family; + CPPUNIT_ASSERT_NO_THROW(family = myMesh6->getFamily(MED_CELL, nb)); + CPPUNIT_ASSERT_EQUAL(family->getName(), families4[nb-1]->getName()); + } + + //get support which reference all elements on the boundary of mesh. + SUPPORT*myBndSup; + CPPUNIT_ASSERT_THROW(myMesh6->getBoundaryElements(MED_CELL), MEDEXCEPTION); + //get only face in 3D. + CPPUNIT_ASSERT_NO_THROW(myBndSup = myMesh6->getBoundaryElements(MED_FACE)); + + //test buildSupportOnElementsFromElementList and buildSupportOnNodeFromElementList + const int * myConnectivityValue6; + CPPUNIT_ASSERT_NO_THROW(myConnectivityValue6 = myMesh6->getReverseConnectivity(MED_DESCENDING)); + const int * myConnectivityIndex6; + CPPUNIT_ASSERT_NO_THROW(myConnectivityIndex6 = myMesh6->getReverseConnectivityIndex(MED_DESCENDING)); + int numberOfElem6; + CPPUNIT_ASSERT_NO_THROW(numberOfElem6 = myMesh6->getNumberOfElementsWithPoly(MED_FACE,MED_ALL_ELEMENTS)); + list<int> myElementsList6; + + for (int i=0; i<numberOfElem6; i++) + if (myConnectivityValue6[myConnectivityIndex6[i]] == 0) { + myElementsList6.push_back(i+1); + } + + SUPPORT * mySupportOnNode; + SUPPORT * mySupportOnElem; + CPPUNIT_ASSERT_NO_THROW(mySupportOnElem = myMesh6->buildSupportOnElementsFromElementList(myElementsList6,MED_FACE)); + CPPUNIT_ASSERT(mySupportOnElem->deepCompare(*myBndSup)); + CPPUNIT_ASSERT_EQUAL(MED_FACE, mySupportOnElem->getEntity()); + + list<int>::const_iterator iteronelem = myElementsList6.begin(); + for (int i = 1; i <= 3; i++, iteronelem++) { + CPPUNIT_ASSERT_EQUAL(i, mySupportOnElem->getValIndFromGlobalNumber(*iteronelem)); + } + + CPPUNIT_ASSERT_NO_THROW(mySupportOnNode = myMesh6->buildSupportOnNodeFromElementList(myElementsList6,MED_FACE)); + CPPUNIT_ASSERT(mySupportOnNode->deepCompare( *(myMesh6->getBoundaryElements(MED_NODE)))); + + //sets mesh fields to initial values + try{ + myMesh6->init(); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //ensure two meshes constracted from one file in two different ways are equal + CPPUNIT_ASSERT(!myMesh6->deepCompare(*myMesh4)); + + //ensure mesh is empty + CPPUNIT_ASSERT(myMesh6->getSpaceDimension() == MED_INVALID); + CPPUNIT_ASSERT(myMesh6->getNumberOfNodes() == MED_INVALID); + CPPUNIT_ASSERT(myMesh6->getCoordinateptr() == NULL); + + delete myMesh4; + delete myMesh5; + delete myMesh6; + + MESH* myMesh7 = MEDMEMTest_createTestMesh(); + vector< vector<double> > myBndBox; + try{ + myBndBox = myMesh7->getBoundingBox(); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + cout<<"Bounding box for createTestMesh()"<<endl; + for(int i = 0; i < myBndBox.size(); i++) + { + for(int j = 0; j < myBndBox[i].size(); j++) + cout<<" "<< myBndBox[i][j]<<" "; + cout<<endl; + } + + double CoorPoint[3] = {0.0, 0.0, 1.0}; //n2 + int idxElem; + try{ + idxElem = myMesh7->getElementContainingPoint(CoorPoint); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT(idxElem != -1); + + double CoorNoPoint[3] = {5.0, 0.0, -5.0}; //there is no such point + int idxNoElem; + try{ + idxNoElem = myMesh7->getElementContainingPoint(CoorNoPoint); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT(idxNoElem == -1); + + /////////////////////////////////////////////////////// + // TEST 5: test desactivateFacesComputation() method // + // of driver: NPAL17670 // + /////////////////////////////////////////////////////// + double coords[54] = { + -0.215040, -0.107520, +0.000000, + +0.000000, -0.107520, +0.000000, + +0.000000, +0.107520, +0.000000, + -0.215040, +0.107520, +0.000000, + +0.215040, -0.107520, +0.000000, + +0.215040, +0.107520, +0.000000, + -0.215040, -0.107520, +1.500000, + -0.215040, -0.107520, +4.080623, + +0.000000, -0.107520, +1.500000, + +0.000000, -0.107520, +4.080623, + +0.000000, +0.107520, +1.500000, + +0.000000, +0.107520, +4.080623, + -0.215040, +0.107520, +1.500000, + -0.215040, +0.107520, +4.080623, + +0.215040, -0.107520, +1.500000, + +0.215040, -0.107520, +4.080623, + +0.215040, +0.107520, +1.500000, + +0.215040, +0.107520, +4.080623 + }; + + int connQuad4[] = { + 2 , 5 , 15 , 9 , + 10, 16 , 18 , 12, + 11 , 13 , 14 , 12, + 7 , 9 , 11 , 13, + 3 , 4 , 13 , 11, + 1 , 2 , 9 , 7, + 1 , 2 , 3 , 4, + 15 , 17 , 18 , 16 , + 5 , 6 , 17 , 15, + 9 , 15 , 17 , 11 , + 13 , 7 , 8 , 14, + 4 , 1 , 7 , 13, + 9 , 11 , 12 , 10, + 8 , 10 , 12 , 14, + 2 , 5 , 6 , 3, + 17 , 11, 12 , 18 , + 2 , 3 , 11 , 9, + 6 , 3 , 11 , 17, + 7 , 9 , 10 , 8, + 9 , 15 , 16 , 10 + }; + + int connHexa8[] = { + 3 , 2 , 1 , 4 , 11 , 9 , 7 , 13, + 17 , 15 , 9 , 11 , 18 , 16 , 10 , 12, + 11 , 9 , 7 , 13 , 12 , 10 , 8 , 14 , + 6 , 5 , 2 , 3 , 17 , 15 , 9 , 11 + }; + + int bottom[2] = {7,15}; + MED_EN::medGeometryElement bottomTypes[1] = {MED_EN::MED_QUAD4}; + int bottomIndex[2] = {1,3}; + int bottomNbOfElts[1] = {2}; + + MESHING* meshing = new MESHING(); + meshing->setName( "TESTMESH" ); + meshing->setSpaceDimension(3); + const int nFaces=20; + const int nNodes=18; + meshing->setNumberOfNodes(nNodes); + meshing->setCoordinates(3, nNodes, coords, "CARTESIAN", + MED_EN::MED_FULL_INTERLACE); + string coordname[3] = { "x", "y", "z" }; + meshing->setCoordinatesNames(coordname); + string coordunit[3] = { "m", "m", "m" }; + meshing->setCoordinatesUnits(coordunit); + //Cell connectivity info for classical elts + const MED_EN::medGeometryElement classicalTypesCell[1]={MED_EN::MED_HEXA8}; + const int nbOfCellElts[1]={4}; + meshing->setNumberOfTypes(1,MED_EN::MED_CELL); + meshing->setTypes(classicalTypesCell,MED_EN::MED_CELL); + meshing->setNumberOfElements(nbOfCellElts,MED_EN::MED_CELL); + meshing->setMeshDimension(3); + //Face connectivity info for classical elts + const MED_EN::medGeometryElement classicalTypesFace[1]={MED_EN::MED_QUAD4}; + const int nbOfFaceElts[1]={nFaces}; + meshing->setNumberOfTypes(1,MED_EN::MED_FACE); + meshing->setTypes(classicalTypesFace,MED_EN::MED_FACE); + meshing->setNumberOfElements(nbOfFaceElts,MED_EN::MED_FACE); + //All cell conn + meshing->setConnectivity(connHexa8,MED_EN::MED_CELL,MED_EN::MED_HEXA8); + //All face conn + meshing->setConnectivity(connQuad4,MED_EN::MED_FACE,MED_EN::MED_QUAD4); + //Adding some groups on faces + addMedFacesGroup( *meshing, 4, bottom, "BottomFaces",bottomTypes,bottomIndex,bottomNbOfElts,1) ; + //addMedFacesGroupAll( *meshing, "AllFaces"); + //writing... + int id=meshing->addDriver(MED_DRIVER,"out.med",meshing->getName()); + meshing->write(id); + // Field writing + SUPPORT *sup=new SUPPORT(meshing,"AllFaces",MED_FACE); + FIELD<double> * field = new FIELD<double>(sup, 1); + field->setName("temperature"); + field->setComponentName(1,"T"); field->setMEDComponentUnit(1,"K"); + double *tab=(double *)field->getValue(); + for(int i=0;i<nFaces;i++) + tab[i]=i*(1.22); + field->setIterationNumber(0); + field->setOrderNumber(-1); + field->setTime(12.); + id=field->addDriver(MED_DRIVER,"out.med",field->getName()); + field->write(id); + delete field; + delete meshing; + // + MED medObj(MED_DRIVER,"out.med"); + MESH *mesh=medObj.getMesh("TESTMESH"); + MED_MESH_RDONLY_DRIVER22 *drv=new MED_MESH_RDONLY_DRIVER22("out.med",mesh); + drv->desactivateFacesComputation(); + int newDrv=mesh->addDriver(*drv); + delete drv; + mesh->read(newDrv); + FIELD<double> *f=(FIELD<double> *)medObj.getField("temperature",0,-1); + f->read(); + const int *conn=mesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,MED_FACE,MED_ALL_ELEMENTS); + for (int j = 0; j < nFaces; j++) { + for (int k = 0; k < 4; k++) { + cout << conn[4*j+k] << " "; + CPPUNIT_ASSERT_EQUAL(conn[4*j+k], connQuad4[4*j+k]); + } + cout << endl; + } + + ////////////////////////////////////////////////////////// + // TEST 6: Test Reading of a Field with given Mesh. // + // Group from the Mesh must be taken for Field Support. // + ////////////////////////////////////////////////////////// + { + // mesh creation + MESHING* mesh_prof = new MESHING(); + mesh_prof->setName("TESTMESH"); + mesh_prof->setSpaceDimension(3); + mesh_prof->setNumberOfNodes(nNodes); + mesh_prof->setCoordinates(3, nNodes, coords, "CARTESIAN", MED_EN::MED_FULL_INTERLACE); + mesh_prof->setCoordinatesNames(coordname); + mesh_prof->setCoordinatesUnits(coordunit); + + //Cell connectivity info for classical elts + //mesh_prof->setNumberOfTypes(1,MED_EN::MED_CELL); + //mesh_prof->setTypes(classicalTypesCell,MED_EN::MED_CELL); + //mesh_prof->setNumberOfElements(nbOfCellElts,MED_EN::MED_CELL); + //mesh_prof->setMeshDimension(3); + //mesh_prof->setConnectivity(connHexa8,MED_EN::MED_CELL,MED_EN::MED_HEXA8); + mesh_prof->setMeshDimension(2); + + //Face connectivity info for classical elts + //mesh_prof->setNumberOfTypes(1,MED_EN::MED_FACE); + //mesh_prof->setTypes(classicalTypesFace,MED_EN::MED_FACE); + //mesh_prof->setNumberOfElements(nbOfFaceElts,MED_EN::MED_FACE); + //mesh_prof->setConnectivity(connQuad4,MED_EN::MED_FACE,MED_EN::MED_QUAD4); + mesh_prof->setNumberOfTypes(1,MED_EN::MED_CELL); + mesh_prof->setTypes(classicalTypesFace,MED_EN::MED_CELL); + mesh_prof->setNumberOfElements(nbOfFaceElts,MED_EN::MED_CELL); + mesh_prof->setConnectivity(connQuad4,MED_EN::MED_CELL,MED_EN::MED_QUAD4); + + //Adding some groups on faces + GROUP faces_prof; + faces_prof.setName("BottomFaces"); + faces_prof.setMesh(mesh_prof); + //faces_prof.setEntity(MED_EN::MED_FACE); + faces_prof.setEntity(MED_EN::MED_CELL); + faces_prof.setNumberOfGeometricType(1); + faces_prof.setGeometricType(bottomTypes); + faces_prof.setNumberOfElements(bottomNbOfElts); + faces_prof.setNumber(bottomIndex, bottom); + mesh_prof->addGroup(faces_prof); + + // Field creation + FIELD<double> * field_prof = new FIELD<double>(&faces_prof, 1); + field_prof->setName("temperature"); + field_prof->setComponentName(1,"T"); + field_prof->setMEDComponentUnit(1,"K"); + double *tab = (double *)field_prof->getValue(); + for (int i = 0; i < 2; i++) + tab[i] = i*(1.22); + field_prof->setTime(12.); + + // Writing... + int id_prof = mesh_prof->addDriver(MED_DRIVER, filename_profiles_wr, mesh_prof->getName()); + mesh_prof->write(id_prof); + mesh_prof->rmDriver(id_prof); + + // Field writing + id_prof = field_prof->addDriver(MED_DRIVER, filename_profiles_wr, field_prof->getName()); + field_prof->write(id_prof); + + delete field_prof; + delete mesh_prof; + + // Reading... + MESH mesh_rd (MED_DRIVER, filename_profiles_wr, "TESTMESH"); + FIELD<double> field_rd (MED_DRIVER, filename_profiles_wr, "temperature", -1, -1, &mesh_rd); + //const vector <GROUP*> groups_rd = mesh_rd.getGroups(MED_EN::MED_FACE); + const vector <GROUP*> groups_rd = mesh_rd.getGroups(MED_EN::MED_CELL); + CPPUNIT_ASSERT(find(groups_rd.begin(),groups_rd.end(),field_rd.getSupport()) != groups_rd.end()); + } +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_MeshAndMeshing_fault.cxx b/src/MEDMEMCppTest/MEDMEMTest_MeshAndMeshing_fault.cxx new file mode 100644 index 000000000..07a3c86a3 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_MeshAndMeshing_fault.cxx @@ -0,0 +1,1695 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/Message.h> +#include <cppunit/TestAssert.h> +#include "MEDMEM_Meshing.hxx" +#include "MEDMEM_Group.hxx" +#include "MEDMEM_define.hxx" +#include "MEDMEM_MedMeshDriver.hxx" +#include "MEDMEM_Field.hxx" +#include "MEDMEM_Grid.hxx" + +#include <sstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +double dmax(double x, double y) { return (x>y)?x:y;} + +double dmin(double x, double y) { return (x>y)?y:x;} + +/*! + * Check methods (18), defined in MEDMEM_Meshing.hxx: + * class MESHING: public MESH { + * (+) MESHING(); + * (+) ~MESHING(); + * (+) void setSpaceDimension (const int SpaceDimension); + * (+) void setMeshDimension (const int MeshDimension); + * (+) void setNumberOfNodes (const int NumberOfNodes); + * (+) void setCoordinates (const int SpaceDimension, const int NumberOfNodes, + * const double * Coordinates, + * const string System, const MED_EN::medModeSwitch Mode); + * (+) void setCoordinatesSystem(const string System) throw (MEDEXCEPTION); + * (+) void setCoordinatesNames (const string * names); + * (+) void setCoordinateName (const string name, const int i); + * (+) void setCoordinatesUnits (const string * units); + * (+) void setCoordinateUnit (const string unit, const int i); + * (+) void setNumberOfTypes (const int NumberOfTypes, + * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); + * (+) void setTypes (const MED_EN::medGeometryElement * Types, + * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); + * (+) void setNumberOfElements (const int * NumberOfElements, + * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); + * (+) void setConnectivity (const int * Connectivity, const MED_EN::medEntityMesh Entity, + * const MED_EN::medGeometryElement Type) throw (MEDEXCEPTION); + * (+) void setPolygonsConnectivity (const int * ConnectivityIndex, const int * ConnectivityValue, + * int nbOfPolygons, + * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); + * (+) void setPolyhedraConnectivity (const int * PolyhedronIndex, const int * FacesIndex, + * const int * Nodes, int nbOfPolyhedra, + * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); + * (NOT YET IMPLEMENTED!!!) void setConnectivities (const int * ConnectivityIndex, + * const int * ConnectivityValue, + * const MED_EN::medConnectivity ConnectivityType, + * const MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); + * (+) void addGroup (const GROUP & Group) throw (MEDEXCEPTION); + * } + */ + +/*! + * Check methods (87), defined in MEDMEM_Mesh.hxx: + * class MESH : public RCBASE { + * (+) void init(); + * (+) MESH(); + * (+) MESH(MESH &m); + * (+) MESH & operator=(const MESH &m); + * (+) virtual bool operator==(const MESH& other) const; + * (+) virtual bool deepCompare(const MESH& other) const; + * (+) MESH(driverTypes driverType, const string & fileName="", + * const string & meshName="") throw (MEDEXCEPTION); + * (+) virtual ~MESH(); + * (+) friend ostream & operator<<(ostream &os, const MESH &my); + * (+) int addDriver(driverTypes driverType, + * const string & fileName="Default File Name.med", + * const string & driverName="Default Mesh Name", + * MED_EN::med_mode_acces access=MED_EN::MED_REMP); + * (+) int addDriver(GENDRIVER & driver); + * (+) void rmDriver(int index=0); + * (+) virtual void read(int index=0); + * (must be private) inline void read(const GENDRIVER & genDriver); + * (+) inline void write(int index=0, const string & driverName = ""); + * (must be private) inline void write(const GENDRIVER & genDriver); + * (+) inline void setName(string name); + * (+) inline void setDescription(string description); + * (+) inline string getName() const; + * (+) inline string getDescription() const; + * (+) inline int getSpaceDimension() const; + * (+) inline int getMeshDimension() const; + * (+) inline bool getIsAGrid(); + * (+) inline int getNumberOfNodes() const; + * (+) virtual inline const COORDINATE * getCoordinateptr() const; + * (+) inline string getCoordinatesSystem() const; + * (+) virtual inline const double * getCoordinates(MED_EN::medModeSwitch Mode) const; + * (+) virtual inline const double getCoordinate(int Number,int Axis) const; + * (+) inline const string * getCoordinatesNames() const; + * (+) inline const string * getCoordinatesUnits() const; + * (+) virtual inline int getNumberOfTypes(MED_EN::medEntityMesh Entity) const; + * (+) virtual int getNumberOfTypesWithPoly(MED_EN::medEntityMesh Entity) const; + * (+) virtual inline const MED_EN::medGeometryElement * getTypes(MED_EN::medEntityMesh Entity) const; + * (+) virtual MED_EN::medGeometryElement * getTypesWithPoly(MED_EN::medEntityMesh Entity) const; + * (+) virtual inline const CELLMODEL * getCellsTypes(MED_EN::medEntityMesh Entity) const; + * (+) virtual inline string * getCellTypeNames(MED_EN::medEntityMesh Entity) const; + * (+) virtual const int * getGlobalNumberingIndex(MED_EN::medEntityMesh Entity) const; + * (+) virtual inline int getNumberOfElements(MED_EN::medEntityMesh Entity, + * MED_EN::medGeometryElement Type) const; + * (+) virtual int getNumberOfElementsWithPoly(MED_EN::medEntityMesh Entity, + * MED_EN::medGeometryElement Type) const; + * (+) virtual inline bool existConnectivity(MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity) const; + * (+) inline bool existPolygonsConnectivity(MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity) const; + * (+) inline bool existPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity) const; + * (+) virtual inline MED_EN::medGeometryElement getElementType + * (MED_EN::medEntityMesh Entity, int Number) const; + * (+) virtual inline MED_EN::medGeometryElement getElementTypeWithPoly + * (MED_EN::medEntityMesh Entity, int Number) const; + * (+) virtual inline void calculateConnectivity(MED_EN::medModeSwitch Mode, + * MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity) const; + * (+) virtual inline int getConnectivityLength(MED_EN::medModeSwitch Mode, + * MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity, + * MED_EN::medGeometryElement Type) const; + * (+) virtual inline const int * getConnectivity(MED_EN::medModeSwitch Mode, + * MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity, + * MED_EN::medGeometryElement Type) const; + * (+) virtual inline const int * getConnectivityIndex + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; + * (+) inline int getPolygonsConnectivityLength + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; + * (+) inline const int * getPolygonsConnectivity + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; + * (+) inline const int * getPolygonsConnectivityIndex + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity) const; + * (+) inline int getNumberOfPolygons(MED_EN::medEntityMesh Entity=MED_EN::MED_ALL_ENTITIES) const; + * (+) inline int getPolyhedronConnectivityLength(MED_EN::medConnectivity ConnectivityType) const; + * (+) inline const int * getPolyhedronConnectivity(MED_EN::medConnectivity ConnectivityType) const; + * (+) inline const int * getPolyhedronFacesIndex() const; + * (+) inline const int * getPolyhedronIndex(MED_EN::medConnectivity ConnectivityType) const; + * (+) inline int getNumberOfPolyhedronFaces() const; + * (+) inline int getNumberOfPolyhedron() const; + * (+) virtual int getElementNumber(MED_EN::medConnectivity ConnectivityType, + * MED_EN::medEntityMesh Entity, MED_EN::medGeometryElement Type, + * int * connectivity) const; + * (+) virtual inline int getReverseConnectivityLength + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; + * (+) virtual inline const int * getReverseConnectivity + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; + * (+) virtual inline int getReverseConnectivityIndexLength + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; + * (+) virtual inline const int * getReverseConnectivityIndex + * (MED_EN::medConnectivity ConnectivityType, MED_EN::medEntityMesh Entity=MED_EN::MED_CELL) const; + * (+) virtual int getNumberOfFamilies(MED_EN::medEntityMesh Entity) const; + * (+) virtual inline const vector<FAMILY*> getFamilies(MED_EN::medEntityMesh Entity) const; + * (+) virtual inline const FAMILY* getFamily(MED_EN::medEntityMesh Entity,int i) const; + * (+) virtual int getNumberOfGroups(MED_EN::medEntityMesh Entity) const; + * (+) virtual inline const vector<GROUP*> getGroups(MED_EN::medEntityMesh Entity) const; + * (+) virtual inline const GROUP* getGroup(MED_EN::medEntityMesh Entity,int i) const; + * (+) virtual inline const CONNECTIVITY* getConnectivityptr() const; + * (+) virtual SUPPORT * getBoundaryElements(MED_EN::medEntityMesh Entity) throw (MEDEXCEPTION); + * (+) SUPPORT * getSkin(const SUPPORT * Support3D) throw (MEDEXCEPTION); + * (+) virtual FIELD<double>* getVolume (const SUPPORT * Support) const throw (MEDEXCEPTION); + * (+) virtual FIELD<double>* getArea (const SUPPORT * Support) const throw (MEDEXCEPTION); + * (+) virtual FIELD<double>* getLength (const SUPPORT * Support) const throw (MEDEXCEPTION); + * (+) virtual FIELD<double>* getNormal (const SUPPORT * Support) const throw (MEDEXCEPTION); + * (+) virtual FIELD<double>* getBarycenter (const SUPPORT * Support) const throw (MEDEXCEPTION); + * (+) static SUPPORT * mergeSupports(const vector<SUPPORT *> Supports) throw (MEDEXCEPTION); + * (+) static SUPPORT * intersectSupports(const vector<SUPPORT *> Supports) throw (MEDEXCEPTION); + * (+) void createFamilies(); + * (+) SUPPORT *buildSupportOnNodeFromElementList + * (const list<int>& listOfElt, MED_EN::medEntityMesh entity) const throw (MEDEXCEPTION); + * (do the same thing as buildSupportOnNodeFromElementList except that a SUPPORT is not created) void fillSupportOnNodeFromElementList + * (const list<int>& listOfElt, SUPPORT *supportToFill) const throw (MEDEXCEPTION); + * (+) SUPPORT *buildSupportOnElementsFromElementList + * (const list<int>& listOfElt, MED_EN::medEntityMesh entity) const throw (MEDEXCEPTION); + * (+) int getElementContainingPoint(const double *coord); + * (+) vector< vector<double> > getBoundingBox() const; + * (+) template<class T> static + * FIELD<T> * mergeFields(const vector< FIELD<T> * > & others, bool meshCompare=false); + * (Presently disconnected in C++) virtual void addReference() const; + * (Presently disconnected in C++) virtual void removeReference() const; + * } + */ +void MEDMEMTest_testMeshAndMeshing() +{ + string datadir = getenv("MED_ROOT_DIR"); + string filename = datadir + "/share/salome/resources/med/pointe.med"; + string meshname = "maa1"; + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if (tmp_dir == "") + tmp_dir = "/tmp"; + string filenameout21 = tmp_dir + "/myMeshWrite4_pointe21.med"; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filenameout21); + + //////////// + // TEST 1 // + //////////// + + MESH * myMesh= new MESH(); + myMesh->setName("FIRST_MESH"); + CPPUNIT_ASSERT(myMesh != NULL); + + //test operator << + //#ifdef ENABLE_FAULTS + //CPPUNIT_ASSERT_NO_THROW(cout << *myMesh << endl); + //#endif +//#ifdef ENABLE_FORCED_FAILURES +// CPPUNIT_FAIL("ERROR: operator << : if mesh is empty then attempt" +// " to get values from null object causes error"); +//#endif + + //test operator = + MESH myMesh1 = *myMesh; + + //deepCompare +//#ifdef ENABLE_FAULTS + bool isEqual = false; + CPPUNIT_ASSERT_NO_THROW(isEqual = myMesh1.deepCompare(*myMesh)); + CPPUNIT_ASSERT(isEqual); +//#endif +//#ifdef ENABLE_FORCED_FAILURES +// CPPUNIT_FAIL("ERROR: deepCompare(...) fails if mesh is empty"); +//#endif + + //ensure it imposible to compare meshes + MESH *myMeshPointer = myMesh; + //test operator == + CPPUNIT_ASSERT(*myMeshPointer == *myMesh); + + delete myMesh; + + //set a MESH object + MESHING myMeshing; + myMeshing.setName("meshing"); + // define coordinates + + int SpaceDimension = 3; + int NumberOfNodes = 19; + double Coordinates[57] = { + 0.0, 0.0, 0.0, + 0.0, 0.0, 1.0, + 2.0, 0.0, 1.0, + 0.0, 2.0, 1.0, + -2.0, 0.0, 1.0, + 0.0, -2.0, 1.0, + 1.0, 1.0, 2.0, + -1.0, 1.0, 2.0, + -1.0, -1.0, 2.0, + 1.0, -1.0, 2.0, + 1.0, 1.0, 3.0, + -1.0, 1.0, 3.0, + -1.0, -1.0, 3.0, + 1.0, -1.0, 3.0, + 1.0, 1.0, 4.0, + -1.0, 1.0, 4.0, + -1.0, -1.0, 4.0, + 1.0, -1.0, 4.0, + 0.0, 0.0, 5.0 + }; + try + { + myMeshing.setCoordinates(SpaceDimension,NumberOfNodes,Coordinates,"CARTESIAN",MED_FULL_INTERLACE); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + string Names[3] = { "X","Y","Z" }; + try + { + myMeshing.setCoordinatesNames(Names); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + string Units[3] = { "cm","cm","cm" }; + try + { + myMeshing.setCoordinatesUnits(Units); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + // define conectivities + + // cell part + + const int NumberOfTypes = 3; + medGeometryElement Types[NumberOfTypes] = {MED_TETRA4,MED_PYRA5,MED_HEXA8}; + const int NumberOfElements[NumberOfTypes] = {12,2,2}; + + CPPUNIT_ASSERT_NO_THROW(myMeshing.setNumberOfTypes(NumberOfTypes,MED_CELL)); + + CPPUNIT_ASSERT_NO_THROW(myMeshing.setTypes(Types,MED_CELL)); + + CPPUNIT_ASSERT_NO_THROW(myMeshing.setNumberOfElements(NumberOfElements,MED_CELL)); + + const int sizeTetra = 12*4; + int ConnectivityTetra[sizeTetra]= + { + 1,2,3,6, + 1,2,4,3, + 1,2,5,4, + 1,2,6,5, + 2,7,4,3, + 2,8,5,4, + 2,9,6,5, + 2,10,3,6, + 2,7,3,10, + 2,8,4,7, + 2,9,5,8, + 2,10,6,9 + }; + + CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityTetra,MED_CELL,MED_TETRA4)); + + int ConnectivityPyra[2*5]= + { + 7,8,9,10,2, + 15,18,17,16,19 + }; + + CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityPyra,MED_CELL,MED_PYRA5)); + + int ConnectivityHexa[2*8]= + { + 11,12,13,14,7,8,9,10, + 15,16,17,18,11,12,13,14 + }; + + CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityHexa,MED_CELL,MED_HEXA8)); + + // face part + const int NumberOfFacesTypes = 2; + medGeometryElement FacesTypes[NumberOfFacesTypes] = {MED_TRIA3,MED_QUAD4}; + const int NumberOfFacesElements[NumberOfFacesTypes] = {4,4}; + + CPPUNIT_ASSERT_NO_THROW(myMeshing.setNumberOfTypes(NumberOfFacesTypes,MED_FACE)); + CPPUNIT_ASSERT_NO_THROW(myMeshing.setTypes(FacesTypes,MED_FACE)); + CPPUNIT_ASSERT_NO_THROW(myMeshing.setNumberOfElements(NumberOfFacesElements,MED_FACE)); + const int nbTria = 4; + const int sizeTria = nbTria*3; + int ConnectivityTria[sizeTria]= + { + 1,4,3, + 1,5,4, + 1,6,5, + 1,3,6 + }; + + CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityTria,MED_FACE,MED_TRIA3)); + const int nbQua = 4; + int ConnectivityQua[nbQua*4]= + { + 7,8,9,10, + 11,12,13,14, + 11,7,8,12, + 12,8,9,13 + }; + + CPPUNIT_ASSERT_NO_THROW(myMeshing.setConnectivity(ConnectivityQua,MED_FACE,MED_QUAD4)); + + int meshDimension = SpaceDimension; // because there 3D cells in the mesh + try + { + myMeshing.setMeshDimension(meshDimension); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + // edge part + + // not yet implemented : if set, results are unpredictable. + + // Some groups : + + // Node : + { + GROUP myGroup; + myGroup.setName("SomeNodes"); + myGroup.setMesh(&myMeshing); + myGroup.setEntity(MED_NODE); + myGroup.setNumberOfGeometricType(1); + medGeometryElement myTypes[1] = {MED_NONE}; + myGroup.setGeometricType(myTypes); + const int myNumberOfElements[1] = {4}; + myGroup.setNumberOfElements(myNumberOfElements); + const int index[1+1] = {1,5}; + const int value[4]= { 1,4,5,7}; + myGroup.setNumber(index,value); + CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); + } + { + GROUP myGroup; + myGroup.setName("OtherNodes"); + myGroup.setMesh(&myMeshing); + myGroup.setEntity(MED_NODE); + myGroup.setNumberOfGeometricType(1); + medGeometryElement myTypes[1] = {MED_NONE}; + myGroup.setGeometricType(myTypes); + const int myNumberOfElements[1] = {3}; + myGroup.setNumberOfElements(myNumberOfElements); + const int index[1+1] = {1,4}; + const int value[3]= { 2,3,6}; + myGroup.setNumber(index,value); + CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); + } + + // Cell : + { + GROUP myGroup; + myGroup.setName("SomeCells"); + myGroup.setMesh(&myMeshing); + myGroup.setEntity(MED_CELL); + myGroup.setNumberOfGeometricType(3); + medGeometryElement myTypes[3] = {MED_TETRA4,MED_PYRA5,MED_HEXA8}; + myGroup.setGeometricType(myTypes); + const int myNumberOfElements[3] = {4,1,2}; + myGroup.setNumberOfElements(myNumberOfElements); + const int index[3+1] = {1,5,6,8}; + const int value[4+1+2]= + { + 2,7,8,12, + 13, + 15,16 + }; + myGroup.setNumber(index,value); + CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); + } + { + GROUP myGroup; + myGroup.setName("OtherCells"); + myGroup.setMesh(&myMeshing); + myGroup.setEntity(MED_CELL); + myGroup.setNumberOfGeometricType(2); + medGeometryElement myTypes[] = {MED_TETRA4,MED_PYRA5}; + myGroup.setGeometricType(myTypes); + const int myNumberOfElements[] = {4,1}; + myGroup.setNumberOfElements(myNumberOfElements); + const int index[2+1] = {1,5,6}; + const int value[4+1]= + { + 3,4,5,9, + 14 + }; + myGroup.setNumber(index,value); + CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); + } + + // Face : + { + GROUP myGroup; + myGroup.setName("SomeFaces"); + myGroup.setMesh(&myMeshing); + myGroup.setEntity(MED_FACE); + myGroup.setNumberOfGeometricType(2); + medGeometryElement myTypes[2] = {MED_TRIA3,MED_QUAD4}; + myGroup.setGeometricType(myTypes); + const int myNumberOfElements[2] = {2,3}; + myGroup.setNumberOfElements(myNumberOfElements); + const int index[2+1] = {1,3,6}; + const int value[2+3]= + { + 2,4, + 5,6,8 + }; + myGroup.setNumber(index,value); + CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); + } + { + GROUP myGroup; + myGroup.setName("OtherFaces"); + myGroup.setMesh(&myMeshing); + myGroup.setEntity(MED_FACE); + myGroup.setNumberOfGeometricType(1); + medGeometryElement myTypes[1] = {MED_TRIA3}; + myGroup.setGeometricType(myTypes); + const int myNumberOfElements[1] = {2}; + myGroup.setNumberOfElements(myNumberOfElements); + const int index[1+1] = {1,3}; + const int value[2]= + { + 1,3 + }; + myGroup.setNumber(index,value); + CPPUNIT_ASSERT_NO_THROW(myMeshing.addGroup(myGroup)); + } + + //test Mesh(MESH &m) + { + MESH * myMesh2 = new MESH( myMeshing ); + CPPUNIT_ASSERT(myMesh2->deepCompare(myMeshing)); + + cout<<*myMesh2<<endl; + ostringstream os; + os << * myMesh2; + CPPUNIT_ASSERT(os.str() != ""); + + CPPUNIT_ASSERT_EQUAL(myMesh2->getName(),(string)"meshing"); + CPPUNIT_ASSERT((myMesh2->getDescription()).size() == 0); + myMesh2->setDescription("This class contains all information related to a 'meshing' mesh "); + CPPUNIT_ASSERT((myMesh2->getDescription()).size() != 0); + + CPPUNIT_ASSERT(myMesh2->getSpaceDimension() == SpaceDimension); + CPPUNIT_ASSERT(myMesh2->getMeshDimension() == meshDimension); + CPPUNIT_ASSERT(myMesh2->getNumberOfNodes() == NumberOfNodes); + + const COORDINATE* coord = myMesh2->getCoordinateptr(); + try + { + CPPUNIT_ASSERT(myMesh2->getCoordinatesSystem() != "catresian"); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + const string * units; + try + { + units = myMesh2->getCoordinatesUnits(); + for (int axe = 0; axe < SpaceDimension; axe++) { + string verif = coord->getCoordinateUnit(axe+1); + CPPUNIT_ASSERT(verif == units[axe]); + } + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + const string * noms; + try + { + noms = myMesh2->getCoordinatesNames(); + for (int axe = 0; axe < SpaceDimension; axe++) { + string verif = coord->getCoordinateName(axe+1); + CPPUNIT_ASSERT(verif == noms[axe]); + } + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + const double * coor2 = myMesh2->getCoordinates(MED_FULL_INTERLACE); + + for (int axe = 0; axe < SpaceDimension; axe++) { + try + { + for (int num = 0; num < NumberOfNodes; num++) { + try + { + const double d = myMesh2->getCoordinate(num + 1, axe + 1); + CPPUNIT_ASSERT(fabs(d - coor2[(num * SpaceDimension)+axe]) < 0.001); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + } + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + } + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + const CONNECTIVITY * myConnectivity = myMesh2->getConnectivityptr(); + + // MED_EN::MED_CELL + MED_EN::medEntityMesh entity = myConnectivity->getEntity(); + CPPUNIT_ASSERT_EQUAL(MED_CELL, entity); + + int typesNb; + CPPUNIT_ASSERT_NO_THROW(typesNb= myConnectivity->getNumberOfTypes(entity)); + CPPUNIT_ASSERT_EQUAL(NumberOfTypes, typesNb); + + const MED_EN::medGeometryElement * Types1; + CPPUNIT_ASSERT_NO_THROW(Types1 = myMesh2->getTypes(entity)); + + medConnectivity myMedConnect; + bool existConnect = false; + if (myMesh2->existConnectivity(MED_NODAL, entity)) + { + existConnect = true; + myMedConnect = MED_NODAL; + } + else if(myMesh2->existConnectivity(MED_DESCENDING, entity)) + { + existConnect = true; + myMedConnect = MED_DESCENDING; + } + + for(int t = 0; t < NumberOfTypes; t++ ) + { + CPPUNIT_ASSERT_EQUAL(Types1[t], Types[t]); + int NumberOfElements1 = 0; + CPPUNIT_ASSERT_NO_THROW(NumberOfElements1 = myMesh2->getNumberOfElements(entity, Types1[t])); + CPPUNIT_ASSERT_EQUAL(NumberOfElements1, NumberOfElements[t]); + if(existConnect) + { + const int * connectivity; + const int * connectivity_index; + CPPUNIT_ASSERT_NO_THROW(connectivity = myMesh2->getConnectivity + (MED_FULL_INTERLACE, myMedConnect, entity, Types1[t])); + connectivity_index = myMesh2->getConnectivityIndex(myMedConnect, entity); + for (int j = 0; j < NumberOfElements1; j++) { + cout<<"!!!!!!!!!!!!!!!"<<endl; + for (int k = connectivity_index[j]; k < connectivity_index[j+1]; k++) + cout << connectivity[k-1] << " "; + cout << endl; + } + } + } + + const CELLMODEL* myCellModel = myMesh2->getCellsTypes(entity); + string* TypeNames; + CPPUNIT_ASSERT_NO_THROW(TypeNames = myMesh2->getCellTypeNames(entity)); + + for(int k = 0; k < NumberOfTypes; k++ ) + { + CPPUNIT_ASSERT_EQUAL(TypeNames[k], myCellModel[k].getName()); + } + delete [] TypeNames; + + const int* myGlobalNbIdx; + CPPUNIT_ASSERT_NO_THROW(myGlobalNbIdx = myMesh2->getGlobalNumberingIndex(MED_FACE)); + for(int i = 0; i <= NumberOfFacesTypes; i++) + { + if(i == NumberOfFacesTypes) + { + CPPUNIT_ASSERT_EQUAL(myGlobalNbIdx[i],nbTria+nbQua+1); + CPPUNIT_ASSERT_THROW(myMesh2->getElementType(MED_FACE, myGlobalNbIdx[i]), MEDEXCEPTION); + break; + } + cout<<"Global number of first element of each geom type : "<<myGlobalNbIdx[i]<<endl; + } + + { + const int * ReverseNodalConnectivity; + + // Show Reverse Nodal Connectivity +//#ifndef ENABLE_FAULTS + // (BUG) CONNECTIVITY::_numberOfNodes is not set + ((CONNECTIVITY*)myConnectivity)->setNumberOfNodes(NumberOfNodes); +//#endif +//#ifdef ENABLE_FORCED_FAILURES +// CPPUNIT_FAIL("ERROR in CONNECTIVITY::calculateReverseNodalConnectivity()" +// " because myMesh2->_connectivity->_numberOfNodes is not set"); +//#endif + + CPPUNIT_ASSERT_NO_THROW(ReverseNodalConnectivity = myMesh2->getReverseConnectivity(MED_NODAL, entity)); + CPPUNIT_ASSERT_NO_THROW(myMesh2->getReverseConnectivityLength(MED_NODAL, entity)); + const int * ReverseNodalConnectivityIndex = myMesh2->getReverseConnectivityIndex(MED_NODAL, entity); + const int ReverseIdxLength = myMesh2->getReverseConnectivityIndexLength(MED_NODAL, entity); + CPPUNIT_ASSERT(ReverseIdxLength == NumberOfNodes+1); + for (int i = 0; i < NumberOfNodes; i++) { + cout << "Node "<< i+1 << " : "; + for (int j = ReverseNodalConnectivityIndex[i]; j < ReverseNodalConnectivityIndex[i+1]; j++) + cout << ReverseNodalConnectivity[j-1] << " "; + cout << endl; + } + + // Show Descending Connectivity + int NumberOfElements1; + const int * connectivity; + const int * connectivity_index; + myMesh2->calculateConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, entity); + try { + NumberOfElements1 = myMesh2->getNumberOfElements(entity, MED_ALL_ELEMENTS); + connectivity = myMesh2->getConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, entity, MED_ALL_ELEMENTS); + connectivity_index = myMesh2->getConnectivityIndex(MED_DESCENDING, entity); + } + catch (MEDEXCEPTION m) { + CPPUNIT_FAIL(m.what()); + } + + for (int j = 0; j < NumberOfElements1; j++) { + cout << "Element " << j+1 << " : "; + for (int k = connectivity_index[j]; k < connectivity_index[j+1]; k++) + cout << connectivity[k-1] << " "; + cout << endl; + } + + // getElementNumber + if (myMesh2->existConnectivity(MED_NODAL, MED_FACE)) { + int myTr[3] = {1,5,4}; + CPPUNIT_ASSERT_NO_THROW(myMesh2->getElementNumber(MED_NODAL,MED_FACE,MED_TRIA3,myTr)); + } + } + + //test family and group + int NumberOfGroups; + CPPUNIT_ASSERT_THROW(myMesh2->getNumberOfGroups(MED_ALL_ENTITIES), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(NumberOfGroups = myMesh2->getNumberOfGroups(MED_CELL)); + CPPUNIT_ASSERT_EQUAL(NumberOfGroups, 2); + vector<GROUP*> groups; + CPPUNIT_ASSERT_NO_THROW(groups = myMesh2->getGroups(MED_CELL)); + CPPUNIT_ASSERT(groups.size() != 0); + for(int nb = 1; nb <= NumberOfGroups; nb++ ) + { + const GROUP* group; + CPPUNIT_ASSERT_NO_THROW(group = myMesh2->getGroup(MED_CELL, nb)); + CPPUNIT_ASSERT_EQUAL(group->getName(), groups[nb-1]->getName()); + } + + int NumberOfFamilies; + CPPUNIT_ASSERT_NO_THROW(NumberOfFamilies = myMesh2->getNumberOfFamilies(MED_CELL)); + CPPUNIT_ASSERT_MESSAGE("Current mesh hasn't Families", NumberOfFamilies == 0); + + //create families - it's not possible to create, becase not all entities are defined + CPPUNIT_ASSERT_THROW( myMesh2->createFamilies(),MEDEXCEPTION); + + /*CPPUNIT_ASSERT_NO_THROW(NumberOfFamilies = myMesh2->getNumberOfFamilies(MED_CELL)); + CPPUNIT_ASSERT( NumberOfFamilies != 0);*/ + + delete myMesh2; + } + + ////////////////////////////////////////////////////////////// + // TEST 2: Polygon and Polyhedron(only NODAL connectivity) // + ///////////////////////////////////////////////////////////// + + double CoordinatesPoly[57] = { + 2.0, 3.0, 2.0, + 3.0, 2.0, 2.0, + 4.0, 1.0, 2.0, + 2.0, 0.0, 2.0, + 0.0, 1.0, 2.0, + 1.0, 2.0, 2.0, + 2.0, 3.0, 1.0, + 3.0, 2.0, 0.0, + 4.0, 1.0, 0.0, + 2.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 1.0, 2.0, 0.0, + 5.0, 3.0, 2.0, + 7.0, 2.0, 2.0, + 6.0, 0.0, 2.0, + 6.0, 3.0, 0.0, + 7.0, 2.0, 0.0, + 6.0, 0.0, -1.0, + 5.0, 1.0, -3.0}; + + const int REFnodalConnOfFaces[74] = { + 1, 2, 3, 4, 5, 6, // Polyhedron 1 + 1, 7, 8, 2, + 2, 8, 9, 3, + 4, 3, 9, 10, + 5, 4, 10, 11, + 6, 5, 11, 12, + 1, 6, 12, 7, + 7, 12, 8, + 10, 9, 8, 12, 11, + + 13, 14, 15, 3, 2, // Polyhedron 2 + 13, 2, 8, 16, + 14, 13, 16, 17, + 15, 14, 17, + 15, 17, 18, + 15, 18, 9, + 3, 15, 9, + 2, 3, 9, 8, + 8, 9, 17, 16, + 9, 18, 17}; + const int NumberOfFaces = 19; + const int NumberOfPolyhedron = 2; + const int nbOfPolygons = 2; + const int REFfacesIndex[NumberOfFaces+1] = { + 1, 7, 11, 15, 19, 23, 27, 31, 34, + 39, 44, 48, 52, 55, 58, 61, 64, 68, 72, 75}; + + const int REFpolyIndex[NumberOfPolyhedron+1] = {1, 10, 20}; + + double PolygonCoordinates[27] = { + 2.0, 3.0, 12.0, + 3.0, 2.0, 12.0, + 4.0, 1.0, 12.0, + 2.0, 0.0, 12.0, + 0.0, 1.0, 12.0, + 1.0, 2.0, 12.0, + 5.0, 3.0, 12.0, + 7.0, 2.0, 12.0, + 6.0, 0.0, 12.0}; + + const int REFpolygonFaces[11] = { + 1, 2, 3, 4, 5, 6, // Polygon 1 + 7, 8, 9, 3, 2}; // Polygon 2 + + const int REFpolygonIndex[nbOfPolygons+1] = {1, 7, 12}; + + MESHING myMeshingPoly; + myMeshingPoly.setName("meshingpoly"); + + int MeshDimension = 3; + + const int NbOfTypes = 1; + medGeometryElement TypesPoly[NbOfTypes] = {MED_TETRA4}; + const int NbOfElements[NbOfTypes] = {1}; + + CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setNumberOfTypes(NbOfTypes, MED_CELL)); + + try + { + myMeshingPoly.setCoordinates(SpaceDimension, NumberOfNodes, CoordinatesPoly, + "CARTESIAN", MED_FULL_INTERLACE); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + myMeshingPoly.setSpaceDimension(SpaceDimension); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + myMeshingPoly.setMeshDimension(MeshDimension); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setTypes(TypesPoly, MED_CELL)); + CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setNumberOfElements(NbOfElements, MED_CELL)); + + string Unit ="cm"; + for(int i = 0; i < SpaceDimension; i++ ) + { + try + { + myMeshingPoly.setCoordinateName(Names[i],i); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + try + { + myMeshingPoly.setCoordinateUnit(Unit, i); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + } + + int ConnectivityTetraPoly[4*1]= + { + 17, 9, 18, 19 + }; + + CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setConnectivity(ConnectivityTetraPoly, MED_CELL, MED_TETRA4)); + + CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.setPolyhedraConnectivity(REFpolyIndex, REFfacesIndex, + REFnodalConnOfFaces, NumberOfPolyhedron, MED_CELL)); + + bool PolyConn = false; + CPPUNIT_ASSERT_NO_THROW(PolyConn = myMeshingPoly.existPolyhedronConnectivity(MED_NODAL, MED_CELL)); + if(PolyConn) + { + CPPUNIT_ASSERT_EQUAL(myMeshingPoly.getNumberOfPolyhedron(),NumberOfPolyhedron); + CPPUNIT_ASSERT_EQUAL(myMeshingPoly.getNumberOfPolyhedronFaces(),NumberOfFaces); + CPPUNIT_ASSERT_NO_THROW(myMeshingPoly.getPolyhedronConnectivityLength(MED_NODAL)); + const int * PolyConn; + const int * PolyFaceIdx; + const int * PolyIdx; + CPPUNIT_ASSERT_NO_THROW(PolyConn = myMeshingPoly.getPolyhedronConnectivity(MED_NODAL)); + CPPUNIT_ASSERT_NO_THROW(PolyFaceIdx = myMeshingPoly.getPolyhedronFacesIndex()); + CPPUNIT_ASSERT_NO_THROW(PolyIdx = myMeshingPoly.getPolyhedronIndex(MED_NODAL)); + for(int i = 0; i<NumberOfPolyhedron; i++) + { + int FaceIdxBegin = PolyIdx[i]; + int FaceIdxEnd = PolyIdx[i+1]; + for(int k = FaceIdxBegin; k < FaceIdxEnd; k++) + { + int IdxBegin = PolyFaceIdx[k-1]; + int IdxEnd = PolyFaceIdx[k]; + for(int j = IdxBegin; j < IdxEnd; j++ ) + CPPUNIT_ASSERT_EQUAL(PolyConn[j-1],REFnodalConnOfFaces[j-1]); + } + } + } + + MESHING myPolygonMeshing; + myPolygonMeshing.setName("PolygonMeshing"); + + medGeometryElement PolygonTypes[NbOfTypes] = {MED_TRIA3}; + const int PolygonNumberOfElements[NbOfTypes] = {2}; + + CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setNumberOfTypes(NbOfTypes, MED_CELL)); + + try + { + myPolygonMeshing.setCoordinates(SpaceDimension, NumberOfNodes, PolygonCoordinates, + "CARTESIAN", MED_FULL_INTERLACE); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + NumberOfNodes = 9; + SpaceDimension = 3; + MeshDimension = 2; + + myPolygonMeshing.setSpaceDimension(SpaceDimension); + CPPUNIT_ASSERT(myPolygonMeshing.getSpaceDimension() == 3); + myPolygonMeshing.setMeshDimension(MeshDimension); + CPPUNIT_ASSERT(myPolygonMeshing.getMeshDimension() == 2); + myPolygonMeshing.setNumberOfNodes(NumberOfNodes); + CPPUNIT_ASSERT(myPolygonMeshing.getNumberOfNodes() == 9); + CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setTypes(PolygonTypes, MED_CELL)); + CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setNumberOfElements(PolygonNumberOfElements, MED_CELL)); + CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setCoordinatesSystem("CARTESIAN")); + + try + { + myPolygonMeshing.setCoordinatesNames(Names); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + myPolygonMeshing.setCoordinatesUnits(Units); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + const int sizeTri = 3*2; + int ConnectivityTri[sizeTri]= + { + 1, 7, 2, 3, 9, 4 + }; + + CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setConnectivity(ConnectivityTri, MED_CELL, MED_TRIA3)); + CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.setPolygonsConnectivity + (REFpolygonIndex, REFpolygonFaces, nbOfPolygons, MED_CELL)); + + bool PolygonConn = false; + CPPUNIT_ASSERT_NO_THROW(PolygonConn = myPolygonMeshing.existPolygonsConnectivity(MED_NODAL, MED_CELL)); + if(PolygonConn) + { + int Polytypes; + CPPUNIT_ASSERT_NO_THROW(Polytypes = myPolygonMeshing.getNumberOfTypesWithPoly(MED_CELL)); + CPPUNIT_ASSERT(NbOfTypes != Polytypes); + + const MED_EN::medGeometryElement * PolyTypes; + CPPUNIT_ASSERT_NO_THROW(PolyTypes = myPolygonMeshing.getTypesWithPoly(MED_CELL)); + CPPUNIT_ASSERT_EQUAL(PolyTypes[NbOfTypes],MED_POLYGON); + + for(int t = 0; t < Polytypes; t++) + { + CPPUNIT_ASSERT_NO_THROW( myPolygonMeshing.getNumberOfElementsWithPoly(MED_CELL, PolyTypes[t])); + } + + medGeometryElement geomPolyElem; + CPPUNIT_ASSERT_NO_THROW(geomPolyElem = myPolygonMeshing.getElementTypeWithPoly(MED_CELL, 1)); + CPPUNIT_ASSERT_EQUAL(geomPolyElem, MED_TRIA3); + + CPPUNIT_ASSERT_EQUAL(myPolygonMeshing.getNumberOfPolygons(),nbOfPolygons); + CPPUNIT_ASSERT_NO_THROW(myPolygonMeshing.getPolygonsConnectivityLength(MED_NODAL,MED_CELL)); + const int * PolygonConn; + const int * PolygonIdx; + CPPUNIT_ASSERT_THROW(PolygonConn = myMeshingPoly.getPolygonsConnectivity(MED_NODAL,MED_CELL),MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(PolygonIdx = myMeshingPoly.getPolygonsConnectivityIndex(MED_NODAL,MED_CELL),MEDEXCEPTION); + } + + ///////////////////////////////////////////////////// + // TEST : SUPPORT* sup = new SUPPORT(myMeshPointe) // + ///////////////////////////////////////////////////// + +//#ifdef ENABLE_FAULTS + { + MESH * myMeshPointe = new MESH(); + myMeshPointe->setName(meshname); + MED_MESH_RDONLY_DRIVER myMeshDriver (filename, myMeshPointe); + myMeshDriver.setMeshName(meshname); + myMeshDriver.open(); + myMeshDriver.read(); + myMeshDriver.close(); + + SUPPORT* sup = new SUPPORT(myMeshPointe); + delete sup; + delete myMeshPointe; + } +//#endif +//#ifdef ENABLE_FORCED_FAILURES +// CPPUNIT_FAIL("ERROR: can not create SUPPORT on mesh, read from pointe.med"); +//#endif + + //////////////////////////////////////////////////////// + // TEST 3: test MESH on MEDMEMTest::createTestMesh()// + /////////////////////////////////////////////////////// + + MESH* myMesh3 = MEDMEMTest_createTestMesh(); + + int MeshDim = myMesh3->getMeshDimension(); + medEntityMesh constituentEntity; + if (MeshDim==3) { + constituentEntity = MED_CELL; + } + if (MeshDim==2) { + constituentEntity = MED_FACE; + } + if (MeshDim==1) { + constituentEntity = MED_EDGE; + } + + int SpaceDim = myMesh3->getSpaceDimension(); + + // Show Reverse Nodal Connectivity + const int* ReverseNodalConnectivity; + const int* ReverseNodalConnectivityIndex; + int ReverseLength; + int ReverseIdxLength; + + CONNECTIVITY* myConnectivity3 = (CONNECTIVITY*)myMesh3->getConnectivityptr(); + myConnectivity3->setNumberOfNodes(myMesh3->getNumberOfNodes()); + + CPPUNIT_ASSERT_NO_THROW(ReverseNodalConnectivity= myMesh3->getReverseConnectivity(MED_NODAL, MED_CELL)); + CPPUNIT_ASSERT_NO_THROW(ReverseLength = myMesh3->getReverseConnectivityLength(MED_NODAL, MED_CELL)); + CPPUNIT_ASSERT_NO_THROW(ReverseNodalConnectivityIndex = myMesh3->getReverseConnectivityIndex(MED_NODAL, MED_CELL)); + CPPUNIT_ASSERT_NO_THROW(ReverseIdxLength = myMesh3->getReverseConnectivityIndexLength(MED_NODAL, MED_CELL)); + CPPUNIT_ASSERT(ReverseIdxLength == myMesh3->getNumberOfNodes()+1); + + for (int i = 0; i < myMesh3->getNumberOfNodes(); i++) { + cout << "Node "<< i+1 << " : "; + for (int j = ReverseNodalConnectivityIndex[i]; j < ReverseNodalConnectivityIndex[i+1]; j++) + cout << ReverseNodalConnectivity[j-1] << " "; + cout << endl; + } + + // Show Descending Connectivity + int NumberOfElements1; + const int * connectivity; + const int * connectivity_index; + myMesh3->calculateConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, MED_EN::MED_CELL); + try { + NumberOfElements1 = myMesh3->getNumberOfElements(MED_CELL, MED_ALL_ELEMENTS); + connectivity = myMesh3->getConnectivity(MED_FULL_INTERLACE, MED_DESCENDING, MED_CELL, MED_ALL_ELEMENTS); + connectivity_index = myMesh3->getConnectivityIndex(MED_DESCENDING, MED_CELL); + } + catch (MEDEXCEPTION m) { + CPPUNIT_FAIL(m.what()); + } + + for (int j = 0; j < NumberOfElements1; j++) { + cout << "Element " << j+1 << " : "; + for (int k = connectivity_index[j]; k < connectivity_index[j+1]; k++) + cout << connectivity[k-1] << " "; + cout << endl; + } + + //test 3D mesh + for(int ind = SpaceDim; ind > 1; ind-- ) + { + int NumberOfElem = myMesh3->getNumberOfElements (constituentEntity,MED_ALL_ELEMENTS); + if(NumberOfElem < 1) continue; + + SUPPORT * sup = (SUPPORT*) NULL; + sup = new SUPPORT(myMesh3,"",constituentEntity); + + if (ind == 2) + { + // test of normal(for 1d or 2d elements) + FIELD<double>* normal; + CPPUNIT_ASSERT_NO_THROW(normal = myMesh3->getNormal(sup)); + + double normal_square, norm; + double maxnorm=0.; + double minnorm=0.; + double tmp_value; + for (int i = 1; i<=NumberOfElem; i++) { + normal_square = 0.; + cout << "Normal " << i << " "; + for (int j=1; j<=SpaceDim; j++) { + tmp_value = normal->getValueIJ(i,j); + normal_square += tmp_value*tmp_value; + cout << tmp_value << " "; + } + norm = sqrt(normal_square); + maxnorm = dmax(maxnorm,norm); + minnorm = dmin(minnorm,norm); + cout << ", Norm = " << norm << endl; + } + cout << "Max Norm " << maxnorm << " Min Norm " << minnorm << endl; + delete normal; + + // test of area(for 2d elements) + FIELD<double>* area; + CPPUNIT_ASSERT_NO_THROW(area = myMesh3->getArea(sup)); + + double maxarea,minarea,areatot; + maxarea = 0.; + minarea = 0.; + areatot = 0.0; + for (int i = 1; i<=NumberOfElem;i++) + { + cout << "Area " << i << " " << area->getValueIJ(i,1) << endl; + maxarea = dmax(maxarea,area->getValueIJ(i,1)); + minarea = dmin(minarea,area->getValueIJ(i,1)); + areatot = areatot + area->getValueIJ(i,1); + } + + cout << "Max Area " << maxarea << " Min Area " << minarea << endl; + cout << "Support Area " << areatot << endl; + + delete area; + } + + // test of barycenter(for 3d and 2d elements) + FIELD<double>* barycenter; + CPPUNIT_ASSERT_NO_THROW(barycenter = myMesh3->getBarycenter(sup)); + + CPPUNIT_ASSERT_NO_THROW(NumberOfElem = myMesh3->getNumberOfElements(constituentEntity,MED_ALL_ELEMENTS)); + + for (int i = 1; i<=NumberOfElem;i++) + { + if (ind == 3) + cout << "Barycenter " << i << " " << barycenter->getValueIJ(i,1) << " " << barycenter->getValueIJ(i,2) << " " << barycenter->getValueIJ(i,3) << endl; + + if (ind == 2) + cout << "Barycenter " << i << " " << barycenter->getValueIJ(i,1) << " " << barycenter->getValueIJ(i,2) << endl; + } + delete barycenter; + + // test of volume(for 3d elements) + if (ind == 3) + { + FIELD<double>* volume; + CPPUNIT_ASSERT_NO_THROW(volume= myMesh3->getVolume(sup)); + + double maxvol,minvol,voltot; + maxvol = 0.; + minvol = 0.; + voltot = 0.0; + for (int i = 1; i<=NumberOfElem;i++) + { + cout << "Volume " << i << " " << volume->getValueIJ(i,1) << endl; + maxvol = dmax(maxvol,volume->getValueIJ(i,1)); + minvol = dmin(minvol,volume->getValueIJ(i,1)); + voltot = voltot + volume->getValueIJ(i,1); + } + + cout << "Max Volume " << maxvol << " Min Volume " << minvol << endl; + cout << "Support Volume " << voltot << endl; + + delete volume; + + // test of skin + SUPPORT *skin; + CPPUNIT_ASSERT_NO_THROW(skin = myMesh3->getSkin(sup)); + + //test mergeSupports and intersectSupports. vactor contains only 1 elements + vector<SUPPORT *> myVectSup; + myVectSup.push_back(skin); + + //method return a copy of skin object + SUPPORT *copyMergeSkin; + CPPUNIT_ASSERT_NO_THROW(copyMergeSkin = myMesh3->mergeSupports(myVectSup)); + try{ + CPPUNIT_ASSERT(copyMergeSkin->deepCompare(*skin)); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //method return a copy of skin object + SUPPORT *copyIntersectSkin; + CPPUNIT_ASSERT_NO_THROW(copyIntersectSkin = myMesh3->intersectSupports(myVectSup)); + try{ + CPPUNIT_ASSERT(copyIntersectSkin->deepCompare(*skin)); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + delete skin; + delete copyMergeSkin; + delete copyIntersectSkin; + } + + constituentEntity++; + } + + + // Testing length and normal vectors on 1d elements + { + // coordinates + int NumberOfNodes3 = 4; + + string Names3[3] = { "X","Y","Z" }; + string Units3[3] = { "cm","cm","cm" }; + + double Coordinates3[4*2] = {0.0, 0.0, // n1 + 1.0, 1.0, // n2 + 0.0, 1.0, // n3 + 1.0, 0.0}; // n4 + + const int NumberOfEdgeTypes = 1; + MED_EN::medGeometryElement EdgeTypes[NumberOfEdgeTypes] = {MED_SEG2}; + const int NumberOfEdges[NumberOfEdgeTypes] = {4}; + int ConnectivityEdge[4*2] = {1,2, 2,3, 3,4, 4,1}; + + // CREATE THE MESH + MEDMEM::MESHING* myMeshing3 = new MEDMEM::MESHING; + myMeshing3->setName("meshing3"); + myMeshing3->setCoordinates(/*SpaceDimension*/2, NumberOfNodes3, Coordinates3, + "CARTESIAN", MED_EN::MED_FULL_INTERLACE); + myMeshing3->setCoordinatesNames(Names3); + myMeshing3->setCoordinatesUnits(Units3); + + // define connectivities + // cell part + const int NumberOfTypes3 = 1; + medGeometryElement Types3[NumberOfTypes3] = {MED_QUAD4}; + const int NumberOfElements3[NumberOfTypes3] = {1}; + + myMeshing3->setNumberOfTypes(NumberOfTypes3,MED_CELL); + myMeshing3->setTypes(Types3,MED_CELL); + myMeshing3->setNumberOfElements(NumberOfElements3,MED_CELL); + + int Connectivityquad[1*4] = {1,2,3,4}; + + myMeshing3->setConnectivity(Connectivityquad,MED_CELL,MED_QUAD4); + + myMeshing3->setNumberOfTypes(NumberOfEdgeTypes, MED_EDGE); + myMeshing3->setTypes(EdgeTypes, MED_EDGE); + myMeshing3->setNumberOfElements(NumberOfEdges, MED_EDGE); + + myMeshing3->setConnectivity(ConnectivityEdge, MED_EDGE, MED_SEG2); + + // mesh dimension + myMeshing3->setMeshDimension(2); + + //test 2D mesh + int NumberOfElem = myMeshing3->getNumberOfElements (MED_EDGE, MED_ALL_ELEMENTS); + + SUPPORT * sup = new SUPPORT (myMeshing3, "", MED_EDGE); + + // test of normal(for 1d or 2d elements) + FIELD<double>* normal; + CPPUNIT_ASSERT_NO_THROW(normal = myMeshing3->getNormal(sup)); + + double normal_square, norm; + double maxnorm=0.; + double minnorm=0.; + double tmp_value; + for (int i = 1; i<=NumberOfElem; i++) { + normal_square = 0.; + cout << "Normal " << i << " "; + for (int j=1; j<=/*SpaceDimension*/2; j++) { + tmp_value = normal->getValueIJ(i,j); + normal_square += tmp_value*tmp_value; + cout << tmp_value << " "; + } + norm = sqrt(normal_square); + maxnorm = dmax(maxnorm,norm); + minnorm = dmin(minnorm,norm); + cout << ", Norm = " << norm << endl; + } + cout << "Max Norm " << maxnorm << " Min Norm " << minnorm << endl; + + // test of length(for 1d elements) + FIELD<double>* length; + CPPUNIT_ASSERT_NO_THROW(length = myMeshing3->getLength(sup)); + + double length_value,maxlength,minlength; + maxlength = 0; + minlength = 0; + for (int i = 1; i<=NumberOfElem;i++) { + length_value = length->getValueIJ(i,1); + cout << "Length " << i << " " << length_value << endl; + maxlength = dmax(maxlength,length_value); + minlength = dmin(minlength,length_value); + } + cout << "Max Length " << maxlength << " Min Length " << minlength << endl; + + vector< FIELD<double> *> myVectField1; + myVectField1.push_back(normal); + myVectField1.push_back(length); + CPPUNIT_ASSERT_NO_THROW(myMeshing3->mergeFields(myVectField1)); + + delete normal; + delete length; + delete sup; + +//#ifdef ENABLE_FAULTS + { + // (BUG) Segmentation fault if vector is empty + vector<SUPPORT *> myVectSupEmpty; + CPPUNIT_ASSERT_THROW(myMesh3->mergeSupports(myVectSupEmpty), MEDEXCEPTION); + } +//#endif + + // test mergeFields method: Fields have the same value type + //intersectSupports and mergeSupports methods + { + SUPPORT * sup1 = new SUPPORT (myMeshing3, "", MED_EDGE); + SUPPORT * sup2 = new SUPPORT (myMeshing3, "", MED_EDGE); + MED_EN::medGeometryElement gtEdges[1] = {MED_SEG2}; + int nbEdges1[1] = {1}; + int edges1[1] = {1}; + int nbEdges2[1] = {2}; + int edges2[2] = {2,3}; + sup1->setpartial("description 1", 1, 1, gtEdges, nbEdges1, edges1); + sup2->setpartial("description 1", 1, 2, gtEdges, nbEdges2, edges2); + + vector<SUPPORT *> myVectSup3; + myVectSup3.push_back(sup1); + myVectSup3.push_back(sup2); + //method return a MergeSup on the union of all SUPPORTs in Supports. + SUPPORT *MergeSup; + CPPUNIT_ASSERT_NO_THROW(MergeSup = myMesh3->mergeSupports(myVectSup3)); + cout << *MergeSup << endl; + delete MergeSup; + + //method return a intersection of all SUPPORTs in IntersectSup + SUPPORT *IntersectSup; + CPPUNIT_ASSERT_NO_THROW(IntersectSup = myMesh3->intersectSupports(myVectSup3)); + if (IntersectSup != NULL) cout<< *IntersectSup <<endl; + delete IntersectSup; + + FIELD<double> * length1 = myMeshing3->getLength(sup1); + FIELD<double> * length2 = myMeshing3->getLength(sup2); + + vector< FIELD<double> *> myVect12; + myVect12.push_back(length1); + myVect12.push_back(length2); + + FIELD<double> * length12; + CPPUNIT_ASSERT_NO_THROW(length12 = myMeshing3->mergeFields(myVect12)); + delete length12; + + delete sup1; + delete sup2; + delete length1; + delete length2; + } + } + + ///////////////////////////////////////////////////////// + // TEST 4: test MESH constructed from file pointe.med // + //////////////////////////////////////////////////////// + MESH * myMesh4 = new MESH(); + myMesh4->setName(meshname); + MED_MESH_RDONLY_DRIVER myMeshDriver (filename, myMesh4); + myMeshDriver.setMeshName(meshname); + + //Mesh has no driver->segmentation violation + //CPPUNIT_ASSERT_THROW(myMesh4->read(), MEDEXCEPTION); + + //Add an existing MESH driver. + int myDriver4; + CPPUNIT_ASSERT_NO_THROW(myDriver4 = myMesh4->addDriver(myMeshDriver)); + + //read all objects in the file + CPPUNIT_ASSERT_NO_THROW(myMesh4->read(myDriver4)); + + if (myMesh4->getIsAGrid()) { + GRID* myGrid = dynamic_cast<GRID*>(myMesh4); + CPPUNIT_ASSERT(myGrid); + } + + //myDriver4->DRONLY->can't write + CPPUNIT_ASSERT_THROW(myMesh4->write(myDriver4), MEDEXCEPTION); + + // add new driver + int idMeshV21; + CPPUNIT_ASSERT_NO_THROW(idMeshV21 = myMesh4->addDriver(MED_DRIVER,filenameout21)); + + //Write all the content of the MESH using driver referenced by the integer handler index. + CPPUNIT_ASSERT_NO_THROW(myMesh4->write(idMeshV21)); + + // remove driver from mesh + CPPUNIT_ASSERT_NO_THROW(myMesh4->rmDriver(myDriver4)); +//#ifdef ENABLE_FORCED_FAILURES +// CPPUNIT_FAIL("ERROR: driver with index idMedV21 has not been removed"); +//#endif + // ensure exception is raised on second attempt to remove driver + //CPPUNIT_ASSERT_THROW(myMesh4->rmDriver(myDriver4),MEDEXCEPTION); + + // Create a MESH object using a MESH driver of type MED_DRIVER associated with file fileName. + MESH* myMesh5; + CPPUNIT_ASSERT_NO_THROW(myMesh5 = new MESH(MED_DRIVER, filename, meshname)); + if(myMesh5->getIsAGrid()){ + GRID* myGrid = dynamic_cast<GRID*>(myMesh4); + CPPUNIT_ASSERT(myGrid); + } + + //ensure two meshes constracted from one file in two different ways are equal + CPPUNIT_ASSERT(myMesh5->deepCompare(*myMesh4)); + + int myDriver6; + MESH* myMesh6 = new MESH(); + try{ + myDriver6 = myMesh6->addDriver(MED_DRIVER, filename, meshname, RDONLY); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try{ + myMesh6->read(myDriver6); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //ensure two meshes constracted from one file in two different ways are equal + CPPUNIT_ASSERT(myMesh6->deepCompare(*myMesh4)); + + //test FAMILY + int NumberOfFamilies4; + CPPUNIT_ASSERT_NO_THROW(NumberOfFamilies4 = myMesh6->getNumberOfFamilies(MED_CELL)); + CPPUNIT_ASSERT_MESSAGE("Current mesh hasn't Families", NumberOfFamilies4 != 0); + + vector<FAMILY*> families4; + CPPUNIT_ASSERT_NO_THROW(families4 = myMesh6->getFamilies(MED_CELL)); + CPPUNIT_ASSERT(families4.size() == NumberOfFamilies4); + for(int nb = 1; nb <= NumberOfFamilies4; nb++ ) + { + const FAMILY* family; + CPPUNIT_ASSERT_NO_THROW(family = myMesh6->getFamily(MED_CELL, nb)); + CPPUNIT_ASSERT_EQUAL(family->getName(), families4[nb-1]->getName()); + } + + //get support which reference all elements on the boundary of mesh. + SUPPORT*myBndSup; + CPPUNIT_ASSERT_THROW(myMesh6->getBoundaryElements(MED_CELL), MEDEXCEPTION); + //get only face in 3D. + CPPUNIT_ASSERT_NO_THROW(myBndSup = myMesh6->getBoundaryElements(MED_FACE)); + + //test buildSupportOnElementsFromElementList and buildSupportOnNodeFromElementList + const int * myConnectivityValue6; + CPPUNIT_ASSERT_NO_THROW(myConnectivityValue6 = myMesh6->getReverseConnectivity(MED_DESCENDING)); + const int * myConnectivityIndex6; + CPPUNIT_ASSERT_NO_THROW(myConnectivityIndex6 = myMesh6->getReverseConnectivityIndex(MED_DESCENDING)); + int numberOfElem6; + CPPUNIT_ASSERT_NO_THROW(numberOfElem6 = myMesh6->getNumberOfElementsWithPoly(MED_FACE,MED_ALL_ELEMENTS)); + list<int> myElementsList6; + + for (int i=0; i<numberOfElem6; i++) + if (myConnectivityValue6[myConnectivityIndex6[i]] == 0) { + myElementsList6.push_back(i+1); + } + + SUPPORT * mySupportOnNode; + SUPPORT * mySupportOnElem; + CPPUNIT_ASSERT_NO_THROW(mySupportOnElem = myMesh6->buildSupportOnElementsFromElementList(myElementsList6,MED_FACE)); + CPPUNIT_ASSERT(mySupportOnElem->deepCompare(*myBndSup)); + CPPUNIT_ASSERT_EQUAL(MED_FACE, mySupportOnElem->getEntity()); + + list<int>::const_iterator iteronelem = myElementsList6.begin(); + for (int i = 1; i <= 3; i++, iteronelem++) { + CPPUNIT_ASSERT_EQUAL(i, mySupportOnElem->getValIndFromGlobalNumber(*iteronelem)); + } + + CPPUNIT_ASSERT_NO_THROW(mySupportOnNode = myMesh6->buildSupportOnNodeFromElementList(myElementsList6,MED_FACE)); + CPPUNIT_ASSERT(mySupportOnNode->deepCompare( *(myMesh6->getBoundaryElements(MED_NODE)))); + + //sets mesh fields to initial values + try{ + myMesh6->init(); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //ensure two meshes constracted from one file in two different ways are equal + CPPUNIT_ASSERT(!myMesh6->deepCompare(*myMesh4)); + + //ensure mesh is empty + CPPUNIT_ASSERT(myMesh6->getSpaceDimension() == MED_INVALID); + CPPUNIT_ASSERT(myMesh6->getNumberOfNodes() == MED_INVALID); + CPPUNIT_ASSERT(myMesh6->getCoordinateptr() == NULL); + + delete myMesh4; + delete myMesh5; + delete myMesh6; + + MESH* myMesh7 = MEDMEMTest_createTestMesh(); + vector< vector<double> > myBndBox; + try{ + myBndBox = myMesh7->getBoundingBox(); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + cout<<"Bounding box for createTestMesh()"<<endl; + for(int i = 0; i < myBndBox.size(); i++) + { + for(int j = 0; j < myBndBox[i].size(); j++) + cout<<" "<< myBndBox[i][j]<<" "; + cout<<endl; + } + + double CoorPoint[3] = {0.0, 0.0, 1.0}; //n2 + int idxElem; + try{ + idxElem = myMesh7->getElementContainingPoint(CoorPoint); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT(idxElem != -1); + + double CoorNoPoint[3] = {5.0, 0.0, -5.0}; //there is no such point + int idxNoElem; + try{ + idxNoElem = myMesh7->getElementContainingPoint(CoorNoPoint); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT(idxNoElem == -1); +} + +int main (int argc, char** argv) +{ + MEDMEMTest_testMeshAndMeshing(); +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_ModulusArray.cxx b/src/MEDMEMCppTest/MEDMEMTest_ModulusArray.cxx new file mode 100644 index 000000000..bf8d7e169 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_ModulusArray.cxx @@ -0,0 +1,289 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/Message.h> +#include <cppunit/TestAssert.h> + +#include "MEDMEM_ModulusArray.hxx" +#include "MEDMEM_define.hxx" + +#include <sstream> +#include <cmath> + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +/*! + * Check methods (4), defined in MEDMEM_ModulusArray.hxx: + * class MEDMODULUSARRAY { + * (+) MEDMODULUSARRAY(int length, const int * array); + * (+) MEDMODULUSARRAY(int vertexLength, int totalLength, const int * array); + * (+) ~MEDMODULUSARRAY(); + * (+) const int operator[](const int &i) const; + * (+) int compare(const MEDMODULUSARRAY &modulusArray) const; + * } + */ +void MEDMEMTest::testModulusArray() +{ + + int array[5]={0,1,2,1,4} ; + MEDMODULUSARRAY modulusArray(5,array); + + cout <<"ModulusArray"<<endl; + for(int i=-10;i<15;i++) + cout <<" - A["<<i<<"]="<<modulusArray[i]<<endl; + cout <<endl; + + // test compare + int ret ; + + int array2[5]={1,4,0,1,2} ; + MEDMODULUSARRAY modulusArray2(5,array2); + + try{ + ret=modulusArray2.compare(modulusArray); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + cout<<"!!!!!!ret"<<ret<<endl; + CPPUNIT_ASSERT_MESSAGE("Two identical arrays - KO", ret == 1); + + int array3[5]={1,2,1,0,4} ; + MEDMODULUSARRAY modulusArray3(5,array3) ; + try{ + ret=modulusArray3.compare(modulusArray); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_MESSAGE("Two arrays are in reverse order - KO",ret == -1); + + int array4[6]={1,2,1,0} ; + MEDMODULUSARRAY modulusArray4(4,array4) ; + try{ + ret=modulusArray4.compare(modulusArray); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_MESSAGE("Two arrays are have different size - KO",ret == 0); + + int array5[5]={1,2,1,0,1} ; + MEDMODULUSARRAY modulusArray5(5,array5) ; + + try{ + ret=modulusArray5.compare(modulusArray); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_MESSAGE("Two different arrays, same size - KO",ret == 0); + + // test small array : + + // 1 + int array6[1]={1} ; + MEDMODULUSARRAY modulusArray6(1,array6); + + cout <<"Test small array"<<endl; + for(int i=-10;i<15;i++) + cout <<" - A["<<i<<"]="<<modulusArray6[i]<<endl; + + + int array7[1]={1} ; + MEDMODULUSARRAY modulusArray7(1,array7); + try{ + ret=modulusArray6.compare(modulusArray7); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_MESSAGE("Two identical arrays - KO", ret == 1); + + int array8[1]={2} ; + MEDMODULUSARRAY modulusArray8(1,array8); + try{ + ret=modulusArray6.compare(modulusArray8); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_MESSAGE("Two different arrays - KO",ret == 0); + + // 2 + int array60[2]={1,2} ; + MEDMODULUSARRAY modulusArray60(2,array60); + + cout<<"ModulusArray 2 :"<<endl; + for(int i=-10;i<15;i++) + cout <<" - A["<<i<<"]="<<modulusArray60[i]<<endl; + cout <<endl; + + int array70[2]={1,2} ; + MEDMODULUSARRAY modulusArray70(2,array70); + + try{ + ret=modulusArray60.compare(modulusArray70); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_MESSAGE("Same arrays, same order - KO",ret == 1); + + int array80[2]={2,2} ; + MEDMODULUSARRAY modulusArray80(2,array80); + try{ + ret=modulusArray60.compare(modulusArray80); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_MESSAGE("Different arrays - KO",ret == 0); + + int array90[2]={2,1} ; + MEDMODULUSARRAY modulusArray90(2,array90); + + try{ + ret=modulusArray60.compare(modulusArray90); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_MESSAGE("Two arrays are in reverse order - KO",ret == -1); + + //test not vertex nodes + int array100[2]={1,2} ; + MEDMODULUSARRAY modulusArray100(2,2,array100); // == MEDMODULUSARRAY(2,array100); + + try{ + ret = modulusArray60.compare(modulusArray100); + } + catch (const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_MESSAGE("Same arrays, same order - KO", ret == 1); + + // check comparison of equal arrays, containing non-vertex nodes + + int array110[4] = {1,2,4,3}; + MEDMODULUSARRAY modulusArray110(2,4,array110); + + int array120[4] = {1,2,4,3}; + MEDMODULUSARRAY modulusArray120(2,4,array120); + + int array130[4] = {1,2,3,4}; + MEDMODULUSARRAY modulusArray130(2,4,array130); + + // same order of non-vertex nodes + CPPUNIT_ASSERT_NO_THROW(ret = modulusArray120.compare(modulusArray110)); + CPPUNIT_ASSERT_MESSAGE("Same arrays, same order - KO", ret == 1); + + // different order of non-vertex nodes + CPPUNIT_ASSERT_NO_THROW(ret = modulusArray130.compare(modulusArray110)); + CPPUNIT_ASSERT_MESSAGE("Same arrays, same order - KO", ret == 1); + + // check comparison of different arrays, containing non-vertex nodes + + // difference is in vertex nodes + int array140[4] = {1,5,4,3}; + MEDMODULUSARRAY modulusArray140 (2,4,array140); + + CPPUNIT_ASSERT_NO_THROW(ret = modulusArray120.compare(modulusArray140)); + CPPUNIT_ASSERT_MESSAGE("Different arrays - KO", ret == 0); + + // difference is in non-vertex nodes + int array150[4] = {1,2,4,5}; + MEDMODULUSARRAY modulusArray150 (2,4,array150); + + CPPUNIT_ASSERT_NO_THROW(ret = modulusArray120.compare(modulusArray150)); + CPPUNIT_ASSERT_MESSAGE("Different arrays - KO", ret == 0); + + // check that operator[] returns only vertex nodes + CPPUNIT_ASSERT_EQUAL(1, modulusArray120[0]); + CPPUNIT_ASSERT_EQUAL(2, modulusArray120[1]); + CPPUNIT_ASSERT_EQUAL(1, modulusArray120[2]); + CPPUNIT_ASSERT_EQUAL(2, modulusArray120[3]); + CPPUNIT_ASSERT_EQUAL(1, modulusArray120[4]); + CPPUNIT_ASSERT_EQUAL(2, modulusArray120[5]); +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_PointerOf.cxx b/src/MEDMEMCppTest/MEDMEMTest_PointerOf.cxx new file mode 100644 index 000000000..8fdecfb6c --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_PointerOf.cxx @@ -0,0 +1,153 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include "MEDMEM_PointerOf.hxx" +#include "MEDMEM_define.hxx" + +#include <cppunit/TestAssert.h> + +#include <sstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; + +/*! + * Check methods (12), defined in MEDMEM_PointerOf.hxx: + * template <typename T> class PointerOf { + * (+) PointerOf(); + * (+) ~PointerOf(); + * (+) PointerOf(const int &size); + * (+) PointerOf(const T *pointer); + * (+) PointerOf(const int &size, const T *pointer); + * (+) PointerOf(const PointerOf<T> & pointerOf); + * (NOT COMPILABLE!!!) PointerOf(const int &size, const PointerOf<T> & pointerOf); + * (+) operator T*(); + * (+) operator const T*() const; + * (+) void set(const int &size); + * (+) void set(const T *pointer); + * (+) void set(const int &size, const T *pointer); + * (+) void setShallowAndOwnership(const T *pointer); + * (+) PointerOf<T>& operator=(const PointerOf<T> &pointer); + * } + * + */ +void MEDMEMTest::testPointerOf() +{ + const int size=10; + PointerOf<int> P; + + try + { + P.set(0); + CPPUNIT_ASSERT((int *)P == NULL); + } + catch ( const std::exception &e ) + { + CPPUNIT_FAIL(e.what()); + } + + try + { + P.set(-1 * size); + CPPUNIT_ASSERT((int *)P == NULL); + } + catch ( const std::exception &e ) + { + CPPUNIT_FAIL(e.what()); + } + + try + { + P.set(size); + CPPUNIT_ASSERT((int *)P != NULL); + } + catch ( const std::exception &e ) + { + CPPUNIT_FAIL(e.what()); + } + + for (int i=0; i < size; i++) + { + P[i]=i; + } + + PointerOf<int> P2(10); + + P2=P; + for (int i=0; i < size; i++) + { + SCRUTE_MED(P2[i]); + } + + int * p=new int [size]; + for (int i=0; i < size; i++) + { + p[i]=i*10; + } + + P2.set(p); + PointerOf<int> P3(p); + + for (int i=0; i < size; i++) + { + CPPUNIT_ASSERT_EQUAL(P2[i],P3[i]); + } + + const PointerOf<int> P4(p); + for (int i=0; i < size; i++) + { + CPPUNIT_ASSERT_EQUAL(P4[i],p[i]); + } + + const PointerOf<int> P5(P4); + CPPUNIT_ASSERT((const int*)P5 != NULL); + + const PointerOf<int> P7(10, p); + + //{ + //#ifdef ENABLE_COMPILATION_ERRORS + //PointerOf<int> PP1 (10, p); + //PointerOf<int> PP2 (10, PP1); + //#endif + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_FAIL("Can not create: PointerOf(const int &size, const PointerOf<T> & pointerOf)"); + //#endif + //} + + //CPPUNIT_ASSERT_THROW(P3.set(0, p),MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(P3.set(0, p)); + + P.setShallowAndOwnership( p ); + for (int i=0; i < size; i++) + { + CPPUNIT_ASSERT_EQUAL(P[i],p[i]); + } + + //delete [] p; not needed - P already owns p and will delete it when the scope is over +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_PolyhedronArray.cxx b/src/MEDMEMCppTest/MEDMEMTest_PolyhedronArray.cxx new file mode 100644 index 000000000..52f489697 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_PolyhedronArray.cxx @@ -0,0 +1,104 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/Message.h> +#include <cppunit/TestAssert.h> + +#include "MEDMEM_PolyhedronArray.hxx" +#include "MEDMEM_define.hxx" + +#include <sstream> +#include <cmath> + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +/*! + * Check methods (12), defined in MEDMEM_PolyhedronArray.hxx: + * class POLYHEDRONARRAY { + * (+) POLYHEDRONARRAY(); + * (+) POLYHEDRONARRAY(MED_EN::med_int numberofpolyhedron, + * MED_EN::med_int numberoffaces, MED_EN::med_int numberofnodes); + * (+) POLYHEDRONARRAY(const POLYHEDRONARRAY& m); + * + * (+) inline MED_EN::med_int getNumberOfPolyhedron() const; + * (+) inline MED_EN::med_int getNumberOfFaces() const; + * (+) inline MED_EN::med_int getNumberOfNodes() const; + * + * (+) inline const MED_EN::med_int* getPolyhedronIndex() const; + * (+) inline const MED_EN::med_int* getFacesIndex() const; + * (+) inline const MED_EN::med_int* getNodes() const; + * + * (+) inline void setPolyhedronIndex(const MED_EN::med_int* polyhedronindex); + * (+) inline void setFacesIndex(const MED_EN::med_int* facesindex); + * (+) inline void setNodes(const MED_EN::med_int* nodes); + * } + */ +void MEDMEMTest::testPolyhedronArray() +{ + const med_int nbPolyhedrons = 2; + const med_int nbFaces = 11; + const med_int nbNodes = 40; + + med_int polyhedronindex[nbPolyhedrons] = {1,7}; + med_int facesindex[nbFaces] = {1,5,9,13,17,21,25,28,31,34,37}; + med_int nodes[nbNodes] = {1,2,6,5,2,3,7,6,4,3,7,8,1,4,8,5,1,2,3,4,5,6,7,8,5,6,9,6,7,9,7,8,9,8,5,9,5,6,7,8}; + + // construction with parameters + POLYHEDRONARRAY myPArray (nbPolyhedrons, nbFaces, nbNodes); + + CPPUNIT_ASSERT_NO_THROW(myPArray.setPolyhedronIndex(polyhedronindex)); + CPPUNIT_ASSERT_NO_THROW(myPArray.setFacesIndex(facesindex)); + CPPUNIT_ASSERT_NO_THROW(myPArray.setNodes(nodes)); + + // copy constructor + POLYHEDRONARRAY myPArray2 (myPArray); + + const med_int* __polyhedronindex = myPArray2.getPolyhedronIndex(); + const med_int* __facesindex = myPArray2.getFacesIndex(); + const med_int* __nodes = myPArray2.getNodes(); + + CPPUNIT_ASSERT_EQUAL(myPArray2.getNumberOfPolyhedron(), nbPolyhedrons); + CPPUNIT_ASSERT_EQUAL(myPArray2.getNumberOfFaces(), nbFaces); + CPPUNIT_ASSERT_EQUAL(myPArray2.getNumberOfNodes(), nbNodes); + + for (int i = 0; i < nbPolyhedrons; i++) + CPPUNIT_ASSERT_EQUAL(__polyhedronindex[i], polyhedronindex[i]); + + for (int i = 0; i < nbFaces; i++) + CPPUNIT_ASSERT_EQUAL(__facesindex[i], facesindex[i]); + + for (int i = 0; i < nbNodes; i++) + CPPUNIT_ASSERT_EQUAL(__nodes[i], nodes[i]); + + // default constructor (has no sense, must be private) + POLYHEDRONARRAY myPArray3; + + CPPUNIT_ASSERT_EQUAL(0, int(myPArray3.getNumberOfPolyhedron())); + CPPUNIT_ASSERT_EQUAL(0, int(myPArray3.getNumberOfFaces())); + CPPUNIT_ASSERT_EQUAL(0, int(myPArray3.getNumberOfNodes())); + + CPPUNIT_ASSERT(myPArray3.getPolyhedronIndex() == NULL); + CPPUNIT_ASSERT(myPArray3.getFacesIndex() == NULL); + CPPUNIT_ASSERT(myPArray3.getNodes() == NULL); +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_PorflowMeshDriver.cxx b/src/MEDMEMCppTest/MEDMEMTest_PorflowMeshDriver.cxx new file mode 100644 index 000000000..40ddf4617 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_PorflowMeshDriver.cxx @@ -0,0 +1,321 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include <MEDMEM_PorflowMeshDriver.hxx> +#include <MEDMEM_Mesh.hxx> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; + +/*! + * Check methods (18), defined in MEDMEM_PorflowMeshDriver.hxx: + * class PORFLOW_MESH_DRIVER : public GENDRIVER { + * (+) PORFLOW_MESH_DRIVER(); + * (+) PORFLOW_MESH_DRIVER(const string & fileName, MESH * ptrMesh, MED_EN::med_mode_acces accessMode); + * (+) PORFLOW_MESH_DRIVER(const PORFLOW_MESH_DRIVER & driver); + * (+) virtual ~PORFLOW_MESH_DRIVER(); + * (+) void open() throw (MEDEXCEPTION); + * (+) void close() throw (MEDEXCEPTION); + * (-) virtual void write(void) const = 0; + * (+) virtual void read (void) = 0; + * (+) void setMeshName(const string & meshName); + * (+) string getMeshName() const; + * } + * class PORFLOW_MESH_RDONLY_DRIVER : public virtual PORFLOW_MESH_DRIVER { + * (+) PORFLOW_MESH_RDONLY_DRIVER(); + * (+) PORFLOW_MESH_RDONLY_DRIVER(const string & fileName, MESH * ptrMesh); + * (+) PORFLOW_MESH_RDONLY_DRIVER(const PORFLOW_MESH_RDONLY_DRIVER & driver); + * (+) virtual ~PORFLOW_MESH_RDONLY_DRIVER(); + * (+) void write(void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * } + * class PORFLOW_MESH_WRONLY_DRIVER : public virtual PORFLOW_MESH_DRIVER { + * (+) PORFLOW_MESH_WRONLY_DRIVER(); + * (+) PORFLOW_MESH_WRONLY_DRIVER(const string & fileName, MESH * ptrMesh); + * (+) PORFLOW_MESH_WRONLY_DRIVER(const PORFLOW_MESH_WRONLY_DRIVER & driver); + * (+) virtual ~PORFLOW_MESH_WRONLY_DRIVER(); + * (NOT IMPLEMENTED!!!) void write(void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * } + * class PORFLOW_MESH_RDWR_DRIVER : public PORFLOW_MESH_RDONLY_DRIVER, public PORFLOW_MESH_WRONLY_DRIVER { + * (+) PORFLOW_MESH_RDWR_DRIVER(); + * (+) PORFLOW_MESH_RDWR_DRIVER(const string & fileName, MESH * ptrMesh); + * (+) PORFLOW_MESH_RDWR_DRIVER(const PORFLOW_MESH_RDWR_DRIVER & driver); + * (+) ~PORFLOW_MESH_RDWR_DRIVER(); + * (CALLS PORFLOW_MESH_WRONLY_DRIVER::write()) void write(void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * } + */ +void MEDMEMTest::testPorflowMeshDriver() +{ + MESH *aMesh = new MESH(); + MESH *aMesh_1 = new MESH(); + + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + + string filename_rd = data_dir + "/share/salome/resources/med/Case1.inp"; + string filename_wr = tmp_dir + "/myWr_Case1.inp"; + string meshname = "Case1"; + string newmeshname = "new" + meshname; + string fileNotExistsName_rd = "notExists.inp"; + string fileNotExistsName_wr = "/path_not_exists/file_not_exists.inp"; + string filename_rdwr = tmp_dir + "/myRdWr_Case1.inp"; + string fcopy = "cp " + filename_rd + " " + filename_rdwr; + string fcopy1 = "cp " + data_dir + "/share/salome/resources/med/Case1.xyz" + " " + tmp_dir + "/Case1.xyz"; + string fcopy2 = "cp " + data_dir + "/share/salome/resources/med/Case1.cnc" + " " + tmp_dir + "/Case1.cnc"; + + //Copy files in the TMP dir for testing READ/WRITE case + system(fcopy.data()); + system(fcopy1.data()); + system(fcopy2.data()); + + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filename_wr); + aRemover.Register(filename_rdwr); + aRemover.Register(tmp_dir + "/Case1.xyz"); + aRemover.Register(tmp_dir + "/Case1.cnc"); + + //-----------------------------Test READ ONLY part---------------------------------------// + { + { + //Creation a incorrect Porflow read only driver + PORFLOW_MESH_RDONLY_DRIVER *aInvalidPorflowRdDriver = + new PORFLOW_MESH_RDONLY_DRIVER(fileNotExistsName_rd, aMesh); + + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidPorflowRdDriver->open(), MEDEXCEPTION); + + delete aInvalidPorflowRdDriver; + } + + //Creation a correct Porflow read only driver (normal constructor) + PORFLOW_MESH_RDONLY_DRIVER *aPorflowRdDriver = new PORFLOW_MESH_RDONLY_DRIVER(filename_rd, aMesh); + + //Check driver + CPPUNIT_ASSERT(aPorflowRdDriver); + + //Trying read mesh from file, if file is not open + CPPUNIT_ASSERT_THROW(aPorflowRdDriver->read(), MEDEXCEPTION); + + //Test open() method + // commented by skl - must be exception since thid file is + // opened yet and such case is tested below + //CPPUNIT_ASSERT_NO_THROW(aPorflowRdDriver->open()); + + //#ifdef ENABLE_FORCED_FAILURES + //Trying open file secondary + //CPPUNIT_ASSERT_THROW(aPorflowRdDriver->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_NO_THROW(aPorflowRdDriver->open()); + //This case work, but it corrypt driver + //#endif + + //Test read() method + CPPUNIT_ASSERT_NO_THROW(aPorflowRdDriver->read()); + + //Check Mesh + CPPUNIT_ASSERT(aMesh); + + //Trying fill not empty mesh + CPPUNIT_ASSERT_THROW(aPorflowRdDriver->read(), MEDEXCEPTION); + + //Test write() method for Porflow RDONLY Driver + CPPUNIT_ASSERT_THROW(aPorflowRdDriver->write(), MEDEXCEPTION); + + //Test setMeshName() and getMeshName() + CPPUNIT_ASSERT_NO_THROW(aPorflowRdDriver->setMeshName(meshname)); + CPPUNIT_ASSERT_EQUAL(meshname, aPorflowRdDriver->getMeshName()); + + //Test close() method + CPPUNIT_ASSERT_NO_THROW(aPorflowRdDriver->close()); + + //Default constructor + PORFLOW_MESH_RDONLY_DRIVER aPorflowRdDriverCpy_1; + // TO DO + + //Test copy constructor + PORFLOW_MESH_RDONLY_DRIVER aPorflowRdDriverCpy_2 (*aPorflowRdDriver); + + //Test (bool operator ==) defined GENDRIVER class in MEDMEM_GenDriver.hxx + CPPUNIT_ASSERT(aPorflowRdDriverCpy_2.GENDRIVER::operator==(*aPorflowRdDriver)); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream rostr1, rostr2; + rostr1 << *aPorflowRdDriver; + rostr2 << aPorflowRdDriverCpy_2; + CPPUNIT_ASSERT(rostr1.str() != ""); + CPPUNIT_ASSERT_EQUAL(rostr1.str() , rostr2.str()); + + delete aPorflowRdDriver; + } + + //---------------------------Test WRITE ONLY part-------------------------------------// + { + { + //Creation a incorrect Porflow write only driver + PORFLOW_MESH_WRONLY_DRIVER *aInvalidPorflowWrDriver = + new PORFLOW_MESH_WRONLY_DRIVER(fileNotExistsName_wr, aMesh); + + //Test case: trying open non existing file + CPPUNIT_ASSERT_THROW(aInvalidPorflowWrDriver->open(), MEDEXCEPTION); + + delete aInvalidPorflowWrDriver; + } + + //Creation a correct write only driver + PORFLOW_MESH_WRONLY_DRIVER *aPorflowWrDriver = new PORFLOW_MESH_WRONLY_DRIVER(filename_wr, aMesh); + + //Check driver + CPPUNIT_ASSERT(aPorflowWrDriver); + + //Test case: trying write mesh to file, if file is not open + CPPUNIT_ASSERT_THROW(aPorflowWrDriver->write(), MEDEXCEPTION); + + //Test open() method + //#ifndef ENABLE_FORCED_FAILURES + FILE *tmpFile = fopen(filename_wr.data(), "w"); + fclose(tmpFile); + //#endif + CPPUNIT_ASSERT_NO_THROW(aPorflowWrDriver->open()); + + //Test case: trying open file secondary. + CPPUNIT_ASSERT_THROW(aPorflowWrDriver->open(), MEDEXCEPTION); + + //Test write() method + //#ifdef ENABLE_FORCED_FAILURES + //Write method is not implemented + //CPPUNIT_ASSERT_NO_THROW(aPorflowWrDriver->write()); + CPPUNIT_ASSERT_THROW(aPorflowWrDriver->write(), MEDEXCEPTION); + //#endif + + //Test read() method for WRITE ONLY driver + CPPUNIT_ASSERT_THROW(aPorflowWrDriver->read(), MEDEXCEPTION); + + //Test setMeshName() and getMeshName() + CPPUNIT_ASSERT_NO_THROW(aPorflowWrDriver->setMeshName(newmeshname)); + CPPUNIT_ASSERT_EQUAL(newmeshname, aPorflowWrDriver->getMeshName()); + + CPPUNIT_ASSERT_NO_THROW(aPorflowWrDriver->close()); + + //Default constructor + PORFLOW_MESH_WRONLY_DRIVER aPorflowWrDriverCpy_1; + + //Test copy constructor + PORFLOW_MESH_WRONLY_DRIVER aPorflowWrDriverCpy_2 (*aPorflowWrDriver); + + //Test (bool operator ==) defined in GENDRIVER class + CPPUNIT_ASSERT(aPorflowWrDriverCpy_2.GENDRIVER::operator==(*aPorflowWrDriver)); + + //Test (friend ostream & operator <<) defined in GENDRIVER class + ostringstream wostr1, wostr2; + wostr1 << *aPorflowWrDriver; + wostr2 << aPorflowWrDriverCpy_2; + CPPUNIT_ASSERT(wostr1.str() != ""); + CPPUNIT_ASSERT(wostr1.str() == wostr2.str()); + + delete aPorflowWrDriver; + } + + //------------------------Test READ / WRITE part------------------------------------// + { + { + //Creation a incorrect read/write driver + PORFLOW_MESH_RDWR_DRIVER *aInvalidPorflowRdWrDriver = + new PORFLOW_MESH_RDWR_DRIVER(fileNotExistsName_wr, aMesh_1); + + //Test case: trying open non existing file + CPPUNIT_ASSERT_THROW(aInvalidPorflowRdWrDriver->open(), MEDEXCEPTION); + + delete aInvalidPorflowRdWrDriver; + } + + //Creation a correct read/write driver + PORFLOW_MESH_RDWR_DRIVER *aPorflowRdWrDriver = new PORFLOW_MESH_RDWR_DRIVER(filename_rdwr, aMesh_1); + + //Check driver + CPPUNIT_ASSERT(aPorflowRdWrDriver); + + //Test case: trying write mesh to file, if file is not open + CPPUNIT_ASSERT_THROW(aPorflowRdWrDriver->write(), MEDEXCEPTION); + + //Test case: trying read mesh from file, if file is not open + CPPUNIT_ASSERT_THROW(aPorflowRdWrDriver->read(), MEDEXCEPTION); + + //Test open() method + CPPUNIT_ASSERT_NO_THROW(aPorflowRdWrDriver->open()); + + //Test case: trying open file secondary. + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) This case work, but corrupt driver + CPPUNIT_ASSERT_THROW(aPorflowRdWrDriver->open(), MEDEXCEPTION); + //#endif + + //Test read() method + CPPUNIT_ASSERT_NO_THROW(); + CPPUNIT_ASSERT_NO_THROW(aPorflowRdWrDriver->read()); + + //Test write() method + //aPorflowRdWrDriver->setMeshName(newmeshname); + //aMesh->setName(newmeshname); + //CPPUNIT_ASSERT_NO_THROW(aPorflowRdWrDriver->write()); + //Write method is not implemented + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_FAIL("PORFLOW_MESH_RDWR_DRIVER::write() method not implemented"); + //#endif + + //Check Mesh + CPPUNIT_ASSERT(aMesh); + + CPPUNIT_ASSERT_NO_THROW(aPorflowRdWrDriver->close()); + + //Default constructor + PORFLOW_MESH_RDWR_DRIVER aPorflowRdWrDriverCpy_1; + // TO DO + + //Test copy constructor + PORFLOW_MESH_RDWR_DRIVER aPorflowRdWrDriverCpy_2 (*aPorflowRdWrDriver); + + //Test (bool operator ==) defined in GENDRIVER class + CPPUNIT_ASSERT(aPorflowRdWrDriverCpy_2.GENDRIVER::operator==(*aPorflowRdWrDriver)); + + //Test (friend ostream & operator <<) defined in GENDRIVER class + ostringstream rwostr1, rwostr2; + rwostr1 << *aPorflowRdWrDriver; + rwostr2 << aPorflowRdWrDriverCpy_2; + CPPUNIT_ASSERT(rwostr1.str() != ""); + CPPUNIT_ASSERT(rwostr1.str() == rwostr2.str()); + + delete aPorflowRdWrDriver; + } + + //Delete all objects + delete aMesh; + delete aMesh_1; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_SkyLineArray.cxx b/src/MEDMEMCppTest/MEDMEMTest_SkyLineArray.cxx new file mode 100644 index 000000000..efd1d321e --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_SkyLineArray.cxx @@ -0,0 +1,201 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> +#include "MEDMEM_SkyLineArray.hxx" +#include "MEDMEM_define.hxx" + +#include <sstream> +#include <cmath> + +using namespace std; +using namespace MEDMEM; + +/*! + * Check methods (17), defined in MEDMEM_SkyLineArray.hxx: + * class MEDSKYLINEARRAY { + * (+) MEDSKYLINEARRAY(); + * (+) MEDSKYLINEARRAY(const MEDSKYLINEARRAY &myArray); + * (+) MEDSKYLINEARRAY(const int count, const int length); + * (+) MEDSKYLINEARRAY(const int count, const int length, + * const int* index, const int* value, bool shallowCopy=false); + * (+) ~MEDSKYLINEARRAY(); + * (+) inline int getNumberOf() const; + * (+) inline int getLength() const; + * (+) inline const int* getIndex() const; + * (+) inline const int* getValue() const; + * (+) inline int getNumberOfI(int i) const throw (MEDEXCEPTION); + * (+) inline const int* getI(int i) const throw (MEDEXCEPTION); + * (+) inline int getIJ(int i, int j) const throw (MEDEXCEPTION); + * (+) inline int getIndexValue(int i) const throw (MEDEXCEPTION); + * (+) inline void setIndex(const int* index); + * (+) inline void setI(const int i, const int* values) throw (MEDEXCEPTION); + * (+) inline void setIJ(int i, int j, int value) throw (MEDEXCEPTION); + * (+) inline void setIndexValue(int i, int value) throw (MEDEXCEPTION); + * (+) friend ostream& operator<<(ostream &os, const MEDSKYLINEARRAY &sky); + * } + * + */ +void MEDMEMTest::testSkyLineArray() +{ + int NumberOfCell = 3 ; // 1 triangle,1 quadrangle,1 triangle + int Size = 10 ; // 10 nodes + + int * index = new int[NumberOfCell+1] ; + index[0]=1; + index[1]=4; + index[2]=8; + index[3]=11; + int * value = new int[Size] ; + value[0]=1; // first + value[1]=2; + value[2]=5; + value[3]=2; // second + value[4]=3; + value[5]=5; + value[6]=6; + value[7]=3; // thirst + value[8]=4; + value[9]=6; + // value[]=; // forth + + MEDSKYLINEARRAY * myArray = new MEDSKYLINEARRAY(NumberOfCell,Size,index,value) ; + const int * ArrayIndex ; + try + { + ArrayIndex = myArray->getIndex() ; + } + catch ( const std::exception &e ) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + const int * ArrayValue ; + try + { + ArrayValue = myArray->getValue() ; + } + catch ( const std::exception &e ) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + + try + { + CPPUNIT_ASSERT(myArray->getNumberOf()==NumberOfCell); + + } + catch ( const std::exception &e ) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + CPPUNIT_ASSERT(myArray->getLength()==Size); + } + catch ( const std::exception &e ) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + for (int i=1; i< NumberOfCell+1 ; i++) + { + const int * cell; + CPPUNIT_ASSERT_NO_THROW(cell = myArray->getI(i)); + int numberof; + CPPUNIT_ASSERT_NO_THROW(numberof= myArray->getNumberOfI(i)); + CPPUNIT_ASSERT(numberof==index[i]-index[i-1]); + int verif; + for (int j=0;j<numberof;j++) + { + CPPUNIT_ASSERT_NO_THROW(verif=myArray->getIJ(i,j+1)); + CPPUNIT_ASSERT(verif == cell[j]); + } + } + + MEDSKYLINEARRAY * myArray2 = new MEDSKYLINEARRAY(*myArray) ; + delete myArray ; + + const int * index2 = myArray2->getIndex() ; + for (int i=1; i<=NumberOfCell ; i++) { + for (int j=index2[i-1];j<index2[i];j++) + CPPUNIT_ASSERT_NO_THROW(myArray2->getIndexValue(j)); + } + + delete myArray2 ; + + MEDSKYLINEARRAY myArray3(NumberOfCell,Size); + try + { + myArray3.setIndex(index); + } + catch ( const std::exception &e ) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + CPPUNIT_ASSERT_THROW(myArray3.setI(0, 0),MEDEXCEPTION); + + for (int i=1; i<NumberOfCell+1 ; i++) { + CPPUNIT_ASSERT_NO_THROW(myArray3.setI(i, &value[index[i-1]-1])); + } + + for (int i=1; i<NumberOfCell+1 ; i++) { + int numberof; + CPPUNIT_ASSERT_NO_THROW(numberof = myArray3.getNumberOfI(i)); + for (int j=1;j<numberof+1;j++) + CPPUNIT_ASSERT_NO_THROW(myArray3.setIJ(i,j,myArray3.getIJ(i,j))) ; + } + + for (int i=1; i<=NumberOfCell ; i++) { + for (int j=index[i-1];j<index[i];j++) + CPPUNIT_ASSERT_NO_THROW(myArray3.setIndexValue(j,value[j-1])); + } + + delete[] index ; + delete[] value ; + MEDSKYLINEARRAY myEmptyArray; + cout<<myEmptyArray<<endl; +} + diff --git a/src/MEDMEMCppTest/MEDMEMTest_Support.cxx b/src/MEDMEMCppTest/MEDMEMTest_Support.cxx new file mode 100644 index 000000000..88d09fd26 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Support.cxx @@ -0,0 +1,690 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_STRING.hxx" +#include "MEDMEM_Support.hxx" + +#include <sstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; + +// #52: MEDMEM_Support.hxx } MEDMEMTest_Support.cxx + +/*! + * Check methods (48), defined in MEDMEM_Support.hxx: + * class SUPPORT : public RCBASE { + * (+) SUPPORT(); + * (+) SUPPORT(MESH* Mesh, string Name="", MED_EN::medEntityMesh Entity=MED_EN::MED_CELL); + * (+) SUPPORT(const SUPPORT & m); + * (+) virtual ~SUPPORT(); + * + * (+) friend ostream & operator<<(ostream &os,const SUPPORT &my); + * (+) SUPPORT& operator=(const SUPPORT &support); + * (+) bool operator == (const SUPPORT &support) const; + * (+) bool deepCompare(const SUPPORT &support) const; + * + * (+) void update(); + * + * (+) inline void setName(string Name); + * (+) inline void setDescription(string Description); + * (+) void setMesh(MESH *Mesh) const; + * (+) inline void setMeshName(const string & meshName); + * (+) inline void setAll(bool All); + * (+) inline void setEntity(MED_EN::medEntityMesh Entity); + * + * (+) inline void setNumberOfGeometricType(int NumberOfGeometricType); + * (+) inline void setGeometricType(const MED_EN::medGeometryElement *GeometricType); + * (+) inline void setNumberOfElements(const int *NumberOfElements); + * (+) inline void setTotalNumberOfElements(int TotalNumberOfElements); + * (+) inline void setNumber(MEDSKYLINEARRAY * Number); + * (+) inline void setNumber(const int * index, const int* value, bool shallowCopy=false); + * + * (+) inline string getName() const; + * (+) inline string getDescription() const; + * (+) virtual inline MESH * getMesh() const; + * (+) string getMeshName() const; + * (+) inline MED_EN::medEntityMesh getEntity() const; + * (+) inline bool isOnAllElements() const; + * + * (+) inline int getNumberOfTypes() const; + * (+) inline const MED_EN::medGeometryElement* getTypes() const; + * (+) inline int getNumberOfElements + * (MED_EN::medGeometryElement GeometricType) const throw (MEDEXCEPTION); + * (+) inline const int * getNumberOfElements() const throw (MEDEXCEPTION); + * (+) virtual inline MEDSKYLINEARRAY * getnumber() const throw (MEDEXCEPTION); + * (NO METHOD IN THIS BRANCH) virtual inline MEDSKYLINEARRAY * getnumberFromFile() const throw (MEDEXCEPTION); + * (+) virtual inline const int * getNumber + * (MED_EN::medGeometryElement GeometricType) const throw (MEDEXCEPTION); + * (NO METHOD IN THIS BRANCH) virtual inline const int * getNumberFromFile + * (MED_EN::medGeometryElement GeometricType) const throw (MEDEXCEPTION); + * (+) virtual inline const int * getNumberIndex() const throw (MEDEXCEPTION); + * (+) virtual int getValIndFromGlobalNumber(const int number) const throw (MEDEXCEPTION); + * + * (+) void blending(SUPPORT * mySupport) throw (MEDEXCEPTION); + * + * (+) void setpartial(string Description, int NumberOfGeometricType, + * int TotalNumberOfEntity, MED_EN::medGeometryElement *GeometricType, + * int *NumberOfEntity, int *NumberValue); + * (+) void setpartial(MEDSKYLINEARRAY * number, bool shallowCopy=false) throw (MEDEXCEPTION); + * (NO METHOD IN THIS BRANCH) void setpartial_fromfile(MEDSKYLINEARRAY * number, bool shallowCopy=false) throw (MEDEXCEPTION); + * + * (+) void setProfilNames(vector<string> profilNames) throw (MEDEXCEPTION); + * (+) vector<string> getProfilNames() const throw (MEDEXCEPTION); + * + * (+) void getBoundaryElements() throw (MEDEXCEPTION); + * + * (+) void changeElementsNbs(MED_EN::medEntityMesh entity, const int *renumberingFromOldToNew, + * int limitNbClassicPoly, const int *renumberingFromOldToNewPoly=0); + * (+) void intersecting(SUPPORT * mySupport) throw (MEDEXCEPTION); + * (+) bool belongsTo(const SUPPORT& other, bool deepCompare=false) const; + * + * (+) SUPPORT *getComplement() const; + * (+) SUPPORT *substract(const SUPPORT& other) const throw (MEDEXCEPTION); + * + * (+) SUPPORT *getBoundaryElements(MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION); + * + * (+) void fillFromNodeList(const list<int>& listOfNode) throw (MEDEXCEPTION); + * (+) void fillFromElementList(const list<int>& listOfElt) throw (MEDEXCEPTION); + * + * (+) void clearDataOnNumbers(); + * + * (reference counter presently disconnected in C++) virtual void addReference() const; + * (reference counter presently disconnected in C++) virtual void removeReference() const; + * } + */ +void MEDMEMTest::testSupport() +{ + // cells connectivities + //const int NumberOfCellTypes = 3; + //MED_EN::medGeometryElement CellTypes[NumberOfCellTypes] = + // {MED_EN::MED_TETRA4, MED_EN::MED_PYRA5, MED_EN::MED_HEXA8}; + //const int NumberOfCells[NumberOfCellTypes] = {12, 2, 2}; + + // faces connectivities + //const int NumberOfFaceTypes = 2; + //MED_EN::medGeometryElement FaceTypes[NumberOfFaceTypes] = {MED_EN::MED_TRIA3, MED_EN::MED_QUAD4}; + //const int NumberOfFaces[NumberOfFaceTypes] = {4, 4}; + + MESH * aMesh = MEDMEMTest_createTestMesh(); + MESH * aMeshOneMore = MEDMEMTest_createTestMesh(); + + //////////// + // TEST 1 // + //////////// + + SUPPORT aSupportOnFaces1 (aMesh, "Support On Faces 1", MED_EN::MED_FACE); + SUPPORT aSupportOnCells1 (aMesh, "Support On Cells 1"/*, MED_EN::MED_CELL*/); + + SUPPORT aSupportOnFaces2; + SUPPORT aSupportOnCells2; + + SUPPORT aSupportOnFaces3 (aMeshOneMore, "Support On Faces 3", MED_EN::MED_FACE); + + // entity + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aSupportOnFaces1.getEntity()); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_CELL, aSupportOnCells1.getEntity()); + + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_CELL, aSupportOnFaces2.getEntity()); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_CELL, aSupportOnCells2.getEntity()); + + aSupportOnFaces2.setEntity(MED_EN::MED_FACE); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aSupportOnFaces2.getEntity()); + + // isOnAllElements + CPPUNIT_ASSERT(aSupportOnFaces1.isOnAllElements()); + CPPUNIT_ASSERT(aSupportOnCells1.isOnAllElements()); + + CPPUNIT_ASSERT(!aSupportOnFaces2.isOnAllElements()); + CPPUNIT_ASSERT(!aSupportOnCells2.isOnAllElements()); + + // mesh and mesh name + CPPUNIT_ASSERT_THROW(aSupportOnFaces1.setMeshName("Mesh 1"), MEDEXCEPTION); + + aSupportOnFaces2.setMeshName("Mesh 1"); + aSupportOnCells2.setMeshName("Mesh 1"); + CPPUNIT_ASSERT(aSupportOnFaces2.getMeshName() == "Mesh 1"); + CPPUNIT_ASSERT(aSupportOnCells2.getMeshName() == "Mesh 1"); + + aSupportOnFaces2.setMesh(aMesh); + CPPUNIT_ASSERT_THROW(aSupportOnFaces2.setMeshName("Mesh 1"), MEDEXCEPTION); + + aSupportOnCells1.setMesh(NULL); + aSupportOnCells1.setMeshName("Mesh 1"); + + CPPUNIT_ASSERT(aSupportOnFaces1.getMeshName() == "meshing"); + CPPUNIT_ASSERT(aSupportOnFaces2.getMeshName() == "meshing"); + CPPUNIT_ASSERT(aSupportOnCells1.getMeshName() == "Mesh 1"); + CPPUNIT_ASSERT(aSupportOnCells2.getMeshName() == "Mesh 1"); + + CPPUNIT_ASSERT(aSupportOnFaces1.getMesh() == aMesh); + CPPUNIT_ASSERT(aSupportOnFaces2.getMesh() == aMesh); + CPPUNIT_ASSERT(aSupportOnCells1.getMesh() == NULL); + CPPUNIT_ASSERT(aSupportOnCells2.getMesh() == NULL); + + // operator == + aSupportOnFaces2.setName("Support On Faces 2"); + aSupportOnCells2.setName("Support On Cells 2"); + + // because aSupportOnFaces1 is on all elements, but aSupportOnFaces2 not + CPPUNIT_ASSERT(!(aSupportOnFaces1 == aSupportOnFaces2)); + + aSupportOnCells1.setAll(false); + CPPUNIT_ASSERT(!aSupportOnCells1.isOnAllElements()); + // this is only sets flag _isOnAllElts to false, but not clear elements and types + // information, so aSupportOnCells1 is not equal to aSupportOnCells2 at this moment + + //#ifdef ENABLE_FAULTS + // (BUG) SUPPORT::operator= gives "Segmentation Fault" on supports with NULL meshes!!! + //CPPUNIT_ASSERT(!(aSupportOnCells1 == aSupportOnCells2)); + //#endif + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_FAIL("SUPPORT::operator= gives Segmentation Fault on supports with NULL meshes!!!"); + //#endif + + aSupportOnFaces2.setAll(true); + CPPUNIT_ASSERT(aSupportOnFaces2.isOnAllElements()); + // flag _isOnAllElts now is set to true, but we need also to call update() + // to set elements and types information from mesh to this support + CPPUNIT_ASSERT(!(aSupportOnFaces1 == aSupportOnFaces2)); + aSupportOnFaces2.update(); + CPPUNIT_ASSERT(aSupportOnFaces1 == aSupportOnFaces2); + + // deep compare + CPPUNIT_ASSERT(aSupportOnFaces1.deepCompare(aSupportOnFaces2)); + + CPPUNIT_ASSERT(!(aSupportOnFaces1 == aSupportOnFaces3)); // different mesh pointers + CPPUNIT_ASSERT(aSupportOnFaces1.deepCompare(aSupportOnFaces3)); // meshes are really equal + + // description + aSupportOnFaces1.setDescription("Support on all faces with mesh pointer"); + aSupportOnFaces2.setDescription("Support on all faces with mesh pointer"); + + aSupportOnCells1.setDescription("Support on a part of cells with mesh name"); + aSupportOnCells2.setDescription("Support on a part of cells with mesh name"); + + CPPUNIT_ASSERT(aSupportOnFaces1.getDescription() == "Support on all faces with mesh pointer"); + CPPUNIT_ASSERT(aSupportOnFaces2.getDescription() == "Support on all faces with mesh pointer"); + CPPUNIT_ASSERT(aSupportOnCells1.getDescription() == "Support on a part of cells with mesh name"); + CPPUNIT_ASSERT(aSupportOnCells2.getDescription() == "Support on a part of cells with mesh name"); + + // operator<< + ostringstream ostr1; + ostr1 << aSupportOnFaces1; + CPPUNIT_ASSERT(ostr1.str() != ""); + + ostringstream ostr2; + ostr2 << aSupportOnCells2; + CPPUNIT_ASSERT(ostr2.str() != ""); + + // set/get elements and types information + + // 1. aSupportOnCells1 is not on all elements, but now it contains information + // about all cells of aMesh, because it was created on mesh and with parameters. + CPPUNIT_ASSERT_EQUAL(3, aSupportOnCells1.getNumberOfTypes()); + CPPUNIT_ASSERT(aSupportOnCells1.getTypes() != NULL); + + //const int * nbEltsSC_old = aSupportOnCells1.getNumberOfElements(); // {12, 2, 2} + + aSupportOnCells1.setNumberOfGeometricType(0); + CPPUNIT_ASSERT_EQUAL(0, aSupportOnCells1.getNumberOfTypes()); + CPPUNIT_ASSERT(aSupportOnCells1.getTypes() == NULL); + + MED_EN::medGeometryElement aSCTypes[2] = {MED_EN::MED_PYRA5, MED_EN::MED_PENTA15}; + aSupportOnCells1.setNumberOfGeometricType(2); + aSupportOnCells1.setGeometricType(aSCTypes); + + CPPUNIT_ASSERT_EQUAL(2, aSupportOnCells1.getNumberOfTypes()); + CPPUNIT_ASSERT(aSupportOnCells1.getTypes() != NULL); + CPPUNIT_ASSERT(aSupportOnCells1.getNumberOfElements() == NULL); // reset by setNumberOfGeometricType + + int nbEltsSC[2] = {2, 1}; + aSupportOnCells1.setNumberOfElements(nbEltsSC); + + const int * nbEltsSCBack = aSupportOnCells1.getNumberOfElements(); + CPPUNIT_ASSERT_EQUAL(2, aSupportOnCells1.getNumberOfElements(MED_EN::MED_PYRA5)); + CPPUNIT_ASSERT_EQUAL(2, nbEltsSCBack[0]); + CPPUNIT_ASSERT_EQUAL(1, aSupportOnCells1.getNumberOfElements(MED_EN::MED_PENTA15)); + CPPUNIT_ASSERT_EQUAL(1, nbEltsSCBack[1]); + CPPUNIT_ASSERT_EQUAL(3, aSupportOnCells1.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + + // old types + CPPUNIT_ASSERT_THROW(aSupportOnCells1.getNumberOfElements(MED_EN::MED_TETRA4), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSupportOnCells1.getNumberOfElements(MED_EN::MED_HEXA8), MEDEXCEPTION); + + //_number= new MEDSKYLINEARRAY(_numberOfGeometricType,_totalNumberOfElements,index,value,shallowCopy); + int indexSC[3] = {1,3,4}; // length = nb.types + 1 + int valueSC[3] = {21,22,47}; // length = total nb. of elements + aSupportOnCells1.setNumber(indexSC, valueSC); + + // check number + MEDSKYLINEARRAY * aNumberSCBack = aSupportOnCells1.getnumber(); + + CPPUNIT_ASSERT_EQUAL(2, aNumberSCBack->getNumberOf()); + CPPUNIT_ASSERT_EQUAL(3, aNumberSCBack->getLength()); + const int * ind = aNumberSCBack->getIndex(); + const int * val = aNumberSCBack->getValue(); + CPPUNIT_ASSERT_EQUAL(1, ind[0]); + CPPUNIT_ASSERT_EQUAL(3, ind[1]); + CPPUNIT_ASSERT_EQUAL(4, ind[2]); + CPPUNIT_ASSERT_EQUAL(21, val[0]); + CPPUNIT_ASSERT_EQUAL(22, val[1]); + CPPUNIT_ASSERT_EQUAL(47, val[2]); + + // 2. aSupportOnCells2 is not on all elements, and now it contains + // no information about elements of a mesh + CPPUNIT_ASSERT_EQUAL(0, aSupportOnCells2.getNumberOfTypes()); + CPPUNIT_ASSERT(aSupportOnCells2.getTypes() == NULL); + + aSupportOnCells2.setNumberOfGeometricType(2); + aSupportOnCells2.setGeometricType(aSCTypes); + + CPPUNIT_ASSERT_EQUAL(2, aSupportOnCells2.getNumberOfTypes()); + CPPUNIT_ASSERT(aSupportOnCells2.getTypes() != NULL); + + aSupportOnCells2.setNumberOfElements(nbEltsSC); + + // we create MEDSKYLINEARRAY as pointer, because aSupportOnCells2 will + // become an owner of it, and we must not delete it. + MEDSKYLINEARRAY * aNumberSC = new MEDSKYLINEARRAY(2, 3, indexSC, valueSC); + aSupportOnCells2.setNumber(aNumberSC); + + // check number + const int * aNumberIndexSC = aSupportOnCells2.getNumberIndex(); + CPPUNIT_ASSERT_EQUAL(1, aNumberIndexSC[0]); + CPPUNIT_ASSERT_EQUAL(3, aNumberIndexSC[1]); + CPPUNIT_ASSERT_EQUAL(4, aNumberIndexSC[2]); + + const int * aNbPYRA5 = aSupportOnCells2.getNumber(MED_EN::MED_PYRA5); + const int * aNbPENTA15 = aSupportOnCells2.getNumber(MED_EN::MED_PENTA15); + CPPUNIT_ASSERT_THROW(aSupportOnCells2.getNumber(MED_EN::MED_TETRA4), MEDEXCEPTION); + + const int * aNbC = aSupportOnCells2.getNumber(MED_EN::MED_ALL_ELEMENTS); + + CPPUNIT_ASSERT_EQUAL(21, aNbPYRA5[0]); + CPPUNIT_ASSERT_EQUAL(22, aNbPYRA5[1]); + CPPUNIT_ASSERT_EQUAL(47, aNbPENTA15[0]); + + CPPUNIT_ASSERT_EQUAL(21, aNbC[0]); + CPPUNIT_ASSERT_EQUAL(22, aNbC[1]); + CPPUNIT_ASSERT_EQUAL(47, aNbC[2]); + + // getValIndFromGlobalNumber + CPPUNIT_ASSERT_EQUAL(1, aSupportOnCells2.getValIndFromGlobalNumber(21)); + CPPUNIT_ASSERT_EQUAL(2, aSupportOnCells2.getValIndFromGlobalNumber(22)); + CPPUNIT_ASSERT_EQUAL(3, aSupportOnCells2.getValIndFromGlobalNumber(47)); + // not existing element + CPPUNIT_ASSERT_THROW(aSupportOnCells2.getValIndFromGlobalNumber(10), MEDEXCEPTION); + + // compare aSupportOnCells1 and aSupportOnCells2 + + // temporary set mesh (because of bug with operator==) + aSupportOnCells1.setMesh(aMesh); + aSupportOnCells2.setMesh(aMesh); + + CPPUNIT_ASSERT_EQUAL(aSupportOnCells1, aSupportOnCells2); + + // restore mesh name + aSupportOnCells1.setMesh(NULL); + aSupportOnCells2.setMesh(NULL); + aSupportOnCells1.setMeshName("Mesh 1"); + aSupportOnCells2.setMeshName("Mesh 1"); + + // 3. aSupportOnFacesN is on all elements, and it contains + // information about all faces of aMesh + CPPUNIT_ASSERT_EQUAL(2, aSupportOnFaces1.getNumberOfTypes()); + const MED_EN::medGeometryElement* aSF1Types = aSupportOnFaces1.getTypes(); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_TRIA3, aSF1Types[0]); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_QUAD4, aSF1Types[1]); + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) Comment to method SUPPORT::getTypes() says: + // "If isOnAllElements is false, returns an array of %medGeometryElement types used by the support." + // But in fact it returns types in any case (comment to SUPPORT::setAll() gives more information). + //CPPUNIT_FAIL("Comment and implementation does not match for SUPPORT::getTypes()"); + // This concerns also method SUPPORT::update(), being called from constructor, + // which fills internal SUPPORT structures with information about mesh elements + // in case of isOnAllElements == true. + // Also comments and implementation does not match for SUPPORT::getNumberOfElements(). + // It seems that in case "isOnAllElements == true" calls like getNumberOfElements() + // must be redirected to mesh, but what if mesh is not set (mesh name used instead)?. + //#endif + const int * nbEltsSF1 = aSupportOnFaces1.getNumberOfElements(); + CPPUNIT_ASSERT_EQUAL(4, aSupportOnFaces1.getNumberOfElements(MED_EN::MED_TRIA3)); + CPPUNIT_ASSERT_EQUAL(4, nbEltsSF1[0]); + CPPUNIT_ASSERT_EQUAL(4, aSupportOnFaces1.getNumberOfElements(MED_EN::MED_QUAD4)); + CPPUNIT_ASSERT_EQUAL(4, nbEltsSF1[1]); + CPPUNIT_ASSERT_EQUAL(8, aSupportOnFaces1.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumberOfElements(MED_EN::MED_TRIA6), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumberOfElements(MED_EN::MED_QUAD8), MEDEXCEPTION); + + // check number + CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumberIndex(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumber(MED_EN::MED_TRIA3), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumber(MED_EN::MED_QUAD4), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumber(MED_EN::MED_ALL_ELEMENTS), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getnumber(), MEDEXCEPTION); + + // getValIndFromGlobalNumber + CPPUNIT_ASSERT_EQUAL(8, aMesh->getNumberOfElements(MED_EN::MED_FACE, MED_EN::MED_ALL_ELEMENTS)); + for (int i = 1; i <= 8; i++) { + CPPUNIT_ASSERT_EQUAL(i, aSupportOnFaces1.getValIndFromGlobalNumber(i)); + } + + //#ifdef ENABLE_FORCED_FAILURES + // Why methods setNumber do not throw exception in case "isOnAllElements == true", + // like methods getNumber do? + //skl??? CPPUNIT_ASSERT_THROW(aSupportOnFaces1.setNumber(indexSF1, valueSF1), MEDEXCEPTION); + //#endif + + //#ifdef ENABLE_FORCED_FAILURES + // It seems to be dangerous and useless to have method SUPPORT::setTotalNumberOfElements() + //CPPUNIT_FAIL("It seems to be dangerous and useless to have method SUPPORT::setTotalNumberOfElements()"); + //#endif + + // following test is commented since method + // setTotalNumberOfElements() is removed. + // setTotalNumberOfElements + //aSupportOnFaces1.setTotalNumberOfElements(1000); + //CPPUNIT_ASSERT_EQUAL(1000, aSupportOnFaces1.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + + // clearDataOnNumbers + aSupportOnCells1.clearDataOnNumbers(); + CPPUNIT_ASSERT_EQUAL(0, aSupportOnCells1.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + CPPUNIT_ASSERT_EQUAL(0, aSupportOnCells1.getNumberOfTypes()); + CPPUNIT_ASSERT_THROW(aSupportOnCells1.getnumber(), MEDEXCEPTION); + + //////////// + // TEST 2 // + //////////// + + list<int> nodes137; + nodes137.push_back(1); + nodes137.push_back(3); + nodes137.push_back(7); + + list<int> nodes248; + nodes248.push_back(2); + nodes248.push_back(4); + nodes248.push_back(8); + + list<int> nodes27; + nodes27.push_back(2); + nodes27.push_back(7); + + SUPPORT aNodes137 (aMesh, "Support On Nodes 1,3,7", MED_EN::MED_CELL); + SUPPORT aNodes248 (aMesh, "Support On Nodes 2,4,8", MED_EN::MED_CELL); + SUPPORT aNodes27 (aMesh, "Support On Nodes 2,7" , MED_EN::MED_CELL); + + aNodes137.fillFromNodeList(nodes137); + aNodes248.fillFromNodeList(nodes248); + aNodes27.fillFromNodeList(nodes27); + + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_NODE, aNodes137.getEntity()); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_NODE, aNodes248.getEntity()); + + list<int>::const_iterator iter137 = nodes137.begin(); + list<int>::const_iterator iter248 = nodes248.begin(); + for (int i = 1; i <= 3; i++, iter137++, iter248++) { + CPPUNIT_ASSERT_EQUAL(i, aNodes137.getValIndFromGlobalNumber(*iter137)); + CPPUNIT_ASSERT_EQUAL(i, aNodes248.getValIndFromGlobalNumber(*iter248)); + } + + //////////// + + list<int> faces123; + faces123.push_back(1); + faces123.push_back(2); + faces123.push_back(3); + + list<int> faces135; + faces135.push_back(1); + faces135.push_back(3); + faces135.push_back(5); + + SUPPORT aFaces123 (aMesh, "Support On Faces 1,2,3", MED_EN::MED_FACE); + SUPPORT aFaces135 (aMesh, "Support On Faces 1,3,5", MED_EN::MED_FACE); + + aFaces123.fillFromElementList(faces123); + aFaces135.fillFromElementList(faces135); + + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces123.getEntity()); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces135.getEntity()); + + list<int>::const_iterator iter123 = faces123.begin(); + list<int>::const_iterator iter135 = faces135.begin(); + for (int i = 1; i <= 3; i++, iter123++, iter135++) { + CPPUNIT_ASSERT_EQUAL(i, aFaces123.getValIndFromGlobalNumber(*iter123)); + CPPUNIT_ASSERT_EQUAL(i, aFaces135.getValIndFromGlobalNumber(*iter135)); + } + + // substract + SUPPORT * aFaces2 = aFaces123.substract(aFaces135); // => 2 + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces2->getEntity()); + CPPUNIT_ASSERT_EQUAL(1, aFaces2->getValIndFromGlobalNumber(2)); + CPPUNIT_ASSERT_EQUAL(1, aFaces2->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + + CPPUNIT_ASSERT_THROW(aFaces123.substract(aNodes137), MEDEXCEPTION); + + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) SUPPORT::substract() does not work with supports on nodes, + // because it uses method MESH::buildSupportOnNodeFromElementList(), + // which does not work if entity = MED_NODE + //SUPPORT * aNodes137mesh = aMesh->buildSupportOnNodeFromElementList(nodes137, MED_EN::MED_NODE); + //delete aNodes137mesh; + SUPPORT * aNodes137sub = aNodes137.substract(aNodes248); // => 1,3,7 + CPPUNIT_ASSERT_EQUAL(*aNodes137sub, aNodes137); + delete aNodes137sub; + //#endif + + // belongsTo + CPPUNIT_ASSERT(aFaces2->belongsTo(aFaces123)); + CPPUNIT_ASSERT(!aFaces2->belongsTo(aFaces135)); + + CPPUNIT_ASSERT(!aFaces2->belongsTo(aSupportOnFaces3)); + CPPUNIT_ASSERT(aFaces2->belongsTo(aSupportOnFaces3, /*deepCompare*/true)); + + delete aFaces2; + + // getComplement + SUPPORT * aFaces_135 = aFaces135.getComplement(); // => 2,4,6,7,8 + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces_135->getEntity()); + CPPUNIT_ASSERT_EQUAL(5, aFaces_135->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) Memory problem in SUPPORT::sub() + // Invalid read of size 4 + // at 0x34902492: MEDMEM::SUPPORT::sub(int, int, int const*, int) (MEDMEM_Support.cxx:852) + // by 0x3490296B: MEDMEM::SUPPORT::getComplement() const (MEDMEM_Support.cxx:916) + // by 0x34398F1E: MEDMEMTest::testSupport() (MEDMEMTest_Support.cxx:514) + // Address 0x352DB91C is 0 bytes after a block of size 12 alloc'd + // at 0x3414C8E2: operator new[](unsigned) (vg_replace_malloc.c:138) + // by 0x3490243A: MEDMEM::SUPPORT::sub(int, int, int const*, int) (MEDMEM_Support.cxx:847) + // by 0x3490296B: MEDMEM::SUPPORT::getComplement() const (MEDMEM_Support.cxx:916) + // by 0x34398F1E: MEDMEMTest::testSupport() (MEDMEMTest_Support.cxx:514) + //CPPUNIT_FAIL("Memory problem in SUPPORT::sub(): Invalid read of size 4 from array <temp>"); + //#endif + + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) SUPPORT::getComplement() does not work with support on nodes, + // because it uses method MESH::buildSupportOnNodeFromElementList(), + // which does not work if entity = MED_NODE + SUPPORT * aNodes_137 = aNodes137.getComplement(); // => 2,4,5,6,8,9,10-19 + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_NODE, aNodes_137->getEntity()); + CPPUNIT_ASSERT_EQUAL(16, aNodes_137->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + //#endif + + // intersecting + aFaces_135->intersecting(&aFaces123); // => 2 + CPPUNIT_ASSERT_EQUAL(1, aFaces_135->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + CPPUNIT_ASSERT_EQUAL(1, aFaces_135->getValIndFromGlobalNumber(2)); + + //aNodes_137->intersecting(&aNodes248); // => 2,4,8 + //CPPUNIT_ASSERT_EQUAL(3, aNodes_137->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + //CPPUNIT_ASSERT_EQUAL(*aNodes_137, aNodes248); + aNodes137.intersecting(&aNodes248); // => {} + CPPUNIT_ASSERT_EQUAL(0, aNodes137.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + + // blending + aFaces_135->blending(&aFaces135); // => 1,2,3,5 + CPPUNIT_ASSERT_EQUAL(4, aFaces_135->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + + aNodes248.blending(&aNodes27); // => 2,4,7,8 + CPPUNIT_ASSERT_EQUAL(4, aNodes248.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + + // operator= + SUPPORT aCopy1; + aCopy1 = aNodes248; + CPPUNIT_ASSERT_EQUAL(aNodes248, aCopy1); + + // copy constructor + SUPPORT aCopy2 (aFaces135); + CPPUNIT_ASSERT_EQUAL(aFaces135, aCopy2); + + delete aFaces_135; + //#ifdef ENABLE_FORCED_FAILURES + delete aNodes_137; + //#endif + + // profil names + vector<string> aPrN2 (2); // nb. types + aPrN2[0] = "Profil 1"; + aPrN2[1] = "Profil 2"; + aFaces135.setProfilNames(aPrN2); + + // because on all elements + CPPUNIT_ASSERT_THROW(aSupportOnFaces3.setProfilNames(aPrN2), MEDEXCEPTION); + + // because length of vector is not equal to nb.types + vector<string> aPrN3 (3); + CPPUNIT_ASSERT_THROW(aFaces135.setProfilNames(aPrN3), MEDEXCEPTION); + + vector<string> aPrN2Back = aFaces135.getProfilNames(); + CPPUNIT_ASSERT_EQUAL(aPrN2[0], aPrN2Back[0]); + CPPUNIT_ASSERT_EQUAL(aPrN2[1], aPrN2Back[1]); + + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) profil names are not copied by copy constructor and operator=, + // not compared by operator==, not dumped in stream by operator<< + //CPPUNIT_FAIL("Not complete implementation for Profil Names"); + //#endif + + //////////// + // TEST 3 // + //////////// + + SUPPORT aPartialCells (aMesh, "Support On Cells 2,3,4", MED_EN::MED_CELL); + SUPPORT aPartialNodes (aMesh, "Support On Nodes 2,3,4", MED_EN::MED_NODE); + + // setpartial + MED_EN::medGeometryElement gtCells[1] = {MED_EN::MED_TETRA4}; + int nbCells[1] = {3}; + int cells[3] = {2,3,4}; + aPartialCells.setpartial("with description", 1, 3, gtCells, nbCells, cells); + CPPUNIT_ASSERT_EQUAL(1, aPartialCells.getValIndFromGlobalNumber(2)); + CPPUNIT_ASSERT_EQUAL(2, aPartialCells.getValIndFromGlobalNumber(3)); + CPPUNIT_ASSERT_EQUAL(3, aPartialCells.getValIndFromGlobalNumber(4)); + + MED_EN::medGeometryElement gtNodes[1] = {MED_EN::MED_NONE}; + aPartialNodes.setNumberOfGeometricType(1); + aPartialNodes.setGeometricType(gtNodes); + int indexSN[2] = {1,4}; + int valueSN[3] = {2,3,4}; + MEDSKYLINEARRAY * aNumberSN = new MEDSKYLINEARRAY(1, 3, indexSN, valueSN); + aPartialNodes.setpartial(aNumberSN, /*shallowCopy*/false); + delete aNumberSN; + CPPUNIT_ASSERT_EQUAL(1, aPartialNodes.getValIndFromGlobalNumber(2)); + CPPUNIT_ASSERT_EQUAL(2, aPartialNodes.getValIndFromGlobalNumber(3)); + CPPUNIT_ASSERT_EQUAL(3, aPartialNodes.getValIndFromGlobalNumber(4)); + + // changeElementsNbs + + // {1,2,3,4,5,6,7,8,9,10} -> {10,9,8,7,6,5,4,3,2,1} + int renumberingFromOldToNew[10] = {10,9,8,7,6,5,4,3,2,1}; + + CPPUNIT_ASSERT_THROW(aPartialCells.changeElementsNbs + (MED_EN::MED_NODE, renumberingFromOldToNew, 10), MEDEXCEPTION); + + aPartialCells.changeElementsNbs(MED_EN::MED_CELL, renumberingFromOldToNew, 10); + CPPUNIT_ASSERT_EQUAL(3, aPartialCells.getValIndFromGlobalNumber(9)); + CPPUNIT_ASSERT_EQUAL(2, aPartialCells.getValIndFromGlobalNumber(8)); + CPPUNIT_ASSERT_EQUAL(1, aPartialCells.getValIndFromGlobalNumber(7)); + + // {1,2,3,4,5,6,7} -> {1,3,5,7,2,4,6}, {8,9,10,11} -> {8,10,9,11} + int renumberingFromOldToNewP[7] = {1,3,5,7,2,4,6}; + int renumberingFromOldToNewPolyP[4] = {8,10,9,11}; + aPartialCells.changeElementsNbs(MED_EN::MED_CELL, renumberingFromOldToNewP, + 7, renumberingFromOldToNewPolyP); + CPPUNIT_ASSERT_EQUAL(3, aPartialCells.getValIndFromGlobalNumber(10)); + CPPUNIT_ASSERT_EQUAL(2, aPartialCells.getValIndFromGlobalNumber(8)); + CPPUNIT_ASSERT_EQUAL(1, aPartialCells.getValIndFromGlobalNumber(6)); + + // this method does not suit for nodes renumbering! + // {1,2,3} -> {3,2,1}, {4,5,6,7} -> {5,6,7,4} + //int renumberingFromOldToNewN[3] = {3,2,1}; + //int renumberingFromOldToNewPolyN[4] = {5,6,7,4}; + //aPartialNodes.changeElementsNbs(MED_EN::MED_NODE, renumberingFromOldToNewN, + // 3, renumberingFromOldToNewPolyN); + + // getBoundaryElements + //#ifdef ENABLE_FAULTS + // (BUG) Segmentation Fault during SUPPORT::getBoundaryElements() + // ??? May be mesh is not complete ??? + SUPPORT aBoundaryFaces (aMesh, "meshing boundary faces", MED_EN::MED_FACE); + aBoundaryFaces.getBoundaryElements(); + //cout << "aBoundaryFaces:" << endl; + //cout << aBoundaryFaces << endl; + + SUPPORT * aBoundaryNodes = aSupportOnFaces3.getBoundaryElements(MED_EN::MED_NODE); + //cout << "aSupportOnFaces3:" << endl; + //cout << aSupportOnFaces3 << endl; + //cout << "aBoundaryNodes:" << endl; + //cout << aBoundaryNodes << endl; + delete aBoundaryNodes; + //#endif + //#ifdef ENABLE_FORCED_FAILURES + //CPPUNIT_FAIL("Segmentation Fault during SUPPORT::getBoundaryElements()"); + // Invalid write of size 4 + // at 0x3439DFCE: void std::_Construct<int, int>(int*, int const&) (stl_construct.h:81) + // by 0x3476E4D1: std::vector<int, std::allocator<int> >::push_back(int const&) (stl_vector.h:560) + // by 0x34763DDB: MEDMEM::CONNECTIVITY::calculateReverseNodalConnectivity() (MEDMEM_Connectivity.cxx:1155) + // by 0x347655FF: MEDMEM::CONNECTIVITY::calculateDescendingConnectivity() (MEDMEM_Connectivity.cxx:1333) + // by 0x3476363E: MEDMEM::CONNECTIVITY::getReverseDescendingConnectivity() (MEDMEM_Connectivity.cxx:1090) + // by 0x34772AB6: MEDMEM::CONNECTIVITY::getReverseConnectivity(long, long) (MEDMEM_Connectivity.hxx:503) + // by 0x348F4F4B: MEDMEM::MESH::getReverseConnectivity(long, long) const (MEDMEM_Mesh.hxx:848) + // by 0x348FF559: MEDMEM::SUPPORT::getBoundaryElements() (MEDMEM_Support.cxx:483) + // by 0x3439C8E5: MEDMEMTest::testSupport() (MEDMEMTest_Support.cxx:641) + // Address 0x61666A2F is not stack'd, malloc'd or (recently) free'd + //#endif + + delete aMesh; + delete aMeshOneMore; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_Support_fault.cxx b/src/MEDMEMCppTest/MEDMEMTest_Support_fault.cxx new file mode 100644 index 000000000..ed25b425d --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Support_fault.cxx @@ -0,0 +1,698 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_STRING.hxx" +#include "MEDMEM_Support.hxx" + +#include <sstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; + +// #52: MEDMEM_Support.hxx } MEDMEMTest_Support.cxx + +/*! + * Check methods (48), defined in MEDMEM_Support.hxx: + * class SUPPORT : public RCBASE { + * (+) SUPPORT(); + * (+) SUPPORT(MESH* Mesh, string Name="", MED_EN::medEntityMesh Entity=MED_EN::MED_CELL); + * (+) SUPPORT(const SUPPORT & m); + * (+) virtual ~SUPPORT(); + * + * (+) friend ostream & operator<<(ostream &os,const SUPPORT &my); + * (+) SUPPORT& operator=(const SUPPORT &support); + * (+) bool operator == (const SUPPORT &support) const; + * (+) bool deepCompare(const SUPPORT &support) const; + * + * (+) void update(); + * + * (+) inline void setName(string Name); + * (+) inline void setDescription(string Description); + * (+) void setMesh(MESH *Mesh) const; + * (+) inline void setMeshName(const string & meshName); + * (+) inline void setAll(bool All); + * (+) inline void setEntity(MED_EN::medEntityMesh Entity); + * + * (+) inline void setNumberOfGeometricType(int NumberOfGeometricType); + * (+) inline void setGeometricType(const MED_EN::medGeometryElement *GeometricType); + * (+) inline void setNumberOfElements(const int *NumberOfElements); + * (+) inline void setTotalNumberOfElements(int TotalNumberOfElements); + * (+) inline void setNumber(MEDSKYLINEARRAY * Number); + * (+) inline void setNumber(const int * index, const int* value, bool shallowCopy=false); + * + * (+) inline string getName() const; + * (+) inline string getDescription() const; + * (+) virtual inline MESH * getMesh() const; + * (+) string getMeshName() const; + * (+) inline MED_EN::medEntityMesh getEntity() const; + * (+) inline bool isOnAllElements() const; + * + * (+) inline int getNumberOfTypes() const; + * (+) inline const MED_EN::medGeometryElement* getTypes() const; + * (+) inline int getNumberOfElements + * (MED_EN::medGeometryElement GeometricType) const throw (MEDEXCEPTION); + * (+) inline const int * getNumberOfElements() const throw (MEDEXCEPTION); + * (+) virtual inline MEDSKYLINEARRAY * getnumber() const throw (MEDEXCEPTION); + * (NO METHOD IN THIS BRANCH) virtual inline MEDSKYLINEARRAY * getnumberFromFile() const throw (MEDEXCEPTION); + * (+) virtual inline const int * getNumber + * (MED_EN::medGeometryElement GeometricType) const throw (MEDEXCEPTION); + * (NO METHOD IN THIS BRANCH) virtual inline const int * getNumberFromFile + * (MED_EN::medGeometryElement GeometricType) const throw (MEDEXCEPTION); + * (+) virtual inline const int * getNumberIndex() const throw (MEDEXCEPTION); + * (+) virtual int getValIndFromGlobalNumber(const int number) const throw (MEDEXCEPTION); + * + * (+) void blending(SUPPORT * mySupport) throw (MEDEXCEPTION); + * + * (+) void setpartial(string Description, int NumberOfGeometricType, + * int TotalNumberOfEntity, MED_EN::medGeometryElement *GeometricType, + * int *NumberOfEntity, int *NumberValue); + * (+) void setpartial(MEDSKYLINEARRAY * number, bool shallowCopy=false) throw (MEDEXCEPTION); + * (NO METHOD IN THIS BRANCH) void setpartial_fromfile(MEDSKYLINEARRAY * number, bool shallowCopy=false) throw (MEDEXCEPTION); + * + * (+) void setProfilNames(vector<string> profilNames) throw (MEDEXCEPTION); + * (+) vector<string> getProfilNames() const throw (MEDEXCEPTION); + * + * (+) void getBoundaryElements() throw (MEDEXCEPTION); + * + * (+) void changeElementsNbs(MED_EN::medEntityMesh entity, const int *renumberingFromOldToNew, + * int limitNbClassicPoly, const int *renumberingFromOldToNewPoly=0); + * (+) void intersecting(SUPPORT * mySupport) throw (MEDEXCEPTION); + * (+) bool belongsTo(const SUPPORT& other, bool deepCompare=false) const; + * + * (+) SUPPORT *getComplement() const; + * (+) SUPPORT *substract(const SUPPORT& other) const throw (MEDEXCEPTION); + * + * (+) SUPPORT *getBoundaryElements(MED_EN::medEntityMesh Entity) const throw (MEDEXCEPTION); + * + * (+) void fillFromNodeList(const list<int>& listOfNode) throw (MEDEXCEPTION); + * (+) void fillFromElementList(const list<int>& listOfElt) throw (MEDEXCEPTION); + * + * (+) void clearDataOnNumbers(); + * + * (reference counter presently disconnected in C++) virtual void addReference() const; + * (reference counter presently disconnected in C++) virtual void removeReference() const; + * } + */ +void MEDMEMTest_testSupport() +{ + // cells connectivities + //const int NumberOfCellTypes = 3; + //MED_EN::medGeometryElement CellTypes[NumberOfCellTypes] = + // {MED_EN::MED_TETRA4, MED_EN::MED_PYRA5, MED_EN::MED_HEXA8}; + //const int NumberOfCells[NumberOfCellTypes] = {12, 2, 2}; + + // faces connectivities + //const int NumberOfFaceTypes = 2; + //MED_EN::medGeometryElement FaceTypes[NumberOfFaceTypes] = {MED_EN::MED_TRIA3, MED_EN::MED_QUAD4}; + //const int NumberOfFaces[NumberOfFaceTypes] = {4, 4}; + + MESH * aMesh = MEDMEMTest_createTestMesh(); + MESH * aMeshOneMore = MEDMEMTest_createTestMesh(); + + //////////// + // TEST 1 // + //////////// + + SUPPORT aSupportOnFaces1 (aMesh, "Support On Faces 1", MED_EN::MED_FACE); + SUPPORT aSupportOnCells1 (aMesh, "Support On Cells 1"/*, MED_EN::MED_CELL*/); + + SUPPORT aSupportOnFaces2; + SUPPORT aSupportOnCells2; + + SUPPORT aSupportOnFaces3 (aMeshOneMore, "Support On Faces 3", MED_EN::MED_FACE); + + // entity + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aSupportOnFaces1.getEntity()); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_CELL, aSupportOnCells1.getEntity()); + + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_CELL, aSupportOnFaces2.getEntity()); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_CELL, aSupportOnCells2.getEntity()); + + aSupportOnFaces2.setEntity(MED_EN::MED_FACE); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aSupportOnFaces2.getEntity()); + + // isOnAllElements + CPPUNIT_ASSERT(aSupportOnFaces1.isOnAllElements()); + CPPUNIT_ASSERT(aSupportOnCells1.isOnAllElements()); + + CPPUNIT_ASSERT(!aSupportOnFaces2.isOnAllElements()); + CPPUNIT_ASSERT(!aSupportOnCells2.isOnAllElements()); + + // mesh and mesh name + CPPUNIT_ASSERT_THROW(aSupportOnFaces1.setMeshName("Mesh 1"), MEDEXCEPTION); + + aSupportOnFaces2.setMeshName("Mesh 1"); + aSupportOnCells2.setMeshName("Mesh 1"); + CPPUNIT_ASSERT(aSupportOnFaces2.getMeshName() == "Mesh 1"); + CPPUNIT_ASSERT(aSupportOnCells2.getMeshName() == "Mesh 1"); + + aSupportOnFaces2.setMesh(aMesh); + CPPUNIT_ASSERT_THROW(aSupportOnFaces2.setMeshName("Mesh 1"), MEDEXCEPTION); + + aSupportOnCells1.setMesh(NULL); + aSupportOnCells1.setMeshName("Mesh 1"); + + CPPUNIT_ASSERT(aSupportOnFaces1.getMeshName() == "meshing"); + CPPUNIT_ASSERT(aSupportOnFaces2.getMeshName() == "meshing"); + CPPUNIT_ASSERT(aSupportOnCells1.getMeshName() == "Mesh 1"); + CPPUNIT_ASSERT(aSupportOnCells2.getMeshName() == "Mesh 1"); + + CPPUNIT_ASSERT(aSupportOnFaces1.getMesh() == aMesh); + CPPUNIT_ASSERT(aSupportOnFaces2.getMesh() == aMesh); + CPPUNIT_ASSERT(aSupportOnCells1.getMesh() == NULL); + CPPUNIT_ASSERT(aSupportOnCells2.getMesh() == NULL); + + // operator == + aSupportOnFaces2.setName("Support On Faces 2"); + aSupportOnCells2.setName("Support On Cells 2"); + + // because aSupportOnFaces1 is on all elements, but aSupportOnFaces2 not + CPPUNIT_ASSERT(!(aSupportOnFaces1 == aSupportOnFaces2)); + + aSupportOnCells1.setAll(false); + CPPUNIT_ASSERT(!aSupportOnCells1.isOnAllElements()); + // this is only sets flag _isOnAllElts to false, but not clear elements and types + // information, so aSupportOnCells1 is not equal to aSupportOnCells2 at this moment + +//#ifdef ENABLE_FAULTS + // (BUG) SUPPORT::operator= gives "Segmentation Fault" on supports with NULL meshes!!! + CPPUNIT_ASSERT(!(aSupportOnCells1 == aSupportOnCells2)); +//#endif +//#ifdef ENABLE_FORCED_FAILURES +// CPPUNIT_FAIL("SUPPORT::operator= gives Segmentation Fault on supports with NULL meshes!!!"); +//#endif + + aSupportOnFaces2.setAll(true); + CPPUNIT_ASSERT(aSupportOnFaces2.isOnAllElements()); + // flag _isOnAllElts now is set to true, but we need also to call update() + // to set elements and types information from mesh to this support + CPPUNIT_ASSERT(!(aSupportOnFaces1 == aSupportOnFaces2)); + aSupportOnFaces2.update(); + CPPUNIT_ASSERT(aSupportOnFaces1 == aSupportOnFaces2); + + // deep compare + CPPUNIT_ASSERT(aSupportOnFaces1.deepCompare(aSupportOnFaces2)); + + CPPUNIT_ASSERT(!(aSupportOnFaces1 == aSupportOnFaces3)); // different mesh pointers + CPPUNIT_ASSERT(aSupportOnFaces1.deepCompare(aSupportOnFaces3)); // meshes are really equal + + // description + aSupportOnFaces1.setDescription("Support on all faces with mesh pointer"); + aSupportOnFaces2.setDescription("Support on all faces with mesh pointer"); + + aSupportOnCells1.setDescription("Support on a part of cells with mesh name"); + aSupportOnCells2.setDescription("Support on a part of cells with mesh name"); + + CPPUNIT_ASSERT(aSupportOnFaces1.getDescription() == "Support on all faces with mesh pointer"); + CPPUNIT_ASSERT(aSupportOnFaces2.getDescription() == "Support on all faces with mesh pointer"); + CPPUNIT_ASSERT(aSupportOnCells1.getDescription() == "Support on a part of cells with mesh name"); + CPPUNIT_ASSERT(aSupportOnCells2.getDescription() == "Support on a part of cells with mesh name"); + + // operator<< + ostringstream ostr1; + ostr1 << aSupportOnFaces1; + CPPUNIT_ASSERT(ostr1.str() != ""); + + ostringstream ostr2; + ostr2 << aSupportOnCells2; + CPPUNIT_ASSERT(ostr2.str() != ""); + + // set/get elements and types information + + // 1. aSupportOnCells1 is not on all elements, but now it contains information + // about all cells of aMesh, because it was created on mesh and with parameters. + CPPUNIT_ASSERT_EQUAL(3, aSupportOnCells1.getNumberOfTypes()); + CPPUNIT_ASSERT(aSupportOnCells1.getTypes() != NULL); + + //const int * nbEltsSC_old = aSupportOnCells1.getNumberOfElements(); // {12, 2, 2} + + aSupportOnCells1.setNumberOfGeometricType(0); + CPPUNIT_ASSERT_EQUAL(0, aSupportOnCells1.getNumberOfTypes()); + CPPUNIT_ASSERT(aSupportOnCells1.getTypes() == NULL); + + MED_EN::medGeometryElement aSCTypes[2] = {MED_EN::MED_PYRA5, MED_EN::MED_PENTA15}; + aSupportOnCells1.setNumberOfGeometricType(2); + aSupportOnCells1.setGeometricType(aSCTypes); + + CPPUNIT_ASSERT_EQUAL(2, aSupportOnCells1.getNumberOfTypes()); + CPPUNIT_ASSERT(aSupportOnCells1.getTypes() != NULL); + CPPUNIT_ASSERT(aSupportOnCells1.getNumberOfElements() == NULL); // reset by setNumberOfGeometricType + + int nbEltsSC[2] = {2, 1}; + aSupportOnCells1.setNumberOfElements(nbEltsSC); + + const int * nbEltsSCBack = aSupportOnCells1.getNumberOfElements(); + CPPUNIT_ASSERT_EQUAL(2, aSupportOnCells1.getNumberOfElements(MED_EN::MED_PYRA5)); + CPPUNIT_ASSERT_EQUAL(2, nbEltsSCBack[0]); + CPPUNIT_ASSERT_EQUAL(1, aSupportOnCells1.getNumberOfElements(MED_EN::MED_PENTA15)); + CPPUNIT_ASSERT_EQUAL(1, nbEltsSCBack[1]); + CPPUNIT_ASSERT_EQUAL(3, aSupportOnCells1.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + + // old types + CPPUNIT_ASSERT_THROW(aSupportOnCells1.getNumberOfElements(MED_EN::MED_TETRA4), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSupportOnCells1.getNumberOfElements(MED_EN::MED_HEXA8), MEDEXCEPTION); + + //_number= new MEDSKYLINEARRAY(_numberOfGeometricType,_totalNumberOfElements,index,value,shallowCopy); + int indexSC[3] = {1,3,4}; // length = nb.types + 1 + int valueSC[3] = {21,22,47}; // length = total nb. of elements + aSupportOnCells1.setNumber(indexSC, valueSC); + + // check number + MEDSKYLINEARRAY * aNumberSCBack = aSupportOnCells1.getnumber(); + + CPPUNIT_ASSERT_EQUAL(2, aNumberSCBack->getNumberOf()); + CPPUNIT_ASSERT_EQUAL(3, aNumberSCBack->getLength()); + const int * ind = aNumberSCBack->getIndex(); + const int * val = aNumberSCBack->getValue(); + CPPUNIT_ASSERT_EQUAL(1, ind[0]); + CPPUNIT_ASSERT_EQUAL(3, ind[1]); + CPPUNIT_ASSERT_EQUAL(4, ind[2]); + CPPUNIT_ASSERT_EQUAL(21, val[0]); + CPPUNIT_ASSERT_EQUAL(22, val[1]); + CPPUNIT_ASSERT_EQUAL(47, val[2]); + + // 2. aSupportOnCells2 is not on all elements, and now it contains + // no information about elements of a mesh + CPPUNIT_ASSERT_EQUAL(0, aSupportOnCells2.getNumberOfTypes()); + CPPUNIT_ASSERT(aSupportOnCells2.getTypes() == NULL); + + aSupportOnCells2.setNumberOfGeometricType(2); + aSupportOnCells2.setGeometricType(aSCTypes); + + CPPUNIT_ASSERT_EQUAL(2, aSupportOnCells2.getNumberOfTypes()); + CPPUNIT_ASSERT(aSupportOnCells2.getTypes() != NULL); + + aSupportOnCells2.setNumberOfElements(nbEltsSC); + + // we create MEDSKYLINEARRAY as pointer, because aSupportOnCells2 will + // become an owner of it, and we must not delete it. + MEDSKYLINEARRAY * aNumberSC = new MEDSKYLINEARRAY(2, 3, indexSC, valueSC); + aSupportOnCells2.setNumber(aNumberSC); + + // check number + const int * aNumberIndexSC = aSupportOnCells2.getNumberIndex(); + CPPUNIT_ASSERT_EQUAL(1, aNumberIndexSC[0]); + CPPUNIT_ASSERT_EQUAL(3, aNumberIndexSC[1]); + CPPUNIT_ASSERT_EQUAL(4, aNumberIndexSC[2]); + + const int * aNbPYRA5 = aSupportOnCells2.getNumber(MED_EN::MED_PYRA5); + const int * aNbPENTA15 = aSupportOnCells2.getNumber(MED_EN::MED_PENTA15); + CPPUNIT_ASSERT_THROW(aSupportOnCells2.getNumber(MED_EN::MED_TETRA4), MEDEXCEPTION); + + const int * aNbC = aSupportOnCells2.getNumber(MED_EN::MED_ALL_ELEMENTS); + + CPPUNIT_ASSERT_EQUAL(21, aNbPYRA5[0]); + CPPUNIT_ASSERT_EQUAL(22, aNbPYRA5[1]); + CPPUNIT_ASSERT_EQUAL(47, aNbPENTA15[0]); + + CPPUNIT_ASSERT_EQUAL(21, aNbC[0]); + CPPUNIT_ASSERT_EQUAL(22, aNbC[1]); + CPPUNIT_ASSERT_EQUAL(47, aNbC[2]); + + // getValIndFromGlobalNumber + CPPUNIT_ASSERT_EQUAL(1, aSupportOnCells2.getValIndFromGlobalNumber(21)); + CPPUNIT_ASSERT_EQUAL(2, aSupportOnCells2.getValIndFromGlobalNumber(22)); + CPPUNIT_ASSERT_EQUAL(3, aSupportOnCells2.getValIndFromGlobalNumber(47)); + // not existing element + CPPUNIT_ASSERT_THROW(aSupportOnCells2.getValIndFromGlobalNumber(10), MEDEXCEPTION); + + // compare aSupportOnCells1 and aSupportOnCells2 + + // temporary set mesh (because of bug with operator==) + aSupportOnCells1.setMesh(aMesh); + aSupportOnCells2.setMesh(aMesh); + + CPPUNIT_ASSERT_EQUAL(aSupportOnCells1, aSupportOnCells2); + + // restore mesh name + aSupportOnCells1.setMesh(NULL); + aSupportOnCells2.setMesh(NULL); + aSupportOnCells1.setMeshName("Mesh 1"); + aSupportOnCells2.setMeshName("Mesh 1"); + + // 3. aSupportOnFacesN is on all elements, and it contains + // information about all faces of aMesh + CPPUNIT_ASSERT_EQUAL(2, aSupportOnFaces1.getNumberOfTypes()); + const MED_EN::medGeometryElement* aSF1Types = aSupportOnFaces1.getTypes(); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_TRIA3, aSF1Types[0]); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_QUAD4, aSF1Types[1]); +//#ifdef ENABLE_FORCED_FAILURES + // (BUG) Comment to method SUPPORT::getTypes() says: + // "If isOnAllElements is false, returns an array of %medGeometryElement types used by the support." + // But in fact it returns types in any case (comment to SUPPORT::setAll() gives more information). +// CPPUNIT_FAIL("Comment and implementation does not match for SUPPORT::getTypes()"); + // This concerns also method SUPPORT::update(), being called from constructor, + // which fills internal SUPPORT structures with information about mesh elements + // in case of isOnAllElements == true. + // Also comments and implementation does not match for SUPPORT::getNumberOfElements(). + // It seems that in case "isOnAllElements == true" calls like getNumberOfElements() + // must be redirected to mesh, but what if mesh is not set (mesh name used instead)?. +//#endif + const int * nbEltsSF1 = aSupportOnFaces1.getNumberOfElements(); + CPPUNIT_ASSERT_EQUAL(4, aSupportOnFaces1.getNumberOfElements(MED_EN::MED_TRIA3)); + CPPUNIT_ASSERT_EQUAL(4, nbEltsSF1[0]); + CPPUNIT_ASSERT_EQUAL(4, aSupportOnFaces1.getNumberOfElements(MED_EN::MED_QUAD4)); + CPPUNIT_ASSERT_EQUAL(4, nbEltsSF1[1]); + CPPUNIT_ASSERT_EQUAL(8, aSupportOnFaces1.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumberOfElements(MED_EN::MED_TRIA6), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumberOfElements(MED_EN::MED_QUAD8), MEDEXCEPTION); + + // check number + CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumberIndex(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumber(MED_EN::MED_TRIA3), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumber(MED_EN::MED_QUAD4), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getNumber(MED_EN::MED_ALL_ELEMENTS), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aSupportOnFaces1.getnumber(), MEDEXCEPTION); + + // getValIndFromGlobalNumber + CPPUNIT_ASSERT_EQUAL(8, aMesh->getNumberOfElements(MED_EN::MED_FACE, MED_EN::MED_ALL_ELEMENTS)); + for (int i = 1; i <= 8; i++) { + CPPUNIT_ASSERT_EQUAL(i, aSupportOnFaces1.getValIndFromGlobalNumber(i)); + } + +//#ifdef ENABLE_FORCED_FAILURES + // Why methods setNumber do not throw exception in case "isOnAllElements == true", + // like methods getNumber do? + //CPPUNIT_ASSERT_THROW(aSupportOnFaces1.setNumber(indexSF1, valueSF1)); +//#endif + + // skl: setTotalNumberOfElements() is removed. + //#ifdef ENABLE_FORCED_FAILURES + // It seems to be dangerous and useless to have method SUPPORT::setTotalNumberOfElements() + //CPPUNIT_FAIL("It seems to be dangerous and useless to have method SUPPORT::setTotalNumberOfElements()"); + //#endif + + // following test is commented since method + // setTotalNumberOfElements() is removed. + /* + // setTotalNumberOfElements + aSupportOnFaces1.setTotalNumberOfElements(1000); + CPPUNIT_ASSERT_EQUAL(1000, aSupportOnFaces1.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + */ + + // clearDataOnNumbers + aSupportOnCells1.clearDataOnNumbers(); + CPPUNIT_ASSERT_EQUAL(0, aSupportOnCells1.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + CPPUNIT_ASSERT_EQUAL(0, aSupportOnCells1.getNumberOfTypes()); + CPPUNIT_ASSERT_THROW(aSupportOnCells1.getnumber(), MEDEXCEPTION); + + //////////// + // TEST 2 // + //////////// + + list<int> nodes137; + nodes137.push_back(1); + nodes137.push_back(3); + nodes137.push_back(7); + + list<int> nodes248; + nodes248.push_back(2); + nodes248.push_back(4); + nodes248.push_back(8); + + list<int> nodes27; + nodes27.push_back(2); + nodes27.push_back(7); + + SUPPORT aNodes137 (aMesh, "Support On Nodes 1,3,7", MED_EN::MED_CELL); + SUPPORT aNodes248 (aMesh, "Support On Nodes 2,4,8", MED_EN::MED_CELL); + SUPPORT aNodes27 (aMesh, "Support On Nodes 2,7" , MED_EN::MED_CELL); + + aNodes137.fillFromNodeList(nodes137); + aNodes248.fillFromNodeList(nodes248); + aNodes27.fillFromNodeList(nodes27); + + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_NODE, aNodes137.getEntity()); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_NODE, aNodes248.getEntity()); + + list<int>::const_iterator iter137 = nodes137.begin(); + list<int>::const_iterator iter248 = nodes248.begin(); + for (int i = 1; i <= 3; i++, iter137++, iter248++) { + CPPUNIT_ASSERT_EQUAL(i, aNodes137.getValIndFromGlobalNumber(*iter137)); + CPPUNIT_ASSERT_EQUAL(i, aNodes248.getValIndFromGlobalNumber(*iter248)); + } + + //////////// + + list<int> faces123; + faces123.push_back(1); + faces123.push_back(2); + faces123.push_back(3); + + list<int> faces135; + faces135.push_back(1); + faces135.push_back(3); + faces135.push_back(5); + + SUPPORT aFaces123 (aMesh, "Support On Faces 1,2,3", MED_EN::MED_FACE); + SUPPORT aFaces135 (aMesh, "Support On Faces 1,3,5", MED_EN::MED_FACE); + + aFaces123.fillFromElementList(faces123); + aFaces135.fillFromElementList(faces135); + + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces123.getEntity()); + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces135.getEntity()); + + list<int>::const_iterator iter123 = faces123.begin(); + list<int>::const_iterator iter135 = faces135.begin(); + for (int i = 1; i <= 3; i++, iter123++, iter135++) { + CPPUNIT_ASSERT_EQUAL(i, aFaces123.getValIndFromGlobalNumber(*iter123)); + CPPUNIT_ASSERT_EQUAL(i, aFaces135.getValIndFromGlobalNumber(*iter135)); + } + + // substract + SUPPORT * aFaces2 = aFaces123.substract(aFaces135); // => 2 + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces2->getEntity()); + CPPUNIT_ASSERT_EQUAL(1, aFaces2->getValIndFromGlobalNumber(2)); + CPPUNIT_ASSERT_EQUAL(1, aFaces2->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + + CPPUNIT_ASSERT_THROW(aFaces123.substract(aNodes137), MEDEXCEPTION); + +//#ifdef ENABLE_FORCED_FAILURES + // (BUG) SUPPORT::substract() does not work with supports on nodes, + // because it uses method MESH::buildSupportOnNodeFromElementList(), + // which does not work if entity = MED_NODE + //SUPPORT * aNodes137mesh = aMesh->buildSupportOnNodeFromElementList(nodes137, MED_EN::MED_NODE); + //delete aNodes137mesh; + SUPPORT * aNodes137sub = aNodes137.substract(aNodes248); // => 1,3,7 + CPPUNIT_ASSERT_EQUAL(*aNodes137sub, aNodes137); + delete aNodes137sub; +//#endif + + // belongsTo + CPPUNIT_ASSERT(aFaces2->belongsTo(aFaces123)); + CPPUNIT_ASSERT(!aFaces2->belongsTo(aFaces135)); + + CPPUNIT_ASSERT(!aFaces2->belongsTo(aSupportOnFaces3)); + CPPUNIT_ASSERT(aFaces2->belongsTo(aSupportOnFaces3, /*deepCompare*/true)); + + delete aFaces2; + + // getComplement + SUPPORT * aFaces_135 = aFaces135.getComplement(); // => 2,4,6,7,8 + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_FACE, aFaces_135->getEntity()); + CPPUNIT_ASSERT_EQUAL(5, aFaces_135->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + +//#ifdef ENABLE_FORCED_FAILURES + // (BUG) Memory problem in SUPPORT::sub() + // Invalid read of size 4 + // at 0x34902492: MEDMEM::SUPPORT::sub(int, int, int const*, int) (MEDMEM_Support.cxx:852) + // by 0x3490296B: MEDMEM::SUPPORT::getComplement() const (MEDMEM_Support.cxx:916) + // by 0x34398F1E: MEDMEMTest::testSupport() (MEDMEMTest_Support.cxx:514) + // Address 0x352DB91C is 0 bytes after a block of size 12 alloc'd + // at 0x3414C8E2: operator new[](unsigned) (vg_replace_malloc.c:138) + // by 0x3490243A: MEDMEM::SUPPORT::sub(int, int, int const*, int) (MEDMEM_Support.cxx:847) + // by 0x3490296B: MEDMEM::SUPPORT::getComplement() const (MEDMEM_Support.cxx:916) + // by 0x34398F1E: MEDMEMTest::testSupport() (MEDMEMTest_Support.cxx:514) +// CPPUNIT_FAIL("Memory problem in SUPPORT::sub(): Invalid read of size 4 from array <temp>"); +//#endif + +//#ifdef ENABLE_FORCED_FAILURES + // (BUG) SUPPORT::getComplement() does not work with support on nodes, + // because it uses method MESH::buildSupportOnNodeFromElementList(), + // which does not work if entity = MED_NODE + SUPPORT * aNodes_137 = aNodes137.getComplement(); // => 2,4,5,6,8,9,10-19 + CPPUNIT_ASSERT_EQUAL(MED_EN::MED_NODE, aNodes_137->getEntity()); + CPPUNIT_ASSERT_EQUAL(16, aNodes_137->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); +//#endif + + // intersecting + aFaces_135->intersecting(&aFaces123); // => 2 + CPPUNIT_ASSERT_EQUAL(1, aFaces_135->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + CPPUNIT_ASSERT_EQUAL(1, aFaces_135->getValIndFromGlobalNumber(2)); + + //aNodes_137->intersecting(&aNodes248); // => 2,4,8 + //CPPUNIT_ASSERT_EQUAL(3, aNodes_137->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + //CPPUNIT_ASSERT_EQUAL(*aNodes_137, aNodes248); + aNodes137.intersecting(&aNodes248); // => {} + CPPUNIT_ASSERT_EQUAL(0, aNodes137.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + + // blending + aFaces_135->blending(&aFaces135); // => 1,2,3,5 + CPPUNIT_ASSERT_EQUAL(4, aFaces_135->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + + aNodes248.blending(&aNodes27); // => 2,4,7,8 + CPPUNIT_ASSERT_EQUAL(4, aNodes248.getNumberOfElements(MED_EN::MED_ALL_ELEMENTS)); + + // operator= + SUPPORT aCopy1; + aCopy1 = aNodes248; + CPPUNIT_ASSERT_EQUAL(aNodes248, aCopy1); + + // copy constructor + SUPPORT aCopy2 (aFaces135); + CPPUNIT_ASSERT_EQUAL(aFaces135, aCopy2); + + delete aFaces_135; +//#ifdef ENABLE_FORCED_FAILURES + delete aNodes_137; +//#endif + + // profil names + vector<string> aPrN2 (2); // nb. types + aPrN2[0] = "Profil 1"; + aPrN2[1] = "Profil 2"; + aFaces135.setProfilNames(aPrN2); + + // because on all elements + CPPUNIT_ASSERT_THROW(aSupportOnFaces3.setProfilNames(aPrN2), MEDEXCEPTION); + + // because length of vector is not equal to nb.types + vector<string> aPrN3 (3); + CPPUNIT_ASSERT_THROW(aFaces135.setProfilNames(aPrN3), MEDEXCEPTION); + + vector<string> aPrN2Back = aFaces135.getProfilNames(); + CPPUNIT_ASSERT_EQUAL(aPrN2[0], aPrN2Back[0]); + CPPUNIT_ASSERT_EQUAL(aPrN2[1], aPrN2Back[1]); + +//#ifdef ENABLE_FORCED_FAILURES + // (BUG) profil names are not copied by copy constructor and operator=, + // not compared by operator==, not dumped in stream by operator<< + //CPPUNIT_FAIL("Not complete implementation for Profil Names"); +//#endif + + //////////// + // TEST 3 // + //////////// + + SUPPORT aPartialCells (aMesh, "Support On Cells 2,3,4", MED_EN::MED_CELL); + SUPPORT aPartialNodes (aMesh, "Support On Nodes 2,3,4", MED_EN::MED_NODE); + + // setpartial + MED_EN::medGeometryElement gtCells[1] = {MED_EN::MED_TETRA4}; + int nbCells[1] = {3}; + int cells[3] = {2,3,4}; + aPartialCells.setpartial("with description", 1, 3, gtCells, nbCells, cells); + CPPUNIT_ASSERT_EQUAL(1, aPartialCells.getValIndFromGlobalNumber(2)); + CPPUNIT_ASSERT_EQUAL(2, aPartialCells.getValIndFromGlobalNumber(3)); + CPPUNIT_ASSERT_EQUAL(3, aPartialCells.getValIndFromGlobalNumber(4)); + + MED_EN::medGeometryElement gtNodes[1] = {MED_EN::MED_NONE}; + aPartialNodes.setNumberOfGeometricType(1); + aPartialNodes.setGeometricType(gtNodes); + int indexSN[2] = {1,4}; + int valueSN[3] = {2,3,4}; + MEDSKYLINEARRAY * aNumberSN = new MEDSKYLINEARRAY(1, 3, indexSN, valueSN); + aPartialNodes.setpartial(aNumberSN, /*shallowCopy*/false); + delete aNumberSN; + CPPUNIT_ASSERT_EQUAL(1, aPartialNodes.getValIndFromGlobalNumber(2)); + CPPUNIT_ASSERT_EQUAL(2, aPartialNodes.getValIndFromGlobalNumber(3)); + CPPUNIT_ASSERT_EQUAL(3, aPartialNodes.getValIndFromGlobalNumber(4)); + + // changeElementsNbs + + // {1,2,3,4,5,6,7,8,9,10} -> {10,9,8,7,6,5,4,3,2,1} + int renumberingFromOldToNew[10] = {10,9,8,7,6,5,4,3,2,1}; + + CPPUNIT_ASSERT_THROW(aPartialCells.changeElementsNbs + (MED_EN::MED_NODE, renumberingFromOldToNew, 10), MEDEXCEPTION); + + aPartialCells.changeElementsNbs(MED_EN::MED_CELL, renumberingFromOldToNew, 10); + CPPUNIT_ASSERT_EQUAL(3, aPartialCells.getValIndFromGlobalNumber(9)); + CPPUNIT_ASSERT_EQUAL(2, aPartialCells.getValIndFromGlobalNumber(8)); + CPPUNIT_ASSERT_EQUAL(1, aPartialCells.getValIndFromGlobalNumber(7)); + + // {1,2,3,4,5,6,7} -> {1,3,5,7,2,4,6}, {8,9,10,11} -> {8,10,9,11} + int renumberingFromOldToNewP[7] = {1,3,5,7,2,4,6}; + int renumberingFromOldToNewPolyP[4] = {8,10,9,11}; + aPartialCells.changeElementsNbs(MED_EN::MED_CELL, renumberingFromOldToNewP, + 7, renumberingFromOldToNewPolyP); + CPPUNIT_ASSERT_EQUAL(3, aPartialCells.getValIndFromGlobalNumber(10)); + CPPUNIT_ASSERT_EQUAL(2, aPartialCells.getValIndFromGlobalNumber(8)); + CPPUNIT_ASSERT_EQUAL(1, aPartialCells.getValIndFromGlobalNumber(6)); + + // this method does not suit for nodes renumbering! + // {1,2,3} -> {3,2,1}, {4,5,6,7} -> {5,6,7,4} + //int renumberingFromOldToNewN[3] = {3,2,1}; + //int renumberingFromOldToNewPolyN[4] = {5,6,7,4}; + //aPartialNodes.changeElementsNbs(MED_EN::MED_NODE, renumberingFromOldToNewN, + // 3, renumberingFromOldToNewPolyN); + + // getBoundaryElements +//#ifdef ENABLE_FAULTS + // (BUG) Segmentation Fault during SUPPORT::getBoundaryElements() + // ??? May be mesh is not complete ??? + SUPPORT aBoundaryFaces (aMesh, "meshing boundary faces", MED_EN::MED_FACE); + aBoundaryFaces.getBoundaryElements(); + //cout << "aBoundaryFaces:" << endl; + //cout << aBoundaryFaces << endl; + + SUPPORT * aBoundaryNodes = aSupportOnFaces3.getBoundaryElements(MED_EN::MED_NODE); + //cout << "aSupportOnFaces3:" << endl; + //cout << aSupportOnFaces3 << endl; + //cout << "aBoundaryNodes:" << endl; + //cout << aBoundaryNodes << endl; + delete aBoundaryNodes; +//#endif +//#ifdef ENABLE_FORCED_FAILURES +// CPPUNIT_FAIL("Segmentation Fault during SUPPORT::getBoundaryElements()"); + // Invalid write of size 4 + // at 0x3439DFCE: void std::_Construct<int, int>(int*, int const&) (stl_construct.h:81) + // by 0x3476E4D1: std::vector<int, std::allocator<int> >::push_back(int const&) (stl_vector.h:560) + // by 0x34763DDB: MEDMEM::CONNECTIVITY::calculateReverseNodalConnectivity() (MEDMEM_Connectivity.cxx:1155) + // by 0x347655FF: MEDMEM::CONNECTIVITY::calculateDescendingConnectivity() (MEDMEM_Connectivity.cxx:1333) + // by 0x3476363E: MEDMEM::CONNECTIVITY::getReverseDescendingConnectivity() (MEDMEM_Connectivity.cxx:1090) + // by 0x34772AB6: MEDMEM::CONNECTIVITY::getReverseConnectivity(long, long) (MEDMEM_Connectivity.hxx:503) + // by 0x348F4F4B: MEDMEM::MESH::getReverseConnectivity(long, long) const (MEDMEM_Mesh.hxx:848) + // by 0x348FF559: MEDMEM::SUPPORT::getBoundaryElements() (MEDMEM_Support.cxx:483) + // by 0x3439C8E5: MEDMEMTest::testSupport() (MEDMEMTest_Support.cxx:641) + // Address 0x61666A2F is not stack'd, malloc'd or (recently) free'd +//#endif + + delete aMesh; + delete aMeshOneMore; +} + +int main (int argc, char** argv) +{ + MEDMEMTest_testSupport(); +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_TopLevel.cxx b/src/MEDMEMCppTest/MEDMEMTest_TopLevel.cxx new file mode 100644 index 000000000..a047437f7 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_TopLevel.cxx @@ -0,0 +1,169 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include <MEDMEM_TopLevel.hxx> +#include <MEDMEM_MedFieldDriver22.hxx> +#include <MEDMEM_Field.hxx> +#include <MEDMEM_Med.hxx> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +/*! + * Check methods (6), defined in MEDMEM_TopLevel.hxx: + * (+) MED *readMedInFile(const std::string& fileName) throw(MEDEXCEPTION); + * (+) MESH *readMeshInFile(const std::string& fileName, const std::string& meshName); + * (+) template<class T> FIELD<T> *readFieldInFile + * (const std::string& fileName, const std::string& fieldName); + * (+) void writeMedToFile(const MED *medObj, const std::string& fileName); + * (+) void writeMeshToFile(const MESH *meshObj, const std::string& fileName); + * (-) template<class T> void writeFieldToFile(const FIELD<T> *fieldObj, const std::string& fileName); + */ +void MEDMEMTest::testTopLevel() +{ + MED * aMed = NULL; + + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if (tmp_dir == "") + tmp_dir = "/tmp"; + + string filename_rd = data_dir + "/share/salome/resources/med/pointe.med"; + string filename22_rd = data_dir + "/share/salome/resources/med/pointe_import22.med"; + string filenameMesh_wr = tmp_dir + "/myMesh.med"; + string filenameMed_wr = tmp_dir + "/myMed.med"; + string filenameField_wr = tmp_dir + "/myField.med"; + string fileNotExist_rd = "/notExist.med"; + string fileNotExist_wr = "/path_not_exist/file_not_exist.med"; + string meshname = "maa1"; + string meshname_not_exist = "anymesh"; + string fieldname_not_exist = "anyfield"; + string fieldname = "fieldnodedouble"; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filenameMesh_wr); + aRemover.Register(filenameMed_wr); + aRemover.Register(filenameField_wr); + + /////////////////// + //Test Read Part // + /////////////////// + { + //Trying read from not existing file + //#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_THROW(readMedInFile(fileNotExist_rd), MEDEXCEPTION); + // (BUG) No exception in this case + //#endif + CPPUNIT_ASSERT_THROW(readMeshInFile(fileNotExist_rd, meshname), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(readFieldInFile<double>(fileNotExist_rd, fieldname), MEDEXCEPTION); + + //Trying read not existing mesh from file + CPPUNIT_ASSERT_THROW(readMeshInFile(filename_rd, meshname_not_exist), MEDEXCEPTION); + + //Trying read not existing field from file + //CPPUNIT_ASSERT_THROW(readFieldInFile<double>(filename22_rd, fieldname_not_exist), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(readFieldInFile<double>(filename_rd, fieldname_not_exist), MEDEXCEPTION); + + //Test readMeshInFile() method + //#ifdef ENABLE_FORCED_FAILURES + { + MESH * aMesh = NULL; + //MEDEXCEPTION: can not open file, but file exist + CPPUNIT_ASSERT_NO_THROW(aMesh = readMeshInFile(filename22_rd, meshname)); + //CPPUNIT_ASSERT_NO_THROW(aMesh = readMeshInFile(filename_rd, meshname)); + CPPUNIT_ASSERT(aMesh); + delete aMesh; + } + //#endif + + //Test readMedInFile() method + { + CPPUNIT_ASSERT_NO_THROW(aMed = readMedInFile(filename_rd)); + CPPUNIT_ASSERT(aMed); + } + + //Test readFieldInFile() method + //#ifdef ENABLE_FORCED_FAILURES + { + FIELD<double> * aField = NULL; + //MEDEXCEPTION: can not open file, but file exist + CPPUNIT_ASSERT_NO_THROW(aField = readFieldInFile<double>(filename22_rd, fieldname)); + CPPUNIT_ASSERT(aField); + delete aField; + } + //#endif + } + + //////////////////// + //Test Write Part // + //////////////////// + { + //Create a FIELD + FIELD<double> *aField_1 = new FIELD<double> (); + + MED_FIELD_RDONLY_DRIVER22<double> *aMedRdFieldDriver22 = + new MED_FIELD_RDONLY_DRIVER22<double>(filename22_rd, aField_1); + aMedRdFieldDriver22->setFieldName(fieldname); + aMedRdFieldDriver22->open(); + aMedRdFieldDriver22->read(); + aMedRdFieldDriver22->close(); + + //Trying write objects in the not existing file + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) No exception in this case + CPPUNIT_ASSERT_THROW(writeMedToFile(aMed, fileNotExist_wr), MEDEXCEPTION); + //#endif + + //Create a MESH + MESH * aMesh = MEDMEMTest_createTestMesh(); + CPPUNIT_ASSERT_THROW(writeMeshToFile(aMesh, fileNotExist_wr), MEDEXCEPTION); + + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) Error during compilation + //MED_SRC/src/MEDMEM/MEDMEM_TopLevel.hxx:66: error: passing `const MEDMEM::FIELD<double, MEDMEM::FullInterlace>' as `this' argument of `int MEDMEM::FIELD<T, INTERLACING_TAG>::addDriver(MEDMEM::driverTypes, const std::string&, const std::string&, MED_EN::med_mode_acces) [with T = double, INTERLACING_TAG = MEDMEM::FullInterlace]' discards qualifiers CPPUNIT_ASSERT_THROW(writeFieldToFile<double>(aField_1, fileNotExist_wr),MEDEXCEPTION); + //CPPUNIT_FAIL("writeFieldToFile(): compilation error"); + //#endif + + //Trying write mesh in the file with empty name + aMesh->setName(""); + CPPUNIT_ASSERT_THROW(writeMeshToFile(aMesh, filenameField_wr), MEDEXCEPTION); + + //Test writeMedToFile() and writeMeshToFile() methods + aMesh->setName(meshname); + CPPUNIT_ASSERT_NO_THROW(writeMeshToFile(aMesh, filenameMesh_wr)); + CPPUNIT_ASSERT_NO_THROW(writeMedToFile(aMed, filenameMed_wr)); + + delete aField_1; + delete aMesh; + delete aMed; + } +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_Unit.cxx b/src/MEDMEMCppTest/MEDMEMTest_Unit.cxx new file mode 100644 index 000000000..2ae546ad1 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_Unit.cxx @@ -0,0 +1,355 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/Message.h> +#include <cppunit/TestAssert.h> + +#include <cstdlib> +#include <exception> + +#include <MEDMEM_Unit.hxx> + +using namespace std; +using namespace MEDMEM; + + +/*! + * Check methods (18), defined in MEDMEM_Unit.hxx: + * class UNIT { + * (+) UNIT(); + * (+) UNIT(string Name, string Description); + * (+) ~UNIT(); + * (+) UNIT & operator=(const UNIT &unit); + * (+) inline void setName(string Name); + * (+) inline void setDescription(string Description); + * (+) inline void setMasse(int Masse); + * (+) inline void setLength(int Length); + * (+) inline void setTime(int Time); + * (+) inline void setTemperature(int Temperature); + * (+) inline void setMatterQuantity(int MatterQuantity); + * (+) void setCurrentStrength(int CurrentStrength); + * (+) inline void setLightIntensity(int LightIntensity); + * + * (+) inline string getName() const; + * (+) inline string getDescription() const; + * (+) inline int getMasse() const; + * (+) inline int getLength() const; + * (+) inline int getTime() const; + * (+) inline int getTemperature() const; + * (+) inline int getMatterQuantity() const; + * (+) inline int getCurrentStrength() const; + * (+) inline int getLightIntensity() const; + * } + * + * Used code of MEDMEM/tests/testUUnit.cxx + */ + +void MEDMEMTest::testUnit() +{ + string myName = "NameForTesting"; + string myDescription = "all values are setted 10"; + int myMasse = 10; + int myLength = 10; + int myTime = 10; + int myTemperature = 10; + int myMatterQuantity = 10; + int myCurrentStrength = 10; + int myLightIntensity = 10; + + //Default constructor + UNIT myUNIT; + + //Normal constructor + UNIT *myUNIT1 = new UNIT(myName,myDescription); + CPPUNIT_ASSERT(myUNIT1); + + //--------------------------------------------------------------------// + // Tests des methodes // + // // + // - setName // + // - setDescription // + // - setMasse // + // - setLength // + // - setTime // + // - setTemperature // + // - setMatterQuantity // + // - setCurrentStrength // + // - setLightIntensity // + //--------------------------------------------------------------------// + + try + { + myUNIT.setName(myName); + } + catch(const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch(...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + myUNIT.setDescription(myDescription); + } + catch(const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch(...) + { + CPPUNIT_FAIL("MEDMEM_UNIT::setDescription(): Unknown exception"); + } + + try + { + myUNIT.setMasse(myMasse); + } + catch(const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch(...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + myUNIT.setLength(myLength); + } + catch(const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch(...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + myUNIT.setTime(myTime); + } + catch(const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch(...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + myUNIT.setTemperature(myTemperature); + } + catch(const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch(...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + myUNIT.setMatterQuantity(myMatterQuantity); + } + catch(const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch(...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + myUNIT.setCurrentStrength(myCurrentStrength); + } + catch(const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch(...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + myUNIT.setLightIntensity(myLightIntensity); + } + catch(const std::exception &e) + { + CPPUNIT_FAIL(e.what()); + } + catch(...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //--------------------------------------------------------------------// + // Tests des methodes // + // // + // - getName // + // - getDescription // + // - getMasse // + // - getLength // + // - getTime // + // - getTemperature // + // - getMatterQuantity // + // - getCurrentStrength // + // - getLightIntensity // + //--------------------------------------------------------------------// + + try + { + CPPUNIT_ASSERT( myUNIT.getName() == myName ); + } + catch( const std::exception &e ) + { + CPPUNIT_FAIL(e.what()); + } + catch ( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + CPPUNIT_ASSERT( myUNIT.getDescription() == myDescription ); + } + catch( const std::exception &e ) + { + CPPUNIT_FAIL(e.what()); + } + catch ( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + CPPUNIT_ASSERT( myUNIT.getMasse() == myMasse ); + } + catch( const std::exception &e ) + { + CPPUNIT_FAIL(e.what()); + } + catch ( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + CPPUNIT_ASSERT( myUNIT.getLength() == myLength ); + } + catch( const std::exception &e ) + { + CPPUNIT_FAIL(e.what()); + } + catch ( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + CPPUNIT_ASSERT( myUNIT.getTime() == myTime ); + } + catch( const std::exception &e ) + { + CPPUNIT_FAIL(e.what()); + } + catch ( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + CPPUNIT_ASSERT( myUNIT.getTemperature() == myTemperature ); + } + catch( const std::exception &e ) + { + CPPUNIT_FAIL(e.what()); + } + catch ( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + CPPUNIT_ASSERT( myUNIT.getMatterQuantity() == myMatterQuantity ); + } + catch( const std::exception &e ) + { + CPPUNIT_FAIL(e.what()); + } + catch ( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + CPPUNIT_ASSERT( myUNIT.getCurrentStrength() == myCurrentStrength ); + } + catch( const std::exception &e ) + { + CPPUNIT_FAIL(e.what()); + } + catch ( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + try + { + CPPUNIT_ASSERT( myUNIT.getLightIntensity() == myLightIntensity ); + } + catch( const std::exception &e ) + { + CPPUNIT_FAIL(e.what()); + } + catch ( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //--------------------------------------------------------------------// + // Tests des method // + // - operator= // + //--------------------------------------------------------------------// + + UNIT myUNITCpy; + myUNITCpy = myUNIT; + CPPUNIT_ASSERT_EQUAL( myUNITCpy.getTemperature(), myUNITCpy.getTemperature()); +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_VtkFieldDriver.cxx b/src/MEDMEMCppTest/MEDMEMTest_VtkFieldDriver.cxx new file mode 100644 index 000000000..ce89f5191 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_VtkFieldDriver.cxx @@ -0,0 +1,304 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include <MEDMEM_VtkFieldDriver.hxx> +#include <MEDMEM_Med.hxx> +#include <MEDMEM_Field.hxx> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +/*! + * Check methods (14), defined in MEDMEM_VtkFieldDriver.hxx: + * template <class T> class VTK_FIELD_DRIVER : public GENDRIVER { + * //MUST BE PRIVATE, because it is impossible to set _ptrField after this constructor. + * //AND cannot compile, so maybe it is specially implemented to prevent usage of it. + * (!) template <class INTERLACING_TAG> VTK_FIELD_DRIVER(); + * (+) template <class INTERLACING_TAG> VTK_FIELD_DRIVER + * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField) + * (+) VTK_FIELD_DRIVER(const VTK_FIELD_DRIVER & fieldDriver) + * (+) ~VTK_FIELD_DRIVER() + * (+) void openConst() const throw (MEDEXCEPTION) + * (+) void openConstAppend() const throw (MEDEXCEPTION) + * (+) void open() throw (MEDEXCEPTION) + * (+) void openAppend() throw (MEDEXCEPTION) + * (+) void closeConst() const throw (MEDEXCEPTION) + * (+) void close() + * (+) void setFieldName(const string & fieldName); + * (+) string getFieldName() const; + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void write(void) const throw (MEDEXCEPTION); + * (+) void writeAppend(void) const throw (MEDEXCEPTION); + * } + */ +void MEDMEMTest::testVtkFieldDriver() +{ + FIELD<int> *aField = new FIELD<int> (); + FIELD<double> *aField_1 = new FIELD<double> (); + + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if (tmp_dir == "") + tmp_dir = "/tmp"; + + string filename_rd = data_dir + "/share/salome/resources/med/pointe_import22.med"; + string emptyfilename = ""; + string fileNotExistsName = "/path_not_exists/file_not_exists.vtk"; + string filename_wr = tmp_dir + "/myField_pointe.vtk"; + + string fieldname_rd_int = "fieldnodeint"; + string fieldname_wr_int = "myintfield"; + string fieldname_rd_double = "fieldnodedouble"; + string fieldname_wr_double = "mydoublefield"; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filename_wr); + + ///////////////////////////////////// + // TEST1: Open not existing file // + ///////////////////////////////////// + //Creation Invalid VtkFieldDriver (file not exist) + VTK_FIELD_DRIVER<int> *aInvalidVtkFieldDriver_1 = new VTK_FIELD_DRIVER<int>(fileNotExistsName, aField); + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_1->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_1->openConst(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_1->openConstAppend(), MEDEXCEPTION); + + ///////////////////////////////////////////// + // TEST2: Open file with empty file name // + ///////////////////////////////////////////// + //Creation Invalid VtkFieldDriver (empty file name) + VTK_FIELD_DRIVER<int> *aInvalidVtkFieldDriver_2 = new VTK_FIELD_DRIVER<int>(emptyfilename, aField); + + //Trying file with empty name + CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_2->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_2->openConst(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_2->openConstAppend(), MEDEXCEPTION); + + //////////////////////// + // TEST2: Main test // + //////////////////////// + //Read Fields from file + MED_FIELD_RDONLY_DRIVER22<int> *aMedRdFieldDriver22_int = new MED_FIELD_RDONLY_DRIVER22<int>(filename_rd, aField); + aMedRdFieldDriver22_int->open(); + aMedRdFieldDriver22_int->setFieldName(fieldname_rd_int); + aMedRdFieldDriver22_int->read(); + aMedRdFieldDriver22_int->close(); + MESH mesh(MED_DRIVER,filename_rd,"maa1"); + aField->getSupport()->setMesh(&mesh); + + MED_FIELD_RDONLY_DRIVER22<double> *aMedRdFieldDriver22_double = new MED_FIELD_RDONLY_DRIVER22<double>(filename_rd, aField_1); + aMedRdFieldDriver22_double->open(); + aMedRdFieldDriver22_double->setFieldName(fieldname_rd_double); + aMedRdFieldDriver22_double->read(); + aMedRdFieldDriver22_double->close(); + aField_1->getSupport()->setMesh(&mesh); + //Check fields + CPPUNIT_ASSERT(aField); + + //Creation correct VtkFieldDriver + VTK_FIELD_DRIVER<int> *aVtkFieldDriver_int = new VTK_FIELD_DRIVER<int>(filename_wr, aField); + + //Check driver + CPPUNIT_ASSERT(aVtkFieldDriver_int); + + //Test setFieldName() and getFieldName() methods + try + { + aVtkFieldDriver_int->setFieldName(fieldname_wr_int); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT_EQUAL(fieldname_wr_int, aVtkFieldDriver_int->getFieldName()); + + //Test open() method + try + { + aVtkFieldDriver_int->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //#ifdef ENABLE_FAULTS + //Test write() method + try + { + aVtkFieldDriver_int->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + // => Segmentation fault + //#endif + + //Test read() method for Vtk Field Driver + CPPUNIT_ASSERT_THROW(aVtkFieldDriver_int->read(),MEDEXCEPTION); + + //Test close() method + try + { + aVtkFieldDriver_int->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test openAppend() method + try + { + aVtkFieldDriver_int->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + + ///////////////////////////////////////////////////////// + // TEST? Test openAppend() and writeAppend() methods // + ///////////////////////////////////////////////////////// + + //Creation correct VtkFieldDriver + VTK_FIELD_DRIVER<double> *aVtkFieldDriver_double = new VTK_FIELD_DRIVER<double>(filename_wr, aField_1); + + //Check driver + CPPUNIT_ASSERT(aVtkFieldDriver_double); + + //Test openAppend() method + try + { + aVtkFieldDriver_double->openAppend(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + aVtkFieldDriver_double->setFieldName(fieldname_wr_double); + + //#ifdef ENABLE_FAULTS + //Test writeAppend() method + try + { + aVtkFieldDriver_double->writeAppend(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + // => Segmentation fault + //#endif + + try + { + aVtkFieldDriver_double->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //#ifdef ENABLE_FORCED_FAILURES + //VTK_FIELD_DRIVER<int> aVtkFieldDriver_intCpy_1; + //VTK_FIELD_DRIVER<int>.template VTK_FIELD_DRIVER<FullInterlace> aVtkFieldDriver_intCpy_1; + //CPPUNIT_FAIL("Compilation error: no matching function for call to 'MEDMEM::VTK_FIELD_DRIVER<int>::VTK_FIELD_DRIVER()"); + //#endif + + //#ifdef ENABLE_FAULTS + //Test copy constructor + VTK_FIELD_DRIVER<int> aVtkFieldDriver_intCpy_2 (*aVtkFieldDriver_int); + // => Segmentation fault after call Copy Constructor + + CPPUNIT_ASSERT_EQUAL(aVtkFieldDriver_intCpy_2, *aVtkFieldDriver_int); + //Test (bool operator ==) defined in GENDRIVER class in MEDMEM_GenDriver.hxx + CPPUNIT_ASSERT(aVtkFieldDriver_intCpy_2.GENDRIVER::operator== (*aVtkFieldDriver_int)); + + //Test (friend ostream & operator <<) defined in GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream ostr1, ostr2; + ostr1<<*aVtkFieldDriver_int; + ostr2<<aVtkFieldDriver_intCpy_2; + + CPPUNIT_ASSERT(ostr1.str() != ""); + CPPUNIT_ASSERT(ostr1.str() == ostr2.str()); + //#endif + + //Delete all objects + delete aField; + delete aField_1; + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) Exception in the destructor after trying close not existing file. + delete aInvalidVtkFieldDriver_1; + //#endif + delete aInvalidVtkFieldDriver_2; + delete aMedRdFieldDriver22_int; + delete aMedRdFieldDriver22_double; + delete aVtkFieldDriver_int; + delete aVtkFieldDriver_double; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_VtkFieldDriver_fault.cxx b/src/MEDMEMCppTest/MEDMEMTest_VtkFieldDriver_fault.cxx new file mode 100644 index 000000000..5d04f483a --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_VtkFieldDriver_fault.cxx @@ -0,0 +1,306 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include <MEDMEM_VtkFieldDriver.hxx> +#include <MEDMEM_Med.hxx> +#include <MEDMEM_Field.hxx> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +/*! + * Check methods (14), defined in MEDMEM_VtkFieldDriver.hxx: + * template <class T> class VTK_FIELD_DRIVER : public GENDRIVER { + * //MUST BE PRIVATE, because it is impossible to set _ptrField after this constructor. + * //AND cannot compile, so maybe it is specially implemented to prevent usage of it. + * (!) template <class INTERLACING_TAG> VTK_FIELD_DRIVER(); + * (+) template <class INTERLACING_TAG> VTK_FIELD_DRIVER + * (const string & fileName, FIELD<T, INTERLACING_TAG> * ptrField) + * (+) VTK_FIELD_DRIVER(const VTK_FIELD_DRIVER & fieldDriver) + * (+) ~VTK_FIELD_DRIVER() + * (+) void openConst() const throw (MEDEXCEPTION) + * (+) void openConstAppend() const throw (MEDEXCEPTION) + * (+) void open() throw (MEDEXCEPTION) + * (+) void openAppend() throw (MEDEXCEPTION) + * (+) void closeConst() const throw (MEDEXCEPTION) + * (+) void close() + * (+) void setFieldName(const string & fieldName); + * (+) string getFieldName() const; + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void write(void) const throw (MEDEXCEPTION); + * (+) void writeAppend(void) const throw (MEDEXCEPTION); + * } + */ +void MEDMEMTest_testVtkFieldDriver() +{ + FIELD<int> *aField = new FIELD<int> (); + FIELD<double> *aField_1 = new FIELD<double> (); + + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if (tmp_dir == "") + tmp_dir = "/tmp"; + + string filename_rd = data_dir + "/share/salome/resources/med/pointe.med"; + string emptyfilename = ""; + string fileNotExistsName = "/path_not_exists/file_not_exists.vtk"; + string filename_wr = tmp_dir + "/myField_pointe.vtk"; + + string fieldname_rd_int = "fieldnodeint"; + string fieldname_wr_int = "myintfield"; + string fieldname_rd_double = "fieldnodedouble"; + string fieldname_wr_double = "mydoublefield"; + + // To remove tmp files from disk + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filename_wr); + + ///////////////////////////////////// + // TEST1: Open not existing file // + ///////////////////////////////////// + //Creation Invalid VtkFieldDriver (file not exist) + VTK_FIELD_DRIVER<int> *aInvalidVtkFieldDriver_1 = new VTK_FIELD_DRIVER<int>(fileNotExistsName, aField); + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_1->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_1->openConst(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_1->openConstAppend(), MEDEXCEPTION); + + ///////////////////////////////////////////// + // TEST2: Open file with empty file name // + ///////////////////////////////////////////// + //Creation Invalid VtkFieldDriver (empty file name) + VTK_FIELD_DRIVER<int> *aInvalidVtkFieldDriver_2 = new VTK_FIELD_DRIVER<int>(emptyfilename, aField); + + //Trying file with empty name + CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_2->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_2->openConst(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aInvalidVtkFieldDriver_2->openConstAppend(), MEDEXCEPTION); + + //////////////////////// + // TEST2: Main test // + //////////////////////// + //Read Fields from file + MED_FIELD_RDONLY_DRIVER21<int> *aMedRdFieldDriver21_int = new MED_FIELD_RDONLY_DRIVER21<int>(filename_rd, aField); + aMedRdFieldDriver21_int->open(); + aMedRdFieldDriver21_int->setFieldName(fieldname_rd_int); + aMedRdFieldDriver21_int->read(); + aMedRdFieldDriver21_int->close(); + + MED_FIELD_RDONLY_DRIVER21<double> *aMedRdFieldDriver21_double = new MED_FIELD_RDONLY_DRIVER21<double>(filename_rd, aField_1); + aMedRdFieldDriver21_double->open(); + aMedRdFieldDriver21_double->setFieldName(fieldname_rd_double); + aMedRdFieldDriver21_double->read(); + aMedRdFieldDriver21_double->close(); + //Check fields + CPPUNIT_ASSERT(aField); + + //Creation correct VtkFieldDriver + VTK_FIELD_DRIVER<int> *aVtkFieldDriver_int = new VTK_FIELD_DRIVER<int>(filename_wr, aField); + + //Check driver + CPPUNIT_ASSERT(aVtkFieldDriver_int); + + //Test setFieldName() and getFieldName() methods + try + { + aVtkFieldDriver_int->setFieldName(fieldname_wr_int); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + CPPUNIT_ASSERT_EQUAL(fieldname_wr_int, aVtkFieldDriver_int->getFieldName()); + + //Test open() method + try + { + aVtkFieldDriver_int->open(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + +//#ifdef ENABLE_FAULTS + //Test write() method + try + { + aVtkFieldDriver_int->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + // => Segmentation fault +//#endif + + //Test read() method for Vtk Field Driver + CPPUNIT_ASSERT_THROW(aVtkFieldDriver_int->read(),MEDEXCEPTION); + + //Test close() method + try + { + aVtkFieldDriver_int->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test openAppend() method + try + { + aVtkFieldDriver_int->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + + ///////////////////////////////////////////////////////// + // TEST? Test openAppend() and writeAppend() methods // + ///////////////////////////////////////////////////////// + + //Creation correct VtkFieldDriver + VTK_FIELD_DRIVER<double> *aVtkFieldDriver_double = new VTK_FIELD_DRIVER<double>(filename_wr, aField_1); + + //Check driver + CPPUNIT_ASSERT(aVtkFieldDriver_double); + + //Test openAppend() method + try + { + aVtkFieldDriver_double->openAppend(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + aVtkFieldDriver_double->setFieldName(fieldname_wr_double); + +//#ifdef ENABLE_FAULTS + //Test writeAppend() method + try + { + aVtkFieldDriver_double->writeAppend(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + // => Segmentation fault +//#endif + + try + { + aVtkFieldDriver_double->close(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //#ifdef ENABLE_FORCED_FAILURES + //VTK_FIELD_DRIVER<int> aVtkFieldDriver_intCpy_1; + //VTK_FIELD_DRIVER<int>.template VTK_FIELD_DRIVER<FullInterlace> aVtkFieldDriver_intCpy_1; + //CPPUNIT_FAIL("Compilation error: no matching function for call to 'MEDMEM::VTK_FIELD_DRIVER<int>::VTK_FIELD_DRIVER()"); + //#endif + +//#ifdef ENABLE_FAULTS + //Test copy constructor + VTK_FIELD_DRIVER<int> aVtkFieldDriver_intCpy_2 (*aVtkFieldDriver_int); + // => Segmentation fault after call Copy Constructor + + CPPUNIT_ASSERT_EQUAL(aVtkFieldDriver_intCpy_2, *aVtkFieldDriver_int); + //Test (bool operator ==) defined in GENDRIVER class in MEDMEM_GenDriver.hxx + CPPUNIT_ASSERT(aVtkFieldDriver_intCpy_2.GENDRIVER::operator== (*aVtkFieldDriver_int)); + + //Test (friend ostream & operator <<) defined in GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream ostr1, ostr2; + ostr1<<*aVtkFieldDriver_int; + ostr2<<aVtkFieldDriver_intCpy_2; + + CPPUNIT_ASSERT(ostr1.str() != ""); + CPPUNIT_ASSERT(ostr1.str() == ostr2.str()); +//#endif + + //Delete all objects + delete aField; + delete aField_1; +//#ifdef ENABLE_FORCED_FAILURES + // (BUG) Exception in the destructor after trying close not existing file. + delete aInvalidVtkFieldDriver_1; +//#endif + delete aInvalidVtkFieldDriver_2; + delete aMedRdFieldDriver21_int; + delete aMedRdFieldDriver21_double; + delete aVtkFieldDriver_int; + delete aVtkFieldDriver_double; +} + +int main (int argc, char** argv) +{ + MEDMEMTest_testVtkFieldDriver(); +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_VtkMedDriver.cxx b/src/MEDMEMCppTest/MEDMEMTest_VtkMedDriver.cxx new file mode 100644 index 000000000..9c6a21764 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_VtkMedDriver.cxx @@ -0,0 +1,135 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include <MEDMEM_Compatibility21_22.hxx> +#include <MEDMEM_VtkMedDriver.hxx> +#include <MEDMEM_MedMedDriver21.hxx> +#include <MEDMEM_Med.hxx> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +/*! + * Check methods (5), defined in MEDMEM_VtkMedDriver.hxx: + * class VTK_MED_DRIVER : public GENDRIVER { + * (+) VTK_MED_DRIVER(const string & fileName, MED * const ptrMed); + * (+) VTK_MED_DRIVER(const VTK_MED_DRIVER & driver); + * (+) ~VTK_MED_DRIVER(); + * (+) void write (void) const; + * (-) virtual void read (void) {}; + * (+) GENDRIVER * copy (void) const; + * } + */ +void MEDMEMTest::testVtkMedDriver() +{ + MED *aMed = new MED(); + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + if (tmp_dir == "") + tmp_dir = "/tmp"; + string filename_rd = data_dir + "/share/salome/resources/med/pointe.med"; + string emptyfilename = ""; + string fileNotExistsName = "/path_not_exists/file_not_exists.vtk"; + string filename_wr = tmp_dir + "/myMED_pointe.vtk"; + + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filename_wr); + + //Read MED structure from file + MED_MED_RDONLY_DRIVER21 *aMedMedRdDriver21 = new MED_MED_RDONLY_DRIVER21(filename_rd, aMed); + aMedMedRdDriver21->open(); + aMedMedRdDriver21->read(); + aMedMedRdDriver21->close(); + //Check Med + CPPUNIT_ASSERT(aMed); + + //Creation incorrect Vtk Med Driver (file is not exists) + VTK_MED_DRIVER *aInvalidVtkMedDriver = new VTK_MED_DRIVER(fileNotExistsName,aMed); + + //Trying write data in the not existing file + CPPUNIT_ASSERT_THROW(aInvalidVtkMedDriver->write(),MEDEXCEPTION); + + //Creation correct Vtk Med Driver + VTK_MED_DRIVER *aVtkMedDriver = new VTK_MED_DRIVER(filename_wr ,aMed); + + //Check driver + CPPUNIT_ASSERT(aVtkMedDriver); + + //Test write() method + + try + { + aVtkMedDriver->write(); + } + catch(MEDEXCEPTION &e) + { + CPPUNIT_FAIL(e.what()); + } + catch( ... ) + { + CPPUNIT_FAIL("Unknown exception"); + } + + //Test copy constructor + VTK_MED_DRIVER *aVtkMedDriverCpy = new VTK_MED_DRIVER(*aVtkMedDriver); + //#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_EQUAL(*aVtkMedDriverCpy, *aVtkMedDriver); + //#endif + + //Test (operator ==) defined in GENDRIVER class in MEDMEM_GenDriver.hxx + //#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT(*aVtkMedDriverCpy == *aVtkMedDriver); + //#endif + + //Test copy() function + VTK_MED_DRIVER *aVtkMedDriverCpy_1 = (VTK_MED_DRIVER*)aVtkMedDriver->copy(); + //#ifdef ENABLE_FORCED_FAILURES + CPPUNIT_ASSERT_EQUAL(*aVtkMedDriverCpy_1, *aVtkMedDriver); + //#endif + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + ostringstream ostr1, ostr2; + ostr1<<*aVtkMedDriverCpy; + ostr2<<*aVtkMedDriverCpy_1; + CPPUNIT_ASSERT(ostr1.str() != ""); + CPPUNIT_ASSERT(ostr1.str() == ostr2.str()); + + + //Delete objects + delete aMedMedRdDriver21; + //#ifdef ENABLE_FORCED_FAILURES + delete aInvalidVtkMedDriver; + delete aVtkMedDriver; + delete aVtkMedDriverCpy; + delete aVtkMedDriverCpy_1; + //MEDEXCEPTION in the destructor (after trying close file) + //#endif +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_VtkMeshDriver.cxx b/src/MEDMEMCppTest/MEDMEMTest_VtkMeshDriver.cxx new file mode 100644 index 000000000..10c6bb0d7 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_VtkMeshDriver.cxx @@ -0,0 +1,166 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include <MEDMEM_VtkMeshDriver.hxx> +#include <MEDMEM_MedMeshDriver22.hxx> +#include <MEDMEM_Mesh.hxx> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; + +/*! + * Check methods (11), defined in MEDMEM_VtkMeshDriver.hxx: + * class VTK_MESH_DRIVER : public GENDRIVER { + * (+) VTK_MESH_DRIVER(); + * (+) VTK_MESH_DRIVER(const string & fileName, MESH * ptrMesh); + * (+) VTK_MESH_DRIVER(const VTK_MESH_DRIVER & driver); + * (+) ~VTK_MESH_DRIVER(); + * (+) void open(); + * (+) void close(); + * (+) void openConst() const throw (MEDEXCEPTION); + * (+) void closeConst() const throw (MEDEXCEPTION); + * (+) void write(void) const throw (MEDEXCEPTION); + * (+) void read (void) throw (MEDEXCEPTION); + * (+) void setMeshName(const string & meshName); + * (+) string getMeshName() const; + * } + */ +void MEDMEMTest::testVtkMeshDriver() +{ + MESH * aMesh = new MESH(); + + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + string filename_rd = data_dir + "/share/salome/resources/med/pointe_import22.med"; + string emptyfilename = ""; + string meshname_rd = "maa1"; + string meshname = "MyMesh"; + string fileNotExistsName = "/path_not_exists/file_not_exists.vtk"; + string filename = tmp_dir + "/my_pointe.vtk"; + + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filename); + + { + //Creation a invalid Vtk driver + VTK_MESH_DRIVER *aInvalidVtkDriver = new VTK_MESH_DRIVER(fileNotExistsName, aMesh); + + //Trying open not existing file + CPPUNIT_ASSERT_THROW(aInvalidVtkDriver->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aInvalidVtkDriver->openConst(), MEDEXCEPTION); + + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) In destructor of VTK_MESH_DRIVER: Exception after trying close not existing file + //CPPUNIT_ASSERT_NO_THROW(delete aInvalidVtkDriver); + //#endif + } + + { + //Create Vtk driver with empty file name + VTK_MESH_DRIVER *aEmptyVtkDriver = new VTK_MESH_DRIVER(emptyfilename, aMesh); + + //Test open() and openConst() methods with empty file name + CPPUNIT_ASSERT_THROW(aEmptyVtkDriver->open(), MEDEXCEPTION); + CPPUNIT_ASSERT_THROW(aEmptyVtkDriver->openConst(), MEDEXCEPTION); + + delete aEmptyVtkDriver; + } + + //Creation corect driver + VTK_MESH_DRIVER *aVtkDriver = new VTK_MESH_DRIVER(filename, aMesh); + CPPUNIT_ASSERT(aVtkDriver); + + //Create a Mesh + MED_MESH_RDONLY_DRIVER22 *aMedMeshRdDriver22 = new MED_MESH_RDONLY_DRIVER22(filename_rd, aMesh); + aMedMeshRdDriver22->open(); + aMedMeshRdDriver22->setMeshName(meshname_rd); + + //Test openConst() and closeConst() methods + CPPUNIT_ASSERT_NO_THROW(aVtkDriver->openConst()); + CPPUNIT_ASSERT_NO_THROW(aVtkDriver->closeConst()); + + //Test open() method + CPPUNIT_ASSERT_NO_THROW(aVtkDriver->open()); + + //Trying open file secondary + //#ifdef ENABLE_FORCED_FAILURES + // (BUG) No exception on attempt to open a file for the second time + //CPPUNIT_ASSERT_THROW(aVtkDriver->open(), MEDEXCEPTION); + //#endif + + //Test read method + CPPUNIT_ASSERT_THROW(aVtkDriver->read(), MEDEXCEPTION); + + //Trying write empty mesh + //#ifdef ENABLE_FAULTS + // ? (BUG) ? In VTK_MESH_DRIVER::write() => Segmentation fault on attempt to write an empty mesh + //CPPUNIT_ASSERT_THROW(aVtkDriver->write(), MEDEXCEPTION); + //#endif + + //Read mesh from Med file + aMedMeshRdDriver22->read(); + + //Check mesh + CPPUNIT_ASSERT(aMesh); + + //Test SetMeshName and getMeshName methods + CPPUNIT_ASSERT_NO_THROW(aVtkDriver->setMeshName(meshname)); + CPPUNIT_ASSERT_EQUAL(meshname, aVtkDriver->getMeshName()); + + //Test write method + CPPUNIT_ASSERT_NO_THROW(aVtkDriver->write()); + + //Test close method + CPPUNIT_ASSERT_NO_THROW(aVtkDriver->close()); + + //Test Default constructor + VTK_MESH_DRIVER aVtkDriverCpy_1; + + //Test copy constructor + //#ifdef ENABLE_FAULTS + // (BUG) In copy constructor of VTK_MESH_DRIVER: Segmentation fault + VTK_MESH_DRIVER aVtkDriverCpy_2 (*aVtkDriver); + //#endif + + //Test (bool operator ==) defined in GENDRIVER class + //CPPUNIT_ASSERT(aVtkDriverCpy_2.GENDRIVER::operator==(aVtkDriver)); + + //Test (friend ostream & operator <<) defined GENDRIVER class in MEDMEM_GenDriver.hxx + //ostringstream ostr1, ostr2; + //ostr1 << aVtkDriverCpy_2; + //ostr2 << aVtkDriver; + //CPPUNIT_ASSERT(ostr1.str() != ""); + //CPPUNIT_ASSERT_EQUAL(ostr1.str(), ostr2.str()); + + //Delete objects + delete aVtkDriver; + delete aMedMeshRdDriver22; + delete aMesh; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_VtkMeshDriver_fault.cxx b/src/MEDMEMCppTest/MEDMEMTest_VtkMeshDriver_fault.cxx new file mode 100644 index 000000000..79e49c8b0 --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_VtkMeshDriver_fault.cxx @@ -0,0 +1,69 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" + +#include <MEDMEM_VtkMeshDriver.hxx> +#include <MEDMEM_MedMeshDriver21.hxx> +#include <MEDMEM_Mesh.hxx> + +using namespace std; +using namespace MEDMEM; + +int main (int argc, char** argv) +{ + string tmp_dir = getenv("TMP") ? getenv("TMP") : "/tmp"; + string meshname = "MyMesh"; + string filename = tmp_dir + "/my_pointe.vtk"; + + MEDMEMTest_TmpFilesRemover aRemover; + aRemover.Register(filename); + + //Create an empty Mesh + MESH * aMesh = new MESH(); + + //Creation corect driver + VTK_MESH_DRIVER *aVtkDriver = new VTK_MESH_DRIVER(filename, aMesh); + aVtkDriver->setMeshName(meshname); + aVtkDriver->open(); + + // ? (BUG) ? In VTK_MESH_DRIVER::write() => Segmentation fault on attempt to write an empty mesh + try + { + //Trying write an empty mesh + aVtkDriver->write(); + } + catch (MEDEXCEPTION & ex) + { + // good behaviour + } + catch (...) + { + } + + aVtkDriver->close(); + + // (BUG) In copy constructor of VTK_MESH_DRIVER: Segmentation fault or Infinite loop + VTK_MESH_DRIVER aVtkDriverCpy_2 (*aVtkDriver); + + delete aVtkDriver; + delete aMesh; +} diff --git a/src/MEDMEMCppTest/MEDMEMTest_nArray.cxx b/src/MEDMEMCppTest/MEDMEMTest_nArray.cxx new file mode 100644 index 000000000..2d2c207fb --- /dev/null +++ b/src/MEDMEMCppTest/MEDMEMTest_nArray.cxx @@ -0,0 +1,534 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include "MEDMEMTest.hxx" +#include <cppunit/Message.h> +#include <cppunit/TestAssert.h> + +#include "MEDMEM_nArray.hxx" +#include "MEDMEM_define.hxx" +#include "MEDMEM_ArrayConvert.hxx" + +#include <sstream> +#include <cmath> + +// use this define to enable lines, execution of which leads to Segmentation Fault +//#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +//#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace MEDMEM; +using namespace MED_EN; + +/*! + * Check methods (21), defined in MEDMEM_nArray.hxx: + * class MEDMEM_Array_ { + * (-) virtual bool getGaussPresence() const { return false; } + * (-) virtual MED_EN::medModeSwitch getInterlacingType() const {return MED_EN::MED_UNDEFINED_INTERLACE;} + * (+) ~MEDMEM_Array_() {}; + * } + * template<class ARRAY_ELEMENT_TYPE, + * class INTERLACING_POLICY=FullInterlaceNoGaussPolicy, + * class CHECKING_POLICY=IndexCheckPolicy> + * class MEDMEM_Array : public INTERLACING_POLICY, public CHECKING_POLICY, public MEDMEM_Array_ { + * (+) MEDMEM_Array(); + * (+) ~MEDMEM_Array(); + * (+) inline MEDMEM_Array(int dim, int nbelem); + * (+) inline MEDMEM_Array(ElementType * values, int dim, int nbelem, + * bool shallowCopy=false, bool ownershipOfValues=false); + * (+) inline MEDMEM_Array(int dim, int nbelem, int nbtypegeo, + * const int * const nbelgeoc, const int * const nbgaussgeo); + * (+) inline MEDMEM_Array(ElementType * values, int dim, int nbelem, int nbtypegeo, + * const int * const nbelgeoc, const int * const nbgaussgeo, + * bool shallowCopy=false, bool ownershipOfValues=false); + * (+) inline MEDMEM_Array(const MEDMEM_Array & array, bool shallowCopy=false); + * (+) inline MEDMEM_Array<ElementType,InterlacingPolicy,CheckingPolicy> & + * operator=(const MEDMEM_Array & array); + * (+) MED_EN::medModeSwitch getInterlacingType() const; + * (+) bool getGaussPresence() const; + * (+) ElementType * getPtr(); + * (+) void setPtr(ElementType * values, bool shallowCopy=false, bool ownershipOfValues=false); + * (+) inline const ElementType * getRow(int i) const; + * (+) void setRow(int i,const ElementType * const value); + * (+) inline const ElementType * getColumn(int j) const; + * (+) void setColumn(int j, const ElementType * const value); + * (+) inline const ElementType & getIJ(int i, int j) const; + * (+) inline const ElementType & getIJK(int i, int j, int k) const; + * (+) inline void setIJ(int i, int j, const ElementType & value); + * (+) inline void setIJK(int i, int j, int k, const ElementType & value); + * (+) bool operator == (const MEDMEM_Array & array) const; + * (+) friend ostream & operator<<(ostream & os, const MEDMEM_Array & array); + * } + */ +void MEDMEMTest::testnArray() +{ + const int mdim = 2; + const int nbelem1 = 20; + const double EPS = 0.00001; + + ///////////////////////////////////////// + // TEST 1 FullInterlace et NoGauss // + //////////////////////////////////////// + const double * myArray1Ptr = 0; + const double array1Ref[] = { 11 , 12 , 21 , 22 , 31 , 32 , 41 , 42 , 51 , 52 , + 61 , 62 , 71 , 72 , 81 , 82 , 91 , 92 , 101 , 102 , + 111 , 112 , 121 , 122 , 131 , 132 , 141 , 142 , + 151 , 152 , 161 , 162 , 171 , 172 , 181 , 182 , + 191 , 192 , 201 , 202 }; + + const double array2Ref[] = { 11 , 21 , 31 , 41 , 51 , 61 , 71 , 81 , 91 , 101 + , 111 , 121 , 131 , 141 , 151 , 161 , 171 , 181 + , 191 , 201 , + 12 , 22 , 32 , 42 , 52 , 62 , 72 , 82 , 92 , 102 + , 112 , 122 , 132 , 142 , 152 , 162 , 172 , 182 + , 192 , 202 }; + + //test MEDMEM_Array(int dim, int nbelem) + MEDMEM_Array<double> myArray1(mdim,nbelem1); + //test getGaussPresence + CPPUNIT_ASSERT( !myArray1.getGaussPresence()); + + //test setIJ. Fill array + for (int i =1; i <= nbelem1; i++) + for (int j =1; j <= mdim; j++) + { + CPPUNIT_ASSERT_NO_THROW(myArray1.setIJ(i,j,i*10+j)); + } + + //test getPtr + myArray1Ptr = myArray1.getPtr(); + for (int i = 0; i < mdim*nbelem1; i++) + CPPUNIT_ASSERT( myArray1Ptr[i] == array1Ref[i] ); + + { + //test MEDMEM_Array(ElementType * values, int dim, int nbelem, bool shallowCopy=false, bool ownershipOfValues=false) + MEDMEM_Array<double> myArray1val ((double*)array1Ref, mdim, nbelem1); + myArray1Ptr = myArray1val.getPtr(); + for (int i = 0; i < mdim*nbelem1; i++) + CPPUNIT_ASSERT( myArray1Ptr[i] == array1Ref[i] ); + + //test MEDMEM_Array(ElementType * values, int dim, int nbelem, bool shallowCopy=true, bool ownershipOfValues=false); + MEDMEM_Array<double> myArray1valsh ((double*)array1Ref, mdim, nbelem1, true); + myArray1Ptr = myArray1valsh.getPtr(); + for (int i = 0; i < mdim*nbelem1; i++) + CPPUNIT_ASSERT( myArray1Ptr[i] == array1Ref[i] ); + + //test setPtr + double myPtr[] = {-1, -2, -3, -4, -5, -6, -7, -8, -9, 0}; + CPPUNIT_ASSERT_NO_THROW(myArray1valsh.setPtr(myPtr)); + //size the array stays the same, only first 10 element are being overwritten + myArray1Ptr = myArray1valsh.getPtr(); + for (int i = 0; i < 10; i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(myArray1Ptr[i], myPtr[i], EPS); + } + + //test MEDMEM_Array(ElementType * values, int dim, int nbelem, bool shallowCopy=true, bool ownershipOfValues=true); + { + double * array1Ref_do_not_delete = new double[40]; + for (int i = 0; i < 40; i = i + 2) { + array1Ref_do_not_delete[i ] = 10.0 * (i+1) + 1; + array1Ref_do_not_delete[i+1] = 10.0 * (i+1) + 2; + } + MEDMEM_Array<double> myArray1valow (array1Ref_do_not_delete, mdim, nbelem1, true, true); + } + + //test MEDMEM_Array(const MEDMEM_Array & array, bool shallowCopy=false) + MEDMEM_Array<double> myArray1bis (myArray1, false); + CPPUNIT_ASSERT(myArray1 == myArray1bis); + + myArray1Ptr = myArray1bis.getPtr(); + for (int i =0; i < mdim*nbelem1; i++) + CPPUNIT_ASSERT( myArray1Ptr[i] == array1Ref[i] ); + + //test MEDMEM_Array() + MEDMEM_Array<double> myArray1ter; + try + { + myArray1ter = myArray1; + myArray1Ptr = myArray1ter.getPtr(); + } + catch ( const std::exception &e ) + { + CPPUNIT_FAIL(e.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + + for (int i =0; i < mdim*nbelem1; i++) + CPPUNIT_ASSERT( myArray1Ptr[i] == array1Ref[i] ); + + MEDMEM_Array<double> myArray1qua(mdim,nbelem1); + myArray1Ptr = myArray1qua.getPtr(); + + for (int i =1; i <= nbelem1; i++) + { + try { + //test setRow(int i,const ElementType * const value) + myArray1qua.setRow(i,&array1Ref[(i-1)*mdim]); + } + catch (MEDMEM::MEDEXCEPTION &m) { + CPPUNIT_FAIL(m.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + } + + for (int i =0; i < mdim*nbelem1; i++) + CPPUNIT_ASSERT( myArray1Ptr[i] == array1Ref[i] ); + + //test getColumn(int j) + CPPUNIT_ASSERT_THROW(myArray1qua.getColumn(1), MEDEXCEPTION); + + MEDMEM_Array<double,NoInterlaceNoGaussPolicy> * myArray1cin = ArrayConvert(myArray1); + myArray1Ptr = myArray1cin->getPtr(); + int elemno = 0; + for (int j=1; j <= mdim; j++) + for (int i=1; i <= nbelem1 ; i++ ) { + CPPUNIT_ASSERT( myArray1cin->getIJ(i,j) == array2Ref[elemno] ); + CPPUNIT_ASSERT( myArray1Ptr[elemno] == array2Ref[elemno] ); + elemno++; + } + + ///////////////////////////////////// + // TEST 2 NoInterlace et NoGauss // + ///////////////////////////////////// + { + const double * myArray2Ptr = 0; + //MEDMEM_Array(int dim, int nbelem) + MEDMEM_Array<double,NoInterlaceNoGaussPolicy> myArray2(mdim,nbelem1); + + for (int i =1; i <= nbelem1; i++) { + for (int j =1; j <= mdim; j++) { + //test setIJ(int i, int j, const ElementType & value) + CPPUNIT_ASSERT_NO_THROW(myArray2.setIJ(i,j,i*10+j)); + } + } + + //test getPtr() + myArray2Ptr = myArray2.getPtr(); + for (int i =0; i < mdim*nbelem1; i++) + CPPUNIT_ASSERT( myArray2Ptr[i] == array2Ref[i] ); + + //test MEDMEM_Array(const MEDMEM_Array & array, bool shallowCopy=false) + MEDMEM_Array<double,NoInterlaceNoGaussPolicy> myArray2bis(myArray2, false); + myArray2Ptr = myArray2bis.getPtr(); + for (int i =0; i < mdim*nbelem1; i++) + CPPUNIT_ASSERT( myArray2Ptr[i] == array2Ref[i] ); + + //test MEDMEM_Array() + MEDMEM_Array<double,NoInterlaceNoGaussPolicy> myArray2ter; + //test operator=(const MEDMEM_Array & array) + myArray2ter = myArray2; + //test getPtr + myArray2Ptr = myArray2ter.getPtr(); + for (int i =0; i < mdim*nbelem1; i++) + CPPUNIT_ASSERT( myArray2Ptr[i] == array2Ref[i] ); + + MEDMEM_Array<double,NoInterlaceNoGaussPolicy> myArray2qua(mdim,nbelem1); + myArray2Ptr = myArray2qua.getPtr(); + + for (int j = 1; j <= mdim; j++) { + //test setColumn(int j, const ElementType * const value) + CPPUNIT_ASSERT_NO_THROW(myArray2qua.setColumn(j,&array2Ref[nbelem1*(j-1)])); + } + + for (int i =0; i < mdim*nbelem1; i++) + CPPUNIT_ASSERT( myArray2Ptr[i] == array2Ref[i] ); + + //test getRow(int i) + CPPUNIT_ASSERT_THROW(myArray2qua.getRow(1), MEDEXCEPTION); + + MEDMEM_Array<double,FullInterlaceNoGaussPolicy> * myArray2cin = ArrayConvert(myArray2); + myArray2Ptr = myArray2cin->getPtr(); + elemno = 0; + for (int i=1; i <= nbelem1 ; i++) { + for (int j=1; j <= mdim; j++) { + CPPUNIT_ASSERT( myArray2cin->getIJ(i,j) == array1Ref[elemno] ); + CPPUNIT_ASSERT( myArray2Ptr[elemno] == array1Ref[elemno] ); + elemno++; + } + } + } + + /////////////////////////////////////// + // TEST 3 FullInterlace et Gauss // + ////////////////////////////////////// + const int nbelem2 = 5; + const int nbtypegeo = 2; + const int nbelgeoc[nbtypegeo+1] = {1,3,6}; + const int nbgaussgeo[nbtypegeo+1] = {-1,2,3}; + + const double * myArray3Ptr = 0; + const double array3Ref[] = {1.11 , 1.12 , 1.21 , 1.22 , + 2.11 , 2.12 , 2.21 , 2.22 , + 13.11 , 13.12 , 13.21 , 13.22 , 13.31 , 13.32 , + 14.11 , 14.12 , 14.21 , 14.22 , 14.31 , 14.32 , + 15.11 , 15.12 , 15.21 , 15.22 , 15.31 , 15.32 }; + + const double array4Ref[] = { 1.11 , 1.21 , 2.11 , 2.21, + 13.11 , 13.21 , 13.31 , 14.11 , 14.21 , 14.31 , + 15.11 , 15.21 , 15.31 , + 1.12 , 1.22 , 2.12 , 2.22 , + 13.12 , 13.22 , 13.32 , 14.12 , 14.22 , 14.32 , + 15.12 , 15.22 , 15.32 }; + + const int array5Ref[] = { 1 , 1 , 2 , 2, + 13 , 13 , 13 , 14 , 14 , 14 , + 15 , 15 , 15 , + 1 , 1 , 2 , 2 , + 13 , 13 , 13 , 14 , 14 , 14 , + 15 , 15 , 15 }; + + //test MEDMEM_Array(int dim, int nbelem, int nbtypegeo, const int * const nbelgeoc, const int * const nbgaussgeo) + MEDMEM_Array<double,FullInterlaceGaussPolicy> myArray3(mdim,nbelem2,nbtypegeo,nbelgeoc,nbgaussgeo); + + elemno = 1; + for (int ntyp=1; ntyp <= nbtypegeo; ntyp++ ) { + for (int i=0; i < (nbelgeoc[ntyp]-nbelgeoc[ntyp-1]) ; i++ ) { + for (int k=1; k <= nbgaussgeo[ntyp]; k++) + for (int j=1; j <= mdim; j++) { + try{ + //test setIJK(int i, int j, int k, const ElementType & value) + myArray3.setIJK(elemno,j,k,elemno+(ntyp-1)*10+0.1*k+0.01*j); + } + catch (MEDMEM::MEDEXCEPTION &m) { + CPPUNIT_FAIL(m.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + } + elemno++; + } + } + + myArray3Ptr = myArray3.getPtr(); + for (int i =0; i < myArray3.getArraySize(); i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(myArray3Ptr[i], array3Ref[i], EPS); + + MEDMEM_Array<double,FullInterlaceGaussPolicy> myArray3bis(myArray3, false); + myArray3Ptr = myArray3bis.getPtr(); + + elemno = 0; + for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) + for (int k=1; k <= myArray3bis.getNbGauss(i); k++) + for (int j=1; j <= mdim; j++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray3bis.getIJK(i,j,k), array3Ref[elemno], EPS ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray3Ptr[elemno], array3Ref[elemno], EPS ); + elemno++; + } + + //test MEDMEM_Array() + MEDMEM_Array<double,FullInterlaceGaussPolicy> myArray3ter; + //test operator=(const MEDMEM_Array & array) + myArray3ter = myArray3; + myArray3Ptr = myArray3ter.getPtr(); + + elemno = 0; + for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) + for (int k=1; k <= myArray3ter.getNbGauss(i); k++) + for (int j=1; j <= mdim; j++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray3ter.getIJK(i,j,k), array3Ref[elemno], EPS ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray3Ptr[elemno], array3Ref[elemno], EPS ); + elemno++; + } + + MEDMEM_Array<double,FullInterlaceGaussPolicy> myArray3qua(mdim,nbelem2, + nbtypegeo,nbelgeoc,nbgaussgeo); + myArray3Ptr = myArray3qua.getPtr(); + + int cumul = 0; + for (int i =1; i <= nbelem2; i++){ + try{ + myArray3qua.setRow(i,&array3Ref[cumul]); + cumul+=myArray3qua.getNbGauss(i)*mdim; + } + catch (MEDMEM::MEDEXCEPTION &m) { + CPPUNIT_FAIL(m.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + }; + + int nnn = myArray3qua.getArraySize(); + for (int i =0; i < myArray3qua.getArraySize(); i++) { + double aa = myArray3Ptr[i]; + double bb = array3Ref[i]; + CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray3Ptr[i], array3Ref[i], EPS ); + } + + MEDMEM_Array<double,NoInterlaceGaussPolicy> * myArray3cin = ArrayConvert(myArray3); + myArray3Ptr = myArray3cin->getPtr(); + elemno = 0; + for (int j=1; j <= mdim; j++) + for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) + for (int k=1; k <= myArray3cin->getNbGauss(i); k++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray3cin->getIJK(i,j,k), array4Ref[elemno], EPS ); + CPPUNIT_ASSERT_DOUBLES_EQUAL(myArray3Ptr[elemno], array4Ref[elemno], EPS ); + elemno++; + } + + //////////////////////////////////// + // TEST 4 NoInterlace et Gauss // + //////////////////////////////////// + const double * myArray4Ptr = 0; + //test MEDMEM_Array(int dim, int nbelem, int nbtypegeo, const int * const nbelgeoc, const int * const nbgaussgeo) + MEDMEM_Array<double,NoInterlaceGaussPolicy> myArray4(mdim,nbelem2,nbtypegeo,nbelgeoc,nbgaussgeo); + + elemno = 1; + for (int ntyp=1; ntyp <= nbtypegeo; ntyp++ ) { + for (int i=0; i < (nbelgeoc[ntyp]-nbelgeoc[ntyp-1]) ; i++ ) { + for (int k=1; k <= nbgaussgeo[ntyp]; k++) + for (int j=1; j <= mdim; j++) { + try{ + //test setIJK(int i, int j, int k, const ElementType & value) + myArray4.setIJK(elemno,j,k,elemno+(ntyp-1)*10+0.1*k+0.01*j); + } + catch (MEDMEM::MEDEXCEPTION &m) { + CPPUNIT_FAIL(m.what()); + } + catch (...) + { + CPPUNIT_FAIL("Unknown exception"); + } + } + elemno++; + } + } + + //test getPtr() + myArray4Ptr = myArray4.getPtr(); + for (int i =0; i < myArray4.getArraySize(); i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray4Ptr[i], array4Ref[i], EPS ); + } + + //test MEDMEM_Array(const MEDMEM_Array & array, bool shallowCopy=false) + MEDMEM_Array<double,NoInterlaceGaussPolicy> myArray4bis(myArray4, false); + myArray4Ptr = myArray4bis.getPtr(); + + elemno = 0; + for (int j=1; j <= mdim; j++) + for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) + for (int k=1; k <= myArray4bis.getNbGauss(i); k++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray4bis.getIJK(i,j,k), array4Ref[elemno], EPS ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray4Ptr[elemno], array4Ref[elemno], EPS ); + elemno++; + } + + //test MEDMEM_Array() + MEDMEM_Array<double,NoInterlaceGaussPolicy> myArray4ter; + //test operator=(const MEDMEM_Array & array) + myArray4ter = myArray4; + myArray4Ptr = myArray4ter.getPtr(); + + elemno = 0; + for (int j=1; j <= mdim; j++) + for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) + for (int k=1; k <= myArray4ter.getNbGauss(i); k++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray4ter.getIJK(i,j,k), array4Ref[elemno], EPS ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray4Ptr[elemno], array4Ref[elemno], EPS ); + elemno++; + } + + { + MEDMEM_Array<double,NoInterlaceGaussPolicy> myArray4qua (mdim,nbelem2,nbtypegeo,nbelgeoc,nbgaussgeo); + myArray4Ptr = myArray4qua.getPtr(); + + for (int j = 1; j <= mdim; j++) { + int k = (myArray4qua.getArraySize() / mdim) * (j - 1); + CPPUNIT_ASSERT_NO_THROW(myArray4qua.setColumn(j, &array4Ref[k])); + } + + for (int i =0; i < myArray4qua.getArraySize(); i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray4Ptr[i], array4Ref[i], EPS ); + } + + { + MEDMEM_Array<double,FullInterlaceGaussPolicy> * myArray4cin = ArrayConvert(myArray4); + myArray4Ptr = myArray4cin->getPtr(); + elemno = 0; + for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) + for (int k=1; k <= myArray4cin->getNbGauss(i); k++) + for (int j=1; j <= mdim; j++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray4cin->getIJK(i,j,k), array3Ref[elemno], EPS ); + CPPUNIT_ASSERT( myArray4cin->getIJK(i,j,k) == myArray3.getIJK(i,j,k) ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( myArray4Ptr[elemno], array3Ref[elemno], EPS ); + elemno++; + } + delete myArray4cin; + } + + CPPUNIT_ASSERT(myArray4bis.getInterlacingType() != MED_UNDEFINED_INTERLACE); + + CPPUNIT_ASSERT_THROW(myArray4.getIJ(0,2), MEDEXCEPTION); + + ostringstream os; + //test operator<<(ostream & os, const MEDMEM_Array & array) + os << myArray4; + CPPUNIT_ASSERT(os.str() != ""); + + const int * myArray5Ptr = 0; + //test MEDMEM_Array(ElementType * values, int dim, int nbelem, int nbtypegeo, + // const int * const nbelgeoc, const int * const nbgaussgeo, + // bool shallowCopy=false, bool ownershipOfValues=false) + MEDMEM_Array<int, NoInterlaceGaussPolicy> myArray5 ((int*)array5Ref, mdim, nbelem2, + nbtypegeo, nbelgeoc, nbgaussgeo); + //test getGaussPresence + CPPUNIT_ASSERT( myArray5.getGaussPresence()); + + myArray5Ptr = myArray5.getPtr(); + for (int i =0; i < myArray5.getArraySize(); i++) { + CPPUNIT_ASSERT_EQUAL( myArray5Ptr[i], array5Ref[i]); + } + + //test MEDMEM_Array(const MEDMEM_Array & array, bool shallowCopy=false) + MEDMEM_Array<int,NoInterlaceGaussPolicy> myArray5bis(myArray5, false); + myArray5Ptr = myArray5bis.getPtr(); + + elemno = 0; + for (int j=1; j <= mdim; j++) + for (int i=1; i < nbelgeoc[nbtypegeo] ; i++ ) + for (int k=1; k <= myArray5bis.getNbGauss(i); k++) { + CPPUNIT_ASSERT_EQUAL( myArray5bis.getIJK(i,j,k), array5Ref[elemno] ); + CPPUNIT_ASSERT_EQUAL( myArray5Ptr[elemno], array5Ref[elemno] ); + elemno++; + } + + //MEDMEM_Array() + MEDMEM_Array<int,NoInterlaceGaussPolicy> myArray5ter; + //test setPtr(ElementType * values, bool shallowCopy=false, bool ownershipOfValues=false) + CPPUNIT_ASSERT_NO_THROW(myArray5.setPtr((int*)array5Ref)); + + //test getPtr() + myArray5Ptr = myArray5ter.getPtr(); + for (int i =0; i < myArray5ter.getArraySize(); i++) { + CPPUNIT_ASSERT_EQUAL( myArray5Ptr[i], array5Ref[i]); + } +} diff --git a/src/MEDMEMCppTest/Makefile.am b/src/MEDMEMCppTest/Makefile.am new file mode 100644 index 000000000..27fc38486 --- /dev/null +++ b/src/MEDMEMCppTest/Makefile.am @@ -0,0 +1,127 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +# SALOMELocalTrace : log on local machine +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +lib_LTLIBRARIES = libMEDMEMCppTest.la + +salomeinclude_HEADERS = MEDMEMTest.hxx + +EXTRA_DIST += BasicMainTest.hxx + +dist_libMEDMEMCppTest_la_SOURCES= \ + MEDMEMTest.cxx \ + MEDMEMTest_Array.cxx \ + MEDMEMTest_AsciiFieldDriver.cxx \ + MEDMEMTest_Connectivity.cxx \ + MEDMEMTest_Coordinate.cxx \ + MEDMEMTest_DriverFactory.cxx \ + MEDMEMTest_Exception.cxx \ + MEDMEMTest_Extractor.cxx \ + MEDMEMTest_Family.cxx \ + MEDMEMTest_Field.cxx \ + MEDMEMTest_Formulae.cxx \ + MEDMEMTest_GaussLocalization.cxx \ + MEDMEMTest_GibiMeshDriver.cxx \ + MEDMEMTest_Grid.cxx \ + MEDMEMTest_Group.cxx \ + MEDMEMTest_Med.cxx \ + MEDMEMTest_MedFieldDriver21.cxx \ + MEDMEMTest_MedFieldDriver22.cxx \ + MEDMEMTest_MedMedDriver21.cxx \ + MEDMEMTest_MedMedDriver22.cxx \ + MEDMEMTest_MedMeshDriver21.cxx \ + MEDMEMTest_MedMeshDriver22.cxx \ + MEDMEMTest_MedVersion.cxx \ + MEDMEMTest_MeshAndMeshing.cxx \ + MEDMEMTest_ModulusArray.cxx \ + MEDMEMTest_nArray.cxx \ + MEDMEMTest_PointerOf.cxx \ + MEDMEMTest_PolyhedronArray.cxx \ + MEDMEMTest_PorflowMeshDriver.cxx \ + MEDMEMTest_SkyLineArray.cxx \ + MEDMEMTest_Support.cxx \ + MEDMEMTest_TopLevel.cxx \ + MEDMEMTest_Unit.cxx \ + MEDMEMTest_VtkFieldDriver.cxx \ + MEDMEMTest_VtkMedDriver.cxx \ + MEDMEMTest_VtkMeshDriver.cxx + +libMEDMEMCppTest_la_CPPFLAGS= @CPPUNIT_INCLUDES@ $(MED2_INCLUDES) $(HDF5_INCLUDES) \ + -I$(srcdir)/../MEDMEM -I$(srcdir)/../INTERP_KERNEL -I$(srcdir)/../MEDWrapper/V2_1/Core +libMEDMEMCppTest_la_LDFLAGS= $(MED2_LIBS) @CPPUNIT_LIBS@ + +if MED_ENABLE_KERNEL + libMEDMEMCppTest_la_CPPFLAGS+= ${KERNEL_CXXFLAGS} + libMEDMEMCppTest_la_LDFLAGS+= ${KERNEL_LDFLAGS} -lSALOMELocalTrace +endif + +# Executables targets +bin_PROGRAMS = \ + TestMEDMEM \ + MEDMEMTest_Array_fault \ + MEDMEMTest_Connectivity_fault \ + MEDMEMTest_Coordinate_fault \ + MEDMEMTest_Family_fault \ + MEDMEMTest_Field_fault \ + MEDMEMTest_Grid_fault \ + MEDMEMTest_MedFieldDriver21_fault \ + MEDMEMTest_MedMedDriver21_fault \ + MEDMEMTest_MedMedDriver22_fault \ + MEDMEMTest_MeshAndMeshing_fault \ + MEDMEMTest_Support_fault \ + MEDMEMTest_VtkFieldDriver_fault \ + MEDMEMTest_VtkMeshDriver_fault + +dist_TestMEDMEM_SOURCES= TestMEDMEM.cxx +dist_MEDMEMTest_Array_fault_SOURCES= MEDMEMTest_Array_fault.cxx +dist_MEDMEMTest_Connectivity_fault_SOURCES= MEDMEMTest_Connectivity_fault.cxx +dist_MEDMEMTest_Coordinate_fault_SOURCES= MEDMEMTest_Coordinate_fault.cxx +dist_MEDMEMTest_Family_fault_SOURCES= MEDMEMTest_Family_fault.cxx +dist_MEDMEMTest_Field_fault_SOURCES= MEDMEMTest_Field_fault.cxx +dist_MEDMEMTest_Grid_fault_SOURCES= MEDMEMTest_Grid_fault.cxx +dist_MEDMEMTest_MedFieldDriver21_fault_SOURCES= MEDMEMTest_MedFieldDriver21_fault.cxx +dist_MEDMEMTest_MedMedDriver21_fault_SOURCES= MEDMEMTest_MedMedDriver21_fault.cxx +dist_MEDMEMTest_MedMedDriver22_fault_SOURCES= MEDMEMTest_MedMedDriver22_fault.cxx +dist_MEDMEMTest_MeshAndMeshing_fault_SOURCES= MEDMEMTest_MeshAndMeshing_fault.cxx +dist_MEDMEMTest_Support_fault_SOURCES= MEDMEMTest_Support_fault.cxx +dist_MEDMEMTest_VtkFieldDriver_fault_SOURCES= MEDMEMTest_VtkFieldDriver_fault.cxx +dist_MEDMEMTest_VtkMeshDriver_fault_SOURCES= MEDMEMTest_VtkMeshDriver_fault.cxx + +LDADD= $(MED2_LIBS) $(libMEDMEMCppTest_la_LDFLAGS) -lm \ + ../MEDWrapper/V2_1/Core/libmed_V2_1.la ../MEDMEM/libmedmem.la libMEDMEMCppTest.la +if MED_ENABLE_KERNEL + LDADD+= -lSALOMEBasics +endif +AM_CPPFLAGS= $(libMEDMEMCppTest_la_CPPFLAGS) + +dist_salomescript_DATA = testMEDMEM.py + +UNIT_TEST_PROG = TestMEDMEM + +OBSOLETE_FILES = \ + TestOpenMED.cxx + +EXTRA_DIST += $(OBSOLETE_FILES) + +check: tests diff --git a/src/MEDMEMCppTest/TestMEDMEM.cxx b/src/MEDMEMCppTest/TestMEDMEM.cxx new file mode 100644 index 000000000..4577cb3ce --- /dev/null +++ b/src/MEDMEMCppTest/TestMEDMEM.cxx @@ -0,0 +1,32 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +// --- include all MEDMEM Test +// +#include "MEDMEMTest.hxx" + +// --- Registers the fixture into the 'registry' + +CPPUNIT_TEST_SUITE_REGISTRATION( MEDMEMTest ); + +// --- generic Main program from KERNEL_SRC/src/Basics/Test + +#include "BasicMainTest.hxx" diff --git a/src/MEDMEMCppTest/TestOpenMED.cxx b/src/MEDMEMCppTest/TestOpenMED.cxx new file mode 100644 index 000000000..5161e69d5 --- /dev/null +++ b/src/MEDMEMCppTest/TestOpenMED.cxx @@ -0,0 +1,76 @@ +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +#include <string> +#include <iostream> + +using namespace std; + +namespace med_2_3 { + extern "C" { + #include <med.h> + #include <med_proto.h> + extern med_idt _MEDdatagroupOuvrir(med_idt pid, char *nom); + extern med_err _MEDdatagroupFermer(med_idt id); + } +} + +int main(int argc, char** argv) +{ + cout<<"test start"<<endl; + + string datadir = getenv("MED_ROOT_DIR"); + std::string filename = datadir + "/share/salome/resources/med/pointe_import22.med"; + + med_2_3::med_idt medIdt = med_2_3::MEDouvrir( (const_cast <char *> (filename.c_str())), + med_2_3::MED_LECTURE_ECRITURE); + + cout<<"The idt of file "<<filename<<" is : "<<medIdt<<endl; + + if(medIdt > 0) { + cout<<"File is opened in mode MED_LECTURE_ECRITURE"<<endl; + int err = med_2_3::MEDfermer(medIdt); + if (err != 0) + cout<<"Error when closing file !"<<endl; + } + else { + cout<<"Could not open file in mode MED_LECTURE_ECRITURE"<<endl; + } + + medIdt = med_2_3::MEDouvrir( (const_cast <char *> (filename.c_str())), + med_2_3::MED_LECTURE); + + cout<<"The idt of file "<<filename<<" is : "<<medIdt<<endl; + + if(medIdt > 0) { + cout<<"File is opened in mode MED_LECTURE"<<endl; + int err = med_2_3::MEDfermer(medIdt); + if (err != 0) + cout<<"Error when closing file !"<<endl; + } + else { + cout<<"Could not open file in mode MED_LECTURE"<<endl; + } + + cout<<"test end"<<endl; + + return 1; +} diff --git a/src/MEDMEMCppTest/testMEDMEM.py b/src/MEDMEMCppTest/testMEDMEM.py new file mode 100644 index 000000000..8c8a2495c --- /dev/null +++ b/src/MEDMEMCppTest/testMEDMEM.py @@ -0,0 +1,91 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +import sys, os,signal,string,commands +###import runSalome +###import orbmodule +###import TestKiller + +# get SALOME environment : + +###args, modules_list, modules_root_dir = runSalome.get_config() +###runSalome.set_env(args, modules_list, modules_root_dir) + +# launch CORBA naming server + +###clt=orbmodule.client() + +# launch CORBA logger server + +###myServer=runSalome.LoggerServer(args) +###myServer.run() +###clt.waitLogger("Logger") + +# execute Unit Test + +command = ['TestMEDMEM'] +ret = os.spawnvp(os.P_WAIT, command[0], command) + +print "MEDMEM General testing done." +print "Run cases, which leads to Segmentation Fault ..." + +command = ['MEDMEMTest_Array_fault'] +ret = os.spawnvp(os.P_WAIT, command[0], command) + +command = ['MEDMEMTest_Connectivity_fault'] +ret = os.spawnvp(os.P_WAIT, command[0], command) + +command = ['MEDMEMTest_Coordinate_fault'] +ret = os.spawnvp(os.P_WAIT, command[0], command) + +command = ['MEDMEMTest_Family_fault'] +ret = os.spawnvp(os.P_WAIT, command[0], command) + +command = ['MEDMEMTest_Field_fault'] +ret = os.spawnvp(os.P_WAIT, command[0], command) + +command = ['MEDMEMTest_Grid_fault'] +ret = os.spawnvp(os.P_WAIT, command[0], command) + +command = ['MEDMEMTest_MedFieldDriver21_fault'] +ret = os.spawnvp(os.P_WAIT, command[0], command) + +command = ['MEDMEMTest_MedMedDriver21_fault'] +ret = os.spawnvp(os.P_WAIT, command[0], command) + +command = ['MEDMEMTest_MedMedDriver22_fault'] +ret = os.spawnvp(os.P_WAIT, command[0], command) + +command = ['MEDMEMTest_MeshAndMeshing_fault'] +ret = os.spawnvp(os.P_WAIT, command[0], command) + +command = ['MEDMEMTest_Support_fault'] +ret = os.spawnvp(os.P_WAIT, command[0], command) + +command = ['MEDMEMTest_VtkFieldDriver_fault'] +ret = os.spawnvp(os.P_WAIT, command[0], command) + +command = ['MEDMEMTest_VtkMeshDriver_fault'] +ret = os.spawnvp(os.P_WAIT, command[0], command) + +# kill Test process + +###TestKiller.killProcess(runSalome.process_id) diff --git a/src/MEDMEM_I/MEDMEM_Family_i.cxx b/src/MEDMEM_I/MEDMEM_Family_i.cxx index 5b7a74e59..c9f832511 100644 --- a/src/MEDMEM_I/MEDMEM_Family_i.cxx +++ b/src/MEDMEM_I/MEDMEM_Family_i.cxx @@ -1,28 +1,31 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// //============================================================================= // File : MEDMEM_Family_i.cxx // Project : SALOME // Author : EDF // $Header: /export/home/PAL/MED_SRC/src/MEDMEM_I/MEDMEM_Family_i.cxx //============================================================================= - +// #include "utilities.h" #include "Utils_CorbaException.hxx" #include "MEDMEM_Family_i.hxx" @@ -37,8 +40,9 @@ using namespace MEDMEM; FAMILY_i::FAMILY_i(): _family((::FAMILY*)NULL), SUPPORT_i() { - BEGIN_OF("Default Constructor FAMILY_i"); - END_OF("Default Constructor FAMILY_i"); + const char* LOC = "Default Constructor FAMILY_i"; + BEGIN_OF(LOC); + END_OF(LOC); } //============================================================================= /*! @@ -48,8 +52,9 @@ FAMILY_i::FAMILY_i(): _family((::FAMILY*)NULL), FAMILY_i::FAMILY_i(const FAMILY_i & f): _family(f._family), SUPPORT_i(f._family) { - BEGIN_OF("Default Constructor FAMILY_i"); - END_OF("Default Constructor FAMILY_i"); + const char* LOC = "Default Constructor FAMILY_i"; + BEGIN_OF(LOC); + END_OF(LOC); } //============================================================================= /*! @@ -67,8 +72,9 @@ FAMILY_i::~FAMILY_i() FAMILY_i::FAMILY_i(const ::FAMILY * const f): _family(f), SUPPORT_i(f) { - BEGIN_OF("Constructor FAMILY_i"); - END_OF("Constructor FAMILY_i"); + const char* LOC = "Constructor FAMILY_i"; + BEGIN_OF(LOC); + END_OF(LOC); } //============================================================================= /*! diff --git a/src/MEDMEM_I/MEDMEM_Family_i.hxx b/src/MEDMEM_I/MEDMEM_Family_i.hxx index 12a908eec..deb2eb0cd 100644 --- a/src/MEDMEM_I/MEDMEM_Family_i.hxx +++ b/src/MEDMEM_I/MEDMEM_Family_i.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // //============================================================================= // File : MEDMEM_Family_i.hxx @@ -23,6 +25,7 @@ // Author : EDF // $Header: /export/home/PAL/MED_SRC/src/MEDMEM_I/MEDMEM_Family_i.hxx //============================================================================= +// #ifndef MED_FAMILY_I_HXX_ #define MED_FAMILY_I_HXX_ diff --git a/src/MEDMEM_I/MEDMEM_FieldTemplate_i.hxx b/src/MEDMEM_I/MEDMEM_FieldTemplate_i.hxx index 0fe7519ca..411b0aa8e 100644 --- a/src/MEDMEM_I/MEDMEM_FieldTemplate_i.hxx +++ b/src/MEDMEM_I/MEDMEM_FieldTemplate_i.hxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #ifndef __MED_FIELDTEMPLATE_I_HXX__ #define __MED_FIELDTEMPLATE_I_HXX__ @@ -27,6 +30,7 @@ #include "MultiCommException.hxx" #include "MEDMEM_ArrayConvert.hxx" #include "MEDMEM_TraitsForFields.hxx" +#include "utilities.h" namespace MEDMEM { @@ -54,8 +58,9 @@ namespace MEDMEM template < class T, class INTERLACING_TAG > FIELDTEMPLATE_I<T,INTERLACING_TAG>::FIELDTEMPLATE_I(): FIELD_i() { - BEGIN_OF("Default Constructor FIELDTEMPLATE_I"); - END_OF("Default Constructor FIELDTEMPLATE_I"); + const char* LOC = "Default Constructor FIELDTEMPLATE_I"; + BEGIN_OF(LOC); + END_OF(LOC); } //============================================================================= /*! @@ -65,8 +70,9 @@ namespace MEDMEM template < class T, class INTERLACING_TAG > FIELDTEMPLATE_I<T,INTERLACING_TAG>::~FIELDTEMPLATE_I() { - BEGIN_OF("Default Destructor FIELDTEMPLATE_I"); - END_OF("Default Destructor FIELDTEMPLATE_I"); + const char* LOC = "Default Destructor FIELDTEMPLATE_I"; + BEGIN_OF(LOC); + END_OF(LOC); } //============================================================================= /*! @@ -77,8 +83,9 @@ namespace MEDMEM FIELDTEMPLATE_I<T,INTERLACING_TAG>::FIELDTEMPLATE_I(FIELDTEMPLATE_I<T, INTERLACING_TAG>& fd): FIELD_i(fd) { - BEGIN_OF("Default Constructor FIELDTEMPLATE_I"); - END_OF("Default Constructor FIELDTEMPLATE_I"); + const char* LOC = "Default Constructor FIELDTEMPLATE_I"; + BEGIN_OF(LOC); + END_OF(LOC); } //============================================================================= /*! @@ -88,8 +95,9 @@ namespace MEDMEM template < class T, class INTERLACING_TAG > FIELDTEMPLATE_I<T,INTERLACING_TAG>::FIELDTEMPLATE_I(MEDMEM::FIELD<T, INTERLACING_TAG> *f, bool ownCppPtr):FIELD_i(f,ownCppPtr) { - BEGIN_OF("Constructor FIELDTEMPLATE_I"); - END_OF(" Constructor FIELDTEMPLATE_I"); + const char* LOC = "Constructor FIELDTEMPLATE_I"; + BEGIN_OF(LOC); + END_OF(LOC); } //============================================================================= diff --git a/src/MEDMEM_I/MEDMEM_Field_i.cxx b/src/MEDMEM_I/MEDMEM_Field_i.cxx index f7d36a80a..ac3b55d73 100644 --- a/src/MEDMEM_I/MEDMEM_Field_i.cxx +++ b/src/MEDMEM_I/MEDMEM_Field_i.cxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// //============================================================================= // File : MEDMEM_Field_i.cxx // Created : mer fév 20 15:47:57 CET 2002 @@ -23,7 +26,7 @@ // Project : SALOME // $Header : $ //============================================================================= - +// #include "MEDMEM_Field_i.hxx" #include "SALOME_NamingService.hxx" @@ -47,8 +50,9 @@ int FIELD_i::fieldIndex = 0; //FIELD_i::FIELD_i():_fieldTptr(FIELD_i::constructConstField()) FIELD_i::FIELD_i():_fieldTptr(constructConstField()),_corbaIndex(FIELD_i::fieldIndex++) { - BEGIN_OF("Default Constructor Field_i"); - END_OF(" Default Constructor Field_i"); + const char* LOC = "Default Constructor Field_i"; + BEGIN_OF(LOC); + END_OF(LOC); } //============================================================================= /*! @@ -70,14 +74,15 @@ FIELD_i::FIELD_i(::FIELD_ * const field, bool ownCppPtr): _FieldId(""), _ownCppPtr(ownCppPtr) { - BEGIN_OF("Constructor FIELD_i(SALOME_MED::SUPPORT_ptr support,::FIELD<T> * const field)"); + const char* LOC = "Constructor FIELD_i(SALOME_MED::SUPPORT_ptr support,::FIELD<T> * const field)"; + BEGIN_OF(LOC); FIELD_i::fieldMap[_corbaIndex]=_fieldTptr; MESSAGE("FIELD_i::FIELD_i Checking of pointeurs !!!"); SCRUTE(_fieldTptr); - END_OF("Constructor FIELD_i(SALOME_MED::SUPPORT_ptr support,::FIELD<T> * const field)"); + END_OF(LOC); } //============================================================================= @@ -89,9 +94,10 @@ FIELD_i::FIELD_i( FIELD_i & f):_fieldTptr(f._fieldTptr), _corbaIndex(FIELD_i::fieldIndex++), _FieldId(""), _ownCppPtr(false) { - BEGIN_OF("Constructor Field_i"); + const char* LOC = "Constructor Field_i"; + BEGIN_OF(LOC); FIELD_i::fieldMap[_corbaIndex]=_fieldTptr; - END_OF("Constructor Field_i"); + END_OF(LOC); } //============================================================================= /*! @@ -170,7 +176,8 @@ throw (SALOME::SALOME_Exception) SALOME_MED::SUPPORT_ptr FIELD_i::getSupport() throw (SALOME::SALOME_Exception) { - BEGIN_OF("SALOME_MED::SUPPORT_ptr FIELD_i::getSupport()"); + const char* LOC = "SALOME_MED::SUPPORT_ptr FIELD_i::getSupport()"; + BEGIN_OF(LOC); if (_fieldTptr==NULL) THROW_SALOME_CORBA_EXCEPTION("No associated Field", @@ -182,7 +189,7 @@ SALOME_MED::SUPPORT_ptr FIELD_i::getSupport() SCRUTE(_fieldTptr); - END_OF("SALOME_MED::SUPPORT_ptr FIELD_i::getSupport()"); + END_OF(LOC); return support ; } @@ -492,7 +499,8 @@ void FIELD_i::addInStudyToComponent (SALOMEDS::SComponent_ptr myComponent, SALOME_MED::FIELD_ptr myIor) throw (SALOME::SALOME_Exception, SALOMEDS::StudyBuilder::LockProtection) { - BEGIN_OF(" FIELD_i::addInStudy"); + const char* LOC = " FIELD_i::addInStudy"; + BEGIN_OF(LOC); if (CORBA::is_nil(myComponent) || CORBA::is_nil(myIor)) THROW_SALOME_CORBA_EXCEPTION("Null parameter", SALOME::BAD_PARAM); @@ -640,7 +648,7 @@ void FIELD_i::addInStudyToComponent (SALOMEDS::SComponent_ptr myComponent, MESSAGE("FIELD_i::addInStudy"); - //END_OF("FIELD_i::addInStudy"); + //END_OF(); } //============================================================================= diff --git a/src/MEDMEM_I/MEDMEM_Field_i.hxx b/src/MEDMEM_I/MEDMEM_Field_i.hxx index 742b0bd6e..0ac91c96f 100644 --- a/src/MEDMEM_I/MEDMEM_Field_i.hxx +++ b/src/MEDMEM_I/MEDMEM_Field_i.hxx @@ -1,29 +1,31 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// //============================================================================= // File : MEDMEM_Field_i.hxx // Project : SALOME // Author : EDF // $Header : $ //============================================================================= - - +// #ifndef MED_FIELD_I_HXX_ #define MED_FIELD_I_HXX_ diff --git a/src/MEDMEM_I/MEDMEM_Group_i.cxx b/src/MEDMEM_I/MEDMEM_Group_i.cxx index 20ffa385a..f4957b8d5 100644 --- a/src/MEDMEM_I/MEDMEM_Group_i.cxx +++ b/src/MEDMEM_I/MEDMEM_Group_i.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // //============================================================================= // File : MEDMEM_Group_i.cxx @@ -23,7 +25,7 @@ // Author : EDF // $Header: /export/home/PAL/MED_SRC/src/MEDMEM_I/MEDMEM_Group_i.cxx //============================================================================= - +// #include <vector> #include "utilities.h" @@ -44,8 +46,9 @@ using namespace MEDMEM; GROUP_i::GROUP_i():_group((::GROUP*)NULL), SUPPORT_i() { - BEGIN_OF("Default Constructor GROUP_i"); - END_OF("Default Constructor GROUP_i"); + const char* LOC = "Default Constructor GROUP_i"; + BEGIN_OF(LOC); + END_OF(LOC); }; //============================================================================= /*! @@ -63,8 +66,9 @@ GROUP_i::~GROUP_i() GROUP_i::GROUP_i(const ::GROUP * const g):_group(g), SUPPORT_i(g) { - BEGIN_OF("Constructor GROUP_i"); - END_OF("Constructor GROUP_i"); + const char* LOC = "Constructor GROUP_i"; + BEGIN_OF(LOC); + END_OF(LOC); }; //============================================================================= /*! @@ -74,8 +78,9 @@ GROUP_i::GROUP_i(const ::GROUP * const g):_group(g), GROUP_i::GROUP_i(const GROUP_i & g):_group(g._group), SUPPORT_i(g._group) { - BEGIN_OF("Constructor GROUP_i"); - END_OF("Constructor GROUP_i"); + const char* LOC = "Constructor GROUP_i"; + BEGIN_OF(LOC); + END_OF(LOC); }; //============================================================================= /*! diff --git a/src/MEDMEM_I/MEDMEM_Group_i.hxx b/src/MEDMEM_I/MEDMEM_Group_i.hxx index 517eae839..19de57679 100644 --- a/src/MEDMEM_I/MEDMEM_Group_i.hxx +++ b/src/MEDMEM_I/MEDMEM_Group_i.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // //============================================================================= // File : MEDMEM_Group_i.hxx @@ -23,6 +25,7 @@ // Author : EDF // $Header: /export/home/PAL/MED_SRC/src/MEDMEM_I/MEDMEM_Group_i.hxx //============================================================================= +// #ifndef MED_GROUP_I_HXX_ #define MED_GROUP_I_HXX_ diff --git a/src/MEDMEM_I/MEDMEM_I.hxx b/src/MEDMEM_I/MEDMEM_I.hxx index 4b469b51b..03a2b1bc5 100755 --- a/src/MEDMEM_I/MEDMEM_I.hxx +++ b/src/MEDMEM_I/MEDMEM_I.hxx @@ -1,28 +1,28 @@ -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. +// +// 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 // // File : MEDMEM_I.hxx // Author : Alexander A. BORODIN // Module : MED - +// #ifndef _MEDMEM_I_HXX_ #define _MEDMEM_I_HXX_ @@ -44,4 +44,4 @@ #define MEDMEM_I_EXPORT #endif -#endif \ No newline at end of file +#endif diff --git a/src/MEDMEM_I/MEDMEM_Med_i.cxx b/src/MEDMEM_I/MEDMEM_Med_i.cxx index 98c023aa6..8ccce99eb 100644 --- a/src/MEDMEM_I/MEDMEM_Med_i.cxx +++ b/src/MEDMEM_I/MEDMEM_Med_i.cxx @@ -1,28 +1,31 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// //============================================================================= // File : MEDMEM_Med_i.cxx // Project : SALOME // Author : EDF // $Header: /export/home/PAL/MED_SRC/src/MEDMEM_I/MEDMEM_i.cxx //============================================================================= - +// #include <deque> //#include "MEDMEM_Field.hxx" @@ -51,8 +54,9 @@ using namespace MEDMEM; //============================================================================= MED_i::MED_i():_med((::MED*)NULL) { - BEGIN_OF("Default Constructor MED_i"); - END_OF("Default Constructor MED_i"); + const char* LOC = "Default Constructor MED_i"; + BEGIN_OF(LOC); + END_OF(LOC); } //============================================================================= @@ -62,8 +66,8 @@ MED_i::MED_i():_med((::MED*)NULL) //============================================================================= void MED_i::init(SALOMEDS::Study_ptr myStudy,driverTypes driverType, const string & fileName) { - const char * LOC = "MED_i::init(driverTypes, const string &)"; - BEGIN_OF(LOC); + const char* LOC = "MED_i::init(driverTypes, const string &)"; + BEGIN_OF(LOC); // we create all IOR from _med _med = new ::MED(driverType,fileName); @@ -243,8 +247,8 @@ void MED_i::initWithFieldType(SALOMEDS::Study_ptr myStudy,driverTypes driverType // if (persistence): // some objects can be not published - const char * LOC = "MED_i::initWithFieldType(driverTypes, const string &)"; - BEGIN_OF(LOC); + const char* LOC = "MED_i::initWithFieldType(driverTypes, const string &)"; + BEGIN_OF(LOC); // we create all IOR from _med @@ -257,9 +261,6 @@ void MED_i::initWithFieldType(SALOMEDS::Study_ptr myStudy,driverTypes driverType SCRUTE(numberOfMeshes); // MESHES : deque<string> meshesNames = _med->getMeshNames(); - string meshName0 = meshesNames[0]; - - SCRUTE(meshName0); for (int i=0; i<numberOfMeshes; i++) { @@ -301,11 +302,13 @@ void MED_i::initWithFieldType(SALOMEDS::Study_ptr myStudy,driverTypes driverType currentEntity != MED_EN::meshEntities.end(); currentEntity++) { - MESSAGE(LOC << ": for entity " << (*currentEntity).first); - // family : + //MESSAGE(LOC << ": for entity " << (*currentEntity).first); + MESSAGE("initWithFieldType: for entity " << (*currentEntity).first); + // family : familyVector = ptrMesh->getFamilies((MED_EN::medEntityMesh)(*currentEntity).first); int nb = familyVector.size(); - MESSAGE(LOC << ": there is(are) " << nb << " family(ies)"); + //MESSAGE(LOC << ": there is(are) " << nb << " family(ies)"); + MESSAGE("initWithFieldType: there is(are) " << nb << " family(ies)"); for (familyVectorIt = familyVector.begin(); familyVectorIt != familyVector.end(); familyVectorIt++) @@ -322,7 +325,8 @@ void MED_i::initWithFieldType(SALOMEDS::Study_ptr myStudy,driverTypes driverType // group : groupVector = ptrMesh->getGroups((MED_EN::medEntityMesh)(*currentEntity).first); nb = groupVector.size(); - MESSAGE(LOC << ": there is(are) " << nb << " group(s)"); + //MESSAGE(LOC << ": there is(are) " << nb << " group(s)"); + MESSAGE("initWithFieldType: there is(are) " << nb << " group(s)"); for (groupVectorIt = groupVector.begin(); groupVectorIt != groupVector.end(); groupVectorIt++) @@ -539,7 +543,8 @@ void MED_i::initWithFieldType(SALOMEDS::Study_ptr myStudy,driverTypes driverType myFieldIntI = new FIELDTEMPLATE_I<int,NoInterlace>((FIELD<int,NoInterlace>*)myField); myFieldIntIOR = myFieldIntI->_this(); } - MESSAGE(LOC << " add in study of the field " << fieldsNames[i].c_str() + //MESSAGE(LOC << " add in study of the field " << fieldsNames[i].c_str() + MESSAGE("initWithFieldType: add in study of the field " << fieldsNames[i].c_str() << " dt = " << dtIt.dt << " it = " << dtIt.it); //if ( !persistence || @@ -565,8 +570,9 @@ void MED_i::initWithFieldType(SALOMEDS::Study_ptr myStudy,driverTypes driverType myFieldDoubleI = new FIELDTEMPLATE_I<double,NoInterlace>((FIELD<double,NoInterlace>*)myField); myFieldDoubleIOR = myFieldDoubleI->_this(); } - MESSAGE(LOC << " add in study of the field " << fieldsNames[i].c_str() - << " dt = " << dtIt.dt << " it = " << dtIt.it); + //MESSAGE(LOC << " add in study of the field " + MESSAGE("initWithFieldType: add in study of the field " + << fieldsNames[i].c_str() << " dt = " << dtIt.dt << " it = " << dtIt.it); //if ( !persistence || // isPublishedObject( myStudy, myFieldDoubleI->getEntryPath() )) @@ -589,7 +595,7 @@ void MED_i::initWithFieldType(SALOMEDS::Study_ptr myStudy,driverTypes driverType MESSAGE("Here we are i="<< i); } - END_OF(LOC); + END_OF(LOC); } //================================================================================ @@ -907,8 +913,8 @@ SALOME_MED::FIELD_ptr MED_i::getField(const char* fieldName, CORBA::Long numOrdre ) throw (SALOME::SALOME_Exception) { - const char * LOC="MED_i::getField(const char*,CORBA::Long,CORBA::Long) "; - BEGIN_OF(LOC); + const char* LOC = "MED_i::getField(const char*,CORBA::Long,CORBA::Long) "; + BEGIN_OF(LOC); DT_IT_ dtIt; @@ -926,7 +932,7 @@ throw (SALOME::SALOME_Exception) if ( itMap_dtIt == map_dtIt.end() ) THROW_SALOME_CORBA_EXCEPTION("Iteration not found !", SALOME::INTERNAL_ERROR); - END_OF(LOC); + END_OF(LOC); return (*itMap_dtIt).second; } @@ -1108,7 +1114,8 @@ throw (SALOME::SALOME_Exception) void MED_i::addInStudy(SALOMEDS::Study_ptr myStudy, SALOME_MED::MED_ptr myIor) throw (SALOME::SALOME_Exception,SALOMEDS::StudyBuilder::LockProtection) { - BEGIN_OF("MED_Mesh_i::addInStudy"); + const char* LOC = "MED_Mesh_i::addInStudy"; + BEGIN_OF(LOC); if ( _medId != "" ) { MESSAGE("Med already in Study"); @@ -1150,7 +1157,7 @@ throw (SALOME::SALOME_Exception,SALOMEDS::StudyBuilder::LockProtection) MESSAGE("Registering of the Corba Med pointer"); Register(); - END_OF("Med_i::addInStudy(SALOMEDS::Study_ptr myStudy)"); + END_OF(LOC); } //============================================================================= @@ -1167,7 +1174,8 @@ void MED_i::addInStudy (SALOMEDS::Study_ptr myStudy, const char * fileName) throw (SALOME::SALOME_Exception,SALOMEDS::StudyBuilder::LockProtection) { - BEGIN_OF("MED_i::addInStudy(myStudy, myIor, fileName)"); + const char* LOC = "MED_i::addInStudy(myStudy, myIor, fileName)"; + BEGIN_OF(LOC); if ( _medId != "" ) { MESSAGE("Med already in Study"); THROW_SALOME_CORBA_EXCEPTION("Med already in Study", SALOME::BAD_PARAM); @@ -1277,5 +1285,5 @@ void MED_i::addInStudy (SALOMEDS::Study_ptr myStudy, MESSAGE("Registering of the Corba Med pointer"); Register(); - END_OF("Med_i::addInStudy(myStudy, myIor, medfather, medObjName)"); + END_OF(LOC); } diff --git a/src/MEDMEM_I/MEDMEM_Med_i.hxx b/src/MEDMEM_I/MEDMEM_Med_i.hxx index 76006af84..658aacf82 100644 --- a/src/MEDMEM_I/MEDMEM_Med_i.hxx +++ b/src/MEDMEM_I/MEDMEM_Med_i.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // //============================================================================= // File : MEDMEM_Med_i.hxx @@ -23,7 +25,7 @@ // Author : EDF // $Header: /export/home/PAL/MED_SRC/src/MEDMEM_I/MEDMEM_Med_i.hxx //============================================================================= - +// #ifndef _MED_MED_I_HXX_ #define _MED_MED_I_HXX_ diff --git a/src/MEDMEM_I/MEDMEM_Mesh_i.cxx b/src/MEDMEM_I/MEDMEM_Mesh_i.cxx index 714b3147c..5491d25a9 100644 --- a/src/MEDMEM_I/MEDMEM_Mesh_i.cxx +++ b/src/MEDMEM_I/MEDMEM_Mesh_i.cxx @@ -1,28 +1,31 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// //============================================================================= // File : MEDMEM_Mesh_i.cxx // Project : SALOME // Author : EDF // $Header: /export/home/PAL/MED_SRC/src/MEDMEM_I/MEDMEM_Mesh_i.cxx //============================================================================= - +// #include <vector> #include "utilities.h" @@ -61,9 +64,10 @@ MESH_i::MESH_i(): _mesh(constructConstMesh()), _corbaIndex(MESH_i::meshIndex++), _meshId("") { - BEGIN_OF("Default Constructor MESH_i"); + const char* LOC = "Default Constructor MESH_i"; + BEGIN_OF(LOC); MESH_i::meshMap[_corbaIndex]=_mesh; - END_OF("Default Constructor MESH_i"); + END_OF(LOC); } //============================================================================= /*! @@ -82,11 +86,12 @@ MESH_i::MESH_i(::MESH * const m ) :_mesh(m), _corbaIndex(MESH_i::meshIndex++), _meshId("") { - BEGIN_OF("Constructor MESH_i(::MESH * const m )"); + const char* LOC = "Constructor MESH_i(::MESH * const m )"; + BEGIN_OF(LOC); MESH_i::meshMap[_corbaIndex]=_mesh; SCRUTE(_mesh); - END_OF("Constructor MESH_i(::MESH * const m )"); + END_OF(LOC); } //============================================================================= /*! @@ -98,9 +103,10 @@ MESH_i::MESH_i( MESH_i & m) :_mesh(m._mesh), _corbaIndex(MESH_i::meshIndex++), _meshId("") { - BEGIN_OF("Constructor MESH_i"); + const char* LOC = "Constructor MESH_i"; + BEGIN_OF(LOC); MESH_i::meshMap[_corbaIndex]=_mesh; - END_OF("Constructor MESH_i"); + END_OF(LOC); } //============================================================================= /*! @@ -1315,6 +1321,30 @@ throw (SALOME::SALOME_Exception) THROW_SALOME_CORBA_EXCEPTION(ex.what(), SALOME::INTERNAL_ERROR); } } + +//============================================================================= +/*! + * CORBA: + */ +//============================================================================= +SALOME_MED::SUPPORT_ptr MESH_i::getSupportOnAll(SALOME_MED::medEntityMesh entity) +throw (SALOME::SALOME_Exception) +{ + if (_mesh==NULL) + THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", \ + SALOME::INTERNAL_ERROR); + try + { + SUPPORT * myNewSupport = _mesh->getSupportOnAll(convertIdlEntToMedEnt(entity)); + SUPPORT_i * mySupportI = new SUPPORT_i(myNewSupport); + return mySupportI->_this(); + } + catch (MEDEXCEPTION &ex) + { + MESSAGE("Unable to get the support "); + THROW_SALOME_CORBA_EXCEPTION(ex.what(), SALOME::INTERNAL_ERROR); + } +} //============================================================================= /*! * CORBA: @@ -1492,7 +1522,8 @@ throw (SALOME::SALOME_Exception) void MESH_i::addInStudy(SALOMEDS::Study_ptr myStudy,SALOME_MED::MESH_ptr myIor ) throw (SALOME::SALOME_Exception,SALOMEDS::StudyBuilder::LockProtection) { - BEGIN_OF("MED_Mesh_i::addInStudy"); + const char* LOC = "MED_Mesh_i::addInStudy"; + BEGIN_OF(LOC); if ( _meshId != "" ) { MESSAGE("Mesh already in Study"); @@ -1560,7 +1591,7 @@ throw (SALOME::SALOME_Exception,SALOMEDS::StudyBuilder::LockProtection) MESSAGE("Registering of the Corba Mesh pointer"); Register(); - END_OF("Mesh_i::addInStudy(SALOMEDS::Study_ptr myStudy)"); + END_OF(LOC); } //============================================================================= /*! @@ -1570,7 +1601,8 @@ throw (SALOME::SALOME_Exception,SALOMEDS::StudyBuilder::LockProtection) void MESH_i::addInStudy(SALOMEDS::Study_ptr myStudy,SALOME_MED::MESH_ptr myIor,const string & fileName ) throw (SALOME::SALOME_Exception,SALOMEDS::StudyBuilder::LockProtection) { - BEGIN_OF("MED_Mesh_i::addInStudy"); + const char* LOC = "MED_Mesh_i::addInStudy"; + BEGIN_OF(LOC); if ( _meshId != "" ) { MESSAGE("Mesh already in Study"); @@ -1626,7 +1658,7 @@ throw (SALOME::SALOME_Exception,SALOMEDS::StudyBuilder::LockProtection) MESSAGE("Registering of the Corba Mesh pointer"); Register(); - END_OF("Mesh_i::addInStudy(SALOMEDS::Study_ptr myStudy)"); + END_OF(LOC); } //============================================================================= diff --git a/src/MEDMEM_I/MEDMEM_Mesh_i.hxx b/src/MEDMEM_I/MEDMEM_Mesh_i.hxx index 965b6afc8..6aa0ddb35 100644 --- a/src/MEDMEM_I/MEDMEM_Mesh_i.hxx +++ b/src/MEDMEM_I/MEDMEM_Mesh_i.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // //============================================================================= // File : MEDMEM_Mesh_i.hxx @@ -23,7 +25,7 @@ // Author : EDF // $Header: /export/home/PAL/MED_SRC/src/MEDMEM_I/MEDMEM_Mesh_i.hxx //============================================================================= - +// #ifndef _MED_MESH_I_HXX_ #define _MED_MESH_I_HXX_ @@ -180,6 +182,8 @@ public: // SALOME_MED::SUPPORT_ptr getBoundaryElements(SALOME_MED::medEntityMesh entity) throw (SALOME::SALOME_Exception); + SALOME_MED::SUPPORT_ptr getSupportOnAll(SALOME_MED::medEntityMesh entity) + throw (SALOME::SALOME_Exception); SALOME_MED::SUPPORT_ptr getSkin (SALOME_MED::SUPPORT_ptr mySupport3D) throw (SALOME::SALOME_Exception); // diff --git a/src/MEDMEM_I/MEDMEM_Support_i.cxx b/src/MEDMEM_I/MEDMEM_Support_i.cxx index 6f2095724..b99245d0e 100644 --- a/src/MEDMEM_I/MEDMEM_Support_i.cxx +++ b/src/MEDMEM_I/MEDMEM_Support_i.cxx @@ -1,28 +1,31 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// //============================================================================= // File : MEDMEM_Support_i.cxx // Project : SALOME // Author : EDF // $Header: /export/home/PAL/MED_SRC/src/MEDMEM_I/MEDMEM_Support_i.cxx //============================================================================= - +// #include "utilities.h" #include "Utils_CorbaException.hxx" #include "Utils_ORB_INIT.hxx" @@ -56,8 +59,9 @@ int SUPPORT_i::supportIndex = 0 ; //============================================================================= SUPPORT_i::SUPPORT_i() :_support((::SUPPORT *)NULL),_corbaIndex(SUPPORT_i::supportIndex++) { - BEGIN_OF("Default Constructor SUPPORT_i"); - END_OF("Default Constructor SUPPORT_i"); + const char* LOC = "Default Constructor SUPPORT_i"; + BEGIN_OF(LOC); + END_OF(LOC); } //============================================================================= @@ -68,9 +72,10 @@ SUPPORT_i::SUPPORT_i() :_support((::SUPPORT *)NULL),_corbaIndex(SUPPORT_i::suppo SUPPORT_i::SUPPORT_i(const ::SUPPORT * const s) :_support(s), _corbaIndex(SUPPORT_i::supportIndex++) { - BEGIN_OF("Constructor SUPPORT_i"); + const char* LOC = "Constructor SUPPORT_i"; + BEGIN_OF(LOC); SUPPORT_i::supportMap[_corbaIndex]=(::SUPPORT *)_support; - END_OF("Constructor SUPPORT_i"); + END_OF(LOC); } //============================================================================= /*! @@ -80,9 +85,10 @@ SUPPORT_i::SUPPORT_i(const ::SUPPORT * const s) :_support(s), SUPPORT_i::SUPPORT_i(const SUPPORT_i &s) :_support(s._support), _corbaIndex(SUPPORT_i::supportIndex++) { - BEGIN_OF("Constructor SUPPORT_i"); + const char* LOC = "Constructor SUPPORT_i"; + BEGIN_OF(LOC); SUPPORT_i::supportMap[_corbaIndex]=(::SUPPORT *)_support; - END_OF("Constructor SUPPORT_i"); + END_OF(LOC); } //============================================================================= /*! @@ -253,7 +259,8 @@ SALOME_MED::SUPPORT::supportInfos * SUPPORT_i::getSupportGlobal() SALOME_MED::MESH_ptr SUPPORT_i::getMesh() throw (SALOME::SALOME_Exception) { - BEGIN_OF("SALOME_MED::MESH_ptr SUPPORT_i::getMesh()"); + const char* LOC = "SALOME_MED::MESH_ptr SUPPORT_i::getMesh()"; + BEGIN_OF(LOC); if (_support==NULL) THROW_SALOME_CORBA_EXCEPTION("No associated Support", \ @@ -271,7 +278,7 @@ throw (SALOME::SALOME_Exception) SCRUTE(m1); SCRUTE(m2); - END_OF("SALOME_MED::MESH_ptr SUPPORT_i::getMesh()"); + END_OF(LOC); return (m2); } @@ -338,14 +345,15 @@ throw (SALOME::SALOME_Exception) SALOME_MED::medEntityMesh SUPPORT_i::getEntity() throw (SALOME::SALOME_Exception) { - BEGIN_OF("SALOME_MED::medEntityMesh SUPPORT_i::getEntity()"); + const char* LOC = "SALOME_MED::medEntityMesh SUPPORT_i::getEntity()"; + BEGIN_OF(LOC); if (_support==NULL) THROW_SALOME_CORBA_EXCEPTION("No associated Support", \ SALOME::INTERNAL_ERROR); try { - END_OF("SALOME_MED::medEntityMesh SUPPORT_i::getEntity()"); + END_OF(LOC); return convertMedEntToIdlEnt(_support->getEntity()); } catch (MEDEXCEPTION &ex) @@ -616,19 +624,19 @@ throw (SALOME::SALOME_Exception) void SUPPORT_i::addInStudy (SALOMEDS::Study_ptr myStudy, SALOME_MED::SUPPORT_ptr myIor) throw (SALOME::SALOME_Exception,SALOMEDS::StudyBuilder::LockProtection) { - const char * LOC = "SUPPORT_i::addInStudy"; + const char* LOC = "SUPPORT_i::addInStudy"; BEGIN_OF(LOC); if ( _supportId != "" ) { - MESSAGE(LOC << "Support already in Study"); + MESSAGE("Support already in Study"); THROW_SALOME_CORBA_EXCEPTION("Support already in Study", \ SALOME::BAD_PARAM); }; if ( CORBA::is_nil(myStudy) ) { - MESSAGE(LOC << "Study not found"); + MESSAGE("Study not found"); THROW_SALOME_CORBA_EXCEPTION("Study deleted !!!", SALOME::INTERNAL_ERROR); } @@ -640,11 +648,11 @@ void SUPPORT_i::addInStudy (SALOMEDS::Study_ptr myStudy, SALOME_MED::SUPPORT_ptr SALOMEDS::AttributeIOR_var aIOR; // Find SComponent labelled 'Med' - MESSAGE(LOC << " Find SComponent labelled 'MED'"); + MESSAGE(" Find SComponent labelled 'MED'"); SALOMEDS::SComponent_var medfather = myStudy->FindComponent("MED"); if ( CORBA::is_nil(medfather) ) { - MESSAGE(LOC << "MED not found"); + MESSAGE("MED not found"); THROW_SALOME_CORBA_EXCEPTION("SComponent labelled 'Med' not Found",SALOME::INTERNAL_ERROR); } @@ -652,10 +660,10 @@ void SUPPORT_i::addInStudy (SALOMEDS::Study_ptr myStudy, SALOME_MED::SUPPORT_ptr SALOMEDS::SObject_var medmeshfather = myStudy->FindObjectByPath("/Med/MEDMESH"); if ( CORBA::is_nil(medmeshfather) ) { - MESSAGE(LOC << " No /Med/MEDMESH Found in study") + MESSAGE(" No /Med/MEDMESH Found in study") THROW_SALOME_CORBA_EXCEPTION("SObject labelled 'MEDMESH' not Found",SALOME::INTERNAL_ERROR); } - MESSAGE(LOC << " Find SObject MESH (represent mesh in support)"); + MESSAGE(" Find SObject MESH (represent mesh in support)"); string meshName = _support->getMesh()->getName() ; string meshNameStudy = meshName; diff --git a/src/MEDMEM_I/MEDMEM_Support_i.hxx b/src/MEDMEM_I/MEDMEM_Support_i.hxx index 12351cd52..3d2858c35 100644 --- a/src/MEDMEM_I/MEDMEM_Support_i.hxx +++ b/src/MEDMEM_I/MEDMEM_Support_i.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // //============================================================================= // File : MEDMEM_Support_i.hxx @@ -23,7 +25,7 @@ // Author : EDF // $Header: /export/home/PAL/MED/src/MEDMEM_I/MEDMEM_Support_i.hxx //============================================================================= - +// #ifndef _MED_SUPPORT_I_HXX_ #define _MED_SUPPORT_I_HXX_ diff --git a/src/MEDMEM_I/MEDMEM_TraitsForFields.hxx b/src/MEDMEM_I/MEDMEM_TraitsForFields.hxx index 977001310..2d57564ba 100644 --- a/src/MEDMEM_I/MEDMEM_TraitsForFields.hxx +++ b/src/MEDMEM_I/MEDMEM_TraitsForFields.hxx @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// #ifndef __MEDMEM_TRAITSFORFIELDS_HXX__ #define __MEDMEM_TRAITSFORFIELDS_HXX__ diff --git a/src/MEDMEM_I/MEDMEM_convert.cxx b/src/MEDMEM_I/MEDMEM_convert.cxx index 09e20ad4d..9ee78b8d8 100644 --- a/src/MEDMEM_I/MEDMEM_convert.cxx +++ b/src/MEDMEM_I/MEDMEM_convert.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // //============================================================================= // File : MEDMEM_convert.cxx @@ -24,7 +26,7 @@ // Project : SALOME // $Header: /export/home/PAL/MED_SRC/src/MEDMEM_I/MEDMEM_convert.cxx //============================================================================= - +// #include "utilities.h" #include "Utils_CorbaException.hxx" diff --git a/src/MEDMEM_I/MEDMEM_convert.hxx b/src/MEDMEM_I/MEDMEM_convert.hxx index 55d14f99c..70a23a408 100644 --- a/src/MEDMEM_I/MEDMEM_convert.hxx +++ b/src/MEDMEM_I/MEDMEM_convert.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // //============================================================================= // File : MEDMEM_convert.hxx @@ -24,6 +26,7 @@ // Project : SALOME // $Header: /export/home/PAL/MED_SRC/src/MEDMEM_I/MEDMEM_convert.hxx //============================================================================= +// # if ! defined ( __CONVERT_H__ ) # define __CONVERT_H__ diff --git a/src/MEDMEM_I/Makefile.am b/src/MEDMEM_I/Makefile.am index 626d9419e..1c5e66416 100644 --- a/src/MEDMEM_I/Makefile.am +++ b/src/MEDMEM_I/Makefile.am @@ -1,27 +1,26 @@ -# MED MEDMEM_I : MED idl descriptions implementation based on the classes of MEDMEM +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # +# 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. # +# 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 +# +# MED MEDMEM_I : MED idl descriptions implementation based on the classes of MEDMEM # - include $(top_srcdir)/adm_local/unix/make_common_starter.am lib_LTLIBRARIES= libMEDMEMImpl.la @@ -52,6 +51,6 @@ libMEDMEMImpl_la_CPPFLAGS= $(CORBA_CXXFLAGS) $(CORBA_INCLUDES) $(MED2_INCLUDES) libMEDMEMImpl_la_LDFLAGS= \ ../../idl/libSalomeIDLMED.la \ ../MEDMEM/libmedmem.la \ - ${KERNEL_LDFLAGS} -lSalomeLifeCycleCORBA -lSALOMELocalTrace -lSalomeCommunication -lSalomeGenericObj -lSalomeNS \ + ${KERNEL_LDFLAGS} -lSalomeLifeCycleCORBA -lSALOMELocalTrace -lSalomeCommunication -lSalomeGenericObj -lSalomeNS -lOpUtil \ $(MED2_LIBS) \ $(HDF5_LIBS) diff --git a/src/MEDMEM_SWIG/MEDMEM_SWIG_Templates.hxx b/src/MEDMEM_SWIG/MEDMEM_SWIG_Templates.hxx index 2d7f22503..4249c84b0 100644 --- a/src/MEDMEM_SWIG/MEDMEM_SWIG_Templates.hxx +++ b/src/MEDMEM_SWIG/MEDMEM_SWIG_Templates.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef MEDMEM_SWIG_TEMPLATES_HXX_ #define MEDMEM_SWIG_TEMPLATES_HXX_ @@ -35,7 +37,7 @@ template<> static double Traducer(PyObject *a) { return PyFloat_AsDouble(a); } static PyObject * Traducer( double value ) { return Py_BuildValue("d", value ); } static double Functor(PyObject *func, double value) - { return Traducer( PyObject_CallFunction( func, "f", value )); } + { return Traducer( PyObject_CallFunction( func, (char *)"f", value )); } }; template<> @@ -45,7 +47,7 @@ template<> static int Traducer(PyObject *a) { return (int) PyInt_AsLong(a); } static PyObject * Traducer( int value ) { return Py_BuildValue("i", value ); } static int Functor(PyObject *func, int value) - { return Traducer( PyObject_CallFunction( func, "i", value )); } + { return Traducer( PyObject_CallFunction( func, (char *)"i", value )); } }; template<class T, class U> diff --git a/src/MEDMEM_SWIG/Makefile.am b/src/MEDMEM_SWIG/Makefile.am index 88f889716..2dc08ba47 100644 --- a/src/MEDMEM_SWIG/Makefile.am +++ b/src/MEDMEM_SWIG/Makefile.am @@ -1,36 +1,37 @@ -# MED MEDMEM_SWIG : binding of C++ implementation and Python +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +# MED MEDMEM_SWIG : binding of C++ implementation and Python # - include $(top_srcdir)/adm_local/unix/make_common_starter.am -lib_LTLIBRARIES= libMEDMEM_Swigcmodule.la +lib_LTLIBRARIES = _libMEDMEM_Swig.la -salomeinclude_HEADERS= \ +salomeinclude_HEADERS = \ libMEDMEM_Swig.i \ - my_typemap.i \ + my_typemap.i \ MEDMEM_SWIG_Templates.hxx if MED_SWIG_1_3_21 -SWIG_DEF= libMEDMEM_Swig.i dummy.i +SWIG_DEF = libMEDMEM_Swig.i dummy.i dummy_wrap.cxx: libMEDMEM_Swig_wrap.cxx sed -e 's/SwigValueWrapper< vector<FAMILY \* > >/vector<FAMILY \* >/g' libMEDMEM_Swig_wrap.cxx > toto @@ -39,30 +40,27 @@ dummy_wrap.cxx: libMEDMEM_Swig_wrap.cxx mv toto libMEDMEM_Swig_wrap.cxx touch dummy_wrap.cxx else !MED_SWIG_1_3_21 -SWIG_DEF= libMEDMEM_Swig.i +SWIG_DEF = libMEDMEM_Swig.i endif -SWIG_FLAGS=@SWIG_FLAGS@ -I$(srcdir) +SWIG_FLAGS = @SWIG_FLAGS@ -I$(srcdir) -nodist_libMEDMEM_Swigcmodule_la_SOURCES= libMEDMEM_Swig_wrap.cxx +dist__libMEDMEM_Swig_la_SOURCES = libMEDMEM_Swig.i +nodist__libMEDMEM_Swig_la_SOURCES = libMEDMEM_Swig_wrap.cxx libMEDMEM_Swig.py: libMEDMEM_Swig_wrap.cxx libMEDMEM_Swig_wrap.cxx: $(SWIG_DEF) $(SWIG) $(SWIG_FLAGS) -o $@ $< -libMEDMEM_Swigcmodule_la_CPPFLAGS= $(CORBA_CXXFLAGS) $(CORBA_INCLUDES) $(PYTHON_INCLUDES) $(MED2_INCLUDES) $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ \ - -I$(srcdir)/../MEDMEM -I$(srcdir)/../MEDWrapper/V2_1/Core -libMEDMEM_Swigcmodule_la_LDFLAGS= $(MED2_LIBS) $(HDF5_LIBS) $(PYTHON_LIBS) \ - ../MEDMEM/libmedmem.la -if MED_ENABLE_KERNEL - libMEDMEM_Swigcmodule_la_CPPFLAGS+= ${KERNEL_CXXFLAGS} - libMEDMEM_Swigcmodule_la_LDFLAGS+= ${KERNEL_LDFLAGS} -lSALOMELocalTrace -endif +_libMEDMEM_Swig_la_CPPFLAGS = $(PYTHON_INCLUDES) $(MED2_INCLUDES) $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ \ + -I$(srcdir)/../MEDMEM -I$(srcdir)/../MEDWrapper/V2_1/Core -I$(srcdir)/../INTERP_KERNEL -I$(srcdir)/../INTERP_KERNEL/Bases +_libMEDMEM_Swig_la_LDFLAGS = -module $(MED2_LIBS) $(HDF5_LIBS) $(PYTHON_LIBS) \ + ../MEDMEM/libmedmem.la ../INTERP_KERNEL/libinterpkernel.la -CLEANFILES=libMEDMEM_Swig_wrap.cxx libMEDMEM_Swig.py +CLEANFILES = libMEDMEM_Swig_wrap.cxx libMEDMEM_Swig.py -nodist_salomescript_DATA= libMEDMEM_Swig.py -dist_salomescript_DATA= \ +nodist_salomescript_DATA = libMEDMEM_Swig.py +dist_salomescript_DATA = \ medmem.py \ med_test1.py \ med_test2.py \ @@ -80,14 +78,8 @@ dist_salomescript_DATA= \ testMedObj.py \ test_profil_MedFieldDriver.py \ testWriteAndFam.py \ - testMedMemGeneral.py - -############################################################################# - -install-exec-hook: $(DESTDIR)$(libdir)/_libMEDMEM_Swig.so - -$(DESTDIR)$(libdir)/_libMEDMEM_Swig.so: - ( cd $(DESTDIR)$(libdir); ln -sf libMEDMEM_Swigcmodule.so _libMEDMEM_Swig.so; ) - -uninstall-hook: - ( cd $(DESTDIR)$(libdir); rm -f _libMEDMEM_Swig.so; ) + testMedMemGeneral.py \ + testMedMemCxxTests.py \ + dumpMEDMEM.py \ + ensightMedEnsight_test.py \ + medEnsightMed_test.py diff --git a/src/MEDMEM_SWIG/dumpMEDMEM.py b/src/MEDMEM_SWIG/dumpMEDMEM.py new file mode 100644 index 000000000..5c46cba7c --- /dev/null +++ b/src/MEDMEM_SWIG/dumpMEDMEM.py @@ -0,0 +1,522 @@ +# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG +# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT +# 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. +# +# 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 +# +############################################################################ +# +# This file provides utilities to dump content of MEDMEM objects: mesh, +# field, group, family, nodal connectivity, node coordinates. +# +############################################################################ + +from libMEDMEM_Swig import * + +import os + +theEntityName = { MED_CELL :"CELL", + MED_FACE :"FACE", + MED_EDGE :"EDGE", + MED_NODE :"NODE", + MED_ALL_ENTITIES:"ALL_ENTITIES" } + +theTypeName = {MED_NONE :"NONE", + MED_POINT1 :"POINT1", + MED_SEG2 :"SEG2", + MED_SEG3 :"SEG3", + MED_TRIA3 :"TRIA3", + MED_QUAD4 :"QUAD4", + MED_TRIA6 :"TRIA6", + MED_QUAD8 :"QUAD8", + MED_TETRA4 :"TETRA4", + MED_PYRA5 :"PYRA5", + MED_PENTA6 :"PENTA6", + MED_HEXA8 :"HEXA8", + MED_TETRA10 :"TETRA10", + MED_PYRA13 :"PYRA13", + MED_PENTA15 :"PENTA15", + MED_HEXA20 :"HEXA20", + MED_POLYGON :"POLYGON", + MED_POLYHEDRA :"POLYHEDRA", + MED_ALL_ELEMENTS:"ALL_ELEMENTS"} + +medModeSwitch = { 0:"FULL_INTERLACE", + 1:"NO_INTERLACE", + 3:"UNDEFINED_INTERLACE" }; + +med_type_champ = { 6 : "REEL64", + 24: "INT32", + 26: "INT64", + 0 : "UNDEFINED_TYPE" } ; + +tab=" " + +debugShowConn=True +debugShowConn=False + +SHOW_ALL = -1 + +# private +def _showNodalConnectivity(mesh,entity,type,elems,tablevel,showOnly=SHOW_ALL): + if debugShowConn: print "ELEMENS:",elems + tab1 = tab*tablevel + tab2 = tab*(tablevel+1) + typeName = theTypeName[type] + nbElem = len( elems ) + if showOnly > 0: + elems = elems[:showOnly] + nbShow = len( elems ) + if type == MED_POLYGON: + connectivity = mesh.getPolygonsConnectivity(MED_NODAL,entity) + index = mesh.getPolygonsConnectivityIndex(MED_NODAL,entity) + if debugShowConn: print "CONN:",connectivity,"\nIND:",index + d = mesh.getNumberOfElements(entity,MED_ALL_ELEMENTS) + for i in elems: + j = i - d + print tab1,typeName,i,":",connectivity[ index[j-1]-1 : index[j]-1 ] + pass + pass + elif type == MED_POLYHEDRA: + connectivity = mesh.getPolyhedronConnectivity(MED_NODAL) + fIndex = mesh.getPolyhedronFacesIndex() + index = mesh.getPolyhedronIndex(MED_NODAL) + d = mesh.getNumberOfElements(entity,MED_ALL_ELEMENTS) + if debugShowConn: print "CONN:",connectivity,"\nIND:",index,"\nFIND:",fIndex + for i in elems: + j = i - d + print tab1,typeName, i + iF1, iF2 = index[ j-1 ]-1, index[ j ]-1 + for f in range( iF2 - iF1 ): + iN1, iN2 = fIndex[ iF1+f ]-1, fIndex[ iF1+f+1 ]-1 + print tab2,"Face",(f+1),":",connectivity[ iN1 : iN2 ] + pass + pass + pass + else: + elemShift = 0 + types = mesh.getTypes( entity ) + for t in types: + if t != type: + elemShift += mesh.getNumberOfElements(entity,t) + else: + break + pass + connectivity = mesh.getConnectivity(MED_FULL_INTERLACE, MED_NODAL, entity,MED_ALL_ELEMENTS) + index = mesh.getConnectivityIndex(MED_FULL_INTERLACE, entity) + if debugShowConn: print "CONN: %s\n INX: %s" % (connectivity,index) + nbNodesPerCell = type%100 + for i in elems: + elem = i + elemShift + n = index[elem-1]-1 + print tab1,typeName,i,":",connectivity[n:n+nbNodesPerCell] + pass + pass + nbSkip = nbElem - nbShow + if nbSkip > 0: + print tab1,"...",nbSkip,"elements not shown" + pass + pass + +#private +def _showSupport(support, tablevel,showElems=0): + tab1 = tab*(tablevel+0) + tab2 = tab*(tablevel+1) + tab3 = tab*(tablevel+3) + entity = support.getEntity() + types = support.getTypes() + nbOfTypes = support.getNumberOfTypes() + onAll = support.isOnAllElements() + print tab1,"-Entity:",theEntityName[entity] + print tab1,"-Types :",types + print tab1,"-Elements" + if onAll: + print tab2,"<< Is on all elements >>" + else: + for type in types: + nbOfElmtsOfType = support.getNumberOfElements(type) + number = support.getNumber(type) + number.sort() + print tab2,"* Type:",theTypeName[type] + print tab3,". Nb elements:",nbOfElmtsOfType + print tab3,". Numbers:",number[:min(100,nbOfElmtsOfType)], + if nbOfElmtsOfType > 100: + print "...skip", nbOfElmtsOfType-100 + else: + print + pass + if entity != MED_NODE and showElems: + print tab3,". Nodal connectivity" + _showNodalConnectivity(support.getMesh(),entity,type,number,tablevel+4,showElems) + pass + pass + pass + print + return + +## Dump i-th family of given entity in mesh. +## Optionally dump nodal connectivity of <showElems> first elements. +## Use showElems=SHOW_ALL to dump connectivity of all elements. + +def ShowFamily(mesh, entity, i, showElems=0): + family = mesh.getFamily(entity,i) + familyName = family.getName() + familyDescription = family.getDescription() + entity = family.getEntity() + familyBool = family.isOnAllElements() + print "\nFAMILY", i, "on", theEntityName[entity] + print tab*1,"-Name :",familyName + print tab*1,"-Description:",familyDescription + familyIdentifier = family.getIdentifier() + nbOfAtt = family.getNumberOfAttributes() + print tab*1,"-Identifier :",familyIdentifier + print tab*1,"-Attributes" + attributesids = family.getAttributesIdentifiers() + attributesvals = family.getAttributesValues() + for k in range(nbOfAtt): + print tab*2,"* Id :",attributesids[k] + print tab*2,"* Value :",attributesvals[k] + print tab*2,"* Description:",family.getAttributeDescription(k+1) + pass + nbOfGrp = family.getNumberOfGroups() + print tab*1,"-Nb Of Groups:",nbOfGrp + print tab*1,"-Groups:" + for k in range(nbOfGrp): + print tab*2,k+1,":",family.getGroupName(k+1) + pass + _showSupport(family,1,showElems) + return + +## Dump all families in mesh. +## Optionally dump nodal connectivity of <showElems> first elements of each family. +## Use showElems=SHOW_ALL to dump connectivity of all elements. + +def ShowFamilies(mesh, showElems=0): + line = "families in mesh <" + mesh.getName() + ">" + print "\n",line,"\n","-"*len(line) + for entity in [MED_NODE,MED_CELL,MED_FACE,MED_EDGE]: + nbFam = mesh.getNumberOfFamilies(entity) + for i in range(nbFam): + ShowFamily(mesh,entity,i+1,showElems) + pass + print + +## Dump a GROUP. +## Optionally dump nodal connectivity of <showElems> first elements of the group. +## Use showElems=SHOW_ALL to dump connectivity of all elements. + +def ShowGroup(group, showElems): + groupName = group.getName() + groupDescription = group.getDescription() + nbOfFam = group.getNumberOfFamilies() + print "\nGROUP on",theEntityName[group.getEntity()] + print tab*1,"-Name :",groupName + print tab*1,"-Description :",groupDescription + print tab*1,"-Nb Of Families:",nbOfFam + print tab*1,"-Families" + for k in range(nbOfFam): + print tab*2,k+1,":",group.getFamily(k+1).getName() + pass + _showSupport(group,1,showElems) + return + +## Dump all GROUP's in mesh. +## Optionally dump nodal connectivity of <showElems> first elements of each group. +## Use showElems=SHOW_ALL to dump connectivity of all elements. + +def ShowGroups(mesh, showElems=0): + line = "groups in mesh <" + mesh.getName() + ">" + print "\n",line,"\n","-"*len(line) + for entity in [MED_NODE,MED_CELL,MED_FACE,MED_EDGE]: + nbGrp = mesh.getNumberOfGroups(entity) + if nbGrp > 0: + for j in range(nbGrp): + group = mesh.getGroup(entity,j+1) + ShowGroup(group,showElems) + pass + pass + pass + +## Dump mesh general information. +## Optionally dump node coordinates of first <nodes2Show> nodes. +## <entity2Show> gives number of elements to dump nodal connectivity by +## entities: [<nb CELLs to show>, <nb FACEs>, <nb EDGEs> ]. +## Use SHOW_ALL to dump all elements or node coordinates. + +def ShowMesh(mesh, nodes2Show=0, entity2Show=[0,0,0]): + print "---------------------- MESH -------------------------" + meshName = mesh.getName() + spaceDim = mesh.getSpaceDimension() + meshDim = mesh.getMeshDimension() + print "The mesh <%s> is a %dD mesh on a %dD geometry" % (meshName,meshDim,spaceDim) + nbNodes = mesh.getNumberOfNodes() + print "There are",nbNodes,"MED_NODE's" + coordSyst = mesh.getCoordinatesSystem() + print "The Coordinates :" + coordNames = [] + coordUnits = [] + for isd in range(spaceDim): + coordNames.append(mesh.getCoordinateName(isd)) + coordUnits.append(mesh.getCoordinateUnit(isd)) + pass + print tab,"system:",coordSyst + print tab,"names:", coordNames + print tab,"units:", coordUnits + ## coordinates + if nodes2Show: + print tab,"values:" + coordinates = mesh.getCoordinates(MED_FULL_INTERLACE) + nbCoord = nodes2Show + maxNbCoord = len( coordinates ) / spaceDim + if nbCoord < 0: nbCoord = maxNbCoord + else: nbCoord = min( nbCoord, maxNbCoord ) + for k in range( nbCoord ): + n = k*spaceDim + print tab*2,k+1,coordinates[n:n+spaceDim] + pass + if nbCoord < maxNbCoord: print tab*2,"... %d nodes skipped" % (maxNbCoord-nbCoord) + pass + # elem types + print "The Elements :" + i = -1 + for entity in [MED_CELL,MED_FACE,MED_EDGE]: + i += 1 + entityName = theEntityName[ entity ] + nbTypes = mesh.getNumberOfTypesWithPoly( entity ) + if nbTypes == 0 : continue + try: + types = mesh.getTypesWithPoly( entity ) + except: + continue + print tab,"%s types:" % entityName + for type in types: + nbElemType = mesh.getNumberOfElementsWithPoly(entity,type) + print tab*2,"%s: \t %d elements" % ( theTypeName[ type ], nbElemType ) + pass + # nodal connectivity + if i >= len( entity2Show ): break + if not entity2Show[ i ]: continue + print tab,"%s nodal connectivity:" % entityName + for type in types: + typeName = theTypeName[ type ] + nbElemType = mesh.getNumberOfElementsWithPoly(entity,type) + if nbElemType == 0: + continue + d = 1 + if type==MED_POLYGON or type==MED_POLYHEDRA: + d += mesh.getNumberOfElements(entity,MED_ALL_ELEMENTS) + number = range (d, nbElemType+d) + _showNodalConnectivity(mesh,entity,type,number,2,entity2Show[ i ]) + pass + pass + + print "----------------------Groups, Families-------------------------" + nbF = 0 + nbG = 0 + for entity in [MED_NODE,MED_CELL,MED_FACE,MED_EDGE]: + nbFam = mesh.getNumberOfFamilies(entity) + nbGrp = mesh.getNumberOfGroups(entity) + nbElem= mesh.getNumberOfElements(entity, MED_ALL_ELEMENTS); + nbF += nbFam + nbG += nbGrp + if (entity == MED_NODE) : + if (nbFam > 0) : print "This mesh has",nbFam,"Node Family(ies)" + if (nbGrp > 0) : print "This mesh has",nbGrp,"Node Group(s)" + if (nbElem> 0) : print "This mesh has",nbElem,"Node Element(s)" + pass + elif (entity == MED_CELL) : + if (nbFam > 0) : print "This mesh has",nbFam,"Cell Family(ies)" + if (nbGrp > 0) : print "This mesh has",nbGrp,"Cell Group(s)" + if (nbElem> 0) : print "This mesh has",nbElem,"Cell Element(s)" + pass + elif (entity == MED_FACE) : + if (nbFam > 0) : print "This mesh has",nbFam,"Face Family(ies)" + if (nbGrp > 0) : print "This mesh has",nbGrp,"Face Group(s)" + if (nbElem> 0) : print "This mesh has",nbElem,"Face Element(s)" + pass + elif (entity == MED_EDGE) : + if (nbFam > 0) : print "This mesh has",nbFam,"Edge Family(ies)" + if (nbGrp > 0) : print "This mesh has",nbGrp,"Edge Group(s)" + if (nbElem> 0) : print "This mesh has",nbElem,"Edge Element(s)" + pass + pass + print "Total nbF", nbF,"nbG",nbG + +## Dump all FIELD's in MED. +## Optionally dump <showValues> first values. +## Use showValues=SHOW_ALL to dump all values. + +def ShowFields( med, showValues=0 ): + nbFields = med.getNumberOfFields() + print "---------------------- Fields-------------------------" + print "Nb fields", nbFields + for iField in range( med.getNumberOfFields() ): + fName = med.getFieldName( iField ) + for it in range( med.getFieldNumberOfIteration( fName ) ): + dt_it_ = med.getFieldIteration( fName, it ) + f = med.getField( fName, dt_it_.dt, dt_it_.it ) + sup = f.getSupport() + name = f.getName() + desc = f.getDescription() + itnb = f.getIterationNumber() + time = f.getTime() + order = f.getOrderNumber() + ftype = f.getValueType() + mode = f.getInterlacingType() + nbcomp = f.getNumberOfComponents() + nbval = f.getNumberOfValues() + nbelem = sup.getNumberOfElements(MED_ALL_ELEMENTS) + nbOfTypes = sup.getNumberOfTypes() + types = sup.getTypes() + isOnAll = sup.isOnAllElements() + print '\nFIELD',iField + print tab*1,'-Name : "%s"' % name + print tab*1,'-Description : "%s"' % desc + print tab*1,'-IterationNumber : %s' % itnb + print tab*1,'-Time : %s' % time + print tab*1,'-OrderNumber : %s' % order + print tab*1,'-Nb Values : %s' % nbval + print tab*1,'-Nb Supp. Elements: %s' % nbelem + print tab*1,'-Nb Componenets : %s' % nbcomp + print tab*1,'-ValueType : %s' % med_type_champ[ftype] + print tab*1,'-Interlace : %s' % medModeSwitch[mode] + print tab*1,'-Conponents' + for k in range(nbcomp): + kp1 = k+1 + compName = f.getComponentName(kp1) + compDesc = f.getComponentDescription(kp1) + compUnit = f.getMEDComponentUnit(kp1) + print tab*2,kp1,'*Name : "%s"' % compName + try: + print tab*2,' *Description: "%s"' % compDesc + except: + print 'INVALID' + try: + print tab*2,' *Unit : "%s"' % compUnit + except: + print 'INVALID' + pass + print tab*1,'-SUPPORT : "%s"' % sup.getName() + print tab*1,'-On all elements : %s' % bool(isOnAll) + print tab*1,'-Types : %s' % types + + if ftype == MED_REEL64: + if mode == MED_FULL_INTERLACE: + f = createFieldDoubleFromField(f) + else: + f = createFieldDoubleNoInterlaceFromField( f ) + elif ftype == MED_INT32: + if mode == MED_FULL_INTERLACE: + f = createFieldIntFromField(f) + else: + f = createFieldIntNoInterlaceFromField( f ) + else: + print tab*1,'<< Unknown field type >>:',ftype + continue + nbGauss = 1 + hasGauss = False + if nbcomp == 0: + nbGauss = 0 + else: + hasGauss = f.getGaussPresence() + if hasGauss: + nbGaussByType = f.getNumberOfGaussPoints() + for k in range(nbOfTypes): + type = types[k] + nbOfElmtsOfType = sup.getNumberOfElements(type) + if hasGauss: nbGauss = nbGaussByType[ k ] + if type == 0: type = MED_POINT1 + print tab*2,k+1,theTypeName[type],':',nbOfElmtsOfType, 'elements,',\ + nbGauss,'gauss point(s)' + pass + nbOf = sup.getNumberOfElements(MED_ALL_ELEMENTS) + elements = [] + if not isOnAll: + elements = sup.getNumber(MED_ALL_ELEMENTS) + if nbcomp == 0: + nbOf = 0 + print tab*1,'-Nb Values :',nbOf + #value = f.getValue(MED_FULL_INTERLACE) + #print value[0: min( 100, len(value)-1 )] + + toShow = min( nbOf, showValues ) + if toShow < 0: toShow = nbOf + for I in range( toShow ): + if elements: + i = elements[ I ] + else: + i = I+1 + if mode == MED_FULL_INTERLACE: + valueI = f.getRow(i) + else: + valueI = [] + for j in range( nbcomp ): + for k in range( f.getNbGaussI( i ) ): + valueI.append( f.getValueIJK(i,j+1,k+1) ) + print ' ',i,' - ',valueI #[:nbcomp] + pass + if nbOf > toShow: + print ' ...skip',nbOf - toShow,'values' + pass + pass + pass + pass + +## Read all fields in MED + +def ReadFields(med): + nbFields = med.getNumberOfFields() + if (nbFields>0): + print 'READ FIELDs ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++' + med.updateSupport() + for i in range(nbFields): + field_name = med.getFieldName(i) + nbOfIt = med.getFieldNumberOfIteration(field_name) + print ' The field is',field_name,'with',nbOfIt,'iteration(s)' + for j in range(nbOfIt): + dtitfield = med.getFieldIteration(field_name,j) + dt = dtitfield.getdt() + it = dtitfield.getit() + field = med.getField(field_name,dt,it) + type = field.getValueType() + print ' * Iteration:',dt,'Order number:',it,'Type:',type + mode = field.getInterlacingType() + if type == MED_INT32: + if mode == MED_FULL_INTERLACE: + fieldint = createFieldIntFromField(field) + else: + fieldint = createFieldIntNoInterlaceFromField( field ) + print ' Reading',fieldint.getName(),'...' + fieldint.read() + elif type == MED_REEL64: + if mode == MED_FULL_INTERLACE: + f = createFieldDoubleFromField(field) + else: + f = createFieldDoubleNoInterlaceFromField( field ) + print ' Reading',f.getName(),'...' + f.read() + else: + print ' !!!! Bad type of Field !!!!' + +# Remove a file if it exists + +def supprimer(f): + if os.access(f, os.F_OK): + os.remove(f) + +# Remove a file if it exists + +def deleteFile( f ): + supprimer( f ) diff --git a/src/MEDMEM_SWIG/ensightMedEnsight_test.py b/src/MEDMEM_SWIG/ensightMedEnsight_test.py new file mode 100644 index 000000000..245d92a69 --- /dev/null +++ b/src/MEDMEM_SWIG/ensightMedEnsight_test.py @@ -0,0 +1,251 @@ +#!/usr/bin/env python +# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG +# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT +# 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. +# +# 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 +# +############################################################################ +# +# This script tests conversion of EnSight to MEDMEM by performing following +# operations on all available EnSight files: +# - read EnSight file into MEDMEM and breifly dump it's content; +# - store MEDMEM to med file; +# - write EnSight file in different formats: Gold and EnSight6, ASCII and binary; +# - checks generated EnSight files using ens_checker utility (if available). +# +# EnSight samples are in EXAMPLES salome CVS repository, in directory SAMPLES_SRC/EnSight. +# DATA_DIR should contain path to SAMPLES_SRC +# +############################################################################ + +from medmem import * +from dumpMEDMEM import * +from re import search +import sys + +ASCII = False +Binary = True +formats = [ + (ENSIGHT_GOLD,ASCII) + ,(ENSIGHT_GOLD,Binary) + ,(ENSIGHT_6,ASCII) + ,(ENSIGHT_6,Binary) + ] + +dataDir = os.getenv("DATA_DIR") +tmpDir = os.getenv("TMP") +if not tmpDir: + tmpDir = os.getenv("TMPDIR") + +# EnSight samples are in EXAMPLES CVS repository, in directory SAMPLES_SRC/EnSight. +# DATA_DIR should contain path to SAMPLES_SRC +inDir = os.path.join( dataDir, "EnSight") +if not os.access(inDir, os.F_OK): + raise RuntimeError, "Path to EnSight files not found, check DATA_DIR environment" + +outDir = os.path.join( tmpDir,"Ensight_out") +if not os.access(outDir, os.F_OK): + os.mkdir( outDir ) + pass + +# find out if ens_checker is available +has_ens_checker = False +tmpFile = os.path.join( outDir, "has_ens_checker" ) +os.system("ens_checker _.case > %s 2>&1" % tmpFile) +tmpFile = open( tmpFile ).read() +if search("EnSight Data Format Checker", tmpFile): + has_ens_checker = True +else: + print "\nWarning: ens_checker utility NOT available" + pass + + +dumpMesh = False +dumpMesh = True + +dumpField= False +dumpField= True + +def check_ens(casefile, logfile): + if not has_ens_checker: + return + cmd = "(cd %s; ens_checker %s > %s 2>&1)" % (outDir, casefile, logfile) + err = os.system( cmd ) + if os.access(logfile, os.F_OK): + log = open(logfile).read() + if search("bummer", log): + print log + raise RuntimeError, "cd %s; ens_checker %s" % (outDir, casefile) + if search("Warning:", log): + print log + pass + pass + +def compatibilityPb(): + "Print traceback and return true if exception is due to EnSight-MEDMEM incompatibility" + isCompatibilityPb = ( sys.exc_value.__str__().find("compatibility problem") > 0 ) + if isCompatibilityPb: + print '$$$$$$$$$$$$$$$$$$$$ COMPATIBILITY PROBLEM $$$$$$$$$$$$$$$$$$$$$$$$' + print sys.exc_value, "\n" + else: + import traceback + traceback.print_exc() + return isCompatibilityPb + +from dircache import listdir + +inFiles = [ + "blow1_ascii.case" +# ,"blow1_bin.case" +# ,"zmat2d_esca.case" +# ,"dyna.case" +# ,"en6.case" +# ,"engold.case" +# ,"engoldup.case" +# ,"frame.case" +# ,"ghost_structured.case" +# ,"ghost_unstructured.case" +# ,"ironProt_ascii.case" +# ,"ironProt_bin.case" +# ,"mandelbrot1.case" +# ,"mandelbrot2.case" +# ,"naca.bin.case" +# ,"office6_bin.case" +# ,"office_ascii.case" +# ,"office_bin.case" +# ,"performance.case" +# ,"range_structured.case" +# ,"x29.case" +# ,"RectGrid_ascii.case" +# ,"RectGrid_bin.case" +# ,"ami.case" +# ,"ami6.case" +# ,"anim.case" +# ,"blow2_ascii.case" +# ,"blow2_bin.case" +# ,"blow3_bin.case" +# ,"blow4_bin.case" +# ,"blow5_ascii.case" +# ,"crash.case" +# ,"cube.case" +# ,"cubeE.case" + ] +inFiles = listdir( inDir ) + + +for inFile in inFiles: # loop on all files in inDir + + # filter .case files + basename, ext = os.path.splitext( inFile ) + if ext != ".case": continue + + # read EnSight into MEDMEM + + setIgnoreIncompatibility(0) + + ensFile = os.path.join( inDir, inFile ) + print "\nreading",ensFile + incompatible = False + try: + medFromEns = MED(ENSIGHT_DRIVER, ensFile) + medFromEns.read(); + except: + if not compatibilityPb(): + sys.exit(1) + else: + continue + + # show MEDMEM contents + m2m_nom = medFromEns.getMeshName(0) + mesh = medFromEns.getMesh(m2m_nom) + if dumpMesh: + ShowMesh( mesh, 10, [10,10,10] ) + ShowGroups( mesh ) + pass + if dumpField: + ShowFields( medFromEns, 10 ) + + # write MEDMEM into MED + + medFile = os.path.join( outDir, basename + ".med" ) + deleteFile(medFile) + print "write",medFile + wdrv = medFromEns.addDriver(MED_DRIVER,medFile) + medFromEns.write( wdrv ) + + # write MEDMEM into EnSight + + for format,bin in formats: + ensFile = os.path.join( outDir, basename ) + if format == ENSIGHT_GOLD: + formatName = "ENSIGHT GOLD" + ensFile += ".g" + else: + formatName = "ENSIGHT 6" + ensFile += '.6' + pass + if bin: + formatName += " Binary" + ensFile += 'b' + else: + formatName += " ASCII" + ensFile += 'a' + pass + ensFile += ".case" + print '*'*80 + print "Format: \t",formatName + print '*'*80 + + setEnSightFormatForWriting( format, bin ) + + medEnsDriver = ENSIGHT_MED_WRONLY_DRIVER (ensFile, medFromEns) + print "writting", ensFile + incompatible = False + try: + medEnsDriver.write() + except: + if not compatibilityPb(): + sys.exit(1) + pass + # try to write anayway, maybe it will be ok + incompatible = True + setIgnoreIncompatibility(1) + try: + medEnsDriver.write() + except: + if not compatibilityPb(): + sys.exit(1) + pass + continue + pass + + # check generated EnSight + try: + checkFile = os.path.join( outDir, basename + ".ens_checker" ) + check_ens(ensFile, checkFile) + except: + if incompatible: + # Ok I was warned about it + continue + sys.exit(1) + pass + pass + print "\n\n\n" + + +# remove created files +for f in listdir( outDir ): + deleteFile( os.path.join( outDir, f )) diff --git a/src/MEDMEM_SWIG/libMEDMEM_Swig.i b/src/MEDMEM_SWIG/libMEDMEM_Swig.i index ba08a8655..fb0189e02 100644 --- a/src/MEDMEM_SWIG/libMEDMEM_Swig.i +++ b/src/MEDMEM_SWIG/libMEDMEM_Swig.i @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // %module libMEDMEM_Swig @@ -49,21 +51,28 @@ #include "MEDMEM_Meshing.hxx" #include "MEDMEM_DriverFactory.hxx" #include "MEDMEM_GaussLocalization.hxx" +#include "MEDMEM_EnsightMedDriver.hxx" +#include "MEDMEM_EnsightMeshDriver.hxx" +#include "MEDMEM_EnsightFieldDriver.hxx" #include "MEDMEM_ArrayInterface.hxx" #include "MEDMEM_SWIG_Templates.hxx" +#include "PointLocator.hxx" using namespace MEDMEM; using namespace MED_EN; - + using namespace INTERP_KERNEL; /* typedef FIELD <double, FullInterlace> FIELDDOUBLEFULLINTERLACE;*/ /* typedef FIELD <int, FullInterlace> FIELDINTFULLINTERLACE;*/ typedef FIELD <double, FullInterlace> FIELDDOUBLE; - typedef FIELD <int, FullInterlace> FIELDINT; + typedef FIELD <int , FullInterlace> FIELDINT; typedef FIELD <double, NoInterlace> FIELDDOUBLENOINTERLACE; - typedef FIELD <int, NoInterlace> FIELDINTNOINTERLACE; + typedef FIELD <int , NoInterlace> FIELDINTNOINTERLACE; typedef FIELD <double, NoInterlaceByType> FIELDDOUBLENOINTERLACEBYTYPE; - typedef FIELD <int, NoInterlaceByType> FIELDINTNOINTERLACEBYTYPE; + typedef FIELD <int , NoInterlaceByType> FIELDINTNOINTERLACEBYTYPE; + // to keep old scripts working + typedef enum {MED_LECT=RDONLY, MED_ECRI=WRONLY, MED_REMP=RDWR} med_mode_acces_old; + %} /* @@ -75,11 +84,11 @@ /*typedef FIELD <double, FullInterlace> FIELDDOUBLEFULLINTERLACE;*/ /*typedef FIELD <int, FullInterlace> FIELDINTFULLINTERLACE;*/ typedef FIELD <double, FullInterlace> FIELDDOUBLE; -typedef FIELD <int, FullInterlace> FIELDINT; +typedef FIELD <int , FullInterlace> FIELDINT; typedef FIELD <double, NoInterlace> FIELDDOUBLENOINTERLACE; -typedef FIELD <int, NoInterlace> FIELDINTNOINTERLACE; +typedef FIELD <int , NoInterlace> FIELDINTNOINTERLACE; typedef FIELD <double, NoInterlaceByType> FIELDDOUBLENOINTERLACEBYTYPE; -typedef FIELD <int, NoInterlaceByType> FIELDINTNOINTERLACEBYTYPE; +typedef FIELD <int , NoInterlaceByType> FIELDINTNOINTERLACEBYTYPE; %include "typemaps.i" %include "my_typemap.i" @@ -148,7 +157,7 @@ typedef FIELD <int, NoInterlaceByType> FIELDINTNOINTERLACEBYTYPE; if(PyCallable_Check($input) == 0) { - char * message = "Error in typemap(python,in) for double or integer callable fonction pointeur : the argument should be a callable object"; + const char * message = "Error in typemap(python,in) for double or integer callable fonction pointeur : the argument should be a callable object"; PyErr_SetString(PyExc_RuntimeError, message); return NULL; } @@ -230,7 +239,7 @@ typedef FIELD <int, NoInterlaceByType> FIELDINTNOINTERLACEBYTYPE; int err = PyList_SetItem(py_list, i, type_converter( arrayvar[ i ])); if(err) { - char * message = "Error in " #method; + const char * message = "Error in " #method; PyErr_SetString(PyExc_RuntimeError, message); return NULL; } @@ -276,7 +285,7 @@ typedef FIELD <int, NoInterlaceByType> FIELDINTNOINTERLACEBYTYPE; SWIG_POINTER_EXCEPTION); if (err == -1) { - char * message = "Error in typemap(python,in) for vector<TYPE>" + const char * message = "Error in typemap(python,in) for vector<TYPE>" "each component should be a TYPE"; PyErr_SetString(PyExc_RuntimeError, message); return NULL; @@ -358,7 +367,8 @@ typedef enum {MED_CARTESIAN, MED_POLAR, MED_BODY_FITTED} med_grid_type; typedef enum {MED_FULL_INTERLACE, MED_NO_INTERLACE} medModeSwitch; -typedef enum {MED_LECT, MED_ECRI, MED_REMP} med_mode_acces; +typedef enum {RDONLY, WRONLY, RDWR} med_mode_acces; +typedef enum {MED_LECT, MED_ECRI, MED_REMP} med_mode_acces_old;// to keep old scripts working typedef enum {ASCENDING=7,DESCENDING=77} med_sort_direc; @@ -375,7 +385,7 @@ typedef enum {MED_NONE=0, MED_POINT1=1, MED_SEG2=102, MED_SEG3=103, typedef enum {MED_NODAL, MED_DESCENDING} medConnectivity ; typedef enum {MED_DRIVER=0, GIBI_DRIVER=1, PORFLOW_DRIVER = 2, VTK_DRIVER=254, - NO_DRIVER=255, ASCII_DRIVER = 3} driverTypes; + NO_DRIVER=255, ASCII_DRIVER = 3, ENSIGHT_DRIVER = 250 } driverTypes; typedef enum {MED_REEL64=6, MED_INT32=24, MED_INT64=26} med_type_champ; @@ -495,7 +505,7 @@ class SUPPORT void setNumberOfElements(int *NumberOfElements); - void setTotalNumberOfElements(int TotalNumberOfElements); + //void setTotalNumberOfElements(int TotalNumberOfElements); void getBoundaryElements(); @@ -694,7 +704,7 @@ public: int addDriver(driverTypes driverType, const std::string& fileName="Default File Name.med", const std::string& driverName="Default Field Name", - med_mode_acces access=MED_REMP); + med_mode_acces access=RDWR); %extend { %newobject getSupportAndOwner(); @@ -833,7 +843,7 @@ public: PyObject * applyPyFunc( PyObject * func ) { - MESSAGE("Appel de applyPyFunc"); + MESSAGE_MED("Appel de applyPyFunc"); if (!PyCallable_Check(func)) { PyErr_SetString(PyExc_TypeError, "FIELD.applyPyFunc prend en argument une fonction"); return NULL; @@ -863,7 +873,7 @@ public: %newobject __add__(const FIELD<T1, INTERLACING_TAG> & ); FIELD<T1, INTERLACING_TAG> * __add__(const FIELD<T1, INTERLACING_TAG> & m) { - MESSAGE("operator + : Creation of the addition of two FIELDs"); + MESSAGE_MED("operator + : Creation of the addition of two FIELDs"); FIELD<T1, INTERLACING_TAG>* result = FIELD<T1, INTERLACING_TAG>::add( *(FIELD<T1, INTERLACING_TAG>*)self , @@ -874,7 +884,7 @@ public: %newobject __sub__(const FIELD<T1, INTERLACING_TAG> & ); FIELD<T1, INTERLACING_TAG> * __sub__(const FIELD<T1, INTERLACING_TAG> & m) { - MESSAGE("operator - : Creation of the substraction of two FIELDs"); + MESSAGE_MED("operator - : Creation of the substraction of two FIELDs"); FIELD<T1, INTERLACING_TAG>* result = FIELD<T1, INTERLACING_TAG>::sub( *(FIELD<T1, INTERLACING_TAG>*)self , (FIELD<T1, INTERLACING_TAG>&)m ); @@ -884,7 +894,7 @@ public: %newobject __mul__(const FIELD<T1, INTERLACING_TAG> & ); FIELD<T1, INTERLACING_TAG> * __mul__(const FIELD<T1, INTERLACING_TAG> & m) { - MESSAGE("operator * : Creation of the multiplication of two FIELDs"); + MESSAGE_MED("operator * : Creation of the multiplication of two FIELDs"); FIELD<T1, INTERLACING_TAG>* result = FIELD<T1, INTERLACING_TAG>::mul( *(FIELD<T1, INTERLACING_TAG>*)self , (FIELD<T1, INTERLACING_TAG>&)m ); @@ -894,7 +904,7 @@ public: %newobject __div__(const FIELD<T1, INTERLACING_TAG> & ); FIELD<T1, INTERLACING_TAG> * __div__(const FIELD<T1, INTERLACING_TAG> & m) { - MESSAGE("operator / : Creation of the division of two FIELDs"); + MESSAGE_MED("operator / : Creation of the division of two FIELDs"); FIELD<T1, INTERLACING_TAG>* result = FIELD<T1, INTERLACING_TAG>::div( *(FIELD<T1, INTERLACING_TAG>*)self , (FIELD<T1, INTERLACING_TAG>&)m ); @@ -904,7 +914,7 @@ public: %newobject addDeep(const FIELD<T1, INTERLACING_TAG> & ); FIELD<T1, INTERLACING_TAG> * addDeep(const FIELD<T1, INTERLACING_TAG> & m) { - MESSAGE("operator + : Creation of the addition of two FIELDINTs"); + MESSAGE_MED("operator + : Creation of the addition of two FIELDINTs"); FIELD<T1, INTERLACING_TAG>* result = FIELD<T1, INTERLACING_TAG>::addDeep( *(FIELD<T1, INTERLACING_TAG>*)self , (FIELD<T1, INTERLACING_TAG>&)m ); @@ -914,7 +924,7 @@ public: %newobject subDeep(const FIELD<T1, INTERLACING_TAG> & ); FIELD<T1, INTERLACING_TAG> * subDeep(const FIELD<T1, INTERLACING_TAG> & m) { - MESSAGE("operator - : Creation of the substraction of two FIELDs"); + MESSAGE_MED("operator - : Creation of the substraction of two FIELDs"); FIELD<T1, INTERLACING_TAG>* result = FIELD<T1, INTERLACING_TAG>::subDeep( *(FIELD<T1, INTERLACING_TAG>*)self , (FIELD<T1, INTERLACING_TAG>&)m ); @@ -924,7 +934,7 @@ public: %newobject mulDeep(const FIELD<T1, INTERLACING_TAG> & ); FIELD<T1, INTERLACING_TAG> * mulDeep(const FIELD<T1, INTERLACING_TAG> & m) { - MESSAGE("operator * : Creation of the multiplication of two FIELDs"); + MESSAGE_MED("operator * : Creation of the multiplication of two FIELDs"); FIELD<T1, INTERLACING_TAG>* result = FIELD<T1, INTERLACING_TAG>::mulDeep( *(FIELD<T1, INTERLACING_TAG>*)self , (FIELD<T1, INTERLACING_TAG>&)m ); @@ -934,7 +944,7 @@ public: %newobject divDeep(const FIELD<T1, INTERLACING_TAG> & ); FIELD<T1, INTERLACING_TAG> * divDeep(const FIELD<T1, INTERLACING_TAG> & m) { - MESSAGE("operator / : Creation of the division of two FIELDs"); + MESSAGE_MED("operator / : Creation of the division of two FIELDs"); FIELD<T1, INTERLACING_TAG>* result = FIELD<T1, INTERLACING_TAG>::divDeep( *(FIELD<T1, INTERLACING_TAG>*)self , (FIELD<T1, INTERLACING_TAG>&)m ); @@ -1058,6 +1068,8 @@ public : int getMeshDimension(); int getNumberOfNodes(); + + void convertToPoly(); bool getIsAGrid(); @@ -1104,6 +1116,8 @@ public : medGeometryElement getElementTypeWithPoly(medEntityMesh Entity,int Number); + SUPPORT * getSupportOnAll(medEntityMesh Entity); + std::string getName() const; %extend { @@ -1154,15 +1168,15 @@ public : } int addDriver(driverTypes driverType, - char * fileName="Default File Name.med", - char * driverName="Default Mesh Name", - med_mode_acces access=MED_REMP) + const char * fileName="Default File Name.med", + const char * driverName="Default Mesh Name", + med_mode_acces access=RDWR) { return self->addDriver(driverType,string(fileName), string(driverName),access); } - void write(int index=0, char * driverName="") + void write(int index=0, const char * driverName="") { self->write(index, string(driverName)); } @@ -1496,8 +1510,8 @@ class GRID : public MESH i++; break; default: - char * message = "Error in GRID::getEntityPosition: wrong Entity"; - PyErr_SetString(PyExc_RuntimeError, message); + const char * message = "Error in GRID::getEntityPosition: wrong Entity"; + PyErr_SetString(PyExc_RuntimeError, (char *)message); return NULL; } PyObject *py_list = PyList_New( size ); @@ -1507,8 +1521,8 @@ class GRID : public MESH Py_BuildValue("i", ijk[j++])); if(err) { - char * message = "Error in GRID::getNodePosition"; - PyErr_SetString(PyExc_RuntimeError, message); + const char * message = "Error in GRID::getNodePosition"; + PyErr_SetString(PyExc_RuntimeError, (char *)message); return NULL; } } @@ -1522,6 +1536,34 @@ class GRID : public MESH } }; +class PointLocator +{ +public: + PointLocator(const MESH& mesh); + virtual ~PointLocator(); + %extend{ + PyObject* locate(const double* x) + { + std::list<int> mylist = self->locate(x); + if (mylist.size()>10) + { + const char * message = "Error in PointLocator : SWIG interface limits the number of cells to 10"; + PyErr_SetString(PyExc_RuntimeError, (char *)message); + return NULL; + } + + int array[10]; // maximum number of cells in which the point lies + int index=0; + for (list<int>::const_iterator iter= mylist.begin(); + iter != mylist.end(); + iter++) + array[index++]= *iter; + TYPEMAP_OUTPUT_ARRAY(array, mylist.size(), PyInt_FromLong, + PointLocator::locate); + } + } +}; + class MED { public: @@ -1554,8 +1596,8 @@ class MED } int addDriver(driverTypes driverType, - char * fileName="Default File Name.med", - med_mode_acces access=MED_REMP) + const char * fileName="Default File Name.med", + med_mode_acces access=RDWR) { return self->addDriver(driverType,string(fileName),access); } @@ -2099,6 +2141,10 @@ class MED_MESH_RDONLY_DRIVER void read ( void ) ; + void desactivateFacesComputation(); + + void activateFacesComputation(); + %extend { MED_MESH_RDONLY_DRIVER(char * fileName, MESH * ptrMesh) { @@ -2388,8 +2434,89 @@ public: %template (ASCII_FIELDDOUBLE_DRIVER) ASCII_FIELD_DRIVER< double >; %template (ASCII_FIELDINT_DRIVER) ASCII_FIELD_DRIVER< int >; +//======================================================================= /* + EnSight drivers */ +// --------------------------------------------------------------- +//!< supported formats +enum EnSightFormat { ENSIGHT_6, ENSIGHT_GOLD }; + +// --------------------------------------------------------------- +//!< set writing format + +void setEnSightFormatForWriting (EnSightFormat format, bool isBinary); + +// --------------------------------------------------------------- +//!< To raise or not if MEDMEM-EnSight incompatibility encounters or suspected. +// See MEDMEM_EnsightUtils.hxx for raison why + +void setIgnoreIncompatibility(bool toIgnore=true); + +// --------------------------------------------------------------- +//!< EnSight reading driver reads all meshes and fields + +class ENSIGHT_MED_RDONLY_DRIVER +{ +public: + ENSIGHT_MED_RDONLY_DRIVER(const std::string & fileName, MED * ptrMed); + void read(); + void readFileStruct(); +}; +// --------------------------------------------------------------- +//!< EnSight writing driver + +class ENSIGHT_MED_WRONLY_DRIVER +{ +public : + ENSIGHT_MED_WRONLY_DRIVER(const std::string & fileName, MED * ptrMed); + void write(); +}; +// --------------------------------------------------------------- +//!< EnSight mesh reading driver + +class ENSIGHT_MESH_RDONLY_DRIVER +{ +public : + //!< to read mesh of index-th time step + ENSIGHT_MESH_RDONLY_DRIVER(const std::string & fileName, MESH * ptrMesh, int index=1); + void read(); +}; +// --------------------------------------------------------------- +//!< Writing EnSight mesh driver. + +class ENSIGHT_MESH_WRONLY_DRIVER +{ +public : + ENSIGHT_MESH_WRONLY_DRIVER(const std::string & fileName, MESH * ptrMesh, bool append=false); + void write(); +}; +// --------------------------------------------------------------- +//!< EnSight field reading driver + +class ENSIGHT_FIELD_RDONLY_DRIVER +{ +public : + //!< Set the name of the FIELD in EnSight file + void setFieldName(const string & fieldName); + //!< read the field of a specified name and index-th time step. + ENSIGHT_FIELD_RDONLY_DRIVER(const std::string & fileName, FIELD_ * ptrField, int step=1); + void read(); +}; +// --------------------------------------------------------------- +//!< Writing EnSight field driver. + +class ENSIGHT_FIELD_WRONLY_DRIVER +{ +public : + //!< Set the name of the FIELD in EnSight file + void setFieldName(const std::string & fieldName); + ENSIGHT_FIELD_WRONLY_DRIVER(const std::string & fileName, FIELD_ * ptrField); + //!< Write FIELD, the mesh is supposed to be written in this file. + void write(); +}; +// end of EnSight drivers +//======================================================================= template <class INTERLACING_TAG> class GAUSS_LOCALIZATION @@ -2485,8 +2612,8 @@ template <class INTERLACING_TAG> class GAUSS_LOCALIZATION template<class T, class INTERLACING_TAG> FIELD<T, INTERLACING_TAG> * createTypedFieldFromField(FIELD_ * field) { - MESSAGE("createTypedFieldFromField : Constructor (for Python API) FIELD<T> with parameter FIELD_"); - MESSAGE("Its returns a proper cast of the input pointer :: FIELD_ --> FIELD<T>"); + MESSAGE_MED("createTypedFieldFromField : Constructor (for Python API) FIELD<T> with parameter FIELD_"); + MESSAGE_MED("Its returns a proper cast of the input pointer :: FIELD_ --> FIELD<T>"); if ( field ) { if (field->getInterlacingType() != SET_INTERLACING_TYPE<INTERLACING_TAG>::_interlacingType) throw MEDEXCEPTION("cast to wrong medModeSwitch (_interlacingType)"); @@ -2571,14 +2698,14 @@ GRID * createGridFromMesh( MESH * aMesh ); %{ GRID * createGridFromMesh( MESH * aMesh ) { - MESSAGE("createGridFromMesh : Constructor (for Python API) GRID with parameter MESH *"); - MESSAGE("Its returns a proper cast of the input pointer :: MESH --> GRID"); + MESSAGE_MED("createGridFromMesh : Constructor (for Python API) GRID with parameter MESH *"); + MESSAGE_MED("Its returns a proper cast of the input pointer :: MESH --> GRID"); if (aMesh->getIsAGrid()) return (GRID *) aMesh; - char * message = "Error in GRID(mesh): mesh is not a grid"; - PyErr_SetString(PyExc_RuntimeError, message); + const char * message = "Error in GRID(mesh): mesh is not a grid"; + PyErr_SetString(PyExc_RuntimeError, (char *)message); return NULL; } @@ -2587,7 +2714,7 @@ GRID * createGridFromMesh( MESH * aMesh ); int NumberOfComponents, PyObject * double_function) { - MESSAGE("createFieldFromAnalytic : Constructor (for Python API) FIELD from an analytic fonction"); + MESSAGE_MED("createFieldFromAnalytic : Constructor (for Python API) FIELD from an analytic fonction"); FIELD<T, INTERLACING_TAG> * fieldAnalytic = new FIELD<T, INTERLACING_TAG>(Support, NumberOfComponents); diff --git a/src/MEDMEM_SWIG/medEnsightMed_test.py b/src/MEDMEM_SWIG/medEnsightMed_test.py new file mode 100644 index 000000000..c4cb10e39 --- /dev/null +++ b/src/MEDMEM_SWIG/medEnsightMed_test.py @@ -0,0 +1,327 @@ +#!/usr/bin/env python +# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG +# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT +# 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. +# +# 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 +# +############################################################################ +# +# This script tests conversion of MEDMEM to EnSight by performing following +# operations on available med files: +# - read med file into MEDMEM and breifly dump it's content; +# - write EnSight file in different formats: Gold and EnSight6, ASCII and binary; +# - checks generated EnSight files using ens_checker utility (if available); +# - read generated EnSight file into MEDMEM and breifly dump it's content; +# - store MEDMEM to med file. +# +############################################################################ + +from medmem import * +from dumpMEDMEM import * +from re import search +import sys + +ASCII = False +Binary = True +formats = [ + (ENSIGHT_GOLD,ASCII) + ,(ENSIGHT_GOLD,Binary) + ,(ENSIGHT_6,ASCII) + ,(ENSIGHT_6,Binary) + ] + +tmpDir = os.getenv("TMP") +if not tmpDir: + tmpDir = os.getenv("TMPDIR") + +inDir = os.path.join(os.getenv("MED_ROOT_DIR"), "share","salome","resources","med") +if not os.access(inDir, os.F_OK): + raise RuntimeError, "Path to med files not found, MED_ROOT_DIR incorrect?" + +outDir = os.path.join( tmpDir,"Ensight_out") +if not os.access(outDir, os.F_OK): + os.mkdir( outDir ) + pass + +# find out if ens_checker is present +has_ens_checker = False +tmpFile = os.path.join( outDir, "has_ens_checker" ) +os.system("ens_checker _.case > %s 2>&1" % tmpFile) +tmpFile = open( tmpFile ).read() +if search("EnSight Data Format Checker", tmpFile): + has_ens_checker = True +else: + print "\nWarning: ens_checker utility NOT available" + pass + +dumpMesh = False +dumpMesh = True + +dumpField= True +dumpField= False + +def check_ens(casefile, logfile): + cmd = "(cd %s; ens_checker %s > %s 2>&1)" % (outDir, casefile, logfile) + err = os.system( cmd ) + if os.access(logfile, os.F_OK): + log = open(logfile).read() + if search("bummer", log): + print log + raise RuntimeError, "cd %s; ens_checker %s" % (outDir, casefile) + if search("Warning:", log): + print log + pass + pass + +def compatibilityPb(): + "Print traceback and return true if exception is due to EnSight-MEDMEM incompatibility" + isCompatibilityPb = ( sys.exc_value.__str__().find("compatibility problem") > 0 ) + if isCompatibilityPb: + print '$$$$$$$$$$$$$$$$$$$$ COMPATIBILITY PROBLEM $$$$$$$$$$$$$$$$$$$$$$$$' + print sys.exc_value, "\n" + else: + import traceback + traceback.print_exc() + return isCompatibilityPb + +from dircache import listdir + +# all files sorted by size increasing +medFiles = [ +# "maillage_chemvalIV_cas1_40elts.med" +# ,"Old_maillage_chemvalIV_cas1_40elts.med" +# ,"maillage_UniSegFam.med" +# ,"champ1.med" +# ,"carre_en_quad4.med" +# ,"maillage_UniSegFam_import22.med" +# ,"poly3D.med" +# ,"Old_Deff_fdt_5.8_castem_vf_diff_conc_dom.med" +# ,"Old_Deff_fdt_5.8_castem_efmh_diff_conc_dom.med" +# ,"test18.med" +# ,"cas_defaut_domaine_fluide.med" +# ,"carre_en_quad4_seg2.med" +# ,"polyedres.med" +# ,"Fields_group3D.med" +# ,"carre_en_quad4_import22.med" +# ,"maillage_5_5_5.med" +# ,"cube_hexa8.med" +# ,"carre_en_quad4_seg2_import22.med" +# ,"new_pointe.med" +# ,"mesh.med" +# ,"cube_hexa8_quad4.med" +# ,"cube_hexa8_import22.med" +# ,"jurassique.med" +# ,"test_2D.med" +# ,"mesh_import22.med" +# ,"pointe_4fields.med" +# ,"cube_hexa8_quad4_import22.med" +# ,"pointe.med" +# ,"test19.med" +# ,"extendedtransport53_triangles.med" +# ,"recoll_bord.med" +# ,"polygones.med" +# ,"zzzz121b_without_tr6.med" +# ,"trio_2D.med" +# ,"essaiminimail.med" +# ,"pointe_import22.med" +# ,"maill.0.med" +# ,"elle_3D_HPr_2x2x2_2.med" +# ,"maill.00_nofield.med" +# ,"elle_3D_HPr_4x4x4_2.med" +# ,"maill.00_nomesh.med" +# ,"fra1.med" +# ,"fra.med" +# ,"maill.00_without_seg2.med" +# ,"freebord.med" +# ,"maill.00.med" +# ,"zzzz121b.med" +# ,"ResOK_0000.med" +# ,"Darcy3_3D_H_10x10x10_2.med" +# ,"maill.0_volumes.med" +# ,"Old_darcy_1.3_resTRACES.med" +# ,"Old_darcy_1.3_resCASTEM.med" +# ,"darcy_1.3_resTRACES.med" +# ,"darcy_1.3_resCASTEM.med" +# ,"geomMesh22.med" +# ,"geomMesh21.med" +# ,"Old_darcy_1.3_resPORFLOW.med" +# ,"darcy_1.3_resPORFLOW.med" +# ,"test_hydro_darcy1a_out.med" +# ,"maillage_2D.med" +# ,"elle_3D_HPr_10x10x10_2.med" +# ,"Old_darcy_1.1_res.med" +# ,"darcy_1.1_res.med" +# ,"maill.1.med" +# ,"clo.med" +# ,"clo2.med" +# ,"Old_H_Traces_Se79_COUPLEX1.med" +# ,"Old_H_Traces_I129_COUPLEX1.med" +# ,"Old_H_PorfPorf_Se79_COUPLEX1.med" +# ,"Old_H_PorfPorf_I129_COUPLEX1.med" +# ,"Old_H_PorfCast_EFMH_Se79_COUPLEX1.med" +# ,"Old_H_PorfCast_EFMH_I129_COUPLEX1.med" +# ,"Old_H_CastPorf_Se79_COUPLEX1.med" +# ,"Old_H_CastPorf_I129_COUPLEX1.med" +# ,"Old_H_CastCast_VF_Se79_COUPLEX1.med" +# ,"Old_H_CastCast_VF_I129_COUPLEX1.med" +# ,"Old_H_CastCast_EFMH_I129_COUPLEX1.med" +# ,"H_Traces_Se79_COUPLEX1.med" +# ,"H_Traces_I129_COUPLEX1.med" +# ,"H_PorfPorf_I129_COUPLEX1.med" +# ,"H_PorfCast_EFMH_Se79_COUPLEX1.med" +# ,"H_PorfCast_EFMH_I129_COUPLEX1.med" +# ,"H_CastPorf_Se79_COUPLEX1.med" +# ,"H_CastPorf_I129_COUPLEX1.med" +# ,"H_CastCast_VF_Se79_COUPLEX1.med" +# ,"H_CastCast_VF_I129_COUPLEX1.med" +# ,"H_CastCast_EFMH_I129_COUPLEX1.med" +# ,"puitsinst.med" +# ,"Old_darcy2_Castem_EFMH.med" +# ,"darcy2_Castem_EFMH.med" +# ,"Old_darcy2_Castem_qua_VF.med" +# ,"Old_darcy2_Castem_qua_EFMH.med" +# ,"darcy2_Castem_qua_VF.med" +# ,"darcy2_Castem_qua_EFMH.med" +# ,"maillage_migr3d.med" +# ,"Mistrat.med" +# ,"Old_ChampsDarcy.med" +# ,"ChampsDarcy.med" +# ,"Mistrat_import22.med" +# ,"resu.2.med" +# ,"maill.2.med" +# ,"TimeStamps.med" +# ,"hexa_28320_ELEM.med" +# ,"TimeStamps_import22.med" + ] + +badFiles = [ # files that can't be read by MEDMEM + "Deff_fdt_5.8_castem_efmh_diff_conc_dom.med" + ,"Deff_fdt_5.8_castem_vf_diff_conc_dom.med" + ] + +medFiles = listdir( inDir ) + + +for medFile in medFiles: # loop on med files in inDir + + basename, ext = os.path.splitext( medFile ) + if ext != ".med" or medFile in badFiles: continue + + # read MED file + medFile = os.path.join( inDir, medFile ) + print "reading",medFile + try: + med = MED(MED_DRIVER, medFile) + med.read(); + m2m_nom = med.getMeshName(0) + mesh = med.getMesh(m2m_nom) + except: + print sys.exc_value + continue + + ShowMesh( mesh ) + #ShowGroups( mesh ) + ## ShowFields( med ) + + basename = os.path.join( outDir, basename ) + '.' + checkFile = basename + "ens_checker" + + for format,bin in formats: + if format == ENSIGHT_GOLD: + formatName = "ENSIGHT GOLD" + formatSuffix = "g" + else: + formatName = "ENSIGHT 6" + formatSuffix = '6' + pass + if bin: + formatName += " Binary" + formatSuffix += 'b' + else: + formatName += " ASCII" + formatSuffix += 'a' + pass + ensFile = basename + formatSuffix + ".case" + print '*'*80 + print "Format: \t",formatName + print '*'*80 + + setEnSightFormatForWriting( format, bin ) + + # write a mesh to EnSight + # print "write a mesh to EnSight" + # myMeshDriver = ENSIGHT_MESH_WRONLY_DRIVER(ensFile,mesh) + # myMeshDriver.write() + + # if med.getNumberOfFields() > 0: + # fName = med.getFieldName( 0 ) + # dt_it_= med.getFieldIteration( fName, 0 ) + # field = med.getField( fName, dt_it_.dt, dt_it_.it ) + # print "add a field to EnSight" + # myFieldDriver = ENSIGHT_FIELD_WRONLY_DRIVER(ensFile,field); + # myFieldDriver.write(); + + # check_ens(ensFile, checkFile) + + # write EnSight + medEnsDriver = ENSIGHT_MED_WRONLY_DRIVER (ensFile, med) + print "writting", ensFile + try: + medEnsDriver.write() + except: + if not compatibilityPb(): + sys.exit(1) + continue + + # check generated EnSight + check_ens(ensFile, checkFile) + + # read generated EnSight into MEDMEM + print "reading",ensFile + medFromEns = MED(ENSIGHT_DRIVER, ensFile) + medFromEns.read(); + + # dump generated EnSight + m2m_nom = medFromEns.getMeshName(0) + mesh = medFromEns.getMesh(m2m_nom) + if dumpMesh: + ShowMesh( mesh ) + #ShowMesh( mesh, 10, [10,10,10] ) + #ShowGroups( mesh ) + pass + if dumpField: + ShowFields( medFromEns ) + pass + + # write EnSight to MED + wFile = basename + formatSuffix + ".med" + deleteFile(wFile) + print "write",wFile + try: + wdrv = medFromEns.addDriver(MED_DRIVER,wFile) + medFromEns.write( wdrv ) + except: + import traceback + traceback.print_exc() + pass + pass + + print "\n\n\n" + + +# remove created files +for f in listdir( outDir ): + deleteFile( os.path.join( outDir, f )) diff --git a/src/MEDMEM_SWIG/medMeshing_test.py b/src/MEDMEM_SWIG/medMeshing_test.py index 607e783f2..d042c0d8d 100644 --- a/src/MEDMEM_SWIG/medMeshing_test.py +++ b/src/MEDMEM_SWIG/medMeshing_test.py @@ -1,30 +1,31 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# -################################################################################### +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +################################################################################### # This Python script uses the wrapped C++ class MESHING to buid a mesh from only # primitive data like coordinates (Pythoin double array) and connectivity (Python # integer arrays). It is the Python equivalent of the C++ program # test_MEDMEM_Meshing.cxx in the ../MEDMEM directory of the SALOME distribution -# ################################################################################### - +# from libMEDMEM_Swig import * # files name to save the generated MESH(ING) in different format diff --git a/src/MEDMEM_SWIG/med_field_anal.py b/src/MEDMEM_SWIG/med_field_anal.py index 933923ad1..b8659e588 100755 --- a/src/MEDMEM_SWIG/med_field_anal.py +++ b/src/MEDMEM_SWIG/med_field_anal.py @@ -1,29 +1,30 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# -############################################################################ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +############################################################################ # This Python script is testing the generation of MED field using a # user-callable function with different number of components and # different SUPPORTs. -# ############################################################################ - +# from math import * def f_scal_dbl_2d(x, y): @@ -83,10 +84,10 @@ import os #befor running this script, please be sure about the path the file fileName # filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") -medFile = filePath + "carre_en_quad4_seg2.med" -medFile = filePath + "cube_hexa8_quad4.med" +medFile = os.path.join(filePath, "carre_en_quad4_seg2.med") +medFile = os.path.join(filePath, "cube_hexa8_quad4.med") def print_ord(i): if i == 0: diff --git a/src/MEDMEM_SWIG/med_opfield_test.py b/src/MEDMEM_SWIG/med_opfield_test.py index de479c8c9..156e1f38f 100755 --- a/src/MEDMEM_SWIG/med_opfield_test.py +++ b/src/MEDMEM_SWIG/med_opfield_test.py @@ -1,27 +1,28 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# -############################################################################ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# this Python script is testing all operations between FIELD(DOUBLE,INT) +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 # ############################################################################ - +# this Python script is testing all operations between FIELD(DOUBLE,INT) +############################################################################ +# from libMEDMEM_Swig import * from random import * import os @@ -29,9 +30,9 @@ import os #befor running this script, please be sure about the path the file fileName # filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") -medFile = filePath + "pointe.med" +medFile = os.path.join( filePath, "pointe.med" ) def add_one(i): return i+1 diff --git a/src/MEDMEM_SWIG/med_opsupp_test.py b/src/MEDMEM_SWIG/med_opsupp_test.py index 6fa18d9de..964ad16f4 100755 --- a/src/MEDMEM_SWIG/med_opsupp_test.py +++ b/src/MEDMEM_SWIG/med_opsupp_test.py @@ -1,28 +1,29 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# -############################################################################ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +############################################################################ # This Python script is testing the merge and the intersection of # several SUPPORTs -# ############################################################################ - +# from libMEDMEM_Swig import * from random import * import os @@ -30,9 +31,9 @@ import os #befor running this script, please be sure about the path the file fileName # filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") -medFile = filePath + "pointe.med" +medFile = os.path.join( filePath, "pointe.med" ) def print_ord(i): if i == 0: diff --git a/src/MEDMEM_SWIG/med_test1.py b/src/MEDMEM_SWIG/med_test1.py index 6697b6e19..bb8e4b1fc 100644 --- a/src/MEDMEM_SWIG/med_test1.py +++ b/src/MEDMEM_SWIG/med_test1.py @@ -1,30 +1,31 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# -################################################################################### +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +################################################################################### # This Python script is parsing a MED file using MED Memory from SALOME platform: # It analyses all meshes in the MED file (coordinates, connectivity of d-cells as # well as (d-1)-cells, families). It analyses fields stored in the MED file (d is # the space dimension). You can assume that it is a kind of MED file parser. -# ################################################################################### - +# from libMEDMEM_Swig import * from random import * import os @@ -32,10 +33,10 @@ import os #befor running this script, please be sure about the path the file fileName # filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") -medFile = filePath + "carre_en_quad4_seg2.med" -#medFile = filePath + "cube_hexa8_quad4.med" +medFile = os.path.join(filePath, "carre_en_quad4_seg2.med") +#medFile = os.path.join(filePath, "cube_hexa8_quad4.med") def print_ord(i): if i == 0: diff --git a/src/MEDMEM_SWIG/med_test2.py b/src/MEDMEM_SWIG/med_test2.py index 397a144ea..1320c222b 100644 --- a/src/MEDMEM_SWIG/med_test2.py +++ b/src/MEDMEM_SWIG/med_test2.py @@ -1,31 +1,32 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# -################################################################################### +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +################################################################################### # This Python script is parsing a MED file using MED Memory from SALOME platform: # It analyses all meshes in the MED file (coordinates, connectivity of d-cells as # well as (d-1)-cells, families), it tests all fields generated in the MESH class # and write them in a 2 new med files (V2.1 and V2.2), it gives only the number of # fields stored in the MED file (d is the mesh/space dimension). -# ################################################################################### - +# from libMEDMEM_Swig import * from random import * @@ -77,10 +78,10 @@ import os #befor running this script, please be sure about the path the file fileName # filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") -medFile = filePath + "carre_en_quad4_seg2.med" -#medFile = filePath + "cube_hexa8_quad4.med" +medFile = os.path.join(filePath, "carre_en_quad4_seg2.med") +#medFile = os.path.join(filePath, "cube_hexa8_quad4.med") def print_ord(i): if i == 0: diff --git a/src/MEDMEM_SWIG/med_test3.py b/src/MEDMEM_SWIG/med_test3.py index 728f0581c..cb8eac30b 100644 --- a/src/MEDMEM_SWIG/med_test3.py +++ b/src/MEDMEM_SWIG/med_test3.py @@ -1,28 +1,29 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# -################################################################################### +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +################################################################################### # This Python script is parsing a MED file using MED Memory from SALOME platform: # It tests the setValue, setRow and setColum functions on MED fields -# ################################################################################### - +# from libMEDMEM_Swig import * from random import * import os @@ -30,10 +31,10 @@ import os #befor running this script, please be sure about the path the file fileName # filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") -medFile = filePath + "carre_en_quad4_seg2.med" -#medFile = filePath + "cube_hexa8_quad4.med" +medFile = os.path.join(filePath, "carre_en_quad4_seg2.med") +#medFile = os.path.join(filePath, "cube_hexa8_quad4.med") def print_ord(i): if i == 0: diff --git a/src/MEDMEM_SWIG/med_test_grid.py b/src/MEDMEM_SWIG/med_test_grid.py index 6dc48da7c..18b40dff2 100755 --- a/src/MEDMEM_SWIG/med_test_grid.py +++ b/src/MEDMEM_SWIG/med_test_grid.py @@ -1,28 +1,30 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# # Python script for testing T5.10 task # ########################################### - #% Test structured mesh (GRID) reading from file test19.med #% test19.med can be obtained by running test19_c.out executable # or locally in MEDMEM directory create_grid - +# from libMEDMEM_Swig import * import os @@ -30,9 +32,9 @@ import os #befor running this script, please be sure about the path the file fileName # filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") -medFile = filePath + "test19.med" +medFile = os.path.join(filePath, "test19.med") print "Read file", medFile md = MED() diff --git a/src/MEDMEM_SWIG/med_test_skin.py b/src/MEDMEM_SWIG/med_test_skin.py index 4cba008a7..1e05fb464 100644 --- a/src/MEDMEM_SWIG/med_test_skin.py +++ b/src/MEDMEM_SWIG/med_test_skin.py @@ -1,33 +1,36 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# #% Test function MESH::getSkin() on mesh from file cube_hexa8_quad4.med #% The med file can be obtained by running create_mesh_c3h8q4 executable - +# from libMEDMEM_Swig import * import os # #befor running this script, please be sure about the path the file fileName # filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") -medFile = filePath + "cube_hexa8_quad4.med" +medFile = os.path.join(filePath, "cube_hexa8_quad4.med") md = MED() diff --git a/src/MEDMEM_SWIG/medmem.py b/src/MEDMEM_SWIG/medmem.py index ebae88d96..9c686e6c8 100644 --- a/src/MEDMEM_SWIG/medmem.py +++ b/src/MEDMEM_SWIG/medmem.py @@ -1,19 +1,22 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# from libMEDMEM_Swig import * diff --git a/src/MEDMEM_SWIG/my_typemap.i b/src/MEDMEM_SWIG/my_typemap.i index 9a96c2e75..6ff1b7e05 100644 --- a/src/MEDMEM_SWIG/my_typemap.i +++ b/src/MEDMEM_SWIG/my_typemap.i @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // %{ #include <stdio.h> diff --git a/src/MEDMEM_SWIG/testDriverAscii.py b/src/MEDMEM_SWIG/testDriverAscii.py index 529fa53f9..e5ea74d2e 100644 --- a/src/MEDMEM_SWIG/testDriverAscii.py +++ b/src/MEDMEM_SWIG/testDriverAscii.py @@ -1,21 +1,24 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# from libMEDMEM_Swig import * import os @@ -25,9 +28,9 @@ import os # filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") -medFile = filePath + "test_2D.med" +medFile = os.path.join(filePath, "test_2D.med") asciiFile = "tyst.txt" diff --git a/src/MEDMEM_SWIG/testGaussLocalization.py b/src/MEDMEM_SWIG/testGaussLocalization.py index b412e1948..d70025d9e 100644 --- a/src/MEDMEM_SWIG/testGaussLocalization.py +++ b/src/MEDMEM_SWIG/testGaussLocalization.py @@ -1,29 +1,30 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# -################################################################################### +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +################################################################################### # This Python script is to test the API of the C++ GAUSS_LOCALIZATION class # defined in MEDMEM_GaussLocalization.hxx. This test is the Python equivalent # of the test_GaussLocalization.cxx program. -# ################################################################################### - +# from libMEDMEM_Swig import * a = 0.446948490915965 diff --git a/src/MEDMEM_SWIG/testMedMemCxxTests.py b/src/MEDMEM_SWIG/testMedMemCxxTests.py index 3ac5b42b1..11805cc59 100644 --- a/src/MEDMEM_SWIG/testMedMemCxxTests.py +++ b/src/MEDMEM_SWIG/testMedMemCxxTests.py @@ -1,27 +1,30 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# from libMEDMEM_Swig import * import os,string filesPath=os.environ["MED_ROOT_DIR"] -filesPath=filesPath+"/share/salome/resources/med/" +filesPath=os.path.join(filesPath, "share", "salome", "resources", "med") testExecfiles = [] argListTest = [] @@ -147,205 +150,205 @@ fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("Darcy3_3D_H_10x10x10") -argListTest.append(filesPath+"Darcy3_3D_H_10x10x10.sauve") +argListTest.append(os.path.join(filesPath,"Darcy3_3D_H_10x10x10.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("dx200_dy1_avec_2couches") -argListTest.append(filesPath+"dx200_dy1_avec_2couches.sauve") +argListTest.append(os.path.join(filesPath,"dx200_dy1_avec_2couches.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("elle_2D_QT_10x10") -argListTest.append(filesPath+"elle_2D_QT_10x10.sauve") +argListTest.append(os.path.join(filesPath,"elle_2D_QT_10x10.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("elle_2D_QT_2x2") -argListTest.append(filesPath+"elle_2D_QT_2x2.sauve") +argListTest.append(os.path.join(filesPath,"elle_2D_QT_2x2.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("elle_2D_QT_40x40") -argListTest.append(filesPath+"elle_2D_QT_40x40.sauve") +argListTest.append(os.path.join(filesPath,"elle_2D_QT_40x40.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("elle_2D_QT_4x4") -argListTest.append(filesPath+"elle_2D_QT_4x4.sauve") +argListTest.append(os.path.join(filesPath,"elle_2D_QT_4x4.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("elle_3D_HPr_10x10x10") -argListTest.append(filesPath+"elle_3D_HPr_10x10x10.sauve") +argListTest.append(os.path.join(filesPath,"elle_3D_HPr_10x10x10.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("elle_3D_HPr_2x2x2") -argListTest.append(filesPath+"elle_3D_HPr_2x2x2.sauve") +argListTest.append(os.path.join(filesPath,"elle_3D_HPr_2x2x2.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("elle_3D_HPr_4x4x4") -argListTest.append(filesPath+"elle_3D_HPr_4x4x4.sauve") +argListTest.append(os.path.join(filesPath,"elle_3D_HPr_4x4x4.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("inclusion_2d_raf") -argListTest.append(filesPath+"inclusion_2d_raf.sauve") +argListTest.append(os.path.join(filesPath,"inclusion_2d_raf.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("inclusion_2d") -argListTest.append(filesPath+"inclusion_2d.sauve") +argListTest.append(os.path.join(filesPath,"inclusion_2d.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("mail_ktest1-3-hexa") -argListTest.append(filesPath+"mail_ktest1-3-hexa.sauve") +argListTest.append(os.path.join(filesPath,"mail_ktest1-3-hexa.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("mail_ktest1-3-tetra") -argListTest.append(filesPath+"mail_ktest1-3-tetra.sauve") +argListTest.append(os.path.join(filesPath,"mail_ktest1-3-tetra.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("mail_ktest3-1") -argListTest.append(filesPath+"mail_ktest3-1.sauve") +argListTest.append(os.path.join(filesPath,"mail_ktest3-1.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("mail_ktest3-2") -argListTest.append(filesPath+"mail_ktest3-2.sauve") +argListTest.append(os.path.join(filesPath,"mail_ktest3-2.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("maillage_andra2_100elts") -argListTest.append(filesPath+"maillage_andra2_100elts.sauve") +argListTest.append(os.path.join(filesPath,"maillage_andra2_100elts.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("maillage_cas2_2d") -argListTest.append(filesPath+"maillage_cas2_2d.sauve") +argListTest.append(os.path.join(filesPath,"maillage_cas2_2d.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("maillage_cas4_234elts") -argListTest.append(filesPath+"maillage_cas4_234elts.sauve") +argListTest.append(os.path.join(filesPath,"maillage_cas4_234elts.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("maillage_CHEMVAL_100elts") -argListTest.append(filesPath+"maillage_CHEMVAL_100elts.sauve") +argListTest.append(os.path.join(filesPath,"maillage_CHEMVAL_100elts.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("maillage_CHEMVAL_40elts") -argListTest.append(filesPath+"maillage_CHEMVAL_40elts.sauve") +argListTest.append(os.path.join(filesPath,"maillage_CHEMVAL_40elts.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("maillage_chemvalIV_cas1_100elts") -argListTest.append(filesPath+"maillage_chemvalIV_cas1_100elts.sauve") +argListTest.append(os.path.join(filesPath,"maillage_chemvalIV_cas1_100elts.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("maillage_chemvalIV_cas1_40elts") -argListTest.append(filesPath+"maillage_chemvalIV_cas1_40elts.sauve") +argListTest.append(os.path.join(filesPath,"maillage_chemvalIV_cas1_40elts.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("maill_mistra_elim") -argListTest.append(filesPath+"maill_mistra_elim.sauve") +argListTest.append(os.path.join(filesPath,"maill_mistra_elim.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("mail_test1-1-qua") -argListTest.append(filesPath+"mail_test1-1-qua.sauve") +argListTest.append(os.path.join(filesPath,"mail_test1-1-qua.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("mail_test1-1-tri") -argListTest.append(filesPath+"mail_test1-1-tri.sauve") +argListTest.append(os.path.join(filesPath,"mail_test1-1-tri.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("mail_test1-2-qua") -argListTest.append(filesPath+"mail_test1-2-qua.sauve") +argListTest.append(os.path.join(filesPath,"mail_test1-2-qua.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("mail_test1-2-tri") -argListTest.append(filesPath+"mail_test1-2-tri.sauve") +argListTest.append(os.path.join(filesPath,"mail_test1-2-tri.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("mail-test1-4-1") -argListTest.append(filesPath+"mail-test1-4-1.sauve") +argListTest.append(os.path.join(filesPath,"mail-test1-4-1.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_gibi_driver") rootFileTest.append("mail-test1-4-2") -argListTest.append(filesPath+"mail-test1-4-2.sauve") +argListTest.append(os.path.join(filesPath,"mail-test1-4-2.sauve")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_porflow_driver") rootFileTest.append("boitenew") -argListTest.append(filesPath+"boitenew.inp") +argListTest.append(os.path.join(filesPath,"boitenew.inp")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_porflow_driver") rootFileTest.append("Case1") -argListTest.append(filesPath+"Case1.inp") +argListTest.append(os.path.join(filesPath,"Case1.inp")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_porflow_driver") rootFileTest.append("cube") -argListTest.append(filesPath+"cube.inp") +argListTest.append(os.path.join(filesPath,"cube.inp")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_porflow_driver") rootFileTest.append("test3") -argListTest.append(filesPath+"test3.inp") +argListTest.append(os.path.join(filesPath,"test3.inp")) meshTest.append("") fieldTest.append("") testExecfiles.append("test_porflow_driver") rootFileTest.append("titi") -argListTest.append(filesPath+"titi.inp") +argListTest.append(os.path.join(filesPath,"titi.inp")) meshTest.append("") fieldTest.append("") @@ -353,241 +356,241 @@ testExecfiles.append("test_copie_connectivity") rootFileTest.append("mesh") meshTest.append("Mesh 1") fieldTest.append("") -argListTest.append(filesPath+"mesh.med" + " " + "'Mesh 1'") +argListTest.append(os.path.join(filesPath,"mesh.med") + " " + "'Mesh 1'") testExecfiles.append("test_copie_connectivity") rootFileTest.append("maillage_UniSegFam") meshTest.append("maillage_CHEMVAL_100elts") fieldTest.append("") -argListTest.append(filesPath+"maillage_UniSegFam.med" + " " + "maillage_CHEMVAL_100elts") +argListTest.append(os.path.join(filesPath,"maillage_UniSegFam.med") + " " + "maillage_CHEMVAL_100elts") testExecfiles.append("test_copie_connectivity") rootFileTest.append("carre_en_quad4") meshTest.append("carre_en_quad4") fieldTest.append("") -argListTest.append(filesPath+"carre_en_quad4.med" + " " + "carre_en_quad4") +argListTest.append(os.path.join(filesPath,"carre_en_quad4.med") + " " + "carre_en_quad4") testExecfiles.append("test_copie_connectivity") rootFileTest.append("cube_hexa8") meshTest.append("CUBE_EN_HEXA8") fieldTest.append("") -argListTest.append(filesPath+"cube_hexa8.med" + " " + "CUBE_EN_HEXA8") +argListTest.append(os.path.join(filesPath,"cube_hexa8.med") + " " + "CUBE_EN_HEXA8") testExecfiles.append("test_copie_connectivity") rootFileTest.append("test19") meshTest.append("maa1") fieldTest.append("") -argListTest.append(filesPath+"test19.med" + " " + "maa1") +argListTest.append(os.path.join(filesPath,"test19.med") + " " + "maa1") testExecfiles.append("test_copie_connectivity") rootFileTest.append("carre_en_quad4_seg2") meshTest.append("carre_en_quad4_seg2") fieldTest.append("") -argListTest.append(filesPath+"carre_en_quad4_seg2.med" + " " + "carre_en_quad4_seg2") +argListTest.append(os.path.join(filesPath,"carre_en_quad4_seg2.med") + " " + "carre_en_quad4_seg2") testExecfiles.append("test_copie_connectivity") rootFileTest.append("cube_hexa8_quad4") meshTest.append("CUBE_EN_HEXA8_QUAD4") fieldTest.append("") -argListTest.append(filesPath+"cube_hexa8_quad4.med" + " " + "CUBE_EN_HEXA8_QUAD4") +argListTest.append(os.path.join(filesPath,"cube_hexa8_quad4.med") + " " + "CUBE_EN_HEXA8_QUAD4") testExecfiles.append("test_copie_connectivity") rootFileTest.append("pointe") meshTest.append("maa1") fieldTest.append("") -argListTest.append(filesPath+"pointe.med" + " " + "maa1") +argListTest.append(os.path.join(filesPath,"pointe.med") + " " + "maa1") testExecfiles.append("test_copie_family") rootFileTest.append("mesh") meshTest.append("Mesh 1") fieldTest.append("") -argListTest.append(filesPath+"mesh.med" + " " + "'Mesh 1'") +argListTest.append(os.path.join(filesPath,"mesh.med") + " " + "'Mesh 1'") testExecfiles.append("test_copie_family") rootFileTest.append("maillage_UniSegFam") meshTest.append("maillage_CHEMVAL_100elts") fieldTest.append("") -argListTest.append(filesPath+"maillage_UniSegFam.med" + " " + "maillage_CHEMVAL_100elts") +argListTest.append(os.path.join(filesPath,"maillage_UniSegFam.med") + " " + "maillage_CHEMVAL_100elts") testExecfiles.append("test_copie_family") rootFileTest.append("carre_en_quad4") meshTest.append("carre_en_quad4") fieldTest.append("") -argListTest.append(filesPath+"carre_en_quad4.med" + " " + "carre_en_quad4") +argListTest.append(os.path.join(filesPath,"carre_en_quad4.med") + " " + "carre_en_quad4") testExecfiles.append("test_copie_family") rootFileTest.append("cube_hexa8") meshTest.append("CUBE_EN_HEXA8") fieldTest.append("") -argListTest.append(filesPath+"cube_hexa8.med" + " " + "CUBE_EN_HEXA8") +argListTest.append(os.path.join(filesPath,"cube_hexa8.med") + " " + "CUBE_EN_HEXA8") testExecfiles.append("test_copie_family") rootFileTest.append("test19") meshTest.append("maa1") fieldTest.append("") -argListTest.append(filesPath+"test19.med" + " " + "maa1") +argListTest.append(os.path.join(filesPath,"test19.med") + " " + "maa1") testExecfiles.append("test_copie_family") rootFileTest.append("carre_en_quad4_seg2") meshTest.append("carre_en_quad4_seg2") fieldTest.append("") -argListTest.append(filesPath+"carre_en_quad4_seg2.med" + " " + "carre_en_quad4_seg2") +argListTest.append(os.path.join(filesPath,"carre_en_quad4_seg2.med") + " " + "carre_en_quad4_seg2") testExecfiles.append("test_copie_family") rootFileTest.append("cube_hexa8_quad4") meshTest.append("CUBE_EN_HEXA8_QUAD4") fieldTest.append("") -argListTest.append(filesPath+"cube_hexa8_quad4.med" + " " + "CUBE_EN_HEXA8_QUAD4") +argListTest.append(os.path.join(filesPath,"cube_hexa8_quad4.med") + " " + "CUBE_EN_HEXA8_QUAD4") testExecfiles.append("test_copie_family") rootFileTest.append("pointe") meshTest.append("maa1") fieldTest.append("") -argListTest.append(filesPath+"pointe.med" + " " + "maa1") +argListTest.append(os.path.join(filesPath,"pointe.med") + " " + "maa1") testExecfiles.append("test_copie_group") rootFileTest.append("mesh") meshTest.append("Mesh 1") fieldTest.append("") -argListTest.append(filesPath+"mesh.med" + " " + "'Mesh 1'") +argListTest.append(os.path.join(filesPath,"mesh.med") + " " + "'Mesh 1'") testExecfiles.append("test_copie_group") rootFileTest.append("maillage_UniSegFam") meshTest.append("maillage_CHEMVAL_100elts") fieldTest.append("") -argListTest.append(filesPath+"maillage_UniSegFam.med" + " " + "maillage_CHEMVAL_100elts") +argListTest.append(os.path.join(filesPath,"maillage_UniSegFam.med") + " " + "maillage_CHEMVAL_100elts") testExecfiles.append("test_copie_group") rootFileTest.append("carre_en_quad4") meshTest.append("carre_en_quad4") fieldTest.append("") -argListTest.append(filesPath+"carre_en_quad4.med" + " " + "carre_en_quad4") +argListTest.append(os.path.join(filesPath,"carre_en_quad4.med") + " " + "carre_en_quad4") testExecfiles.append("test_copie_group") rootFileTest.append("cube_hexa8") meshTest.append("CUBE_EN_HEXA8") fieldTest.append("") -argListTest.append(filesPath+"cube_hexa8.med" + " " + "CUBE_EN_HEXA8") +argListTest.append(os.path.join(filesPath,"cube_hexa8.med") + " " + "CUBE_EN_HEXA8") testExecfiles.append("test_copie_group") rootFileTest.append("test19") meshTest.append("maa1") fieldTest.append("") -argListTest.append(filesPath+"test19.med" + " " + "maa1") +argListTest.append(os.path.join(filesPath,"test19.med") + " " + "maa1") testExecfiles.append("test_copie_group") rootFileTest.append("carre_en_quad4_seg2") meshTest.append("carre_en_quad4_seg2") fieldTest.append("") -argListTest.append(filesPath+"carre_en_quad4_seg2.med" + " " + "carre_en_quad4_seg2") +argListTest.append(os.path.join(filesPath,"carre_en_quad4_seg2.med") + " " + "carre_en_quad4_seg2") testExecfiles.append("test_copie_group") rootFileTest.append("cube_hexa8_quad4") meshTest.append("CUBE_EN_HEXA8_QUAD4") fieldTest.append("") -argListTest.append(filesPath+"cube_hexa8_quad4.med" + " " + "CUBE_EN_HEXA8_QUAD4") +argListTest.append(os.path.join(filesPath,"cube_hexa8_quad4.med") + " " + "CUBE_EN_HEXA8_QUAD4") testExecfiles.append("test_copie_group") rootFileTest.append("pointe") meshTest.append("maa1") fieldTest.append("") -argListTest.append(filesPath+"pointe.med" + " " + "maa1") +argListTest.append(os.path.join(filesPath,"pointe.med") + " " + "maa1") testExecfiles.append("test_copie_mesh") rootFileTest.append("mesh") meshTest.append("Mesh 1") fieldTest.append("") -argListTest.append(filesPath+"mesh.med" + " " + "'Mesh 1'") +argListTest.append(os.path.join(filesPath,"mesh.med") + " " + "'Mesh 1'") testExecfiles.append("test_copie_mesh") rootFileTest.append("maillage_UniSegFam") meshTest.append("maillage_CHEMVAL_100elts") fieldTest.append("") -argListTest.append(filesPath+"maillage_UniSegFam.med" + " " + "maillage_CHEMVAL_100elts") +argListTest.append(os.path.join(filesPath,"maillage_UniSegFam.med") + " " + "maillage_CHEMVAL_100elts") testExecfiles.append("test_copie_mesh") rootFileTest.append("carre_en_quad4") meshTest.append("carre_en_quad4") fieldTest.append("") -argListTest.append(filesPath+"carre_en_quad4.med" + " " + "carre_en_quad4") +argListTest.append(os.path.join(filesPath,"carre_en_quad4.med") + " " + "carre_en_quad4") testExecfiles.append("test_copie_mesh") rootFileTest.append("cube_hexa8") meshTest.append("CUBE_EN_HEXA8") fieldTest.append("") -argListTest.append(filesPath+"cube_hexa8.med" + " " + "CUBE_EN_HEXA8") +argListTest.append(os.path.join(filesPath,"cube_hexa8.med") + " " + "CUBE_EN_HEXA8") testExecfiles.append("test_copie_mesh") rootFileTest.append("test19") meshTest.append("maa1") fieldTest.append("") -argListTest.append(filesPath+"test19.med" + " " + "maa1") +argListTest.append(os.path.join(filesPath,"test19.med") + " " + "maa1") testExecfiles.append("test_copie_mesh") rootFileTest.append("carre_en_quad4_seg2") meshTest.append("carre_en_quad4_seg2") fieldTest.append("") -argListTest.append(filesPath+"carre_en_quad4_seg2.med" + " " + "carre_en_quad4_seg2") +argListTest.append(os.path.join(filesPath,"carre_en_quad4_seg2.med") + " " + "carre_en_quad4_seg2") testExecfiles.append("test_copie_mesh") rootFileTest.append("cube_hexa8_quad4") meshTest.append("CUBE_EN_HEXA8_QUAD4") fieldTest.append("") -argListTest.append(filesPath+"cube_hexa8_quad4.med" + " " + "CUBE_EN_HEXA8_QUAD4") +argListTest.append(os.path.join(filesPath,"cube_hexa8_quad4.med") + " " + "CUBE_EN_HEXA8_QUAD4") testExecfiles.append("test_copie_mesh") rootFileTest.append("pointe") meshTest.append("maa1") fieldTest.append("") -argListTest.append(filesPath+"pointe.med" + " " + "maa1") +argListTest.append(os.path.join(filesPath,"pointe.med") + " " + "maa1") testExecfiles.append("test_copie_support") rootFileTest.append("mesh") meshTest.append("Mesh 1") fieldTest.append("") -argListTest.append(filesPath+"mesh.med" + " " + "'Mesh 1'") +argListTest.append(os.path.join(filesPath,"mesh.med") + " " + "'Mesh 1'") testExecfiles.append("test_copie_support") rootFileTest.append("maillage_UniSegFam") meshTest.append("maillage_CHEMVAL_100elts") fieldTest.append("") -argListTest.append(filesPath+"maillage_UniSegFam.med" + " " + "maillage_CHEMVAL_100elts") +argListTest.append(os.path.join(filesPath,"maillage_UniSegFam.med") + " " + "maillage_CHEMVAL_100elts") testExecfiles.append("test_copie_support") rootFileTest.append("carre_en_quad4") meshTest.append("carre_en_quad4") fieldTest.append("") -argListTest.append(filesPath+"carre_en_quad4.med" + " " + "carre_en_quad4") +argListTest.append(os.path.join(filesPath,"carre_en_quad4.med") + " " + "carre_en_quad4") testExecfiles.append("test_copie_support") rootFileTest.append("cube_hexa8") meshTest.append("CUBE_EN_HEXA8") fieldTest.append("") -argListTest.append(filesPath+"cube_hexa8.med" + " " + "CUBE_EN_HEXA8") +argListTest.append(os.path.join(filesPath,"cube_hexa8.med") + " " + "CUBE_EN_HEXA8") testExecfiles.append("test_copie_support") rootFileTest.append("test19") meshTest.append("maa1") fieldTest.append("") -argListTest.append(filesPath+"test19.med" + " " + "maa1") +argListTest.append(os.path.join(filesPath,"test19.med") + " " + "maa1") testExecfiles.append("test_copie_support") rootFileTest.append("carre_en_quad4_seg2") meshTest.append("carre_en_quad4_seg2") fieldTest.append("") -argListTest.append(filesPath+"carre_en_quad4_seg2.med" + " " + "carre_en_quad4_seg2") +argListTest.append(os.path.join(filesPath,"carre_en_quad4_seg2.med") + " " + "carre_en_quad4_seg2") testExecfiles.append("test_copie_support") rootFileTest.append("cube_hexa8_quad4") meshTest.append("CUBE_EN_HEXA8_QUAD4") fieldTest.append("") -argListTest.append(filesPath+"cube_hexa8_quad4.med" + " " + "CUBE_EN_HEXA8_QUAD4") +argListTest.append(os.path.join(filesPath,"cube_hexa8_quad4.med") + " " + "CUBE_EN_HEXA8_QUAD4") testExecfiles.append("test_copie_support") rootFileTest.append("pointe") meshTest.append("maa1") fieldTest.append("") -argListTest.append(filesPath+"pointe.med" + " " + "maa1") +argListTest.append(os.path.join(filesPath,"pointe.med") + " " + "maa1") ############################################################################### diff --git a/src/MEDMEM_SWIG/testMedMemGeneral.py b/src/MEDMEM_SWIG/testMedMemGeneral.py index af523a014..1ae3b74e6 100755 --- a/src/MEDMEM_SWIG/testMedMemGeneral.py +++ b/src/MEDMEM_SWIG/testMedMemGeneral.py @@ -1,43 +1,49 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# -################################################################################### +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +################################################################################### # This Python script is testing all functionalities of the Med Memory through its # Python API; for this purpose a battery of med file as well as gibi files are # scanned using the parser written in the Python script med_test1.py with some # addings to test other functionality written in othe Python scripts in the bin # directory of the installation of MED -# ################################################################################### - +# from libMEDMEM_Swig import * from random import * import sys,os,string -filesPath=os.environ["MED_ROOT_DIR"] -filesPath=filesPath+"/share/salome/resources/med/" +filesPath = os.environ["MED_ROOT_DIR"] +filesPath = os.path.join(filesPath, "share", "salome", "resources", "med") -os.system("rm -rf "+filesPath+"*_test.*") +tmpDir = os.getenv("TEMP") +if tmpDir == None: + tmpDir = "/tmp" -files = [] -meshNameFiles = [] +tmpMask = os.path.join(tmpDir, "*_test.*") +os.system("rm -rf " + tmpMask) + +fileNames = [] +meshNames = [] def print_ord(i): if i == 0: @@ -63,162 +69,168 @@ def add_one(i): # from CODE_ASTER # -##files.append("maill.0.med") -##meshNameFiles.append("MAILTRQU") +##fileNames.append("maill.0.med") +##meshNames.append("MAILTRQU") -##files.append("zzzz121b.med") -##meshNameFiles.append("MUN") +##fileNames.append("zzzz121b.med") +##meshNames.append("MUN") # # from the SMESH Salome Module # -files.append("mesh.med") -meshNameFiles.append("Mesh 1") +fileNames.append("mesh.med") +meshNames.append("Mesh 1") -files.append("mesh_import22.med") -meshNameFiles.append("Mesh 1") +fileNames.append("mesh_import22.med") +meshNames.append("Mesh 1") # # from other source including LGLS ones # -files.append("maillage_UniSegFam.med") -meshNameFiles.append("maillage_CHEMVAL_100elts") +fileNames.append("maillage_UniSegFam.med") +meshNames.append("maillage_CHEMVAL_100elts") -files.append("maillage_UniSegFam_import22.med") -meshNameFiles.append("maillage_CHEMVAL_100elts") +fileNames.append("maillage_UniSegFam_import22.med") +meshNames.append("maillage_CHEMVAL_100elts") -files.append("carre_en_quad4.med") -meshNameFiles.append("carre_en_quad4") +fileNames.append("carre_en_quad4.med") +meshNames.append("carre_en_quad4") -files.append("carre_en_quad4_import22.med") -meshNameFiles.append("carre_en_quad4") +fileNames.append("carre_en_quad4_import22.med") +meshNames.append("carre_en_quad4") -files.append("cube_hexa8.med") -meshNameFiles.append("CUBE_EN_HEXA8") +fileNames.append("cube_hexa8.med") +meshNames.append("CUBE_EN_HEXA8") -files.append("cube_hexa8_import22.med") -meshNameFiles.append("CUBE_EN_HEXA8") +fileNames.append("cube_hexa8_import22.med") +meshNames.append("CUBE_EN_HEXA8") -##files.append("test19.med") -##meshNameFiles.append("CartGrid") +##fileNames.append("test19.med") +##meshNames.append("CartGrid") -##files.append("test19.med") -##meshNameFiles.append("bodyfitted") +##fileNames.append("test19.med") +##meshNames.append("bodyfitted") -##files.append("test19.med") -##meshNameFiles.append("maa1") +##fileNames.append("test19.med") +##meshNames.append("maa1") -files.append("carre_en_quad4_seg2.med") -meshNameFiles.append("carre_en_quad4_seg2") +fileNames.append("carre_en_quad4_seg2.med") +meshNames.append("carre_en_quad4_seg2") -files.append("carre_en_quad4_seg2_import22.med") -meshNameFiles.append("carre_en_quad4_seg2") +fileNames.append("carre_en_quad4_seg2_import22.med") +meshNames.append("carre_en_quad4_seg2") -files.append("cube_hexa8_quad4.med") -meshNameFiles.append("CUBE_EN_HEXA8_QUAD4") +fileNames.append("cube_hexa8_quad4.med") +meshNames.append("CUBE_EN_HEXA8_QUAD4") -files.append("cube_hexa8_quad4_import22.med") -meshNameFiles.append("CUBE_EN_HEXA8_QUAD4") +fileNames.append("cube_hexa8_quad4_import22.med") +meshNames.append("CUBE_EN_HEXA8_QUAD4") -files.append("pointe.med") -meshNameFiles.append("maa1") +fileNames.append("pointe.med") +meshNames.append("maa1") -files.append("pointe_import22.med") -meshNameFiles.append("maa1") +fileNames.append("pointe_import22.med") +meshNames.append("maa1") -files.append("Mistrat.med") -meshNameFiles.append("Mistrat_Hexa") +fileNames.append("Mistrat.med") +meshNames.append("Mistrat_Hexa") -files.append("Mistrat_import22.med") -meshNameFiles.append("Mistrat_Hexa") +fileNames.append("Mistrat_import22.med") +meshNames.append("Mistrat_Hexa") -##files.append("TimeStamps.med") -##meshNameFiles.append("dom") +##fileNames.append("TimeStamps.med") +##meshNames.append("dom") -files.append("Darcy3_3D_H_10x10x10_2.med") -meshNameFiles.append("Darcy3_3D_H_10x10x10") +fileNames.append("Darcy3_3D_H_10x10x10_2.med") +meshNames.append("Darcy3_3D_H_10x10x10") -files.append("elle_3D_HPr_10x10x10_2.med") -meshNameFiles.append("elle_3D_HPr_10x10x10") +fileNames.append("elle_3D_HPr_10x10x10_2.med") +meshNames.append("elle_3D_HPr_10x10x10") -files.append("elle_3D_HPr_2x2x2_2.med") -meshNameFiles.append("elle_3D_HPr_2x2x2") +fileNames.append("elle_3D_HPr_2x2x2_2.med") +meshNames.append("elle_3D_HPr_2x2x2") -files.append("elle_3D_HPr_4x4x4_2.med") -meshNameFiles.append("elle_3D_HPr_4x4x4") +fileNames.append("elle_3D_HPr_4x4x4_2.med") +meshNames.append("elle_3D_HPr_4x4x4") -files.append("ChampsDarcy.med") -meshNameFiles.append("2D_I129") +fileNames.append("ChampsDarcy.med") +meshNames.append("2D_I129") -files.append("darcy_1.1_res.med") -meshNameFiles.append("mail_test1-1-tri") +fileNames.append("darcy_1.1_res.med") +meshNames.append("mail_test1-1-tri") -files.append("darcy_1.3_resCASTEM.med") -meshNameFiles.append("mail_ktest1-3-tetra") +fileNames.append("darcy_1.3_resCASTEM.med") +meshNames.append("mail_ktest1-3-tetra") -files.append("darcy_1.3_resPORFLOW.med") -meshNameFiles.append("mail_ktest1-3-hexa") +fileNames.append("darcy_1.3_resPORFLOW.med") +meshNames.append("mail_ktest1-3-hexa") -files.append("darcy_1.3_resTRACES.med") -meshNameFiles.append("mail_ktest1-3-tetra") +fileNames.append("darcy_1.3_resTRACES.med") +meshNames.append("mail_ktest1-3-tetra") -files.append("darcy2_Castem_EFMH.med") -meshNameFiles.append("mail_test1-2-tri") +fileNames.append("darcy2_Castem_EFMH.med") +meshNames.append("mail_test1-2-tri") -files.append("darcy2_Castem_qua_EFMH.med") -meshNameFiles.append("mail_test1-2-qua") +fileNames.append("darcy2_Castem_qua_EFMH.med") +meshNames.append("mail_test1-2-qua") -files.append("darcy2_Castem_qua_VF.med") -meshNameFiles.append("mail_test1-2-qua") +fileNames.append("darcy2_Castem_qua_VF.med") +meshNames.append("mail_test1-2-qua") -files.append("Deff_fdt_5.8_castem_efmh_diff_conc_dom.med") -meshNameFiles.append("maillage_deffec_fdt") +# there is a field with too long name (38 > MED_TAILLE_NOM==32): +# "analytical_field - CONCENTRATION of A1" +# so that invalid writing is sometimes fatal +# fileNames.append("Deff_fdt_5.8_castem_efmh_diff_conc_dom.med") +# meshNames.append("maillage_deffec_fdt") -files.append("Deff_fdt_5.8_castem_vf_diff_conc_dom.med") -meshNameFiles.append("maillage_deffec_fdt") +# there is a field with too long name (38 > MED_TAILLE_NOM==32): +# "analytical_field - CONCENTRATION of A1" +# so that invalid writing is sometimes fatal +# fileNames.append("Deff_fdt_5.8_castem_vf_diff_conc_dom.med") +# meshNames.append("maillage_deffec_fdt") -files.append("extendedtransport53_triangles.med") -meshNameFiles.append("TestA3_2094_0.1_rsurf_tri") +fileNames.append("extendedtransport53_triangles.med") +meshNames.append("TestA3_2094_0.1_rsurf_tri") -files.append("H_CastCast_EFMH_I129_COUPLEX1.med") -meshNameFiles.append("COUPLEX1") +fileNames.append("H_CastCast_EFMH_I129_COUPLEX1.med") +meshNames.append("COUPLEX1") -files.append("H_CastCast_VF_I129_COUPLEX1.med") -meshNameFiles.append("COUPLEX1") +fileNames.append("H_CastCast_VF_I129_COUPLEX1.med") +meshNames.append("COUPLEX1") -files.append("H_CastCast_VF_Se79_COUPLEX1.med") -meshNameFiles.append("COUPLEX1") +fileNames.append("H_CastCast_VF_Se79_COUPLEX1.med") +meshNames.append("COUPLEX1") -files.append("H_CastPorf_I129_COUPLEX1.med") -meshNameFiles.append("COUPLEX1") +fileNames.append("H_CastPorf_I129_COUPLEX1.med") +meshNames.append("COUPLEX1") -files.append("H_CastPorf_Se79_COUPLEX1.med") -meshNameFiles.append("COUPLEX1") +fileNames.append("H_CastPorf_Se79_COUPLEX1.med") +meshNames.append("COUPLEX1") -files.append("H_PorfCast_EFMH_I129_COUPLEX1.med") -meshNameFiles.append("COUPLEX1") +fileNames.append("H_PorfCast_EFMH_I129_COUPLEX1.med") +meshNames.append("COUPLEX1") -files.append("H_PorfCast_EFMH_Se79_COUPLEX1.med") -meshNameFiles.append("COUPLEX1") +fileNames.append("H_PorfCast_EFMH_Se79_COUPLEX1.med") +meshNames.append("COUPLEX1") -files.append("H_PorfPorf_I129_COUPLEX1.med") -meshNameFiles.append("COUPLEX1") +fileNames.append("H_PorfPorf_I129_COUPLEX1.med") +meshNames.append("COUPLEX1") -files.append("H_Traces_I129_COUPLEX1.med") -meshNameFiles.append("COUPLEX1") +fileNames.append("H_Traces_I129_COUPLEX1.med") +meshNames.append("COUPLEX1") -files.append("H_Traces_Se79_COUPLEX1.med") -meshNameFiles.append("COUPLEX1") +fileNames.append("H_Traces_Se79_COUPLEX1.med") +meshNames.append("COUPLEX1") -files.append("maillage_5_5_5.med") -meshNameFiles.append("maillage_5_5_5") +fileNames.append("maillage_5_5_5.med") +meshNames.append("maillage_5_5_5") -files.append("maillage_chemvalIV_cas1_40elts.med") -meshNameFiles.append("maillage_chemvalIV_cas1_40elts") +fileNames.append("maillage_chemvalIV_cas1_40elts.med") +meshNames.append("maillage_chemvalIV_cas1_40elts") @@ -227,115 +239,116 @@ meshNameFiles.append("maillage_chemvalIV_cas1_40elts") # Castem or Gibi file list # -files.append("Darcy3_3D_H_10x10x10.sauve") -meshNameFiles.append("") +fileNames.append("Darcy3_3D_H_10x10x10.sauve") +meshNames.append("") -files.append("dx200_dy1_avec_2couches.sauve") -meshNameFiles.append("") +fileNames.append("dx200_dy1_avec_2couches.sauve") +meshNames.append("") -files.append("elle_2D_QT_10x10.sauve") -meshNameFiles.append("") +fileNames.append("elle_2D_QT_10x10.sauve") +meshNames.append("") -files.append("elle_2D_QT_2x2.sauve") -meshNameFiles.append("") +fileNames.append("elle_2D_QT_2x2.sauve") +meshNames.append("") -files.append("elle_2D_QT_40x40.sauve") -meshNameFiles.append("") +fileNames.append("elle_2D_QT_40x40.sauve") +meshNames.append("") -files.append("elle_2D_QT_4x4.sauve") -meshNameFiles.append("") +fileNames.append("elle_2D_QT_4x4.sauve") +meshNames.append("") -files.append("elle_3D_HPr_10x10x10.sauve") -meshNameFiles.append("") +fileNames.append("elle_3D_HPr_10x10x10.sauve") +meshNames.append("") -files.append("elle_3D_HPr_2x2x2.sauve") -meshNameFiles.append("") +fileNames.append("elle_3D_HPr_2x2x2.sauve") +meshNames.append("") -files.append("elle_3D_HPr_4x4x4.sauve") -meshNameFiles.append("") +fileNames.append("elle_3D_HPr_4x4x4.sauve") +meshNames.append("") -files.append("inclusion_2d_raf.sauve") -meshNameFiles.append("") +fileNames.append("inclusion_2d_raf.sauve") +meshNames.append("") -files.append("inclusion_2d.sauve") -meshNameFiles.append("") +fileNames.append("inclusion_2d.sauve") +meshNames.append("") -files.append("mail_ktest1-3-hexa.sauve") -meshNameFiles.append("") +fileNames.append("mail_ktest1-3-hexa.sauve") +meshNames.append("") -files.append("mail_ktest1-3-tetra.sauve") -meshNameFiles.append("") +fileNames.append("mail_ktest1-3-tetra.sauve") +meshNames.append("") -files.append("mail_ktest3-1.sauve") -meshNameFiles.append("") +fileNames.append("mail_ktest3-1.sauve") +meshNames.append("") -files.append("mail_ktest3-2.sauve") -meshNameFiles.append("") +fileNames.append("mail_ktest3-2.sauve") +meshNames.append("") -files.append("maillage_andra2_100elts.sauve") -meshNameFiles.append("") +fileNames.append("maillage_andra2_100elts.sauve") +meshNames.append("") -files.append("maillage_cas2_2d.sauve") -meshNameFiles.append("") +fileNames.append("maillage_cas2_2d.sauve") +meshNames.append("") -files.append("maillage_cas4_234elts.sauve") -meshNameFiles.append("") +fileNames.append("maillage_cas4_234elts.sauve") +meshNames.append("") -files.append("maillage_CHEMVAL_100elts.sauve") -meshNameFiles.append("") +fileNames.append("maillage_CHEMVAL_100elts.sauve") +meshNames.append("") -files.append("maillage_CHEMVAL_40elts.sauve") -meshNameFiles.append("") +fileNames.append("maillage_CHEMVAL_40elts.sauve") +meshNames.append("") -files.append("maillage_chemvalIV_cas1_100elts.sauve") -meshNameFiles.append("") +fileNames.append("maillage_chemvalIV_cas1_100elts.sauve") +meshNames.append("") -files.append("maillage_chemvalIV_cas1_40elts.sauve") -meshNameFiles.append("") +fileNames.append("maillage_chemvalIV_cas1_40elts.sauve") +meshNames.append("") -files.append("mail_test1-1-qua.sauve") -meshNameFiles.append("") +fileNames.append("mail_test1-1-qua.sauve") +meshNames.append("") -files.append("mail_test1-1-tri.sauve") -meshNameFiles.append("") +fileNames.append("mail_test1-1-tri.sauve") +meshNames.append("") -files.append("mail_test1-2-qua.sauve") -meshNameFiles.append("") +fileNames.append("mail_test1-2-qua.sauve") +meshNames.append("") -files.append("mail_test1-2-tri.sauve") -meshNameFiles.append("") +fileNames.append("mail_test1-2-tri.sauve") +meshNames.append("") -files.append("mail-test1-4-1.sauve") -meshNameFiles.append("") +fileNames.append("mail-test1-4-1.sauve") +meshNames.append("") -files.append("mail-test1-4-2.sauve") -meshNameFiles.append("") +fileNames.append("mail-test1-4-2.sauve") +meshNames.append("") # # Porflow file list # -files.append("boitenew.inp") -meshNameFiles.append("") +fileNames.append("boitenew.inp") +meshNames.append("") -files.append("Case1.inp") -meshNameFiles.append("") +fileNames.append("Case1.inp") +meshNames.append("") -files.append("cube.inp") -meshNameFiles.append("") +fileNames.append("cube.inp") +meshNames.append("") -files.append("test3.inp") -meshNameFiles.append("") +fileNames.append("test3.inp") +meshNames.append("") -files.append("titi.inp") -meshNameFiles.append("") +fileNames.append("titi.inp") +meshNames.append("") ################################################################################### -nbOfFiles = len(files) +nbOfFiles = len(fileNames) +filesFull = [] for i in range(nbOfFiles): - files[i] = filesPath + files[i] + filesFull.append(os.path.join(filesPath, fileNames[i])) ################################################################################### # @@ -347,12 +360,13 @@ print " This test is running on ",nbOfFiles," files" print "" for i in range(nbOfFiles): - file = files[i] - decompFile = string.split(file,".") + fileName = fileNames[i] + fileFull = filesFull[i] + decompFile = string.split(fileName,".") lenDecompFileM1 = len(decompFile)-1 if (lenDecompFileM1 == 0) : - print "The file ",file," should have at least a . in its name " + print "The file ",fileName," should have at least a . in its name " sys.exit(1) extensionFile = decompFile[lenDecompFileM1] @@ -361,46 +375,48 @@ for i in range(nbOfFiles): for k in range(1,lenDecompFileM1): rootFile = rootFile + "." + decompFile[k] - medV21FileName = rootFile + "V21_test.med" - medV22FileName = rootFile + "V22_test.med" - vtkFileName = rootFile + "_test.vtk" + rootFileFull = os.path.join(tmpDir, rootFile) + + medV21FileName = rootFileFull + "V21_test.med" + medV22FileName = rootFileFull + "V22_test.med" + vtkFileName = rootFileFull + "_test.vtk" try: mesh = MESH() if (extensionFile == "med"): - print "The file ",file," is a MED file and the name of the mesh is ", meshNameFiles[i] - meshDriver = MED_MESH_RDONLY_DRIVER(file,mesh) - meshDriver.setMeshName(meshNameFiles[i]) + print "The file ",fileName," is a MED file and the name of the mesh is ", meshNames[i] + meshDriver = MED_MESH_RDONLY_DRIVER(fileFull,mesh) + meshDriver.setMeshName(meshNames[i]) elif (extensionFile == "sauve"): - print "The file ",file," is a GIBI file" - meshDriver = GIBI_MESH_RDONLY_DRIVER(file,mesh) + print "The file ",fileName," is a GIBI file" + meshDriver = GIBI_MESH_RDONLY_DRIVER(fileFull,mesh) elif (extensionFile == "inp"): - print "The file ",file," is a PORFLOW file" - meshDriver = PORFLOW_MESH_RDONLY_DRIVER(file,mesh) + print "The file ",fileName," is a PORFLOW file" + meshDriver = PORFLOW_MESH_RDONLY_DRIVER(fileFull,mesh) else : - print "the file ",file,"has an unknow extension" + print "the file ",fileName,"has an unknow extension" sys.exit(1) meshDriver.open() meshDriver.read() except: meshDriver.close() - print "The mesh stored in the file ",file," is perhaps a GRID." + print "The mesh stored in the file ",fileName," is perhaps a GRID." try: print "... of MED_CARTESIAN type ?" type = MED_CARTESIAN mesh = GRID() mesh.setGridType(type) if (extensionFile == "med"): - meshDriver = MED_MESH_RDONLY_DRIVER(file,mesh) - meshDriver.setMeshName(meshNameFiles[i]) + meshDriver = MED_MESH_RDONLY_DRIVER(fileFull,mesh) + meshDriver.setMeshName(meshNames[i]) elif (extensionFile == "sauve"): - meshDriver = GIBI_MESH_RDONLY_DRIVER(file,mesh) + meshDriver = GIBI_MESH_RDONLY_DRIVER(fileFull,mesh) elif (extensionFile == "inp"): - print "The file ",file," is a PORFLOW file" - meshDriver = PORFLOW_MESH_RDONLY_DRIVER(file,mesh) + print "The file ",fileName," is a PORFLOW file" + meshDriver = PORFLOW_MESH_RDONLY_DRIVER(fileFull,mesh) else : - print "the file ",file,"has an unknow extension" + print "the file ",fileName,"has an unknow extension" sys.exit(1) meshDriver.open() @@ -413,12 +429,12 @@ for i in range(nbOfFiles): type = MED_POLAR mesh.setGridType(type) if (extensionFile == "med"): - meshDriver = MED_MESH_RDONLY_DRIVER(file,mesh) - meshDriver.setMeshName(meshNameFiles[i]) + meshDriver = MED_MESH_RDONLY_DRIVER(fileFull,mesh) + meshDriver.setMeshName(meshNames[i]) elif (extensionFile == "sauve"): - meshDriver = GIBI_MESH_RDONLY_DRIVER(file,mesh) + meshDriver = GIBI_MESH_RDONLY_DRIVER(fileFull,mesh) else : - print "the file ",file,"has an unknow extension" + print "the file ",fileName,"has an unknow extension" sys.exit(1) meshDriver.open() @@ -430,12 +446,12 @@ for i in range(nbOfFiles): type = MED_BODY_FITTED mesh.setGridType(type) if (extensionFile == "med"): - meshDriver = MED_MESH_RDONLY_DRIVER(file,mesh) - meshDriver.setMeshName(meshNameFiles[i]) + meshDriver = MED_MESH_RDONLY_DRIVER(fileFull,mesh) + meshDriver.setMeshName(meshNames[i]) elif (extensionFile == "sauve"): - meshDriver = GIBI_MESH_RDONLY_DRIVER(file,mesh) + meshDriver = GIBI_MESH_RDONLY_DRIVER(fileFull,mesh) else : - print "the file ",file,"has an unknow extension" + print "the file ",fileName,"has an unknow extension" sys.exit(1) meshDriver.open() @@ -667,13 +683,13 @@ for i in range(nbOfFiles): if (medFileVersion == V22): setMedFileVersionForWriting(V21) - idMedV21 = mesh.addDriver(MED_DRIVER,medV21FileName,mesh.getName(),MED_REMP) + idMedV21 = mesh.addDriver(MED_DRIVER,medV21FileName,mesh.getName(),RDWR) mesh.write(idMedV21) if (medFileVersion == V21): setMedFileVersionForWriting(V22) - idMedV22 = mesh.addDriver(MED_DRIVER,medV22FileName,mesh.getName(),MED_REMP) + idMedV22 = mesh.addDriver(MED_DRIVER,medV22FileName,mesh.getName(),RDWR) mesh.write(idMedV22) idVtk = mesh.addDriver(VTK_DRIVER,vtkFileName,mesh.getName()) @@ -785,7 +801,7 @@ for i in range(nbOfFiles): idMedV22 = normal.addDriver(MED_DRIVER,medV22FileName,normal.getName()) normal.write(idMedV22) - + print "but not in vtk format because vtk does not offer the possibility to view a field on edges or faces" print "" @@ -798,7 +814,7 @@ for i in range(nbOfFiles): print " * ",areaCell areatot = areatot + areaCell print "Area of the mesh:",areatot - print "" + print "" print "Saving in file the cell area field under the med and vtk format" medFileVersion = getMedFileVersionForWriting() @@ -862,7 +878,7 @@ for i in range(nbOfFiles): idMedV22 = normal.addDriver(MED_DRIVER,medV22FileName,normal.getName()) normal.write(idMedV22) - + print "but no in vtk format because vtk does not offer the possibility to view a field on edges or faces" print "" @@ -899,7 +915,7 @@ for i in range(nbOfFiles): if (extensionFile == "med"): md = MED() - mdDriver = MED_MED_RDONLY_DRIVER(file,md) + mdDriver = MED_MED_RDONLY_DRIVER(fileFull,md) mdDriver.open() mdDriver.readFileStruct() @@ -907,7 +923,7 @@ for i in range(nbOfFiles): nbMeshes = md.getNumberOfMeshes() nbFields = md.getNumberOfFields() - print "The med file", file, "contains", nbMeshes, "mesh(es) and", nbFields, "field(s)" + print "The med file", fileName, "contains", nbMeshes, "mesh(es) and", nbFields, "field(s)" if (nbMeshes>0): print "Mesh(es) Name(s) is(are) " @@ -926,7 +942,7 @@ for i in range(nbOfFiles): print "" # mesh_name = md.getMeshName(0) - mesh_name = meshNameFiles[i] + mesh_name = meshNames[i] mesh = md.getMesh(mesh_name) mesh.read() spaceDim = mesh.getSpaceDimension() @@ -1343,7 +1359,7 @@ for i in range(nbOfFiles): print " *",valueI[:nbOfComp] except: print "testMedMemGeneral fielddoublediv = fielddouble / fielddouble2 catch/except error" - + print "" print "TESTS OPERATIONS SUR FIELDDOUBLE : " fielddoublesub = fielddouble-fielddouble2 diff --git a/src/MEDMEM_SWIG/testMedObj.py b/src/MEDMEM_SWIG/testMedObj.py index 4a00a63be..813e51b9b 100755 --- a/src/MEDMEM_SWIG/testMedObj.py +++ b/src/MEDMEM_SWIG/testMedObj.py @@ -1,32 +1,32 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# -################################################################################### +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 # +################################################################################### # This Python script is testing the mounting in memory of a med file, # via the object MED and the writing of this object MED in Med file format # V2.1 V2.2 -# # Then from the 2 file produced before, a mounting and a writing of those files in # different Med file format is tested -# ################################################################################### - +# from libMEDMEM_Swig import * import string import os @@ -34,11 +34,11 @@ import os #befor running this script, please be sure about the path the files # filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") medFile = "pointe.med" -medFile = filePath + medFile +medFile = os.path.join(filePath, medFile) rootFile = string.split(medFile,".")[0] medFileOut21 = rootFile + "_Out21.med" medFileOut22 = rootFile + "_Out22.med" diff --git a/src/MEDMEM_SWIG/testWriteAndFam.py b/src/MEDMEM_SWIG/testWriteAndFam.py index 4e745c8af..50ffcff87 100755 --- a/src/MEDMEM_SWIG/testWriteAndFam.py +++ b/src/MEDMEM_SWIG/testWriteAndFam.py @@ -1,29 +1,29 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# -################################################################################### +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# This Python script is testing the writing in Med format V2.1 V2.2 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# You can check if the analysis of the families is OK. +# 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. +# +# 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 # ################################################################################### - +# This Python script is testing the writing in Med format V2.1 V2.2 +# You can check if the analysis of the families is OK. +################################################################################### +# from libMEDMEM_Swig import * import string import os @@ -31,7 +31,7 @@ import os #befor running this script, please be sure about the path the files # filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") medFiles = [] medFiles.append("geomMesh21.med") @@ -40,7 +40,7 @@ nbOfFiles = len(medFiles) for i in range(nbOfFiles): medFile = medFiles[i] - medFile = filePath + medFile + medFile = os.path.join( filePath, medFile ) medFiles[i] = medFile pass diff --git a/src/MEDMEM_SWIG/test_gibi.py b/src/MEDMEM_SWIG/test_gibi.py index 0be3e8966..425349dcc 100644 --- a/src/MEDMEM_SWIG/test_gibi.py +++ b/src/MEDMEM_SWIG/test_gibi.py @@ -1,26 +1,27 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# -################################################################################### +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 # ################################################################################### - +################################################################################### +# from libMEDMEM_Swig import * from random import * import string @@ -29,11 +30,11 @@ import os #befor running this script, please be sure about the path the file fileName # filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") gibiFile = "elle_2D_QT_2x2.sauve" mesh1Name = string.split(gibiFile,".")[0]+"_fromGibiDriver" -gibiFile = filePath + gibiFile +gibiFile = os.path.join(filePath, gibiFile) medFile = string.split(gibiFile,".")[0]+"_fromGibiDriver.med" vtkFile = string.split(gibiFile,".")[0]+"_fromGibiDriver.vtk" mesh2Name = mesh1Name diff --git a/src/MEDMEM_SWIG/test_porflow.py b/src/MEDMEM_SWIG/test_porflow.py index c5a84e834..a6f51cc3d 100644 --- a/src/MEDMEM_SWIG/test_porflow.py +++ b/src/MEDMEM_SWIG/test_porflow.py @@ -1,26 +1,27 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# -################################################################################### +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 # ################################################################################### - +################################################################################### +# from libMEDMEM_Swig import * from random import * import string @@ -29,11 +30,11 @@ import os #befor running this script, please be sure about the path the file fileName # filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") porflowFile = "boitenew.inp" mesh1Name = string.split(porflowFile,".")[0]+"_fromPorflowDriver" -porflowFile = filePath + porflowFile +porflowFile = os.path.join(filePath, porflowFile) medFile = string.split(porflowFile,".")[0]+"_fromPorflowDriver.med" vtkFile = string.split(porflowFile,".")[0]+"_fromPorflowDriver.vtk" mesh2Name = mesh1Name diff --git a/src/MEDMEM_SWIG/test_profil_MedFieldDriver.py b/src/MEDMEM_SWIG/test_profil_MedFieldDriver.py index 6f9e9d5a9..27008bec1 100644 --- a/src/MEDMEM_SWIG/test_profil_MedFieldDriver.py +++ b/src/MEDMEM_SWIG/test_profil_MedFieldDriver.py @@ -1,28 +1,29 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# -############################################################################ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +############################################################################ # this Python script is testing the profil functionality using the FIELD # constructor via a MED driver. -# ############################################################################ - +# from libMEDMEM_Swig import * # users inputs @@ -50,9 +51,9 @@ import os #befor running this script, please be sure about the path the file fileName # filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") -medFile = filePath + medFile +medFile = os.path.join(filePath, medFile) def analyseField(field): fieldName = field.getName() diff --git a/src/MEDSPLITTER/MEDSPLITTER.hxx b/src/MEDSPLITTER/MEDSPLITTER.hxx index 1ea1cf44f..5d6cf46d6 100755 --- a/src/MEDSPLITTER/MEDSPLITTER.hxx +++ b/src/MEDSPLITTER/MEDSPLITTER.hxx @@ -1,28 +1,26 @@ -// Copyright (C) 2003 OPEN CASCADE -// -// 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. -// -// 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 +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 // // File : MEDSPLITTER.hxx // Author : Alexander A. BORODIN // Module : MED // Exporting/Importing defines for Windows Platform - +// #ifndef MEDSPLITTER_HXX_ #define MEDSPLITTER_HXX_ diff --git a/src/MEDSPLITTER/MEDSPLITTER_API.cxx b/src/MEDSPLITTER/MEDSPLITTER_API.cxx index 885c9bf94..afb2884c8 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_API.cxx +++ b/src/MEDSPLITTER/MEDSPLITTER_API.cxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// /*! * API for the MEDSPLITTER tool * diff --git a/src/MEDSPLITTER/MEDSPLITTER_API.hxx b/src/MEDSPLITTER/MEDSPLITTER_API.hxx index 35238762b..45db73d95 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_API.hxx +++ b/src/MEDSPLITTER/MEDSPLITTER_API.hxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #ifndef MEDSPLITTER_API_HXX_ #define MEDSPLITTER_API_HXX_ diff --git a/src/MEDSPLITTER/MEDSPLITTER_FaceModel.hxx b/src/MEDSPLITTER/MEDSPLITTER_FaceModel.hxx index 4f82cc105..63fa824c2 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_FaceModel.hxx +++ b/src/MEDSPLITTER/MEDSPLITTER_FaceModel.hxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #ifndef MEDSPLITTER_FACEMODEL_HXX_ #define MEDSPLITTER_FACEMODEL_HXX_ diff --git a/src/MEDSPLITTER/MEDSPLITTER_Graph.cxx b/src/MEDSPLITTER/MEDSPLITTER_Graph.cxx index e0c2ea911..a731ef0f9 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_Graph.cxx +++ b/src/MEDSPLITTER/MEDSPLITTER_Graph.cxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #include "MEDSPLITTER_Graph.hxx" using namespace MEDSPLITTER; diff --git a/src/MEDSPLITTER/MEDSPLITTER_Graph.hxx b/src/MEDSPLITTER/MEDSPLITTER_Graph.hxx index 4a6489631..fcd2124b3 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_Graph.hxx +++ b/src/MEDSPLITTER/MEDSPLITTER_Graph.hxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #ifndef GRAPH_HXX_ #define GRAPH_HXX_ diff --git a/src/MEDSPLITTER/MEDSPLITTER_MESHCollection.H b/src/MEDSPLITTER/MEDSPLITTER_MESHCollection.H index 25f2da90c..cc7437046 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_MESHCollection.H +++ b/src/MEDSPLITTER/MEDSPLITTER_MESHCollection.H @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #ifndef MEDSPLITTER_MESHCOLLECTION_H_ #define MEDSPLITTER_MESHCOLLECTION_H_ diff --git a/src/MEDSPLITTER/MEDSPLITTER_MESHCollection.cxx b/src/MEDSPLITTER/MEDSPLITTER_MESHCollection.cxx index d9d2b4102..ce1820828 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_MESHCollection.cxx +++ b/src/MEDSPLITTER/MEDSPLITTER_MESHCollection.cxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #include <vector> #include <string> #ifndef WNT @@ -99,7 +117,7 @@ MESHCollection::MESHCollection(const MESHCollection& initial_collection, Topolog m_mesh[idomain]= static_cast<MEDMEM::MESH*> (mesh_builder); ostringstream osname; osname << mesh_name<<"_"<<idomain+1; - SCRUTE(osname.str()); + SCRUTE_MED(osname.str()); mesh_builder->setName(osname.str()); createNodalConnectivity(initial_collection,idomain, MED_EN::MED_CELL); @@ -446,9 +464,10 @@ void MESHCollection::getPolyhedraNodeConnectivity(const int* cell_list,int nb_ce void MESHCollection::write(const string& filename) { //building the connect zones necessary for writing joints + cout<<"Building Connect Zones"<<endl; if (m_topology->nbDomain()>1) buildConnectZones(); - + cout <<"End of connect zones building"<<endl; //suppresses link with driver so that it can be changed for writing if (m_driver!=0)delete m_driver; m_driver=0; @@ -500,7 +519,7 @@ void MESHCollection::getTypeList(int* cell_list,int nb_cells, MED_EN::medEntityMesh entity, MED_EN::medGeometryElement* type_list) const { - MESSAGE (" Beginning of getTypeList with entity "<<entity); + MESSAGE_MED (" Beginning of getTypeList with entity "<<entity); int *local=new int[nb_cells]; int *ip=new int[nb_cells]; switch (entity) @@ -520,7 +539,7 @@ void MESHCollection::getTypeList(int* cell_list,int nb_cells, } delete[]local; delete[]ip; - MESSAGE("end of getTypeList"); + MESSAGE_MED("end of getTypeList"); } @@ -1007,7 +1026,7 @@ Topology* MESHCollection::createPartition(int nbdomain, MEDMEM::MEDSKYLINEARRAY* array=0; int* edgeweights=0; - MESSAGE("Building cell graph"); + MESSAGE_MED("Building cell graph"); buildCellGraph(array,edgeweights); switch (split) @@ -1034,17 +1053,17 @@ Topology* MESHCollection::createPartition(int nbdomain, if (user_vertices_weights!=0) m_cell_graph->setVerticesWeights(user_vertices_weights); - MESSAGE("Partitioning graph"); + MESSAGE_MED("Partitioning graph"); m_cell_graph->partGraph(nbdomain,options_string); - MESSAGE("Building new topology"); + MESSAGE_MED("Building new topology"); //m_cell_graph is a shared pointer Topology* topology = new ParallelTopology (m_cell_graph, nbdomain, getMeshDimension()); //cleaning if (edgeweights!=0) delete[] edgeweights; //if (array!=0) delete array; - MESSAGE("End of partition creation"); + MESSAGE_MED("End of partition creation"); return topology; } @@ -1092,13 +1111,16 @@ void MESHCollection::buildConnectZones(int idomain) // constructing node/node correspondencies vector<MEDMEM::MEDSKYLINEARRAY*> node_node_correspondency; node_node_correspondency.resize(m_topology->nbDomain()); + + cout << "Computing node/node corresp"<<endl; + m_topology->computeNodeNodeCorrespondencies(idomain, node_node_correspondency ); for (int idistant=0; idistant< m_topology->nbDomain(); idistant++) { - // on regarde si une correspondance noeud/noeud a été trouvée + // on regarde si une correspondance noeud/noeud a été trouvée // entre idomain et idistant - // si oui, on crée une connectzone + // si oui, on crée une connectzone if (node_node_correspondency[idistant]!=0) { MEDMEM::CONNECTZONE* cz= new MEDMEM::CONNECTZONE(); @@ -1111,6 +1133,8 @@ void MESHCollection::buildConnectZones(int idomain) m_connect_zones.push_back(cz); } } + cout << "Computing node/node corresp"<<endl; + vector<MEDMEM::MEDSKYLINEARRAY*> cell_cell_correspondency; cell_cell_correspondency.resize(m_topology->nbDomain()); m_topology->computeCellCellCorrespondencies(idomain, cell_cell_correspondency, m_cell_graph.get()); @@ -1140,7 +1164,9 @@ void MESHCollection::buildConnectZones(int idomain) void MESHCollection::buildConnectZones() { - + cout << "Computing node/node corresp"<<endl; + + //Creating nodes for (int idomain=0; idomain<m_topology->nbDomain(); idomain++) { @@ -1152,9 +1178,9 @@ void MESHCollection::buildConnectZones() for (int idistant=0; idistant< m_topology->nbDomain(); idistant++) { - // on regarde si une correspondance noeud/noeud a été trouvée + // on regarde si une correspondance noeud/noeud a été trouvée // entre idomain et idistant - // si oui, on crée une connectzone + // si oui, on crée une connectzone if (node_node_correspondency[idistant]!=0) { MEDMEM::CONNECTZONE* cz= new MEDMEM::CONNECTZONE(); @@ -1168,7 +1194,8 @@ void MESHCollection::buildConnectZones() } } } - + cout << "Computing face corresp"<<endl; + //creating faces if required if (m_subdomain_boundary_creates) { @@ -1192,7 +1219,7 @@ void MESHCollection::buildConnectZones() cell_cell_correspondency.resize(m_topology->nbDomain()); m_topology->computeCellCellCorrespondencies(idomain, cell_cell_correspondency, m_cell_graph.get()); - + for (int idistant=0; idistant< m_topology->nbDomain(); idistant++) { if (idistant <= idomain) continue; @@ -1202,17 +1229,18 @@ void MESHCollection::buildConnectZones() if (cell_cell_correspondency[idistant]!=0) { int nbcells = cell_cell_correspondency[idistant]->getNumberOf(); + // MEDMEM::CELLMODEL_Map cellmodel_map; for (int ilocal=0; ilocal<nbcells; ilocal++) { - medGeometryElement local_type = m_mesh[idomain]->getElementType(MED_EN::MED_CELL,ilocal+1); - MEDMEM::CELLMODEL local_model (local_type); + // medGeometryElement local_type = m_mesh[idomain]->getElementType(MED_EN::MED_CELL,ilocal+1); + // MEDMEM::CELLMODEL local_model = cellmodel_map.retrieveCellModel (local_type); const int* index = cell_cell_correspondency[idistant]->getIndex(); const int* value = cell_cell_correspondency[idistant]->getValue(); for (int icelldistant = index[ilocal]; icelldistant < index[ilocal+1]; icelldistant++) { int distant_id = value[icelldistant-1]; - medGeometryElement distant_type = m_mesh[idistant]->getElementType(MED_EN::MED_CELL,distant_id); - MEDMEM::CELLMODEL distant_model (distant_type); + // medGeometryElement distant_type = m_mesh[idistant]->getElementType(MED_EN::MED_CELL,distant_id); + // MEDMEM::CELLMODEL distant_model = cellmodel_map.retrieveCellModel (distant_type); MEDSPLITTER_FaceModel* face = getCommonFace(idomain,ilocal+1,idistant,distant_id,global_face_id); face_map[idomain][face->getType()].push_back(face); MEDSPLITTER_FaceModel* face2 = getCommonFace(idistant,distant_id,idomain, ilocal+1,global_face_id); @@ -1382,7 +1410,8 @@ void MESHCollection::buildConnectZones() delete (iter->second)[i]; } - + cout << "Computing cell/cell corresp"<<endl; + //Creating cell/cell correspondencies for (int idomain=0;idomain<m_topology->nbDomain();idomain++) { @@ -1651,7 +1680,7 @@ void MESHCollection::castAllFields(const MESHCollection& initial_collection) void MESHCollection::createNodalConnectivity(const MESHCollection& initial_collection,int idomain, MED_EN::medEntityMesh entity) { - MESSAGE ("beginning of createNodalConnectivity for entity "<<entity); + MESSAGE_MED ("beginning of createNodalConnectivity for entity "<<entity); int dimension=0; int nb_elems=0; MEDMEM::MESHING* mesh_builder = static_cast<MEDMEM::MESHING*>(m_mesh[idomain]); @@ -1678,7 +1707,7 @@ void MESHCollection::createNodalConnectivity(const MESHCollection& initial_colle } if (nb_elems == 0) return; - SCRUTE(nb_elems); + SCRUTE_MED(nb_elems); int *list= new int[nb_elems]; @@ -1747,7 +1776,7 @@ void MESHCollection::createNodalConnectivity(const MESHCollection& initial_colle //setting the list of present ypes int* present_type_numbers=new int[nb_present_types]; MED_EN::medGeometryElement* type_array = new MED_EN::medGeometryElement[nb_present_types]; - MESSAGE("Nb de types presents "<<nb_present_types); + MESSAGE_MED("Nb de types presents "<<nb_present_types); int itype=0; for (iter = type_numbers.begin();iter != type_numbers.end(); iter++) { @@ -1758,7 +1787,7 @@ void MESHCollection::createNodalConnectivity(const MESHCollection& initial_colle present_type_numbers[itype]=type_numbers[type]; - MESSAGE("Nombre d'elements de type "<<type<<" : "<<type_numbers[type]); + MESSAGE_MED("Nombre d'elements de type "<<type<<" : "<<type_numbers[type]); itype++; } @@ -1840,7 +1869,7 @@ void MESHCollection::createNodalConnectivity(const MESHCollection& initial_colle { //setting coordinates from initial_collection coordinates int nbnode=m_topology->getNodeNumber(idomain); - MESSAGE("Number of nodes on domain "<< idomain <<" : "<<nbnode); + MESSAGE_MED("Number of nodes on domain "<< idomain <<" : "<<nbnode); double* coordinates=new double[initial_collection.getSpaceDimension()*nbnode]; int* node_list=new int[nbnode]; @@ -1907,7 +1936,7 @@ void MESHCollection::createNodalConnectivity(const MESHCollection& initial_colle } } - MESSAGE("end of createNodalConnectivity"); + MESSAGE_MED("end of createNodalConnectivity"); } @@ -1987,7 +2016,7 @@ MEDSPLITTER_FaceModel* MESHCollection::getCommonFace(int ip1,int ilocal1,int ip2 while (iface<nbfaces) { - //SCRUTE (iface); + //SCRUTE_MED (iface); int nbnodes= types[iface]%100; const int* nodes = celltype1.getNodesConstituent(1,iface+1); int common_nodes=0; diff --git a/src/MEDSPLITTER/MEDSPLITTER_MESHCollection.hxx b/src/MEDSPLITTER/MEDSPLITTER_MESHCollection.hxx index e1a1b43dc..4cb2b8d71 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_MESHCollection.hxx +++ b/src/MEDSPLITTER/MEDSPLITTER_MESHCollection.hxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #ifndef MESHCOLLECTION_ #define MESHCOLLECTION_ diff --git a/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionDriver.H b/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionDriver.H index b71ea2d0f..8a2bf01fc 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionDriver.H +++ b/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionDriver.H @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #ifndef MEDSPLITTER_MESHCOLLECTIONDRIVER_H #define MEDSPLITTER_MESHCOLLECTIONDRIVER_H diff --git a/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionDriver.cxx b/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionDriver.cxx index 84dc23812..3c4cc444b 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionDriver.cxx +++ b/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionDriver.cxx @@ -1,4 +1,21 @@ - +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #include <vector> #include <string> #include <map> @@ -51,7 +68,8 @@ MESHCollectionDriver::MESHCollectionDriver(MESHCollection* collection):m_collect * */ int MESHCollectionDriver::readSeq(char* filename, char* meshname) { - BEGIN_OF("MEDSPLITTER::MESHCollectionDriver::readSeq()"); + const char* LOC = "MEDSPLITTER::MESHCollectionDriver::readSeq()"; + BEGIN_OF_MED(LOC); m_filename.resize(1); m_filename[0]=string(filename); @@ -73,7 +91,7 @@ int MESHCollectionDriver::readSeq(char* filename, char* meshname) ParallelTopology* aPT = new ParallelTopology ((m_collection->getMesh()), (m_collection->getCZ()), cellglobal, nodeglobal, faceglobal); m_collection->setTopology(aPT); - END_OF("MEDSPLITTER::MESHCollectionDriver::readSeq()"); + END_OF_MED(LOC); return 0; } @@ -90,12 +108,13 @@ int MESHCollectionDriver::readSeq(char* filename, char* meshname) void MESHCollectionDriver::readFileStruct(vector <string>& field_names,vector<int>& iternumber,vector <int>& ordernumber, vector <int>& types) { - BEGIN_OF("MEDSPLITTER::MESHCollectionDriver::readFileStruct()") + const char* LOC = "MEDSPLITTER::MESHCollectionDriver::readFileStruct()"; + BEGIN_OF_MED(LOC); const MEDMEM::MED med_struct (MEDMEM::MED_DRIVER,m_filename[0]); int nb_fields = med_struct.getNumberOfFields(); - MESSAGE("found "<<nb_fields<<" fields in file") + MESSAGE_MED("found "<<nb_fields<<" fields in file") deque<string> names = med_struct.getFieldNames(); for (int ifield = 0; ifield < nb_fields; ifield++) { @@ -116,13 +135,14 @@ void MESHCollectionDriver::readFileStruct(vector <string>& field_names,vector<i } } - END_OF("MEDSPLITTER::MESHCollectionDriver::readFileStruct()") + END_OF_MED(LOC); } //!retrieves the type of a field for a given fieldname int MESHCollectionDriver::getFieldType(const string& fieldname) { - BEGIN_OF("MEDSPLITTER::MESHCollectionDriver::getFieldType()") + const char* LOC = "MEDSPLITTER::MESHCollectionDriver::getFieldType()"; + BEGIN_OF_MED(LOC); const MEDMEM::MED med_struct (MEDMEM::MED_DRIVER,m_filename[0]); deque<MEDMEM::DT_IT_> dtit=med_struct.getFieldIteration(fieldname); @@ -131,7 +151,7 @@ int MESHCollectionDriver::getFieldType(const string& fieldname) // testing whether the field is of double or int type MEDMEM::FIELD_* field = med_struct.getField(fieldname,iter->dt,iter->it); - END_OF("MEDSPLITTER::MESHCollectionDriver::getFieldType()") + END_OF_MED(LOC); if (dynamic_cast<MEDMEM::FIELD<double>*>(field)) return 1; @@ -147,7 +167,8 @@ vector<int*>& faceglobal, vector<int*>& nodeglobal, int idomain ) { - BEGIN_OF("MEDSPLITTER::MESHCollectionDriver::readSubdomain()"); + const char* LOC = "MEDSPLITTER::MESHCollectionDriver::readSubdomain()"; + BEGIN_OF_MED(LOC); char file[256]; char meshname[MED_TAILLE_NOM]; @@ -214,7 +235,7 @@ vector<int*>& nodeglobal, int idomain { int * array=new int[ncell]; int offset=0; - MESSAGE("Reading cell global numbering for mesh "<< idomain); + MESSAGE_MED("Reading cell global numbering for mesh "<< idomain); list<MED_EN::medGeometryElement>::const_iterator iter; char meshchar[MED_TAILLE_NOM]; strcpy(meshchar,(m_collection->getMesh())[idomain]->getName().c_str()); @@ -234,7 +255,7 @@ vector<int*>& nodeglobal, int idomain delete[] types; } - MESSAGE("Reading node global numbering"); + MESSAGE_MED("Reading node global numbering"); int nnode= (m_collection->getMesh())[idomain]->getNumberOfNodes(); { int* array=new int[nnode]; @@ -243,7 +264,7 @@ vector<int*>& nodeglobal, int idomain nodeglobal[idomain]=array; } - MESSAGE("Reading face global numbering for mesh "<<idomain); + MESSAGE_MED("Reading face global numbering for mesh "<<idomain); int nbface=(m_collection->getMesh())[idomain]->getNumberOfElementsWithPoly(MED_EN::MED_FACE,MED_EN::MED_ALL_ELEMENTS); if (nbface!=0) { @@ -260,7 +281,7 @@ vector<int*>& nodeglobal, int idomain int ntype = (m_collection->getMesh())[idomain]->getNumberOfElementsWithPoly(MED_EN::MED_FACE,type); if (ntype==0) continue; med_2_3::MEDglobalNumLire(fid,meshname, array+offset, ntype, - med_2_3::MED_FACE, (med_2_3::med_geometrie_element)type); + med_2_3::MED_MAILLE, (med_2_3::med_geometrie_element)type); offset+=ntype; } faceglobal[idomain]=array; @@ -269,7 +290,7 @@ vector<int*>& nodeglobal, int idomain med_2_3::MEDfermer(fid); // if (nbface!=0) delete[]array; - END_OF("MEDSPLITTER::MESHCollectionDriver::readSubdomain()"); + END_OF_MED(LOC); } void MESHCollectionDriver::writeSubdomain(int idomain, int nbdomains, char* distfilename) @@ -278,14 +299,15 @@ vector<int*>& nodeglobal, int idomain // if (nbdomains>1) // m_collection->buildConnectZones(idomain); - MESSAGE(" Number of connect zones "<<(m_collection->getCZ()).size()); + MESSAGE_MED(" Number of connect zones "<<(m_collection->getCZ()).size()); //writing connect zones in joints med_2_3::med_idt fid = med_2_3::MEDouvrir(distfilename,med_2_3::MED_LECTURE_ECRITURE); int index_joint=0; - + + for (int icz=0; icz<(m_collection->getCZ()).size(); icz++) { if ((m_collection->getCZ())[icz]->getLocalDomainNumber()==idomain) @@ -300,11 +322,12 @@ vector<int*>& nodeglobal, int idomain char distant_name[MED_TAILLE_NOM]; //sprintf(distant_name,"domain_%i",(m_collection->getCZ())[icz]->getDistantDomainNumber()); - sprintf(distant_name,(m_collection->getMesh())[idistant]->getName().c_str()); + // sprintf(distant_name,(m_collection->getMesh())[idistant]->getName().c_str()); + sprintf(distant_name,"domain_%i",idistant); char mesh_name[MED_TAILLE_NOM]; strcpy (mesh_name, m_collection->getMesh(idomain)->getName().c_str()); - SCRUTE(m_collection->getMesh(idomain)->getName()); + SCRUTE_MED(m_collection->getMesh(idomain)->getName()); error = med_2_3::MEDjointCr(fid,mesh_name, joint_name, desc, idistant, distant_name); if (error==-1) cout << "erreur creation de joint "<<endl; @@ -330,57 +353,62 @@ vector<int*>& nodeglobal, int idomain if (error==-1) cout << "erreur creation de joint "<<endl; //writing cell/cell joint - writeElementJoint(MED_EN::MED_CELL, icz, idomain, idistant, mesh_name,joint_name,fid); + writeElementJoint(MED_EN::MED_CELL, icz, idomain, idistant, mesh_name,joint_name,fid); //writing face/face joint if (m_collection->getSubdomainBoundaryCreates()) { MED_EN::medEntityMesh constituent_entity = (m_collection->getMeshDimension()==3)?MED_EN::MED_FACE:MED_EN::MED_EDGE; - writeElementJoint(constituent_entity, icz, idomain, idistant, mesh_name,joint_name,fid); + writeElementJoint(constituent_entity, icz, idomain, idistant, mesh_name,joint_name,fid); } index_joint++; } } - + + char meshchar[MED_TAILLE_NOM]; + strcpy(meshchar,(m_collection->getMesh())[idomain]->getName().c_str()); + // Writing cell global numbering // + { int ncell=m_collection->getTopology()->getCellNumber(idomain); - int * array=new int[ncell]; + int* array=new int[ncell]; m_collection->getTopology()->getCellList(idomain,array); int offset=0; - + MED_EN::MESH_ENTITIES::const_iterator currentEntity; list<MED_EN::medGeometryElement>::const_iterator iter; currentEntity = MED_EN::meshEntities.find(MED_EN::MED_CELL); - char meshchar[MED_TAILLE_NOM]; - strcpy(meshchar,(m_collection->getMesh())[idomain]->getName().c_str()); + int nbtypes = (m_collection->getMesh())[idomain]->getNumberOfTypesWithPoly(MED_EN::MED_CELL); MED_EN::medGeometryElement* types =(m_collection->getMesh())[idomain]->getTypesWithPoly(MED_EN::MED_CELL); for (int itype=0; itype<nbtypes;itype++) - { - MED_EN::medGeometryElement type=types[itype]; - if (!m_collection->isDimensionOK(type,m_collection->getMeshDimension())) continue; - int ntype = (m_collection->getMesh())[idomain]->getNumberOfElementsWithPoly(MED_EN::MED_CELL,type); - if (ntype==0) continue; - med_2_3::MEDglobalNumEcr(fid,meshchar, array+offset, ntype, - med_2_3::MED_MAILLE, (med_2_3::med_geometrie_element)type); - offset+=ntype; + { + MED_EN::medGeometryElement type=types[itype]; + if (!m_collection->isDimensionOK(type,m_collection->getMeshDimension())) continue; + int ntype = (m_collection->getMesh())[idomain]->getNumberOfElementsWithPoly(MED_EN::MED_CELL,type); + if (ntype==0) continue; + med_2_3::MEDglobalNumEcr(fid,meshchar, array+offset, ntype, + med_2_3::MED_MAILLE, (med_2_3::med_geometrie_element)type); + offset+=ntype; - } + } delete[] types; delete[] array; - + } + MED_EN::medEntityMesh constituent_entity; if (m_collection->getMeshDimension()==3) - constituent_entity=MED_EN::MED_FACE; - else if (m_collection->getMeshDimension()==2) - constituent_entity=MED_EN::MED_EDGE; - else throw MEDEXCEPTION("Wrong dimension"); - - + constituent_entity=MED_EN::MED_FACE; + else if (m_collection->getMeshDimension()==2) + constituent_entity=MED_EN::MED_EDGE; + else throw MEDEXCEPTION("Wrong dimension"); + + //writing face global numbering - - offset=0; + { + int * array; + int offset=0; int nface= m_collection->getTopology()->getFaceNumber(idomain); if (nface >0) array=new int[nface]; @@ -390,33 +418,40 @@ vector<int*>& nodeglobal, int idomain MED_EN::medGeometryElement* facetypes; if (nbfacetypes>0) facetypes =(m_collection->getMesh())[idomain]->getTypesWithPoly(constituent_entity); - + for (int itype=0; itype<nbfacetypes;itype++) - { - MED_EN::medGeometryElement type=facetypes[itype]; - if (!m_collection->isDimensionOK(type,m_collection->getMeshDimension()-1)) continue; - - int ntype = (m_collection->getMesh())[idomain]->getNumberOfElementsWithPoly(constituent_entity,type); - if (ntype==0) continue; - med_2_3::MEDglobalNumEcr(fid,meshchar, array+offset, ntype, - med_2_3::MED_MAILLE, (med_2_3::med_geometrie_element)type); - offset+=ntype; - } - if (nface>0) delete[] array; - if (nbfacetypes>0) delete[] facetypes; - - //writing node global numbering - - int nnode= m_collection->getTopology()->getNodeNumber(idomain); - array=new int[nnode]; - m_collection->getTopology()->getNodeList(idomain,array); - med_2_3::MEDglobalNumEcr(fid,meshchar, array, nnode, - med_2_3::MED_NOEUD, med_2_3::MED_POINT1); - - delete[] array; - med_2_3::MEDfermer(fid); - MESSAGE("End of writing"); - + { + MED_EN::medGeometryElement type=facetypes[itype]; + if (!m_collection->isDimensionOK(type,m_collection->getMeshDimension()-1)) continue; + + int ntype = (m_collection->getMesh())[idomain]->getNumberOfElementsWithPoly(constituent_entity,type); + if (ntype==0) continue; + med_2_3::MEDglobalNumEcr(fid,meshchar, array+offset, ntype, + med_2_3::MED_MAILLE, (med_2_3::med_geometrie_element)type); + + offset+=ntype; + } + if (nface>0) delete[] array; + if (nbfacetypes>0) delete[] facetypes; + } + + + //writing node global numbering + { + int nnode= m_collection->getTopology()->getNodeNumber(idomain); + int* array=new int[nnode]; + + m_collection->getTopology()->getNodeList(idomain,array); + + med_2_3::MEDglobalNumEcr(fid,meshchar, array, nnode, + med_2_3::MED_NOEUD, med_2_3::MED_POINT1); + + delete[] array; + } + + med_2_3::MEDfermer(fid); + MESSAGE_MED("End of writing"); + } void MESHCollectionDriver::writeElementJoint(medEntityMesh entity , @@ -459,47 +494,68 @@ void MESHCollectionDriver::writeElementJoint(medEntityMesh entity , { distant_offset[distant_types[i]]=distant_gni[i]-1; } - - //classifying all thje cell/cell relationships into geomtype/geomtype relationships - //there exists a vector for each geomtype/geomtype pair - // the vectors are stored in cellmap, a std::map with a pair<geomtype,geomtype> key - - for (int i=0; i<nbcells; i++) - for (int icol = index[i]-1; icol<index[i+1]-1; icol++) - { - MED_EN::medGeometryElement local_type = (m_collection->getMesh())[idomain]->getElementType(entity,i+1); - MED_EN::medGeometryElement distant_type = (m_collection->getMesh())[idistant]->getElementType(entity,value[icol]); - cellmap[make_pair(local_type, distant_type)].push_back(i+1-local_offset[local_type]); - cellmap[make_pair(local_type, distant_type)].push_back(value[icol]-distant_offset[distant_type]); - } - map <pair <MED_EN::medGeometryElement, MED_EN::medGeometryElement> , vector<int> >::const_iterator iter; + if (nb_types_local==1 && nb_types_distant==1) + { + MED_EN::medGeometryElement local_type = (m_collection->getMesh())[idomain]->getElementType(entity,1); + MED_EN::medGeometryElement distant_type = (m_collection->getMesh())[idistant]->getElementType(entity,1); + vector<int> corresp; + for (int i=0; i<nbcells; i++) + for (int icol = index[i]-1; icol<index[i+1]-1; icol++) + { + corresp.push_back(i+1); + corresp.push_back(value[icol]); + } + int size_joint = corresp.size()/2; + med_2_3::MEDjointEcr(fid, mesh_name, joint_name, &corresp[0], + size_joint, med_2_3::MED_MAILLE, + (med_2_3::med_geometrie_element)local_type ,med_2_3::MED_MAILLE, + (med_2_3::med_geometrie_element)distant_type ); + } + else + { + //classifying all thje cell/cell relationships into geomtype/geomtype relationships + //there exists a vector for each geomtype/geomtype pair + // the vectors are stored in cellmap, a std::map with a pair<geomtype,geomtype> key + + for (int i=0; i<nbcells; i++) + for (int icol = index[i]-1; icol<index[i+1]-1; icol++) + { + MED_EN::medGeometryElement local_type = (m_collection->getMesh())[idomain]->getElementType(entity,i+1); + MED_EN::medGeometryElement distant_type = (m_collection->getMesh())[idistant]->getElementType(entity,value[icol]); + + cellmap[make_pair(local_type, distant_type)].push_back(i+1-local_offset[local_type]); + cellmap[make_pair(local_type, distant_type)].push_back(value[icol]-distant_offset[distant_type]); - //going through all the (geom,geom) pairs and writing the joints - for (iter= cellmap.begin(); iter != cellmap.end(); iter++) - { - int size= iter->second.size(); - int *corresp = new int[size]; - for (int ind=0; ind < size; ind++) - corresp[ind]=(iter->second)[ind]; - med_2_3::med_geometrie_element local_geo_elem=(med_2_3::med_geometrie_element)iter->first.first; - med_2_3::med_geometrie_element distant_geo_elem=(med_2_3::med_geometrie_element)iter->first.second; - int size_joint=size/2; - //med_2_3::med_err error = - med_2_3::MEDjointEcr(fid, mesh_name, joint_name, corresp, size_joint, med_2_3::MED_MAILLE, - local_geo_elem,med_2_3::MED_MAILLE, distant_geo_elem); - - // MED v 2.3.1 returns an error code when - // writing a joint that is already present in the file. - // Also, it returns an error code if a joint - // concerns 3D elements. - // Until these two items are not - // changed, the following line must be commented out - - //if (error==-1) throw MEDEXCEPTION("Error filling joint"); - - delete[]corresp; - } + } + map <pair <MED_EN::medGeometryElement, MED_EN::medGeometryElement> , vector<int> >::const_iterator iter; + + //going through all the (geom,geom) pairs and writing the joints + for (iter= cellmap.begin(); iter != cellmap.end(); iter++) + { + int size= iter->second.size(); + int *corresp = new int[size]; + for (int ind=0; ind < size; ind++) + corresp[ind]=(iter->second)[ind]; + med_2_3::med_geometrie_element local_geo_elem=(med_2_3::med_geometrie_element)iter->first.first; + med_2_3::med_geometrie_element distant_geo_elem=(med_2_3::med_geometrie_element)iter->first.second; + int size_joint=size/2; + //med_2_3::med_err error = + med_2_3::MEDjointEcr(fid, mesh_name, joint_name, corresp, size_joint, med_2_3::MED_MAILLE, + local_geo_elem,med_2_3::MED_MAILLE, distant_geo_elem); + delete[] corresp; + } + // MED v 2.3.1 returns an error code when + // writing a joint that is already present in the file. + // Also, it returns an error code if a joint + // concerns 3D elements. + // Until these two items are not + // changed, the following line must be commented out + + //if (error==-1) throw MEDEXCEPTION("Error filling joint"); + + + } } void MESHCollectionDriver::jointSort(int* elems, int nbelems, bool is_first) diff --git a/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionDriver.hxx b/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionDriver.hxx index ef1d5698a..e042b0d70 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionDriver.hxx +++ b/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionDriver.hxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #ifndef MESHCOLLECTIONDRIVER_HXX_ #define MESHCOLLECTIONDRIVER_HXX_ diff --git a/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedAsciiDriver.H b/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedAsciiDriver.H index b78f52bbe..a7821576d 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedAsciiDriver.H +++ b/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedAsciiDriver.H @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #ifndef MEDSPLITTER_MESHCOLLECTIONMEDASCIIDRIVER_H #define MEDSPLITTER_MESHCOLLECTIONMEDASCIIDRIVER_H diff --git a/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedAsciiDriver.cxx b/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedAsciiDriver.cxx index 4b019f8a9..34e1b8732 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedAsciiDriver.cxx +++ b/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedAsciiDriver.cxx @@ -1,4 +1,21 @@ - +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #include <vector> #include <string> #include <map> @@ -54,7 +71,8 @@ MESHCollectionMedAsciiDriver::MESHCollectionMedAsciiDriver(MESHCollection* colle int MESHCollectionMedAsciiDriver::read(char* filename) { - BEGIN_OF("MEDSPLITTER::MESHCollectionDriver::read()") + const char* LOC = "MEDSPLITTER::MESHCollectionDriver::read()"; + BEGIN_OF_MED(LOC); //ditributed meshes vector<int*> cellglobal; @@ -65,7 +83,7 @@ int MESHCollectionMedAsciiDriver::read(char* filename) // reading ascii master file try{ - MESSAGE("Start reading"); + MESSAGE_MED("Start reading"); ifstream asciiinput(filename); if (!asciiinput) @@ -119,7 +137,7 @@ int MESHCollectionMedAsciiDriver::read(char* filename) }//loop on domains - MESSAGE("end of read"); + MESSAGE_MED("end of read"); }//of try catch(...) { @@ -139,7 +157,7 @@ int MESHCollectionMedAsciiDriver::read(char* filename) if (faceglobal[i]!=0) delete[] faceglobal[i]; } - END_OF("MEDSPLITTER::MESHCollectionDriver::read()") + END_OF_MED(LOC); return 0; } @@ -152,7 +170,8 @@ int MESHCollectionMedAsciiDriver::read(char* filename) void MESHCollectionMedAsciiDriver::write(char* filename) { - BEGIN_OF("MEDSPLITTER::MESHCollectionDriver::write()") + const char* LOC = "MEDSPLITTER::MESHCollectionDriver::write()"; + BEGIN_OF_MED(LOC); ofstream file(filename); @@ -175,11 +194,11 @@ void MESHCollectionMedAsciiDriver::write(char* filename) m_filename[idomain]=string(distfilename); - MESSAGE("File name "<<string(distfilename)); + MESSAGE_MED("File name "<<string(distfilename)); - int id=(m_collection->getMesh())[idomain]->addDriver(MEDMEM::MED_DRIVER,distfilename,(m_collection->getMesh())[idomain]->getName(),MED_EN::MED_CREATE); + int id=(m_collection->getMesh())[idomain]->addDriver(MEDMEM::MED_DRIVER,distfilename,(m_collection->getMesh())[idomain]->getName(),MED_EN::WRONLY); - MESSAGE("Start writing"); + MESSAGE_MED("Start writing"); (m_collection->getMesh())[idomain]->write(id); //updating the ascii description file @@ -188,6 +207,6 @@ void MESHCollectionMedAsciiDriver::write(char* filename) writeSubdomain(idomain, nbdomains, distfilename); } - END_OF("MEDSPLITTER::MESHCollectionDriver::write()"); + END_OF_MED(LOC); } diff --git a/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedAsciiDriver.hxx b/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedAsciiDriver.hxx index ea2de13a3..999063bf3 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedAsciiDriver.hxx +++ b/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedAsciiDriver.hxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #ifndef MESHCOLLECTIONMEDASCIIDRIVER_HXX_ #define MESHCOLLECTIONMEDASCIIDRIVER_HXX_ diff --git a/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedXMLDriver.H b/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedXMLDriver.H index a69896abc..9cfa056c3 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedXMLDriver.H +++ b/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedXMLDriver.H @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #ifndef MEDSPLITTER_MESHCOLLECTIONMEDXMLDRIVER_H #define MEDSPLITTER_MESHCOLLECTIONMEDXMLDRIVER_H diff --git a/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedXMLDriver.cxx b/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedXMLDriver.cxx index 173b27c30..43e39298e 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedXMLDriver.cxx +++ b/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedXMLDriver.cxx @@ -1,4 +1,21 @@ - +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #include <vector> #include <string> #include <map> @@ -67,7 +84,8 @@ MESHCollectionMedXMLDriver::MESHCollectionMedXMLDriver(MESHCollection* collectio int MESHCollectionMedXMLDriver::read(char* filename) { - BEGIN_OF("MEDSPLITTER::MESHCollectionDriver::read()"); + const char* LOC = "MEDSPLITTER::MESHCollectionDriver::read()"; + BEGIN_OF_MED(LOC); //ditributed meshes vector<int*> cellglobal; @@ -80,7 +98,7 @@ int MESHCollectionMedXMLDriver::read(char* filename) // reading ascii master file try{ - MESSAGE("Start reading"); + MESSAGE_MED("Start reading"); // Setting up the XML tree corresponding to filename xmlDocPtr master_doc=xmlParseFile(filename); @@ -209,7 +227,7 @@ int MESHCollectionMedXMLDriver::read(char* filename) xmlXPathFreeContext(xpathCtx); xmlFreeDoc(master_doc); - MESSAGE("end of read"); + MESSAGE_MED("end of read"); }//of try catch(...) { @@ -228,7 +246,7 @@ int MESHCollectionMedXMLDriver::read(char* filename) if (faceglobal[i]!=0) delete[] faceglobal[i]; } - END_OF("MEDSPLITTER::MESHCollectionDriver::read()") + END_OF_MED(LOC); return 0; } @@ -241,7 +259,8 @@ int MESHCollectionMedXMLDriver::read(char* filename) void MESHCollectionMedXMLDriver::write(char* filename) { - BEGIN_OF("MEDSPLITTER::MESHCollectionDriver::writeXML()"); + const char* LOC = "MEDSPLITTER::MESHCollectionDriver::writeXML()"; + BEGIN_OF_MED(LOC); xmlDocPtr master_doc = 0; xmlNodePtr root_node = 0, node, node2; @@ -303,7 +322,7 @@ void MESHCollectionMedXMLDriver::write(char* filename) m_filename.resize(nbdomains); //loop on the domains - for (int idomain=0; idomain<nbdomains;idomain++) + for (int idomain=nbdomains-1; idomain>=0;idomain--) { char distfilename[256]; @@ -314,12 +333,13 @@ void MESHCollectionMedXMLDriver::write(char* filename) m_filename[idomain]=string(distfilename); - MESSAGE("File name "<<string(distfilename)); + MESSAGE_MED("File name "<<string(distfilename)); - int id=(m_collection->getMesh())[idomain]->addDriver(MEDMEM::MED_DRIVER,distfilename,(m_collection->getMesh())[idomain]->getName(),MED_EN::MED_CREATE); + int id=(m_collection->getMesh())[idomain]->addDriver(MEDMEM::MED_DRIVER,distfilename,(m_collection->getMesh())[idomain]->getName(),MED_EN::WRONLY); - MESSAGE("Start writing"); + MESSAGE_MED("Start writing"); (m_collection->getMesh())[idomain]->write(id); + (m_collection->getMesh())[idomain]->rmDriver(id); //updating the ascii description file node = xmlNewChild(file_node, 0, BAD_CAST "subfile",0); @@ -332,8 +352,7 @@ void MESHCollectionMedXMLDriver::write(char* filename) xmlNewProp(node, BAD_CAST "subdomain", BAD_CAST buff); xmlNewChild(node,0,BAD_CAST "name", BAD_CAST (m_collection->getMesh())[idomain]->getName().c_str()); - writeSubdomain(idomain, nbdomains, distfilename); - + writeSubdomain(idomain, nbdomains, distfilename); } strcat(filename,".xml"); m_master_filename=filename; @@ -341,6 +360,6 @@ void MESHCollectionMedXMLDriver::write(char* filename) xmlFreeDoc(master_doc); xmlCleanupParser(); - END_OF("MEDSPLITTER::MESHCollectionDriver::writeXML()"); + END_OF_MED(LOC); } diff --git a/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedXMLDriver.hxx b/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedXMLDriver.hxx index da93ab540..05fb7cf05 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedXMLDriver.hxx +++ b/src/MEDSPLITTER/MEDSPLITTER_MESHCollectionMedXMLDriver.hxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #ifndef MESHCOLLECTIONMEDXMLDRIVER_HXX_ #define MESHCOLLECTIONMEDXMLDRIVER_HXX_ diff --git a/src/MEDSPLITTER/MEDSPLITTER_METISGraph.cxx b/src/MEDSPLITTER/MEDSPLITTER_METISGraph.cxx index c4a22a9c2..a020b86d3 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_METISGraph.cxx +++ b/src/MEDSPLITTER/MEDSPLITTER_METISGraph.cxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// extern "C" { #include "metis.h" } diff --git a/src/MEDSPLITTER/MEDSPLITTER_METISGraph.hxx b/src/MEDSPLITTER/MEDSPLITTER_METISGraph.hxx index 5e0c50afc..43c38985a 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_METISGraph.hxx +++ b/src/MEDSPLITTER/MEDSPLITTER_METISGraph.hxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #ifndef METISGRAPH_HXX_ #define METISGRAPH_HXX_ diff --git a/src/MEDSPLITTER/MEDSPLITTER_ParallelTopology.cxx b/src/MEDSPLITTER/MEDSPLITTER_ParallelTopology.cxx index 9012b3bd3..28239de33 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_ParallelTopology.cxx +++ b/src/MEDSPLITTER/MEDSPLITTER_ParallelTopology.cxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #include <set> #include <map> #include <vector> @@ -72,7 +90,7 @@ ParallelTopology::ParallelTopology(vector<MEDMEM::MESH*> meshes, if (cellglobal[idomain]==0) { - MESSAGE("Creating global numbering"); + MESSAGE_MED("Creating global numbering"); //creating global numbering from scratch for (int i=0; i<m_nb_cells[idomain]; i++) { @@ -86,7 +104,7 @@ ParallelTopology::ParallelTopology(vector<MEDMEM::MESH*> meshes, //using global numbering coming from a previous numbering else { - MESSAGE("Using former global numbering"); + MESSAGE_MED("Using former global numbering"); for (int i=0; i<m_nb_cells[idomain]; i++) { int global=cellglobal[idomain][i]; @@ -124,9 +142,9 @@ ParallelTopology::ParallelTopology(vector<MEDMEM::MESH*> meshes, } m_nb_total_faces=nbfaces; m_nb_faces[0]=nbfaces; - MESSAGE ("nb total cells "<< m_nb_total_cells); - MESSAGE("nb total nodes "<< m_nb_total_nodes); - MESSAGE("nb total faces "<< m_nb_total_faces); + MESSAGE_MED ("nb total cells "<< m_nb_total_cells); + MESSAGE_MED("nb total nodes "<< m_nb_total_nodes); + MESSAGE_MED("nb total faces "<< m_nb_total_faces); return; } @@ -192,7 +210,7 @@ ParallelTopology::ParallelTopology(vector<MEDMEM::MESH*> meshes, // meshes[idomain]->getConnectivity(MED_EN::MED_FULL_INTERLACE, MED_EN::MED_DESCENDING, MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); m_nb_faces[idomain]=meshes[idomain]->getNumberOfElementsWithPoly(constituent_entity,MED_EN::MED_ALL_ELEMENTS); - MESSAGE ("Nb faces domain " << idomain<<m_nb_faces[idomain]); + MESSAGE_MED ("Nb faces domain " << idomain<<m_nb_faces[idomain]); m_face_loc_to_glob[idomain].resize(m_nb_faces[idomain]); local2distant.clear(); for (int icz=0; icz<cz.size(); icz++) @@ -242,7 +260,7 @@ ParallelTopology::ParallelTopology(vector<MEDMEM::MESH*> meshes, { int global_number=faceglobal[idomain][iface]; - //SCRUTE(global_number); + //SCRUTE_MED(global_number); m_face_glob_to_loc.insert(make_pair(global_number,make_pair(idomain,iface+1))); //m_face_loc_to_glob[make_pair(idomain,iface+1)]=global_number; m_face_loc_to_glob[idomain][iface]=global_number; @@ -253,9 +271,9 @@ ParallelTopology::ParallelTopology(vector<MEDMEM::MESH*> meshes, m_nb_total_cells=index_global; m_nb_total_nodes=index_node_global; m_nb_total_faces=index_face_global; - SCRUTE(m_nb_total_cells); - SCRUTE(m_nb_total_faces); - SCRUTE(m_nb_total_nodes); + SCRUTE_MED(m_nb_total_cells); + SCRUTE_MED(m_nb_total_faces); + SCRUTE_MED(m_nb_total_nodes); } @@ -291,9 +309,9 @@ ParallelTopology::ParallelTopology(boost::shared_ptr<Graph> graph, int nb_domain } for (int idomain=0; idomain<m_nb_domain; idomain++) - MESSAGE("Nombre de cellules dans le domaine "<< idomain <<" : "<<m_nb_cells[idomain]); + MESSAGE_MED("Nombre de cellules dans le domaine "<< idomain <<" : "<<m_nb_cells[idomain]); - SCRUTE(m_nb_total_cells); + SCRUTE_MED(m_nb_total_cells); } @@ -395,7 +413,7 @@ void ParallelTopology::convertGlobalFaceListWithTwins(const int* face_list, int for (int i=0; i< nbface; i++) { //int count = m_face_glob_to_loc.count(face_list[i]); - //if (count >1) MESSAGE("face en doublon "<<face_list[i]); + //if (count >1) MESSAGE_MED("face en doublon "<<face_list[i]); size+= m_face_glob_to_loc.count(face_list[i]); } int index=0; @@ -595,8 +613,8 @@ void ParallelTopology::createFaceMapping(const MESHCollection& initial_collectio { int nbplainface = initial_collection.getMesh(iold)->getNumberOfElements(constituent_entity,MED_EN::MED_ALL_ELEMENTS); int nbtotalface = initial_collection.getMesh(iold)->getNumberOfElementsWithPoly(constituent_entity,MED_EN::MED_ALL_ELEMENTS); - SCRUTE(nbplainface); - SCRUTE(nbtotalface); + SCRUTE_MED(nbplainface); + SCRUTE_MED(nbtotalface); const int* face_conn; const int* face_offset; const int* poly_conn; @@ -656,10 +674,10 @@ void ParallelTopology::createFaceMapping(const MESHCollection& initial_collectio for (int inode= poly_index[iface-nbplainface];inode < poly_index[iface-nbplainface+1]; inode++) { int node=poly_conn[inode-1]; - // SCRUTE(node); + // SCRUTE_MED(node); int global = old_topology->convertNodeToGlobal(iold,node); // cout << "global node "<<global<<"ip "<<iold<< "noeud"<<node<<endl; - // SCRUTE(global); + // SCRUTE_MED(global); nodes.insert(global); typedef hash_multimap<int,pair<int,int> >::iterator mmiter; pair<mmiter,mmiter> range=m_node_glob_to_loc.equal_range(global); @@ -692,11 +710,11 @@ void ParallelTopology::createFaceMapping(const MESHCollection& initial_collectio global_face_number=global_index; } - // SCRUTE(nbnodes); + // SCRUTE_MED(nbnodes); for (int inew=0;inew<m_nb_domain;inew++) { - // SCRUTE(domain_counts[inew]); + // SCRUTE_MED(domain_counts[inew]); if(domain_counts[inew]==nbnodes) { new_counts[inew]++; @@ -712,9 +730,9 @@ void ParallelTopology::createFaceMapping(const MESHCollection& initial_collectio for (int inew=0;inew<m_nb_domain;inew++) { m_nb_faces[inew]=new_counts[inew]; - MESSAGE(" Nb faces ["<<inew<<"]="<<m_nb_faces[inew]); + MESSAGE_MED(" Nb faces ["<<inew<<"]="<<m_nb_faces[inew]); } - MESSAGE(" total number of faces"<<getFaceNumber()); + MESSAGE_MED(" total number of faces"<<getFaceNumber()); } ////creating node mapping @@ -750,7 +768,7 @@ void ParallelTopology::createFaceMapping2ndversion(const MESHCollection& initial MED_EN::MED_DESCENDING,MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS); const int* face_offset = initial_collection.getMesh(iold)-> getConnectivityIndex(MED_EN::MED_DESCENDING,MED_EN::MED_CELL); - MESSAGE("end of connectivity calculation"); + MESSAGE_MED("end of connectivity calculation"); set<int> global_treated; for (int icell=0; icell<nbcell; icell++) { @@ -780,7 +798,7 @@ void ParallelTopology::createFaceMapping2ndversion(const MESHCollection& initial m_nb_faces[inew]=new_counts[inew]; // cout << " Nb faces ["<<inew<<"]="<<m_nb_faces[inew]<<endl; } - MESSAGE(" total number of faces"<<getFaceNumber()); + MESSAGE_MED(" total number of faces"<<getFaceNumber()); } @@ -929,20 +947,21 @@ void ParallelTopology::computeCellCellCorrespondencies(int idomain, vector<MEDME vector <hash_multimap<int,int> > cell_corresp; //TODO : remplacer int* par une map <int,int> - vector<int* > number_of_connections(m_nb_domain); - + // vector<int* > number_of_connections(m_nb_domain); + // vector<map<int,int> > number_of_connections; + vector<map<int,int> > number_of_connections; cell_corresp.resize(m_nb_domain); - number_of_connections.resize(m_nb_domain); - for (int i=0; i<m_nb_domain; i++) - { - // cell_corresp[i]=new multimap<int,int>; - if (m_nb_cells[i] >0) - { - number_of_connections[i]=new int[m_nb_cells[idomain]]; - for (int j=0; j<m_nb_cells[idomain]; j++) - number_of_connections[i][j]=0; - } - } + number_of_connections.resize(m_nb_domain); +// for (int i=0; i<m_nb_domain; i++) +// { +// // cell_corresp[i]=new multimap<int,int>; +// if (m_nb_cells[i] >0) +// { +// number_of_connections[i]=new int[m_nb_cells[idomain]]; +// for (int j=0; j<m_nb_cells[idomain]; j++) +// number_of_connections[i][j]=0; +// } +// } const MEDMEM::MEDSKYLINEARRAY* skylinegraph = graph->getGraph(); @@ -968,7 +987,11 @@ void ParallelTopology::computeCellCellCorrespondencies(int idomain, vector<MEDME if (local.first != idomain) { cell_corresp[local.first].insert(make_pair(icell+1,local.second)); - number_of_connections[local.first][icell]++; + // number_of_connections[local.first][icell]++; + if (number_of_connections[local.first].find(icell)==number_of_connections[local.first].end()) + number_of_connections[local.first].insert(make_pair(icell,1)); + else + number_of_connections[local.first][icell]++; } } @@ -976,13 +999,17 @@ void ParallelTopology::computeCellCellCorrespondencies(int idomain, vector<MEDME for (int inew=0; inew<m_nb_domain; inew++) { - if (inew==idomain) continue; + if (inew==idomain || number_of_connections[inew].empty()) continue; int* new_index=new int[m_nb_cells[idomain]+1]; new_index[0]=1; for (int i=0; i<m_nb_cells[idomain]; i++) { - new_index[i+1]=new_index[i]+number_of_connections[inew][i]; + + if (number_of_connections[inew].find(i)!=number_of_connections[inew].end()) + new_index[i+1]=new_index[i]+number_of_connections[inew][i]; + else + new_index[i+1]=new_index[i]; } int* new_value; if (new_index[m_nb_cells[idomain]]-1 > 0) @@ -992,8 +1019,13 @@ void ParallelTopology::computeCellCellCorrespondencies(int idomain, vector<MEDME int value_i=0; + // hash_multimap<int,int>::iterator iter=cell_corresp[inew].begin(); + for (int i=0; i<m_nb_cells[idomain]; i++) { + // for (int j=new_index[i];j<new_index[i+1];j++,value_i++,iter++) + // new_value[value_i]=iter->second; + typedef hash_multimap<int,int>::iterator mmiter; pair<mmiter,mmiter> range=cell_corresp[inew].equal_range(i+1); for (mmiter it=range.first; it!=range.second; it++) @@ -1015,9 +1047,9 @@ void ParallelTopology::computeCellCellCorrespondencies(int idomain, vector<MEDME } - for (int inew=0; inew<m_nb_domain; inew++) - if (m_nb_cells[inew]>0) - delete[] number_of_connections[inew]; +// for (int inew=0; inew<m_nb_domain; inew++) +// if (m_nb_cells[inew]>0) +// delete[] number_of_connections[inew]; } diff --git a/src/MEDSPLITTER/MEDSPLITTER_ParallelTopology.hxx b/src/MEDSPLITTER/MEDSPLITTER_ParallelTopology.hxx index d337a9fba..d33a50adc 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_ParallelTopology.hxx +++ b/src/MEDSPLITTER/MEDSPLITTER_ParallelTopology.hxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #ifndef PARALLELTOPOLOGY_HXX_ #define PARALLELTOPOLOGY_HXX_ @@ -251,8 +269,8 @@ namespace MEDSPLITTER { pair<MMiter,MMiter> eq = m_face_glob_to_loc.equal_range(iglobal); for (MMiter it=eq.first; it != eq.second; it++) { - SCRUTE (it->second.first); - SCRUTE (idomain); + SCRUTE_MED (it->second.first); + SCRUTE_MED (idomain); if (it->second.first == idomain) return it->second.second; } diff --git a/src/MEDSPLITTER/MEDSPLITTER_SCOTCHGraph.cxx b/src/MEDSPLITTER/MEDSPLITTER_SCOTCHGraph.cxx index 6fc19f150..b63e99742 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_SCOTCHGraph.cxx +++ b/src/MEDSPLITTER/MEDSPLITTER_SCOTCHGraph.cxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #include <cstdio> extern "C" { #define restrict @@ -66,7 +84,7 @@ void SCOTCHGraph::partGraph(int ndomain, const string& options_string) else // partition for 1 subdomain for (int i=0; i<n+1; i++) - partition[i]=1; + partition[i]=0; SCOTCH_stratExit(&scotch_strategy); SCOTCH_graphExit(&scotch_graph); diff --git a/src/MEDSPLITTER/MEDSPLITTER_SCOTCHGraph.hxx b/src/MEDSPLITTER/MEDSPLITTER_SCOTCHGraph.hxx index 3abbb71ab..77fc5d6d3 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_SCOTCHGraph.hxx +++ b/src/MEDSPLITTER/MEDSPLITTER_SCOTCHGraph.hxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #ifndef SCOTCHGRAPH_HXX_ #define SCOTCHGRAPH_HXX_ diff --git a/src/MEDSPLITTER/MEDSPLITTER_SequentialTopology.cxx b/src/MEDSPLITTER/MEDSPLITTER_SequentialTopology.cxx index bd8f73ce4..210a44f74 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_SequentialTopology.cxx +++ b/src/MEDSPLITTER/MEDSPLITTER_SequentialTopology.cxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #include "MEDMEM_SkyLineArray.hxx" #include "MEDMEM_ConnectZone.hxx" #include "MEDMEM_DriversDef.hxx" diff --git a/src/MEDSPLITTER/MEDSPLITTER_SequentialTopology.hxx b/src/MEDSPLITTER/MEDSPLITTER_SequentialTopology.hxx index 68b5cdc2b..dc97776b3 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_SequentialTopology.hxx +++ b/src/MEDSPLITTER/MEDSPLITTER_SequentialTopology.hxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #ifndef SequentialTOPOLOGY_HXX_ #define SequentialTOPOLOGY_HXX_ diff --git a/src/MEDSPLITTER/MEDSPLITTER_Topology.hxx b/src/MEDSPLITTER/MEDSPLITTER_Topology.hxx index 218fac388..a532075b6 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_Topology.hxx +++ b/src/MEDSPLITTER/MEDSPLITTER_Topology.hxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #ifndef TOPOLOGY_HXX_ #define TOPOLOGY_HXX_ diff --git a/src/MEDSPLITTER/MEDSPLITTER_UserGraph.cxx b/src/MEDSPLITTER/MEDSPLITTER_UserGraph.cxx index d65032066..e473912e4 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_UserGraph.cxx +++ b/src/MEDSPLITTER/MEDSPLITTER_UserGraph.cxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #include "MEDSPLITTER_Graph.hxx" #include "MEDSPLITTER_UserGraph.hxx" diff --git a/src/MEDSPLITTER/MEDSPLITTER_UserGraph.hxx b/src/MEDSPLITTER/MEDSPLITTER_UserGraph.hxx index a210ee24a..b9422b180 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_UserGraph.hxx +++ b/src/MEDSPLITTER/MEDSPLITTER_UserGraph.hxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #ifndef MEDSPLITTER_USERGRAPH_HXX_ #define MEDSPLITTER_USERGRAPH_HXX_ diff --git a/src/MEDSPLITTER/MEDSPLITTER_utils.hxx b/src/MEDSPLITTER/MEDSPLITTER_utils.hxx index dd4832fb7..ddf69f33f 100644 --- a/src/MEDSPLITTER/MEDSPLITTER_utils.hxx +++ b/src/MEDSPLITTER/MEDSPLITTER_utils.hxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #ifndef MEDSPLITTER_UTILS_HXX_ #define MEDSPLITTER_UTILS_HXX_ diff --git a/src/MEDSPLITTER/Makefile.am b/src/MEDSPLITTER/Makefile.am index 4c3846fef..3a26e4f6f 100644 --- a/src/MEDSPLITTER/Makefile.am +++ b/src/MEDSPLITTER/Makefile.am @@ -1,25 +1,23 @@ -# MED MEDMEM : MED files in memory +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# 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. +# +# 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 +# +# MED MEDMEM : MED files in memory # - include $(top_srcdir)/adm_local/unix/make_common_starter.am # this directory must be recompiled before Test folder @@ -33,6 +31,10 @@ lib_LTLIBRARIES= libmedsplitter.la salomeinclude_HEADERS= \ MEDSPLITTER_Topology.hxx \ MEDSPLITTER_MESHCollection.hxx \ +MEDSPLITTER_MESHCollection.H \ +MEDSPLITTER_MESHCollectionDriver.H \ +MEDSPLITTER_MESHCollectionMedXMLDriver.H \ +MEDSPLITTER_MESHCollectionMedAsciiDriver.H \ MEDSPLITTER_MESHCollectionDriver.hxx \ MEDSPLITTER_MESHCollectionMedXMLDriver.hxx \ MEDSPLITTER_MESHCollectionMedAsciiDriver.hxx \ @@ -41,6 +43,8 @@ MEDSPLITTER_FaceModel.hxx \ MEDSPLITTER_Graph.hxx\ MEDSPLITTER_UserGraph.hxx\ MEDSPLITTER_API.hxx \ +MEDSPLITTER_SequentialTopology.hxx \ +MEDSPLITTER_utils.hxx \ MEDSPLITTER.hxx if MED_ENABLE_METIS @@ -96,3 +100,9 @@ medsplitter_LDADD= $(libmedsplitter_la_LDFLAGS) -lm $(BOOST_LIBS) libmedsplitter if MED_ENABLE_KERNEL medsplitter_LDADD+= -lSALOMEBasics endif + +OBSOLETE_FILES = \ + MEDSPLITTER_SequentialTopology.cxx \ + test_HighLevelAPI.cxx + +EXTRA_DIST += $(OBSOLETE_FILES) diff --git a/src/MEDSPLITTER/Test/MEDSPLITTERTest.cxx b/src/MEDSPLITTER/Test/MEDSPLITTERTest.cxx index 33322ebc0..09878e72a 100644 --- a/src/MEDSPLITTER/Test/MEDSPLITTERTest.cxx +++ b/src/MEDSPLITTER/Test/MEDSPLITTERTest.cxx @@ -1,23 +1,21 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// 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. // -// 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // - #include "MEDSPLITTERTest.hxx" #include <cppunit/TestAssert.h> diff --git a/src/MEDSPLITTER/Test/MEDSPLITTERTest.hxx b/src/MEDSPLITTER/Test/MEDSPLITTERTest.hxx index e2b32b0b6..16083d0c2 100644 --- a/src/MEDSPLITTER/Test/MEDSPLITTERTest.hxx +++ b/src/MEDSPLITTER/Test/MEDSPLITTERTest.hxx @@ -1,23 +1,21 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// 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. // -// 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // - #ifndef _MEDSPLITTERTEST_HXX_ #define _MEDSPLITTERTEST_HXX_ diff --git a/src/MEDSPLITTER/Test/MEDSPLITTERTest_MESHCollection.cxx b/src/MEDSPLITTER/Test/MEDSPLITTERTest_MESHCollection.cxx index 8b42659eb..6e6b3333e 100644 --- a/src/MEDSPLITTER/Test/MEDSPLITTERTest_MESHCollection.cxx +++ b/src/MEDSPLITTER/Test/MEDSPLITTERTest_MESHCollection.cxx @@ -1,22 +1,21 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// 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. // -// 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. +// 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 +// 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 // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com - #include "MEDSPLITTERTest.hxx" #include <cppunit/TestAssert.h> @@ -94,8 +93,8 @@ using namespace MEDMEM; void MEDSPLITTERTest::testMESHCollection_constructor() { - string data_dir = getenv("DATA_DIR"); - string filename_rd = data_dir + "/MedFiles/carre_en_quad4_import22.med"; + string data_dir = getenv("MED_ROOT_DIR"); + string filename_rd = data_dir + "/share/salome/resources/med/carre_en_quad4_import22.med"; string fileNotExist_rd = "notExist22.med"; string emptyfilename = ""; @@ -126,11 +125,11 @@ void MEDSPLITTERTest::testMESHCollection_constructor() //! Testing basic manipulation for a sequential file void MEDSPLITTERTest::testMESHCollection_read_seq() { - string data_dir = getenv("DATA_DIR"); + string data_dir = getenv("MED_ROOT_DIR"); string tmp_dir = getenv("TMP"); if (tmp_dir == "") tmp_dir = "/tmp"; - string filename_rd = data_dir + "/MedFiles/pointe_import22.med"; + string filename_rd = data_dir + "/share/salome/resources/med/pointe_import22.med"; string filename_seq_wr = tmp_dir + "/myWrField_seq_pointe22"; string filename_seq_med = tmp_dir + "/myWrField_seq_pointe221.med"; @@ -172,11 +171,11 @@ void MEDSPLITTERTest::testMESHCollection_read_seq() void MEDSPLITTERTest::testMESHCollection_read_para() { - string data_dir = getenv("DATA_DIR"); + string data_dir = getenv("MED_ROOT_DIR"); string tmp_dir = getenv("TMP"); if (tmp_dir == "") tmp_dir = "/tmp"; - string filename_rd = data_dir + "/MedFiles/pointe_import22.med"; + string filename_rd = data_dir + "/share/salome/resources/med/pointe_import22.med"; string filename_para_wr = tmp_dir + "/myWrField_para_pointe22_"; string filename_xml = tmp_dir + "/myWrField_para_pointe22_.xml"; string filename_para_med0 = tmp_dir + "/myWrField_para_pointe22_1.med"; @@ -255,11 +254,11 @@ void MEDSPLITTERTest::testMESHCollection_read_para() void MEDSPLITTERTest::testMESHCollection_square() { - string data_dir = getenv("DATA_DIR"); + string data_dir = getenv("MED_ROOT_DIR"); string tmp_dir = getenv("TMP"); if (tmp_dir == "") tmp_dir = "/tmp"; - string filename_rd = data_dir + "/MedFiles/carre_en_quad4_import22.med"; + string filename_rd = data_dir + "/share/salome/resources/med/carre_en_quad4_import22.med"; string filename_wr = tmp_dir+"/carre_split"; string filename_wr_1 = tmp_dir+"/carre_split1.med"; string filename_wr_2 = tmp_dir+"/carre_split2.med"; @@ -267,6 +266,7 @@ void MEDSPLITTERTest::testMESHCollection_square() // To remove tmp files from disk MEDSPLITTERTest_TmpFilesRemover aRemover; aRemover.Register(filename_wr); + aRemover.Register(filename_wr+".xml"); aRemover.Register(filename_wr_1); aRemover.Register(filename_wr_2); @@ -419,11 +419,11 @@ void MEDSPLITTERTest::testMESHCollection_square() void MEDSPLITTERTest::testMESHCollection_square_with_faces() { - string data_dir = getenv("DATA_DIR"); + string data_dir = getenv("MED_ROOT_DIR"); string tmp_dir = getenv("TMP"); if (tmp_dir == "") tmp_dir = "/tmp"; - string filename_rd = data_dir + "/MedFiles/carre_en_quad4_import22.med"; + string filename_rd = data_dir + "/share/salome/resources/med/carre_en_quad4_import22.med"; string filename_wr = tmp_dir+"/carre_split_faces"; string filename_wr_1 = tmp_dir+"/carre_split_faces1.med"; string filename_wr_2 = tmp_dir+"/carre_split_faces2.med"; @@ -431,6 +431,7 @@ void MEDSPLITTERTest::testMESHCollection_square_with_faces() // To remove tmp files from disk MEDSPLITTERTest_TmpFilesRemover aRemover; aRemover.Register(filename_wr); + aRemover.Register(filename_wr+".xml"); aRemover.Register(filename_wr_1); aRemover.Register(filename_wr_2); @@ -629,12 +630,13 @@ void MEDSPLITTERTest::testMESHCollection_square_with_faces() void MEDSPLITTERTest::testMESHCollection_indivisible() { - string data_dir = getenv("DATA_DIR"); + string data_dir = getenv("MED_ROOT_DIR"); string tmp_dir = getenv("TMP"); if (tmp_dir == "") tmp_dir = "/tmp"; - string filename_rd = data_dir + "/MedFiles/maill.00.med"; + string filename_rd = data_dir + "/share/salome/resources/med/maill.00.med"; string filename_wr = tmp_dir + "/carre_indivisible"; + string filename_wr_xml = tmp_dir + "/carre_indivisible.xml"; string filename_wr_1 = tmp_dir + "/carre_indivisible1.med"; string filename_wr_2 = tmp_dir + "/carre_indivisible2.med"; string filename_wr_3 = tmp_dir + "/carre_indivisible3.med"; @@ -643,6 +645,7 @@ void MEDSPLITTERTest::testMESHCollection_indivisible() // To remove tmp files from disk MEDSPLITTERTest_TmpFilesRemover aRemover; aRemover.Register(filename_wr); + aRemover.Register(filename_wr_xml); aRemover.Register(filename_wr_1); aRemover.Register(filename_wr_2); aRemover.Register(filename_wr_3); @@ -727,11 +730,11 @@ void MEDSPLITTERTest::testMESHCollection_indivisible() void MEDSPLITTERTest::testMESHCollection_user_partition() { - string data_dir = getenv("DATA_DIR"); + string data_dir = getenv("MED_ROOT_DIR"); string tmp_dir = getenv("TMP"); if (tmp_dir == "") tmp_dir = "/tmp"; - string filename_rd = data_dir + "/MedFiles/carre_en_quad4_import22.med"; + string filename_rd = data_dir + "/share/salome/resources/med/carre_en_quad4_import22.med"; string filename_wr = tmp_dir+"/carre_split_user"; string filename_wr_1 = tmp_dir+"/carre_split_user1.med"; string filename_wr_2 = tmp_dir+"/carre_split_user2.med"; @@ -739,6 +742,7 @@ void MEDSPLITTERTest::testMESHCollection_user_partition() // To remove tmp files from disk MEDSPLITTERTest_TmpFilesRemover aRemover; aRemover.Register(filename_wr); + aRemover.Register(filename_wr+".xml"); aRemover.Register(filename_wr_1); aRemover.Register(filename_wr_2); @@ -899,11 +903,11 @@ void MEDSPLITTERTest::testMESHCollection_user_partition() void MEDSPLITTERTest::testMESHCollection_complete_sequence() { - string data_dir = getenv("DATA_DIR"); + string data_dir = getenv("MED_ROOT_DIR"); string tmp_dir = getenv("TMP"); if (tmp_dir == "") tmp_dir = "/tmp"; - string filename_rd = data_dir + "/MedFiles/pointe_import22.med"; + string filename_rd = data_dir + "/share/salome/resources/med/pointe_import22.med"; string filename_para_wr = tmp_dir + "/myWrField_para1_pointe22_"; string filename_para_med1 = tmp_dir + "/myWrField_para1_pointe22_1.med"; string filename_para_med2 = tmp_dir + "/myWrField_para1_pointe22_2.med"; @@ -925,6 +929,7 @@ void MEDSPLITTERTest::testMESHCollection_complete_sequence() aRemover.Register(filename_para2_med2); aRemover.Register(filename_para2_med3); aRemover.Register(filename_seq_wr); + aRemover.Register(filename_seq_wr+".xml"); aRemover.Register(filename_seq_med); @@ -977,11 +982,11 @@ void MEDSPLITTERTest::testMESHCollection_complete_sequence() void MEDSPLITTERTest::testMESHCollection_complete_sequence_with_polygon() { - string data_dir = getenv("DATA_DIR"); + string data_dir = getenv("MED_ROOT_DIR"); string tmp_dir = getenv("TMP"); if (tmp_dir == "") tmp_dir = "/tmp"; - string filename_rd = data_dir + "/MedFiles/recoll_bord.med"; + string filename_rd = data_dir + "/share/salome/resources/med/recoll_bord.med"; string filename_para_wr = tmp_dir + "/myWrField_para_recoll_"; string filename_para_med1 = tmp_dir + "/myWrField_para_recoll_1.med"; string filename_para_med2 = tmp_dir + "/myWrField_para_recoll_2.med"; @@ -1003,6 +1008,7 @@ void MEDSPLITTERTest::testMESHCollection_complete_sequence_with_polygon() aRemover.Register(filename_para2_med2); aRemover.Register(filename_para2_med3); aRemover.Register(filename_seq_wr); + aRemover.Register(filename_seq_wr+".xml"); aRemover.Register(filename_seq_med); @@ -1052,11 +1058,11 @@ void MEDSPLITTERTest::testMESHCollection_complete_sequence_with_polygon() void MEDSPLITTERTest::testMESHCollection_complete_sequence_with_polyhedra() { - string data_dir = getenv("DATA_DIR"); + string data_dir = getenv("MED_ROOT_DIR"); string tmp_dir = getenv("TMP"); if (tmp_dir == "") tmp_dir = "/tmp"; - string filename_rd = data_dir + "/MedFiles/poly3D.med"; + string filename_rd = data_dir + "/share/salome/resources/med/poly3D.med"; //string filename_rd = "/tmp/polyedres.med" ; string filename_para_wr = tmp_dir + "/myWrField_para_poly3D_"; string filename_para_med1 = tmp_dir + "/myWrField_para_poly3D_1.med"; @@ -1120,11 +1126,11 @@ void MEDSPLITTERTest::testMESHCollection_complete_sequence_with_polyhedra() void MEDSPLITTERTest::testMESHCollection_families() { - string data_dir = getenv("DATA_DIR"); + string data_dir = getenv("MED_ROOT_DIR"); string tmp_dir = getenv("TMP"); if (tmp_dir == "") tmp_dir = "/tmp"; - string filename_rd = data_dir + "/MedFiles/trio_2D.med"; + string filename_rd = data_dir + "/share/salome/resources/med/trio_2D.med"; string filename_wr = tmp_dir+"/trio_split_faces"; string filename_wr_1 = tmp_dir+"/trio_split_faces1.med"; string filename_wr_2 = tmp_dir+"/trio_split_faces2.med"; @@ -1132,8 +1138,9 @@ void MEDSPLITTERTest::testMESHCollection_families() // To remove tmp files from disk MEDSPLITTERTest_TmpFilesRemover aRemover; aRemover.Register(filename_wr); - // aRemover.Register(filename_wr_1); - //aRemover.Register(filename_wr_2); + aRemover.Register(filename_wr+".xml"); + aRemover.Register(filename_wr_1); + aRemover.Register(filename_wr_2); char meshname[30] = "dom"; char meshname1[30] = "dom_1"; diff --git a/src/MEDSPLITTER/Test/MEDSPLITTERTest_ParallelTopology.cxx b/src/MEDSPLITTER/Test/MEDSPLITTERTest_ParallelTopology.cxx index eae90c611..ef46386f4 100644 --- a/src/MEDSPLITTER/Test/MEDSPLITTERTest_ParallelTopology.cxx +++ b/src/MEDSPLITTER/Test/MEDSPLITTERTest_ParallelTopology.cxx @@ -1,22 +1,21 @@ -// Copyright (C) 2006 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// 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. // -// 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. +// 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 +// 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 // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com - #include "MEDSPLITTERTest.hxx" #include <cppunit/TestAssert.h> @@ -107,11 +106,11 @@ void MEDSPLITTERTest::testParallelTopology_graph_constructor() #ifndef ENABLE_METIS CPPUNIT_FAIL("METIS is not available. Please, check your compilation."); #else - string data_dir = getenv("DATA_DIR"); + string data_dir = getenv("MED_ROOT_DIR"); string tmp_dir = getenv("TMP"); if (tmp_dir == "") tmp_dir = "/tmp"; - string filename_rd = data_dir + "/MedFiles/carre_en_quad4_import22.med"; + string filename_rd = data_dir + "/share/salome/resources/med/carre_en_quad4_import22.med"; string filename_para_wr = tmp_dir + "/myWrField_seq_pointe22_"; string filename_para_med0 = tmp_dir + "/myWrField_seq_pointe22_1.med"; string filename_para_med1 = tmp_dir + "/myWrField_seq_pointe22_2.med"; diff --git a/src/MEDSPLITTER/Test/Makefile.am b/src/MEDSPLITTER/Test/Makefile.am index 9b4fb93fd..ce6421630 100644 --- a/src/MEDSPLITTER/Test/Makefile.am +++ b/src/MEDSPLITTER/Test/Makefile.am @@ -1,7 +1,4 @@ -# SALOMELocalTrace : log on local machine -# -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2007-2008 CEA/DEN, 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 @@ -19,6 +16,8 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # +# SALOMELocalTrace : log on local machine +# include $(top_srcdir)/adm_local/unix/make_common_starter.am lib_LTLIBRARIES = libMEDSPLITTERTest.la @@ -33,7 +32,7 @@ salomeinclude_HEADERS = MEDSPLITTERTest.hxx libMEDSPLITTERTest_la_CPPFLAGS= @CPPUNIT_INCLUDES@ $(MED2_INCLUDES) \ $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ $(BOOST_CPPFLAGS) $(LIBXML_CXXFLAGS) \ -I$(srcdir)/.. -I$(srcdir)/../../MEDWrapper/V2_1/Core -I$(srcdir)/../../MEDMEM \ - -I$(srcdir)/../../MEDMEM/Test + -I$(srcdir)/../../MEDMEMCppTest libMEDSPLITTERTest_la_LDFLAGS= $(MED2_LIBS) @CPPUNIT_LIBS@ if MED_ENABLE_KERNEL @@ -63,5 +62,8 @@ if MED_ENABLE_KERNEL TestMEDSPLITTER_LDADD+= -lSALOMEBasics endif -salomescript_DATA = testMEDSPLITTER.py +dist_salomescript_DATA = testMEDSPLITTER.py + UNIT_TEST_PROG = TestMEDSPLITTER + +check: tests diff --git a/src/MEDSPLITTER/Test/TestMEDSPLITTER.cxx b/src/MEDSPLITTER/Test/TestMEDSPLITTER.cxx index b58602cad..1770a1d50 100644 --- a/src/MEDSPLITTER/Test/TestMEDSPLITTER.cxx +++ b/src/MEDSPLITTER/Test/TestMEDSPLITTER.cxx @@ -1,25 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// 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. // -// 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. +// 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 +// 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 +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // - // --- include all MEDMEM Test - +// #include "MEDSPLITTERTest.hxx" // --- Registers the fixture into the 'registry' diff --git a/src/MEDSPLITTER/Test/testMEDSPLITTER.py b/src/MEDSPLITTER/Test/testMEDSPLITTER.py index e3b224781..0309dd2fb 100644 --- a/src/MEDSPLITTER/Test/testMEDSPLITTER.py +++ b/src/MEDSPLITTER/Test/testMEDSPLITTER.py @@ -1,4 +1,4 @@ -# Copyright (C) 2005 CEA/DEN, EDF R&D, OPEN CASCADE, PRINCIPIA R&D +# Copyright (C) 2007-2008 CEA/DEN, 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 @@ -16,7 +16,6 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # - import os # execute Unit Test diff --git a/src/MEDSPLITTER/medsplitter.cxx b/src/MEDSPLITTER/medsplitter.cxx index a9c080c83..43b6ea2da 100644 --- a/src/MEDSPLITTER/medsplitter.cxx +++ b/src/MEDSPLITTER/medsplitter.cxx @@ -1,32 +1,28 @@ -// MED medsplitter : tool to split n MED files into p separate -// MED files with a partitioning specified -// by an external tool +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// 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. +// +// 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 // +// MED medsplitter : tool to split n MED files into p separate +// MED files with a partitioning specified +// by an external tool // File : medsplitter.cxx // Author : Vincent BERGEAUD (CEA-DEN/DANS/DM2S/SFME/LGLS) // Module : MED - +// #ifdef BOOST_PROGRAM_OPTIONS_LIB #include <boost/program_options.hpp> namespace po=boost::program_options; @@ -291,6 +287,12 @@ int main(int argc, char** argv) // Creating a new mesh collection from the partitioning MEDSPLITTER::MESHCollection new_collection(*collection, new_topo, split_families, empty_groups); + if (mesh_only) + { + delete collection; + collection=0; + } + if (!xml_output_master) new_collection.setDriverType(MEDSPLITTER::MedAscii); diff --git a/src/MEDSPLITTER/test_HighLevelAPI.cxx b/src/MEDSPLITTER/test_HighLevelAPI.cxx index e9265c033..4b0dfd23d 100644 --- a/src/MEDSPLITTER/test_HighLevelAPI.cxx +++ b/src/MEDSPLITTER/test_HighLevelAPI.cxx @@ -1,3 +1,21 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// #include "MEDSPLITTER_API.hxx" #include <string> diff --git a/src/MEDSPLITTER_Swig/MEDSPLITTER.py b/src/MEDSPLITTER_Swig/MEDSPLITTER.py new file mode 100644 index 000000000..c902f3b1d --- /dev/null +++ b/src/MEDSPLITTER_Swig/MEDSPLITTER.py @@ -0,0 +1,19 @@ +# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG +# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT +# 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. +# +# 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 +# +from libMEDSPLITTER_Swig import * diff --git a/src/MEDSPLITTER_Swig/Makefile.am b/src/MEDSPLITTER_Swig/Makefile.am new file mode 100644 index 000000000..d863654c4 --- /dev/null +++ b/src/MEDSPLITTER_Swig/Makefile.am @@ -0,0 +1,58 @@ +# MED MEDMEM_SWIG : binding of C++ implementation and Python +# +# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +lib_LTLIBRARIES = _libMEDSPLITTER_Swig.la + +salomeinclude_HEADERS = \ + libMEDSPLITTER_Swig.i + +SWIG_DEF = libMEDSPLITTER_Swig.i + +SWIG_FLAGS = @SWIG_FLAGS@ -I$(srcdir) -I$(srcdir)/../MEDMEM_SWIG + +dist__libMEDSPLITTER_Swig_la_SOURCES = libMEDSPLITTER_Swig.i +nodist__libMEDSPLITTER_Swig_la_SOURCES = libMEDSPLITTER_Swig_wrap.cxx +libMEDSPLITTER_Swig.py: libMEDSPLITTER_Swig_wrap.cxx + +libMEDSPLITTER_Swig_wrap.cxx: $(SWIG_DEF) + $(SWIG) $(SWIG_FLAGS) -o $@ $< + +_libMEDSPLITTER_Swig_la_CPPFLAGS = $(CORBA_CXXFLAGS) $(CORBA_INCLUDES) $(PYTHON_INCLUDES) \ + $(MED2_INCLUDES) $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ \ + -I$(srcdir)/../MEDMEM -I$(srcdir)/../MEDWrapper/V2_1/Core -I$(srcdir)/../INTERP_KERNEL \ + -I$(srcdir)/../MEDSPLITTER + +_libMEDSPLITTER_Swig_la_LDFLAGS = -module $(MED2_LIBS) $(HDF5_LIBS) $(PYTHON_LIBS) \ + ../MEDMEM/libmedmem.la ../INTERP_KERNEL/libinterpkernel.la \ + ../MEDSPLITTER/libmedsplitter.la + +if MED_ENABLE_KERNEL + _libMEDSPLITTER_Swig_la_CPPFLAGS += ${KERNEL_CXXFLAGS} + _libMEDSPLITTER_Swig_la_LDFLAGS += ${KERNEL_LDFLAGS} -lSALOMELocalTrace +endif + +CLEANFILES = libMEDSPLITTER_Swig_wrap.cxx libMEDSPLITTER_Swig.py + +nodist_salomescript_DATA = libMEDSPLITTER_Swig.py +dist_salomescript_DATA = MEDSPLITTER.py test_MEDSPLITTER.py diff --git a/src/MEDSPLITTER_Swig/libMEDSPLITTER_Swig.i b/src/MEDSPLITTER_Swig/libMEDSPLITTER_Swig.i new file mode 100644 index 000000000..d74113d6c --- /dev/null +++ b/src/MEDSPLITTER_Swig/libMEDSPLITTER_Swig.i @@ -0,0 +1,69 @@ +// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +%module libMEDSPLITTER_Swig + +%{ +#include "MEDMEM_Mesh.hxx" +#include<MEDSPLITTER_Topology.hxx> +#include<MEDSPLITTER_MESHCollection.hxx> + +using namespace MEDSPLITTER; + +typedef enum {METIS,SCOTCH} splitter_type; +%} + +typedef enum {METIS,SCOTCH} splitter_type; +typedef enum{MedAscii, MedXML, Undefined} DriverType; + +%include "my_typemap.i" + +namespace MEDSPLITTER { +class Graph { +public: + typedef enum {METIS,SCOTCH} splitter_type; + %extend { + Graph() {return 0;} + } +}; +} + +class MESHCollection { +public: + MESHCollection(const MESHCollection&, MEDSPLITTER::Topology*, + bool family_splitting=false, bool create_empty_groups=false); + MESHCollection(const char* filename); + MESHCollection(const char* filename, char* meshname); + + MEDSPLITTER::Topology* createPartition(int nbdomain, + MEDSPLITTER::Graph::splitter_type splitter_type = METIS, + const char* theStr=0); + MEDSPLITTER::Topology* createPartition(const int* partition); + + void setDriverType(::DriverType type); + void setSubdomainBoundaryCreates(bool flag); + + void write(const char* filename); + void castAllFields(const MESHCollection& old_collection); + void castFamilies(const MESHCollection& old_collection); + void castField(const MESHCollection& old_collection, const char* fieldname, + int itnumber, int ordernumber); + + void setIndivisibleGroup(const std::string& a); +}; diff --git a/src/MEDSPLITTER_Swig/test_MEDSPLITTER.py b/src/MEDSPLITTER_Swig/test_MEDSPLITTER.py new file mode 100644 index 000000000..1c859152b --- /dev/null +++ b/src/MEDSPLITTER_Swig/test_MEDSPLITTER.py @@ -0,0 +1,31 @@ +from MEDSPLITTER import * +import os + +#Beginning of the computation + +#Loading the mesh collection +print "reading files" + +data_dir = os.getenv("MED_ROOT_DIR") +filename_rd = os.path.join( data_dir, "share/salome/resources/med/pointe_import22.med") +meshname="maa1" + +collection = MESHCollection(filename_rd,meshname) + +print "MEDSPLITTER - computing partition " + + +new_topo = collection.createPartition(4,METIS); + +# Creating a new mesh collection from the partitioning +new_collection = MESHCollection(collection, new_topo, 1, 1); + + +new_collection.setSubdomainBoundaryCreates(1); + +print "MEDSPLITTER - writing output files " +new_collection.write("/tmp/myOutput.med") + +# Casting the fields on the new collection +new_collection.castAllFields(collection); + diff --git a/src/MEDWrapper/Base/MED_Algorithm.cxx b/src/MEDWrapper/Base/MED_Algorithm.cxx index 2ecf0ca18..c47acbb1e 100644 --- a/src/MEDWrapper/Base/MED_Algorithm.cxx +++ b/src/MEDWrapper/Base/MED_Algorithm.cxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #include "MED_Algorithm.hxx" #include "MED_Wrapper.hxx" @@ -173,7 +171,7 @@ namespace MED if(aTimeStampInfoSet.empty()) continue; const PTimeStampInfo& aTimeStampInfo = *aTimeStampInfoSet.begin(); - anEntite2TFieldInfo2TimeStampInfoSet[aTimeStampInfo->GetEntity()].insert(*anIter); + anEntite2TFieldInfo2TimeStampInfoSet[ConvertEntity(aTimeStampInfo->GetEntity())].insert(*anIter); } return anEntite2TFieldInfo2TimeStampInfoSet; } @@ -364,4 +362,18 @@ namespace MED for(TInt i=0; i<aNbCells; i++) aFamily2NbCells[theInfo->GetFamNum(i)] += 1; return aFamily2NbCells; } + + EEntiteMaillage ConvertEntity(const EEntiteMaillage& aEntity){ + switch( aEntity ){ + + case eNOEUD_ELEMENT: + case eMAILLE: return eMAILLE; //eNOEUD_ELEMENT it is eMAILLE + + case eFACE: + case eARETE: + case eNOEUD: return aEntity; break; + default: return EEntiteMaillage(-1); + + } + } } diff --git a/src/MEDWrapper/Base/MED_Algorithm.hxx b/src/MEDWrapper/Base/MED_Algorithm.hxx index 3e6e44ac9..044003ec9 100644 --- a/src/MEDWrapper/Base/MED_Algorithm.hxx +++ b/src/MEDWrapper/Base/MED_Algorithm.hxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #ifndef MED_Algorithm_HeaderFile #define MED_Algorithm_HeaderFile @@ -152,7 +150,12 @@ namespace MED MEDWRAPPER_EXPORT TFamilyID2NbCells GetFamilyID2NbCells(PGrilleInfo& theInfo); - + + //! Convert eNOEUD_ELEMENT to eMAILLE + MEDWRAPPER_EXPORT + EEntiteMaillage + ConvertEntity(const EEntiteMaillage& aEntity); + } #endif diff --git a/src/MEDWrapper/Base/MED_Common.hxx b/src/MEDWrapper/Base/MED_Common.hxx index 2e7b8e174..580c2bdfd 100644 --- a/src/MEDWrapper/Base/MED_Common.hxx +++ b/src/MEDWrapper/Base/MED_Common.hxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #ifndef MED_Common_HeaderFile #define MED_Common_HeaderFile @@ -78,7 +76,7 @@ namespace MED{ ePYRA13=313, ePENTA15=315, eHEXA20=320, ePOLYGONE=400, ePOLYEDRE=500, eNONE=0} EGeometrieElement; - typedef enum {eMAILLE, eFACE, eARETE, eNOEUD} EEntiteMaillage; + typedef enum {eMAILLE, eFACE, eARETE, eNOEUD, eNOEUD_ELEMENT} EEntiteMaillage; typedef enum {eNO_PFLMOD, eGLOBAL, eCOMPACT} EModeProfil; @@ -102,19 +100,19 @@ namespace MED{ GetEntity2GeomSet(); template<EVersion> - TInt + TInt MEDWRAPPER_EXPORT GetDESCLength(); template<EVersion> - TInt + TInt MEDWRAPPER_EXPORT GetIDENTLength(); template<EVersion> - TInt + TInt MEDWRAPPER_EXPORT GetNOMLength(); template<EVersion> - TInt + TInt MEDWRAPPER_EXPORT GetLNOMLength(); template<EVersion> @@ -180,7 +178,7 @@ namespace MED{ struct TWrapper; typedef SharedPtr<TWrapper> PWrapper; -}; +} #endif diff --git a/src/MEDWrapper/Base/MED_CoordUtils.cxx b/src/MEDWrapper/Base/MED_CoordUtils.cxx index 72247833d..6ae9c7608 100644 --- a/src/MEDWrapper/Base/MED_CoordUtils.cxx +++ b/src/MEDWrapper/Base/MED_CoordUtils.cxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #include "MED_CoordUtils.hxx" #include "MED_Utilities.hxx" diff --git a/src/MEDWrapper/Base/MED_CoordUtils.hxx b/src/MEDWrapper/Base/MED_CoordUtils.hxx index 6c875e374..2f412cb18 100644 --- a/src/MEDWrapper/Base/MED_CoordUtils.hxx +++ b/src/MEDWrapper/Base/MED_CoordUtils.hxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #ifndef MED_CoordUtils_HeaderFile #define MED_CoordUtils_HeaderFile diff --git a/src/MEDWrapper/Base/MED_GaussDef.cxx b/src/MEDWrapper/Base/MED_GaussDef.cxx index 1b51cb60c..e96043736 100644 --- a/src/MEDWrapper/Base/MED_GaussDef.cxx +++ b/src/MEDWrapper/Base/MED_GaussDef.cxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : MED_GaussDef.hxx // Module : MED // Author : Edward AGAPOV (eap) // $Header: - +// #include "MED_GaussDef.hxx" #include "MED_Utilities.hxx" #include "MED_GaussUtils.hxx" diff --git a/src/MEDWrapper/Base/MED_GaussDef.hxx b/src/MEDWrapper/Base/MED_GaussDef.hxx index 4e0d1ab36..dc434b8d7 100644 --- a/src/MEDWrapper/Base/MED_GaussDef.hxx +++ b/src/MEDWrapper/Base/MED_GaussDef.hxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : MED_GaussDef.hxx // Module : MED // Author : Edward AGAPOV (eap) // $Header: - +// #ifndef MED_GaussDef_HeaderFile #define MED_GaussDef_HeaderFile diff --git a/src/MEDWrapper/Base/MED_GaussUtils.cxx b/src/MEDWrapper/Base/MED_GaussUtils.cxx index 87550c06e..cf99acc78 100644 --- a/src/MEDWrapper/Base/MED_GaussUtils.cxx +++ b/src/MEDWrapper/Base/MED_GaussUtils.cxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #include "MED_GaussUtils.hxx" #include "MED_Utilities.hxx" @@ -1479,12 +1477,19 @@ namespace MED for(TInt aGaussId = 0; aGaussId < aNbGauss; aGaussId++){ const TCCoordSlice& aCoord = theGauss[aGaussId]; TFloatVecSlice aSlice = theFun.GetFunSlice(aGaussId); - - aSlice[0] = 0.25*(-aCoord[0] + aCoord[1] + aCoord[2] - 1.0)*(-aCoord[0] - aCoord[1] + aCoord[2] - 1.0)/(1.0 - aCoord[2]); - aSlice[1] = 0.25*(-aCoord[0] - aCoord[1] + aCoord[2] - 1.0)*(+aCoord[0] - aCoord[1] + aCoord[2] - 1.0)/(1.0 - aCoord[2]); - aSlice[2] = 0.25*(+aCoord[0] + aCoord[1] + aCoord[2] - 1.0)*(+aCoord[0] - aCoord[1] + aCoord[2] - 1.0)/(1.0 - aCoord[2]); - aSlice[3] = 0.25*(+aCoord[0] + aCoord[1] + aCoord[2] - 1.0)*(-aCoord[0] + aCoord[1] + aCoord[2] - 1.0)/(1.0 - aCoord[2]); - aSlice[4] = 1.0 - aCoord[2]; + // APO & RNV: + // Fix for 0019920: EDF 788 VISU: Bad localisation of gauss points for pyramids + // Seems shape function for ePYRA5 elements is: + // w0 = 0.25*(-X + Y - 1.0)*(-X - Y - 1.0)*(1.0 - Z); + // w1 = 0.25*(-X - Y - 1.0)*(+X - Y - 1.0)*(1.0 - Z); + // w2 = 0.25*(+X + Y - 1.0)*(+X - Y - 1.0)*(1.0 - Z); + // w3 = 0.25*(+X + Y - 1.0)*(-X + Y - 1.0)*(1.0 - Z); + // w4 = +Z; + aSlice[0] = 0.25*(-aCoord[0] + aCoord[1] - 1.0)*(-aCoord[0] - aCoord[1] - 1.0)*(1.0 - aCoord[2]); + aSlice[1] = 0.25*(-aCoord[0] - aCoord[1] - 1.0)*(+aCoord[0] - aCoord[1] - 1.0)*(1.0 - aCoord[2]); + aSlice[2] = 0.25*(+aCoord[0] + aCoord[1] - 1.0)*(+aCoord[0] - aCoord[1] - 1.0)*(1.0 - aCoord[2]); + aSlice[3] = 0.25*(+aCoord[0] + aCoord[1] - 1.0)*(-aCoord[0] + aCoord[1] - 1.0)*(1.0 - aCoord[2]); + aSlice[4] = aCoord[2]; } } @@ -1497,7 +1502,7 @@ namespace MED TInt aNbRef = myRefCoord.size(); for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ + switch(aRefId){ case 0: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; case 3: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; @@ -1513,20 +1518,27 @@ namespace MED TFun& theFun) const { GetFun(theRef,theGauss,theFun); - + TInt aNbGauss = theGauss.size(); for(TInt aGaussId = 0; aGaussId < aNbGauss; aGaussId++){ const TCCoordSlice& aCoord = theGauss[aGaussId]; TFloatVecSlice aSlice = theFun.GetFunSlice(aGaussId); - - aSlice[0] = 0.25*(-aCoord[0] + aCoord[1] + aCoord[2] - 1.0)*(-aCoord[0] - aCoord[1] + aCoord[2] - 1.0)/(1.0 - aCoord[2]); - aSlice[3] = 0.25*(-aCoord[0] - aCoord[1] + aCoord[2] - 1.0)*(+aCoord[0] - aCoord[1] + aCoord[2] - 1.0)/(1.0 - aCoord[2]); - aSlice[2] = 0.25*(+aCoord[0] + aCoord[1] + aCoord[2] - 1.0)*(+aCoord[0] - aCoord[1] + aCoord[2] - 1.0)/(1.0 - aCoord[2]); - aSlice[1] = 0.25*(+aCoord[0] + aCoord[1] + aCoord[2] - 1.0)*(-aCoord[0] + aCoord[1] + aCoord[2] - 1.0)/(1.0 - aCoord[2]); - aSlice[4] = 1.0 - aCoord[2]; + // APO & RNV: + // Fix for 0019920: EDF 788 VISU: Bad localisation of gauss points for pyramids + // Seems shape function for ePYRA5 elements is: + // w0 = 0.25*(-X + Y - 1.0)*(-X - Y - 1.0)*(1.0 - Z); + // w1 = 0.25*(-X - Y - 1.0)*(+X - Y - 1.0)*(1.0 - Z); + // w2 = 0.25*(+X + Y - 1.0)*(+X - Y - 1.0)*(1.0 - Z); + // w3 = 0.25*(+X + Y - 1.0)*(-X + Y - 1.0)*(1.0 - Z); + // w4 = +Z; + aSlice[0] = 0.25*(-aCoord[0] + aCoord[1] - 1.0)*(-aCoord[0] - aCoord[1] - 1.0)*(1.0 - aCoord[2]); + aSlice[3] = 0.25*(-aCoord[0] - aCoord[1] - 1.0)*(+aCoord[0] - aCoord[1] - 1.0)*(1.0 - aCoord[2]); + aSlice[2] = 0.25*(+aCoord[0] + aCoord[1] - 1.0)*(+aCoord[0] - aCoord[1] - 1.0)*(1.0 - aCoord[2]); + aSlice[1] = 0.25*(+aCoord[0] + aCoord[1] - 1.0)*(-aCoord[0] + aCoord[1] - 1.0)*(1.0 - aCoord[2]); + aSlice[4] = aCoord[2]; } } - + //--------------------------------------------------------------- diff --git a/src/MEDWrapper/Base/MED_GaussUtils.hxx b/src/MEDWrapper/Base/MED_GaussUtils.hxx index 14de39d57..c2c6f8c04 100644 --- a/src/MEDWrapper/Base/MED_GaussUtils.hxx +++ b/src/MEDWrapper/Base/MED_GaussUtils.hxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #ifndef MED_GaussUtils_HeaderFile #define MED_GaussUtils_HeaderFile diff --git a/src/MEDWrapper/Base/MED_SharedPtr.hxx b/src/MEDWrapper/Base/MED_SharedPtr.hxx index 8c1b2b509..b3bf0d975 100644 --- a/src/MEDWrapper/Base/MED_SharedPtr.hxx +++ b/src/MEDWrapper/Base/MED_SharedPtr.hxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #ifndef MED_SharedPtr_HeaderFile #define MED_SharedPtr_HeaderFile diff --git a/src/MEDWrapper/Base/MED_SliceArray.hxx b/src/MEDWrapper/Base/MED_SliceArray.hxx index cce9c465c..4abde7e4c 100644 --- a/src/MEDWrapper/Base/MED_SliceArray.hxx +++ b/src/MEDWrapper/Base/MED_SliceArray.hxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #ifndef MED_SliceArray_HeaderFile #define MED_SliceArray_HeaderFile diff --git a/src/MEDWrapper/Base/MED_Structures.cxx b/src/MEDWrapper/Base/MED_Structures.cxx index a00690550..4eebda592 100644 --- a/src/MEDWrapper/Base/MED_Structures.cxx +++ b/src/MEDWrapper/Base/MED_Structures.cxx @@ -1,11 +1,28 @@ -// Copyright (C) 2003 CEA/DEN, EDF R&D +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 // // File : MED_Structure.cxx // Author : Eugeny NIKOLAEV // Module : MED - +// #include "MED_Structures.hxx" #include "MED_Utilities.hxx" diff --git a/src/MEDWrapper/Base/MED_Structures.hxx b/src/MEDWrapper/Base/MED_Structures.hxx index ee0e0e3e9..835a89230 100644 --- a/src/MEDWrapper/Base/MED_Structures.hxx +++ b/src/MEDWrapper/Base/MED_Structures.hxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #ifndef MED_Structures_HeaderFile #define MED_Structures_HeaderFile diff --git a/src/MEDWrapper/Base/MED_TStructures.hxx b/src/MEDWrapper/Base/MED_TStructures.hxx index 15794a80b..30314f8bc 100644 --- a/src/MEDWrapper/Base/MED_TStructures.hxx +++ b/src/MEDWrapper/Base/MED_TStructures.hxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #ifndef MED_TStructures_HeaderFile #define MED_TStructures_HeaderFile @@ -459,11 +457,9 @@ namespace MED myCoord.reset(new TNodeCoord(theNbElem * theMeshInfo->myDim)); - if(theIsElemNum) - myCoordUnits.resize(theMeshInfo->myDim*GetPNOMLength<eVersion>()+1); + myCoordUnits.resize(theMeshInfo->myDim*GetPNOMLength<eVersion>()+1); - if(theIsElemNames) - myCoordNames.resize(theMeshInfo->myDim*GetPNOMLength<eVersion>()+1); + myCoordNames.resize(theMeshInfo->myDim*GetPNOMLength<eVersion>()+1); } diff --git a/src/MEDWrapper/Base/MED_TWrapper.hxx b/src/MEDWrapper/Base/MED_TWrapper.hxx index 1df33bd86..313f8a3a1 100644 --- a/src/MEDWrapper/Base/MED_TWrapper.hxx +++ b/src/MEDWrapper/Base/MED_TWrapper.hxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #ifndef MED_TWrapper_HeaderFile #define MED_TWrapper_HeaderFile diff --git a/src/MEDWrapper/Base/MED_Utilities.cxx b/src/MEDWrapper/Base/MED_Utilities.cxx index c459ae26d..d393f9476 100644 --- a/src/MEDWrapper/Base/MED_Utilities.cxx +++ b/src/MEDWrapper/Base/MED_Utilities.cxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #include "MED_Utilities.hxx" #include "MED_Common.hxx" diff --git a/src/MEDWrapper/Base/MED_Utilities.hxx b/src/MEDWrapper/Base/MED_Utilities.hxx index 0d3aee086..5109b2c58 100644 --- a/src/MEDWrapper/Base/MED_Utilities.hxx +++ b/src/MEDWrapper/Base/MED_Utilities.hxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #ifndef MED_Utilities_HeaderFile #define MED_Utilities_HeaderFile @@ -49,7 +47,7 @@ namespace MED static std::string GetPrefix(); }; -}; +} #ifdef _DEBUG_ #define MSG(deb,msg) if(deb) std::cout<<MED::PrefixPrinter::GetPrefix()<<msg<<" ("<<__FILE__<<" ["<<__LINE__<<"])\n" diff --git a/src/MEDWrapper/Base/MED_Vector.hxx b/src/MEDWrapper/Base/MED_Vector.hxx index f1a6d4ae6..96e20bbce 100644 --- a/src/MEDWrapper/Base/MED_Vector.hxx +++ b/src/MEDWrapper/Base/MED_Vector.hxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #ifndef MED_Vector_HeaderFile #define MED_Vector_HeaderFile @@ -79,9 +77,9 @@ namespace MED superclass(__a) {} - TVector(size_type __n, const value_type& __value, + TVector(size_type __n, const value_type& __val, const allocator_type& __a = allocator_type()): - superclass(__n, __value, __a) + superclass(__n, __val, __a) {} explicit diff --git a/src/MEDWrapper/Base/MED_Wrapper.cxx b/src/MEDWrapper/Base/MED_Wrapper.cxx index 979e59178..bf1e325d8 100644 --- a/src/MEDWrapper/Base/MED_Wrapper.cxx +++ b/src/MEDWrapper/Base/MED_Wrapper.cxx @@ -1,11 +1,28 @@ -// Copyright (C) 2003 CEA/DEN, EDF R&D +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 // // File : MED_Wrapper.cxx // Author : Alexey PETROV // Module : MED - +// #include "MED_Wrapper.hxx" #include "MED_Utilities.hxx" @@ -23,7 +40,11 @@ namespace MED ::TLockProxy(TWrapper* theWrapper): myWrapper(theWrapper) { +#if BOOST_VERSION >= 103500 + myWrapper->myMutex.lock(); +#else boost::detail::thread::lock_ops<TWrapper::TMutex>::lock(myWrapper->myMutex); +#endif INITMSG(MYDEBUG,"TLockProxy() - this -"<<this<<"; myWrapper = "<<myWrapper<<std::endl); } @@ -31,7 +52,11 @@ namespace MED ::~TLockProxy() { INITMSG(MYDEBUG,"~TLockProxy() - this -"<<this<<"; myWrapper = "<<myWrapper<<std::endl); +#if BOOST_VERSION >= 103500 + myWrapper->myMutex.unlock(); +#else boost::detail::thread::lock_ops<TWrapper::TMutex>::unlock(myWrapper->myMutex); +#endif } TWrapper* @@ -662,5 +687,5 @@ namespace MED { PGrilleInfo anInfo = CrGrilleInfo(theMeshInfo,theInfo); return anInfo; - } + } } diff --git a/src/MEDWrapper/Base/MED_Wrapper.hxx b/src/MEDWrapper/Base/MED_Wrapper.hxx index 67c995c4f..bc9ba4014 100644 --- a/src/MEDWrapper/Base/MED_Wrapper.hxx +++ b/src/MEDWrapper/Base/MED_Wrapper.hxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #ifndef MED_Wrapper_HeaderFile #define MED_Wrapper_HeaderFile diff --git a/src/MEDWrapper/Base/MED_WrapperBase.hxx b/src/MEDWrapper/Base/MED_WrapperBase.hxx index b0bbf02e6..6897f9fc6 100755 --- a/src/MEDWrapper/Base/MED_WrapperBase.hxx +++ b/src/MEDWrapper/Base/MED_WrapperBase.hxx @@ -1,28 +1,28 @@ -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. +// +// 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 // // File : MED_WrapperBase.hxx // Author : Alexander A. BORODIN // Module : MED - +// #ifndef _MED_WrapperBase_HXX_ #define _MED_WrapperBase_HXX_ diff --git a/src/MEDWrapper/Base/Makefile.am b/src/MEDWrapper/Base/Makefile.am index 5786b153b..963323790 100644 --- a/src/MEDWrapper/Base/Makefile.am +++ b/src/MEDWrapper/Base/Makefile.am @@ -1,31 +1,29 @@ -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # +# 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. # +# 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 # # File : # Author : # Module : # $Header$ - +# include $(top_srcdir)/adm_local/unix/make_common_starter.am lib_LTLIBRARIES= libMEDWrapperBase.la @@ -55,5 +53,11 @@ dist_libMEDWrapperBase_la_SOURCES= \ MED_Utilities.cxx \ MED_GaussDef.cxx -libMEDWrapperBase_la_CPPFLAGS= $(BOOST_CPPFLAGS) $(HDF5_INCLUDES) -D@MACHINE@ -I$(top_builddir)/salome_adm/unix $(MED_CPPFLAGS) +libMEDWrapperBase_la_CPPFLAGS= $(BOOST_CPPFLAGS) $(HDF5_INCLUDES) -D@MACHINE@ +if MED_ENABLE_KERNEL + libMEDWrapperBase_la_CPPFLAGS+= -I$(KERNEL_ROOT_DIR)/include/salome +else + libMEDWrapperBase_la_CPPFLAGS+= -I$(top_builddir)/adm_local_without_kernel/unix +endif +libMEDWrapperBase_la_CPPFLAGS+= $(MED_CPPFLAGS) libMEDWrapperBase_la_LDFLAGS= $(BOOST_LIBS) -lboost_thread${BOOST_LIBSUFFIX} diff --git a/src/MEDWrapper/Factory/MED_Factory.cxx b/src/MEDWrapper/Factory/MED_Factory.cxx index eb9a164e4..9fe683377 100644 --- a/src/MEDWrapper/Factory/MED_Factory.cxx +++ b/src/MEDWrapper/Factory/MED_Factory.cxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #include "MED_Factory.hxx" #include "MED_Utilities.hxx" #include "MED_V2_2_Wrapper.hxx" @@ -94,6 +92,23 @@ namespace MED return aVersion; } + bool getMEDVersion( const std::string& fname, int& major, int& minor, int& release ) + { + med_idt f = MEDouvrir( (char*)fname.c_str(), MED_LECTURE ); + if( f<0 ) + return false; + + med_int aMajor, aMinor, aRelease; + med_err aRet = MEDversionLire( f, &aMajor, &aMinor, &aRelease ); + major = aMajor; + minor = aMinor; + release = aRelease; + MEDfermer( f ); + if( aRet<0 ) + return false; + return true; + } + PWrapper CrWrapper(const std::string& theFileName, bool theDoPreCheckInSeparateProcess) { diff --git a/src/MEDWrapper/Factory/MED_Factory.hxx b/src/MEDWrapper/Factory/MED_Factory.hxx index 69a46dae4..c3837bde5 100644 --- a/src/MEDWrapper/Factory/MED_Factory.hxx +++ b/src/MEDWrapper/Factory/MED_Factory.hxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #ifndef MED_Factory_HeaderFile #define MED_Factory_HeaderFile @@ -38,6 +36,9 @@ namespace MED EVersion GetVersionId(const std::string& theFileName, bool theDoPreCheckInSeparateProcess = false); + + MEDWRAPPER_FACTORY_EXPORT + bool getMEDVersion( const std::string&, int&, int&, int& ); MEDWRAPPER_FACTORY_EXPORT PWrapper diff --git a/src/MEDWrapper/Factory/MED_Test.cxx b/src/MEDWrapper/Factory/MED_Test.cxx index 67ae2c862..7a4f28020 100644 --- a/src/MEDWrapper/Factory/MED_Test.cxx +++ b/src/MEDWrapper/Factory/MED_Test.cxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #include "MED_Utilities.hxx" #include "MED_Algorithm.hxx" #include "MED_GaussUtils.hxx" diff --git a/src/MEDWrapper/Factory/MED_WrapperFactory.hxx b/src/MEDWrapper/Factory/MED_WrapperFactory.hxx index c40f6cbd0..d9a0b9d11 100755 --- a/src/MEDWrapper/Factory/MED_WrapperFactory.hxx +++ b/src/MEDWrapper/Factory/MED_WrapperFactory.hxx @@ -1,28 +1,28 @@ -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. +// +// 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 // // File : MED_WrapperFactory.hxx // Author : Alexander A. BORODIN // Module : MED - +// #ifndef _MED_WrapperFactory_HXX_ #define _MED_WrapperFactory_HXX_ diff --git a/src/MEDWrapper/Factory/Makefile.am b/src/MEDWrapper/Factory/Makefile.am index 456cdaa57..3f374eddc 100644 --- a/src/MEDWrapper/Factory/Makefile.am +++ b/src/MEDWrapper/Factory/Makefile.am @@ -1,31 +1,29 @@ -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # +# 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. # +# 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 # # File : # Author : # Module : # $Header$ - +# include $(top_srcdir)/adm_local/unix/make_common_starter.am lib_LTLIBRARIES= libMEDWrapper.la @@ -38,7 +36,13 @@ dist_libMEDWrapper_la_SOURCES= \ MED_Factory.cxx libMEDWrapper_la_CPPFLAGS= $(BOOST_CPPFLAGS) $(MED2_INCLUDES) \ - -I$(srcdir)/../Base -I$(top_builddir)/salome_adm/unix -I$(srcdir)/../V2_1/Wrapper -I$(srcdir)/../V2_2 + -I$(srcdir)/../Base +if MED_ENABLE_KERNEL + libMEDWrapper_la_CPPFLAGS+= -I$(KERNEL_ROOT_DIR)/include/salome +else + libMEDWrapper_la_CPPFLAGS+= -I$(top_builddir)/adm_local_without_kernel/unix +endif +libMEDWrapper_la_CPPFLAGS+= -I$(srcdir)/../V2_1/Wrapper -I$(srcdir)/../V2_2 libMEDWrapper_la_LDFLAGS= ../V2_2/libMEDWrapper_V2_2.la ../V2_1/Wrapper/libMEDWrapper_V2_1.la # Executables targets diff --git a/src/MEDWrapper/Factory/mprint_version.cxx b/src/MEDWrapper/Factory/mprint_version.cxx index 72ef0ae91..445f359df 100644 --- a/src/MEDWrapper/Factory/mprint_version.cxx +++ b/src/MEDWrapper/Factory/mprint_version.cxx @@ -1,23 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // - extern "C"{ #include <med.h> } diff --git a/src/MEDWrapper/Makefile.am b/src/MEDWrapper/Makefile.am index 061fa236d..7f2dcf7eb 100644 --- a/src/MEDWrapper/Makefile.am +++ b/src/MEDWrapper/Makefile.am @@ -1,26 +1,26 @@ -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 # # $Header$ - +# include $(top_srcdir)/adm_local/unix/make_common_starter.am # if without KERNEL, build only med 2.1 library diff --git a/src/MEDWrapper/V2_1/Core/MEDattrNumLire.cxx b/src/MEDWrapper/V2_1/Core/MEDattrNumLire.cxx index 6d31bdee9..59b85a5ea 100644 --- a/src/MEDWrapper/V2_1/Core/MEDattrNumLire.cxx +++ b/src/MEDWrapper/V2_1/Core/MEDattrNumLire.cxx @@ -20,6 +20,8 @@ #include "med.hxx" #include "med_outils.hxx" +#include <cstring> + /* * - Nom de la fonction : _MEDattrNumLire * - Description : lecture d'un attribut entier diff --git a/src/MEDWrapper/V2_1/Core/MEDbodyFittedEcr.cxx b/src/MEDWrapper/V2_1/Core/MEDbodyFittedEcr.cxx index 9d7577b99..3c07c1e99 100644 --- a/src/MEDWrapper/V2_1/Core/MEDbodyFittedEcr.cxx +++ b/src/MEDWrapper/V2_1/Core/MEDbodyFittedEcr.cxx @@ -19,6 +19,8 @@ #include "med_outils.hxx" #include "med.hxx" +#include <cstring> + #if defined(HAVE_F77INT64) #define MED_INTEGER MED_INT64 #else diff --git a/src/MEDWrapper/V2_1/Core/MEDbodyFittedLire.cxx b/src/MEDWrapper/V2_1/Core/MEDbodyFittedLire.cxx index 75d1a4ae4..6273f4029 100644 --- a/src/MEDWrapper/V2_1/Core/MEDbodyFittedLire.cxx +++ b/src/MEDWrapper/V2_1/Core/MEDbodyFittedLire.cxx @@ -19,6 +19,8 @@ #include "med_outils.hxx" #include "med.hxx" +#include <cstring> + namespace med_2_1{ med_err diff --git a/src/MEDWrapper/V2_1/Core/MEDchampInfo.cxx b/src/MEDWrapper/V2_1/Core/MEDchampInfo.cxx index c3634ef10..22810797b 100644 --- a/src/MEDWrapper/V2_1/Core/MEDchampInfo.cxx +++ b/src/MEDWrapper/V2_1/Core/MEDchampInfo.cxx @@ -19,6 +19,8 @@ #include "med.hxx" #include "med_outils.hxx" +#include <cstring> + namespace med_2_1{ med_err diff --git a/src/MEDWrapper/V2_1/Core/MEDdatasetNumEcrire.cxx b/src/MEDWrapper/V2_1/Core/MEDdatasetNumEcrire.cxx index f2b1ce8d1..5c6f69ed9 100644 --- a/src/MEDWrapper/V2_1/Core/MEDdatasetNumEcrire.cxx +++ b/src/MEDWrapper/V2_1/Core/MEDdatasetNumEcrire.cxx @@ -219,7 +219,13 @@ _MEDdatasetNumEcrire(med_idt pere,char *nom, med_type_champ type, } } -#ifdef HDF_NEW_API +#ifdef HDF_NEW_API2 + if ( (ret = H5Sselect_elements(memspace,H5S_SELECT_SET, pcount[0], (const hsize_t *) pflmem ) ) <0) + return -1; + + if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET, pcount[0], (const hsize_t *) pfldsk ) ) <0) + return -1; +#elif defined HDF_NEW_API if ( (ret = H5Sselect_elements(memspace,H5S_SELECT_SET, pcount[0], (const hsize_t **) pflmem ) ) <0) return -1; @@ -254,7 +260,13 @@ _MEDdatasetNumEcrire(med_idt pere,char *nom, med_type_champ type, } } -#ifdef HDF_NEW_API +#ifdef HDF_NEW_API2 + if ( (ret = H5Sselect_elements(memspace,H5S_SELECT_SET, pcount[0], (const hsize_t *) pflmem ) ) <0) + return -1; + + if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET, pcount[0], (const hsize_t *) pfldsk ) ) <0) + return -1; +#elif defined HDF_NEW_API if ( (ret = H5Sselect_elements(memspace,H5S_SELECT_SET, pcount[0], (const hsize_t **) pflmem ) ) <0) return -1; @@ -341,7 +353,10 @@ _MEDdatasetNumEcrire(med_idt pere,char *nom, med_type_champ type, } } -#ifdef HDF_NEW_API +#ifdef HDF_NEW_API2 + if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET,pcount[0], (const hsize_t *) pfldsk ) ) <0) + return -1; +#elif defined HDF_NEW_API if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET,pcount[0], (const hsize_t **) pfldsk ) ) <0) return -1; #else @@ -381,7 +396,13 @@ _MEDdatasetNumEcrire(med_idt pere,char *nom, med_type_champ type, } } -#ifdef HDF_NEW_API +#ifdef HDF_NEW_API2 + if ( (ret = H5Sselect_elements(memspace ,H5S_SELECT_SET,pcount[0], (const hsize_t *) pflmem ) ) <0) + return -1; + + if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET,pcount[0], (const hsize_t *) pfldsk ) ) <0) + return -1; +#elif defined HDF_NEW_API if ( (ret = H5Sselect_elements(memspace ,H5S_SELECT_SET,pcount[0], (const hsize_t **) pflmem ) ) <0) return -1; diff --git a/src/MEDWrapper/V2_1/Core/MEDdatasetNumLire.cxx b/src/MEDWrapper/V2_1/Core/MEDdatasetNumLire.cxx index 8420c22f5..a11d83d4b 100644 --- a/src/MEDWrapper/V2_1/Core/MEDdatasetNumLire.cxx +++ b/src/MEDWrapper/V2_1/Core/MEDdatasetNumLire.cxx @@ -204,7 +204,13 @@ _MEDdatasetNumLire(med_idt pere,char *nom,med_type_champ type, } } -#ifdef HDF_NEW_API +#ifdef HDF_NEW_API2 + if ( (ret = H5Sselect_elements(memspace ,H5S_SELECT_SET, pcount[0], (const hsize_t *) pflmem ) ) <0) + return -1; + + if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET, pcount[0], (const hsize_t *) pfldsk ) ) <0) + return -1; +#elif defined HDF_NEW_API if ( (ret = H5Sselect_elements(memspace ,H5S_SELECT_SET, pcount[0], (const hsize_t **) pflmem ) ) <0) return -1; @@ -239,7 +245,13 @@ _MEDdatasetNumLire(med_idt pere,char *nom,med_type_champ type, } } -#ifdef HDF_NEW_API +#ifdef HDF_NEW_API2 + if ( (ret = H5Sselect_elements(memspace ,H5S_SELECT_SET, pcount[0], (const hsize_t *) pflmem ) ) <0) + return -1; + + if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET, pcount[0], (const hsize_t *) pfldsk ) ) <0) + return -1; +#elif defined HDF_NEW_API if ( (ret = H5Sselect_elements(memspace ,H5S_SELECT_SET, pcount[0], (const hsize_t **) pflmem ) ) <0) return -1; @@ -325,7 +337,10 @@ _MEDdatasetNumLire(med_idt pere,char *nom,med_type_champ type, } } -#ifdef HDF_NEW_API +#ifdef HDF_NEW_API2 + if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET,pcount[0], (const hsize_t *) pfldsk ) ) <0) + return -1; +#elif defined HDF_NEW_API if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET,pcount[0], (const hsize_t **) pfldsk ) ) <0) return -1; #else @@ -369,7 +384,13 @@ _MEDdatasetNumLire(med_idt pere,char *nom,med_type_champ type, } } -#ifdef HDF_NEW_API +#ifdef HDF_NEW_API2 + if ( (ret = H5Sselect_elements(memspace ,H5S_SELECT_SET, pcount[0], (const hsize_t *) pflmem ) ) <0) + return -1; + + if ( (ret = H5Sselect_elements(dataspace,H5S_SELECT_SET,pcount[0], (const hsize_t *) pfldsk ) ) <0) + return -1; +#elif defined HDF_NEW_API if ( (ret = H5Sselect_elements(memspace ,H5S_SELECT_SET, pcount[0], (const hsize_t **) pflmem ) ) <0) return -1; diff --git a/src/MEDWrapper/V2_1/Core/MEDfamMaaCr.cxx b/src/MEDWrapper/V2_1/Core/MEDfamMaaCr.cxx index f7dc6d2b4..fd542a207 100644 --- a/src/MEDWrapper/V2_1/Core/MEDfamMaaCr.cxx +++ b/src/MEDWrapper/V2_1/Core/MEDfamMaaCr.cxx @@ -20,6 +20,7 @@ #include "med_outils.hxx" #include <stdio.h> +#include <cstring> namespace med_2_1{ diff --git a/src/MEDWrapper/V2_1/Core/MEDgridCr.cxx b/src/MEDWrapper/V2_1/Core/MEDgridCr.cxx index 6e9ae942d..73c49747c 100644 --- a/src/MEDWrapper/V2_1/Core/MEDgridCr.cxx +++ b/src/MEDWrapper/V2_1/Core/MEDgridCr.cxx @@ -19,6 +19,8 @@ #include "med.hxx" #include "med_outils.hxx" +#include <cstring> + namespace med_2_1{ med_err diff --git a/src/MEDWrapper/V2_1/Core/MEDgridEcr.cxx b/src/MEDWrapper/V2_1/Core/MEDgridEcr.cxx index 3acc181ee..6e6079d06 100644 --- a/src/MEDWrapper/V2_1/Core/MEDgridEcr.cxx +++ b/src/MEDWrapper/V2_1/Core/MEDgridEcr.cxx @@ -19,6 +19,8 @@ #include "med_outils.hxx" #include "med.hxx" +#include <cstring> + namespace med_2_1{ med_err diff --git a/src/MEDWrapper/V2_1/Core/MEDgridLire.cxx b/src/MEDWrapper/V2_1/Core/MEDgridLire.cxx index 032266335..4877c9bf4 100644 --- a/src/MEDWrapper/V2_1/Core/MEDgridLire.cxx +++ b/src/MEDWrapper/V2_1/Core/MEDgridLire.cxx @@ -1,6 +1,8 @@ #include "med_outils.hxx" #include "med.hxx" +#include <cstring> + namespace med_2_1{ med_err diff --git a/src/MEDWrapper/V2_1/Core/MEDindiceInfo.cxx b/src/MEDWrapper/V2_1/Core/MEDindiceInfo.cxx index 4e88572f0..94c0af4a3 100644 --- a/src/MEDWrapper/V2_1/Core/MEDindiceInfo.cxx +++ b/src/MEDWrapper/V2_1/Core/MEDindiceInfo.cxx @@ -20,6 +20,8 @@ #include "med.hxx" #include "med_outils.hxx" +#include <cstring> + /* * - Nom de la fonction : _MEDindiceInfo * - Description : en argument de H5Giterate, donne le nom diff --git a/src/MEDWrapper/V2_1/Core/MEDnGrid.cxx b/src/MEDWrapper/V2_1/Core/MEDnGrid.cxx index 607888cf2..5da5dbbee 100644 --- a/src/MEDWrapper/V2_1/Core/MEDnGrid.cxx +++ b/src/MEDWrapper/V2_1/Core/MEDnGrid.cxx @@ -19,6 +19,8 @@ #include "med.hxx" #include "med_outils.hxx" +#include <cstring> + namespace med_2_1{ med_int diff --git a/src/MEDWrapper/V2_1/Core/MEDnomDataset.cxx b/src/MEDWrapper/V2_1/Core/MEDnomDataset.cxx index fe72b24bb..54b94eb9e 100644 --- a/src/MEDWrapper/V2_1/Core/MEDnomDataset.cxx +++ b/src/MEDWrapper/V2_1/Core/MEDnomDataset.cxx @@ -20,6 +20,8 @@ #include "med.hxx" #include "med_outils.hxx" +#include <cstring> + /* * - Nom de la fonction : _MEDnomDataset * - Description : fournit un nom de dataset diff --git a/src/MEDWrapper/V2_1/Core/MEDnomEntite.cxx b/src/MEDWrapper/V2_1/Core/MEDnomEntite.cxx index b5b4350fb..3e51b673e 100644 --- a/src/MEDWrapper/V2_1/Core/MEDnomEntite.cxx +++ b/src/MEDWrapper/V2_1/Core/MEDnomEntite.cxx @@ -19,6 +19,8 @@ #include "med.hxx" #include "med_outils.hxx" +#include <cstring> + /* * - Nom de la fonction : _MEDnomEntite * - Description : fournit le nom associe a un type d'entite MED diff --git a/src/MEDWrapper/V2_1/Core/MEDnomGeometrie.cxx b/src/MEDWrapper/V2_1/Core/MEDnomGeometrie.cxx index 3cbc6bbe0..1f04b02a1 100644 --- a/src/MEDWrapper/V2_1/Core/MEDnomGeometrie.cxx +++ b/src/MEDWrapper/V2_1/Core/MEDnomGeometrie.cxx @@ -19,6 +19,8 @@ #include "med.hxx" #include "med_outils.hxx" +#include <cstring> + /* * - Nom de la fonction : _MEDnomGeometrie * - Description : fournit le nom de l'element geometrique associe diff --git a/src/MEDWrapper/V2_1/Core/MEDpasdetempsInfo.cxx b/src/MEDWrapper/V2_1/Core/MEDpasdetempsInfo.cxx index 53a2e599d..e2a9435e9 100644 --- a/src/MEDWrapper/V2_1/Core/MEDpasdetempsInfo.cxx +++ b/src/MEDWrapper/V2_1/Core/MEDpasdetempsInfo.cxx @@ -19,6 +19,8 @@ #include "med.hxx" #include "med_outils.hxx" +#include <cstring> + /* Le nom de cette fonction n'est pas très bien choisie */ namespace med_2_1{ diff --git a/src/MEDWrapper/V2_1/Core/Makefile.am b/src/MEDWrapper/V2_1/Core/Makefile.am index 3888cebbc..afe5a090f 100644 --- a/src/MEDWrapper/V2_1/Core/Makefile.am +++ b/src/MEDWrapper/V2_1/Core/Makefile.am @@ -1,31 +1,29 @@ -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # +# 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. # +# 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 # # File : # Author : # Module : # $Header$ - +# include $(top_srcdir)/adm_local/unix/make_common_starter.am lib_LTLIBRARIES= libmed_V2_1.la diff --git a/src/MEDWrapper/V2_1/Core/hdf5_version2api.hxx b/src/MEDWrapper/V2_1/Core/hdf5_version2api.hxx index 2e353ea07..a4e21aea4 100644 --- a/src/MEDWrapper/V2_1/Core/hdf5_version2api.hxx +++ b/src/MEDWrapper/V2_1/Core/hdf5_version2api.hxx @@ -31,7 +31,12 @@ #if H5_VERS_RELEASE < 4 #else +#if H5_VERS_RELEASE >= 7 +#define HDF_NEW_API2 #define HDF_NEW_API +#else +#define HDF_NEW_API +#endif #endif #else /* H5_VERS_MINOR >= 7 */ diff --git a/src/MEDWrapper/V2_1/Makefile.am b/src/MEDWrapper/V2_1/Makefile.am index 984f31eec..b31495c1c 100644 --- a/src/MEDWrapper/V2_1/Makefile.am +++ b/src/MEDWrapper/V2_1/Makefile.am @@ -1,31 +1,29 @@ -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # +# 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. # +# 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 # # File : # Author : # Module : # $Header$ - +# include $(top_srcdir)/adm_local/unix/make_common_starter.am # if without KERNEL, build only med 2.1 library diff --git a/src/MEDWrapper/V2_1/Wrapper/MED_V2_1_Wrapper.cxx b/src/MEDWrapper/V2_1/Wrapper/MED_V2_1_Wrapper.cxx index eff67b417..e344a591f 100644 --- a/src/MEDWrapper/V2_1/Wrapper/MED_V2_1_Wrapper.cxx +++ b/src/MEDWrapper/V2_1/Wrapper/MED_V2_1_Wrapper.cxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #include "MED_V2_1_Wrapper.hxx" #include "MED_Algorithm.hxx" #include "MED_Utilities.hxx" diff --git a/src/MEDWrapper/V2_1/Wrapper/MED_V2_1_Wrapper.hxx b/src/MEDWrapper/V2_1/Wrapper/MED_V2_1_Wrapper.hxx index 74e88beb9..fcc360f91 100644 --- a/src/MEDWrapper/V2_1/Wrapper/MED_V2_1_Wrapper.hxx +++ b/src/MEDWrapper/V2_1/Wrapper/MED_V2_1_Wrapper.hxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #ifndef MED_V2_1_Wrapper_HeaderFile #define MED_V2_1_Wrapper_HeaderFile diff --git a/src/MEDWrapper/V2_1/Wrapper/Makefile.am b/src/MEDWrapper/V2_1/Wrapper/Makefile.am index ebe5acbbe..c70bd2053 100644 --- a/src/MEDWrapper/V2_1/Wrapper/Makefile.am +++ b/src/MEDWrapper/V2_1/Wrapper/Makefile.am @@ -1,31 +1,29 @@ -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # +# 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. # +# 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 # # File : # Author : # Module : # $Header$ - +# include $(top_srcdir)/adm_local/unix/make_common_starter.am lib_LTLIBRARIES= libMEDWrapper_V2_1.la @@ -37,6 +35,11 @@ dist_libMEDWrapper_V2_1_la_SOURCES= \ MED_V2_1_Wrapper.cxx libMEDWrapper_V2_1_la_CPPFLAGS= -D@MACHINE@ $(BOOST_CPPFLAGS) $(HDF5_INCLUDES) \ - -I$(srcdir)/../../Base -I$(srcdir)/../Core -I$(top_builddir)/salome_adm/unix + -I$(srcdir)/../../Base -I$(srcdir)/../Core +if MED_ENABLE_KERNEL + libMEDWrapper_V2_1_la_CPPFLAGS+= -I$(KERNEL_ROOT_DIR)/include/salome +else + libMEDWrapper_V2_1_la_CPPFLAGS+= -I$(top_builddir)/adm_local_without_kernel/unix +endif libMEDWrapper_V2_1_la_LDFLAGS= $(HDF5_LIBS) libMEDWrapper_V2_1_la_LIBADD= ../../Base/libMEDWrapperBase.la ../Core/libmed_V2_1.la diff --git a/src/MEDWrapper/V2_2/MED_V2_2_Wrapper.cxx b/src/MEDWrapper/V2_2/MED_V2_2_Wrapper.cxx index c4e2cc7dd..02b405037 100644 --- a/src/MEDWrapper/V2_2/MED_V2_2_Wrapper.cxx +++ b/src/MEDWrapper/V2_2/MED_V2_2_Wrapper.cxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #include "MED_V2_2_Wrapper.hxx" #include "MED_Algorithm.hxx" #include "MED_Utilities.hxx" @@ -1742,8 +1740,14 @@ namespace MED TValueHolder<TString, char> aFieldName(anInfo.myName); MED::TMeshInfo& aMeshInfo = anInfo.myMeshInfo; - TEntityInfo::const_iterator anIter = theEntityInfo.begin(); - for(; anIter != theEntityInfo.end(); anIter++){ + MED::TEntityInfo localEntityInfo = theEntityInfo; + TEntityInfo::iterator anLocalIter = localEntityInfo.find(eMAILLE); + if(anLocalIter != localEntityInfo.end()){ + localEntityInfo[eNOEUD_ELEMENT] = anLocalIter->second; + } + + TEntityInfo::const_iterator anIter = localEntityInfo.begin(); + for(; anIter != localEntityInfo.end(); anIter++){ med_entite_maillage anEntity = med_entite_maillage(anIter->first); const TGeom2Size& aGeom2Size = anIter->second; TGeom2Size::const_iterator anGeomIter = aGeom2Size.begin(); @@ -2024,18 +2028,6 @@ namespace MED } } - if(aNbGauss > 1 && !aGaussInfo){ - if(theErr){ - *theErr = MED_FAUX; - return; - } - EXCEPTION(std::runtime_error,"GetTimeStampValue "<< - "- aNbGauss("<<aNbGauss<<") > 1 && !aGaussInfo"<< - "; aGaussName = '"<<&aGaussName[0]<<"'"<< - "; aGeom = "<<aGeom<< - ""); - } - if(aGaussInfo && aNbGauss != aGaussInfo->GetNbGauss()){ if(theErr){ *theErr = MED_FAUX; @@ -2465,5 +2457,5 @@ namespace MED EXCEPTION(std::runtime_error,"GetGrilleInfo - MEDstructureCoordLire(...)"); } - } + } } diff --git a/src/MEDWrapper/V2_2/MED_V2_2_Wrapper.hxx b/src/MEDWrapper/V2_2/MED_V2_2_Wrapper.hxx index 6b7b22212..290aa73d1 100644 --- a/src/MEDWrapper/V2_2/MED_V2_2_Wrapper.hxx +++ b/src/MEDWrapper/V2_2/MED_V2_2_Wrapper.hxx @@ -1,31 +1,29 @@ -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // +// 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. // +// 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 // // File : // Author : // Module : // $Header$ - +// #ifndef MED_V2_2_Wrapper_HeaderFile #define MED_V2_2_Wrapper_HeaderFile diff --git a/src/MEDWrapper/V2_2/Makefile.am b/src/MEDWrapper/V2_2/Makefile.am index 36dfbfedb..73712d3f3 100644 --- a/src/MEDWrapper/V2_2/Makefile.am +++ b/src/MEDWrapper/V2_2/Makefile.am @@ -1,31 +1,29 @@ -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # +# 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. # +# 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 # # File : # Author : # Module : # $Header$ - +# include $(top_srcdir)/adm_local/unix/make_common_starter.am lib_LTLIBRARIES= libMEDWrapper_V2_2.la @@ -36,6 +34,11 @@ salomeinclude_HEADERS = \ dist_libMEDWrapper_V2_2_la_SOURCES = \ MED_V2_2_Wrapper.cxx -libMEDWrapper_V2_2_la_CPPFLAGS= $(BOOST_CPPFLAGS) $(MED2_INCLUDES) -I$(srcdir)/../Base -I$(top_builddir)/salome_adm/unix +libMEDWrapper_V2_2_la_CPPFLAGS= $(BOOST_CPPFLAGS) $(MED2_INCLUDES) -I$(srcdir)/../Base +if MED_ENABLE_KERNEL + libMEDWrapper_V2_2_la_CPPFLAGS+= -I$(KERNEL_ROOT_DIR)/include/salome +else + libMEDWrapper_V2_2_la_CPPFLAGS+= -I$(top_builddir)/adm_local_without_kernel/unix +endif libMEDWrapper_V2_2_la_LDFLAGS= $(MED2_LIBS) $(HDF5_LIBS) libMEDWrapper_V2_2_la_LIBADD= ../Base/libMEDWrapperBase.la diff --git a/src/MED_SWIG/MED_shared_modules.py b/src/MED_SWIG/MED_shared_modules.py index 3144240a2..dacbaa333 100644 --- a/src/MED_SWIG/MED_shared_modules.py +++ b/src/MED_SWIG/MED_shared_modules.py @@ -1,21 +1,24 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# """ """ diff --git a/src/MED_SWIG/Makefile.am b/src/MED_SWIG/Makefile.am index 949a25e60..65e356371 100644 --- a/src/MED_SWIG/Makefile.am +++ b/src/MED_SWIG/Makefile.am @@ -1,25 +1,26 @@ -# MED MED_SWIG : binding of C++ implementaion with Python +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # +# 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. +# +# 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 +# +# MED MED_SWIG : binding of C++ implementaion with Python # - include $(top_srcdir)/adm_local/unix/make_common_starter.am dist_sharedpkgpython_DATA= MED_shared_modules.py diff --git a/src/MULTIPR/MULTIPR_API.cxx b/src/MULTIPR/MULTIPR_API.cxx index aa8c04b01..7453c72b8 100755 --- a/src/MULTIPR/MULTIPR_API.cxx +++ b/src/MULTIPR/MULTIPR_API.cxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_API.cxx * diff --git a/src/MULTIPR/MULTIPR_API.hxx b/src/MULTIPR/MULTIPR_API.hxx index 23a34341c..60c282e00 100755 --- a/src/MULTIPR/MULTIPR_API.hxx +++ b/src/MULTIPR/MULTIPR_API.hxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_API.hxx * diff --git a/src/MULTIPR/MULTIPR_DecimationAccel.cxx b/src/MULTIPR/MULTIPR_DecimationAccel.cxx index c5f825fda..6cb8d96b8 100755 --- a/src/MULTIPR/MULTIPR_DecimationAccel.cxx +++ b/src/MULTIPR/MULTIPR_DecimationAccel.cxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_DecimationAccel.cxx * diff --git a/src/MULTIPR/MULTIPR_DecimationAccel.hxx b/src/MULTIPR/MULTIPR_DecimationAccel.hxx index d82472a0e..6010425b7 100755 --- a/src/MULTIPR/MULTIPR_DecimationAccel.hxx +++ b/src/MULTIPR/MULTIPR_DecimationAccel.hxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_DecimationAccel.hxx * diff --git a/src/MULTIPR/MULTIPR_DecimationFilter.cxx b/src/MULTIPR/MULTIPR_DecimationFilter.cxx index d3d1f8d25..1a8b45ae4 100755 --- a/src/MULTIPR/MULTIPR_DecimationFilter.cxx +++ b/src/MULTIPR/MULTIPR_DecimationFilter.cxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_DecimationFilter.cxx * diff --git a/src/MULTIPR/MULTIPR_DecimationFilter.hxx b/src/MULTIPR/MULTIPR_DecimationFilter.hxx index 31281b886..bd53c5772 100755 --- a/src/MULTIPR/MULTIPR_DecimationFilter.hxx +++ b/src/MULTIPR/MULTIPR_DecimationFilter.hxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_DecimationFilter.hxx * diff --git a/src/MULTIPR/MULTIPR_Elements.cxx b/src/MULTIPR/MULTIPR_Elements.cxx index ab223f278..be3dd1bef 100755 --- a/src/MULTIPR/MULTIPR_Elements.cxx +++ b/src/MULTIPR/MULTIPR_Elements.cxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_Elements.cxx * diff --git a/src/MULTIPR/MULTIPR_Elements.hxx b/src/MULTIPR/MULTIPR_Elements.hxx index ecd4248fc..cdaa14e55 100755 --- a/src/MULTIPR/MULTIPR_Elements.hxx +++ b/src/MULTIPR/MULTIPR_Elements.hxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_Elements.hxx * @@ -26,6 +43,7 @@ extern "C" #include "med.h" } +#include <iostream> #include <set> #include <vector> diff --git a/src/MULTIPR/MULTIPR_Exceptions.hxx b/src/MULTIPR/MULTIPR_Exceptions.hxx index 14c200e9f..546c1352c 100755 --- a/src/MULTIPR/MULTIPR_Exceptions.hxx +++ b/src/MULTIPR/MULTIPR_Exceptions.hxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_Exceptions.hxx * diff --git a/src/MULTIPR/MULTIPR_Family.cxx b/src/MULTIPR/MULTIPR_Family.cxx index 40373d3c2..ce7ac3a6b 100755 --- a/src/MULTIPR/MULTIPR_Family.cxx +++ b/src/MULTIPR/MULTIPR_Family.cxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_Family.cxx * diff --git a/src/MULTIPR/MULTIPR_Family.hxx b/src/MULTIPR/MULTIPR_Family.hxx index eab5065b2..4722444ff 100755 --- a/src/MULTIPR/MULTIPR_Family.hxx +++ b/src/MULTIPR/MULTIPR_Family.hxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_Family.hxx * diff --git a/src/MULTIPR/MULTIPR_Field.cxx b/src/MULTIPR/MULTIPR_Field.cxx index 67bae0f30..033455709 100755 --- a/src/MULTIPR/MULTIPR_Field.cxx +++ b/src/MULTIPR/MULTIPR_Field.cxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_Field.cxx * @@ -24,6 +41,7 @@ #include "MULTIPR_Profil.hxx" #include <iostream> +#include <limits> using namespace std; diff --git a/src/MULTIPR/MULTIPR_Field.hxx b/src/MULTIPR/MULTIPR_Field.hxx index f265d29bf..d1b3f400f 100755 --- a/src/MULTIPR/MULTIPR_Field.hxx +++ b/src/MULTIPR/MULTIPR_Field.hxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_Field.hxx * diff --git a/src/MULTIPR/MULTIPR_GaussLoc.cxx b/src/MULTIPR/MULTIPR_GaussLoc.cxx index eeeed7fac..b3d58d24d 100755 --- a/src/MULTIPR/MULTIPR_GaussLoc.cxx +++ b/src/MULTIPR/MULTIPR_GaussLoc.cxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_GaussLoc.cxx * diff --git a/src/MULTIPR/MULTIPR_GaussLoc.hxx b/src/MULTIPR/MULTIPR_GaussLoc.hxx index 6eb15f76f..e2c63d815 100755 --- a/src/MULTIPR/MULTIPR_GaussLoc.hxx +++ b/src/MULTIPR/MULTIPR_GaussLoc.hxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_GaussLoc.hxx * diff --git a/src/MULTIPR/MULTIPR_Globals.hxx b/src/MULTIPR/MULTIPR_Globals.hxx index a5897af2b..754ec7e6a 100755 --- a/src/MULTIPR/MULTIPR_Globals.hxx +++ b/src/MULTIPR/MULTIPR_Globals.hxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_Globals.hxx * diff --git a/src/MULTIPR/MULTIPR_Mesh.cxx b/src/MULTIPR/MULTIPR_Mesh.cxx index 4788b6087..fdbf87f18 100755 --- a/src/MULTIPR/MULTIPR_Mesh.cxx +++ b/src/MULTIPR/MULTIPR_Mesh.cxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_Mesh.cxx * diff --git a/src/MULTIPR/MULTIPR_Mesh.hxx b/src/MULTIPR/MULTIPR_Mesh.hxx index 72d75a1ec..0573a57cc 100755 --- a/src/MULTIPR/MULTIPR_Mesh.hxx +++ b/src/MULTIPR/MULTIPR_Mesh.hxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_Mesh.hxx * diff --git a/src/MULTIPR/MULTIPR_MeshDis.cxx b/src/MULTIPR/MULTIPR_MeshDis.cxx index 5eaa381ed..3b1d826fa 100755 --- a/src/MULTIPR/MULTIPR_MeshDis.cxx +++ b/src/MULTIPR/MULTIPR_MeshDis.cxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_MeshDis.cxx * diff --git a/src/MULTIPR/MULTIPR_MeshDis.hxx b/src/MULTIPR/MULTIPR_MeshDis.hxx index 45f76db43..65c269c75 100755 --- a/src/MULTIPR/MULTIPR_MeshDis.hxx +++ b/src/MULTIPR/MULTIPR_MeshDis.hxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_MeshDis.hxx * diff --git a/src/MULTIPR/MULTIPR_Nodes.cxx b/src/MULTIPR/MULTIPR_Nodes.cxx index e3596a491..1d3ba2497 100755 --- a/src/MULTIPR/MULTIPR_Nodes.cxx +++ b/src/MULTIPR/MULTIPR_Nodes.cxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_Nodes.cxx * @@ -19,6 +36,7 @@ #include "MULTIPR_Exceptions.hxx" #include <iostream> +#include <limits> using namespace std; diff --git a/src/MULTIPR/MULTIPR_Nodes.hxx b/src/MULTIPR/MULTIPR_Nodes.hxx index a33ffd43e..9b81216f8 100755 --- a/src/MULTIPR/MULTIPR_Nodes.hxx +++ b/src/MULTIPR/MULTIPR_Nodes.hxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_Nodes.hxx * diff --git a/src/MULTIPR/MULTIPR_Obj.cxx b/src/MULTIPR/MULTIPR_Obj.cxx index b081f81fc..1358b7ece 100755 --- a/src/MULTIPR/MULTIPR_Obj.cxx +++ b/src/MULTIPR/MULTIPR_Obj.cxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_Obj.cxx * diff --git a/src/MULTIPR/MULTIPR_Obj.hxx b/src/MULTIPR/MULTIPR_Obj.hxx index f6474bc62..1ba838d96 100755 --- a/src/MULTIPR/MULTIPR_Obj.hxx +++ b/src/MULTIPR/MULTIPR_Obj.hxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_GaussLoc.hxx * diff --git a/src/MULTIPR/MULTIPR_PointOfField.hxx b/src/MULTIPR/MULTIPR_PointOfField.hxx index bcf340654..88e7a131e 100755 --- a/src/MULTIPR/MULTIPR_PointOfField.hxx +++ b/src/MULTIPR/MULTIPR_PointOfField.hxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_PointOfField.hxx * @@ -22,7 +39,7 @@ extern "C" { #include "med.h" } - +#include <limits> namespace multipr { diff --git a/src/MULTIPR/MULTIPR_Profil.cxx b/src/MULTIPR/MULTIPR_Profil.cxx index 11649e374..f15d65d07 100755 --- a/src/MULTIPR/MULTIPR_Profil.cxx +++ b/src/MULTIPR/MULTIPR_Profil.cxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_Profil.cxx * diff --git a/src/MULTIPR/MULTIPR_Profil.hxx b/src/MULTIPR/MULTIPR_Profil.hxx index fba60ff0b..d423afa48 100755 --- a/src/MULTIPR/MULTIPR_Profil.hxx +++ b/src/MULTIPR/MULTIPR_Profil.hxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_Profil.hxx * @@ -27,6 +44,7 @@ extern "C" #include <vector> #include <set> +#include <iostream> namespace multipr { diff --git a/src/MULTIPR/MULTIPR_ProgressCallback.hxx b/src/MULTIPR/MULTIPR_ProgressCallback.hxx index 22f6938d4..59136238d 100755 --- a/src/MULTIPR/MULTIPR_ProgressCallback.hxx +++ b/src/MULTIPR/MULTIPR_ProgressCallback.hxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_ProgressCallback.hxx * diff --git a/src/MULTIPR/MULTIPR_Utils.cxx b/src/MULTIPR/MULTIPR_Utils.cxx index ed0a3e95f..ce4ee0733 100755 --- a/src/MULTIPR/MULTIPR_Utils.cxx +++ b/src/MULTIPR/MULTIPR_Utils.cxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_Utils.cxx * diff --git a/src/MULTIPR/MULTIPR_Utils.hxx b/src/MULTIPR/MULTIPR_Utils.hxx index e77bec718..4d3779e0f 100755 --- a/src/MULTIPR/MULTIPR_Utils.hxx +++ b/src/MULTIPR/MULTIPR_Utils.hxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file MULTIPR_Utils.hxx * diff --git a/src/MULTIPR/Makefile.am b/src/MULTIPR/Makefile.am index 0aafc5b70..d5c90a943 100644 --- a/src/MULTIPR/Makefile.am +++ b/src/MULTIPR/Makefile.am @@ -1,23 +1,21 @@ -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, 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. +# +# 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 # - include $(top_srcdir)/adm_local/unix/make_common_starter.am lib_LTLIBRARIES= libMULTIPR_API.la diff --git a/src/MULTIPR/multipr.cxx b/src/MULTIPR/multipr.cxx index b06f612d6..18ac87f02 100755 --- a/src/MULTIPR/multipr.cxx +++ b/src/MULTIPR/multipr.cxx @@ -1,6 +1,23 @@ -// Project MULTIPR, IOLS WP1.2.1 - EDF/CS +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// // Partitioning/decimation module for the SALOME v3.2 platform - +// /** * \file multipr.cxx * diff --git a/src/Makefile.am b/src/Makefile.am index 6e901cee2..7f55d52cf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,6 @@ -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # # This library is free software; you can redistribute it and/or @@ -15,14 +17,23 @@ # 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 - +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# include $(top_srcdir)/adm_local/unix/make_common_starter.am -SUBDIRS = MEDWrapper MEDMEM INTERPOLATION MEDMEM_SWIG +SUBDIRS = MEDWrapper INTERP_KERNEL MEDMEM MEDCoupling INTERPOLATION MEDMEM_SWIG MEDMEMBinTest $(MPIDIR) + +if CPPUNIT_IS_OK + SUBDIRS+= MEDMEMCppTest INTERP_KERNELTest +endif + +if MPI_IS_OK + SUBDIRS+= ParaMEDMEM +endif if MED_ENABLE_SPLITTER - SUBDIRS+= MEDSPLITTER + SUBDIRS+= MEDSPLITTER MEDSPLITTER_Swig + # MULTIPR if MED_ENABLE_METIS @@ -42,4 +53,4 @@ if MED_ENABLE_GUI SUBDIRS+= MEDGUI endif -DIST_SUBDIRS= MEDWrapper INTERPOLATION MEDMEM MEDMEM_SWIG MEDSPLITTER MULTIPR MEDMEM_I MED MedCorba_Swig MED_SWIG MedClient MEDGUI +DIST_SUBDIRS= MEDWrapper INTERPOLATION MEDCoupling MEDMEM INTERP_KERNEL MEDMEM_SWIG MEDMEMBinTest MEDMEMCppTest MEDSPLITTER MULTIPR ParaMEDMEM ParaMEDMEM_Swig MEDMEM_I MED MedCorba_Swig MED_SWIG MedClient MEDGUI diff --git a/src/MedClient/Makefile.am b/src/MedClient/Makefile.am index 4cda3c5b9..73c2fdf0c 100644 --- a/src/MedClient/Makefile.am +++ b/src/MedClient/Makefile.am @@ -1,24 +1,24 @@ -# MED MedClient : tool to transfer MED CORBA from server producer of MED object to a client using those MED object +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# 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 +# +# MED MedClient : tool to transfer MED CORBA from server producer of MED object to a client using those MED object # - SUBDIRS = src test diff --git a/src/MedClient/src/CONNECTIVITYClient.cxx b/src/MedClient/src/CONNECTIVITYClient.cxx index 07fe4a369..82f63946b 100644 --- a/src/MedClient/src/CONNECTIVITYClient.cxx +++ b/src/MedClient/src/CONNECTIVITYClient.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MEDMEM_convert.hxx" #include "Utils_CorbaException.hxx" @@ -37,13 +39,14 @@ CONNECTIVITYClient::CONNECTIVITYClient(const SALOME_MED::MESH_ptr m, _numberOfElements_client(0), _complete(false) { - BEGIN_OF("CONNECTIVITYClient::CONNECTIVITYClient()"); + const char* LOC = "CONNECTIVITYClient::CONNECTIVITYClient()"; + BEGIN_OF(LOC); ASSERT(m); blankCopy(); - END_OF("CONNECTIVITYClient::CONNECTIVITYClient()"); + END_OF(LOC); } //============================================================================= @@ -53,12 +56,13 @@ CONNECTIVITYClient::CONNECTIVITYClient(const SALOME_MED::MESH_ptr m, //============================================================================= CONNECTIVITYClient::~CONNECTIVITYClient() { - BEGIN_OF("CONNECTIVITYClient::~CONNECTIVITYClient()"); + const char* LOC = "CONNECTIVITYClient::~CONNECTIVITYClient()"; + BEGIN_OF(LOC); if (_numberOfElements_client) delete [] _numberOfElements_client; - END_OF("CONNECTIVITYClient::~CONNECTIVITYClient()"); + END_OF(LOC); } //============================================================================= @@ -69,7 +73,8 @@ CONNECTIVITYClient::~CONNECTIVITYClient() //============================================================================= void CONNECTIVITYClient::blankCopy() { - BEGIN_OF("CONNECTIVITYClient::blankCopy()"); + const char* LOC = "CONNECTIVITYClient::blankCopy()"; + BEGIN_OF(LOC); SALOME_MED::MESH::connectivityInfos_var all; medEntityMesh Entity = getEntity(); try @@ -134,7 +139,7 @@ void CONNECTIVITYClient::blankCopy() _complete = false; - END_OF("CONNECTIVITYClient::blankCopy()"); + END_OF(LOC); } //============================================================================= @@ -154,7 +159,8 @@ void CONNECTIVITYClient::blankCopy() void CONNECTIVITYClient::fillCopy() { - BEGIN_OF("void CONNECTIVITYClient::fillCopy()"); + const char* LOC = "void CONNECTIVITYClient::fillCopy()"; + BEGIN_OF(LOC); if (!_complete) { @@ -236,7 +242,7 @@ void CONNECTIVITYClient::fillCopy() _complete = true; } - END_OF("void CONNECTIVITYClient::fillCopy()"); + END_OF(LOC); } //============================================================================= @@ -246,7 +252,8 @@ void CONNECTIVITYClient::fillCopy() int CONNECTIVITYClient::getNumberOf(medEntityMesh Entity, medGeometryElement Type) const { - BEGIN_OF("void CONNECTIVITYClient::getNumberOf()"); + const char* LOC = "void CONNECTIVITYClient::getNumberOf()"; + BEGIN_OF(LOC); int n = 0; @@ -276,7 +283,7 @@ int CONNECTIVITYClient::getNumberOf(medEntityMesh Entity, n = CONNECTIVITY::getNumberOf(Entity, Type); SCRUTE(n); - END_OF("void CONNECTIVITYClient::getNumberOf()"); + END_OF(LOC); return n; } @@ -289,7 +296,8 @@ const int * CONNECTIVITYClient::getConnectivity medEntityMesh Entity, medGeometryElement Type) { - BEGIN_OF("void CONNECTIVITYClient::getConnectivity()"); + const char* LOC = "void CONNECTIVITYClient::getConnectivity()"; + BEGIN_OF(LOC); if (!_complete) fillCopy(); @@ -297,7 +305,7 @@ const int * CONNECTIVITYClient::getConnectivity const int * c = CONNECTIVITY::getConnectivity (ConnectivityType, Entity, Type); - END_OF("void CONNECTIVITYClient::getConnectivity()"); + END_OF(LOC); return c; } @@ -309,7 +317,8 @@ const int * CONNECTIVITYClient::getConnectivityIndex (medConnectivity ConnectivityType, medEntityMesh Entity) { - BEGIN_OF("void CONNECTIVITYClient::getConnectivityIndex()"); + const char* LOC = "void CONNECTIVITYClient::getConnectivityIndex()"; + BEGIN_OF(LOC); if (!_complete) fillCopy(); @@ -317,7 +326,7 @@ const int * CONNECTIVITYClient::getConnectivityIndex const int *c = CONNECTIVITY::getConnectivityIndex (ConnectivityType, Entity); - END_OF("void CONNECTIVITYClient::getConnectivityIndex()"); + END_OF(LOC); return c; } @@ -329,14 +338,15 @@ void CONNECTIVITYClient::calculateConnectivity (medConnectivity connectivityType, medEntityMesh Entity) { - BEGIN_OF("void CONNECTIVITYClient::calculateConnectivity()"); + const char* LOC = "void CONNECTIVITYClient::calculateConnectivity()"; + BEGIN_OF(LOC); if (!_complete) fillCopy(); CONNECTIVITY::calculateConnectivity(connectivityType, Entity); - END_OF("void CONNECTIVITYClient::calculateConnectivity()"); + END_OF(LOC); } //============================================================================= @@ -345,14 +355,15 @@ void CONNECTIVITYClient::calculateConnectivity //============================================================================= void CONNECTIVITYClient::updateFamily (vector<FAMILY*> myFamilies) { - BEGIN_OF("void CONNECTIVITYClient::updateFamily()"); + const char* LOC = "void CONNECTIVITYClient::updateFamily()"; + BEGIN_OF(LOC); if (!_complete) fillCopy(); CONNECTIVITY::updateFamily(myFamilies); - END_OF("void CONNECTIVITYClient::updateFamily()"); + END_OF(LOC); } //============================================================================= @@ -362,14 +373,15 @@ void CONNECTIVITYClient::updateFamily (vector<FAMILY*> myFamilies) const int * CONNECTIVITYClient::getGlobalNumberingIndex (medEntityMesh Entity) const throw (MEDEXCEPTION) { - BEGIN_OF("void CONNECTIVITYClient::getGlobalNumberingIndex()"); + const char* LOC = "void CONNECTIVITYClient::getGlobalNumberingIndex()"; + BEGIN_OF(LOC); if (!_complete) (const_cast<CONNECTIVITYClient *>(this))->fillCopy(); const int * index = CONNECTIVITY::getGlobalNumberingIndex(Entity); - END_OF("void CONNECTIVITYClient::getGlobalNumberingIndex()"); + END_OF(LOC); return index; } @@ -381,14 +393,15 @@ const int * CONNECTIVITYClient::getGlobalNumberingIndex bool CONNECTIVITYClient::existConnectivity(medConnectivity ConnectivityType, medEntityMesh Entity) const { - BEGIN_OF("void CONNECTIVITYClient::existConnectivity()"); + const char* LOC = "void CONNECTIVITYClient::existConnectivity()"; + BEGIN_OF(LOC); if (!_complete) (const_cast<CONNECTIVITYClient *>(this))->fillCopy(); bool b = CONNECTIVITY::existConnectivity(ConnectivityType, Entity); - END_OF("void CONNECTIVITYClient::existConnectivity()"); + END_OF(LOC); return b; } @@ -401,7 +414,8 @@ const int * CONNECTIVITYClient::getReverseConnectivity (medConnectivity ConnectivityType, medEntityMesh Entity) throw (MEDEXCEPTION) { - BEGIN_OF("void CONNECTIVITYClient::getReverseConnectivity()"); + const char* LOC = "void CONNECTIVITYClient::getReverseConnectivity()"; + BEGIN_OF(LOC); if (!_complete) fillCopy(); @@ -409,7 +423,7 @@ const int * CONNECTIVITYClient::getReverseConnectivity const int *c = CONNECTIVITY::getReverseConnectivity (ConnectivityType, Entity); - END_OF("void CONNECTIVITYClient::getReverseConnectivity()"); + END_OF(LOC); return c; } @@ -422,7 +436,8 @@ const int * CONNECTIVITYClient::getReverseConnectivityIndex (medConnectivity ConnectivityType, medEntityMesh Entity) throw (MEDEXCEPTION) { - BEGIN_OF("void CONNECTIVITYClient::getReverseConnectivityIndex()"); + const char* LOC = "void CONNECTIVITYClient::getReverseConnectivityIndex()"; + BEGIN_OF(LOC); if (!_complete) fillCopy(); @@ -430,7 +445,7 @@ const int * CONNECTIVITYClient::getReverseConnectivityIndex const int *c = CONNECTIVITY::getReverseConnectivityIndex (ConnectivityType, Entity); - END_OF("void CONNECTIVITYClient::getReverseConnectivityIndex()"); + END_OF(LOC); return c; } @@ -442,14 +457,15 @@ const int * CONNECTIVITYClient::getReverseConnectivityIndex const int* CONNECTIVITYClient::getValue(medConnectivity TypeConnectivity, medGeometryElement Type) { - BEGIN_OF("void CONNECTIVITYClient::getValue()"); + const char* LOC = "void CONNECTIVITYClient::getValue()"; + BEGIN_OF(LOC); if (!_complete) fillCopy(); const int * c = CONNECTIVITY::getValue(TypeConnectivity, Type); - END_OF("void CONNECTIVITYClient::()"); + END_OF(LOC); return c; } @@ -460,14 +476,15 @@ const int* CONNECTIVITYClient::getValue(medConnectivity TypeConnectivity, //============================================================================= const int* CONNECTIVITYClient::getValueIndex(medConnectivity TypeConnectivity) { - BEGIN_OF("void CONNECTIVITYClient::getValueIndex()"); + const char* LOC = "void CONNECTIVITYClient::getValueIndex()"; + BEGIN_OF(LOC); if (!_complete) fillCopy(); const int * c = CONNECTIVITY::getValueIndex(TypeConnectivity); - END_OF("void CONNECTIVITYClient::getValueIndex()"); + END_OF(LOC); return c; } @@ -478,14 +495,15 @@ const int* CONNECTIVITYClient::getValueIndex(medConnectivity TypeConnectivity) //============================================================================= const int* CONNECTIVITYClient::getNeighbourhood() const { - BEGIN_OF("void CONNECTIVITYClient::getNeighbourhood()"); + const char* LOC = "void CONNECTIVITYClient::getNeighbourhood()"; + BEGIN_OF(LOC); if (!_complete) (const_cast<CONNECTIVITYClient *>(this))->fillCopy(); const int * c = CONNECTIVITY::getNeighbourhood(); - END_OF("void CONNECTIVITYClient::getNeighbourhood()"); + END_OF(LOC); return c; } @@ -498,14 +516,15 @@ const int* CONNECTIVITYClient::getNeighbourhood() const bool CONNECTIVITYClient::existPolygonsConnectivity(medConnectivity connectivityType, medEntityMesh Entity) const { - BEGIN_OF("void CONNECTIVITYClient::existPolygonsConnectivity()"); + const char* LOC = "void CONNECTIVITYClient::existPolygonsConnectivity()"; + BEGIN_OF(LOC); if (!_complete) (const_cast<CONNECTIVITYClient *>(this))->fillCopy(); bool b = CONNECTIVITY::existPolygonsConnectivity( connectivityType, Entity ); - END_OF("void CONNECTIVITYClient::existPolygonsConnectivity(connectivityType, Entity)"); + END_OF(LOC); return b; } @@ -518,14 +537,15 @@ bool CONNECTIVITYClient::existPolygonsConnectivity(medConnectivity connectivityT bool CONNECTIVITYClient::existPolyhedronConnectivity(medConnectivity connectivityType, medEntityMesh Entity) const { - BEGIN_OF("void CONNECTIVITYClient::existPolyhedronConnectivity()"); + const char* LOC = "void CONNECTIVITYClient::existPolyhedronConnectivity()"; + BEGIN_OF(LOC); if (!_complete) (const_cast<CONNECTIVITYClient *>(this))->fillCopy(); bool b = CONNECTIVITY::existPolyhedronConnectivity( connectivityType, Entity ); - END_OF("void CONNECTIVITYClient::existPolyhedronConnectivity(connectivityType, Entity)"); + END_OF(LOC); return b; } @@ -538,14 +558,15 @@ bool CONNECTIVITYClient::existPolyhedronConnectivity(medConnectivity connectivit const int* CONNECTIVITYClient::getPolygonsConnectivity(medConnectivity ConnectivityType, medEntityMesh Entity) { - BEGIN_OF("void CONNECTIVITYClient::getPolygonsConnectivity()"); + const char* LOC = "void CONNECTIVITYClient::getPolygonsConnectivity()"; + BEGIN_OF(LOC); if (!_complete) fillCopy(); const int * c = CONNECTIVITY::getPolygonsConnectivity (ConnectivityType, Entity); - END_OF("void CONNECTIVITYClient::getPolygonsConnectivity()"); + END_OF(LOC); return c; } @@ -557,14 +578,15 @@ const int* CONNECTIVITYClient::getPolygonsConnectivity(medConnectivity Connectiv const int* CONNECTIVITYClient::getPolygonsConnectivityIndex(medConnectivity ConnectivityType, medEntityMesh Entity) { - BEGIN_OF("void CONNECTIVITYClient::getPolygonsConnectivityIndex()"); + const char* LOC = "void CONNECTIVITYClient::getPolygonsConnectivityIndex()"; + BEGIN_OF(LOC); if (!_complete) fillCopy(); const int * c = CONNECTIVITY::getPolygonsConnectivityIndex (ConnectivityType, Entity); - END_OF("void CONNECTIVITYClient::getPolygonsConnectivityIndex()"); + END_OF(LOC); return c; } @@ -575,14 +597,15 @@ const int* CONNECTIVITYClient::getPolygonsConnectivityIndex(medConnectivity Conn const int* CONNECTIVITYClient::getPolyhedronConnectivity(medConnectivity ConnectivityType) const { - BEGIN_OF("void CONNECTIVITYClient::getPolyhedronConnectivity()"); + const char* LOC = "void CONNECTIVITYClient::getPolyhedronConnectivity()"; + BEGIN_OF(LOC); if (!_complete) (const_cast<CONNECTIVITYClient *>(this))->fillCopy(); const int * c = CONNECTIVITY::getPolyhedronConnectivity (ConnectivityType); - END_OF("void CONNECTIVITYClient::getPolyhedronConnectivity()"); + END_OF(LOC); return c; } @@ -593,14 +616,15 @@ const int* CONNECTIVITYClient::getPolyhedronConnectivity(medConnectivity Connect const int* CONNECTIVITYClient::getPolyhedronFacesIndex() const { - BEGIN_OF("void CONNECTIVITYClient::getPolyhedronFacesIndex()"); + const char* LOC = "void CONNECTIVITYClient::getPolyhedronFacesIndex()"; + BEGIN_OF(LOC); if (!_complete) (const_cast<CONNECTIVITYClient *>(this))->fillCopy(); const int * c = CONNECTIVITY::getPolyhedronFacesIndex(); - END_OF("void CONNECTIVITYClient::getPolyhedronFacesIndex()"); + END_OF(LOC); return c; } @@ -611,14 +635,15 @@ const int* CONNECTIVITYClient::getPolyhedronFacesIndex() const const int* CONNECTIVITYClient::getPolyhedronIndex(medConnectivity ConnectivityType) const { - BEGIN_OF("void CONNECTIVITYClient::getPolyhedronIndex()"); + const char* LOC = "void CONNECTIVITYClient::getPolyhedronIndex()"; + BEGIN_OF(LOC); if (!_complete) (const_cast<CONNECTIVITYClient *>(this))->fillCopy(); const int * c = CONNECTIVITY::getPolyhedronIndex (ConnectivityType); - END_OF("void CONNECTIVITYClient::getPolyhedronIndex()"); + END_OF(LOC); return c; } @@ -629,7 +654,8 @@ const int* CONNECTIVITYClient::getPolyhedronIndex(medConnectivity ConnectivityTy int CONNECTIVITYClient::getNumberOfPolygons() const { - BEGIN_OF("void CONNECTIVITYClient::getNumberOfPolygons()"); + const char* LOC = "void CONNECTIVITYClient::getNumberOfPolygons()"; + BEGIN_OF(LOC); int n = 0; @@ -642,7 +668,7 @@ int CONNECTIVITYClient::getNumberOfPolygons() const SCRUTE(n); - END_OF("void CONNECTIVITYClient::getNumberOfPolygons()"); + END_OF(LOC); return n; } @@ -653,7 +679,8 @@ int CONNECTIVITYClient::getNumberOfPolygons() const int CONNECTIVITYClient::getNumberOfPolyhedronFaces() const { - BEGIN_OF("void CONNECTIVITYClient::getNumberOfPolyhedronFaces()"); + const char* LOC = "void CONNECTIVITYClient::getNumberOfPolyhedronFaces()"; + BEGIN_OF(LOC); if (!_complete) (const_cast<CONNECTIVITYClient *>(this))->fillCopy(); @@ -662,7 +689,7 @@ int CONNECTIVITYClient::getNumberOfPolyhedronFaces() const SCRUTE(n); - END_OF("void CONNECTIVITYClient::getNumberOfPolyhedronFaces()"); + END_OF(LOC); return n; } @@ -673,7 +700,8 @@ int CONNECTIVITYClient::getNumberOfPolyhedronFaces() const int CONNECTIVITYClient::getNumberOfPolyhedron() const { - BEGIN_OF("void CONNECTIVITYClient::getNumberOfPolyhedron()"); + const char* LOC = "void CONNECTIVITYClient::getNumberOfPolyhedron()"; + BEGIN_OF(LOC); int n = 0; @@ -686,7 +714,7 @@ int CONNECTIVITYClient::getNumberOfPolyhedron() const SCRUTE(n); - END_OF("void CONNECTIVITYClient::getNumberOfPolyhedron()"); + END_OF(LOC); return n; } diff --git a/src/MedClient/src/CONNECTIVITYClient.hxx b/src/MedClient/src/CONNECTIVITYClient.hxx index b015e8cfc..fbe1f8c59 100644 --- a/src/MedClient/src/CONNECTIVITYClient.hxx +++ b/src/MedClient/src/CONNECTIVITYClient.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef _CONNECTIVITY_CLIENT_HXX #define _CONNECTIVITY_CLIENT_HXX diff --git a/src/MedClient/src/COORDINATEClient.cxx b/src/MedClient/src/COORDINATEClient.cxx index dca0978a6..33c0e0465 100644 --- a/src/MedClient/src/COORDINATEClient.cxx +++ b/src/MedClient/src/COORDINATEClient.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "COORDINATEClient.hxx" #include <string> @@ -39,11 +41,12 @@ COORDINATEClient::COORDINATEClient(const SALOME_MED::MESH_ptr m, _complete(false), IOR_Mesh(SALOME_MED::MESH::_duplicate(m)) { - BEGIN_OF("COORDINATEClient::COORDINATEClient(...)"); + const char* LOC = "COORDINATEClient::COORDINATEClient(...)"; + BEGIN_OF(LOC); blankCopy(); - END_OF("COORDINATEClient::COORDINATEClient(...)"); + END_OF(LOC); } //============================================================================= /*! @@ -52,7 +55,8 @@ COORDINATEClient::COORDINATEClient(const SALOME_MED::MESH_ptr m, //============================================================================= void COORDINATEClient::blankCopy() { - BEGIN_OF("void COORDINATEClient::blankCopy()"); + const char* LOC = "void COORDINATEClient::blankCopy()"; + BEGIN_OF(LOC); std::string *tA; long nA; @@ -84,7 +88,7 @@ void COORDINATEClient::blankCopy() _complete = false; - END_OF("void COORDINATEClient::blankCopy()"); + END_OF(LOC); } //============================================================================= /*! @@ -94,7 +98,8 @@ void COORDINATEClient::blankCopy() void COORDINATEClient::fillCopy() { - BEGIN_OF("void COORDINATEClient::fillCopy()"); + const char* LOC = "void COORDINATEClient::fillCopy()"; + BEGIN_OF(LOC); //PN ?? Est-ce qu on peut pas mettre une variable dans COORDINATEClient // qu on remplirait dans blankCopy ?? @@ -112,7 +117,7 @@ void COORDINATEClient::fillCopy() _complete = true; - END_OF("void COORDINATEClient::fillCopy()"); + END_OF(LOC); } //============================================================================= @@ -123,12 +128,13 @@ void COORDINATEClient::fillCopy() const double * COORDINATEClient::getCoordinates(medModeSwitch Mode) { - BEGIN_OF("void COORDINATEClient::getCoordinates()"); + const char* LOC = "void COORDINATEClient::getCoordinates()"; + BEGIN_OF(LOC); if (!_complete) fillCopy(); const double * c = COORDINATE::getCoordinates(Mode); - END_OF("void COORDINATEClient::getCoordinates()"); + END_OF(LOC); return c; } @@ -140,12 +146,13 @@ const double * COORDINATEClient::getCoordinates(medModeSwitch Mode) double COORDINATEClient::getCoordinate(int Number,int Axis) { - BEGIN_OF("void COORDINATEClient::getCoordinate()"); + const char* LOC = "void COORDINATEClient::getCoordinate()"; + BEGIN_OF(LOC); if (!_complete) fillCopy(); double d = COORDINATE::getCoordinate(Number, Axis); - END_OF("void COORDINATEClient::getCoordinate()"); + END_OF(LOC); return d; } @@ -156,12 +163,13 @@ double COORDINATEClient::getCoordinate(int Number,int Axis) //============================================================================= const double * COORDINATEClient::getCoordinateAxis(int Axis) { - BEGIN_OF("void COORDINATEClient::getCoordinateAxis()"); + const char* LOC = "void COORDINATEClient::getCoordinateAxis()"; + BEGIN_OF(LOC); if (!_complete) fillCopy(); const double *c = COORDINATE::getCoordinateAxis(Axis); - END_OF("void COORDINATEClient::getCoordinateAxis()"); + END_OF(LOC); return c; } @@ -172,12 +180,13 @@ const double * COORDINATEClient::getCoordinateAxis(int Axis) //============================================================================= const int* COORDINATEClient::getNodesNumbers() const { - BEGIN_OF("void COORDINATEClient::getNodesNumbers()"); + const char* LOC = "void COORDINATEClient::getNodesNumbers()"; + BEGIN_OF(LOC); if (!_complete) (const_cast < COORDINATEClient * >(this))->fillCopy(); MESSAGE("NON IMPLEMENTE DANS L'API CORBA"); - END_OF("void COORDINATEClient::getNodesNumbers()"); + END_OF(LOC); return NULL; } diff --git a/src/MedClient/src/COORDINATEClient.hxx b/src/MedClient/src/COORDINATEClient.hxx index 03b8b2bfc..ff654c0ed 100644 --- a/src/MedClient/src/COORDINATEClient.hxx +++ b/src/MedClient/src/COORDINATEClient.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef _COORDINATE_CLIENT_HXX #define _COORDINATE_CLIENT_HXX diff --git a/src/MedClient/src/FAMILYClient.cxx b/src/MedClient/src/FAMILYClient.cxx index 84a2d0476..99a4be53e 100644 --- a/src/MedClient/src/FAMILYClient.cxx +++ b/src/MedClient/src/FAMILYClient.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "FAMILYClient.hxx" #include "MESHClient.hxx" @@ -32,14 +34,15 @@ FAMILYClient::FAMILYClient(const SALOME_MED::FAMILY_ptr S, FAMILY(), IOR_Family(SALOME_MED::FAMILY::_duplicate(S)) { - BEGIN_OF("FAMILYClient::FAMILYClient(SALOME_MED::FAMILY_ptr m)"); + const char* LOC = "FAMILYClient::FAMILYClient(SALOME_MED::FAMILY_ptr m)"; + BEGIN_OF(LOC); SCRUTE(S); SCRUTE(M); blankCopy(false); - END_OF("FAMILYClient::FAMILYClient(SALOME_MED::FAMILY_ptr m)"); + END_OF(LOC); } //============================================================================= /*! @@ -48,7 +51,8 @@ FAMILYClient::FAMILYClient(const SALOME_MED::FAMILY_ptr S, //============================================================================= void FAMILYClient::blankCopy(bool blankSupport) { - BEGIN_OF("FAMILYClient::blankCopy()"); + const char* LOC = "FAMILYClient::blankCopy()"; + BEGIN_OF(LOC); if (blankSupport) SUPPORTClient::blankCopy(); @@ -93,7 +97,7 @@ void FAMILYClient::blankCopy(bool blankSupport) _complete = false; - END_OF("FAMILYClient::blankCopy()"); + END_OF(LOC); } //============================================================================= @@ -103,7 +107,8 @@ void FAMILYClient::blankCopy(bool blankSupport) //============================================================================= void FAMILYClient::fillCopy(bool fillSupport) { - BEGIN_OF("FAMILYClient::fillCopy()"); + const char* LOC = "FAMILYClient::fillCopy()"; + BEGIN_OF(LOC); if (!_complete) { @@ -115,7 +120,7 @@ void FAMILYClient::fillCopy(bool fillSupport) _complete = true; } - END_OF("FAMILYClient::fillCopy()"); + END_OF(LOC); } //============================================================================= @@ -126,6 +131,7 @@ void FAMILYClient::fillCopy(bool fillSupport) FAMILYClient::~FAMILYClient() { - BEGIN_OF("FAMILYClient::~FAMILYClient()"); - END_OF("FAMILYClient::~FAMILYClient()"); + const char* LOC = "FAMILYClient::~FAMILYClient()"; + BEGIN_OF(LOC); + END_OF(LOC); } diff --git a/src/MedClient/src/FAMILYClient.hxx b/src/MedClient/src/FAMILYClient.hxx index 39915e24d..108d01daf 100644 --- a/src/MedClient/src/FAMILYClient.hxx +++ b/src/MedClient/src/FAMILYClient.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef _FAMILYCLIENT_HXX #define _FAMILYCLIENT_HXX diff --git a/src/MedClient/src/FIELDClient.cxx b/src/MedClient/src/FIELDClient.cxx index a852945eb..61a9f8f55 100644 --- a/src/MedClient/src/FIELDClient.cxx +++ b/src/MedClient/src/FIELDClient.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // template<class T, class INTERLACING_TAG> FIELDClient<T,INTERLACING_TAG>::FIELDClient(typename FIELDI_TRAITS<T,INTERLACING_TAG>::SimpleFieldCorbaPtrType ptrCorba,MEDMEM::SUPPORT * S):_fieldPtr(FIELDI_TRAITS<T,INTERLACING_TAG>::SimpleFieldGlobalType::_duplicate(ptrCorba)),_refCounter(1) diff --git a/src/MedClient/src/FIELDClient.hxx b/src/MedClient/src/FIELDClient.hxx index 65f19dcca..546557e35 100644 --- a/src/MedClient/src/FIELDClient.hxx +++ b/src/MedClient/src/FIELDClient.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef _FIELDCLIENT_HXX #define _FIELDCLIENT_HXX diff --git a/src/MedClient/src/FIELDDOUBLEClient.cxx b/src/MedClient/src/FIELDDOUBLEClient.cxx index 880711e82..73b74bbde 100644 --- a/src/MedClient/src/FIELDDOUBLEClient.cxx +++ b/src/MedClient/src/FIELDDOUBLEClient.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "FIELDDOUBLEClient.hxx" namespace MEDMEM{ @@ -29,9 +31,10 @@ FIELDDOUBLEClient::FIELDDOUBLEClient(SALOME_MED::FIELDDOUBLE_ptr ptrCorba, MEDMEM::SUPPORT * S) : FIELDClient<double>(ptrCorba,S) { - BEGIN_OF("Constructor with arguments (for Python API) FIELDDOUBLEClient"); + const char* LOC = "Constructor with arguments (for Python API) FIELDDOUBLEClient"; + BEGIN_OF(LOC); - END_OF("Constructor with arguments (for Python API) FIELDDOUBLEClient"); + END_OF(LOC); } //============================================================================= /*! @@ -40,9 +43,10 @@ FIELDDOUBLEClient::FIELDDOUBLEClient(SALOME_MED::FIELDDOUBLE_ptr ptrCorba, //============================================================================= FIELDDOUBLEClient::~FIELDDOUBLEClient() { - BEGIN_OF("Default Destructor (for Python API) FIELDDOUBLEClient"); + const char* LOC = "Default Destructor (for Python API) FIELDDOUBLEClient"; + BEGIN_OF(LOC); - END_OF("Default Destructor (for Python API) FIELDDOUBLEClient"); + END_OF(LOC); } } diff --git a/src/MedClient/src/FIELDDOUBLEClient.hxx b/src/MedClient/src/FIELDDOUBLEClient.hxx index 585ac3335..cdffe6953 100644 --- a/src/MedClient/src/FIELDDOUBLEClient.hxx +++ b/src/MedClient/src/FIELDDOUBLEClient.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef _FIELDDOUBLECLIENT_HXX #define _FIELDDOUBLECLIENT_HXX diff --git a/src/MedClient/src/FIELDINTClient.cxx b/src/MedClient/src/FIELDINTClient.cxx index f3a51c5e4..ddd7696de 100644 --- a/src/MedClient/src/FIELDINTClient.cxx +++ b/src/MedClient/src/FIELDINTClient.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "FIELDINTClient.hxx" namespace MEDMEM{ @@ -29,9 +31,10 @@ FIELDINTClient::FIELDINTClient(SALOME_MED::FIELDINT_ptr ptrCorba, MEDMEM::SUPPORT * S) : FIELDClient<int>(ptrCorba,S) { - BEGIN_OF("Constructor with arguments (for Python API) FIELDINTClient"); + const char* LOC = "Constructor with arguments (for Python API) FIELDINTClient"; + BEGIN_OF(LOC); - END_OF("Constructor with arguments (for Python API) FIELDINTClient"); + END_OF(LOC); } //============================================================================= /*! @@ -40,9 +43,10 @@ FIELDINTClient::FIELDINTClient(SALOME_MED::FIELDINT_ptr ptrCorba, //============================================================================= FIELDINTClient::~FIELDINTClient() { - BEGIN_OF("Default Destructor (for Python API) FIELDINTClient"); + const char* LOC = "Default Destructor (for Python API) FIELDINTClient"; + BEGIN_OF(LOC); - END_OF("Default Destructor (for Python API) FIELDINTClient"); + END_OF(LOC); } } diff --git a/src/MedClient/src/FIELDINTClient.hxx b/src/MedClient/src/FIELDINTClient.hxx index cc18a1469..f8292837a 100644 --- a/src/MedClient/src/FIELDINTClient.hxx +++ b/src/MedClient/src/FIELDINTClient.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef _FIELDINTCLIENT_HXX #define _FIELDINTCLIENT_HXX diff --git a/src/MedClient/src/GROUPClient.cxx b/src/MedClient/src/GROUPClient.cxx index d9fd6efed..09099ae42 100644 --- a/src/MedClient/src/GROUPClient.cxx +++ b/src/MedClient/src/GROUPClient.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "GROUPClient.hxx" #include "MESHClient.hxx" @@ -33,12 +35,13 @@ GROUPClient::GROUPClient(const SALOME_MED::GROUP_ptr G, GROUP(), IOR_Group(SALOME_MED::GROUP::_duplicate(G)) { - BEGIN_OF("GROUPClient::GROUPClient()"); + const char* LOC = "GROUPClient::GROUPClient()"; + BEGIN_OF(LOC); SCRUTE(G); SCRUTE(M); - END_OF("GROUPClient::GROUPClient()"); + END_OF(LOC); } //============================================================================= @@ -48,12 +51,13 @@ GROUPClient::GROUPClient(const SALOME_MED::GROUP_ptr G, //============================================================================= void GROUPClient::blankCopy() { - BEGIN_OF("GROUPClient::blankCopy()"); + const char* LOC = "GROUPClient::blankCopy()"; + BEGIN_OF(LOC); SUPPORTClient::blankCopy(); _complete = false; - END_OF("GROUPClient::blankCopy()"); + END_OF(LOC); } //============================================================================= /*! @@ -63,12 +67,13 @@ void GROUPClient::blankCopy() void GROUPClient::fillCopy() { - BEGIN_OF("GROUPClient::fillCopy()"); + const char* LOC = "GROUPClient::fillCopy()"; + BEGIN_OF(LOC); SUPPORTClient::fillCopy(); _complete = true; - END_OF("GROUPClient::fillCopy()"); + END_OF(LOC); } //============================================================================= @@ -79,6 +84,7 @@ void GROUPClient::fillCopy() GROUPClient::~GROUPClient() { - BEGIN_OF("GROUPClient::~GROUPClient()"); - END_OF("GROUPClient::~GROUPClient()"); + const char* LOC = "GROUPClient::~GROUPClient()"; + BEGIN_OF(LOC); + END_OF(LOC); } diff --git a/src/MedClient/src/GROUPClient.hxx b/src/MedClient/src/GROUPClient.hxx index 29d47387d..21984dff6 100644 --- a/src/MedClient/src/GROUPClient.hxx +++ b/src/MedClient/src/GROUPClient.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef _GROUPCLIENT_HXX #define _GROUPCLIENT_HXX diff --git a/src/MedClient/src/MESHClient.cxx b/src/MedClient/src/MESHClient.cxx index f774c4f48..025265f9a 100644 --- a/src/MedClient/src/MESHClient.cxx +++ b/src/MedClient/src/MESHClient.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MESHClient.hxx" #include "MEDMEM_convert.hxx" @@ -40,7 +42,8 @@ MESHClient::MESHClient(const SALOME_MED::MESH_ptr m) : _complete(false) { - BEGIN_OF("MESHClient::MESHClient(SALOME_MED::MESH_ptr m)"); + const char* LOC = "MESHClient::MESHClient(SALOME_MED::MESH_ptr m)"; + BEGIN_OF(LOC); ASSERT(m); @@ -49,7 +52,7 @@ MESHClient::MESHClient(const SALOME_MED::MESH_ptr m) : blankCopy(); - END_OF("MESHClient::MESHClient(SALOME_MED::MESH_ptr m)"); + END_OF(LOC); } //============================================================================= /*! @@ -77,7 +80,8 @@ GROUP * convertGroup(const SALOME_MED::GROUP_ptr &F, MESH *M) //============================================================================= void MESHClient::blankCopy() { - BEGIN_OF("MESHClient::blankCopy()"); + const char* LOC = "MESHClient::blankCopy()"; + BEGIN_OF(LOC); SALOME_MED::MESH::meshInfos_var all = IOR_Mesh->getMeshGlobal(); //CORBA::String_var s; @@ -151,7 +155,7 @@ void MESHClient::blankCopy() _complete = false; - END_OF("MESHClient::blankCopy()"); + END_OF(LOC); } //============================================================================= /*! @@ -161,7 +165,8 @@ void MESHClient::blankCopy() void MESHClient::fillCopy() { - BEGIN_OF("MESHClient::fillCopy()"); + const char* LOC = "MESHClient::fillCopy()"; + BEGIN_OF(LOC); COORDINATEClient *_coord = dynamic_cast<COORDINATEClient *> (_coordinate); @@ -215,7 +220,7 @@ void MESHClient::fillCopy() _complete = true; - END_OF("MESHClient::fillCopy()"); + END_OF(LOC); } //============================================================================= @@ -225,7 +230,8 @@ void MESHClient::fillCopy() //============================================================================= bool MESHClient::operator==(const MESH& other) const { - BEGIN_OF("MESHClient::operator=="); + const char* LOC = "MESHClient::operator=="; + BEGIN_OF(LOC); const MESHClient* otherClt=dynamic_cast<const MESHClient *>(&other); if(otherClt) { @@ -246,9 +252,10 @@ bool MESHClient::operator==(const MESH& other) const MESHClient::~MESHClient() { - BEGIN_OF("MESHClient::~MESHClient()"); + const char* LOC = "MESHClient::~MESHClient()"; + BEGIN_OF(LOC); IOR_Mesh->Destroy(); - END_OF("MESHClient::~MESHClient()"); + END_OF(LOC); } //============================================================================= diff --git a/src/MedClient/src/MESHClient.hxx b/src/MedClient/src/MESHClient.hxx index ed64220e7..81727825b 100644 --- a/src/MedClient/src/MESHClient.hxx +++ b/src/MedClient/src/MESHClient.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef _MESHCLIENT_HXX #define _MESHCLIENT_HXX diff --git a/src/MedClient/src/Makefile.am b/src/MedClient/src/Makefile.am index d4b21cb18..25b12c0e1 100644 --- a/src/MedClient/src/Makefile.am +++ b/src/MedClient/src/Makefile.am @@ -1,29 +1,29 @@ -# MED MedClient : tool to transfer MED CORBA from server producer of MED object to a client using those MED object +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # +# 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. +# +# 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 +# +# MED MedClient : tool to transfer MED CORBA from server producer of MED object to a client using those MED object # - include $(top_srcdir)/adm_local/unix/make_common_starter.am -salomeinclude_HEADERS= \ +salomeinclude_HEADERS = \ COORDINATEClient.hxx \ CONNECTIVITYClient.hxx \ MESHClient.hxx \ @@ -32,6 +32,7 @@ salomeinclude_HEADERS= \ GROUPClient.hxx \ FIELDClient.hxx \ FIELDClient.cxx \ + UtilClient.hxx \ libMEDClient.i if MED_SWIG_1_3_21 @@ -47,14 +48,14 @@ else !MED_SWIG_1_3_21 SWIG_DEF = libMEDClient.i endif -dist_salomescript_DATA= \ +dist_salomescript_DATA = \ medClient_test.py \ testMeshAlliances.py -nodist_salomescript_DATA= libMEDClient.py +nodist_salomescript_DATA = libMEDClient.py -lib_LTLIBRARIES= libMEDClientcmodule.la +lib_LTLIBRARIES = libMEDClientcmodule.la _libMEDClient.la -dist_libMEDClientcmodule_la_SOURCES= \ +dist_libMEDClientcmodule_la_SOURCES = \ COORDINATEClient.cxx \ CONNECTIVITYClient.cxx \ MESHClient.cxx \ @@ -62,24 +63,45 @@ dist_libMEDClientcmodule_la_SOURCES= \ FAMILYClient.cxx \ GROUPClient.cxx -libMEDClientcmodule_la_CPPFLAGS= $(CORBA_CXXFLAGS) $(CORBA_INCLUDES) \ +dist__libMEDClient_la_SOURCES = libMEDClient.i +nodist__libMEDClient_la_SOURCES = libMEDClient_wrap.cxx + +libMEDClientcmodule_la_CPPFLAGS = $(CORBA_CXXFLAGS) $(CORBA_INCLUDES) \ $(MED2_INCLUDES) $(HDF5_INCLUDES) $(PYTHON_INCLUDES) ${KERNEL_CXXFLAGS} \ -I$(srcdir)/../../MEDMEM_I -I$(srcdir)/../../MEDMEM -I$(top_builddir)/salome_adm/unix -I$(top_builddir)/idl \ - -I$(srcdir)/../../MEDWrapper/V2_1/Core -I$(srcdir)/../../MEDMEM_SWIG -I$(srcdir)/../../MED -libMEDClientcmodule_la_LDFLAGS=${KERNEL_LDFLAGS} -lOpUtil -lSalomeCommunication ../../MedCorba_Swig/libMedCorba_Swigcmodule.la ../../MEDMEM/libmedmem.la + -I$(srcdir)/../../MEDWrapper/V2_1/Core -I$(srcdir)/../../MEDMEM_SWIG -I$(srcdir)/../../MED -I$(srcdir)/../../INTERP_KERNEL -I$(srcdir)/../../MED -I$(srcdir)/../../INTERP_KERNEL/Bases +libMEDClientcmodule_la_LDFLAGS = ${KERNEL_LDFLAGS} -lOpUtil -lSalomeCommunication ../../MEDMEM/libmedmem.la \ + ../../MEDMEM_I/libMEDMEMImpl.la ../../INTERP_KERNEL/libinterpkernel.la ../../MED/libMEDEngine.la + +_libMEDClient_la_CPPFLAGS = $(libMEDClientcmodule_la_CPPFLAGS) +_libMEDClient_la_LDFLAGS = -module $(libMEDClientcmodule_la_LDFLAGS) -lMEDClientcmodule -SWIG_FLAGS= @SWIG_FLAGS@ -I$(srcdir) -I$(srcdir)/../../MedCorba_Swig -I$(srcdir)/../../MEDMEM_SWIG -SWIG_DEP=$(srcdir)/../../MedCorba_Swig/libMedCorba_Swig.i $(srcdir)/../../MEDMEM_SWIG/libMEDMEM_Swig.i -nodist_libMEDClientcmodule_la_SOURCES= libMEDClient_wrap.cxx +SWIG_FLAGS = @SWIG_FLAGS@ -I$(srcdir) -I$(srcdir)/../../MedCorba_Swig -I$(srcdir)/../../MEDMEM_SWIG +SWIG_DEP = $(srcdir)/../../MedCorba_Swig/libMedCorba_Swig.i $(srcdir)/../../MEDMEM_SWIG/libMEDMEM_Swig.i libMEDClient.py: libMEDClient_wrap.cxx libMEDClient_wrap.cxx: $(SWIG_DEF) $(SWIG_DEP) $(SWIG) $(SWIG_FLAGS) -o $@ $(SWIG_DEF) -CLEANFILES= libMEDClient.py libMEDClient_wrap.cxx +CLEANFILES = libMEDClient.py libMEDClient_wrap.cxx -install-exec-hook: $(libdir)/_libMEDClient.so +OBSOLETE_FILES = \ + FIELDDOUBLEClient.cxx \ + FIELDDOUBLEClient.hxx \ + FIELDINTClient.cxx \ + FIELDINTClient.hxx \ + MakefileForTest \ + MemorySpy.cxx \ + MemorySpy.hxx \ + README_medclient_test \ + TESTMEDCLIENT_Gen.idl \ + TESTMEDCLIENT_Gen_i.cxx \ + TESTMEDCLIENT_Gen_i.hxx \ + create_mesh_c2q4.c \ + create_mesh_c2t3.c \ + create_mesh_c3h8.c \ + create_mesh_c3t4.c \ + test_medclient.py -$(libdir)/_libMEDClient.so: - ( cd $(libdir); ln -sf libMEDClientcmodule.so _libMEDClient.so; ) +EXTRA_DIST += $(OBSOLETE_FILES) diff --git a/src/MedClient/src/MakefileForTest b/src/MedClient/src/MakefileForTest index a03720d47..cb7cdad6e 100644 --- a/src/MedClient/src/MakefileForTest +++ b/src/MedClient/src/MakefileForTest @@ -1,3 +1,24 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# IDL = TESTMEDCLIENT_Gen.idl INC_IDL = $(patsubst %.idl,%.hh, $(IDL)) diff --git a/src/MedClient/src/MemorySpy.cxx b/src/MedClient/src/MemorySpy.cxx index 1c6eb38b9..18feb602b 100644 --- a/src/MedClient/src/MemorySpy.cxx +++ b/src/MedClient/src/MemorySpy.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "MemorySpy.hxx" diff --git a/src/MedClient/src/MemorySpy.hxx b/src/MedClient/src/MemorySpy.hxx index 0e74148df..8a86c92da 100644 --- a/src/MedClient/src/MemorySpy.hxx +++ b/src/MedClient/src/MemorySpy.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef __MEMORYSPY_HXX__ #define __MEMORYSPY_HXX__ diff --git a/src/MedClient/src/SUPPORTClient.cxx b/src/MedClient/src/SUPPORTClient.cxx index faea8438d..5e4edeaca 100644 --- a/src/MedClient/src/SUPPORTClient.cxx +++ b/src/MedClient/src/SUPPORTClient.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "Utils_CorbaException.hxx" #include "UtilClient.hxx" @@ -37,7 +39,8 @@ SUPPORTClient::SUPPORTClient(const SALOME_MED::SUPPORT_ptr S, SUPPORT(), IOR_Support(SALOME_MED::SUPPORT::_duplicate(S)),_refCounter(1) { - BEGIN_OF("SUPPORTClient::SUPPORTClient(SALOME_MED::SUPPORT_ptr m)"); + const char* LOC = "SUPPORTClient::SUPPORTClient(SALOME_MED::SUPPORT_ptr m)"; + BEGIN_OF(LOC); SCRUTE(S); SCRUTE(M); @@ -50,7 +53,7 @@ SUPPORTClient::SUPPORTClient(const SALOME_MED::SUPPORT_ptr S, } blankCopy(); - END_OF("SUPPORTClient::SUPPORTClient(SALOME_MED::SUPPORT_ptr m)"); + END_OF(LOC); } //============================================================================= /*! @@ -59,7 +62,8 @@ SUPPORTClient::SUPPORTClient(const SALOME_MED::SUPPORT_ptr S, //============================================================================= void SUPPORTClient::blankCopy() { - BEGIN_OF("SUPPORTClient::blankCopy"); + const char* LOC = "SUPPORTClient::blankCopy"; + BEGIN_OF(LOC); try { @@ -96,7 +100,7 @@ void SUPPORTClient::blankCopy() SALOME::INTERNAL_ERROR); } - END_OF("SUPPORTClient::blankCopy"); + END_OF(LOC); } //============================================================================= @@ -106,7 +110,8 @@ void SUPPORTClient::blankCopy() //============================================================================= void SUPPORTClient::fillCopy() { - BEGIN_OF("SUPPORTClient::fillCopy"); + const char* LOC = "SUPPORTClient::fillCopy"; + BEGIN_OF(LOC); if (!_complete_support) { if(!_isOnAllElts) { @@ -125,7 +130,7 @@ void SUPPORTClient::fillCopy() _complete_support = true; } - END_OF("SUPPORTClient::fillCopy"); + END_OF(LOC); } //============================================================================= /*! @@ -134,11 +139,12 @@ void SUPPORTClient::fillCopy() //============================================================================= SUPPORTClient::~SUPPORTClient() { - BEGIN_OF("SUPPORTClient::~SUPPORTClient"); + const char* LOC = "SUPPORTClient::~SUPPORTClient"; + BEGIN_OF(LOC); IOR_Support->Destroy(); if(_mesh) _mesh->removeReference(); - END_OF("SUPPORTClient::~SUPPORTClient"); + END_OF(LOC); } //============================================================================= @@ -148,12 +154,13 @@ SUPPORTClient::~SUPPORTClient() //============================================================================= MEDSKYLINEARRAY * SUPPORTClient::getnumber() const throw (MEDEXCEPTION) { - BEGIN_OF("SUPPORTClient::getnumber()"); + const char* LOC = "SUPPORTClient::getnumber()"; + BEGIN_OF(LOC); if (!_complete_support) (const_cast<SUPPORTClient *>(this))->fillCopy(); MEDSKYLINEARRAY *m = SUPPORT::getnumber(); - END_OF("SUPPORTClient::getnumber()"); + END_OF(LOC); return m; } @@ -165,12 +172,13 @@ MEDSKYLINEARRAY * SUPPORTClient::getnumber() const throw (MEDEXCEPTION) const int * SUPPORTClient::getNumber(medGeometryElement GeometricType) const throw (MEDEXCEPTION) { - BEGIN_OF("SUPPORTClient::getnumber(medGeometryElement)"); + const char* LOC = "SUPPORTClient::getnumber(medGeometryElement)"; + BEGIN_OF(LOC); if (!_complete_support) (const_cast<SUPPORTClient *>(this))->fillCopy(); const int *n = SUPPORT::getNumber(GeometricType); - END_OF("SUPPORTClient::getnumber(medGeometryElement)"); + END_OF(LOC); return n; } @@ -181,12 +189,13 @@ const int * SUPPORTClient::getNumber(medGeometryElement GeometricType) //============================================================================= const int * SUPPORTClient::getNumberIndex() const throw (MEDEXCEPTION) { - BEGIN_OF("SUPPORTClient::getnumberIndex()"); + const char* LOC = "SUPPORTClient::getnumberIndex()"; + BEGIN_OF(LOC); if (!_complete_support) (const_cast<SUPPORTClient *>(this))->fillCopy(); const int * n = SUPPORT::getNumberIndex(); - END_OF("SUPPORTClient::getnumberIndex()"); + END_OF(LOC); return n; } @@ -197,12 +206,13 @@ const int * SUPPORTClient::getNumberIndex() const throw (MEDEXCEPTION) //============================================================================= int SUPPORTClient::getValIndFromGlobalNumber(const int number) const throw (MEDEXCEPTION) { - BEGIN_OF("SUPPORTClient::getValIndFromGlobalNumber()"); + const char* LOC = "SUPPORTClient::getValIndFromGlobalNumber()"; + BEGIN_OF(LOC); if (!_complete_support) (const_cast<SUPPORTClient *>(this))->fillCopy(); const int n = SUPPORT::getValIndFromGlobalNumber(number); - END_OF("SUPPORTClient::getValIndFromGlobalNumber()"); + END_OF(LOC); return n; } diff --git a/src/MedClient/src/SUPPORTClient.hxx b/src/MedClient/src/SUPPORTClient.hxx index 3561c1cb5..1593e27c6 100644 --- a/src/MedClient/src/SUPPORTClient.hxx +++ b/src/MedClient/src/SUPPORTClient.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef _SUPPORTCLIENT_HXX #define _SUPPORTCLIENT_HXX diff --git a/src/MedClient/src/TESTMEDCLIENT_Gen.idl b/src/MedClient/src/TESTMEDCLIENT_Gen.idl index 9849d6b8b..d493b360e 100644 --- a/src/MedClient/src/TESTMEDCLIENT_Gen.idl +++ b/src/MedClient/src/TESTMEDCLIENT_Gen.idl @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef _TESTMEDCLIENT_GEN_IDL_ #define _TESTMEDCLIENT_GEN_IDL_ diff --git a/src/MedClient/src/TESTMEDCLIENT_Gen_i.cxx b/src/MedClient/src/TESTMEDCLIENT_Gen_i.cxx index b1ef5094a..1576f3fbb 100755 --- a/src/MedClient/src/TESTMEDCLIENT_Gen_i.cxx +++ b/src/MedClient/src/TESTMEDCLIENT_Gen_i.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #define private public #define protected public diff --git a/src/MedClient/src/TESTMEDCLIENT_Gen_i.hxx b/src/MedClient/src/TESTMEDCLIENT_Gen_i.hxx index 28b203cd9..f403d5eb5 100644 --- a/src/MedClient/src/TESTMEDCLIENT_Gen_i.hxx +++ b/src/MedClient/src/TESTMEDCLIENT_Gen_i.hxx @@ -1,27 +1,29 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef _TESTMEDCLIENT_GEN_I_HXX_ #define _TESTMEDCLIENT_GEN_I_HXX_ #include <TESTMEDCLIENT_Gen.hh> -#include <iostream.h> +#include <iostream> #include "SALOME_Component_i.hxx" class TESTMEDCLIENT_Gen_i : diff --git a/src/MedClient/src/UtilClient.hxx b/src/MedClient/src/UtilClient.hxx index 9e91c3f8d..1722f5482 100644 --- a/src/MedClient/src/UtilClient.hxx +++ b/src/MedClient/src/UtilClient.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef UTILCLIENT_HXX_ #define UTILCLIENT_HXX_ diff --git a/src/MedClient/src/create_mesh_c2q4.c b/src/MedClient/src/create_mesh_c2q4.c index ed83a920d..637cd1560 100644 --- a/src/MedClient/src/create_mesh_c2q4.c +++ b/src/MedClient/src/create_mesh_c2q4.c @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// /* creation d'une geometrie 2d : un cube [0,1]^2 maillé uniformement en quadrangle reguliers; @@ -226,7 +229,7 @@ int main (int argc, char **argv) strcat(MedFile,buff); strcat(MedFile,".med"); - fid = MEDouvrir(MedFile,MED_REMP); + fid = MEDouvrir(MedFile,RDWR); if (fid < 0) ret = -1; @@ -248,7 +251,7 @@ int main (int argc, char **argv) if (ret == 0) ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, - nufano,nnoe,MED_ECRI); + nufano,nnoe,WRONLY); printf("%d\n",ret); /* @@ -262,7 +265,7 @@ int main (int argc, char **argv) if (ret == 0) ret = MEDelementsEcr(fid,maa,mdim,quad4,MED_FULL_INTERLACE, nomquad4,MED_FAUX,numquad4,MED_VRAI,nufaquad4,nquad4, - MED_MAILLE,MED_QUAD4,MED_NOD,MED_ECRI); + MED_MAILLE,MED_QUAD4,MED_NOD,WRONLY); printf("%d \n",ret); /***************************************************************************/ @@ -303,7 +306,7 @@ int main (int argc, char **argv) ret = MEDchampEcr(fid, maa, champDbleVectNode, (unsigned char *)DbleVectNode, MED_NO_INTERLACE, nnoe, - MED_NOPG, MED_ALL, MED_NOPFL, MED_ECRI, MED_NOEUD, + MED_NOPG, MED_ALL, MED_NOPFL, WRONLY, MED_NOEUD, 0, MED_NOPDT," ", 0., MED_NONOR); printf("MEDchampEcr DbleVectNode : %d \n",ret); @@ -322,7 +325,7 @@ int main (int argc, char **argv) ret = MEDchampEcr(fid, maa, champDbleVectCell, (unsigned char *)DbleVectCell, MED_NO_INTERLACE, nquad4, - MED_NOPG, MED_ALL, MED_NOPFL, MED_ECRI, MED_MAILLE, + MED_NOPG, MED_ALL, MED_NOPFL, WRONLY, MED_MAILLE, MED_QUAD4, MED_NOPDT," ", 0., MED_NONOR); printf("MEDchampEcr DbleVectCell : %d \n",ret); diff --git a/src/MedClient/src/create_mesh_c2t3.c b/src/MedClient/src/create_mesh_c2t3.c index e4e001a90..621911b23 100644 --- a/src/MedClient/src/create_mesh_c2t3.c +++ b/src/MedClient/src/create_mesh_c2t3.c @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// /* creation d'une geometrie 2d : un cube [0,1]^2 maillé uniformement en triangles reguliers; @@ -235,7 +238,7 @@ int main (int argc, char **argv) strcat(MedFile,buff); strcat(MedFile,".med"); - fid = MEDouvrir(MedFile,MED_REMP); + fid = MEDouvrir(MedFile,RDWR); if (fid < 0) ret = -1; @@ -257,7 +260,7 @@ int main (int argc, char **argv) if (ret == 0) ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, - nufano,nnoe,MED_ECRI); + nufano,nnoe,WRONLY); printf("%d\n",ret); /* @@ -271,7 +274,7 @@ int main (int argc, char **argv) if (ret == 0) ret = MEDelementsEcr(fid,maa,mdim,tria3,MED_FULL_INTERLACE, nomtria3,MED_FAUX,numtria3,MED_VRAI,nufatria3,ntria3, - MED_MAILLE,MED_TRIA3,MED_NOD,MED_ECRI); + MED_MAILLE,MED_TRIA3,MED_NOD,WRONLY); printf("%d \n",ret); /***************************************************************************/ @@ -312,7 +315,7 @@ int main (int argc, char **argv) ret = MEDchampEcr(fid, maa, champDbleVectNode, (unsigned char *)DbleVectNode, MED_NO_INTERLACE, nnoe, - MED_NOPG, MED_ALL, MED_NOPFL, MED_ECRI, MED_NOEUD, + MED_NOPG, MED_ALL, MED_NOPFL, WRONLY, MED_NOEUD, 0, MED_NOPDT," ", 0., MED_NONOR); printf("MEDchampEcr DbleVectNode : %d \n",ret); @@ -332,7 +335,7 @@ int main (int argc, char **argv) ret = MEDchampEcr(fid, maa, champDbleVectCell, (unsigned char *)DbleVectCell, MED_NO_INTERLACE, ntria3, - MED_NOPG, MED_ALL, MED_NOPFL, MED_ECRI, MED_MAILLE, + MED_NOPG, MED_ALL, MED_NOPFL, WRONLY, MED_MAILLE, MED_TRIA3, MED_NOPDT," ", 0., MED_NONOR); printf("MEDchampEcr DbleVectCell : %d \n",ret); diff --git a/src/MedClient/src/create_mesh_c3h8.c b/src/MedClient/src/create_mesh_c3h8.c index 2ba30dd7f..a031e2798 100644 --- a/src/MedClient/src/create_mesh_c3h8.c +++ b/src/MedClient/src/create_mesh_c3h8.c @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// /* creation d'une geometrie 3d : un cube [0,1]^3 maillé uniformement en hexahedres reguliers; @@ -250,7 +253,7 @@ int main (int argc, char **argv) strcat(MedFile,buff); strcat(MedFile,".med"); - fid = MEDouvrir(MedFile,MED_REMP); + fid = MEDouvrir(MedFile,RDWR); if (fid < 0) ret = -1; @@ -273,7 +276,7 @@ int main (int argc, char **argv) if (ret == 0) ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, - nufano,nnoe,MED_ECRI); + nufano,nnoe,WRONLY); printf("%d\n",ret); /* @@ -287,7 +290,7 @@ int main (int argc, char **argv) if (ret == 0) ret = MEDelementsEcr(fid,maa,mdim,hexa8,MED_FULL_INTERLACE, nomhexa8,MED_FAUX,numhexa8,MED_VRAI,nufahexa8,nhexa8, - MED_MAILLE,MED_HEXA8,MED_NOD,MED_ECRI); + MED_MAILLE,MED_HEXA8,MED_NOD,WRONLY); printf("%d \n",ret); /***************************************************************************/ @@ -328,7 +331,7 @@ int main (int argc, char **argv) ret = MEDchampEcr(fid, maa, champDbleVectNode, (unsigned char *)DbleVectNode, MED_NO_INTERLACE, nnoe, - MED_NOPG, MED_ALL, MED_NOPFL, MED_ECRI, MED_NOEUD, + MED_NOPG, MED_ALL, MED_NOPFL, WRONLY, MED_NOEUD, 0, MED_NOPDT," ", 0., MED_NONOR); printf("MEDchampEcr DbleVectNode : %d \n",ret); @@ -347,7 +350,7 @@ int main (int argc, char **argv) ret = MEDchampEcr(fid, maa, champDbleVectCell, (unsigned char *)DbleVectCell, MED_NO_INTERLACE, nhexa8, - MED_NOPG, MED_ALL, MED_NOPFL, MED_ECRI, MED_MAILLE, + MED_NOPG, MED_ALL, MED_NOPFL, WRONLY, MED_MAILLE, MED_HEXA8, MED_NOPDT," ", 0., MED_NONOR); printf("MEDchampEcr DbleVectCell : %d \n",ret); diff --git a/src/MedClient/src/create_mesh_c3t4.c b/src/MedClient/src/create_mesh_c3t4.c index 14c23f8e7..9e3ef4aff 100644 --- a/src/MedClient/src/create_mesh_c3t4.c +++ b/src/MedClient/src/create_mesh_c3t4.c @@ -1,21 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -// PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -// 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. -// -// 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 -// +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// /* creation d'une geometrie 3d : un cube [0,1]^3 maillé uniformement en tetrahedres reguliers; @@ -299,7 +302,7 @@ int main (int argc, char **argv) strcat(MedFile,buff); strcat(MedFile,".med"); - fid = MEDouvrir(MedFile,MED_REMP); + fid = MEDouvrir(MedFile,RDWR); if (fid < 0) ret = -1; @@ -322,7 +325,7 @@ int main (int argc, char **argv) if (ret == 0) ret = MEDnoeudsEcr(fid,maa,mdim,coo,MED_FULL_INTERLACE,MED_CART, nomcoo,unicoo,nomnoe,MED_FAUX,numnoe,MED_VRAI, - nufano,nnoe,MED_ECRI); + nufano,nnoe,WRONLY); printf("%d\n",ret); /* @@ -336,7 +339,7 @@ int main (int argc, char **argv) if (ret == 0) ret = MEDelementsEcr(fid,maa,mdim,tetra4,MED_FULL_INTERLACE, nomtetra4,MED_FAUX,numtetra4,MED_VRAI,nufatetra4, - ntetra4,MED_MAILLE,MED_TETRA4,MED_NOD,MED_ECRI); + ntetra4,MED_MAILLE,MED_TETRA4,MED_NOD,WRONLY); printf("%d \n",ret); /***************************************************************************/ @@ -379,7 +382,7 @@ int main (int argc, char **argv) ret = MEDchampEcr(fid, maa, champDbleVectNode, (unsigned char *) DbleVectNode, MED_NO_INTERLACE, dimTot, - MED_NOPG, MED_ALL, MED_NOPFL, MED_ECRI, MED_NOEUD, + MED_NOPG, MED_ALL, MED_NOPFL, WRONLY, MED_NOEUD, 0, MED_NOPDT," ", 0., MED_NONOR); printf("MEDchampEcr DbleVectNode : %d \n",ret); @@ -400,7 +403,7 @@ int main (int argc, char **argv) ret = MEDchampEcr(fid, maa, champDbleVectCell, (unsigned char *) DbleVectCell, MED_NO_INTERLACE, dimTot, - MED_NOPG, MED_ALL, MED_NOPFL, MED_ECRI, MED_MAILLE, + MED_NOPG, MED_ALL, MED_NOPFL, WRONLY, MED_MAILLE, MED_TETRA4, MED_NOPDT," ", 0., MED_NONOR); printf("MEDchampEcr DbleVectCell : %d \n",ret); diff --git a/src/MedClient/src/libMEDClient.i b/src/MedClient/src/libMEDClient.i index 1307d4ea4..96143791c 100644 --- a/src/MedClient/src/libMEDClient.i +++ b/src/MedClient/src/libMEDClient.i @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // %module libMEDClient diff --git a/src/MedClient/src/medClient_test.py b/src/MedClient/src/medClient_test.py index 7380b952a..49c8eef50 100644 --- a/src/MedClient/src/medClient_test.py +++ b/src/MedClient/src/medClient_test.py @@ -1,27 +1,29 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# -#################################################################################################### +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +#################################################################################################### # Test the MedClient classes: mounting in Memory a .med file and using this file as a client of # the MED component we try -# #################################################################################################### +# from libMEDClient import * import string @@ -137,9 +139,9 @@ medComp=salome.lcc.FindOrLoadComponent("FactoryServer", "MED") import os filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join(filePath, "share", "salome", "resources", "med") -filePathName = filePath + fileName +filePathName = os.path.join( filePath, fileName ) print "Reading the .med file ",filePathName," and pushing corba objects in the SALOME study" medComp.readStructFileWithFieldType(filePathName,salome.myStudyName) diff --git a/src/MedClient/src/testMeshAlliances.py b/src/MedClient/src/testMeshAlliances.py index d2f3a4650..6f000f5f9 100755 --- a/src/MedClient/src/testMeshAlliances.py +++ b/src/MedClient/src/testMeshAlliances.py @@ -1,3 +1,24 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# import salome import SALOME import os @@ -5,7 +26,7 @@ import os from libMEDClient import * filePath=os.environ["MED_ROOT_DIR"] -filePath=filePath+"/share/salome/resources/med/" +filePath=os.path.join( filePath, "share", "salome", "resources", "med" ) medFiles = [] medFiles.append("extendedtransport53_triangles.med") @@ -24,7 +45,7 @@ nbOfFiles = len(medFiles) med=salome.lcc.FindOrLoadComponent("FactoryServer", "MED") for i in range(nbOfFiles): - medFile = filePath + medFiles[i] + medFile = os.path.join( filePath, medFiles[i] ) meshName = meshNames[i] diff --git a/src/MedClient/src/test_medclient.py b/src/MedClient/src/test_medclient.py index 654ab3d6e..2c51c1efb 100644 --- a/src/MedClient/src/test_medclient.py +++ b/src/MedClient/src/test_medclient.py @@ -1,21 +1,24 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# import salome import SALOME_TESTMEDCLIENT import SALOME_MED diff --git a/src/MedClient/test/Makefile.am b/src/MedClient/test/Makefile.am index e61d4eac6..74a57ac24 100644 --- a/src/MedClient/test/Makefile.am +++ b/src/MedClient/test/Makefile.am @@ -1,26 +1,26 @@ -# MED MedClient : tool to transfer MED CORBA from server producer of MED object to a client using those MED object +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # +# 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. +# +# 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 +# +# MED MedClient : tool to transfer MED CORBA from server producer of MED object to a client using those MED object # - include $(top_srcdir)/adm_local/unix/make_common_starter.am dist_salomeres_DATA= \ diff --git a/src/MedClient/test/environ/Makefile.am b/src/MedClient/test/environ/Makefile.am index c18362ec7..1581204a0 100644 --- a/src/MedClient/test/environ/Makefile.am +++ b/src/MedClient/test/environ/Makefile.am @@ -1,35 +1,30 @@ -# MED MedClient : tool to transfer MED CORBA from server producer of MED object to a client using those MED object +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +# MED MedClient : tool to transfer MED CORBA from server producer of MED object to a client using those MED object # - include $(top_srcdir)/adm_local/unix/make_common_starter.am -SUBDIRS= csh - -nodist_purebin_SCRIPTS= runTestMedCorba +SUBDIRS = csh -nodist_testsenviron_SCRIPTS= runEnvironTests +nodist_purebin_SCRIPTS = runTestMedCorba -EXTRA_DIST+= \ - runContainer.in \ - runEnvironTests.in \ - runTestMedCorba.in \ - stopContainer.in +nodist_testsenviron_SCRIPTS = runEnvironTests diff --git a/src/MedClient/test/environ/csh/Makefile.am b/src/MedClient/test/environ/csh/Makefile.am index 8ee983a9a..c224490be 100644 --- a/src/MedClient/test/environ/csh/Makefile.am +++ b/src/MedClient/test/environ/csh/Makefile.am @@ -1,36 +1,30 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# - +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# include $(top_srcdir)/adm_local/unix/make_common_starter.am -nodist_testsenvironcsh_SCRIPTS= \ +nodist_testsenvironcsh_SCRIPTS = \ init1 \ init2 \ init3 \ runContainer \ runEnvironTests \ stopContainer - -EXTRA_DIST+= \ - init1.in \ - init2.in \ - init3.in \ - runContainer.in \ - runEnvironTests.in \ - stopContainer.in diff --git a/src/MedClient/test/environ/csh/init1.in b/src/MedClient/test/environ/csh/init1.in index bd0bbeca9..04d05dd5a 100644 --- a/src/MedClient/test/environ/csh/init1.in +++ b/src/MedClient/test/environ/csh/init1.in @@ -1,3 +1,24 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# cd ${KERNEL_ROOT_DIR}/bin/salome pwd ./allkill || true diff --git a/src/MedClient/test/environ/csh/init2.in b/src/MedClient/test/environ/csh/init2.in index 451835ead..74a8f7d66 100644 --- a/src/MedClient/test/environ/csh/init2.in +++ b/src/MedClient/test/environ/csh/init2.in @@ -1,4 +1,25 @@ #!/bin/csh +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# cd ${SALOME_BIN_TESTS} diff --git a/src/MedClient/test/environ/csh/init3.in b/src/MedClient/test/environ/csh/init3.in index fc7b3a531..a117bf74c 100644 --- a/src/MedClient/test/environ/csh/init3.in +++ b/src/MedClient/test/environ/csh/init3.in @@ -1,2 +1,23 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# cd ${KERNEL_ROOT_DIR}/bin/salome csh diff --git a/src/MedClient/test/environ/csh/runContainer.in b/src/MedClient/test/environ/csh/runContainer.in index 2fd3ddb61..e703ed579 100644 --- a/src/MedClient/test/environ/csh/runContainer.in +++ b/src/MedClient/test/environ/csh/runContainer.in @@ -1,4 +1,25 @@ #! /bin/csh +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# set CONTAINER_NAME=$1 diff --git a/src/MedClient/test/environ/csh/runEnvironTests.in b/src/MedClient/test/environ/csh/runEnvironTests.in index 69655e197..e364f210f 100644 --- a/src/MedClient/test/environ/csh/runEnvironTests.in +++ b/src/MedClient/test/environ/csh/runEnvironTests.in @@ -1,3 +1,23 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 # [ -f ~/.Xresources ] && xrdb ~/.Xresources diff --git a/src/MedClient/test/environ/csh/stopContainer.in b/src/MedClient/test/environ/csh/stopContainer.in index 3cbbee5e7..3ac6e1dd5 100644 --- a/src/MedClient/test/environ/csh/stopContainer.in +++ b/src/MedClient/test/environ/csh/stopContainer.in @@ -1,4 +1,25 @@ #! /bin/sh +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# EXEC_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` diff --git a/src/MedClient/test/environ/runContainer.in b/src/MedClient/test/environ/runContainer.in index 579a99034..d31e40ab6 100644 --- a/src/MedClient/test/environ/runContainer.in +++ b/src/MedClient/test/environ/runContainer.in @@ -1,3 +1,23 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 # set xTest = 1 diff --git a/src/MedClient/test/environ/runEnvironTests.in b/src/MedClient/test/environ/runEnvironTests.in index ef3305285..52c013b04 100644 --- a/src/MedClient/test/environ/runEnvironTests.in +++ b/src/MedClient/test/environ/runEnvironTests.in @@ -1,3 +1,23 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 # set xTest = 1 diff --git a/src/MedClient/test/environ/runTestMedCorba.in b/src/MedClient/test/environ/runTestMedCorba.in index 736d46251..3e2b89a75 100644 --- a/src/MedClient/test/environ/runTestMedCorba.in +++ b/src/MedClient/test/environ/runTestMedCorba.in @@ -1,4 +1,25 @@ #! /bin/bash +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# PYTHON_VERSION=python@PYTHON_VERSION@ diff --git a/src/MedClient/test/environ/stopContainer.in b/src/MedClient/test/environ/stopContainer.in index f09fc1c68..3d15d962c 100644 --- a/src/MedClient/test/environ/stopContainer.in +++ b/src/MedClient/test/environ/stopContainer.in @@ -1,3 +1,23 @@ +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 # set xTest = 1 diff --git a/src/MedClient/test/test1/Compo1.py b/src/MedClient/test/test1/Compo1.py index ba8307438..96e9a8559 100644 --- a/src/MedClient/test/test1/Compo1.py +++ b/src/MedClient/test/test1/Compo1.py @@ -1,21 +1,24 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# from libMEDMEM_Swig import * diff --git a/src/MedClient/test/test1/Compo1Py.idl b/src/MedClient/test/test1/Compo1Py.idl index e58ee2ce0..28d0c337f 100644 --- a/src/MedClient/test/test1/Compo1Py.idl +++ b/src/MedClient/test/test1/Compo1Py.idl @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #include "SALOME_Component.idl" #include "MED.idl" diff --git a/src/MedClient/test/test1/Compo1Py.py b/src/MedClient/test/test1/Compo1Py.py index f3dea81af..6606b394f 100644 --- a/src/MedClient/test/test1/Compo1Py.py +++ b/src/MedClient/test/test1/Compo1Py.py @@ -1,21 +1,24 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# import sys from omniORB import CORBA, PortableServer import CosNaming diff --git a/src/MedClient/test/test1/Makefile.am b/src/MedClient/test/test1/Makefile.am index 7d8988887..ae6026ff0 100644 --- a/src/MedClient/test/test1/Makefile.am +++ b/src/MedClient/test/test1/Makefile.am @@ -1,29 +1,29 @@ -# MED MedClient : tool to transfer MED CORBA from server producer of MED object to a client using those MED object +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # +# 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. +# +# 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 +# +# MED MedClient : tool to transfer MED CORBA from server producer of MED object to a client using those MED object # - include $(top_srcdir)/adm_local/unix/make_common_starter.am -EXTRA_DIST+= \ +dist_salomeres_DATA = \ resources/CatalogModuleTest.xml \ resources/Compo1PyCatalog.xml @@ -35,3 +35,6 @@ dist_salomescript_DATA= \ TestMedCorba3.py \ TestMedCorba4.py \ TestMedCorba5.py + +EXTRA_DIST += \ + Compo1Py.idl diff --git a/src/MedClient/test/test1/TestMedCorba1.py b/src/MedClient/test/test1/TestMedCorba1.py index 6f71d3c18..90c93d1c0 100644 --- a/src/MedClient/test/test1/TestMedCorba1.py +++ b/src/MedClient/test/test1/TestMedCorba1.py @@ -1,27 +1,31 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# import os -BASE = os.environ["MED_ROOT_DIR"] + '/share/salome/resources/med/' +BASE = os.environ["MED_ROOT_DIR"] +BASE = os.path.join( BASE, 'share', 'salome', 'resources', 'med' ) -fileName = BASE + 'pointe.med' -fileName = BASE + 'carre_en_quad4_seg2.med' -fileName = BASE + 'test_hydro_darcy1a_out.med' +fileName = os.path.join( BASE, 'pointe.med' ) +fileName = os.path.join( BASE, 'carre_en_quad4_seg2.med' ) +fileName = os.path.join( BASE, 'test_hydro_darcy1a_out.med' ) # MED Mesh read from a (local) file diff --git a/src/MedClient/test/test1/TestMedCorba2.py b/src/MedClient/test/test1/TestMedCorba2.py index 7cc6fd720..5c2d3a3d0 100644 --- a/src/MedClient/test/test1/TestMedCorba2.py +++ b/src/MedClient/test/test1/TestMedCorba2.py @@ -1,26 +1,30 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# import os -BASE = os.environ["MED_ROOT_DIR"] + '/share/salome/resources/med/' +BASE = os.environ["MED_ROOT_DIR"] +BASE = os.path.join( BASE, 'share', 'salome', 'resources', 'med' ) -fileName = BASE + 'pointe.med' -fileName = BASE + 'carre_en_quad4_seg2.med' +fileName = os.path.join( BASE, 'pointe.med' ) +fileName = os.path.join( BASE, 'carre_en_quad4_seg2.med' ) # MED Mesh read from a (local) file diff --git a/src/MedClient/test/test1/TestMedCorba3.py b/src/MedClient/test/test1/TestMedCorba3.py index c637bdd56..edefdd07d 100644 --- a/src/MedClient/test/test1/TestMedCorba3.py +++ b/src/MedClient/test/test1/TestMedCorba3.py @@ -1,26 +1,30 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# import os -BASE = os.environ["MED_ROOT_DIR"] + '/share/salome/resources/med/' +BASE = os.environ["MED_ROOT_DIR"] +BASE = os.path.join( BASE, 'share', 'salome', 'resources', 'med' ) -fileName = BASE + 'pointe.med' -fileName = BASE + 'carre_en_quad4_seg2.med' +fileName = os.path.join( BASE, 'pointe.med' ) +fileName = os.path.join( BASE, 'carre_en_quad4_seg2.med' ) # MED Mesh read from a (local) file diff --git a/src/MedClient/test/test1/TestMedCorba4.py b/src/MedClient/test/test1/TestMedCorba4.py index f29dd14f9..c1cf39351 100644 --- a/src/MedClient/test/test1/TestMedCorba4.py +++ b/src/MedClient/test/test1/TestMedCorba4.py @@ -1,26 +1,30 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# import os -BASE = os.environ["MED_ROOT_DIR"] + '/share/salome/resources/med/' +BASE = os.environ["MED_ROOT_DIR"] +BASE = os.path.join( BASE, 'share', 'salome', 'resources', 'med' ) -fileName = BASE + 'pointe.med' -fileName = BASE + 'carre_en_quad4_seg2.med' +fileName = os.path.join( BASE, 'pointe.med' ) +fileName = os.path.join( BASE, 'carre_en_quad4_seg2.med' ) # MED Mesh read from a (local) file diff --git a/src/MedClient/test/test1/TestMedCorba5.py b/src/MedClient/test/test1/TestMedCorba5.py index 2b57c5002..41b2c2432 100644 --- a/src/MedClient/test/test1/TestMedCorba5.py +++ b/src/MedClient/test/test1/TestMedCorba5.py @@ -1,26 +1,30 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# import os -BASE = os.environ["MED_ROOT_DIR"] + '/share/salome/resources/med/' +BASE = os.environ["MED_ROOT_DIR"] +BASE = os.path.join( BASE, 'share', 'salome', 'resources', 'med' ) -fileName = BASE + 'pointe.med' -fileName = BASE + 'carre_en_quad4_seg2.med' +fileName = os.path.join( BASE, 'pointe.med' ) +fileName = os.path.join( BASE, 'carre_en_quad4_seg2.med' ) def compare(x, y): diff --git a/src/MedClient/test/test1/resources/CatalogModuleTest.xml b/src/MedClient/test/test1/resources/CatalogModuleTest.xml index 431ae25c8..91c73eb10 100644 --- a/src/MedClient/test/test1/resources/CatalogModuleTest.xml +++ b/src/MedClient/test/test1/resources/CatalogModuleTest.xml @@ -1,4 +1,27 @@ <?xml version='1.0' encoding='us-ascii' ?> +<!-- + Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE + + Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, + CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS + + 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. + + 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 + +--> <!-- XML component catalog --> <begin-catalog> diff --git a/src/MedClient/test/test1/resources/Compo1PyCatalog.xml b/src/MedClient/test/test1/resources/Compo1PyCatalog.xml index d0c3bd15f..65c5e1f62 100644 --- a/src/MedClient/test/test1/resources/Compo1PyCatalog.xml +++ b/src/MedClient/test/test1/resources/Compo1PyCatalog.xml @@ -1,4 +1,27 @@ <?xml version='1.0' encoding='us-ascii' ?> +<!-- + Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE + + Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, + CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS + + 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. + + 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 + +--> <begin-catalog> <path-prefix-list></path-prefix-list> diff --git a/src/MedClient/test/test2/Compo2.cxx b/src/MedClient/test/test2/Compo2.cxx index e48d39ad1..ac783a684 100644 --- a/src/MedClient/test/test2/Compo2.cxx +++ b/src/MedClient/test/test2/Compo2.cxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef _DEBUG_ #define _DEBUG_ @@ -40,7 +42,8 @@ Compo2::~Compo2() std::string Compo2::Calcul(const MESH &M) { - BEGIN_OF("std::string Compo2::Calcul(MESH &M)"); + const char* LOC = "std::string Compo2::Calcul(MESH &M)"; + BEGIN_OF(LOC); MESSAGE("type virtuel : MESH"); MESSAGE("type reel : " << typeid(M).name()); @@ -56,13 +59,14 @@ std::string Compo2::Calcul(const MESH &M) std::cerr << "erreur Compo2::Calcul" << std::endl; } - END_OF("std::string Compo2::Calcul(MESH &M)"); + END_OF(LOC); return name; } const FAMILY * Compo2::Calcul2(const MESH &M) { - BEGIN_OF("const FAMILY * Compo2::Calcul2(const MESH &M)"); + const char* LOC = "const FAMILY * Compo2::Calcul2(const MESH &M)"; + BEGIN_OF(LOC); const FAMILY * F = M.getFamily(MED_CELL, 1); std::cerr << "ok ici 2" << std::endl; @@ -73,13 +77,14 @@ const FAMILY * Compo2::Calcul2(const MESH &M) std::cerr << "erreur Compo2::Calcul2" << std::endl; } - END_OF("const FAMILY * Compo2::Calcul2(const MESH &M)"); + END_OF(LOC); return F; } void Compo2::Calcul3(const FIELD<double> &F) { - BEGIN_OF("void Compo2::Calcul3(const FIELD<double> *)"); + const char* LOC = "void Compo2::Calcul3(const FIELD<double> *)"; + BEGIN_OF(LOC); const double *v = F.getValue(); long i, n = F.getSupport()->getNumberOfElements(MED_CELL); @@ -92,5 +97,5 @@ void Compo2::Calcul3(const FIELD<double> &F) std::cout << std::endl; } - END_OF("void Compo2::Calcul2(const FIELD<double> *)"); + END_OF(LOC); } diff --git a/src/MedClient/test/test2/Compo2.hxx b/src/MedClient/test/test2/Compo2.hxx index 3c42d2d2e..bad885445 100644 --- a/src/MedClient/test/test2/Compo2.hxx +++ b/src/MedClient/test/test2/Compo2.hxx @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // #ifndef __COMPO2 #define __COMPO2 diff --git a/src/MedClient/test/test2/Makefile.am b/src/MedClient/test/test2/Makefile.am index b6d9a4168..9c45da242 100644 --- a/src/MedClient/test/test2/Makefile.am +++ b/src/MedClient/test/test2/Makefile.am @@ -1,50 +1,28 @@ -# MED MedClient : tool to transfer MED CORBA from server producer of MED object to a client using those MED object +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # +# 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. +# +# 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 +# +# MED MedClient : tool to transfer MED CORBA from server producer of MED object to a client using those MED object # - include $(top_srcdir)/adm_local/unix/make_common_starter.am -dist_salomescript_DATA= \ - TestMedCorba6.py \ - TestMedCorba7.py \ - TestMedCorba8.py -nodist_salomescript_DATA= \ - libCompo2.py - -# Libraries targets -lib_LTLIBRARIES= libCompo2cmodule.la -dist_libCompo2cmodule_la_SOURCES= Compo2.cxx -nodist_libCompo2cmodule_la_SOURCES= libCompo2_wrap.cxx - -EXTRA_DIST+= Compo2.hxx - -libCompo2cmodule_la_CPPFLAGS= $(CORBA_CXXFLAGS) $(CORBA_INCLUDES) \ - ${MED2_INCLUDES} ${HDF5_INCLUDES} ${PYTHON_INCLUDES} ${KERNEL_CXXFLAGS} \ - -I$(srcdir)/../../../MEDMEM_I -I$(srcdir)/../../../MEDMEM -I$(top_builddir)/salome_adm/unix -I$(top_builddir)/idl \ - -I$(srcdir)/../../../MEDWrapper/V2_1/Core -I$(srcdir)/../../../MEDMEM_SWIG -I$(srcdir)/../../../MED -I$(srcdir)/../../src -libCompo2cmodule_la_LDFLAGS= ${KERNEL_LDFLAGS} ${MED2_LIBS} ${HDF5_LIBS} \ - ../../src/libMEDClientcmodule.la ../../../MEDMEM_SWIG/libMEDMEM_Swigcmodule.la \ - ../../../MEDMEM/libmedmem.la ../../../MEDMEM_I/libMEDMEMImpl.la - if MED_SWIG_1_3_21 SWIG_DEF = libCompo2.i dummy.i @@ -58,17 +36,34 @@ else !MED_SWIG_1_3_21 SWIG_DEF = libCompo2.i endif -SWIG_FLAGS= @SWIG_FLAGS@ -I$(srcdir) -I$(srcdir)/../../src -I$(srcdir)/../../../MEDMEM_SWIG -I$(srcdir)/../../../MedCorba_Swig -SWIG_DEP=../../src/libMEDClient.i ../../../MEDMEM_SWIG/libMEDMEM_Swig.i ../../../MedCorba_Swig/libMedCorba_Swig.i +dist_salomescript_DATA = \ + TestMedCorba6.py \ + TestMedCorba7.py \ + TestMedCorba8.py +nodist_salomescript_DATA = \ + libCompo2.py + +# Libraries targets +lib_LTLIBRARIES = _libCompo2.la + +dist__libCompo2_la_SOURCES = Compo2.hxx Compo2.cxx libCompo2.i +nodist__libCompo2_la_SOURCES = libCompo2_wrap.cxx + +_libCompo2_la_CPPFLAGS = $(CORBA_CXXFLAGS) $(CORBA_INCLUDES) \ + ${MED2_INCLUDES} ${HDF5_INCLUDES} ${PYTHON_INCLUDES} ${KERNEL_CXXFLAGS} \ + -I$(srcdir)/../../../MEDMEM_I -I$(srcdir)/../../../MEDMEM -I$(top_builddir)/salome_adm/unix -I$(top_builddir)/idl \ + -I$(srcdir)/../../../MEDWrapper/V2_1/Core -I$(srcdir)/../../../MEDMEM_SWIG -I$(srcdir)/../../../MED -I$(srcdir)/../../src \ + -I$(srcdir)/../../../INTERP_KERNEL -I$(srcdir)/../../../INTERP_KERNEL/Bases +_libCompo2_la_LDFLAGS = -module ${KERNEL_LDFLAGS} ${MED2_LIBS} ${HDF5_LIBS} \ + ../../../MEDMEM/libmedmem.la ../../../MEDMEM_I/libMEDMEMImpl.la ../../../INTERP_KERNEL/libinterpkernel.la \ + ../../../MED/libMEDEngine.la ../../src/libMEDClientcmodule.la + +SWIG_FLAGS = @SWIG_FLAGS@ -I$(srcdir) -I$(srcdir)/../../src -I$(srcdir)/../../../MEDMEM_SWIG -I$(srcdir)/../../../MedCorba_Swig +SWIG_DEP = ../../src/libMEDClient.i ../../../MEDMEM_SWIG/libMEDMEM_Swig.i ../../../MedCorba_Swig/libMedCorba_Swig.i libCompo2.py: libCompo2_wrap.cxx libCompo2_wrap.cxx: $(SWIG_DEF) $(SWIG) $(SWIG_FLAGS) -o $@ $< -CLEANFILES= libCompo2_wrap.cxx libCompo2.py - -install-exec-hook: $(libdir)/_libCompo2.so - -$(libdir)/_libCompo2.so: - ( cd $(libdir); ln -sf libCompo2cmodule.so _libCompo2.so; ) +CLEANFILES = libCompo2_wrap.cxx libCompo2.py diff --git a/src/MedClient/test/test2/TestMedCorba6.py b/src/MedClient/test/test2/TestMedCorba6.py index c7dc24a0e..9f5d36afb 100644 --- a/src/MedClient/test/test2/TestMedCorba6.py +++ b/src/MedClient/test/test2/TestMedCorba6.py @@ -1,30 +1,34 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# import os ## ne fonctionne pas ? ## import salome -BASE = os.environ["MED_ROOT_DIR"] + '/share/salome/resources/med/' +BASE = os.environ["MED_ROOT_DIR"] +BASE = os.path.join( BASE, 'share', 'salome', 'resources', 'med' ) -fileName = BASE + 'pointe.med' -fileName = BASE + 'carre_en_quad4_seg2.med' +fileName = os.path.join( BASE, 'pointe.med' ) +fileName = os.path.join( BASE, 'carre_en_quad4_seg2.med' ) def compare(x, y): diff --git a/src/MedClient/test/test2/TestMedCorba7.py b/src/MedClient/test/test2/TestMedCorba7.py index 70283f35f..d3a72ba59 100644 --- a/src/MedClient/test/test2/TestMedCorba7.py +++ b/src/MedClient/test/test2/TestMedCorba7.py @@ -1,28 +1,32 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# import os -BASE = os.environ["MED_ROOT_DIR"] + '/share/salome/resources/med/' +BASE = os.environ["MED_ROOT_DIR"] +BASE = os.path.join( BASE, 'share', 'salome', 'resources', 'med' ) -fileName = BASE + 'pointe.med' -fileName = BASE + 'test_hydro_darcy1a_out.med' -fileName = BASE + 'carre_en_quad4_seg2.med' +fileName = os.path.join( BASE, 'pointe.med' ) +fileName = os.path.join( BASE, 'test_hydro_darcy1a_out.med' ) +fileName = os.path.join( BASE, 'carre_en_quad4_seg2.med' ) def compare(x, y): if (len(x) != len(y)): diff --git a/src/MedClient/test/test2/TestMedCorba8.py b/src/MedClient/test/test2/TestMedCorba8.py index e73ef6e89..c0c832693 100644 --- a/src/MedClient/test/test2/TestMedCorba8.py +++ b/src/MedClient/test/test2/TestMedCorba8.py @@ -1,30 +1,34 @@ -# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG -# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT -# 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. -# -# 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 -# +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# import os # import salome -BASE = os.environ["MED_ROOT_DIR"] + '/share/salome/resources/med/' +BASE = os.environ["MED_ROOT_DIR"] +BASE = os.path.join( BASE, 'share', 'salome', 'resources', 'med' ) -fileName = BASE + 'pointe.med' -fileName = BASE + 'test_hydro_darcy1a_out.med' -fileName = BASE + 'carre_en_quad4_seg2.med' +fileName = os.path.join( BASE, 'pointe.med' ) +fileName = os.path.join( BASE, 'test_hydro_darcy1a_out.med' ) +fileName = os.path.join( BASE, 'carre_en_quad4_seg2.med' ) from omniORB import CORBA diff --git a/src/MedClient/test/test2/libCompo2.i b/src/MedClient/test/test2/libCompo2.i index f3412fe2d..2da294257 100644 --- a/src/MedClient/test/test2/libCompo2.i +++ b/src/MedClient/test/test2/libCompo2.i @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // %module libCompo2 diff --git a/src/MedCorba_Swig/Makefile.am b/src/MedCorba_Swig/Makefile.am index 812f4635e..26daa330b 100644 --- a/src/MedCorba_Swig/Makefile.am +++ b/src/MedCorba_Swig/Makefile.am @@ -1,28 +1,29 @@ -# MED MedCorba_Swig : binding of MED CORBA objects woth Python +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# +# MED MedCorba_Swig : binding of MED CORBA objects woth Python # - include $(top_srcdir)/adm_local/unix/make_common_starter.am -lib_LTLIBRARIES= libMedCorba_Swigcmodule.la +lib_LTLIBRARIES = _libMedCorba_Swig.la if MED_SWIG_1_3_21 SWIG_DEF = libMedCorba_Swig.i dummy.i @@ -37,11 +38,12 @@ else !MED_SWIG_1_3_21 SWIG_DEF = libMedCorba_Swig.i endif -SWIG_FLAGS= @SWIG_FLAGS@ -I$(srcdir) -I$(srcdir)/../MEDMEM_SWIG -SWIG_DEP= ../MEDMEM_SWIG/libMEDMEM_Swig.i +SWIG_FLAGS = @SWIG_FLAGS@ -I$(srcdir) -I$(srcdir)/../MEDMEM_SWIG +SWIG_DEP = ../MEDMEM_SWIG/libMEDMEM_Swig.i -nodist_libMedCorba_Swigcmodule_la_SOURCES= libMedCorba_Swig_wrap.cxx -salomeinclude_HEADERS= libMedCorba_Swig.i +dist__libMedCorba_Swig_la_SOURCES = libMedCorba_Swig.i +nodist__libMedCorba_Swig_la_SOURCES = libMedCorba_Swig_wrap.cxx +salomeinclude_HEADERS = libMedCorba_Swig.i libMedCorba_Swig.py: libMedCorba_Swig_wrap.cxx @@ -50,19 +52,15 @@ libMedCorba_Swig_wrap.cxx: $(SWIG_DEF) $(SWIG_DEP) ############################################################################# -libMedCorba_Swigcmodule_la_CPPFLAGS= $(CORBA_CXXFLAGS) $(CORBA_INCLUDES) \ - $(PYTHON_INCLUDES) $(MED2_INCLUDES) $(HDF5_INCLUDES) ${KERNEL_CXXFLAGS} -ftemplate-depth-42 \ +_libMedCorba_Swig_la_CPPFLAGS = $(CORBA_CXXFLAGS) $(CORBA_INCLUDES) \ + $(PYTHON_INCLUDES) $(MED2_INCLUDES) $(HDF5_INCLUDES) ${KERNEL_CXXFLAGS} \ -I$(srcdir)/../MEDMEM_I -I$(srcdir)/../MEDMEM -I$(srcdir)/../MEDMEM_SWIG -I$(srcdir)/../MED -I$(srcdir)/../MEDWrapper/V2_1/Core \ - -I$(top_builddir)/salome_adm/unix -I$(top_builddir)/idl -libMedCorba_Swigcmodule_la_LDFLAGS=$(PYTHON_LIBS) $(MED2_LIBS) $(HDF5_LIBS) ${KERNEL_LDFLAGS} -lSALOMELocalTrace \ - ../MEDMEM_I/libMEDMEMImpl.la ../MEDMEM/libmedmem.la ../MEDMEM_SWIG/libMEDMEM_Swigcmodule.la ../MED/libMEDEngine.la + -I$(srcdir)/../INTERP_KERNEL -I$(srcdir)/../INTERP_KERNEL/Bases -I$(top_builddir)/salome_adm/unix -I$(top_builddir)/idl +_libMedCorba_Swig_la_LDFLAGS = -module $(PYTHON_LIBS) $(MED2_LIBS) $(HDF5_LIBS) ${KERNEL_LDFLAGS} -lSALOMELocalTrace \ + ../MEDMEM_I/libMEDMEMImpl.la ../MEDMEM/libmedmem.la ../INTERP_KERNEL/libinterpkernel.la ../MED/libMEDEngine.la +### ../MEDMEM_SWIG/_libMEDMEM_Swig.la -dist_salomescript_DATA = medcorba_test.py batchmode_medcorba_test.py batchmode_medcorba_test1.py +dist_salomescript_DATA = medcorba_test.py batchmode_medcorba_test.py batchmode_medcorba_test1.py nodist_salomescript_DATA = libMedCorba_Swig.py -CLEANFILES= libMedCorba_Swig.py libMedCorba_Swig_wrap.cxx - -install-exec-hook: $(libdir)/_libMedCorba_Swig.so - -$(libdir)/_libMedCorba_Swig.so: - ( cd $(libdir); ln -sf libMedCorba_Swigcmodule.so _libMedCorba_Swig.so; ) +CLEANFILES = libMedCorba_Swig.py libMedCorba_Swig_wrap.cxx diff --git a/src/MedCorba_Swig/batchmode_medcorba_test.py b/src/MedCorba_Swig/batchmode_medcorba_test.py index 0ab8d5110..0eb10031d 100755 --- a/src/MedCorba_Swig/batchmode_medcorba_test.py +++ b/src/MedCorba_Swig/batchmode_medcorba_test.py @@ -1,12 +1,28 @@ -# MED MedCorba_Swig : binding of MED CORBA objects woth Python +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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. # -# Copyright (C) 2003 CEA/DEN, EDF R&D +# 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 # +# MED MedCorba_Swig : binding of MED CORBA objects woth Python # File : batchmode_medcorba_test.py # Module : MED - +# import batchmode_salome import SALOME_MED @@ -17,8 +33,8 @@ from random import * import os -filePath=os.environ["DATA_DIR"] -filePath=filePath+"/MedFiles/" +filePath = os.environ["MED_ROOT_DIR"] +filePath = os.path.join( filePath, "share", "salome", "resources", "med" ) #============================================================================== @@ -166,7 +182,7 @@ print "" fileName = "cube_hexa8_quad4.med" #medFile = "carre_en_quad4_seg2.med" -medFile = filePath + fileName +medFile = os.path.join( filePath, fileName ) print "Loading of the Med Component" print "" diff --git a/src/MedCorba_Swig/batchmode_medcorba_test1.py b/src/MedCorba_Swig/batchmode_medcorba_test1.py index 2dad332e8..a1641417f 100644 --- a/src/MedCorba_Swig/batchmode_medcorba_test1.py +++ b/src/MedCorba_Swig/batchmode_medcorba_test1.py @@ -1,12 +1,28 @@ -# MED MedCorba_Swig : binding of MED CORBA objects woth Python +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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. # -# Copyright (C) 2003 CEA/DEN, EDF R&D +# 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 # +# MED MedCorba_Swig : binding of MED CORBA objects woth Python # File : batchmode_medcorba_test.py # Module : MED - +# import batchmode_salome import SALOME_MED @@ -17,8 +33,8 @@ from random import * import os -filePath=os.environ["DATA_DIR"] -filePath=filePath+"/MedFiles/" +filePath = os.environ["MED_ROOT_DIR"] +filePath = os.path.join( filePath, "share", "salome", "resources", "med" ) #============================================================================== diff --git a/src/MedCorba_Swig/libMedCorba_Swig.i b/src/MedCorba_Swig/libMedCorba_Swig.i index e4ae4ec9f..96188a06f 100644 --- a/src/MedCorba_Swig/libMedCorba_Swig.i +++ b/src/MedCorba_Swig/libMedCorba_Swig.i @@ -1,21 +1,23 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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. +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE // -// 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 +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// 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. +// +// 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 // %module libMedCorba_Swig @@ -572,7 +574,8 @@ SALOME_MED::MESH_ptr createCorbaMesh(MESH * mesh); %{ SALOME_MED::FIELDDOUBLE_ptr createCorbaFieldDouble(SALOME_MED::SUPPORT_ptr mySupportIOR,FIELDDOUBLE * field, bool ownCppPtr=false) { - BEGIN_OF("SALOME_MED::FIELDDOUBLE_ptr createCorbaFieldDouble from libMedCorba_Swig"); + const char* LOC = "SALOME_MED::FIELDDOUBLE_ptr createCorbaFieldDouble from libMedCorba_Swig"; + BEGIN_OF(LOC); SCRUTE(field); @@ -589,7 +592,7 @@ SALOME_MED::MESH_ptr createCorbaMesh(MESH * mesh); SCRUTE(fieldcorba2); - END_OF("SALOME_MED::FIELDDOUBLE_ptr createCorbaFieldDouble from libMedCorba_Swig"); + END_OF(LOC); MESSAGE("Test de tirarge sur le pointeur Corba Field dans le cxx"); @@ -617,7 +620,8 @@ SALOME_MED::MESH_ptr createCorbaMesh(MESH * mesh); SALOME_MED::FIELDINT_ptr createCorbaFieldInt(SALOME_MED::SUPPORT_ptr mySupportIOR,FIELDINT * field, bool ownCppPtr=false) { - BEGIN_OF("SALOME_MED::FIELDINT_ptr createCorbaFieldInt from libMedCorba_Swig"); + const char* LOC = "SALOME_MED::FIELDINT_ptr createCorbaFieldInt from libMedCorba_Swig"; + BEGIN_OF(LOC); SCRUTE(field); @@ -634,7 +638,7 @@ SALOME_MED::MESH_ptr createCorbaMesh(MESH * mesh); SCRUTE(fieldcorba2); - END_OF("SALOME_MED::FIELDINT_ptr createCorbaFieldInt from libMedCorba_Swig"); + END_OF(LOC); MESSAGE("Test de tirarge sur le pointeur Corba Field dans le cxx"); char * name = fieldcorba2->getName(); @@ -661,7 +665,8 @@ SALOME_MED::MESH_ptr createCorbaMesh(MESH * mesh); SALOME_MED::SUPPORT_ptr createCorbaSupport(const SUPPORT * const support) { - BEGIN_OF("SALOME_MED::SUPPORT_ptr createCorbaSupport from libMedCorba_Swig"); + const char* LOC = "SALOME_MED::SUPPORT_ptr createCorbaSupport from libMedCorba_Swig"; + BEGIN_OF(LOC); SCRUTE(support); @@ -674,14 +679,15 @@ SALOME_MED::MESH_ptr createCorbaMesh(MESH * mesh); SCRUTE(supportcorba); - END_OF("SALOME_MED::SUPPORT_ptr createCorbaSupport from libMedCorba_Swig"); + END_OF(LOC); return supportcorba; } SALOME_MED::MESH_ptr createCorbaMesh(MESH * mesh) { - BEGIN_OF("SALOME_MED::MESH_ptr createCorbaMesh from libMedCorba_Swig"); + const char* LOC = "SALOME_MED::MESH_ptr createCorbaMesh from libMedCorba_Swig"; + BEGIN_OF(LOC); SCRUTE(mesh); @@ -694,7 +700,7 @@ SALOME_MED::MESH_ptr createCorbaMesh(MESH * mesh); SCRUTE(meshcorba); - END_OF("SALOME_MED::MESH_ptr createCorbaMesh from libMedCorba_Swig"); + END_OF(LOC); return meshcorba; } @@ -702,7 +708,8 @@ SALOME_MED::MESH_ptr createCorbaMesh(MESH * mesh); FIELDDOUBLE * createLocalFieldDouble(const int NumberOfComponents, const int LengthValue) { - BEGIN_OF("FIELDDOUBLE createLocalFieldDouble from libMedCorba_Swig"); + const char* LOC = "FIELDDOUBLE createLocalFieldDouble from libMedCorba_Swig"; + BEGIN_OF(LOC); SCRUTE(NumberOfComponents); SCRUTE(LengthValue); @@ -711,7 +718,7 @@ SALOME_MED::MESH_ptr createCorbaMesh(MESH * mesh); FIELDDOUBLE * fieldloc = new FIELDDOUBLE(); fieldloc -> allocValue(NumberOfComponents,LengthValue); - END_OF("FIELDDOUBLE createLocalFieldDouble from libMedCorba_Swig"); + END_OF(LOC); return fieldloc; } @@ -719,7 +726,8 @@ SALOME_MED::MESH_ptr createCorbaMesh(MESH * mesh); FIELDINT * createLocalFieldInt(const int NumberOfComponents, const int LengthValue) { - BEGIN_OF("FIELDINT createLocalFieldInt from libMedCorba_Swig"); + const char* LOC = "FIELDINT createLocalFieldInt from libMedCorba_Swig"; + BEGIN_OF(LOC); SCRUTE(NumberOfComponents); SCRUTE(LengthValue); @@ -728,7 +736,7 @@ SALOME_MED::MESH_ptr createCorbaMesh(MESH * mesh); FIELDINT * fieldloc = new FIELDINT(); fieldloc -> allocValue(NumberOfComponents,LengthValue); - END_OF("FIELDDOUBLE createLocalFieldInt from libMedCorba_Swig"); + END_OF(LOC); return fieldloc; } diff --git a/src/MedCorba_Swig/medcorba_test.py b/src/MedCorba_Swig/medcorba_test.py index 9c568cfdb..f2b3fd6c8 100644 --- a/src/MedCorba_Swig/medcorba_test.py +++ b/src/MedCorba_Swig/medcorba_test.py @@ -1,29 +1,28 @@ -# MED MedCorba_Swig : binding of MED CORBA objects woth Python +# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -# -# 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. -# -# 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 +# 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. # +# 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 +# +# MED MedCorba_Swig : binding of MED CORBA objects woth Python # File : medcorba_test.py # Module : MED - +# import salome import SALOME_MED @@ -37,10 +36,9 @@ from random import * import os -# filePath=os.environ["MED_ROOT_DIR"] -# filePath=filePath+"/share/salome/resources/med/" -filePath = os.environ["DATA_DIR"] -filePath = os.path.join( filePath, "MedFiles" ) +filePath = os.environ["MED_ROOT_DIR"] +filePath = os.path.join( filePath, "share", "salome", "resources", "med" ) + #============================================================================== def AnalyzeField(field): diff --git a/src/ParaMEDMEM/BASICS_JR b/src/ParaMEDMEM/BASICS_JR new file mode 100644 index 000000000..af82fda16 --- /dev/null +++ b/src/ParaMEDMEM/BASICS_JR @@ -0,0 +1,339 @@ + +Le document de specification : +============================== + +Globalement le document de specification correspond a +l'implementation qui a ete faite avec : + +. Transport-ParaMEDMEM qui a ete enrichi avec la classe MPI_Access + +. Presentation-ParaMEDMEM qui a ete enrichi avec la classe + MPI_AccessDEC + + +La conception correspondant a cette specification est restee +la meme : + +. MPI_Access gere pour un ProcessorGroup (IntraCommunicator) : + - Les structures MPI_Request et MPI_Status + - La valeur des "tags" MPI + - Les requetes d'ecritures et de lectures asynchrones + - Les communications en "Point a Point" [I]Send, [I]Recv ainsi + que [I]SendRecv. + - A la difference de l'API MPI [I]SendRecv ne concerne qu'un + seul et meme "target". + - Les controles de communications asynchrones Wait, Test, + WaitAll, TestAll, [I]Probe, Cancel et CancelAll. + - Comme c'etait demande seules les methodes "utiles" ont ete + implementees. + - Les appels a [I]Send ou a [I]Recv avec des sendbuff/recvbuff + de valeur NULL ou avec des sendcount/recvcount de valeur + nulle sont ignores. + - Les methodes de communications collectives ne sont pas + implementees dans MPI_Access. + - Les deux methodes "Cancel" concernent soit un IRecv deja + soumis soit un message en attente (sans IRecv deja soumis). + Elles regroupent les differents appels de l'API MPI + necessaires (IProbe, IRecv, Wait, Test_Canceled ...). + +. MPI_AccessDEC utilise les services de MPI_Access pour un + ProcessorGroup (IntraCommunicator) et gere : + - Les communications collectives en "Point a Point". + (AllToAll[v] synchrone ou asynchrone). + - Les temps et l'interpolation + - Les [I]Send avec leurs buffers (delete []) + - Les [I]Recv + - La finalisation des envois et receptions de messages dans + le destructeur afin qu'il n'y ait plus de message en attente + et afin de liberer les buffers + + +MPI_Access et "tags" (ou "MPITags") : +===================================== + +. Le constructeur permet optionnellement de fixer une plage de tags + a utiliser : [BaseTag , MaxTag]. + Par defaut c'est [ 0 , MPI_TAG_UB], MPI_TAG_UB etant la valeur + maximum d'une implementation de MPI (valeur minimum 32767 + soit 2**15-1). Sur awa avec l'implementation lam MPI_TAG_UB + vaut 7353944. La norme MPI specifie que cette valeur doit + etre la meme dans les process demarres avec mpirun. + Dans le cas de l'usage simultane du meme IntraCommunicator + dans un meme process (ou de plusieurs IntraCommunicator + d'intersection non nulle) cela peut eviter toute ambiguite + et aider au debug. + +. Dans MPI_Access les tags sont constitues de deux parties + (#define ModuloTag 10) : + + Le dernier digit decimal correspond au MPI_DataType ( 1 pour + les messages "temps", 2 pour MPI_INT et 3 pour MPI_DOUBLE) + + La valeur des autres digits correspond a une numerotation + circulaire des messages. + + Un message "temps" et le message de donnees associe ont le + meme numero de message (mais des types et donc des tags + differents). + +. Pour un envoi de message d'un process "source" vers un process + "target", on dispose de _SendMPITag[target] dans le process + source (il contient le dernier "tag" utilise pour l'envoi de + messages vers le process target). + Et dans le process "target" qui recoit ce message, on dispose + de _RecvMPITag[source] (il contient le dernier "tag" utilise + pour la reception de messages du process source). + Naturellement d'apres la norme MPI les valeurs de ces tags sont + les memes. + + +MPI_Access et "RequestIds" : +============================ + +. ATTENTION : Dans le document de specification, la distinction + n'est pas faite clairement entre les "MPITags" (voir ci-dessus) + qui sont un argument des appels a MPI et les "RequestIds" qui + ne concernent pas les appels MPI. Ces "RequestIds" figurent + en effet sous le nom de tag comme argument d'entree/sortie dans l'API + de MPI_Access decrite dans le document de specification. Mais + dans l'implementation on a bien le nom RequestId (ou bien + RecvRequestId/SendRequestId). + +. Lors de la soumission d'une requete d'ecriture ou de lecture MPI + via MPI_Access, on obtient un identifieur "RequestId". + Cet identifieur "RequestId" correspond a une structure RequestStruct + de MPI_Access a laquelle on accede avec la map + "_MapOfRequestStruct". + Cette structure RequestStruct permet de gerer MPI_Request et + MPI_Status * de MPI et permet d'obtenir des informations sur + la requete : target, send/recv, tag, [a]synchrone, type, outcount. + +. C'est cet identifieur qui peut etre utilise pour controler une + requete asynchrone via MPI_Access : Wait, Test, Probe, etc... + +. En pratique "RequestId" est simplement un entier de l'intervalle + [0 , 2**32-1]. Il y a uniquement un compteur cyclique global + aussi bien pour les [I]Send que pour les [I]Recv. + +. Ces "RequestIds" et leur structures associees facilitent les + communications asynchrones. + Par exemple on a mpi_access->Wait( int RequestId ) + au lieu de MPI_Wait(MPI_Request *request, MPI_Status *status) + avec gestion de status. + +. L'API de MPI_Access peut fournir les "SendRequestIds" d'un "target", + les "RecvRequestIds" d'un "source" ou bien les "SendRequestIds" de + tous les "targets" ou les "RecvRequestIds" de tous les "sources". + Cela permet d'eviter leur gestion au niveau de Presentation-ParaMEDMEM. + + +MPI_AccessDEC : +=============== + +. Comme la classe DEC, il est base sur local_group et distant_group + ce qui forme un MPI_union_group et donc un IntraCommunicator. + +. Il permet de choisir le mode synchrone ou asynchrone (par defaut). + Le meme programme peut fonctionner en synchrone ou en asynchrone + sans devoir etre modifie. + +. Il permet de choisir un mode d'interpolation (actuellement + uniquement une interpolation lineaire) ou bien un mode sans + interpolation (par defaut). Ceci pour les communications collectives. + Avec interpolation les communications collectives transmettent et + recoivent un message "temps" en plus des donnees. + +. Il implemente AllToAll[v] en "Point a Point" avec ou sans interpolation. + +. Il gere les buffers d'envoi de messages. Il les detruit donc + lorsqu'ils sont disponibles. + +. Il cree et utilise MPI_Access. + + +MPI_AccessDEC et la gestion des SendBuffers : +============================================= + +. Comme dans les communications collectives on n'envoie que des + parties du meme buffer à chaque process "target", il faut s'assurer + en asynchrone que toutes ces parties sont disponibles pour + pouvoir liberer le buffer. + +. On suppose que ces buffers ont ete alloues avec un new double[] + +. La structure SendBuffStruct permet de conserver l'adresse du buffer + et de gerer un compteur de references de ce buffer. Elle comporte + aussi MPI_Datatype pour pouvoir faire un delete [] (double *) ... + lorsque le compteur est null. + +. La map _MapOfSendBuffers etablit la correspondance entre chaque + RequestId obtenu de MPI_Access->ISend(...) et un SendBuffStruct + pour chaque "target" d'une partie du buffer. + +. Tout cela ne concerne que les envois asynchrones. En synchrone, + on detruit senbuf juste apres l'avoir transmis. + + +MPI_AccessDEC et la gestion des RecvBuffers : +============================================= + +S'il n'y a pas d'interpolation, rien de particulier n'est fait. + +Avec interpolation pour chaque target : +--------------------------------------- +. On a _TimeMessages[target] qui est un vecteur de TimesMessages. + On en a 2 dans notre cas avec une interpolation lineaire qui + contiennent le time(t0)/deltatime precedent et le dernier + time(t1)/deltatime. + +. On a _DataMessages[target] qui est un vecteur de DatasMessages + On en a 2 dans notre cas avec une interpolation lineaire qui + contiennent les donnees obtenues par Recv au time(t0)/deltatime + precedent et au dernier time(t1)/deltatime. + +. Au temps _t(t*) du processus courrant on effectue l'interpolation + entre les valeurs des 2 DatasMessages que l'on rend dans la + partie de recvbuf correspondant au target pourvu que t0 < t* <= t1. + +. Par suite de la difference des "deltatimes" entre process, on + peut avoir t0 < t1 < t* auquel cas on aura une extrapolation. + +. Les vecteurs _OutOfTime, _DataMessagesRecvCount et _DataMessagesType + contiennent pour chaque target true si t* > dernier t1, recvcount et + MPI_Datatype pour finaliser la gestion des messages a la fin. + + +Etapes des communications collectives de MPI_AccessDEC : +======================================================== + +AllToAll[v] : Les arguments sont les memes que dans MPI sauf MPI_Comm +------------- inutile (deja connu de MPI_AccessDEC et MPI_Access). + + Si on a un TimeInterpolator, appel de AllToAll[v]Time. + + Sinon, on appelle CheckSent pour les echanges + asynchrones (voir ci-apres) et on appelle SendRecv + pour chaque "target". + +AllToAll[v]Time : +----------------- + +. CheckSent() : + + appelle SendRequestIds de MPI_Access afin d'obtenir tous les + RequestIds d'envoi de messages a tous les "targets". + + Pour chaque RequestId, appelle Test de MPI_Access pour savoir + si le buffer est libre (flag = true). Lorsqu'il s'agit du + FinalCheckSent, on appelle Wait au lieu de Test. + + Si le buffer est libre, on decremente le compteur de la + structure SendBuffStruct obtenue avec _MapOfSendBuffers. + (voir MPI_AccessDEC et la gestion des SendBuffers ci-dessus) + + Si le compteur est nul on detruit le TimeMessage ou le + SendBuffer en fonction du DataType. + + Puis on detruit la structure SendBuffStruct avant de supprimer + (erase) cet item de _MapOfSendBuffers + +. DoSend : + + On cree un TimeMessage (voir cette structure dans MPI_Access). + + Si l'on est en asynchrone on cree deux structures SendBuffStruct + aSendTimeStruct et aSendDataStruct que l'on remplit. + + On remplit la structure aSendTimeMessage avec time/deltatime du + process courant. "deltatime" doit etre nul s'il s'agit du dernier + pas de temps. + + Puis pour chaque "target", on envoie le TimeMessage et la partie + de sendbuf concernee par ce target. + + Si l'on est en asynchrone, on incremente le compteur et on ajoute + a _MapOfSendBuffers aSendTimeStruct et aSendDataStruct avec les + identifieurs SendTimeRequestId et SendDataRequestId recus de + MPI_Access->Send(...). + + Et enfin si l'on est en synchrone, on detruit les SendMessages. + +. CheckTime(recvcount , recvtype , target , UntilEnd) + + Au depart, on lit le premier "Message-temps" dans + &(*_TimeMessages)[target][1] et le premier message de donnees + dans le buffer alloue (*_DataMessages)[target][1]. + + Par convention deltatime des messages temps est nul si c'est le + dernier. + + Boucle while : _t(t*) est le temps courant du processus. + "tant que _t(t*) est superieur au temps du "target" + (*_TimeMessages)[target][1].time et que + (*_TimeMessages)[target][1].deltatime n'est pas nul", + ainsi en fin de boucle on aura : + _t(t*) <= (*_TimeMessages)[target][1].time avec + _t(t*) > (*_TimeMessages)[target][0].time + ou bien on aura le dernier message temps du "target". + + S'il s'agit de la finalisation des receptions des messages + temps et donnees (UntilEnd vaut true), on effectue la + boucle jusqu'a ce que l'on trouve + (*_TimeMessages)[target][1].deltatime nul. + + Dans la boucle : + On recopie le dernier message temps dans le message temps + precedent et on lit le message temps suivant. + On detruit le buffer de donnees du temps precedent. + On recopie le pointeur du dernier buffer de donnees dans + le precedent. + On alloue un nouveau dernier buffer de donnees + (*_DataMessages)[target][1] et on lit les donnees + correspondantes dans ce buffer. + + Si le temps courant du process est plus grand que le dernier + temps (*_TimeMessages)[target][1].time du target, on donne + la valeur true a (*_OutOfTime)[target]. + (*_TimeMessages)[target][1].deltatime est alors nul. + +. CheckTime + DoRecv + DoInterp + + Pour chaque target on appelle CheckTime + + Si on a un TimeInterpolator et si le message temps du target + n'est pas le premier, on appelle l'interpolateur qui stocke + ses resultats dans la partie du buffer de reception qui + correspond au "target". + + Sinon, on recopie les donnees recues pour ce premier pas de + temps dans la partie du buffer de reception qui correspond au + "target". + + +Presentation-ParaMEDMEM : +========================= + +. Des modifications mineures ont ete effectuees dans Presentation-ParaMEDMEM + afin de pouvoir utiliser ces nouvelles fonctionnalites. Il n'y + a surtout pas eu de bouleversement destabilisateur. L'ancien + mode de fonctionnement reste naturellement disponible. + +. Cela repose sur trois nouvelles options creees avec registerOption + dans le constructeur de IntersectionDEC : + + Asynchronous : true ou false (par defaut) + + TimeInterpolation : WithoutTimeInterp (par defaut) ou LinearTimeInterp + typedef enum{WithoutTimeInterp,LinearTimeInterp} TimeInterpolationMethod; + dans MPI_AccessDEC.hxx + + AllToAllMethod : Native (par defaut) ou PointToPoint + typedef enum{Native,PointToPoint} AllToAllMethod; + dans MxN_Mapping.hxx + +. Le choix des options se fait avec le Data Exchange Channel : + + ParaMEDMEM::IntersectionDEC dec (*source_group,*target_group); + + dec.setOption("Asynchronous",true); + + dec.setOption("TimeInterpolation",LinearTimeInterp); + + dec.setOption("AllToAllMethod",PointToPoint); + +. Dans dec.synchronize(), + + on cree un objet InterpolationMatrix + qui lui-meme cree un objet MxN_Mapping + qui lui-meme cree maintenant un objet MPI_AccessDEC + + on transmet a MxN_Mapping via l'InterpolationMatrix l'option + choisie de AllToAllMethod + + on transmet a MPI_AccessDEC les valeurs des options Asynchronous + et TimeInterpolation : methodes Asynchronous et + SetTimeInterpolator de MPI_AccessDEC. + +. ParaMEDMEM::IntersectionDEC comporte maintenant une surcharge des + methodes recvData() et sendData() : + + void IntersectionDEC::recvData( double time ) qui appelle + SetTime(time) de MPI_AccessDEC et + recvData() + + void IntersectionDEC::sendData( double time , double deltatime ) + qui appelle + SetTime(time,deltatime) de MPI_AccessDEC et + sendData() + +. recvData() et sendData() de ParaMEDMEM::IntersectionDEC + appellent multiply et transposeMultiply de l'InterpolationMatrix + qui appellent sendRecv et reverseSendRecv de MxN_Mapping + qui appellent comm_interface.allToAllV en mode "Native" + ou bien MPI_AccessDEC::AllToAllv en mode "PointToPoint" + diff --git a/src/ParaMEDMEM/BlockTopology.cxx b/src/ParaMEDMEM/BlockTopology.cxx new file mode 100644 index 000000000..e769260cd --- /dev/null +++ b/src/ParaMEDMEM/BlockTopology.cxx @@ -0,0 +1,335 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "BlockTopology.hxx" +#include "MemArray.hxx" +#include "MEDCouplingSMesh.hxx" +#include "CommInterface.hxx" +#include "ProcessorGroup.hxx" +#include "MPIProcessorGroup.hxx" +#include "ComponentTopology.hxx" +#include "InterpKernelUtilities.hxx" + +#include <vector> +#include <algorithm> +#include <utility> +#include <iostream> + +using namespace std; + +namespace ParaMEDMEM +{ + + //!converts a pair <subdomainid,local> to a global number + std::pair<int,int> BlockTopology::globalToLocal(const int global) const + { + int subdomain_id=0; + int position=global; + int size=_nb_elems; + int size_procs=_proc_group->size(); + int increment=size; + vector<int>axis_position(_dimension); + vector<int>axis_offset(_dimension); + for (int idim=0; idim<_dimension; idim++) + { + int axis_size=_local_array_indices[idim].size()-1; + int axis_nb_elem=_local_array_indices[idim][axis_size]; + increment=increment/axis_nb_elem; + int proc_increment = size_procs/(axis_size); + int axis_pos=position/increment; + position=position%increment; + int iaxis=1; + while (_local_array_indices[idim][iaxis]<=axis_pos) + { + subdomain_id+=proc_increment; + iaxis++; + } + axis_position[idim]=axis_pos-_local_array_indices[idim][iaxis-1]; + axis_offset[idim]=iaxis; + } + int local=0; + int local_increment=1; + for (int idim=_dimension-1; idim>=0; idim--) + { + local+=axis_position[idim]*local_increment; + local_increment*=_local_array_indices[idim][axis_offset[idim]]-_local_array_indices[idim][axis_offset[idim]-1]; + } + return make_pair(subdomain_id,local); + } + + //!converts local number to a global number + int BlockTopology::localToGlobal(const pair<int,int> local) const + { + + int subdomain_id=local.first; + int global=0; + int loc=local.second; + int increment=_nb_elems; + int proc_increment=_proc_group->size(); + int local_increment=getNbLocalElements(); + for (int idim=0; idim < _dimension; idim++) + { + int axis_size=_local_array_indices[idim].size()-1; + int axis_nb_elem=_local_array_indices[idim][axis_size]; + increment=increment/axis_nb_elem; + proc_increment = proc_increment/(axis_size); + int proc_axis=subdomain_id/proc_increment; + subdomain_id=subdomain_id%proc_increment; + int local_axis_nb_elem=_local_array_indices[idim][proc_axis+1]-_local_array_indices[idim][proc_axis]; + local_increment = local_increment/local_axis_nb_elem; + int iaxis=loc/local_increment+_local_array_indices[idim][proc_axis]; + global+=increment*iaxis; + loc = loc%local_increment; + } + return global; + } + + //Retrieves the local number of elements + int BlockTopology::getNbLocalElements()const + { + int position=_proc_group->myRank(); + int nb_elem = 1; + int increment=1; + for (int i=_dimension-1; i>=0; i--) + { + increment *=_nb_procs_per_dim[i]; + int idim=position%increment; + position=position/increment; + int imin=_local_array_indices[i][idim]; + int imax=_local_array_indices[i][idim+1]; + nb_elem*=(imax-imin); + } + return nb_elem; + } + + /*! + * Constructor of a block topology from a grid. + * This preliminary version simply splits along the first axis + * instead of making the best choice with respect to the + * values of the different axes. + */ + BlockTopology::BlockTopology(const ProcessorGroup& group, MEDCouplingSMesh *grid): + _proc_group(&group), _dimension(grid->getSpaceDimension()), _owns_processor_group(false) + { + vector <int> axis_length(_dimension); + _nb_elems=1; + for (int idim=0; idim <_dimension; idim++) + { + DataArrayDouble *arr=grid->getCoordsAt(idim); + axis_length[idim]=arr->getNbOfElems(); + _nb_elems*=axis_length[idim]; + } + //default splitting along 1st dimension + _local_array_indices.resize(_dimension); + _nb_procs_per_dim.resize(_dimension); + + _local_array_indices[0].resize(_proc_group->size()+1); + _local_array_indices[0][0]=0; + _nb_procs_per_dim[0]=_proc_group->size(); + + for (int i=1; i<=_proc_group->size(); i++) + { + _local_array_indices[0][i]=_local_array_indices[0][i-1]+ + axis_length[0]/_proc_group->size(); + if (i<= axis_length[0]%_proc_group->size()) + _local_array_indices[0][i]+=1; + } + for (int i=1; i<_dimension; i++) + { + _local_array_indices[i].resize(2); + _local_array_indices[i][0]=0; + _local_array_indices[i][1]=axis_length[i]; + _nb_procs_per_dim[i]=1; + } + _cycle_type.resize(_dimension); + for (int i=0; i<_dimension; i++) + _cycle_type[i]=ParaMEDMEM::Block; + } + + /*! + * Creation of a block topology by composing + * a geometrical topology and a component topology. + * This constructor is intended for creating fields + * for which the parallel distribution is made on the + * components of the field rather than on the geometrical + * partitioning of the underlying mesh. + * + */ + BlockTopology::BlockTopology(const BlockTopology& geom_topo, const ComponentTopology& comp_topo):_owns_processor_group(false) + { + // so far, the block topology can only be created if the proc group + // is either on geom_topo or on comp_topo + if (geom_topo.getProcGroup()->size()>1 && comp_topo.nbBlocks()>1) + throw INTERP_KERNEL::Exception(LOCALIZED("BlockTopology cannot yet be constructed with both complex geo and components topology")); + + if (comp_topo.nbComponents()==1) + { + *this=geom_topo; + return; + } + else + { + _dimension = geom_topo.getDimension()+1; + if (comp_topo.nbBlocks()>1) + _proc_group=comp_topo.getProcGroup(); + else + _proc_group=geom_topo.getProcGroup(); + _local_array_indices=geom_topo._local_array_indices; + vector<int> comp_indices = *(comp_topo.getBlockIndices()); + _local_array_indices.push_back(comp_indices); + _nb_procs_per_dim=geom_topo._nb_procs_per_dim; + _nb_procs_per_dim.push_back(comp_topo.nbBlocks()); + _cycle_type=geom_topo._cycle_type; + _cycle_type.push_back(Block); + _nb_elems=geom_topo.getNbElements()*comp_topo.nbComponents(); + } + } + + /*! Constructor for creating a one-dimensional + * topology from a processor group and a local + * number of elements on each processor + * + * The function must be called only by the processors belonging + * to group \a group. Calling it from a processor not belonging + * to \a group will cause an MPI error, while calling from a subset + * of \a group will result in a deadlock. + */ + BlockTopology::BlockTopology(const ProcessorGroup& group, int nb_elem):_proc_group(&group),_dimension(1),_owns_processor_group(false) + { + int* nbelems_per_proc = new int[group.size()]; + const MPIProcessorGroup* mpi_group=dynamic_cast<const MPIProcessorGroup*>(_proc_group); + const MPI_Comm* comm=mpi_group->getComm(); + int nbtemp=nb_elem; + mpi_group->getCommInterface().allGather(&nbtemp, 1, MPI_INTEGER, + nbelems_per_proc, 1, MPI_INTEGER, + *comm); + _nb_elems=0; + + //splitting along only dimension + _local_array_indices.resize(1); + _nb_procs_per_dim.resize(1); + + _local_array_indices[0].resize(_proc_group->size()+1); + _local_array_indices[0][0]=0; + _nb_procs_per_dim[0]=_proc_group->size(); + + for (int i=1; i<=_proc_group->size(); i++) + { + _local_array_indices[0][i]=_local_array_indices[0][i-1]+ + nbelems_per_proc[i-1]; + _nb_elems+=nbelems_per_proc[i-1]; + } + _cycle_type.resize(1); + _cycle_type[0]=ParaMEDMEM::Block; + delete[] nbelems_per_proc; + } + + BlockTopology::~BlockTopology() + { + if (_owns_processor_group) + delete _proc_group; + } + + /*! Retrieves the min and max indices of the domain stored locally + * for each dimension. The output vector has the topology dimension + * as a size and each pair <int,int> contains min and max. Indices + * range from min to max-1. + */ + std::vector<std::pair<int,int> > BlockTopology::getLocalArrayMinMax() const + { + vector<pair<int,int> > local_indices (_dimension); + int myrank=_proc_group->myRank(); + int increment=1; + for (int i=_dimension-1; i>=0; i--) + { + increment *=_nb_procs_per_dim[i]; + int idim=myrank%increment; + local_indices[i].first=_local_array_indices[i][idim]; + local_indices[i].second=_local_array_indices[i][idim+1]; + cout << local_indices[i].first << " "<< local_indices[i].second<<endl; + } + return local_indices; + } + + /*! Serializes the data contained in the Block Topology + * for communication purposes*/ + void BlockTopology::serialize(int* & serializer, int& size) const + { + vector<int> buffer; + + buffer.push_back(_dimension); + buffer.push_back(_nb_elems); + for (int i=0; i<_dimension; i++) + { + buffer.push_back(_nb_procs_per_dim[i]); + buffer.push_back(_cycle_type[i]); + buffer.push_back(_local_array_indices[i].size()); + for (int j=0; j<_local_array_indices[i].size(); j++) + buffer.push_back(_local_array_indices[i][j]); + } + + //serializing the comm group + int size_comm=_proc_group->size(); + buffer.push_back(size_comm); + MPIProcessorGroup world_group(_proc_group->getCommInterface()); + for (int i=0; i<size_comm;i++) + { + int world_rank=world_group.translateRank(_proc_group, i); + buffer.push_back(world_rank); + } + + serializer=new int[buffer.size()]; + size=buffer.size(); + copy(buffer.begin(), buffer.end(), serializer); + } + + /*! + * + * Unserializes the data contained in the Block Topology + * after communication. Uses the same structure as the one used for serialize() + * + */ + void BlockTopology::unserialize(const int* serializer,const CommInterface& comm_interface) + { + const int* ptr_serializer=serializer; + cout << "unserialize..."<<endl; + _dimension=*(ptr_serializer++); + cout << "dimension "<<_dimension<<endl; + _nb_elems=*(ptr_serializer++); + cout << "nbelems "<<_nb_elems<<endl; + _nb_procs_per_dim.resize(_dimension); + _cycle_type.resize(_dimension); + _local_array_indices.resize(_dimension); + for (int i=0; i<_dimension; i++) + { + _nb_procs_per_dim[i]=*(ptr_serializer++); + _cycle_type[i]=(CYCLE_TYPE)*(ptr_serializer++); + _local_array_indices[i].resize(*(ptr_serializer++)); + for (int j=0; j<_local_array_indices[i].size(); j++) + _local_array_indices[i][j]=*(ptr_serializer++); + } + set<int> procs; + int size_comm=*(ptr_serializer++); + for (int i=0; i<size_comm; i++) + procs.insert(*(ptr_serializer++)); + cout << "unserialize..."<<procs.size()<<endl; + _proc_group=new MPIProcessorGroup(comm_interface,procs); + _owns_processor_group=true; + //TODO manage memory ownership of _proc_group + } +} diff --git a/src/ParaMEDMEM/BlockTopology.hxx b/src/ParaMEDMEM/BlockTopology.hxx new file mode 100644 index 000000000..4a9f3a1ad --- /dev/null +++ b/src/ParaMEDMEM/BlockTopology.hxx @@ -0,0 +1,69 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __BLOCKTOPOLOGY_HXX__ +#define __BLOCKTOPOLOGY_HXX__ + +#include "Topology.hxx" +#include "ProcessorGroup.hxx" + +#include <vector> + +namespace ParaMEDMEM +{ + class ComponentTopology; + class MEDCouplingSMesh; + + typedef enum{Block,Cycle} CYCLE_TYPE; + + class BlockTopology : public Topology + { + public: + BlockTopology() { } + BlockTopology(const ProcessorGroup& group, MEDCouplingSMesh *grid); + BlockTopology(const BlockTopology& geom_topo, const ComponentTopology& comp_topo); + BlockTopology(const ProcessorGroup& group, int nb_elem); + virtual ~BlockTopology(); + //!Retrieves the number of elements for a given topology + int getNbElements()const { return _nb_elems; } + int getNbLocalElements() const; + const ProcessorGroup* getProcGroup()const { return _proc_group; } + std::pair<int,int> globalToLocal (const int) const ; + int localToGlobal (const std::pair<int,int>) const; + std::vector<std::pair<int,int> > getLocalArrayMinMax() const ; + int getDimension() const { return _dimension; } + void serialize(int* & serializer, int& size) const ; + void unserialize(const int* serializer, const CommInterface& comm_interface); + private: + //dimension : 2 or 3 + int _dimension; + //proc array + std::vector<int> _nb_procs_per_dim; + //stores the offsets vector + std::vector<std::vector<int> > _local_array_indices; + //stores the cycle type (block or cyclic) + std::vector<CYCLE_TYPE> _cycle_type; + //Processor group + const ProcessorGroup* _proc_group; + //nb of elements + int _nb_elems; + bool _owns_processor_group; + }; +} + +#endif diff --git a/src/ParaMEDMEM/CommInterface.cxx b/src/ParaMEDMEM/CommInterface.cxx new file mode 100644 index 000000000..abcfaddb8 --- /dev/null +++ b/src/ParaMEDMEM/CommInterface.cxx @@ -0,0 +1,62 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "CommInterface.hxx" + +namespace ParaMEDMEM +{ + /*! \defgroup comm_interface CommInterface + Class \a CommInterface is the gateway to the MPI library. + It is a helper class that gathers the calls to the MPI + library that are made in the ParaMEDMEM library. This gathering + allows easier gathering of information about the communication + in the library. + + It is typically called after the MPI_Init() call in a program. It is afterwards passed as a parameter to the constructors of ParaMEDMEM objects so that they access the MPI library via the CommInterface. + + As an example, the following code excerpt initializes a processor group made of the zero processor. + + \verbatim + #include "CommInterface.hxx" + #include "ProcessorGroup.hxx" + + int main(int argc, char** argv) + { + //initialization + MPI_Init(&argc, &argv); + ParaMEDMEM::CommInterface comm_interface; + + //setting up a processor group with proc 0 + set<int> procs; + procs.insert(0); + ParaMEDMEM::ProcessorGroup group(procs, comm_interface); + + //cleanup + MPI_Finalize(); + } + \endverbatim + */ + + CommInterface::CommInterface() + { + } + + CommInterface::~CommInterface() + { + } +} diff --git a/src/ParaMEDMEM/CommInterface.hxx b/src/ParaMEDMEM/CommInterface.hxx new file mode 100644 index 000000000..39a072c63 --- /dev/null +++ b/src/ParaMEDMEM/CommInterface.hxx @@ -0,0 +1,91 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __COMMINTERFACE_HXX__ +#define __COMMINTERFACE_HXX__ + +#include <mpi.h> +namespace ParaMEDMEM +{ + + class CommInterface + { + public: + CommInterface(){} + virtual ~CommInterface(){} + int worldSize() const { + int size; + MPI_Comm_size(MPI_COMM_WORLD, &size); + return size;} + int commSize(MPI_Comm comm, int* size) const { return MPI_Comm_size(comm,size); } + int commRank(MPI_Comm comm, int* rank) const { return MPI_Comm_rank(comm,rank); } + int commGroup(MPI_Comm comm, MPI_Group* group) const { return MPI_Comm_group(comm, group); } + int groupIncl(MPI_Group group, int size, int* ranks, MPI_Group* group_output) const { return MPI_Group_incl(group, size, ranks, group_output); } + int commCreate(MPI_Comm comm, MPI_Group group, MPI_Comm* comm_output) const { return MPI_Comm_create(comm,group,comm_output); } + int groupFree(MPI_Group* group) const { return MPI_Group_free(group); } + int commFree(MPI_Comm* comm) const { return MPI_Comm_free(comm); } + + int send(void* buffer, int count, MPI_Datatype datatype, int target, int tag, MPI_Comm comm) const { return MPI_Send(buffer,count, datatype, target, tag, comm); } + int recv(void* buffer, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status* status) const { return MPI_Recv(buffer,count, datatype, source, tag, comm, status); } + int sendRecv(void* sendbuf, int sendcount, MPI_Datatype sendtype, + int dest, int sendtag, void* recvbuf, int recvcount, + MPI_Datatype recvtype, int source, int recvtag, MPI_Comm comm, + MPI_Status* status) { return MPI_Sendrecv(sendbuf, sendcount, sendtype, dest, sendtag, recvbuf, recvcount, recvtype, source, recvtag, comm,status); } + + int Isend(void* buffer, int count, MPI_Datatype datatype, int target, + int tag, MPI_Comm comm, MPI_Request *request) const { return MPI_Isend(buffer,count, datatype, target, tag, comm, request); } + int Irecv(void* buffer, int count, MPI_Datatype datatype, int source, + int tag, MPI_Comm comm, MPI_Request* request) const { return MPI_Irecv(buffer,count, datatype, source, tag, comm, request); } + + int wait(MPI_Request *request, MPI_Status *status) const { return MPI_Wait(request, status); } + int test(MPI_Request *request, int *flag, MPI_Status *status) const { return MPI_Test(request, flag, status); } + int requestFree(MPI_Request *request) const { return MPI_Request_free(request); } + int waitany(int count, MPI_Request *array_of_requests, int *index, MPI_Status *status) const { return MPI_Waitany(count, array_of_requests, index, status); } + int testany(int count, MPI_Request *array_of_requests, int *index, int *flag, MPI_Status *status) const { return MPI_Testany(count, array_of_requests, index, flag, status); } + int waitall(int count, MPI_Request *array_of_requests, MPI_Status *array_of_status) const { return MPI_Waitall(count, array_of_requests, array_of_status); } + int testall(int count, MPI_Request *array_of_requests, int *flag, MPI_Status *array_of_status) const { return MPI_Testall(count, array_of_requests, flag, array_of_status); } + int waitsome(int incount, MPI_Request *array_of_requests,int *outcount, int *array_of_indices, MPI_Status *array_of_status) const { return MPI_Waitsome(incount, array_of_requests, outcount, array_of_indices, array_of_status); } + int testsome(int incount, MPI_Request *array_of_requests, int *outcount, + int *array_of_indices, MPI_Status *array_of_status) const { return MPI_Testsome(incount, array_of_requests, outcount, array_of_indices, array_of_status); } + int probe(int source, int tag, MPI_Comm comm, MPI_Status *status) const { return MPI_Probe(source, tag, comm, status) ; } + int Iprobe(int source, int tag, MPI_Comm comm, int *flag, MPI_Status *status) const { return MPI_Iprobe(source, tag, comm, flag, status) ; } + int cancel(MPI_Request *request) const { return MPI_Cancel(request); } + int testCancelled(MPI_Status *status, int *flag) const { return MPI_Test_cancelled(status, flag); } + int barrier(MPI_Comm comm) const { return MPI_Barrier(comm); } + int errorString(int errorcode, char *string, int *resultlen) const { return MPI_Error_string(errorcode, string, resultlen); } + int getCount(MPI_Status *status, MPI_Datatype datatype, int *count) const { return MPI_Get_count(status, datatype, count); } + + int broadcast(void* buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm) const { return MPI_Bcast(buffer, count, datatype, root, comm); } + int allGather(void* sendbuf, int sendcount, MPI_Datatype sendtype, + void* recvbuf, int recvcount, MPI_Datatype recvtype, + MPI_Comm comm) const { return MPI_Allgather(sendbuf,sendcount, sendtype, recvbuf, recvcount, recvtype, comm); } + int allToAll(void* sendbuf, int sendcount, MPI_Datatype sendtype, + void* recvbuf, int recvcount, MPI_Datatype recvtype, + MPI_Comm comm) const { return MPI_Alltoall(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm); } + int allToAllV(void* sendbuf, int* sendcounts, int* senddispls, + MPI_Datatype sendtype, void* recvbuf, int* recvcounts, + int* recvdispls, MPI_Datatype recvtype, + MPI_Comm comm) const { return MPI_Alltoallv(sendbuf, sendcounts, senddispls, sendtype, recvbuf, recvcounts, recvdispls, recvtype, comm); } + + int reduce(void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, + MPI_Op op, int root, MPI_Comm comm) const { return MPI_Reduce(sendbuf, recvbuf, count, datatype, op, root, comm); } + int allReduce(void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) const { return MPI_Allreduce(sendbuf, recvbuf, count, datatype, op, comm); } + }; +} + +#endif /*COMMINTERFACE_HXX_*/ diff --git a/src/ParaMEDMEM/ComponentTopology.cxx b/src/ParaMEDMEM/ComponentTopology.cxx new file mode 100644 index 000000000..850730108 --- /dev/null +++ b/src/ParaMEDMEM/ComponentTopology.cxx @@ -0,0 +1,113 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "ComponentTopology.hxx" +#include "InterpolationUtils.hxx" + +namespace ParaMEDMEM +{ + /* Generic constructor for \a nb_comp components equally parted + * in \a nb_blocks blocks + */ + ComponentTopology::ComponentTopology(int nb_comp, ProcessorGroup* group):_proc_group(group) + { + int nb_blocks=group->size(); + + if (nb_blocks>nb_comp) + throw INTERP_KERNEL::Exception("ComponentTopology Number of components must be larger than number of blocks"); + + _component_array.resize(nb_blocks+1); + _component_array[0]=0; + for (int i=1; i<=nb_blocks; i++) + { + _component_array[i]=_component_array[i-1]+nb_comp/nb_blocks; + if (i<=nb_comp%nb_blocks) + _component_array[i]++; + } + } + + /* Generic constructor for \a nb_comp components equally parted + * in \a nb_blocks blocks + */ + ComponentTopology::ComponentTopology(int nb_comp, int nb_blocks):_proc_group(0) + { + if (nb_blocks>nb_comp) + throw INTERP_KERNEL::Exception("ComponentTopology Number of components must be larger than number of blocks"); + + _component_array.resize(nb_blocks+1); + _component_array[0]=0; + for (int i=1; i<=nb_blocks; i++) + { + _component_array[i]=_component_array[i-1]+nb_comp/nb_blocks; + if (i<=nb_comp%nb_blocks) + _component_array[i]++; + } + + } + + //!Constructor for one block of \a nb_comp components + ComponentTopology::ComponentTopology(int nb_comp):_proc_group(0) + { + + _component_array.resize(2); + _component_array[0]=0; + _component_array[1]=nb_comp; + + } + + //! Constructor for one component + ComponentTopology::ComponentTopology():_proc_group(0) + { + _component_array.resize(2); + _component_array[0]=0; + _component_array[1]=1; + + } + + ComponentTopology::~ComponentTopology() + { + } + + int ComponentTopology::nbLocalComponents() const + { + if (_proc_group==0) + return nbComponents(); + + int nbcomp; + int myrank = _proc_group->myRank(); + if (myrank!=-1) + nbcomp = _component_array[myrank+1]-_component_array[myrank]; + else + nbcomp=0; + return nbcomp; + } + + int ComponentTopology::firstLocalComponent() const + { + if (_proc_group==0) + return 0; + + int icomp; + int myrank = _proc_group->myRank(); + if (myrank!=-1) + icomp = _component_array[myrank]; + else + icomp=-1; + return icomp; + } +} diff --git a/src/ParaMEDMEM/ComponentTopology.hxx b/src/ParaMEDMEM/ComponentTopology.hxx new file mode 100644 index 000000000..7653822c0 --- /dev/null +++ b/src/ParaMEDMEM/ComponentTopology.hxx @@ -0,0 +1,54 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __COMPONENTTOPOLOGY_HXX__ +#define __COMPONENTTOPOLOGY_HXX__ + +#include "ProcessorGroup.hxx" +#include "Topology.hxx" + +#include <vector> + +namespace ParaMEDMEM +{ + class ComponentTopology + { + public: + ComponentTopology(int nb_comp, ProcessorGroup* group); + ComponentTopology(int nb_comp, int nb_blocks); + ComponentTopology(int nb_comp); + ComponentTopology(); + virtual ~ComponentTopology(); + //!returns the number of MED components in the topology + int nbComponents() const { return _component_array.back(); } + //!returns the number of MED components on local processor + int nbLocalComponents() const ; + //!returns the number of the first MED component on local processor + int firstLocalComponent() const ; + //!returns the number of blocks in the topology + int nbBlocks()const {return _component_array.size()-1;} + //!returns the block structure + const std::vector<int>* getBlockIndices() const { return &_component_array; } + const ProcessorGroup* getProcGroup()const { return _proc_group; } + private: + std::vector<int> _component_array; + ProcessorGroup* _proc_group; + }; +} + +#endif /*COMPONENTTOPOLOGY_HXX_*/ diff --git a/src/ParaMEDMEM/DEC.cxx b/src/ParaMEDMEM/DEC.cxx new file mode 100644 index 000000000..a1620c4d1 --- /dev/null +++ b/src/ParaMEDMEM/DEC.cxx @@ -0,0 +1,238 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "CommInterface.hxx" +#include "Topology.hxx" +#include "BlockTopology.hxx" +#include "ComponentTopology.hxx" +#include "ParaFIELD.hxx" +#include "DEC.hxx" +#include "ICoCoField.hxx" +#include "ICoCoMEDField.hxx" +#include "ICoCoTrioField.hxx" +#include "MPIProcessorGroup.hxx" + +#include <cmath> + +/*! \defgroup dec DEC + * + * \section decintroduction Introduction + * + * Interface class for creation of a link between two + * processor groups for exhanging mesh or field data. + * The DEC is defined by attaching a field on the receiving or on the + * sending side. + * On top of attaching a ParaMEDMEM::FIELD, it is possible to + * attach a ICoCo::Field. This class is an abstract class that enables + * coupling of codes that respect the ICoCo interface \ref icoco. It has two implementations: + * one for codes that express their fields as MEDCoupling fields (ICoCo::MEDField) and one + * for codes that express their fields as Trio/U fields. + * + * \section dec_options DEC Options + * Options supported by DEC objects are + * + * <TABLE BORDER=1 > + * <TR><TD>Option</TD><TD>Description</TD><TD>Default value</TD></TR> + * <TR><TD>ForcedRenormalization</TD><TD>After receiving data, the target field is renormalized so that L2-norms of the source and target fields match.</TD><TD> false </TD></TR> + *</TABLE> + + + The following code excerpt shows how to set options for an object that inherits from DEC : + + \code + IntersectionDEC dec(source_group,target_group); + dec.setOptions("ForcedRenormalization",true); + dec.attachLocalField(field); + dec.synchronize(); + if (source_group.containsMyRank()) + dec.sendData(); + else + dec.recvData(); + \endcode +*/ + +namespace ParaMEDMEM +{ + + + /*! \addtogroup dec + @{ + */ + DEC::DEC(ProcessorGroup& source_group, ProcessorGroup& target_group):_local_field(0), + _source_group(&source_group), + _target_group(&target_group), + _owns_field(false), + _icoco_field(0) + { + _union_group = source_group.fuse(target_group); + } + + DEC::~DEC() + { + // delete _union_group; + if(_owns_field) + delete _local_field; + delete _icoco_field; + delete _union_group; + } + /*! Attaches a local field to a DEC. + If the processor is on the receiving end of the DEC, the field + will be updated by a recvData() call. + Reversely, if the processor is on the sending end, the field will be read, possibly transformed, and sent appropriately to the other side. + */ + void DEC::attachLocalField(const ParaFIELD* field) + { + _local_field=field; + _comm_interface=&(field->getTopology()->getProcGroup()->getCommInterface()); + compareFieldAndMethod(); + } + + /*! Attaches a local field to a DEC. The method will test whether the processor + is on the source or the target side and will associate the mesh underlying the + field to the local side. + + If the processor is on the receiving end of the DEC, the field + will be updated by a recvData() call. + Reversely, if the processor is on the sending end, the field will be read, possibly transformed, + and sent appropriately to the other side. + */ + + void DEC::attachLocalField(MEDCouplingFieldDouble* field) + { + ProcessorGroup* local_group; + if (_source_group->containsMyRank()) + local_group=_source_group; + else if (_target_group->containsMyRank()) + local_group=_target_group; + else + throw INTERP_KERNEL::Exception("Invalid procgroup for field attachment to DEC"); + + _local_field= new ParaFIELD(field, *local_group); + _owns_field=true; + _comm_interface=&(local_group->getCommInterface()); + } + + /*! + Attaches a local field to a DEC. + If the processor is on the receiving end of the DEC, the field + will be updated by a recvData() call. + Reversely, if the processor is on the sending end, the field will be read, possibly transformed, and sent appropriately to the other side. + The field type is a generic ICoCo Field, so that the DEC can couple a number of different fields : + - a ICoCo::MEDField, that is created from a MEDCoupling structure + - a ICOCo::TrioField, that is created from tables extracted from a TRIO-U structure. + + */ + + void DEC::attachLocalField(const ICoCo::Field* field) + { + const ICoCo::MEDField* medfield=dynamic_cast<const ICoCo::MEDField*> (field); + if(medfield !=0) + { + attachLocalField(medfield->getField()); + return; + } + const ICoCo::TrioField* triofield=dynamic_cast<const ICoCo::TrioField*> (field); + if (triofield !=0) + { + ProcessorGroup* localgroup; + if (_source_group->containsMyRank()) + localgroup=_source_group; + else + localgroup=_target_group; + _icoco_field=new ICoCo::MEDField(*const_cast<ICoCo::TrioField* >(triofield), *localgroup); + attachLocalField(_icoco_field); + return; + } + throw INTERP_KERNEL::Exception("incompatible field type"); + } + + /*! + Computes the field norm over its support + on the source side and renormalizes the field on the target side + so that the norms match. + + \f[ + I_{source}=\sum_{i=1}^{n_{source}}V_{i}.|\Phi^{source}_{i}|^2, + \f] + + \f[ + I_{target}=\sum_{i=1}^{n_{target}}V_{i}.|\Phi^{target}_{i}|^2, + \f] + + \f[ + \Phi^{target}:=\Phi^{target}.\sqrt{I_{source}/I_{target}}. + \f] + + */ + void DEC::renormalizeTargetField() + { + if (_source_group->containsMyRank()) + for (int icomp=0; icomp<_local_field->getField()->getArray()->getNumberOfComponents(); icomp++) + { + double total_norm = _local_field->getVolumeIntegral(icomp+1); + double source_norm = total_norm; + _comm_interface->broadcast(&source_norm, 1, MPI_DOUBLE, 0,* dynamic_cast<MPIProcessorGroup*>(_union_group)->getComm()); + + } + if (_target_group->containsMyRank()) + { + for (int icomp=0; icomp<_local_field->getField()->getArray()->getNumberOfComponents(); icomp++) + { + double total_norm = _local_field->getVolumeIntegral(icomp+1); + double source_norm=total_norm; + _comm_interface->broadcast(&source_norm, 1, MPI_DOUBLE, 0,* dynamic_cast<MPIProcessorGroup*>(_union_group)->getComm()); + + if (fabs(total_norm)>1e-100) + _local_field->getField()->applyLin(source_norm/total_norm,0.0,icomp+1); + } + } + } + /*! @} */ + + void DEC::compareFieldAndMethod() const throw(INTERP_KERNEL::Exception) + { + if (_local_field) + { + TypeOfField entity = _local_field->getField()->getEntity(); + if ( getMethod() == "P0" ) + { + if ( entity != ON_CELLS ) + throw INTERP_KERNEL::Exception("Field support and interpolation method mismatch." + " For P0 interpolation, field must be on MED_CELL's"); + } + else if ( getMethod() == "P1" ) + { + if ( entity != ON_NODES ) + throw INTERP_KERNEL::Exception("Field support and interpolation method mismatch." + " For P1 interpolation, field must be on MED_NODE's"); + } + else if ( getMethod() == "P1d" ) + { + if ( entity != ON_CELLS ) + throw INTERP_KERNEL::Exception("Field support and interpolation method mismatch." + " For P1d interpolation, field must be on MED_CELL's"); + if ( _target_group->containsMyRank() ) + throw INTERP_KERNEL::Exception("Projection to P1d field not supported"); + } + else + { + throw INTERP_KERNEL::Exception("Unknown interpolation method. Possible methods: P0, P1, P1d"); + } + } + } +} diff --git a/src/ParaMEDMEM/DEC.hxx b/src/ParaMEDMEM/DEC.hxx new file mode 100644 index 000000000..50b8dd1c2 --- /dev/null +++ b/src/ParaMEDMEM/DEC.hxx @@ -0,0 +1,69 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __DEC_HXX__ +#define __DEC_HXX__ + +#include "MEDCouplingFieldDouble.hxx" +#include "NormalizedUnstructuredMesh.hxx" +#include "DECOptions.hxx" + +namespace ICoCo +{ + class Field; +} + +namespace ParaMEDMEM +{ + class ProcessorGroup; + class ParaFIELD; + class CommInterface; + class DEC : public DECOptions + { + public: + DEC():_local_field(0) { } + DEC(ProcessorGroup& source_group, ProcessorGroup& target_group); + void attachLocalField( MEDCouplingFieldDouble* field); + void attachLocalField(const ParaFIELD* field); + void attachLocalField(const ICoCo::Field* field); + + virtual void prepareSourceDE()=0; + virtual void prepareTargetDE()=0; + virtual void recvData()=0; + virtual void sendData()=0; + virtual void synchronize()=0; + virtual ~DEC(); + virtual void computeProcGroup() { } + void renormalizeTargetField(); + protected: + void compareFieldAndMethod() const throw(INTERP_KERNEL::Exception); + protected: + const ParaFIELD* _local_field; + //! Processor group representing the union of target and source processors + ProcessorGroup* _union_group; + ProcessorGroup* _source_group; + ProcessorGroup* _target_group; + + const CommInterface* _comm_interface; + bool _owns_field; + private: + ICoCo::Field* _icoco_field; + }; +} + +#endif diff --git a/src/ParaMEDMEM/DECOptions.hxx b/src/ParaMEDMEM/DECOptions.hxx new file mode 100644 index 000000000..c3eb41e2c --- /dev/null +++ b/src/ParaMEDMEM/DECOptions.hxx @@ -0,0 +1,73 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __DECOPTIONS_HXX__ +#define __DECOPTIONS_HXX__ + +#include <string> + +namespace ParaMEDMEM +{ + //Enum describing the allToAll method used in the communication pattern + typedef enum { Native, PointToPoint } AllToAllMethod; + typedef enum { WithoutTimeInterp, LinearTimeInterp } TimeInterpolationMethod; + + class DECOptions + { + protected: + std::string _method; + bool _asynchronous; + TimeInterpolationMethod _timeInterpolationMethod; + AllToAllMethod _allToAllMethod; + bool _forcedRenormalization; + public: + DECOptions():_method("P0"), + _timeInterpolationMethod(WithoutTimeInterp), + _asynchronous(false), + _forcedRenormalization(false), + _allToAllMethod(Native) + { + } + + DECOptions(const DECOptions& deco) + { + _method=deco._method; + _timeInterpolationMethod=deco._timeInterpolationMethod; + _asynchronous=deco._asynchronous; + _forcedRenormalization=deco._forcedRenormalization; + _allToAllMethod=deco._allToAllMethod; + } + + const std::string& getMethod() const { return _method; } + void setMethod(const char *m) { _method=m; } + + TimeInterpolationMethod getTimeInterpolationMethod() const { return DECOptions::_timeInterpolationMethod; } + void setTimeInterpolationMethod(TimeInterpolationMethod it) { DECOptions::_timeInterpolationMethod=it; } + + bool getForcedRenormalization() const { return DECOptions::_forcedRenormalization; } + void setForcedRenormalization( bool dr) { DECOptions::_forcedRenormalization = dr; } + + bool getAsynchronous() const { return DECOptions::_asynchronous; } + void setAsynchronous( bool dr) { DECOptions::_asynchronous = dr; } + + AllToAllMethod getAllToAllMethod() const { return _allToAllMethod; } + void setAllToAllMethod(AllToAllMethod sp) { _allToAllMethod=sp; } + }; +} + +#endif diff --git a/src/ParaMEDMEM/ElementLocator.cxx b/src/ParaMEDMEM/ElementLocator.cxx new file mode 100644 index 000000000..5397b2a67 --- /dev/null +++ b/src/ParaMEDMEM/ElementLocator.cxx @@ -0,0 +1,520 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <mpi.h> +#include "CommInterface.hxx" +#include "ElementLocator.hxx" +#include "Topology.hxx" +#include "BlockTopology.hxx" +#include "ParaMESH.hxx" +#include "ProcessorGroup.hxx" +#include "MPIProcessorGroup.hxx" + +#include <map> +#include <set> +#include <limits> + +using namespace std; + +namespace ParaMEDMEM +{ + ElementLocator::ElementLocator(const ParaMESH& sourceMesh, + const ProcessorGroup& distant_group) + : _local_para_mesh(sourceMesh), + _local_cell_mesh(sourceMesh.getCellMesh()), + _local_face_mesh(sourceMesh.getFaceMesh()), + _local_group(*sourceMesh.getBlockTopology()->getProcGroup()), + _distant_group(distant_group) + { + _union_group = _local_group.fuse(distant_group); + _computeBoundingBoxes(); + } + + ElementLocator::~ElementLocator() + { + delete _union_group; + delete [] _domain_bounding_boxes; + } + + // ========================================================================== + // Procedure for exchanging mesh between a distant proc and a local processor + // param idistantrank proc id on distant group + // param distant_mesh on return , points to a local reconstruction of + // the distant mesh + // param distant_ids on return, contains a vector defining a correspondence + // between the distant ids and the ids of the local reconstruction + // ========================================================================== + void ElementLocator::exchangeMesh(int idistantrank, + MEDCouplingUMesh*& distant_mesh, + int*& distant_ids) + { + int dim = _local_cell_mesh->getSpaceDimension(); + int rank = _union_group->translateRank(&_distant_group,idistantrank); + + if (find(_distant_proc_ids.begin(), _distant_proc_ids.end(),rank)==_distant_proc_ids.end()) + { + return; + } + + set <int> elems; + double* distant_bb = _domain_bounding_boxes+rank*2*dim; + double* elem_bb=new double[2*dim]; + + //defining pointers to med + const int* conn = _local_cell_mesh->getNodalConnectivity()->getPointer() ; + const int* conn_index= _local_cell_mesh->getNodalConnectivityIndex()->getPointer(); + const double* coords = _local_cell_mesh->getCoords()->getPointer() ; + + for ( int ielem=0; ielem<_local_cell_mesh->getNumberOfCells() ; ielem++) + { + for (int i=0; i<dim; i++) + { + elem_bb[i*2]=std::numeric_limits<double>::max(); + elem_bb[i*2+1]=-std::numeric_limits<double>::max(); + } + + for (int inode=conn_index[ielem]+1; inode<conn_index[ielem+1]; inode++)//+1 due to offset of cell type. + { + int node= conn[inode]; + + for (int idim=0; idim<dim; idim++) + { + if ( coords[node*dim+idim] < elem_bb[idim*2] ) + { + elem_bb[idim*2] = coords[node*dim+idim] ; + } + if ( coords[node*dim+idim] > elem_bb[idim*2+1] ) + { + elem_bb[idim*2+1] = coords[node*dim+idim] ; + } + } + } + if (_intersectsBoundingBox(elem_bb, distant_bb, dim)) + { + elems.insert(ielem); + } + } + //send_mesh contains null pointer if elems is empty + MEDCouplingUMesh* send_mesh = _meshFromElems(elems); + + // Constituting an array containing the ids of the elements that are + // going to be sent to the distant subdomain. + // This array enables the correct redistribution of the data when the + // interpolated field is transmitted to the target array + + int* distant_ids_send=0; + if (elems.size()>0) + { + distant_ids_send = new int[elems.size()]; + int index=0; + for (std::set<int>::const_iterator iter = elems.begin(); iter!= elems.end(); iter++) + { + distant_ids_send[index]=*iter; + index++; + } + } + _exchangeMesh(send_mesh, distant_mesh, idistantrank, distant_ids_send, distant_ids); + delete[] distant_ids_send; + delete[] elem_bb; + send_mesh->decrRef(); + } + + void ElementLocator::exchangeMethod(const std::string& sourceMeth, int idistantrank, std::string& targetMeth) + { + CommInterface comm_interface=_union_group->getCommInterface(); + MPIProcessorGroup* group=static_cast<MPIProcessorGroup*> (_union_group); + const MPI_Comm* comm=(group->getComm()); + MPI_Status status; + // it must be converted to union numbering before communication + int idistRankInUnion = group->translateRank(&_distant_group,idistantrank); + char *recv_buffer=new char[4]; + std::vector<char> send_buffer(4); + std::copy(sourceMeth.begin(),sourceMeth.end(),send_buffer.begin()); + comm_interface.sendRecv(&send_buffer[0], 4, MPI_CHAR,idistRankInUnion, 1112, + recv_buffer, 4, MPI_CHAR,idistRankInUnion, 1112, + *comm, &status); + targetMeth=recv_buffer; + delete [] recv_buffer; + } + + + // ====================== + // Compute bounding boxes + // ====================== + + void ElementLocator::_computeBoundingBoxes() + { + CommInterface comm_interface =_union_group->getCommInterface(); + int dim = _local_cell_mesh->getSpaceDimension(); + _domain_bounding_boxes = new double[2*dim*_union_group->size()]; + const double* coords = _local_cell_mesh->getCoords()->getPointer() ; + + int nbnodes = _local_cell_mesh->getNumberOfNodes(); + double * minmax=new double [2*dim]; + for (int idim=0; idim<dim; idim++) + { + minmax[idim*2]=std::numeric_limits<double>::max(); + minmax[idim*2+1]=-std::numeric_limits<double>::max(); + } + + for (int i=0; i<nbnodes; i++) + { + for (int idim=0; idim<dim;idim++) + { + if ( minmax[idim*2] > coords[i*dim+idim] ) + { + minmax[idim*2] = coords[i*dim+idim] ; + } + if ( minmax[idim*2+1] < coords[i*dim+idim] ) + { + minmax[idim*2+1] = coords[i*dim+idim] ; + } + } + } + + MPIProcessorGroup* group=static_cast<MPIProcessorGroup*> (_union_group); + const MPI_Comm* comm = group->getComm(); + comm_interface.allGather(minmax, 2*dim, MPI_DOUBLE, + _domain_bounding_boxes,2*dim, MPI_DOUBLE, + *comm); + + for (int i=0; i< _distant_group.size(); i++) + { + int rank= _union_group->translateRank(&_distant_group,i); + + if (_intersectsBoundingBox(rank)) + { + _distant_proc_ids.push_back(rank); + } + } + delete[] minmax; + } + + + // ============================================= + // Intersect Bounding Box (with a given "irank") + // ============================================= + bool ElementLocator::_intersectsBoundingBox(int irank) + { + int dim=_local_cell_mesh->getSpaceDimension(); + double* local_bb = _domain_bounding_boxes+_union_group->myRank()*2*dim; + double* distant_bb = _domain_bounding_boxes+irank*2*dim; + + for (int idim=0; idim < _local_cell_mesh->getSpaceDimension(); idim++) + { + const double eps = 1e-12; + bool intersects = (distant_bb[idim*2]<local_bb[idim*2+1]+eps) + && (local_bb[idim*2]<distant_bb[idim*2+1]+eps); + if (!intersects) return false; + } + return true; + } + + // ============================================= + // Intersect Bounding Box given 2 Bounding Boxes + // ============================================= + bool ElementLocator::_intersectsBoundingBox(double* bb1, double* bb2, int dim) + { + double bbtemp[2*dim]; + double deltamax=0.0; + double adjustment_eps=getBoundingBoxAdjustment(); + + for (int i=0; i< dim; i++) + { + double delta = bb1[2*i+1]-bb1[2*i]; + if ( delta > deltamax ) + { + deltamax = delta ; + } + // deltamax = (delta>deltamax)?delta:deltamax; + } + for (int i=0; i<dim; i++) + { + bbtemp[i*2]=bb1[i*2]-deltamax*adjustment_eps; + bbtemp[i*2+1]=bb1[i*2+1]+deltamax*adjustment_eps; + } + + for (int idim=0; idim < dim; idim++) + { + bool intersects = (bbtemp[idim*2]<bb2[idim*2+1]) + && (bb2[idim*2]<bbtemp[idim*2+1]) ; + if (!intersects) return false; + } + return true; + } + + + // ====================== + // Exchanging meshes data + // ====================== + void ElementLocator::_exchangeMesh( MEDCouplingUMesh* local_mesh, + MEDCouplingUMesh*& distant_mesh, + int iproc_distant, + const int* distant_ids_send, + int*& distant_ids_recv) + { + CommInterface comm_interface=_union_group->getCommInterface(); + + // First stage : exchanging sizes + // ------------------------------ + + int* send_buffer = new int[5]; + int* recv_buffer = new int[5]; + + //treatment for non-empty mesh + int nbconn=0; + int nbelems=0; + + if (local_mesh !=0) + { + nbelems = local_mesh->getNumberOfCells(); + nbconn = local_mesh->getMeshLength(); + send_buffer[0] = local_mesh->getSpaceDimension(); + send_buffer[1] = local_mesh->getMeshDimension(); + send_buffer[2] = local_mesh->getNumberOfNodes(); + send_buffer[3] = nbelems; + send_buffer[4] = nbconn; + } + else + { + for (int i=0; i<5; i++) + { + send_buffer[i]=0; + } + } + + MPIProcessorGroup* group=static_cast<MPIProcessorGroup*> (_union_group); + const MPI_Comm* comm=(group->getComm()); + MPI_Status status; + + // iproc_distant is the number of proc in distant group + // it must be converted to union numbering before communication + int iprocdistant_in_union = group->translateRank(&_distant_group, + iproc_distant); + + comm_interface.sendRecv(send_buffer, 5, MPI_INT, iprocdistant_in_union, 1112, + recv_buffer, 5, MPI_INT,iprocdistant_in_union,1112, + *comm, &status); + + int distant_space_dim = recv_buffer[0]; + int distant_mesh_dim = recv_buffer[1]; + int distant_nnodes = recv_buffer[2]; + int distant_nb_elems = recv_buffer[3]; + int distant_nb_conn = recv_buffer[4]; + + delete[] send_buffer; + delete[] recv_buffer; + + // Second stage : exchanging connectivity buffers + // ---------------------------------------------- + + int nb_integers = nbconn + 2*nbelems + 1; + send_buffer = new int[nb_integers]; + const int* conn = 0; + const int* global_numbering=0; + int* ptr_buffer = send_buffer; + + if (local_mesh != 0) + { + conn = local_mesh->getNodalConnectivity()->getPointer(); + + global_numbering = local_mesh->getNodalConnectivityIndex()->getPointer() ; + + //copying the data in the integer buffer + + memcpy(ptr_buffer, global_numbering, (nbelems+1)*sizeof(int)); + ptr_buffer += nbelems+1; + memcpy(ptr_buffer,conn, nbconn*sizeof(int)); + ptr_buffer += nbconn; + memcpy(ptr_buffer, distant_ids_send, nbelems*sizeof(int)); + } + + // Preparing the recv buffers + int nb_recv_integers = distant_nb_conn + 2*distant_nb_elems + 1 ; + recv_buffer=new int[nb_recv_integers]; + + // Exchanging integer buffer + comm_interface.sendRecv(send_buffer, nb_integers, MPI_INT, + iprocdistant_in_union, 1111, + recv_buffer, nb_recv_integers, MPI_INT, + iprocdistant_in_union,1111, + *comm, &status); + + if ( nb_integers>0 ) + { + delete[] send_buffer; + } + + // Third stage : exchanging coordinates + // ------------------------------------ + + int nb_recv_floats = distant_space_dim*distant_nnodes; + int nb_send_floats = 0; + double* coords=0; + + if ( local_mesh!=0 ) + { + nb_send_floats = local_mesh->getSpaceDimension() + * local_mesh->getNumberOfNodes(); + coords = local_mesh->getCoords()->getPointer(); + } + + DataArrayDouble* myCoords=DataArrayDouble::New(); + myCoords->alloc(distant_nnodes,distant_space_dim); + + comm_interface.sendRecv(coords, nb_send_floats, MPI_DOUBLE, + iprocdistant_in_union, 1112, + myCoords->getPointer(), nb_recv_floats, MPI_DOUBLE, + iprocdistant_in_union, 1112, + *group->getComm(), &status); + + + // Reconstructing an image of the distant mesh locally + + if ( nb_recv_integers>0 && distant_space_dim !=0 ) + { + MEDCouplingUMesh* meshing = MEDCouplingUMesh::New() ; + + // Coordinates + meshing->setCoords(myCoords) ; + myCoords->decrRef(); + // Connectivity + + int *work=recv_buffer; + DataArrayInt* myConnecIndex=DataArrayInt::New(); + myConnecIndex->alloc(distant_nb_elems+1,1); + memcpy(myConnecIndex->getPointer(), work, (distant_nb_elems+1)*sizeof(int)); + work += distant_nb_elems + 1 ; + + DataArrayInt* myConnec=DataArrayInt::New(); + myConnec->alloc(distant_nb_conn,1); + memcpy(myConnec->getPointer(), work, (distant_nb_conn)*sizeof(int)); + work+=distant_nb_conn; + meshing->setConnectivity(myConnec, myConnecIndex) ; + myConnec->decrRef(); + myConnecIndex->decrRef(); + + // correspondence between the distant ids and the ids of + // the local reconstruction + + distant_ids_recv=new int [distant_nb_elems]; + for (int i=0; i<distant_nb_elems; i++) + { + distant_ids_recv[i]=*work++; + } + + // Mesh dimension + meshing->setMeshDimension(distant_mesh_dim); + + distant_mesh=meshing; + delete[] recv_buffer; + } + + } + + + // ============== + // _meshFromElems + // ============== + + MEDCouplingUMesh* ElementLocator::_meshFromElems(set<int>& elems) + { + //returns null pointer if there are no elems in the mesh + if ( elems.size()==0 ) return 0; + + // Defining pointers + const int* conn_mesh = + const_cast<int*> (_local_cell_mesh->getNodalConnectivity()->getPointer()); + + const int* conn_index = + const_cast<int*> (_local_cell_mesh->getNodalConnectivityIndex()->getPointer()); + + const double* coords = + const_cast<double*> ( _local_cell_mesh->getCoords()->getPointer()); + + set<int> nodes; + int nbconn=0; + for (set<int>::const_iterator iter=elems.begin(); iter!=elems.end(); iter++) + { + // Conn_index : C-like Addresses + for (int inode=conn_index[*iter]+1; inode<conn_index[*iter+1]; inode++) + { + nodes.insert(conn_mesh[inode]); + nbconn++ ; + } + } + + map<int,int> big2small; + int i=0; + for (set<int>::const_iterator iter=nodes.begin(); iter!=nodes.end(); iter++) + { + big2small[*iter]=i; + i++; + } + + // Memory allocate + DataArrayInt *conn = DataArrayInt::New() ; + conn->alloc(nbconn+elems.size(),1) ; + int *connPtr=conn->getPointer(); + + DataArrayInt * connIndex = DataArrayInt::New() ; + connIndex->alloc(elems.size()+1,1) ; + int* connIndexPtr=connIndex->getPointer(); + + DataArrayDouble *new_coords = DataArrayDouble::New() ; + new_coords->alloc(nodes.size(), _local_cell_mesh->getSpaceDimension()) ; + double *new_coords_ptr = new_coords->getPointer(); + + // New connectivity table + int index=0; + int mainIndex=0; + for (set<int>::const_iterator iter=elems.begin(); iter!=elems.end(); iter++,mainIndex++) + { + connIndexPtr[mainIndex]=index; + connPtr[index++]=conn_mesh[conn_index[*iter]]; + for (int inode = conn_index[*iter]+1; inode < conn_index[*iter+1]; inode++) + { + connPtr[index]=big2small[conn_mesh[inode]] ; // C-like number + index++; + } + } + connIndexPtr[mainIndex]=index; + // Coordinates + index=0; + for (set<int>::const_iterator iter=nodes.begin(); iter!=nodes.end(); iter++) + { + int dim = _local_cell_mesh->getSpaceDimension(); + for (int i=0; i<dim;i++) + { + new_coords_ptr[index]=coords[(*iter)*dim+i]; + index++; + } + } + + // Initialize + MEDCouplingUMesh* meshing = MEDCouplingUMesh::New() ; + meshing->setCoords(new_coords) ; + new_coords->decrRef(); + meshing->setConnectivity(conn, connIndex) ; + conn->decrRef(); + connIndex->decrRef(); + meshing->setMeshDimension(_local_cell_mesh->getMeshDimension()); + + return meshing; + } +} diff --git a/src/ParaMEDMEM/ElementLocator.hxx b/src/ParaMEDMEM/ElementLocator.hxx new file mode 100644 index 000000000..eb05f12d9 --- /dev/null +++ b/src/ParaMEDMEM/ElementLocator.hxx @@ -0,0 +1,69 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __ELEMENTLOCATOR_HXX__ +#define __ELEMENTLOCATOR_HXX__ + +#include "InterpolationOptions.hxx" +#include "MEDCouplingUMesh.hxx" + +#include <vector> +#include <set> + +namespace ParaMEDMEM +{ + class ParaMESH; + class ProcessorGroup; + class ParaSUPPORT; + class InterpolationMatrix; + + + class ElementLocator : public INTERP_KERNEL::InterpolationOptions + { + public: + ElementLocator(const ParaMESH& sourceMesh, const ProcessorGroup& distant_group); + + virtual ~ElementLocator(); + void exchangeMesh(int idistantrank, + MEDCouplingUMesh*& target_mesh, + int*& distant_ids); + void exchangeMethod(const std::string& sourceMeth, int idistantrank, std::string& targetMeth); + private: + const ParaMESH& _local_para_mesh ; + MEDCouplingUMesh* _local_cell_mesh; + MEDCouplingUMesh* _local_face_mesh; + std::vector<MEDCouplingUMesh*> _distant_cell_meshes; + std::vector<MEDCouplingUMesh*> _distant_face_meshes; + double* _domain_bounding_boxes; + const ProcessorGroup& _distant_group; + const ProcessorGroup& _local_group; + ProcessorGroup* _union_group; + std::vector<int> _distant_proc_ids; + + void _computeBoundingBoxes(); + bool _intersectsBoundingBox(int irank); + bool _intersectsBoundingBox(double* bb1, double* bb2, int dim); + void _exchangeMesh(MEDCouplingUMesh* local_mesh, MEDCouplingUMesh*& distant_mesh, + int iproc_distant, const int* distant_ids_send, + int*& distant_ids_recv); + MEDCouplingUMesh* _meshFromElems(std::set<int>& elems); + }; + +} + +#endif diff --git a/src/ParaMEDMEM/ExplicitCoincidentDEC.cxx b/src/ParaMEDMEM/ExplicitCoincidentDEC.cxx new file mode 100644 index 000000000..79ca01197 --- /dev/null +++ b/src/ParaMEDMEM/ExplicitCoincidentDEC.cxx @@ -0,0 +1,384 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <mpi.h> +#include "CommInterface.hxx" +#include "Topology.hxx" +#include "BlockTopology.hxx" +#include "ComponentTopology.hxx" +#include "ParaFIELD.hxx" +#include "MPIProcessorGroup.hxx" +#include "ExplicitCoincidentDEC.hxx" +#include "ExplicitMapping.hxx" +#include "InterpKernelUtilities.hxx" + +using namespace std; + +namespace ParaMEDMEM +{ + + ExplicitCoincidentDEC::ExplicitCoincidentDEC():_toposource(0),_topotarget(0) + { + } + + ExplicitCoincidentDEC::~ExplicitCoincidentDEC() + { + } + + /*! Synchronization process for exchanging topologies + */ + void ExplicitCoincidentDEC::synchronize() + { + if (_source_group->containsMyRank()) + { + _toposource = dynamic_cast<ExplicitTopology*>(_local_field->getTopology()); + _sourcegroup= _toposource->getProcGroup()->createProcGroup(); + _targetgroup=_toposource->getProcGroup()->createComplementProcGroup(); + } + if (_target_group->containsMyRank()) + { + _topotarget = dynamic_cast<ExplicitTopology*>(_local_field->getTopology()); + _sourcegroup= _topotarget->getProcGroup()->createComplementProcGroup(); + _targetgroup=_topotarget->getProcGroup()->createProcGroup(); + } + + // Exchanging + + // Transmitting source topology to target code + broadcastTopology(_toposource,_topotarget,1000); + transferMappingToSource(); + } + + /*! Creates the arrays necessary for the data transfer + * and fills the send array with the values of the + * source field + * */ + void ExplicitCoincidentDEC::prepareSourceDE() + { + //////////////////////////////////// + //Step 1 : buffer array creation + + if (!_toposource->getProcGroup()->containsMyRank()) + return; + MPIProcessorGroup* group=new MPIProcessorGroup(_sourcegroup->getCommInterface()); + + // Warning : the size of the target side is implicitly deduced + //from the size of MPI_COMM_WORLD + int target_size = _toposource->getProcGroup()->getCommInterface().worldSize()- _toposource->getProcGroup()->size() ; + + vector<int>* target_arrays=new vector<int>[target_size]; + + int nb_local = _toposource-> getNbLocalElements(); + + int union_size=group->size(); + + _sendcounts=new int[union_size]; + _senddispls=new int[union_size]; + _recvcounts=new int[union_size]; + _recvdispls=new int[union_size]; + + for (int i=0; i< union_size; i++) + { + _sendcounts[i]=0; + _recvcounts[i]=0; + _recvdispls[i]=0; + } + _senddispls[0]=0; + + int* counts=_explicit_mapping.getCounts(); + for (int i=0; i<group->size(); i++) + _sendcounts[i]=counts[i]; + + for (int iproc=1; iproc<group->size();iproc++) + _senddispls[iproc]=_senddispls[iproc-1]+_sendcounts[iproc-1]; + + _sendbuffer = new double [nb_local * _toposource->getNbComponents()]; + + ///////////////////////////////////////////////////////////// + //Step 2 : filling the buffers with the source field values + + int* counter=new int [target_size]; + counter[0]=0; + for (int i=1; i<target_size; i++) + counter[i]=counter[i-1]+target_arrays[i-1].size(); + + + const double* value = _local_field->getField()->getArray()->getPointer(); + + int* bufferindex= _explicit_mapping.getBufferIndex(); + + for (int ielem=0; ielem<nb_local; ielem++) + { + int ncomp = _toposource->getNbComponents(); + for (int icomp=0; icomp<ncomp; icomp++) + { + _sendbuffer[ielem*ncomp+icomp]=value[bufferindex[ielem]*ncomp+icomp]; + } + } + delete[] target_arrays; + delete[] counter; + } + + /*! + * Creates the buffers for receiving the fields on the target side + */ + void ExplicitCoincidentDEC::prepareTargetDE() + { + if (!_topotarget->getProcGroup()->containsMyRank()) + return; + MPIProcessorGroup* group=new MPIProcessorGroup(_topotarget->getProcGroup()->getCommInterface()); + + vector < vector <int> > source_arrays(_sourcegroup->size()); + int nb_local = _topotarget-> getNbLocalElements(); + for (int ielem=0; ielem< nb_local ; ielem++) + { + //pair<int,int> source_local =_distant_elems[ielem]; + pair <int,int> source_local=_explicit_mapping.getDistantNumbering(ielem); + source_arrays[source_local.first].push_back(source_local.second); + } + int union_size=group->size(); + _recvcounts=new int[union_size]; + _recvdispls=new int[union_size]; + _sendcounts=new int[union_size]; + _senddispls=new int[union_size]; + + for (int i=0; i< union_size; i++) + { + _sendcounts[i]=0; + _recvcounts[i]=0; + _recvdispls[i]=0; + } + for (int iproc=0; iproc < _sourcegroup->size(); iproc++) + { + //converts the rank in target to the rank in union communicator + int unionrank=group->translateRank(_sourcegroup,iproc); + _recvcounts[unionrank]=source_arrays[iproc].size()*_topotarget->getNbComponents(); + } + for (int i=1; i<union_size; i++) + _recvdispls[i]=_recvdispls[i-1]+_recvcounts[i-1]; + _recvbuffer=new double[nb_local*_topotarget->getNbComponents()]; + + } + + + /*! + * Synchronizing a topology so that all the + * group possesses it. + * + * \param toposend Topology that is transmitted. It is read on processes where it already exists, and it is created and filled on others. + * \param toporecv Topology which is received. + * \param tag Communication tag associated with this operation. + */ + void ExplicitCoincidentDEC::broadcastTopology(const ExplicitTopology* toposend, ExplicitTopology* toporecv, int tag) + { + MPI_Status status; + + int* serializer=0; + int size; + + MPIProcessorGroup* group=new MPIProcessorGroup(*_comm_interface); + + // The send processors serialize the send topology + // and send the buffers to the recv procs + if (toposend !=0 && toposend->getProcGroup()->containsMyRank()) + { + toposend->serialize(serializer, size); + for (int iproc=0; iproc< group->size(); iproc++) + { + int itarget=iproc; + if (!toposend->getProcGroup()->contains(itarget)) + { + _comm_interface->send(&size,1,MPI_INT, itarget,tag+itarget,*(group->getComm())); + _comm_interface->send(serializer, size, MPI_INT, itarget, tag+itarget,*(group->getComm())); + } + } + } + else + { + vector <int> size (group->size()); + int myworldrank=group->myRank(); + for (int iproc=0; iproc<group->size();iproc++) + { + int isource = iproc; + if (!toporecv->getProcGroup()->contains(isource)) + { + int nbelem; + _comm_interface->recv(&nbelem, 1, MPI_INT, isource, tag+myworldrank, *(group->getComm()), &status); + int* buffer = new int[nbelem]; + _comm_interface->recv(buffer, nbelem, MPI_INT, isource,tag+myworldrank, *(group->getComm()), &status); + + ExplicitTopology* topotemp=new ExplicitTopology(); + topotemp->unserialize(buffer, *_comm_interface); + delete[] buffer; + + for (int ielem=0; ielem<toporecv->getNbLocalElements(); ielem++) + { + int global = toporecv->localToGlobal(ielem); + int sendlocal=topotemp->globalToLocal(global); + if (sendlocal!=-1) + { + size[iproc]++; + _explicit_mapping.pushBackElem(make_pair(iproc,sendlocal)); + } + } + delete topotemp; + } + } + } + MESSAGE (" rank "<<group->myRank()<< " broadcastTopology is over"); + } + + void ExplicitCoincidentDEC::transferMappingToSource() + { + + MPIProcessorGroup* group=new MPIProcessorGroup(*_comm_interface); + + // sending source->target mapping which is stored by target + //in _distant_elems from target to source + if (_topotarget!=0 && _topotarget->getProcGroup()->containsMyRank()) + { + int world_size = _topotarget->getProcGroup()->getCommInterface().worldSize() ; + int* nb_transfer_union=new int[world_size]; + int* dummy_recv=new int[world_size]; + for (int i=0; i<world_size; i++) + nb_transfer_union[i]=0; + //converts the rank in target to the rank in union communicator + + for (int i=0; i< _explicit_mapping.nbDistantDomains(); i++) + { + int unionrank=group->translateRank(_sourcegroup,_explicit_mapping.getDistantDomain(i)); + nb_transfer_union[unionrank]=_explicit_mapping.getNbDistantElems(i); + } + _comm_interface->allToAll(nb_transfer_union, 1, MPI_INT, dummy_recv, 1, MPI_INT, MPI_COMM_WORLD); + + int* sendbuffer= _explicit_mapping.serialize(_topotarget->getProcGroup()->myRank()); + + int* sendcounts= new int [world_size]; + int* senddispls = new int [world_size]; + for (int i=0; i< world_size; i++) + { + sendcounts[i]=2*nb_transfer_union[i]; + if (i==0) + senddispls[i]=0; + else + senddispls[i]=senddispls[i-1]+sendcounts[i-1]; + } + int* recvcounts=new int[world_size]; + int* recvdispls=new int[world_size]; + int *dummyrecv; + for (int i=0; i <world_size; i++) + { + recvcounts[i]=0; + recvdispls[i]=0; + } + _comm_interface->allToAllV(sendbuffer, sendcounts, senddispls, MPI_INT, dummyrecv, recvcounts, senddispls, MPI_INT, MPI_COMM_WORLD); + + } + //receiving in the source subdomains the mapping sent by targets + else + { + int world_size = _toposource->getProcGroup()->getCommInterface().worldSize() ; + int* nb_transfer_union=new int[world_size]; + int* dummy_send=new int[world_size]; + for (int i=0; i<world_size; i++) + dummy_send[i]=0; + _comm_interface->allToAll(dummy_send, 1, MPI_INT, nb_transfer_union, 1, MPI_INT, MPI_COMM_WORLD); + + int total_size=0; + for (int i=0; i< world_size; i++) + total_size+=nb_transfer_union[i]; + int nbtarget = _targetgroup->size(); + int* targetranks = new int[ nbtarget]; + for (int i=0; i<nbtarget; i++) + targetranks[i]=group->translateRank(_targetgroup,i); + int* mappingbuffer= new int [total_size*2]; + int* sendcounts= new int [world_size]; + int* senddispls = new int [world_size]; + int* recvcounts=new int[world_size]; + int* recvdispls=new int[world_size]; + for (int i=0; i< world_size; i++) + { + recvcounts[i]=2*nb_transfer_union[i]; + if (i==0) + recvdispls[i]=0; + else + recvdispls[i]=recvdispls[i-1]+recvcounts[i-1]; + } + + int *dummysend; + for (int i=0; i <world_size; i++) + { + sendcounts[i]=0; + senddispls[i]=0; + } + _comm_interface->allToAllV(dummysend, sendcounts, senddispls, MPI_INT, mappingbuffer, recvcounts, recvdispls, MPI_INT, MPI_COMM_WORLD); + _explicit_mapping.unserialize(world_size,nb_transfer_union,nbtarget, targetranks, mappingbuffer); + } + } + + void ExplicitCoincidentDEC::recvData() + { + //MPI_COMM_WORLD is used instead of group because there is no + //mechanism for creating the union group yet + MESSAGE("recvData"); + + cout<<"start AllToAll"<<endl; + _comm_interface->allToAllV(_sendbuffer, _sendcounts, _senddispls, MPI_DOUBLE, + _recvbuffer, _recvcounts, _recvdispls, MPI_DOUBLE,MPI_COMM_WORLD); + cout<<"end AllToAll"<<endl; + int nb_local = _topotarget->getNbLocalElements(); + double* value=new double[nb_local*_topotarget->getNbComponents()]; + + vector<int> counters(_sourcegroup->size()); + counters[0]=0; + for (int i=0; i<_sourcegroup->size()-1; i++) + { + MPIProcessorGroup* group=new MPIProcessorGroup(*_comm_interface); + int worldrank=group->translateRank(_sourcegroup,i); + counters[i+1]=counters[i]+_recvcounts[worldrank]; + } + + for (int ielem=0; ielem<nb_local ; ielem++) + { + pair<int,int> distant_numbering=_explicit_mapping.getDistantNumbering(ielem); + int iproc=distant_numbering.first; + int ncomp = _topotarget->getNbComponents(); + for (int icomp=0; icomp< ncomp; icomp++) + value[ielem*ncomp+icomp]=_recvbuffer[counters[iproc]*ncomp+icomp]; + counters[iproc]++; + } + _local_field->getField()->getArray()->useArray(value,true,CPP_DEALLOC,nb_local,_topotarget->getNbComponents()); + } + + void ExplicitCoincidentDEC::sendData() + { + MESSAGE ("sendData"); + for (int i=0; i< 4; i++) + cout << _sendcounts[i]<<" "; + cout <<endl; + for (int i=0; i< 4; i++) + cout << _senddispls[i]<<" "; + cout <<endl; + //MPI_COMM_WORLD is used instead of group because there is no + //mechanism for creating the union group yet + cout <<"start AllToAll"<<endl; + _comm_interface->allToAllV(_sendbuffer, _sendcounts, _senddispls, MPI_DOUBLE, + _recvbuffer, _recvcounts, _recvdispls, MPI_DOUBLE,MPI_COMM_WORLD); + } +} + diff --git a/src/ParaMEDMEM/ExplicitCoincidentDEC.hxx b/src/ParaMEDMEM/ExplicitCoincidentDEC.hxx new file mode 100644 index 000000000..3eb131c01 --- /dev/null +++ b/src/ParaMEDMEM/ExplicitCoincidentDEC.hxx @@ -0,0 +1,61 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __EXPLICITCOINCIDENTDEC_HXX__ +#define __EXPLICITCOINCIDENTDEC_HXX__ + +#include "DEC.hxx" +#include "ExplicitMapping.hxx" +#include "ExplicitTopology.hxx" + +#include <map> + +namespace ParaMEDMEM +{ + class BlockTopology; + + class ExplicitCoincidentDEC : public DEC + { + public: + ExplicitCoincidentDEC(); + virtual ~ExplicitCoincidentDEC(); + void synchronize(); + void broadcastTopology(BlockTopology*&, int tag); + void broadcastTopology(const ExplicitTopology* toposend, ExplicitTopology* toporecv, int tag); + void transferMappingToSource(); + void prepareSourceDE(); + void prepareTargetDE(); + void recvData(); + void sendData(); + private: + ExplicitTopology* _toposource; + ExplicitTopology* _topotarget; + ProcessorGroup* _targetgroup; + ProcessorGroup* _sourcegroup; + int* _sendcounts; + int* _recvcounts; + int* _senddispls; + int* _recvdispls; + double* _recvbuffer; + double* _sendbuffer; + std::map<int,std::pair<int,int> > _distant_elems; + ExplicitMapping _explicit_mapping; + }; +} + +#endif diff --git a/src/ParaMEDMEM/ExplicitMapping.hxx b/src/ParaMEDMEM/ExplicitMapping.hxx new file mode 100644 index 000000000..2cf70a2ae --- /dev/null +++ b/src/ParaMEDMEM/ExplicitMapping.hxx @@ -0,0 +1,175 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __EXPLICITMAPPING_HXX__ +#define __EXPLICITMAPPING_HXX__ + +#include <vector> +#include <map> +#include <set> + +namespace ParaMEDMEM +{ + class ExplicitMapping + { + public: + + ExplicitMapping():_numbers(0), _domains(0), _comm_buffer(0) { } + + ~ExplicitMapping() + { + if (_domains!=0) delete[] _domains; + if (_numbers!=0) delete[] _numbers; + if (_comm_buffer!=0) delete[] _comm_buffer; + } + + void pushBackElem(std::pair<int,int> idistant) + { + _mapping.push_back(idistant); + } + + void setDistantElem(int ilocal, std::pair<int,int> idistant) + { + _mapping[ilocal]=idistant; + } + + int nbDistantDomains() + { + if (_distant_domains.empty()) + { + for (std::vector <std::pair<int,int> >::const_iterator iter= _mapping.begin(); + iter!=_mapping.end(); + iter++) + _distant_domains.insert(iter->first); + } + return _distant_domains.size(); + } + + std::pair <int,int> getDistantNumbering(int ielem)const + { + return _mapping[ielem]; + } + + int getDistantDomain(int i) + { + if (_domains==0) + computeNumbers(); + + return _domains[i]; + } + + int getNbDistantElems(int i) + { + if (_numbers==0) + computeNumbers(); + return _numbers[i]; + } + + int* serialize(int idproc) + { + _comm_buffer=new int[_mapping.size()*2]; + std::vector<int> offsets(_distant_domains.size()); + offsets[0]=0; + for (int i=1; i<_distant_domains.size();i++) + offsets[i]=offsets[i-1]+_numbers[i-1]; + + for (int i=0; i< _mapping.size(); i++) + { + int offset= offsets[_mapping[i].first]; + _comm_buffer[offset*2]=idproc; + _comm_buffer[offset*2+1]=_mapping[i].second; + offsets[_mapping[i].first]++; + } + return _comm_buffer; + } + + void unserialize(int nbprocs, int* sizes,int nbtarget, int* targetrank, int* commbuffer) + { + int total_size=0; + for (int i=0; i< nbprocs; i++) + total_size+=sizes[i]; + + _mapping.resize(total_size); + _buffer_index=new int[total_size]; + int indmap=0; + for (int i=0; i<nbprocs; i++) + for (int ielem=0; ielem<sizes[i]; ielem++) + { + _mapping[indmap].first=i; + _mapping[indmap].second=commbuffer[indmap*2+1]; + _buffer_index[indmap]=commbuffer[indmap*2+1]; + indmap++; + } + _numbers=new int [nbtarget]; + _domains=new int [nbtarget]; + + int index=0; + for (int i=0; i<nbtarget; i++) + { + if (sizes[targetrank[i]]>0) + { + _numbers[index]=sizes[targetrank[i]]; + _domains[index]=i; + index++; + } + } + _send_counts=new int[nbprocs]; + for (int i=0; i<nbprocs; i++) + _send_counts[i]=sizes[i]; + } + + int* getBufferIndex() const { return _buffer_index; } + int* getCounts() const { return _send_counts; } + private: + std::vector <std::pair<int,int> > _mapping; + std::set<int> _distant_domains; + int* _numbers; + int* _domains; + int* _comm_buffer; + int* _buffer_index; + int* _send_counts; + + void computeNumbers() + { + std::map <int,int> counts; + if (_numbers==0) + { + _numbers=new int[nbDistantDomains()]; + _domains=new int[nbDistantDomains()]; + for (int i=0; i< _mapping.size(); i++) + { + if ( counts.find(_mapping[i].first) == counts.end()) + counts.insert(std::make_pair(_mapping[i].first,1)); + else + (counts[_mapping[i].first])++; + } + int counter=0; + for (std::map<int,int>::const_iterator iter=counts.begin(); + iter!=counts.end(); + iter++) + { + _numbers[counter]=iter->second; + _domains[counter]=iter->first; + counter++; + } + } + } + }; +} + +#endif diff --git a/src/ParaMEDMEM/ExplicitTopology.cxx b/src/ParaMEDMEM/ExplicitTopology.cxx new file mode 100644 index 000000000..de90d7060 --- /dev/null +++ b/src/ParaMEDMEM/ExplicitTopology.cxx @@ -0,0 +1,108 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "CommInterface.hxx" +#include "ProcessorGroup.hxx" +#include "MPIProcessorGroup.hxx" +#include "ParaMESH.hxx" +#include "Topology.hxx" +#include "ExplicitTopology.hxx" +#include "BlockTopology.hxx" +#include "ComponentTopology.hxx" + +#include <vector> +#include <algorithm> + +using namespace std; +namespace ParaMEDMEM +{ + +ExplicitTopology::ExplicitTopology(const ParaMESH& paramesh ): +_proc_group(paramesh.getBlockTopology()->getProcGroup()), +_nb_components(1) +{ + _nb_elems=paramesh.getCellMesh()->getNumberOfCells(); + const int* global=paramesh.getGlobalNumberingCell(); + _loc2glob=new int[_nb_elems]; + + for (int i=0; i<_nb_elems; i++) + { + _loc2glob[i]=global[i]; + _glob2loc[global[i]]=i; + } +} + +ExplicitTopology::ExplicitTopology(const ExplicitTopology& topo, int nb_components) +{ + _proc_group = topo._proc_group; + _nb_elems = topo._nb_elems; + _nb_components = nb_components; + _loc2glob=new int[_nb_elems]; + for (int i=0; i<_nb_elems; i++) + { + _loc2glob[i]=topo._loc2glob[i]; + } + _glob2loc=topo._glob2loc; +} + + +ExplicitTopology::~ExplicitTopology() +{ + if (_loc2glob != 0) delete[] _loc2glob; +} + + +/*! Serializes the data contained in the Explicit Topology + * for communication purposes*/ +void ExplicitTopology::serialize(int* & serializer, int& size) const +{ + vector <int> buffer; + + buffer.push_back(_nb_elems); + for (int i=0; i<_nb_elems; i++) + { + buffer.push_back(_loc2glob[i]); + } + + serializer=new int[buffer.size()]; + size= buffer.size(); + copy(buffer.begin(), buffer.end(), serializer); + +} +/*! Unserializes the data contained in the Explicit Topology + * after communication. Uses the same structure as the one used for serialize() + * + * */ +void ExplicitTopology::unserialize(const int* serializer,const CommInterface& comm_interface) +{ + const int* ptr_serializer=serializer; + cout << "unserialize..."<<endl; + _nb_elems=*ptr_serializer++; + cout << "nbelems "<<_nb_elems<<endl; + _loc2glob=new int[_nb_elems]; + for (int i=0; i<_nb_elems; i++) + { + _loc2glob[i]=*ptr_serializer; + _glob2loc[*ptr_serializer]=i; + ptr_serializer++; + + } + +} + +} diff --git a/src/ParaMEDMEM/ExplicitTopology.hxx b/src/ParaMEDMEM/ExplicitTopology.hxx new file mode 100644 index 000000000..453294a39 --- /dev/null +++ b/src/ParaMEDMEM/ExplicitTopology.hxx @@ -0,0 +1,91 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __EXPLICITTOPOLOGY_HXX__ +#define __EXPLICITTOPOLOGY_HXX__ + +#include "ProcessorGroup.hxx" + +#include <vector> +#include <utility> +#include <iostream> +#include <ext/hash_map> + +namespace ParaMEDMEM +{ + class ParaMESH; + class Topology; + class ComponentTopology; + + class ExplicitTopology : public Topology + { + public: + ExplicitTopology() { } + ExplicitTopology( const ExplicitTopology& topo, int nbcomponents); + ExplicitTopology(const ParaMESH &mesh); + virtual ~ExplicitTopology(); + + inline int getNbElements()const; + inline int getNbLocalElements() const; + const ProcessorGroup* getProcGroup()const { return _proc_group; } + int localToGlobal (const std::pair<int,int> local) const { return localToGlobal(local.second); } + inline int localToGlobal(int) const; + inline int globalToLocal(int) const; + void serialize(int* & serializer, int& size) const ; + void unserialize(const int* serializer, const CommInterface& comm_interface); + int getNbComponents() const { return _nb_components; } + private: + //Processor group + const ProcessorGroup* _proc_group; + //nb of elements + int _nb_elems; + //nb of components + int _nb_components; + //mapping local to global + int* _loc2glob; + //mapping global to local + __gnu_cxx::hash_map<int,int> _glob2loc; + }; + + //!converts a pair <subdomainid,local> to a global number + inline int ExplicitTopology::globalToLocal(const int global) const + { + return (_glob2loc.find(global))->second;; + } + + //!converts local number to a global number + int ExplicitTopology::localToGlobal(int local) const + { + return _loc2glob[local]; + } + + //!Retrieves the number of elements for a given topology + inline int ExplicitTopology::getNbElements() const + { + return _nb_elems; + } + + //Retrieves the local number of elements + inline int ExplicitTopology::getNbLocalElements()const + { + return _glob2loc.size(); + } +} + + +#endif diff --git a/src/ParaMEDMEM/ICoCoField.hxx b/src/ParaMEDMEM/ICoCoField.hxx new file mode 100644 index 000000000..b2436fde4 --- /dev/null +++ b/src/ParaMEDMEM/ICoCoField.hxx @@ -0,0 +1,38 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __ICOCOFIELD_HXX__ +#define __ICOCOFIELD_HXX__ + +#include <string> + +namespace ICoCo +{ + class Field + { + public: + Field() { } + virtual ~Field() { } + void setName(const std::string& name) { _name=name; } + std::string getName() const { return _name; } + protected: + std::string _name; + }; +} + +#endif diff --git a/src/ParaMEDMEM/ICoCoMEDField.cxx b/src/ParaMEDMEM/ICoCoMEDField.cxx new file mode 100644 index 000000000..65522d7b8 --- /dev/null +++ b/src/ParaMEDMEM/ICoCoMEDField.cxx @@ -0,0 +1,143 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "ICoCoMEDField.hxx" +#include "ICoCoTrioField.hxx" +#include "ProcessorGroup.hxx" +#include "ParaMESH.hxx" +#include "ParaFIELD.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace ICoCo +{ + + /*! Constructor directly attaching a ParaMESH and a ParaFIELD + the object does not take the control the objects pointed by + \a mesh and \a field. + */ + + MEDField::MEDField(ParaMEDMEM::ParaMESH* mesh, ParaMEDMEM::ParaFIELD* field): + _mesh(mesh), + _field(field), + _has_field_ownership(false), + _local_mesh(0), + _support(0), + _comp_topology(0) + { + } + + MEDField::MEDField(TrioField& triofield, const ParaMEDMEM::ProcessorGroup& group): + _has_field_ownership(true) + { + _local_mesh = ParaMEDMEM::MEDCouplingUMesh::New(); + _local_mesh->setMeshDimension(triofield._space_dim); + ParaMEDMEM::DataArrayDouble *myCoords=ParaMEDMEM::DataArrayDouble::New(); + myCoords->alloc(triofield._nbnodes,triofield._space_dim); + _local_mesh->setCoords(myCoords); + double *ptr=myCoords->getPointer(); + std::copy(triofield._coords,triofield._coords+triofield._space_dim*triofield._nbnodes,ptr); + _local_mesh->allocateCells(triofield._nb_elems); + INTERP_KERNEL::NormalizedCellType elemtype; + switch (triofield._mesh_dim) + { + case 2: + switch (triofield._nodes_per_elem) + { + case 3: + elemtype=INTERP_KERNEL::NORM_TRI3; + break; + case 4 : + elemtype=INTERP_KERNEL::NORM_QUAD4; + break; + default: + throw INTERP_KERNEL::Exception("incompatible Trio field - wrong nb of nodes per elem"); + } + break; + case 3: + switch (triofield._nodes_per_elem) + { + case 4: + elemtype=INTERP_KERNEL::NORM_TETRA4; + break; + case 8 : + elemtype=INTERP_KERNEL::NORM_HEXA8; + break; + default: + throw INTERP_KERNEL::Exception("incompatible Trio field - wrong nb of nodes per elem"); + } + break; + default: + throw INTERP_KERNEL::Exception("incompatible Trio field - wrong mesh dimension"); + } + //creating a connectivity table that complies to MED (1 indexing) + //and passing it to _local_mesh + int* conn=new int[triofield._nb_elems*triofield._nodes_per_elem]; + for (int i=0; i<triofield._nb_elems;i++) + for(int j=0;j<triofield._nodes_per_elem;j++) + { + conn[j]=(triofield._connectivity)[i*triofield._nb_elems+j]; + _local_mesh->insertNextCell(elemtype,triofield._nodes_per_elem,conn); + } + delete[] conn; + + _local_mesh->setMeshDimension(triofield._mesh_dim); + + _mesh=new ParaMEDMEM::ParaMESH(_local_mesh, group, "support for trio field"); + _comp_topology=new ParaMEDMEM::ComponentTopology(triofield._nb_field_components); + + //field on the sending end + if (triofield._field!=0) + { + _field = new ParaMEDMEM::ParaFIELD(ParaMEDMEM::ON_CELLS,_mesh, *_comp_topology ); + ParaMEDMEM::DataArrayDouble *fieldArr=_field->getField()->getArray(); + _field->getField()->setName(triofield.getName().c_str()); + _field->getField()->setTime(triofield._time1); + _field->getField()->setDtIt(0,triofield._itnumber); + for (int i =0; i<triofield._nb_elems; i++) + for (int j=0; j<triofield._nb_field_components; j++) + { + fieldArr->setIJ(i,j,triofield._field[i*triofield._nb_field_components+j]); + } + } + //field on the receiving end + else + { + _field = new ParaMEDMEM::ParaFIELD(ParaMEDMEM::ON_CELLS,_support, *_comp_topology ); + _field->getField()->setName(triofield.getName().c_str()); + _field->getField()->setTime(triofield._time1); + _field->getField()->setDtIt(0,triofield._itnumber); + // the trio field points to the pointer inside the MED field + triofield._field=const_cast<double*> (_field->getField()->getArray()->getPointer()); + for (int i=0; i<triofield._nb_field_components*triofield._nb_elems;i++) + triofield._field[i]=0.0; + } + } + + MEDField::~MEDField() + { + delete _comp_topology; + delete _support; + _support=0; + if (_has_field_ownership) + { + delete _field; + delete _mesh; + } + } + +}; diff --git a/src/ParaMEDMEM/ICoCoMEDField.hxx b/src/ParaMEDMEM/ICoCoMEDField.hxx new file mode 100644 index 000000000..94d2ed592 --- /dev/null +++ b/src/ParaMEDMEM/ICoCoMEDField.hxx @@ -0,0 +1,60 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __ICOCOMEDFIELD_HXX__ +#define __ICOCOMEDFIELD_HXX__ + +#include "ICoCoField.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" + +#include <vector> + +namespace ParaMEDMEM +{ + class ParaMESH; + class ParaFIELD; + class ParaSUPPORT; + class ComponentTopology; + class ProcessorGroup; +} +namespace ICoCo +{ + class TrioField; + + class MEDField : public ICoCo::Field + { + public: + MEDField(){}; + MEDField(ParaMEDMEM::ParaMESH* mesh, ParaMEDMEM::ParaFIELD* field); + MEDField(TrioField& , const ParaMEDMEM::ProcessorGroup& group); + virtual ~MEDField(); + ParaMEDMEM::ParaFIELD* getField() const { return _field; } + ParaMEDMEM::ParaMESH* getMesh()const { return _mesh; } + private: + ParaMEDMEM::ParaMESH* _mesh; + ParaMEDMEM::ParaFIELD* _field; + ParaMEDMEM::MEDCouplingFieldDouble* _local_field; + bool _has_field_ownership; + ParaMEDMEM::MEDCouplingUMesh* _local_mesh; + ParaMEDMEM::ParaMESH* _support; + ParaMEDMEM::ComponentTopology* _comp_topology; + }; +}; + +#endif diff --git a/src/ParaMEDMEM/ICoCoTrioField.hxx b/src/ParaMEDMEM/ICoCoTrioField.hxx new file mode 100644 index 000000000..869745b4c --- /dev/null +++ b/src/ParaMEDMEM/ICoCoTrioField.hxx @@ -0,0 +1,59 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __ICOCOTRIOFIELD_HXX__ +#define __ICOCOTRIOFIELD_HXX__ + +#include "ICoCoField.hxx" + +#include <string> + +namespace ICoCo +{ + /*! + \brief structure for coupling Trio codes via the ICoCo interface + + This structure contains all the necessary information + for constructing a ParaMEDMEM::ParaFIELD (with the addition of the MPI + communicator). The ICoCo API specifies two kinds of calls for + the ICoCo::Field : either with the mesh only or with the entire information (mesh and field). + This structure can therefore be left without _time, _nb_field_components, _field + information, which are related to the field values. + */ + class TrioField : public Field + { + public: + TrioField() { _connectivity=0; _coords=0; _field=0; _has_field_ownership=false; } + ~TrioField() { delete[] _connectivity; delete[] _coords; if (_has_field_ownership) delete[] _field; } + public: + int _mesh_dim; + int _space_dim; + int _nbnodes; + int _nodes_per_elem; + int _nb_elems; + int _itnumber; + int* _connectivity; + double* _coords; + double _time1,_time2; + int _nb_field_components; + double* _field; + bool _has_field_ownership; + }; +} + +#endif diff --git a/src/ParaMEDMEM/InterpolationMatrix.cxx b/src/ParaMEDMEM/InterpolationMatrix.cxx new file mode 100644 index 000000000..e4605258c --- /dev/null +++ b/src/ParaMEDMEM/InterpolationMatrix.cxx @@ -0,0 +1,574 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "ParaMESH.hxx" +#include "ProcessorGroup.hxx" +#include "MxN_Mapping.hxx" +#include "InterpolationMatrix.hxx" +#include "TranslationRotationMatrix.hxx" +#include "Interpolation.hxx" +#include "Interpolation2D.txx" +#include "Interpolation3DSurf.txx" +#include "Interpolation3D.txx" +#include "MEDCouplingNormalizedUnstructuredMesh.txx" +#include "InterpolationOptions.hxx" +#include "VolSurfFormulae.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +// class InterpolationMatrix +// This class enables the storage of an interpolation matrix Wij mapping +// source field Sj to target field Ti via Ti=Vi^(-1).Wij.Sj. +// The matrix is built and stored on the processors belonging to the source +// group. + +using namespace std; + +namespace ParaMEDMEM +{ + + // ==================================================================== + // Creates an empty matrix structure linking two distributed supports. + // The method must be called by all processors belonging to source + // and target groups. + // param source_support local support + // param source_group processor group containing the local processors + // param target_group processor group containing the distant processors + // param method interpolation method + // ==================================================================== + + InterpolationMatrix::InterpolationMatrix(ParaMEDMEM::ParaMESH *source_support, + const ProcessorGroup& source_group, + const ProcessorGroup& target_group, + const DECOptions& dec_options, + const INTERP_KERNEL::InterpolationOptions& interp_options): + _source_support(source_support->getCellMesh()), + _mapping(source_group, target_group, dec_options), + _source_group(source_group), + _target_group(target_group), + _source_volume(0), + DECOptions(dec_options), + INTERP_KERNEL::InterpolationOptions(interp_options) + { + int nbelems = _source_support->getNumberOfCells(); + + _row_offsets.resize(nbelems+1); + for (int i=0; i<nbelems+1; i++) + { + _row_offsets[i]=0; + } + + _coeffs.resize(nbelems); + } + + InterpolationMatrix::~InterpolationMatrix() + { + } + + + // ====================================================================== + // \brief Adds the contribution of a distant subdomain to the* + // interpolation matrix. + // The method adds contribution to the interpolation matrix. + // For each row of the matrix, elements are addded as + // a (column, coeff) pair in the _coeffs array. This column number refers + // to an element on the target side via the _col_offsets array. + // It is made of a series of (iproc, ielem) pairs. + // The number of elements per row is stored in the row_offsets array. + + // param distant_support local representation of the distant subdomain + // param iproc_distant id of the distant subdomain (in the distant group) + // param distant_elems mapping between the local representation of + // the subdomain and the actual elem ids on the distant subdomain + // ====================================================================== + + void InterpolationMatrix::addContribution ( MEDCouplingUMesh& distant_support, + int iproc_distant, + int* distant_elems, + const std::string& srcMeth, + const std::string& targetMeth) + { + if (distant_support.getMeshDimension() != _source_support->getMeshDimension()) + { + throw INTERP_KERNEL::Exception("local and distant meshes do not have the same space and mesh dimensions"); + } + std::string interpMethod(srcMeth); + interpMethod+=targetMeth; + //creating the interpolator structure + vector<map<int,double> > surfaces; + int colSize=0; + //computation of the intersection volumes between source and target elements + + if ( distant_support.getMeshDimension() == 2 + && distant_support.getSpaceDimension() == 3 ) + { + MEDCouplingNormalizedUnstructuredMesh<3,2> target_wrapper(&distant_support); + MEDCouplingNormalizedUnstructuredMesh<3,2> source_wrapper(_source_support); + + INTERP_KERNEL::Interpolation3DSurf interpolator (*this); + colSize=interpolator.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod.c_str()); + target_wrapper.ReleaseTempArrays(); + source_wrapper.ReleaseTempArrays(); + } + else if ( distant_support.getMeshDimension() == 2 + && distant_support.getSpaceDimension() == 2) + { + MEDCouplingNormalizedUnstructuredMesh<2,2> target_wrapper(&distant_support); + MEDCouplingNormalizedUnstructuredMesh<2,2> source_wrapper(_source_support); + + INTERP_KERNEL::Interpolation2D interpolator (*this); + colSize=interpolator.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod.c_str()); + target_wrapper.ReleaseTempArrays(); + source_wrapper.ReleaseTempArrays(); + } + else if ( distant_support.getMeshDimension() == 3 + && distant_support.getSpaceDimension() ==3 ) + { + MEDCouplingNormalizedUnstructuredMesh<3,3> target_wrapper(&distant_support); + MEDCouplingNormalizedUnstructuredMesh<3,3> source_wrapper(_source_support); + + INTERP_KERNEL::Interpolation3D interpolator (*this); + colSize=interpolator.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod.c_str()); + target_wrapper.ReleaseTempArrays(); + source_wrapper.ReleaseTempArrays(); + } + else + { + throw INTERP_KERNEL::Exception("no interpolator exists for these mesh and space dimensions "); + } + + int source_size=surfaces.size(); + + MEDCouplingFieldDouble *target_triangle_surf = + getSupportVolumes(&distant_support); + MEDCouplingFieldDouble *source_triangle_surf = + getSupportVolumes(_source_support) ; + + // Storing the source volumes + _source_volume.resize(source_size); + for (int i=0; i<source_size; i++) + { + _source_volume[i] = source_triangle_surf->getIJ(i,0); + } + + source_triangle_surf->decrRef(); + + //loop over the elements to build the interpolation + //matrix structures + for (int ielem=0; ielem < surfaces.size(); ielem++) + { + _row_offsets[ielem+1] += surfaces[ielem].size(); + //_source_indices.push_back(make_pair(iproc_distant, ielem)); + + for (map<int,double>::const_iterator iter = surfaces[ielem].begin(); + iter != surfaces[ielem].end(); + iter++) + { + //surface of the target triangle + double surf = target_triangle_surf->getIJ(iter->first,0); + + //locating the (iproc, itriangle) pair in the list of columns + vector<pair<int,int> >::iterator iter2 = + find(_col_offsets.begin(), _col_offsets.end(), + make_pair(iproc_distant,iter->first)); + int col_id; + + if (iter2 == _col_offsets.end()) + { + //(iproc, itriangle) is not registered in the list + //of distant elements + + _col_offsets.push_back(make_pair(iproc_distant,iter->first)); + col_id =_col_offsets.size(); + _mapping.addElementFromSource(iproc_distant, + distant_elems[iter->first]); + _target_volume.push_back(surf); + } + else + { + col_id = iter2 - _col_offsets.begin() + 1; + } + + //the non zero coefficient is stored + //ielem is the row, + //col_id is the number of the column + //iter->second is the value of the coefficient + + _coeffs[ielem].push_back(make_pair(col_id,iter->second)); + } + } + target_triangle_surf->decrRef(); + } + + + // ================================================================== + // The call to this method updates the arrays on the target side + // so that they know which amount of data from which processor they + // should expect. + // That call makes actual interpolations via multiply method + // available. + // ================================================================== + + void InterpolationMatrix::prepare() + { + int nbelems = _source_support->getNumberOfCells(); + for (int ielem=0; ielem < nbelems; ielem++) + { + _row_offsets[ielem+1]+=_row_offsets[ielem]; + } + _mapping.prepareSendRecv(); + } + + + // ======================================================================= + // brief performs t=Ws, where t is the target field, s is the source field + + // The call to this method must be called both on the working side + // and on the idle side. On the working side, the vector T=VT^(-1).(W.S) + // is computed and sent. On the idle side, no computation is done, but the + // result from the working side is received and the field is updated. + + // param field source field on processors involved on the source side, + // target field on processors on the target side + // ======================================================================= + + void InterpolationMatrix::multiply(MEDCouplingFieldDouble& field) const + { + int nbcomp = field.getArray()->getNumberOfComponents(); + vector<double> target_value(_col_offsets.size()* nbcomp,0.0); + + //computing the matrix multiply on source side + if (_source_group.containsMyRank()) + { + int nbrows = _source_support->getNumberOfCells(); + + // performing W.S + // W is the intersection matrix + // S is the source vector + + for (int irow=0; irow<nbrows; irow++) + { + for (int icomp=0; icomp< nbcomp; icomp++) + { + double coeff_row = field.getIJ(irow,icomp); + for (int icol=_row_offsets[irow]; icol< _row_offsets[irow+1];icol++) + { + int colid= _coeffs[irow][icol-_row_offsets[irow]].first; + double value = _coeffs[irow][icol-_row_offsets[irow]].second; + target_value[(colid-1)*nbcomp+icomp]+=value*coeff_row; + } + } + } + + // performing VT^(-1).(W.S) + // where VT^(-1) is the inverse of the diagonal matrix containing + // the volumes of target cells + + for (int i=0; i<_col_offsets.size();i++) + { + for (int icomp=0; icomp<nbcomp; icomp++) + { + target_value[i*nbcomp+icomp] /= _target_volume[i]; + } + } + + } + + if (_target_group.containsMyRank()) + { + int nbelems = field.getArray()->getNumberOfTuples() ; + double* value = const_cast<double*> (field.getArray()->getPointer()); + for (int i=0; i<nbelems*nbcomp; i++) + { + value[i]=0.0; + } + } + + //on source side : sending T=VT^(-1).(W.S) + //on target side :: receiving T and storing it in field + _mapping.sendRecv(&target_value[0],field); + } + + + // ========================================================================= + // brief performs s=WTt, where t is the target field, s is the source field, + // WT is the transpose matrix from W + + // The call to this method must be called both on the working side + // and on the idle side. On the working side, the target vector T is + // received and the vector S=VS^(-1).(WT.T) is computed to update + // the field. + // On the idle side, no computation is done, but the field is sent. + + // param field source field on processors involved on the source side, + // target field on processors on the target side + // ========================================================================= + + void InterpolationMatrix::transposeMultiply(MEDCouplingFieldDouble& field) const + { + // int nbcomp = field.getNumberOfComponents(); + int nbcomp = field.getArray()->getNumberOfComponents(); + vector<double> source_value(_col_offsets.size()* nbcomp,0.0); + _mapping.reverseSendRecv(&source_value[0],field); + + //treatment of the transpose matrix multiply on the source side + if (_source_group.containsMyRank()) + { + int nbrows = _source_support->getNumberOfCells(); + double *array = field.getArray()->getPointer() ; + + // Initialization + std::fill(array, array+nbrows*nbcomp, 0.0) ; + + //performing WT.T + //WT is W transpose + //T is the target vector + for (int irow = 0; irow < nbrows; irow++) + { + for (int icol = _row_offsets[irow]; icol < _row_offsets[irow+1]; icol++) + { + int colid = _coeffs[irow][icol-_row_offsets[irow]].first; + double value = _coeffs[irow][icol-_row_offsets[irow]].second; + + for (int icomp=0; icomp<nbcomp; icomp++) + { + double coeff_row = source_value[(colid-1)*nbcomp+icomp]; + array[irow*nbcomp+icomp] += value*coeff_row; + } + } + } + + //performing VS^(-1).(WT.T) + //VS^(-1) is the inverse of the diagonal matrix storing + //volumes of the source cells + + for (int irow=0; irow<nbrows; irow++) + { + for (int icomp=0; icomp<nbcomp; icomp++) + { + array[irow*nbcomp+icomp] /= _source_volume[irow]; + } + } + + } + } + + MEDCouplingFieldDouble* InterpolationMatrix::getSupportVolumes(MEDCouplingMesh * mesh) + { + if(!mesh->isStructured()) + return getSupportUnstructuredVolumes((MEDCouplingUMesh *)mesh); + else + throw INTERP_KERNEL::Exception("Not implemented yet !!!"); + } + + // ==================================================================== + // brief returns the volumes of the cells underlying the field \a field + + // For 2D geometries, the returned field contains the areas. + // For 3D geometries, the returned field contains the volumes. + + // param field field on which cells the volumes are required + // return field containing the volumes + // ==================================================================== + + MEDCouplingFieldDouble* InterpolationMatrix::getSupportUnstructuredVolumes(MEDCouplingUMesh * mesh) + { + int ipt, type ; + int nbelem = mesh->getNumberOfCells() ; + int dim_mesh = mesh->getMeshDimension(); + int dim_space = mesh->getSpaceDimension() ; + double *coords = mesh->getCoords()->getPointer() ; + int *connec = mesh->getNodalConnectivity()->getPointer() ; + int *connec_index = mesh->getNodalConnectivityIndex()->getPointer() ; + + + MEDCouplingFieldDouble* field = MEDCouplingFieldDouble::New(ON_CELLS); + DataArrayDouble* array = DataArrayDouble::New() ; + array->alloc(nbelem, 1) ; + double *area_vol = array->getPointer() ; + + switch (dim_mesh) + { + case 2: // getting the areas + for ( int iel=0 ; iel<nbelem ; iel++ ) + { + ipt = connec_index[iel] ; + type = connec[ipt] ; + + switch ( type ) + { + case INTERP_KERNEL::NORM_TRI3 : + case INTERP_KERNEL::NORM_TRI6 : + { + int N1 = connec[ipt+1]; + int N2 = connec[ipt+2]; + int N3 = connec[ipt+3]; + + area_vol[iel]=INTERP_KERNEL::calculateAreaForTria(coords+(dim_space*N1), + coords+(dim_space*N2), + coords+(dim_space*N3), + dim_space); + } + break ; + + case INTERP_KERNEL::NORM_QUAD4 : + case INTERP_KERNEL::NORM_QUAD8 : + { + int N1 = connec[ipt+1]; + int N2 = connec[ipt+2]; + int N3 = connec[ipt+3]; + int N4 = connec[ipt+4]; + + area_vol[iel]=INTERP_KERNEL::calculateAreaForQuad(coords+dim_space*N1, + coords+dim_space*N2, + coords+dim_space*N3, + coords+dim_space*N4, + dim_space) ; + } + break ; + + case INTERP_KERNEL::NORM_POLYGON : + { + // We must remember that the first item is the type. That's + // why we substract 1 to get the number of nodes of this polygon + int size = connec_index[iel+1] - connec_index[iel] - 1 ; + + double **pts = new double *[size] ; + + for ( int inod=0 ; inod<size ; inod++ ) + { + // Remember the first item is the type + pts[inod] = coords+dim_space*connec[ipt+inod+1] ; + } + + area_vol[iel]=INTERP_KERNEL::calculateAreaForPolyg((const double **)pts, + size,dim_space); + delete [] pts; + } + break ; + + default : + throw INTERP_KERNEL::Exception("Bad Support to get Areas on it !"); + + } // End of switch + + } // End of the loop over the cells + break; + case 3: // getting the volumes + for ( int iel=0 ; iel<nbelem ; iel++ ) + { + ipt = connec_index[iel] ; + type = connec[ipt] ; + + switch ( type ) + { + case INTERP_KERNEL::NORM_TETRA4 : + case INTERP_KERNEL::NORM_TETRA10 : + { + int N1 = connec[ipt+1]; + int N2 = connec[ipt+2]; + int N3 = connec[ipt+3]; + int N4 = connec[ipt+4]; + + area_vol[iel]=INTERP_KERNEL::calculateVolumeForTetra(coords+dim_space*N1, + coords+dim_space*N2, + coords+dim_space*N3, + coords+dim_space*N4) ; + } + break ; + + case INTERP_KERNEL::NORM_PYRA5 : + case INTERP_KERNEL::NORM_PYRA13 : + { + int N1 = connec[ipt+1]; + int N2 = connec[ipt+2]; + int N3 = connec[ipt+3]; + int N4 = connec[ipt+4]; + int N5 = connec[ipt+5]; + + area_vol[iel]=INTERP_KERNEL::calculateVolumeForPyra(coords+dim_space*N1, + coords+dim_space*N2, + coords+dim_space*N3, + coords+dim_space*N4, + coords+dim_space*N5) ; + } + break ; + + case INTERP_KERNEL::NORM_PENTA6 : + case INTERP_KERNEL::NORM_PENTA15 : + { + int N1 = connec[ipt+1]; + int N2 = connec[ipt+2]; + int N3 = connec[ipt+3]; + int N4 = connec[ipt+4]; + int N5 = connec[ipt+5]; + int N6 = connec[ipt+6]; + + area_vol[iel]=INTERP_KERNEL::calculateVolumeForPenta(coords+dim_space*N1, + coords+dim_space*N2, + coords+dim_space*N3, + coords+dim_space*N4, + coords+dim_space*N5, + coords+dim_space*N6) ; + } + break ; + + case INTERP_KERNEL::NORM_HEXA8 : + case INTERP_KERNEL::NORM_HEXA20 : + { + int N1 = connec[ipt+1]; + int N2 = connec[ipt+2]; + int N3 = connec[ipt+3]; + int N4 = connec[ipt+4]; + int N5 = connec[ipt+5]; + int N6 = connec[ipt+6]; + int N7 = connec[ipt+7]; + int N8 = connec[ipt+8]; + + area_vol[iel]=INTERP_KERNEL::calculateVolumeForHexa(coords+dim_space*N1, + coords+dim_space*N2, + coords+dim_space*N3, + coords+dim_space*N4, + coords+dim_space*N5, + coords+dim_space*N6, + coords+dim_space*N7, + coords+dim_space*N8) ; + } + break ; + + case INTERP_KERNEL::NORM_POLYHED : + { + throw INTERP_KERNEL::Exception("Not yet implemented !"); + } + break ; + + default: + throw INTERP_KERNEL::Exception("Bad Support to get Volume on it !"); + } + } + break; + default: + throw INTERP_KERNEL::Exception("interpolation is not available for this dimension"); + } + + field->setArray(array) ; + array->decrRef(); + field->setMesh(mesh) ; + + return field ; + } +} diff --git a/src/ParaMEDMEM/InterpolationMatrix.hxx b/src/ParaMEDMEM/InterpolationMatrix.hxx new file mode 100644 index 000000000..c0c6984a8 --- /dev/null +++ b/src/ParaMEDMEM/InterpolationMatrix.hxx @@ -0,0 +1,66 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERPOLATIONMATRIX_HXX__ +#define __INTERPOLATIONMATRIX_HXX__ + +#include "MPIAccessDEC.hxx" +#include "MxN_Mapping.hxx" +#include "InterpolationOptions.hxx" +#include "DECOptions.hxx" + +namespace ParaMEDMEM +{ + class InterpolationMatrix : public INTERP_KERNEL::InterpolationOptions, + public DECOptions + { + public: + + InterpolationMatrix(ParaMEDMEM::ParaMESH *source_support, + const ProcessorGroup& source_group, + const ProcessorGroup& target_group, + const DECOptions& dec_opt, + const InterpolationOptions& i_opt); + + + virtual ~InterpolationMatrix(); + void addContribution(MEDCouplingUMesh& distant_support, int iproc_distant, + int* distant_elems, const std::string& srcMeth, const std::string& targetMeth); + void multiply(MEDCouplingFieldDouble& field) const; + void transposeMultiply(MEDCouplingFieldDouble& field)const; + void prepare(); + int getNbRows() const {return _row_offsets.size();} + MPIAccessDEC* getAccessDEC(){return _mapping.getAccessDEC();} + + static MEDCouplingFieldDouble *getSupportVolumes(MEDCouplingMesh *field); + static MEDCouplingFieldDouble *getSupportUnstructuredVolumes(MEDCouplingUMesh *field); + private: + std::vector<int> _row_offsets; + std::vector<std::pair<int,int> > _col_offsets; + MEDCouplingUMesh *_source_support; + MxN_Mapping _mapping; + + const ProcessorGroup& _source_group; + const ProcessorGroup& _target_group; + std::vector<double> _target_volume; + std::vector<double> _source_volume; + std::vector<std::vector<std::pair<int,double> > > _coeffs; + }; +} + +#endif diff --git a/src/ParaMEDMEM/IntersectionDEC.cxx b/src/ParaMEDMEM/IntersectionDEC.cxx new file mode 100644 index 000000000..fc209b47e --- /dev/null +++ b/src/ParaMEDMEM/IntersectionDEC.cxx @@ -0,0 +1,276 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <mpi.h> +#include "CommInterface.hxx" +#include "Topology.hxx" +#include "BlockTopology.hxx" +#include "ComponentTopology.hxx" +#include "ParaFIELD.hxx" +#include "MPIProcessorGroup.hxx" +#include "ParaMESH.hxx" +#include "DEC.hxx" +#include "InterpolationMatrix.hxx" +#include "IntersectionDEC.hxx" +#include "ElementLocator.hxx" + + + +namespace ParaMEDMEM +{ + + /*! + \defgroup intersectiondec IntersectionDEC + + \section overview Overview + + The IntersectionDEC enables the \ref conservativeremapping of fields between two parallel codes. This remapping is based on the computation of intersection volumes between elements from code A and elements from code B. The computation is possible for 3D meshes, 2D meshes, and 3D-surface meshes. Dimensions must be similar for code A and code B (for instance, though it could be desirable, it is not yet possible to couple 3D surfaces with 2D surfaces). + + In the present version, only fields lying on elements are considered. + + \image html NonCoincident_small.png "Example showing the transfer from a field based on a quadrangular mesh to a triangular mesh. In a P0-P0 interpolation, to obtain the value on a triangle, the values on quadrangles are weighted by their intersection area and summed." + + \image latex NonCoincident_small.eps "Example showing the transfer from a field based on a quadrangular mesh to a triangular mesh. In a P0-P0 interpolation, to obtain the value on a triangle, the values on quadrangles are weighted by their intersection area and summed." + + A typical use of IntersectionDEC encompasses two distinct phases : + - A setup phase during which the intersection volumes are computed and the communication structures are setup. This corresponds to calling the IntersectionDEC::synchronize() method. + - A use phase during which the remappings are actually performed. This corresponds to the calls to sendData() and recvData() which actually trigger the data exchange. The data exchange are synchronous in the current version of the library so that recvData() and sendData() calls must be synchronized on code A and code B processor groups. + + The following code excerpt illutrates a typical use of the IntersectionDEC class. + + \code + ... + IntersectionDEC dec(groupA, groupB); + dec.attachLocalField(field); + dec.synchronize(); + if (groupA.containsMyRank()) + dec.recvData(); + else if (groupB.containsMyRank()) + dec.sendData(); + ... + \endcode + A \ref conservativeremapping of the field from the source mesh to the target mesh is performed by the function synchronise(), which computes the \ref remappingmatrix. + + Computing the field on the receiving side can be expressed in terms of a matrix-vector product : \f$ \phi_t=W.\phi_s\f$, with \f$ \phi_t \f$ the field on the target side and \f$ \phi_s \f$ the field on the source side. + When remapping a 3D surface to another 3D surface, a projection phase is necessary to match elements from both sides. Care must be taken when defining this projection to obtain a \ref conservative remapping. + + In the P0-P0 case, this matrix is a plain rectangular matrix with coefficients equal to the intersection areas between triangle and quadrangles. For instance, in the above figure, the matrix is : + + \f[ + \begin{tabular}{|cccc|} + 0.72 & 0 & 0.2 & 0 \\ + 0.46 & 0 & 0.51 & 0.03\\ + 0.42 & 0.53 & 0 & 0.05\\ + 0 & 0 & 0.92 & 0.05 \\ + \end{tabular} + \f] + + + + \section intersectiondec_options Options + On top of \ref dec_options, options supported by %IntersectionDEC objects are + related to the underlying Intersector class. + All the options available in the intersector objects are + available for the %IntersectionDEC object. The various options available for * intersectors can be reviewed in \ref InterpKerIntersectors. + + For instance : + \verbatim + IntersectionDEC dec(source_group, target_group); + dec.attachLocalField(field); + dec.setOptions("DoRotate",false); + dec.setOptions("Precision",1e-12); + dec.synchronize(); + \endverbatim + + \warning{ Options must be set before calling the synchronize method. } + */ + + /*! + \addtogroup intersectiondec + @{ + */ + + IntersectionDEC::IntersectionDEC() + { + } + + /*! + This constructor creates an IntersectionDEC which has \a source_group as a working side + and \a target_group as an idle side. All the processors will actually participate, but intersection computations will be performed on the working side during the \a synchronize() phase. + The constructor must be called synchronously on all processors of both processor groups. + + \param source_group working side ProcessorGroup + \param target_group lazy side ProcessorGroup + + */ + IntersectionDEC::IntersectionDEC(ProcessorGroup& source_group, ProcessorGroup& target_group): + DEC(source_group, target_group),_interpolation_matrix(0) + { + + } + + IntersectionDEC::~IntersectionDEC() + { + if (_interpolation_matrix !=0) + delete _interpolation_matrix; + } + + /*! + \brief Synchronization process for exchanging topologies. + + This method prepares all the structures necessary for sending data from a processor group to the other. It uses the mesh underlying the fields that have been set with attachLocalField method. + It works in four steps : + -# Bounding boxes are computed for each subdomain, + -# The lazy side mesh parts that are likely to intersect the working side local processor are sent to the working side, + -# The working side calls the interpolation kernel to compute the intersection between local and imported mesh. + -# The lazy side is updated so that it knows the structure of the data that will be sent by + the working side during a \a sendData() call. + + */ + void IntersectionDEC::synchronize() + { + ParaMEDMEM::ParaMESH* para_mesh = _local_field->getSupport(); + //cout <<"size of Interpolation Matrix"<<sizeof(InterpolationMatrix)<<endl; + _interpolation_matrix = new InterpolationMatrix (para_mesh, *_source_group,*_target_group,*this,*this); + + //setting up the communication DEC on both sides + if (_source_group->containsMyRank()) + { + //locate the distant meshes + ElementLocator locator(*para_mesh, *_target_group); + + //transfering option from IntersectionDEC to ElementLocator + locator.setBoundingBoxAdjustment(getBoundingBoxAdjustment()); + + MEDCouplingUMesh* distant_mesh=0; + int* distant_ids=0; + for (int i=0; i<_target_group->size(); i++) + { + // int idistant_proc = (i+_source_group->myRank())%_target_group->size(); + int idistant_proc=i; + + //gathers pieces of the target meshes that can intersect the local mesh + locator.exchangeMesh(idistant_proc,distant_mesh,distant_ids); + std::string distantMeth; + locator.exchangeMethod(_method,idistant_proc,distantMeth); + if (distant_mesh !=0) + { + //adds the contribution of the distant mesh on the local one + int idistant_proc_in_union=_union_group->translateRank(_target_group,idistant_proc); + std::cout <<"add contribution from proc "<<idistant_proc_in_union<<" to proc "<<_union_group->myRank()<<std::endl; + _interpolation_matrix->addContribution(*distant_mesh,idistant_proc_in_union,distant_ids,_method,distantMeth); + + distant_mesh->decrRef(); + delete[] distant_ids; + distant_mesh=0; + distant_ids=0; + } + } + } + + if (_target_group->containsMyRank()) + { + ElementLocator locator(*para_mesh, *_source_group); + //transfering option from IntersectionDEC to ElementLocator + locator.setBoundingBoxAdjustment(getBoundingBoxAdjustment()); + + MEDCouplingUMesh* distant_mesh=0; + int* distant_ids=0; + for (int i=0; i<_source_group->size(); i++) + { + // int idistant_proc = (i+_target_group->myRank())%_source_group->size(); + int idistant_proc=i; + //gathers pieces of the target meshes that can intersect the local mesh + locator.exchangeMesh(idistant_proc,distant_mesh,distant_ids); + std::cout << " Data sent from "<<_union_group->myRank()<<" to source proc "<< idistant_proc<<std::endl; + std::string distantMeth; + locator.exchangeMethod(_method,idistant_proc,distantMeth); + if (distant_mesh!=0) + { + distant_mesh->decrRef(); + delete[] distant_ids; + distant_mesh=0; + distant_ids=0; + } + } + } + _interpolation_matrix->prepare(); + } + + + /*! + Receives the data whether the processor is on the working side or on the lazy side. It must match a \a sendData() call on the other side. + */ + void IntersectionDEC::recvData() + { + if (_source_group->containsMyRank()) + _interpolation_matrix->transposeMultiply(*_local_field->getField()); + else if (_target_group->containsMyRank()) + { + _interpolation_matrix->multiply(*_local_field->getField()); + if (getForcedRenormalization()) + renormalizeTargetField(); + } + } + + + /*! + Receives the data at time \a time in asynchronous mode. The value of the field + will be time-interpolated from the field values received. + \param time time at which the value is desired + */ + void IntersectionDEC::recvData( double time ) + { + _interpolation_matrix->getAccessDEC()->setTime(time); + recvData() ; + } + + /*! + Sends the data whether the processor is on the working side or on the lazy side. + It must match a recvData() call on the other side. + */ + void IntersectionDEC::sendData() + { + if (_source_group->containsMyRank()) + { + + _interpolation_matrix->multiply(*_local_field->getField()); + if (getForcedRenormalization()) + renormalizeTargetField(); + + } + else if (_target_group->containsMyRank()) + _interpolation_matrix->transposeMultiply(*_local_field->getField()); + } + + /*! + Sends the data available at time \a time in asynchronous mode. + \param time time at which the value is available + \param deltatime time interval between the value presently sent and the next one. + */ + void IntersectionDEC::sendData( double time , double deltatime ) + { + _interpolation_matrix->getAccessDEC()->setTime(time,deltatime); + sendData() ; + } + + /*! + @} + */ + +} diff --git a/src/ParaMEDMEM/IntersectionDEC.hxx b/src/ParaMEDMEM/IntersectionDEC.hxx new file mode 100644 index 000000000..6659155c8 --- /dev/null +++ b/src/ParaMEDMEM/IntersectionDEC.hxx @@ -0,0 +1,54 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __INTERSECTIONDEC_HXX__ +#define __INTERSECTIONDEC_HXX__ + +#include "DEC.hxx" +#include "MxN_Mapping.hxx" +#include "InterpolationOptions.hxx" + +namespace ParaMEDMEM +{ + class InterpolationMatrix; + + class IntersectionDEC : public DEC, public INTERP_KERNEL::InterpolationOptions + { + public: + IntersectionDEC(); + IntersectionDEC(ProcessorGroup& source_group, ProcessorGroup& target_group); + virtual ~IntersectionDEC(); + void synchronize(); + void recvData(); + void recvData(double time); + void sendData(); + void sendData(double time , double deltatime); + void prepareSourceDE() { } + void prepareTargetDE() { } + private : + //Number of distant points to be located locally + int _nb_distant_points; + //coordinates of distant points + const double* _distant_coords; + //local element number containing the distant points + const int* _distant_locations; + InterpolationMatrix* _interpolation_matrix; + }; +} + +#endif diff --git a/src/ParaMEDMEM/LinearTimeInterpolator.cxx b/src/ParaMEDMEM/LinearTimeInterpolator.cxx new file mode 100644 index 000000000..24f5c9ea5 --- /dev/null +++ b/src/ParaMEDMEM/LinearTimeInterpolator.cxx @@ -0,0 +1,54 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// + +#include "LinearTimeInterpolator.hxx" + +using namespace std; + +namespace ParaMEDMEM +{ + + LinearTimeInterpolator::LinearTimeInterpolator( double InterpPrecision, int nStepBefore, + int nStepAfter ): + TimeInterpolator( InterpPrecision, nStepBefore, nStepAfter ) + { + } + + LinearTimeInterpolator::~LinearTimeInterpolator() + { + } + + void LinearTimeInterpolator::doInterp( double time0, double time1, double time, + int recvcount , int nbuff0, int nbuff1, + int **recvbuff0, int **recvbuff1, int *result ) + { + for(int i = 0 ; i < recvcount ; i++ ) + result[i] = (int) ((recvbuff0[0][i]*(time1 - time) + recvbuff1[0][i]*(time - time0))/(time1 - time0) + _interp_precision); + } + + void LinearTimeInterpolator::doInterp( double time0, double time1, double time, + int recvcount , int nbuff0, int nbuff1, + double **recvbuff0, double **recvbuff1, + double *result ) + { + for(int i = 0 ; i < recvcount ; i++ ) + result[i] = (recvbuff0[0][i]*(time1 - time) + recvbuff1[0][i]*(time - time0))/(time1 - time0); + } + +} diff --git a/src/ParaMEDMEM/LinearTimeInterpolator.hxx b/src/ParaMEDMEM/LinearTimeInterpolator.hxx new file mode 100644 index 000000000..7bfbafd4b --- /dev/null +++ b/src/ParaMEDMEM/LinearTimeInterpolator.hxx @@ -0,0 +1,46 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __LINEARTIMEINTERPOLATOR_HXX__ +#define __LINEARTIMEINTERPOLATOR_HXX__ + +#include "TimeInterpolator.hxx" + +#include <map> +#include <iostream> + +namespace ParaMEDMEM +{ + class DEC; + + class LinearTimeInterpolator : public TimeInterpolator + { + public: + LinearTimeInterpolator( double InterpPrecision=0, int nStepBefore=1, + int nStepAfter=1 ) ; + virtual ~LinearTimeInterpolator(); + void doInterp( double time0, double time1, double time, int recvcount, + int nbuff0, int nbuff1, + int **recvbuff0, int **recvbuff1, int *result ); + void doInterp( double time0, double time1, double time, int recvcount, + int nbuff0, int nbuff1, + double **recvbuff0, double **recvbuff1, double *result ); + }; +} + +#endif diff --git a/src/ParaMEDMEM/MEDLoader/MEDLoader.cxx b/src/ParaMEDMEM/MEDLoader/MEDLoader.cxx new file mode 100644 index 000000000..bc5f3d5f3 --- /dev/null +++ b/src/ParaMEDMEM/MEDLoader/MEDLoader.cxx @@ -0,0 +1,417 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "MEDLoader.hxx" +#include "CellModel.hxx" +#include "ParaMESH.hxx" +#include "BlockTopology.hxx" +#include "MEDCouplingUMesh.hxx" + +extern "C" +{ +#include "med.h" +} + +#include <string> +#include <cstring> +#include <sstream> +#include <fstream> + +med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE] = { MED_POINT1, + MED_SEG2, + MED_SEG3, + MED_TRIA3, + MED_TRIA6, + MED_QUAD4, + MED_QUAD8, + MED_TETRA4, + MED_TETRA10, + MED_HEXA8, + MED_HEXA20, + MED_PENTA6, + MED_PENTA15, + MED_PYRA5, + MED_PYRA13 }; + +INTERP_KERNEL::NormalizedCellType typmai2[MED_NBR_GEOMETRIE_MAILLE] = { INTERP_KERNEL::NORM_ERROR, + INTERP_KERNEL::NORM_SEG2, + INTERP_KERNEL::NORM_SEG3, + INTERP_KERNEL::NORM_TRI3, + INTERP_KERNEL::NORM_QUAD4, + INTERP_KERNEL::NORM_QUAD8, + INTERP_KERNEL::NORM_TETRA4, + INTERP_KERNEL::NORM_TETRA10, + INTERP_KERNEL::NORM_HEXA8, + INTERP_KERNEL::NORM_HEXA20, + INTERP_KERNEL::NORM_PENTA6, + INTERP_KERNEL::NORM_PENTA15, + INTERP_KERNEL::NORM_PYRA5, + INTERP_KERNEL::NORM_PYRA13 }; + +using namespace ParaMEDMEM; + +const char WHITE_SPACES[]=" \n"; + +MEDLoader::MEDConnOfOneElemType::MEDConnOfOneElemType(INTERP_KERNEL::NormalizedCellType type, int *conn, int lgth):_lgth(lgth), + _conn(conn),_global(0), + _type(type) +{ +} + +void MEDLoader::MEDConnOfOneElemType::setGlobal(int *global) +{ + if(_global!=global) + { + if(_global) + delete [] _global; + _global=global; + } +} + +void MEDLoader::MEDConnOfOneElemType::releaseArray() +{ + delete [] _conn; + delete [] _global; +} + +std::string buildStringFromFortran(const char *expr, int lgth) +{ + std::string ret(expr,lgth); + std::string whiteSpaces(WHITE_SPACES); + std::size_t lgthReal=strlen(ret.c_str()); + std::string ret2=ret.substr(0,lgthReal); + std::size_t found=ret2.find_last_not_of(whiteSpaces); + if (found!=std::string::npos) + ret2.erase(found+1); + else + ret2.clear();//ret is all whitespace + return ret2; +} + +namespace MEDLoader +{ + med_int getIdFromMeshName(med_idt fid, const char *meshName) throw(INTERP_KERNEL::Exception) + { + if(meshName==0) + return 1; + med_int n=MEDnMaa(fid); + if(n==0) + throw INTERP_KERNEL::Exception("No mesh in file."); + med_maillage type_maillage; + char maillage_description[MED_TAILLE_DESC+1]; + med_int dim; + char nommaa[MED_TAILLE_NOM+1]; + std::ostringstream os; + for(med_int i=1;i<=n;i++) + { + MEDmaaInfo(fid,i,nommaa,&dim,&type_maillage,maillage_description); + std::string cur=buildStringFromFortran(nommaa,sizeof(nommaa)); + if(cur==meshName) + return i; + os << "\'" << cur.c_str() << "\' "; + } + std::ostringstream os2; + os2 << "MeshName '" << meshName << "' not in file : meshes available : " << os.str(); + throw INTERP_KERNEL::Exception(os2.str().c_str()); + } + + void readUMeshDataInMedFile(med_idt fid, med_int meshId, double *&coords, int& nCoords, int& spaceDim, std::list<MEDLoader::MEDConnOfOneElemType>& conn) + { + char nommaa[MED_TAILLE_NOM+1]; + char maillage_description[MED_TAILLE_DESC+1]; + char comp[3*MED_TAILLE_PNOM+1]; + char unit[3*MED_TAILLE_PNOM+1]; + med_maillage type_maillage; + med_int Mdim; + MEDmaaInfo(fid,meshId,nommaa,&Mdim,&type_maillage,maillage_description); + spaceDim=(int)Mdim; + nCoords=MEDnEntMaa(fid,nommaa,MED_COOR,MED_NOEUD,(med_geometrie_element)0,(med_connectivite)0); + coords=new double[nCoords*spaceDim]; + med_repere repere; + MEDcoordLire(fid,nommaa,Mdim,coords,MED_FULL_INTERLACE,MED_ALL,NULL,0,&repere,comp,unit); + med_booleen inoele, inuele; + for(int i=0;i<MED_NBR_GEOMETRIE_MAILLE;i++) + { + med_geometrie_element curMedType=typmai[i]; + med_entite_maillage whichEntity; + int curNbOfElemM=MEDnEntMaa(fid,nommaa,MED_CONN,MED_MAILLE,curMedType,MED_NOD); + int curNbOfElemF=MEDnEntMaa(fid,nommaa,MED_CONN,MED_FACE,curMedType,MED_NOD); + int curNbOfElem; + if(curNbOfElemF>curNbOfElemM) + { + curNbOfElem=curNbOfElemF; + whichEntity=MED_FACE; + } + else + { + curNbOfElem=curNbOfElemM; + whichEntity=MED_MAILLE; + } + if(curNbOfElem>0) + { + int *connTab=new int[(curMedType%100)*curNbOfElem]; + MEDLoader::MEDConnOfOneElemType elem(typmai2[i],connTab,curNbOfElem); + int *tmp=new int[curNbOfElem]; + int *fam=new int[curNbOfElem]; + char *noms=new char[MED_TAILLE_PNOM*curNbOfElem+1]; + MEDelementsLire(fid,nommaa,Mdim,connTab,MED_FULL_INTERLACE,noms,&inoele,tmp,&inuele,fam,curNbOfElem,whichEntity,curMedType,MED_NOD); + delete [] tmp; + delete [] fam; + delete [] noms; + //trying to read global numbering + int *globArr=new int[curNbOfElem]; + if(MEDglobalNumLire(fid,nommaa,globArr,curNbOfElem,whichEntity,curMedType)==0) + elem.setGlobal(globArr); + else + delete [] globArr; + conn.push_back(elem); + } + } + } +} + +unsigned MEDLoader::calculateHighestMeshDim(const std::list<MEDLoader::MEDConnOfOneElemType>& conn) +{ + unsigned ret=0; + for(std::list<MEDLoader::MEDConnOfOneElemType>::const_iterator iter=conn.begin();iter!=conn.end();iter++) + { + unsigned curDim=INTERP_KERNEL::CellModel::getCellModel((*iter).getType()).getDimension(); + if(ret<curDim) + ret=curDim; + } + return ret; +} + +void MEDLoader::keepSpecifiedMeshDim(std::list<MEDLoader::MEDConnOfOneElemType>& conn, unsigned meshDim) +{ + for(std::list<MEDLoader::MEDConnOfOneElemType>::iterator iter=conn.begin();iter!=conn.end();) + { + unsigned curDim=INTERP_KERNEL::CellModel::getCellModel((*iter).getType()).getDimension(); + if(curDim!=meshDim) + { + (*iter).releaseArray(); + iter=conn.erase(iter); + } + else + iter++; + } +} + +void MEDLoader::tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list<MEDLoader::MEDConnOfOneElemType>& medConnFrmt, + DataArrayInt* &conn, + DataArrayInt* &connIndex) +{ + if(medConnFrmt.empty()) + { + conn=0; + connIndex=0; + return ; + } + std::list<MEDLoader::MEDConnOfOneElemType>::const_iterator iter=medConnFrmt.begin(); + int totalNbOfCells=0; + int totalNbOfMedConn=0; + for(;iter!=medConnFrmt.end();iter++) + { + const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::getCellModel((*iter).getType()); + totalNbOfCells+=(*iter).getLength(); + if(!cellMod.isDynamic()) + totalNbOfMedConn+=(*iter).getLength()*cellMod.getNumberOfNodes(); + else + throw INTERP_KERNEL::Exception("Polyg/polh not implemented yet !"); + } + connIndex=DataArrayInt::New(); + conn=DataArrayInt::New(); + connIndex->alloc(totalNbOfCells+1,1); + int *connIdxPtr=connIndex->getPointer(); + int connFillId=0; + conn->alloc(totalNbOfMedConn+totalNbOfCells,1); + int *connPtr=conn->getPointer(); + for(iter=medConnFrmt.begin();iter!=medConnFrmt.end();iter++) + { + INTERP_KERNEL::NormalizedCellType type=(*iter).getType(); + int *sourceConn=(*iter).getArray(); + const INTERP_KERNEL::CellModel& cellMod=INTERP_KERNEL::CellModel::getCellModel(type); + int nbOfCellsInCurType; + int nbOfNodesIn1Cell=cellMod.getNumberOfNodes(); + if(!cellMod.isDynamic()) + nbOfCellsInCurType=(*iter).getLength(); + else + throw INTERP_KERNEL::Exception("Polyg/polh not implemented yet !"); + if(!cellMod.isDynamic()) + { + for(int i=0;i<nbOfCellsInCurType;i++,connIdxPtr++) + { + *connIdxPtr=connFillId; + *connPtr++=type; + connPtr=std::transform(sourceConn,sourceConn+nbOfNodesIn1Cell,connPtr,std::bind2nd(std::minus<int>(),1)); + connFillId+=nbOfNodesIn1Cell+1; + sourceConn+=nbOfNodesIn1Cell; + } + *connIdxPtr=connFillId; + } + } +} + +void MEDLoader::releaseMEDFileCoreFrmt(std::list<MEDLoader::MEDConnOfOneElemType>& medConnFrmt) +{ + for(std::list<MEDLoader::MEDConnOfOneElemType>::iterator iter=medConnFrmt.begin();iter!=medConnFrmt.end();iter++) + (*iter).releaseArray(); + medConnFrmt.clear(); +} + +/*! + * This method builds a sub set of connectivity for a given type 'type'. + * @param conn input containing connectivity with MEDCoupling format. + * @param connIndex input containing connectivity index in MEDCoupling format. + * @param type input specifying which cell types will be extracted in conn4MEDFile. + * @param conn4MEDFile output containing the connectivity directly understandable by MEDFile; conn4MEDFile has to be empty before this method called. + * @return nb of elements extracted. + */ +int MEDLoader::buildMEDSubConnectivityOfOneType(DataArrayInt *conn, DataArrayInt *connIndex, INTERP_KERNEL::NormalizedCellType type, std::vector<int>& conn4MEDFile) +{ + int ret=0; + int nbOfElem=connIndex->getNbOfElems()-1; + const int *connPtr=conn->getPointer(); + const int *connIdxPtr=connIndex->getPointer(); + for(int i=0;i<nbOfElem;i++) + { + int delta=connIdxPtr[1]-connIdxPtr[0]; + if(*connPtr==type) + { + conn4MEDFile.insert(conn4MEDFile.end(),connPtr+1,connPtr+delta); + ret++; + } + connIdxPtr++; + connPtr+=delta; + } + std::transform(conn4MEDFile.begin(),conn4MEDFile.end(),conn4MEDFile.begin(),std::bind2nd(std::plus<int>(),1)); + return ret; +} + +MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const char *fileName, const char *meshName, int meshDimRelToMax) throw(INTERP_KERNEL::Exception) +{ + //Extraction data from MED file. + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + med_int mid=getIdFromMeshName(fid,meshName); + unsigned meshDimExtract; + double *coords; + int nCoords; + int spaceDim; + std::list<MEDLoader::MEDConnOfOneElemType> conn; + readUMeshDataInMedFile(fid,mid,coords,nCoords,spaceDim,conn); + meshDimExtract=calculateHighestMeshDim(conn); + meshDimExtract=meshDimExtract+meshDimRelToMax; + keepSpecifiedMeshDim(conn,meshDimExtract); + MEDfermer(fid); + //Put data in returned data structure. + MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); + ret->setName(meshName); + ret->setMeshDimension(meshDimExtract); + // + DataArrayDouble *coordsArr=DataArrayDouble::New(); + coordsArr->useArray(coords,true,ParaMEDMEM::CPP_DEALLOC,nCoords,spaceDim); + ret->setCoords(coordsArr); + coordsArr->decrRef(); + // + DataArrayInt *connArr,*connIndexArr; + tradMEDFileCoreFrmt2MEDCouplingUMesh(conn,connArr,connIndexArr); + ret->setConnectivity(connArr,connIndexArr); + //clean-up + if(connArr) + connArr->decrRef(); + if(connIndexArr) + connIndexArr->decrRef(); + releaseMEDFileCoreFrmt(conn); + return ret; +} + +void MEDLoader::writeUMesh(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh) +{ + med_idt fid=MEDouvrir((char *)fileName,MED_CREATION); + char maa[MED_TAILLE_NOM+1]; + std::fill(maa,maa+MED_TAILLE_NOM+1,'\0'); + const char *meshName=mesh->getName(); + strcpy(maa,meshName); + MEDmaaCr(fid,maa,mesh->getMeshDimension(),MED_NON_STRUCTURE,maa); + std::set<INTERP_KERNEL::NormalizedCellType> allTypes(mesh->getAllTypes()); + DataArrayInt *conn=mesh->getNodalConnectivity(); + DataArrayInt *connIndex=mesh->getNodalConnectivityIndex(); + char familyName[MED_TAILLE_NOM+1]; + std::fill(familyName,familyName+MED_TAILLE_NOM+1,'\0'); + const char DftFamilyName[]="DftFamily"; + std::copy(DftFamilyName,DftFamilyName+sizeof(DftFamilyName),familyName); + for(int i=0;i<MED_NBR_GEOMETRIE_MAILLE;i++) + { + med_geometrie_element curMedType=typmai[i]; + INTERP_KERNEL::NormalizedCellType curType=typmai2[i]; + if(allTypes.find(curType)!=allTypes.end()) + { + std::vector<int> medConn; + int nbOfElt=buildMEDSubConnectivityOfOneType(conn,connIndex,curType,medConn); + MEDconnEcr(fid,maa,mesh->getMeshDimension(),&medConn[0],MED_FULL_INTERLACE,nbOfElt,MED_MAILLE,curMedType,MED_NOD); + } + } + MEDfamCr(fid,maa,familyName,0,0,0,0,0,0,0); + DataArrayDouble *arr=mesh->getCoords(); + char comp[2*MED_TAILLE_PNOM+1]; + char unit[2*MED_TAILLE_PNOM+1]; + std::fill(comp,comp+2*MED_TAILLE_PNOM,' '); + comp[2*MED_TAILLE_PNOM]='\0'; + char *work=comp; + for(int i=0;i<mesh->getSpaceDimension();i++,work+=3) + *work='X'+i; + std::fill(unit,unit+2*MED_TAILLE_PNOM+1,'\0'); + MEDcoordEcr(fid,maa,mesh->getSpaceDimension(),arr->getPointer(),MED_FULL_INTERLACE,mesh->getNumberOfNodes(),MED_CART,comp,unit); + MEDfermer(fid); +} + +/*! + * This method builds the master file 'fileName' of a parallel MED file defined in 'fileNames'. + */ +void MEDLoader::writeMasterFile(const char *fileName, const std::vector<std::string>& fileNames, const char *meshName) +{ + int nbOfDom=fileNames.size(); + std::ofstream fs(fileName); + fs << "#MED Fichier V 2.3" << " " << std::endl; + fs << "#"<<" " << std::endl; + fs << nbOfDom <<" " << std::endl; + for(int i=0;i<nbOfDom;i++) + fs << meshName << " " << i+1 << " " << meshName << "_" << i+1 << " localhost " << fileNames[i] << " " << std::endl; +} + +void MEDLoader::writeParaMesh(const char *fileName, ParaMEDMEM::ParaMESH *mesh) +{ + if(!mesh->getBlockTopology()->getProcGroup()->containsMyRank()) + return ; + int myRank=mesh->getBlockTopology()->getProcGroup()->myRank(); + int nbDomains=mesh->getBlockTopology()->getProcGroup()->size(); + std::vector<std::string> fileNames(nbDomains); + for(int i=0;i<nbDomains;i++) + { + std::ostringstream sstr; + sstr << fileName << i+1 << ".med"; + fileNames[i]=sstr.str(); + } + if(myRank==0) + writeMasterFile(fileName,fileNames,mesh->getCellMesh()->getName()); + writeUMesh(fileNames[myRank].c_str(),mesh->getCellMesh()); +} + +void MEDLoader::writeParaField(const char *fileName, const char *meshName, ParaMEDMEM::ParaFIELD *f) +{ +} diff --git a/src/ParaMEDMEM/MEDLoader/MEDLoader.hxx b/src/ParaMEDMEM/MEDLoader/MEDLoader.hxx new file mode 100644 index 000000000..b5f7065da --- /dev/null +++ b/src/ParaMEDMEM/MEDLoader/MEDLoader.hxx @@ -0,0 +1,69 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __MEDLOADER_HXX__ +#define __MEDLOADER_HXX__ + +#include "InterpKernelException.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +#include <list> +#include <vector> + +namespace ParaMEDMEM +{ + class ParaMESH; + class ParaFIELD; + class DataArrayInt; + class MEDCouplingUMesh; +} + +namespace MEDLoader +{ + class MEDConnOfOneElemType + { + public: + MEDConnOfOneElemType(INTERP_KERNEL::NormalizedCellType type, int *conn, int lgth); + INTERP_KERNEL::NormalizedCellType getType() const { return _type; } + int getLength() const { return _lgth; } + int *getArray() const { return _conn; } + void setGlobal(int *global); + void releaseArray(); + private: + int _lgth; + int *_conn; + int *_global; + INTERP_KERNEL::NormalizedCellType _type; + }; + unsigned calculateHighestMeshDim(const std::list<MEDConnOfOneElemType>& conn); + void keepSpecifiedMeshDim(std::list<MEDConnOfOneElemType>& conn, unsigned meshDim); + void tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list<MEDConnOfOneElemType>& medConnFrmt, + ParaMEDMEM::DataArrayInt* &conn, + ParaMEDMEM::DataArrayInt* &connIndex); + void releaseMEDFileCoreFrmt(std::list<MEDLoader::MEDConnOfOneElemType>& medConnFrmt); + void writeMasterFile(const char *fileName, const std::vector<std::string>& fileNames, const char *meshName); + int buildMEDSubConnectivityOfOneType(ParaMEDMEM::DataArrayInt *conn, ParaMEDMEM::DataArrayInt *connIndex, + INTERP_KERNEL::NormalizedCellType type, std::vector<int>& conn4MEDFile); + // + ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const char *fileName, const char *meshName=0, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); + void writeUMesh(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh); + void writeParaMesh(const char *fileName, ParaMEDMEM::ParaMESH *mesh); + void writeParaField(const char *fileName, const char *meshName, ParaMEDMEM::ParaFIELD *f); +} + +#endif diff --git a/src/ParaMEDMEM/MEDLoader/Makefile.am b/src/ParaMEDMEM/MEDLoader/Makefile.am new file mode 100755 index 000000000..372249430 --- /dev/null +++ b/src/ParaMEDMEM/MEDLoader/Makefile.am @@ -0,0 +1,39 @@ +# Copyright (C) 2007-2008 CEA/DEN, 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. +# +# 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 +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +lib_LTLIBRARIES= libparamedmemmedloader.la + +salomeinclude_HEADERS= \ +MEDLoader.hxx + +dist_libparamedmemmedloader_la_SOURCES= \ +MEDLoader.cxx + +#libmedmem_la_LDFLAGS= -L$(top_builddir)/lib@LIB_LOCATION_SUFFIX@/salome +libparamedmemmedloader_la_CPPFLAGS= $(MPI_INCLUDES) $(MED2_INCLUDES) $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ \ + -I$(srcdir)/../../INTERP_KERNEL \ + -I$(srcdir)/../../INTERP_KERNEL/Geometric2D \ + -I$(srcdir)/../../INTERP_KERNEL/Bases \ + -I$(srcdir)/../../MEDCoupling \ + -I$(srcdir)/../ + +# change motivated by the bug KERNEL4778. +libparamedmemmedloader_la_LDFLAGS= ../../MEDCoupling/libmedcoupling.la \ +../../INTERP_KERNEL/libinterpkernel.la $(MPI_LIBS) $(MED2_LIBS) $(HDF5_LIBS) diff --git a/src/ParaMEDMEM/MPIAccess.cxx b/src/ParaMEDMEM/MPIAccess.cxx new file mode 100644 index 000000000..9c33dc352 --- /dev/null +++ b/src/ParaMEDMEM/MPIAccess.cxx @@ -0,0 +1,1070 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "MPIAccess.hxx" +#include "InterpolationUtils.hxx" + +#include <iostream> + +using namespace std; + +namespace ParaMEDMEM +{ + /*! \defgroup mpi_access MPIAccess + Class \a MPIAccess is the gateway to the MPI library. + It is a helper class that gathers the calls to the MPI + library that are made in the ParaMEDMEM library. This gathering + allows easier gathering of information about the communication + in the library. With MPIAccess, tags are managed automatically + and asynchronous operations are easier. + + It is typically called after the MPI_Init() call in a program. It is afterwards passed as a parameter to the constructors of ParaMEDMEM objects so that they access the MPI library via the MPIAccess. + + As an example, the following code initializes a processor group made of the zero processor. + + \verbatim + #include "MPIAccess.hxx" + #include "ProcessorGroup.hxx" + + int main(int argc, char** argv) + { + //initialization + MPI_Init(&argc, &argv); + ParaMEDMEM::CommInterface comm_interface; + + //setting up a processor group with proc 0 + set<int> procs; + procs.insert(0); + ParaMEDMEM::ProcessorGroup group(procs, comm_interface); + + ParaMEDMEM::MPIAccess mpi_access(group); + + //cleanup + MPI_Finalize(); + } + \endverbatim + */ + + + /*! Creates a MPIAccess that is based on the processors included in \a ProcessorGroup. + This class may be called for easier use of MPI API. + + \param ProcessorGroup MPIProcessorGroup object giving access to group management + \param BaseTag and MaxTag define the range of tags to be used. + Tags are managed by MPIAccess. They are cyclically incremented. + When there is a Send or a Receive operation there is a new RequestId tag returned + to the caller. That RequestId may be used to manage the operation Wait, Check of + status etc... The MPITag internally managed by MPIAccess is used as "tag" argument + in MPI call. + */ + + MPIAccess::MPIAccess(MPIProcessorGroup * ProcessorGroup, int BaseTag, int MaxTag) : + _comm_interface( ProcessorGroup->getCommInterface() ) , + _intra_communicator( ProcessorGroup->getComm() ) + { + int mpitagub ; + int flag ; + //MPI_Attr_get does not run with _IntraCommunicator ??? + //MPI_Attr_get(*_IntraCommunicator,MPI_TAG_UB,&mpitagub,&flag) ; + MPI_Attr_get(MPI_COMM_WORLD,MPI_TAG_UB,&mpitagub,&flag) ; + mpitagub=abs(mpitagub); + if ( BaseTag != 0 ) + BaseTag = (BaseTag/MODULO_TAG)*MODULO_TAG ; + if ( MaxTag == 0 ) + MaxTag = (mpitagub/MODULO_TAG-1)*MODULO_TAG ; + MPI_Comm_rank( *_intra_communicator, &_my_rank ) ; + cout << "MPIAccess::MPIAccess" << _my_rank << " this " << this << " BaseTag " << BaseTag + << " MaxTag " << MaxTag << " mpitagub " << mpitagub << " (minimum 32767) " + << " flag " << flag << endl ; + if ( !flag | (BaseTag < 0) | (BaseTag >= MaxTag) | (MaxTag > mpitagub) ) + throw INTERP_KERNEL::Exception("wrong call to MPIAccess constructor"); + + _processor_group = ProcessorGroup ; + _processor_group_size = _processor_group->size() ; + _trace = false ; + + cout << "MPIAccess::MPIAccess" << _my_rank << " _processor_group_size " + << _processor_group_size << endl ; + + _base_request = -1 ; + _max_request = std::numeric_limits<int>::max() ; + _request = _base_request ; + + _base_MPI_tag = BaseTag ; + _max_MPI_tag = MaxTag ; + + _send_request = new int[ _processor_group_size ] ; + _recv_request = new int[ _processor_group_size ] ; + + _send_requests.resize( _processor_group_size ) ; + _recv_requests.resize( _processor_group_size ) ; + + _send_MPI_tag = new int[ _processor_group_size ] ; + _recv_MPI_Tag = new int[ _processor_group_size ] ; + int i ; + for (i = 0 ; i < _processor_group_size ; i++ ) + { + _send_request[ i ] = _max_request ; + _recv_request[ i ] = _max_request ; + _send_requests[ i ].resize(0) ; + _recv_requests[ i ].resize(0) ; + _send_MPI_tag[ i ] = _max_MPI_tag ; + _recv_MPI_Tag[ i ] = _max_MPI_tag ; + } + MPI_Datatype array_of_types[3] ; + array_of_types[0] = MPI_DOUBLE ; + array_of_types[1] = MPI_DOUBLE ; + array_of_types[2] = MPI_INT ; + int array_of_blocklengths[3] ; + array_of_blocklengths[0] = 1 ; + array_of_blocklengths[1] = 1 ; + array_of_blocklengths[2] = 1 ; + MPI_Aint array_of_displacements[3] ; + array_of_displacements[0] = 0 ; + array_of_displacements[1] = sizeof(double) ; + array_of_displacements[2] = 2*sizeof(double) ; + MPI_Type_struct(3, array_of_blocklengths, array_of_displacements, + array_of_types, &_MPI_TIME) ; + MPI_Type_commit(&_MPI_TIME) ; + } + + MPIAccess::~MPIAccess() + { + cout << "MPIAccess::~MPIAccess" << _my_rank << " this " << this << endl ; + delete [] _send_request ; + delete [] _recv_request ; + delete [] _send_MPI_tag ; + delete [] _recv_MPI_Tag ; + MPI_Type_free(&_MPI_TIME) ; + cout << "End of MPIAccess::~MPIAccess" << _my_rank << " this " << this << endl ; + } + + /* + MPIAccess and "RequestIds" : + ============================ + + . WARNING : In the specification document, the distinction + between "MPITags" and "RequestIds" is not clear. "MPITags" + are arguments of calls to MPI. "RequestIds" does not concern + calls to MPI. "RequestIds" are named "tag"as arguments in/out + in the MPIAccess API in the specification documentation. + But in the implementation we have the right name RequestId (or + RecvRequestId/SendRequestId). + + . When we have a MPI write/read request via MPIAccess, we get + an identifier "RequestId". + That identifier matches a structure RequestStruct of + MPIAccess. The access to that structure is done with the map + "_MapOfRequestStruct". + That structure RequestStruct give the possibility to manage + the structures MPI_Request and MPI_Status * of MPI. It give + also the possibility to get informations about that request : + target, send/recv, tag, [a]synchronous, type, outcount. + + . That identifier is used to control an asynchronous request + via MPIAccess : Wait, Test, Probe, etc... + + . In practise "RequestId" is simply an integer fo the interval + [0 , 2**32-1]. There is only one such a cyclic for + [I]Sends and [I]Recvs. + + . That "RequestIds" and their associated structures give an easy + way to manage asynchronous communications. + For example we have mpi_access->Wait( int RequestId ) instead of + MPI_Wait(MPI_Request *request, MPI_Status *status). + + . The API of MPIAccess may give the "SendRequestIds" of a "target", + the "RecvRequestIds" from a "source" or the "SendRequestIds" of + all "targets" or the "RecvRequestIds" of all "sources". + That avoid to manage them in Presentation-ParaMEDMEM. + */ + + int MPIAccess::newRequest( MPI_Datatype datatype, int tag , int destsourcerank , + bool fromsourcerank , bool asynchronous ) + { + RequestStruct *mpiaccessstruct = new RequestStruct; + mpiaccessstruct->MPITag = tag ; + mpiaccessstruct->MPIDatatype = datatype ; + mpiaccessstruct->MPITarget = destsourcerank ; + mpiaccessstruct->MPIIsRecv = fromsourcerank ; + MPI_Status *aStatus = new MPI_Status ; + mpiaccessstruct->MPIStatus = aStatus ; + mpiaccessstruct->MPIAsynchronous = asynchronous ; + mpiaccessstruct->MPICompleted = !asynchronous ; + mpiaccessstruct->MPIOutCount = -1 ; + if ( !asynchronous ) + { + mpiaccessstruct->MPIRequest = MPI_REQUEST_NULL ; + mpiaccessstruct->MPIStatus->MPI_SOURCE = destsourcerank ; + mpiaccessstruct->MPIStatus->MPI_TAG = tag ; + mpiaccessstruct->MPIStatus->MPI_ERROR = MPI_SUCCESS ; + } + if ( _request == _max_request ) + _request = _base_request ; + _request += 1 ; + _map_of_request_struct[_request] = mpiaccessstruct ; + if ( fromsourcerank ) + _recv_request[ destsourcerank ] = _request; + else + _send_request[ destsourcerank ] = _request; + if ( _trace ) + cout << "NewRequest" << _my_rank << "( " << _request << " ) " + << mpiaccessstruct << endl ; + return _request ; + } + + /* + MPIAccess and "tags" (or "MPITags") : + ===================================== + + . The constructor give the possibility to choose an interval of + tags to use : [BaseTag , MaxTag]. + The default is [ 0 , MPI_TAG_UB], MPI_TAG_UB being the maximum + value in an implementation of MPI (minimum 32767 = 2**15-1). + On awa with the implementation lam MPI_TAG_UB value is + 7353944. The norma MPI specify that value is the same in all + processes started by mpirun. + In the case of the use of the same IntraCommunicator in a process + for several distinct data flows (or for several IntraCommunicators + with common processes), that permits to avoid ambibuity + and may help debug. + + . In MPIAccess the tags have two parts (#define MODULO_TAG 10) : + + The last decimal digit decimal correspond to MPI_DataType ( 1 for + TimeMessages, 2 for MPI_INT and 3 for MPI_DOUBLE) + + The value of other digits correspond to a circular numero for each + message. + + A TimeMessage and the associated DataMessage have the same numero + (but the types are different and the tags also). + + . For a Send of a message from a process "source" to a process + "target", we have _send_MPI_tag[target] in the process + source (it contains the last "tag" used for the Send of a pour l'envoi de + message to the process target). + And in the process "target" which receive that message, we have + _recv_MPI_Tag[source] (it contains the last "tag" used for the Recv + of messages from the process source). + Naturally in the MPI norma the values of that tags must be the same. + */ + int MPIAccess::newSendTag( MPI_Datatype datatype, int destrank , int method , + bool asynchronous, int &RequestId ) + { + int tag ; + tag = incrTag( _send_MPI_tag[destrank] ) ; + tag = valTag( tag, method ) ; + _send_MPI_tag[ destrank ] = tag ; + RequestId = newRequest( datatype, tag, destrank , false , asynchronous ) ; + _send_request[ destrank ] = RequestId ; + _send_requests[ destrank ].push_back( RequestId ) ; + return tag ; + } + + int MPIAccess::newRecvTag( MPI_Datatype datatype, int sourcerank , int method , + bool asynchronous, int &RequestId ) + { + int tag ; + tag = incrTag( _recv_MPI_Tag[sourcerank] ) ; + tag = valTag( tag, method ) ; + _recv_MPI_Tag[ sourcerank ] = tag ; + RequestId = newRequest( datatype, tag , sourcerank , true , asynchronous ) ; + _recv_request[ sourcerank ] = RequestId ; + _recv_requests[ sourcerank ].push_back( RequestId ) ; + return tag ; + } + + // Returns the number of all SendRequestIds that may be used to allocate + // ArrayOfSendRequests for the call to SendRequestIds + int MPIAccess::sendRequestIdsSize() + { + int size = 0; + for (int i = 0 ; i < _processor_group_size ; i++ ) + size += _send_requests[ i ].size() ; + return size ; + } + + // Returns in ArrayOfSendRequests with the dimension "size" all the + // SendRequestIds + int MPIAccess::sendRequestIds(int size, int *ArrayOfSendRequests) + { + int destrank ; + int i = 0 ; + for ( destrank = 0 ; destrank < _processor_group_size ; destrank++ ) + { + list< int >::const_iterator iter ; + for (iter = _send_requests[ destrank ].begin() ; iter != _send_requests[destrank].end() ; iter++ ) + ArrayOfSendRequests[i++] = *iter ; + } + return i ; + } + + // Returns the number of all RecvRequestIds that may be used to allocate + // ArrayOfRecvRequests for the call to RecvRequestIds + int MPIAccess::recvRequestIdsSize() + { + int size = 0 ; + for (int i = 0 ; i < _processor_group_size ; i++ ) + size += _recv_requests[ i ].size() ; + return size ; + } + + // Returns in ArrayOfRecvRequests with the dimension "size" all the + // RecvRequestIds + int MPIAccess::recvRequestIds(int size, int *ArrayOfRecvRequests) + { + int sourcerank ; + int i = 0 ; + for ( sourcerank = 0 ; sourcerank < _processor_group_size ; sourcerank++ ) + { + list< int >::const_iterator iter ; + for (iter = _recv_requests[ sourcerank ].begin() ; iter != _recv_requests[sourcerank].end() ; iter++ ) + ArrayOfRecvRequests[i++] = *iter ; + } + return i ; + } + + // Returns in ArrayOfSendRequests with the dimension "size" all the + // SendRequestIds to a destination rank + int MPIAccess::sendRequestIds(int destrank, int size, int *ArrayOfSendRequests) + { + if (size < _send_requests[destrank].size() ) + throw INTERP_KERNEL::Exception("wrong call to MPIAccess::SendRequestIds"); + int i = 0 ; + list< int >::const_iterator iter ; + for (iter = _send_requests[ destrank ].begin() ; iter != _send_requests[destrank].end() ; iter++ ) + ArrayOfSendRequests[i++] = *iter ; + return _send_requests[destrank].size() ; + } + + // Returns in ArrayOfRecvRequests with the dimension "size" all the + // RecvRequestIds from a sourcerank + int MPIAccess::recvRequestIds(int sourcerank, int size, int *ArrayOfRecvRequests) + { + if (size < _recv_requests[sourcerank].size() ) + throw INTERP_KERNEL::Exception("wrong call to MPIAccess::RecvRequestIds"); + int i = 0 ; + list< int >::const_iterator iter ; + _recv_requests[ sourcerank ] ; + for (iter = _recv_requests[ sourcerank ].begin() ; iter != _recv_requests[sourcerank].end() ; iter++ ) + ArrayOfRecvRequests[i++] = *iter ; + return _recv_requests[sourcerank].size() ; + } + + // Send in synchronous mode count values of type datatype from buffer to target + // (returns RequestId identifier even if the corresponding structure is deleted : + // it is only in order to have the same signature as the asynchronous mode) + int MPIAccess::send(void* buffer, int count, MPI_Datatype datatype, int target, int &RequestId) + { + int sts = MPI_SUCCESS ; + RequestId = -1 ; + if ( count ) + { + _MessageIdent aMethodIdent = methodId( datatype ) ; + int MPItag = newSendTag( datatype, target , aMethodIdent , false , RequestId ) ; + if ( aMethodIdent == _message_time ) + { + TimeMessage *aTimeMsg = (TimeMessage *) buffer ; + aTimeMsg->tag = MPItag ; + } + deleteRequest( RequestId ) ; + sts = _comm_interface.send(buffer, count, datatype, target, MPItag, + *_intra_communicator ) ; + if ( _trace ) + cout << "MPIAccess::Send" << _my_rank << " SendRequestId " + << RequestId << " count " << count << " target " << target + << " MPItag " << MPItag << endl ; + } + return sts ; + } + + // Receive (read) in synchronous mode count values of type datatype in buffer from source + // (returns RequestId identifier even if the corresponding structure is deleted : + // it is only in order to have the same signature as the asynchronous mode) + // The output argument OutCount is optionnal : *OutCount <= count + int MPIAccess::recv(void* buffer, int count, MPI_Datatype datatype, int source, int &RequestId, int *OutCount) + { + int sts = MPI_SUCCESS ; + RequestId = -1 ; + if ( OutCount != NULL ) + *OutCount = -1 ; + if ( count ) + { + _MessageIdent aMethodIdent = methodId( datatype ) ; + int MPItag = newRecvTag( datatype, source , aMethodIdent , false , RequestId ) ; + sts = _comm_interface.recv(buffer, count, datatype, source, MPItag, + *_intra_communicator , MPIStatus( RequestId ) ) ; + int outcount = 0 ; + if ( sts == MPI_SUCCESS ) + { + MPI_Datatype datatype = MPIDatatype( RequestId ) ; + _comm_interface.getCount(MPIStatus( RequestId ), datatype, &outcount ) ; + setMPIOutCount( RequestId , outcount ) ; + setMPICompleted( RequestId , true ) ; + deleteStatus( RequestId ) ; + } + if ( OutCount != NULL ) + *OutCount = outcount ; + if ( _trace ) + cout << "MPIAccess::Recv" << _my_rank << " RecvRequestId " + << RequestId << " count " << count << " source " << source + << " MPItag " << MPItag << endl ; + deleteRequest( RequestId ) ; + } + return sts ; + } + + // Send in asynchronous mode count values of type datatype from buffer to target + // Returns RequestId identifier. + int MPIAccess::ISend(void* buffer, int count, MPI_Datatype datatype, int target, int &RequestId) + { + int sts = MPI_SUCCESS ; + RequestId = -1 ; + if ( count ) + { + _MessageIdent aMethodIdent = methodId( datatype ) ; + int MPItag = newSendTag( datatype, target , aMethodIdent , true , RequestId ) ; + if ( aMethodIdent == _message_time ) + { + TimeMessage *aTimeMsg = (TimeMessage *) buffer ; + aTimeMsg->tag = MPItag ; + } + MPI_Request *aSendRequest = MPIRequest( RequestId ) ; + if ( _trace ) + { + cout << "MPIAccess::ISend" << _my_rank << " ISendRequestId " + << RequestId << " count " << count << " target " << target + << " MPItag " << MPItag << endl ; + if ( MPItag == 1 ) + cout << "MPIAccess::ISend" << _my_rank << " time " + << ((TimeMessage *)buffer)->time << " " << ((TimeMessage *)buffer)->deltatime + << endl ; + } + sts = _comm_interface.Isend(buffer, count, datatype, target, MPItag, + *_intra_communicator , aSendRequest) ; + } + return sts ; + } + + // Receive (read) in asynchronous mode count values of type datatype in buffer from source + // returns RequestId identifier. + int MPIAccess::IRecv(void* buffer, int count, MPI_Datatype datatype, int source, int &RequestId) + { + int sts = MPI_SUCCESS ; + RequestId = -1 ; + if ( count ) + { + _MessageIdent aMethodIdent = methodId( datatype ) ; + int MPItag = newRecvTag( datatype, source , aMethodIdent , true , RequestId ) ; + MPI_Request *aRecvRequest = MPIRequest( RequestId ) ; + if ( _trace ) + { + cout << "MPIAccess::IRecv" << _my_rank << " IRecvRequestId " + << RequestId << " count " << count << " source " << source + << " MPItag " << MPItag << endl ; + if ( MPItag == 1 ) + cout << "MPIAccess::ISend" << _my_rank << " time " + << ((TimeMessage *)buffer)->time << " " << ((TimeMessage *)buffer)->deltatime + << endl ; + } + sts = _comm_interface.Irecv(buffer, count, datatype, source, MPItag, + *_intra_communicator , aRecvRequest) ; + } + return sts ; + } + + // Perform a Send and a Recv in synchronous mode + int MPIAccess::sendRecv(void* sendbuf, int sendcount, MPI_Datatype sendtype, + int dest, int &SendRequestId, + void* recvbuf, int recvcount, MPI_Datatype recvtype, + int source, int &RecvRequestId, int *OutCount) + { + int sts = MPI_SUCCESS ; + SendRequestId = -1 ; + RecvRequestId = -1 ; + if ( recvcount ) + sts = IRecv(recvbuf, recvcount, recvtype, source, RecvRequestId) ; + int outcount = -1 ; + if ( _trace ) + cout << "MPIAccess::SendRecv" << _my_rank << " IRecv RecvRequestId " + << RecvRequestId << endl ; + if ( sts == MPI_SUCCESS ) + { + if ( sendcount ) + sts = send(sendbuf, sendcount, sendtype, dest, SendRequestId) ; + if ( _trace ) + cout << "MPIAccess::SendRecv" << _my_rank << " Send SendRequestId " + << SendRequestId << endl ; + if ( sts == MPI_SUCCESS && recvcount ) + { + sts = wait( RecvRequestId ) ; + outcount = MPIOutCount( RecvRequestId ) ; + if ( _trace ) + cout << "MPIAccess::SendRecv" << _my_rank << " IRecv RecvRequestId " + << RecvRequestId << " outcount " << outcount << endl ; + } + } + if ( OutCount != NULL ) + { + *OutCount = outcount ; + if ( _trace ) + cout << "MPIAccess::SendRecv" << _my_rank << " *OutCount = " << *OutCount + << endl ; + } + deleteRequest( RecvRequestId ) ; + return sts ; + } + + // Perform a Send and a Recv in asynchronous mode + int MPIAccess::ISendRecv(void* sendbuf, int sendcount, MPI_Datatype sendtype, + int dest, int &SendRequestId, + void* recvbuf, int recvcount, MPI_Datatype recvtype, + int source, int &RecvRequestId) + { + int sts = MPI_SUCCESS ; + SendRequestId = -1 ; + RecvRequestId = -1 ; + if ( recvcount ) + sts = IRecv(recvbuf, recvcount, recvtype, source, RecvRequestId) ; + if ( sts == MPI_SUCCESS ) + if ( sendcount ) + sts = ISend(sendbuf, sendcount, sendtype, dest, SendRequestId) ; + return sts ; + } + + // Perform a wait of a Send or Recv asynchronous Request + // Do nothing for a synchronous Request + // Manage MPI_Request * and MPI_Status * structure + int MPIAccess::wait( int RequestId ) + { + int status = MPI_SUCCESS ; + if ( !MPICompleted( RequestId ) ) + { + if ( *MPIRequest( RequestId ) != MPI_REQUEST_NULL ) + { + if ( _trace ) + cout << "MPIAccess::Wait" << _my_rank << " -> wait( " << RequestId + << " ) MPIRequest " << MPIRequest( RequestId ) << " MPIStatus " + << MPIStatus( RequestId ) << " MPITag " << MPITag( RequestId ) + << " MPIIsRecv " << MPIIsRecv( RequestId ) << endl ; + status = _comm_interface.wait(MPIRequest( RequestId ), MPIStatus( RequestId )) ; + } + else + { + if ( _trace ) + cout << "MPIAccess::Wait" << _my_rank << " MPIRequest == MPI_REQUEST_NULL" + << endl ; + } + setMPICompleted( RequestId , true ) ; + if ( MPIIsRecv( RequestId ) && MPIStatus( RequestId ) ) + { + MPI_Datatype datatype = MPIDatatype( RequestId ) ; + int outcount ; + status = _comm_interface.getCount(MPIStatus( RequestId ), datatype, + &outcount ) ; + if ( status == MPI_SUCCESS ) + { + setMPIOutCount( RequestId , outcount ) ; + deleteStatus( RequestId ) ; + if ( _trace ) + cout << "MPIAccess::Wait" << _my_rank << " RequestId " << RequestId + << "MPIIsRecv " << MPIIsRecv( RequestId ) << " outcount " << outcount + << endl ; + } + else + { + if ( _trace ) + cout << "MPIAccess::Wait" << _my_rank << " MPIIsRecv " + << MPIIsRecv( RequestId ) << " outcount " << outcount << endl ; + } + } + else + { + if ( _trace ) + cout << "MPIAccess::Wait" << _my_rank << " MPIIsRecv " << MPIIsRecv( RequestId ) + << " MPIOutCount " << MPIOutCount( RequestId ) << endl ; + } + } + if ( _trace ) + cout << "MPIAccess::Wait" << _my_rank << " RequestId " << RequestId + << " Request " << MPIRequest( RequestId ) + << " Status " << MPIStatus( RequestId ) << " MPICompleted " + << MPICompleted( RequestId ) << " MPIOutCount " << MPIOutCount( RequestId ) + << endl ; + return status ; + } + + // Perform a "test" of a Send or Recv asynchronous Request + // If the request is done, returns true in the flag argument + // If the request is not finished, returns false in the flag argument + // Do nothing for a synchronous Request + // Manage MPI_request * and MPI_status * structure + int MPIAccess::test(int RequestId, int &flag) + { + int status = MPI_SUCCESS ; + flag = MPICompleted( RequestId ) ; + if ( _trace ) + cout << "MPIAccess::Test" << _my_rank << " flag " << flag ; + if ( MPIIsRecv( RequestId ) ) + { + if ( _trace ) + cout << " Recv" ; + } + else + { + if ( _trace ) + cout << " Send" ; + } + if( _trace ) + cout << "Request" << RequestId << " " << MPIRequest( RequestId ) + << " Status " << MPIStatus( RequestId ) << endl ; + if ( !flag ) + { + if ( *MPIRequest( RequestId ) != MPI_REQUEST_NULL ) + { + if ( _trace ) + cout << "MPIAccess::Test" << _my_rank << " -> test( " << RequestId + << " ) MPIRequest " << MPIRequest( RequestId ) + << " MPIStatus " << MPIStatus( RequestId ) + << " MPITag " << MPITag( RequestId ) + << " MPIIsRecv " << MPIIsRecv( RequestId ) << endl ; + status = _comm_interface.test(MPIRequest( RequestId ), &flag, + MPIStatus( RequestId )) ; + } + else + { + if ( _trace ) + cout << "MPIAccess::Test" << _my_rank << " MPIRequest == MPI_REQUEST_NULL" + << endl ; + } + if ( flag ) + { + setMPICompleted( RequestId , true ) ; + if ( MPIIsRecv( RequestId ) && MPIStatus( RequestId ) ) + { + int outcount ; + MPI_Datatype datatype = MPIDatatype( RequestId ) ; + status = _comm_interface.getCount( MPIStatus( RequestId ), datatype, + &outcount ) ; + if ( status == MPI_SUCCESS ) + { + setMPIOutCount( RequestId , outcount ) ; + deleteStatus( RequestId ) ; + if ( _trace ) + cout << "MPIAccess::Test" << _my_rank << " MPIIsRecv " + << MPIIsRecv( RequestId ) << " outcount " << outcount << endl ; + } + else + { + if ( _trace ) + cout << "MPIAccess::Test" << _my_rank << " MPIIsRecv " + << MPIIsRecv( RequestId ) << " outcount " << outcount << endl ; + } + } + else + { + if ( _trace ) + cout << "MPIAccess::Test" << _my_rank << " MPIIsRecv " + << MPIIsRecv( RequestId ) << " MPIOutCount " + << MPIOutCount( RequestId ) << endl ; + } + } + } + if ( _trace ) + cout << "MPIAccess::Test" << _my_rank << " RequestId " << RequestId + << " flag " << flag << " MPICompleted " << MPICompleted( RequestId ) + << " MPIOutCount " << MPIOutCount( RequestId ) << endl ; + return status ; + } + + int MPIAccess::waitAny(int count, int *array_of_RequestIds, int &RequestId) + { + int status = MPI_ERR_OTHER ; + RequestId = -1 ; + cout << "MPIAccess::WaitAny not yet implemented" << endl ; + return status ; + } + + int MPIAccess::testAny(int count, int *array_of_RequestIds, int &RequestId, int &flag) + { + int status = MPI_ERR_OTHER ; + RequestId = -1 ; + flag = 0 ; + cout << "MPIAccess::TestAny not yet implemented" << endl ; + return status ; + } + + // Perform a wait of each Send or Recv asynchronous Request of the array + // array_of_RequestIds of size "count". + // That array may be filled with a call to SendRequestIdsSize or RecvRequestIdsSize + // Do nothing for a synchronous Request + // Manage MPI_Request * and MPI_Status * structure + int MPIAccess::waitAll(int count, int *array_of_RequestIds) + { + if ( _trace ) + cout << "WaitAll" << _my_rank << " : count " << count << endl ; + int status ; + int retstatus = MPI_SUCCESS ; + int i ; + for ( i = 0 ; i < count ; i++ ) + { + if ( _trace ) + cout << "WaitAll" << _my_rank << " " << i << " -> Wait( " + << array_of_RequestIds[i] << " )" << endl ; + status = wait( array_of_RequestIds[i] ) ; + if ( status != MPI_SUCCESS ) + retstatus = status ; + } + if ( _trace ) + cout << "EndWaitAll" << _my_rank << endl ; + return retstatus ; + } + + // Perform a "test" of each Send or Recv asynchronous Request of the array + // array_of_RequestIds of size "count". + // That array may be filled with a call to SendRequestIdsSize or RecvRequestIdsSize + // If all requests are done, returns true in the flag argument + // If all requests are not finished, returns false in the flag argument + // Do nothing for a synchronous Request + // Manage MPI_Request * and MPI_Status * structure + int MPIAccess::testAll(int count, int *array_of_RequestIds, int &flag) + { + if ( _trace ) + cout << "TestAll" << _my_rank << " : count " << count << endl ; + int status ; + int retstatus = MPI_SUCCESS ; + bool retflag = true ; + int i ; + for ( i = 0 ; i < count ; i++ ) + { + status = test( array_of_RequestIds[i] , flag ) ; + retflag = retflag && (flag != 0) ; + if ( status != MPI_SUCCESS ) + retstatus = status ; + } + flag = retflag ; + if ( _trace ) + cout << "EndTestAll" << _my_rank << endl ; + return retstatus ; + } + + int MPIAccess::waitSome(int count, int *array_of_RequestIds, int outcount, + int *outarray_of_RequestIds) + { + int status = MPI_ERR_OTHER ; + cout << "MPIAccess::WaitSome not yet implemented" << endl ; + return status ; + } + + int MPIAccess::testSome(int count, int *array_of_RequestIds, int outcounts, + int *outarray_of_RequestIds) + { + int status = MPI_ERR_OTHER ; + cout << "MPIAccess::TestSome not yet implemented" << endl ; + return status ; + } + + // Probe checks if a message is available for read from FromSource rank. + // Returns the corresponding source, MPITag, datatype and outcount + // Probe is a blocking call which wait until a message is available + int MPIAccess::probe(int FromSource, int &source, int &MPITag, + MPI_Datatype &myDatatype, int &outcount) + { + MPI_Status aMPIStatus ; + int sts = _comm_interface.probe( FromSource, MPI_ANY_TAG, + *_intra_communicator , &aMPIStatus ) ; + if ( sts == MPI_SUCCESS ) + { + source = aMPIStatus.MPI_SOURCE ; + MPITag = aMPIStatus.MPI_TAG ; + int MethodId = (MPITag % MODULO_TAG) ; + myDatatype = datatype( (ParaMEDMEM::_MessageIdent) MethodId ) ; + _comm_interface.getCount(&aMPIStatus, myDatatype, &outcount ) ; + if ( _trace ) + cout << "MPIAccess::Probe" << _my_rank << " FromSource " << FromSource + << " source " << source << " MPITag " << MPITag << " MethodId " + << MethodId << " datatype " << myDatatype << " outcount " << outcount + << endl ; + } + else + { + source = -1 ; + MPITag = -1 ; + myDatatype = 0 ; + outcount = -1 ; + } + return sts ; + } + + // IProbe checks if a message is available for read from FromSource rank. + // If there is a message available, returns the corresponding source, + // MPITag, datatype and outcount with flag = true + // If not, returns flag = false + int MPIAccess::IProbe(int FromSource, int &source, int &MPITag, + MPI_Datatype &myDataType, int &outcount, int &flag) + { + MPI_Status aMPIStatus ; + int sts = _comm_interface.Iprobe( FromSource, MPI_ANY_TAG, + *_intra_communicator , &flag, + &aMPIStatus ) ; + if ( sts == MPI_SUCCESS && flag ) + { + source = aMPIStatus.MPI_SOURCE ; + MPITag = aMPIStatus.MPI_TAG ; + int MethodId = (MPITag % MODULO_TAG) ; + myDataType = datatype( (ParaMEDMEM::_MessageIdent) MethodId ) ; + _comm_interface.getCount(&aMPIStatus, myDataType, &outcount ) ; + if ( _trace ) + cout << "MPIAccess::IProbe" << _my_rank << " FromSource " << FromSource + << " source " << source << " MPITag " << MPITag << " MethodId " + << MethodId << " datatype " << myDataType << " outcount " << outcount + << " flag " << flag << endl ; + } + else + { + source = -1 ; + MPITag = -1 ; + myDataType = 0 ; + outcount = -1 ; + } + return sts ; + } + + // Cancel concerns a "posted" asynchronous IRecv + // Returns flag = true if the receiving request was successfully canceled + // Returns flag = false if the receiving request was finished but not canceled + // Use cancel, wait and test_cancelled of the MPI API + int MPIAccess::cancel( int RecvRequestId, int &flag ) + { + flag = 0 ; + int sts = _comm_interface.cancel( MPIRequest( RecvRequestId ) ) ; + if ( sts == MPI_SUCCESS ) + { + sts = _comm_interface.wait( MPIRequest( RecvRequestId ) , + MPIStatus( RecvRequestId ) ) ; + if ( sts == MPI_SUCCESS ) + sts = _comm_interface.testCancelled( MPIStatus( RecvRequestId ) , &flag ) ; + } + return sts ; + } + + // Cancel concerns a "pending" receiving message (without IRecv "posted") + // Returns flag = true if the message was successfully canceled + // Returns flag = false if the receiving request was finished but not canceled + // Use Irecv, cancel, wait and test_cancelled of the MPI API + int MPIAccess::cancel( int source, int theMPITag, MPI_Datatype datatype, int outcount, int &flag ) + { + int sts ; + MPI_Aint extent ; + flag = 0 ; + sts = MPI_Type_extent( datatype , &extent ) ; + if ( sts == MPI_SUCCESS ) + { + void * recvbuf = malloc( extent*outcount ) ; + MPI_Request aRecvRequest ; + if ( _trace ) + cout << "MPIAccess::Cancel" << _my_rank << " Irecv extent " << extent + << " datatype " << datatype << " source " << source << " theMPITag " + << theMPITag << endl ; + sts = _comm_interface.Irecv( recvbuf, outcount, datatype, source, theMPITag, + *_intra_communicator , &aRecvRequest ) ; + if ( sts == MPI_SUCCESS ) + { + sts = _comm_interface.cancel( &aRecvRequest ) ; + if ( _trace ) + cout << "MPIAccess::Cancel" << _my_rank << " theMPITag " << theMPITag + << " cancel done" << endl ; + if ( sts == MPI_SUCCESS ) + { + MPI_Status aStatus ; + if ( _trace ) + cout << "MPIAccess::Cancel" << _my_rank << " wait" << endl ; + sts = _comm_interface.wait( &aRecvRequest , &aStatus ) ; + if ( sts == MPI_SUCCESS ) + { + if ( _trace ) + cout << "MPIAccess::Cancel" << _my_rank << " test_cancelled" << endl ; + sts = _comm_interface.testCancelled( &aStatus , &flag ) ; + } + } + } + if ( _trace && datatype == timeType() ) + cout << "MPIAccess::Cancel" << _my_rank << " time " + << ((TimeMessage *) recvbuf)->time << " " + << ((TimeMessage *) recvbuf)->deltatime << endl ; + free( recvbuf ) ; + } + if ( _trace ) + cout << "MPIAccess::Cancel" << _my_rank << " flag " << flag << endl ; + return sts ; + } + + + // CancelAll concerns all "pending" receiving message (without IRecv "posted") + // CancelAll use IProbe and Cancel (see obove) + int MPIAccess::cancelAll() + { + int sts = MPI_SUCCESS ; + int target ; + int source ; + int MPITag ; + MPI_Datatype datatype ; + int outcount ; + int flag ; + for ( target = 0 ; target < _processor_group_size ; target++ ) + { + sts = IProbe(target, source, MPITag, datatype, outcount, flag) ; + if ( sts == MPI_SUCCESS && flag ) + { + sts = cancel(source, MPITag, datatype, outcount, flag) ; + if ( _trace ) + cout << "MPIAccess::CancelAll" << _my_rank << " source " << source + << " MPITag " << MPITag << " datatype " << datatype + << " outcount " << outcount << " Cancel flag " << flag << endl ; + if ( sts != MPI_SUCCESS ) + break ; + } + else if ( sts != MPI_SUCCESS ) + break ; + } + return sts ; + } + + // Same as barrier of MPI API + int MPIAccess::barrier() + { + int status = _comm_interface.barrier( *_intra_communicator ) ; + return status ; + } + + // Same as Error_string of MPI API + int MPIAccess::errorString(int errorcode, char *string, int *resultlen) const + { + return _comm_interface.errorString( errorcode, string, resultlen) ; + } + + // Returns source, tag, error and outcount corresponding to receiving RequestId + // By default the corresponding structure of RequestId is deleted + int MPIAccess::status(int RequestId, int &source, int &tag, int &error, + int &outcount, bool keepRequestStruct) + { + MPI_Status *myStatus = MPIStatus( RequestId ) ; + if ( _trace ) + cout << "MPIAccess::status" << _my_rank << " RequestId " << RequestId + << " status " << myStatus << endl ; + if ( myStatus != NULL && MPIAsynchronous( RequestId ) && + MPICompleted( RequestId ) ) + { + if ( MPIIsRecv( RequestId ) ) + { + source = myStatus->MPI_SOURCE ; + tag = myStatus->MPI_TAG ; + error = myStatus->MPI_ERROR ; + MPI_Datatype datatype = MPIDatatype( RequestId ) ; + _comm_interface.getCount(myStatus, datatype, &outcount ) ; + if ( _trace ) + cout << "MPIAccess::status" << _my_rank << " RequestId " << RequestId + << " status " << myStatus << " outcount " << outcount << endl ; + setMPIOutCount( RequestId , outcount ) ; + } + else + { + source = MPITarget( RequestId ) ; + tag = MPITag( RequestId ) ; + error = 0 ; + outcount = MPIOutCount( RequestId ) ; + } + if ( !keepRequestStruct ) + deleteRequest( RequestId ) ; + return MPI_SUCCESS ; + } + else + { + source = MPITarget( RequestId ) ; + tag = MPITag( RequestId ) ; + error = 0 ; + outcount = MPIOutCount( RequestId ) ; + } + return MPI_SUCCESS ; + } + + int MPIAccess::requestFree( MPI_Request *request ) + { + return _comm_interface.requestFree( request ) ; + } + + // Print all informations of all known requests for debugging purpose + void MPIAccess::check() const + { + int i = 0 ; + map< int , RequestStruct * >::const_iterator MapOfRequestStructiterator ; + cout << "MPIAccess::Check" << _my_rank << "_map_of_request_struct_size " + << _map_of_request_struct.size() << endl ; + for ( MapOfRequestStructiterator = _map_of_request_struct.begin() ; + MapOfRequestStructiterator != _map_of_request_struct.end() ; + MapOfRequestStructiterator++ ) + { + if ( MapOfRequestStructiterator->second != NULL ) + { + cout << " Check" << _my_rank << " " << i << ". Request" + << MapOfRequestStructiterator->first << "-->" ; + if ( (MapOfRequestStructiterator->second)->MPIAsynchronous ) + cout << "I" ; + if ( (MapOfRequestStructiterator->second)->MPIIsRecv ) + cout << "Recv from " ; + else + cout << "Send to " ; + cout << (MapOfRequestStructiterator->second)->MPITarget + << " MPITag " << (MapOfRequestStructiterator->second)->MPITag + << " DataType " << (MapOfRequestStructiterator->second)->MPIDatatype + << " Request " << (MapOfRequestStructiterator->second)->MPIRequest + << " Status " << (MapOfRequestStructiterator->second)->MPIStatus + << " Completed " << (MapOfRequestStructiterator->second)->MPICompleted + << endl ; + } + i++ ; + } + } + + // Outputs fields of a TimeMessage structure + ostream & operator<< (ostream & f ,const TimeMessage & aTimeMsg ) + { + f << " time " << aTimeMsg.time << " deltatime " << aTimeMsg.deltatime + << " tag " << aTimeMsg.tag ; + return f; + } + + // Outputs the DataType coded in a Tag + ostream & operator<< (ostream & f ,const _MessageIdent & methodtype ) + { + switch (methodtype) + { + case _message_time : + f << " MethodTime "; + break; + case _message_int : + f << " MPI_INT "; + break; + case _message_double : + f << " MPI_DOUBLE "; + break; + default : + f << " UnknownMethodType "; + break; + } + return f; + } +} diff --git a/src/ParaMEDMEM/MPIAccess.hxx b/src/ParaMEDMEM/MPIAccess.hxx new file mode 100644 index 000000000..6ae79aa12 --- /dev/null +++ b/src/ParaMEDMEM/MPIAccess.hxx @@ -0,0 +1,494 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __MPIACCESS_HXX__ +#define __MPIACCESS_HXX__ + +#include "CommInterface.hxx" +#include "ProcessorGroup.hxx" +#include "MPIProcessorGroup.hxx" + +#include <map> +#include <list> +#include <vector> +#include <iostream> + +namespace ParaMEDMEM +{ + typedef struct + { + double time ; + double deltatime ; + int tag ; + } TimeMessage; + + static MPI_Request mpirequestnull = MPI_REQUEST_NULL ; + enum _MessageIdent { _message_unknown, _message_time, _message_int, _message_double } ; + + class MPIAccess + { + private: + struct RequestStruct + { + int MPITarget ; + bool MPIIsRecv ; + int MPITag ; + bool MPIAsynchronous ; + bool MPICompleted ; + MPI_Datatype MPIDatatype ; + MPI_Request MPIRequest ; + MPI_Status *MPIStatus ; + int MPIOutCount ; + }; + public: + MPIAccess(MPIProcessorGroup * ProcessorGroup, int BaseTag=0, int MaxTag=0) ; + virtual ~MPIAccess() ; + + void trace( bool trace = true ) ; + + void deleteRequest( int RequestId ) ; + void deleteRequests(int size , int *ArrayOfSendRequests ) ; + + int sendMPITag(int destrank) ; + int recvMPITag(int sourcerank) ; + + int sendRequestIdsSize() ; + int sendRequestIds(int size, int *ArrayOfSendRequests) ; + int recvRequestIdsSize() ; + int recvRequestIds(int size, int *ArrayOfRecvRequests) ; + + int sendRequestIdsSize(int destrank) ; + int sendRequestIds(int destrank, int size, int *ArrayOfSendRequests) ; + int recvRequestIdsSize(int sourcerank) ; + int recvRequestIds(int sourcerank, int size, int *ArrayOfRecvRequests) ; + + int send(void* buffer, int count, MPI_Datatype datatype, int target, + int &RequestId) ; + int ISend(void* buffer, int count, MPI_Datatype datatype, int target, + int &RequestId) ; + int recv(void* buffer, int count, MPI_Datatype datatype, int source, + int &RequestId, int *OutCount=NULL) ; + int IRecv(void* buffer, int count, MPI_Datatype datatype, int source, + int &RequestId) ; + int sendRecv(void* sendbuf, int sendcount, MPI_Datatype sendtype, int dest, + int &SendRequestId, void* recvbuf, int recvcount, + MPI_Datatype recvtype, int source, + int &RecvRequestId, int *OutCount=NULL) ; + int ISendRecv(void* sendbuf, int sendcount, MPI_Datatype sendtype, int dest, + int &SendRequestId, void* recvbuf, int recvcount, + MPI_Datatype recvtype, int source, int &RecvRequestId) ; + + int wait(int RequestId) ; + int test(int RequestId, int &flag) ; + int waitAny(int count, int *array_of_RequestIds, int &RequestId) ; + int testAny(int count, int *array_of_RequestIds, int &RequestId, int &flag) ; + int waitAll(int count, int *array_of_RequestIds) ; + int testAll(int count, int *array_of_RequestIds, int &flag) ; + int waitSome(int count, int *array_of_RequestIds, int outcount, + int *outarray_of_RequestIds) ; + int testSome(int count, int *array_of_RequestIds, int outcounts, + int *outarray_of_RequestIds) ; + int probe(int FromSource, int &source, int &MPITag, MPI_Datatype &datatype, + int &outcount) ; + int IProbe(int FromSource, int &source, int &MPITag, MPI_Datatype &datatype, + int &outcount, int &flag) ; + int cancel( int RecvRequestId, int &flag ) ; + int cancel( int source, int MPITag, MPI_Datatype datatype, int outcount, + int &flag ) ; + int cancelAll() ; + int barrier() ; + int errorString(int errorcode, char *string, int *resultlen) const ; + int status(int RequestId, int &source, int &tag, int &error, int &outcount, + bool keepRequestStruct=false) ; + int requestFree( MPI_Request *request ) ; + + void check() const ; + + MPI_Datatype timeType() const ; + bool isTimeMessage( int MPITag ) const ; + MPI_Aint timeExtent() const ; + MPI_Aint intExtent() const ; + MPI_Aint doubleExtent() const ; + MPI_Aint extent( MPI_Datatype datatype ) const ; + + int MPITag( int RequestId ) ; + int MPITarget( int RequestId ) ; + bool MPIIsRecv( int RequestId ) ; + bool MPIAsynchronous( int RequestId ) ; + bool MPICompleted( int RequestId ) ; + MPI_Datatype MPIDatatype( int RequestId ) ; + int MPIOutCount( int RequestId ) ; + + private: + int newRequest( MPI_Datatype datatype, int tag , int destsourcerank , + bool fromsourcerank , bool asynchronous ) ; + int newSendTag( MPI_Datatype datatype, int destrank , int method , + bool asynchronous, int &RequestId ) ; + int newRecvTag( MPI_Datatype datatype, int sourcerank , int method , + bool asynchronous, int &RequestId ) ; + int incrTag( int prevtag ) ; + int valTag( int tag, int method ) ; + + void deleteSendRecvRequest( int RequestId ) ; + + void deleteStatus( int RequestId ) ; + + MPI_Request *MPIRequest( int RequestId ) ; + MPI_Status *MPIStatus( int RequestId ) ; + void setMPICompleted( int RequestId , bool completed ) ; + void setMPIOutCount( int RequestId , int outcount ) ; + void clearMPIStatus( int RequestId ) ; + + _MessageIdent methodId( MPI_Datatype datatype ) const ; + MPI_Datatype datatype( _MessageIdent aMethodIdent ) const ; + private: + const CommInterface &_comm_interface ; + const MPI_Comm* _intra_communicator ; + MPIProcessorGroup * _processor_group ; + int _processor_group_size ; + int _my_rank ; + bool _trace ; + int _base_request ; + int _max_request ; + int _request ; + int * _send_request ; + int * _recv_request ; + std::vector< std::list< int > > _send_requests ; + std::vector< std::list< int > > _recv_requests ; + int _base_MPI_tag ; + int _max_MPI_tag ; + int * _send_MPI_tag ; + int * _recv_MPI_Tag ; + MPI_Datatype _MPI_TIME ; + static const int MODULO_TAG=10; + std::map< int , RequestStruct * > _map_of_request_struct ; + + }; + + inline void MPIAccess::trace( bool trace ) + { + _trace = trace ; + } + + // Delete the structure Request corresponding to RequestId identifier after + // the deletion of the structures MPI_Request * and MPI_Status * + // remove it from _MapOfRequestStruct (erase) + inline void MPIAccess::deleteRequest( int RequestId ) + { + struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; + if ( aRequestStruct ) + { + if ( _trace ) + std::cout << "MPIAccess::DeleteRequest" << _my_rank << "( " << RequestId << " ) " + << aRequestStruct << " MPIRequest " << aRequestStruct->MPIRequest + << " MPIIsRecv " << aRequestStruct->MPIIsRecv << std::endl ; + if ( _map_of_request_struct[RequestId]->MPIRequest != MPI_REQUEST_NULL ) + requestFree( &_map_of_request_struct[RequestId]->MPIRequest ) ; + deleteSendRecvRequest( RequestId ) ; + deleteStatus( RequestId ) ; + _map_of_request_struct.erase( RequestId ) ; + delete aRequestStruct ; + } + else + { + if ( _trace ) + std::cout << "MPIAccess::DeleteRequest" << _my_rank << "( " << RequestId + << " ) Request not found" << std::endl ; + } + } + + // Delete all requests of the array ArrayOfSendRequests + inline void MPIAccess::deleteRequests(int size , int *ArrayOfSendRequests ) + { + for (int i = 0 ; i < size ; i++ ) + deleteRequest( ArrayOfSendRequests[i] ) ; + } + + // Returns the last MPITag of the destination rank destrank + inline int MPIAccess::sendMPITag(int destrank) + { + return _send_MPI_tag[destrank] ; + } + + // Returns the last MPITag of the source rank sourcerank + inline int MPIAccess::recvMPITag(int sourcerank) + { + return _recv_MPI_Tag[sourcerank] ; + } + + // Returns the number of all SendRequestIds matching a destination rank. It may be + // used to allocate ArrayOfSendRequests for the call to SendRequestIds + inline int MPIAccess::sendRequestIdsSize(int destrank) + { + return _send_requests[destrank].size() ; + } + + // Returns the number of all RecvRequestIds matching a source rank. It may be + // used to allocate ArrayOfRecvRequests for the call to RecvRequestIds + inline int MPIAccess::recvRequestIdsSize(int sourcerank) + { + return _recv_requests[sourcerank].size() ; + } + + // Returns the MPI_Datatype (registered in MPI in the constructor with + // MPI_Type_struct and MPI_Type_commit) for TimeMessages + inline MPI_Datatype MPIAccess::timeType() const + { + return _MPI_TIME ; + } + + // Returns true if the tag MPITag corresponds to a TimeMessage + inline bool MPIAccess::isTimeMessage( int MPITag ) const + { + return ((MPITag%MODULO_TAG) == _message_time) ; + } + + // Returns the MPI size of a TimeMessage + inline MPI_Aint MPIAccess::timeExtent() const + { + MPI_Aint extent ; + MPI_Type_extent( _MPI_TIME , &extent ) ; + return extent ; + } + + // Returns the MPI size of a MPI_INT + inline MPI_Aint MPIAccess::intExtent() const + { + MPI_Aint extent ; + MPI_Type_extent( MPI_INT , &extent ) ; + return extent ; + } + + // Returns the MPI size of a MPI_DOUBLE + inline MPI_Aint MPIAccess::doubleExtent() const + { + MPI_Aint extent ; + MPI_Type_extent( MPI_DOUBLE , &extent ) ; + return extent ; + } + + // Returns the MPI size of the MPI_Datatype datatype + inline MPI_Aint MPIAccess::extent( MPI_Datatype datatype ) const + { + if ( datatype == _MPI_TIME ) + return timeExtent() ; + if ( datatype == MPI_INT ) + return intExtent() ; + if ( datatype == MPI_DOUBLE ) + return doubleExtent() ; + return 0 ; + } + + // Returns the MPITag of the request corresponding to RequestId identifier + inline int MPIAccess::MPITag( int RequestId ) + { + struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; + if ( aRequestStruct ) + return aRequestStruct->MPITag ; + return -1 ; + } + + // Returns the MPITarget of the request corresponding to RequestId identifier + inline int MPIAccess::MPITarget( int RequestId ) + { + struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; + if ( aRequestStruct ) + return aRequestStruct->MPITarget ; + return -1 ; + } + + // Returns true if the request corresponding to RequestId identifier was [I]Recv + inline bool MPIAccess::MPIIsRecv( int RequestId ) + { + struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; + if ( aRequestStruct ) + return aRequestStruct->MPIIsRecv ; + return false ; + } + + // Returns true if the request corresponding to RequestId identifier was asynchronous + inline bool MPIAccess::MPIAsynchronous( int RequestId ) + { + struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; + if ( aRequestStruct ) + return aRequestStruct->MPIAsynchronous ; + return false ; + } + + // Returns true if the request corresponding to RequestId identifier was completed + inline bool MPIAccess::MPICompleted( int RequestId ) + { + struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; + if ( aRequestStruct ) + return aRequestStruct->MPICompleted; + return true ; + } + + // Returns the MPI_datatype of the request corresponding to RequestId identifier + inline MPI_Datatype MPIAccess::MPIDatatype( int RequestId ) + { + struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; + if ( aRequestStruct ) + return aRequestStruct->MPIDatatype; + return (MPI_Datatype ) NULL ; + } + + // Returns the size of the receiving message of the request corresponding to + // RequestId identifier + inline int MPIAccess::MPIOutCount( int RequestId ) + { + struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; + if ( aRequestStruct ) + return aRequestStruct->MPIOutCount; + return 0 ; + } + + // Increments the previous tag value (cyclically) + // Look at MPIAccess::NewSendTag/NewRecvTag in MPIAccess.cxx + inline int MPIAccess::incrTag( int prevtag ) + { + int tag; + if ( (prevtag % MODULO_TAG) == _message_time ) + tag = ((prevtag/MODULO_TAG)*MODULO_TAG); + else + tag = ((prevtag/MODULO_TAG + 1)*MODULO_TAG); + if ( tag > _max_MPI_tag ) + tag = _base_MPI_tag ; + return tag ; + } + + // Returns the MPITag with the method-type field + // Look at MPIAccess::NewSendTag/NewRecvTag in MPIAccess.cxx + inline int MPIAccess::valTag( int tag, int method ) + { + return ((tag/MODULO_TAG)*MODULO_TAG) + method; + } + + // Remove a Request identifier from the list _RecvRequests/_SendRequests for + // the corresponding target. + inline void MPIAccess::deleteSendRecvRequest( int RequestId ) + { + if ( _trace ) + std::cout << "MPIAccess::DeleteSendRecvRequest" << _my_rank + << "( " << RequestId << " ) " << std::endl ; + if ( MPIIsRecv( RequestId ) ) + _recv_requests[ MPITarget( RequestId ) ].remove( RequestId ); + else + _send_requests[ MPITarget( RequestId ) ].remove( RequestId ); + } + + // Delete the MPI structure MPI_status * of a ReaquestId + inline void MPIAccess::deleteStatus( int RequestId ) + { + if ( _map_of_request_struct[RequestId]->MPIStatus != NULL ) + { + delete _map_of_request_struct[RequestId]->MPIStatus ; + clearMPIStatus( RequestId ) ; + } + } + + // Returns the MPI structure MPI_request * of a RequestId + inline MPI_Request * MPIAccess::MPIRequest( int RequestId ) + { + struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; + if ( aRequestStruct ) + return &aRequestStruct->MPIRequest; + return &mpirequestnull ; + } + + // Returns the MPI structure MPI_status * of a RequestId + inline MPI_Status * MPIAccess::MPIStatus( int RequestId ) + { + struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ]; + if ( aRequestStruct ) + return aRequestStruct->MPIStatus; + return NULL ; + } + + // Set the MPICompleted field of the structure Request corresponding to RequestId + // identifier with the value completed + inline void MPIAccess::setMPICompleted( int RequestId , bool completed ) + { + struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; + if ( aRequestStruct ) + aRequestStruct->MPICompleted = completed; + } + + // Set the MPIOutCount field of the structure Request corresponding to RequestId + // identifier with the value outcount + inline void MPIAccess::setMPIOutCount( int RequestId , int outcount ) + { + struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; + if ( aRequestStruct ) + aRequestStruct->MPIOutCount = outcount; + } + + // Nullify the MPIStatusfield of the structure Request corresponding to RequestId + // identifier + inline void MPIAccess::clearMPIStatus( int RequestId ) + { + struct RequestStruct *aRequestStruct = _map_of_request_struct[ RequestId ] ; + if ( aRequestStruct ) + aRequestStruct->MPIStatus = NULL ; + } + + // Returns the _MessageIdent enum value corresponding to the MPI_Datatype datatype + // Look at MPIAccess::NewSendTag/NewRecvTag in MPIAccess.cxx + inline _MessageIdent MPIAccess::methodId( MPI_Datatype datatype ) const + { + _MessageIdent aMethodIdent ; + if ( datatype == _MPI_TIME ) + aMethodIdent = _message_time; + else if ( datatype == MPI_INT ) + aMethodIdent = _message_int ; + else if ( datatype == MPI_DOUBLE ) + aMethodIdent = _message_double ; + else + aMethodIdent = _message_unknown ; + return aMethodIdent ; + } + + // Returns the MPI_Datatype corresponding to the _MessageIdent enum aMethodIdent + inline MPI_Datatype MPIAccess::datatype( _MessageIdent aMethodIdent ) const + { + MPI_Datatype aDataType ; + switch( aMethodIdent ) + { + case _message_time : + aDataType = _MPI_TIME ; + break ; + case _message_int : + aDataType = MPI_INT ; + break ; + case _message_double : + aDataType = MPI_DOUBLE ; + break ; + default : + aDataType = (MPI_Datatype) -1 ; + break ; + } + return aDataType ; + } + + std::ostream & operator<< (std::ostream &,const _MessageIdent &); + + std::ostream & operator<< (std::ostream &,const TimeMessage &); + +} + +#endif diff --git a/src/ParaMEDMEM/MPIAccessDEC.cxx b/src/ParaMEDMEM/MPIAccessDEC.cxx new file mode 100644 index 000000000..d05698790 --- /dev/null +++ b/src/ParaMEDMEM/MPIAccessDEC.cxx @@ -0,0 +1,1061 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// + +#include "MPIAccessDEC.hxx" + +using namespace std; + +namespace ParaMEDMEM +{ + + /*! + This constructor creates an MPIAccessDEC which has \a source_group as a working side + and \a target_group as an idle side. + The constructor must be called synchronously on all processors of both processor groups. + + \param source_group working side ProcessorGroup + \param target_group lazy side ProcessorGroup + \param Asynchronous Communication mode (default asynchronous) + \param nStepBefore Number of Time step needed for the interpolation before current time + \param nStepAfter Number of Time step needed for the interpolation after current time + + */ + + MPIAccessDEC::MPIAccessDEC( const ProcessorGroup& source_group, + const ProcessorGroup& target_group, + bool Asynchronous ) + { + + ProcessorGroup * union_group = source_group.fuse(target_group) ; + int i ; + std::set<int> procs; + for ( i = 0 ; i < union_group->size() ; i++ ) + { + procs.insert(i) ; + } + MPIProcessorGroup *mpilg = (MPIProcessorGroup *)&source_group; + _MPI_union_group = new ParaMEDMEM::MPIProcessorGroup( union_group->getCommInterface(),procs,mpilg->getWorldComm()); + delete union_group ; + _my_rank = _MPI_union_group->myRank() ; + _group_size = _MPI_union_group->size() ; + _MPI_access = new MPIAccess( _MPI_union_group ) ; + _asynchronous = Asynchronous ; + _time_messages = new vector< vector< TimeMessage > > ; + _time_messages->resize( _group_size ) ; + _out_of_time = new vector< bool > ; + _out_of_time->resize( _group_size ) ; + _data_messages_recv_count = new vector< int > ; + _data_messages_recv_count->resize( _group_size ) ; + for ( i = 0 ; i < _group_size ; i++ ) + { + (*_out_of_time)[i] = false ; + (*_data_messages_recv_count)[i] = 0 ; + } + _data_messages_type = new vector< MPI_Datatype > ; + _data_messages_type->resize( _group_size ) ; + _data_messages = new vector< vector< void * > > ; + _data_messages->resize( _group_size ) ; + _time_interpolator = NULL ; + _map_of_send_buffers = new map< int , SendBuffStruct * > ; + cout << "MPIAccessDEC" << _my_rank << " Asynchronous " << _asynchronous << endl ; + } + + MPIAccessDEC::~MPIAccessDEC() + { + checkFinalSent() ; + checkFinalRecv() ; + delete _MPI_union_group ; + delete _MPI_access ; + if ( _time_interpolator ) + delete _time_interpolator ; + if ( _time_messages ) + delete _time_messages ; + if ( _out_of_time ) + delete _out_of_time ; + if ( _data_messages_recv_count ) + delete _data_messages_recv_count ; + if ( _data_messages_type ) + delete _data_messages_type ; + if ( _data_messages ) + delete _data_messages ; + if ( _map_of_send_buffers ) + delete _map_of_send_buffers ; + } + + void MPIAccessDEC::setTimeInterpolator( TimeInterpolationMethod aTimeInterp , + double InterpPrecision, int nStepBefore, + int nStepAfter ) + { + cout << "MPIAccessDEC::SetTimeInterpolator" << _my_rank << " Asynchronous " + << _asynchronous << " TimeInterpolationMethod " << aTimeInterp + << " InterpPrecision " << InterpPrecision << " nStepBefore " << nStepBefore + << " nStepAfter " << nStepAfter << endl ; + if ( _time_interpolator ) + delete _time_interpolator ; + switch ( aTimeInterp ) + { + case WithoutTimeInterp : + _time_interpolator = NULL ; + _n_step_before = 0 ; + _n_step_after = 0 ; + break ; + case LinearTimeInterp : + _time_interpolator = new LinearTimeInterpolator( InterpPrecision , nStepBefore , + nStepAfter ) ; + _n_step_before = nStepBefore ; + _n_step_after = nStepAfter ; + int i ; + for ( i = 0 ; i < _group_size ; i++ ) + { + (*_time_messages)[ i ].resize( _n_step_before + _n_step_after ) ; + (*_data_messages)[ i ].resize( _n_step_before + _n_step_after ) ; + int j ; + for ( j = 0 ; j < _n_step_before + _n_step_after ; j++ ) + { + (*_time_messages)[ i ][ j ].time = -1 ; + (*_time_messages)[ i ][ j ].deltatime = -1 ; + (*_data_messages)[ i ][ j ] = NULL ; + } + } + break ; + } + } + + /*! + Send sendcount datas from sendbuf[offset] with type sendtype to target of IntraCommunicator + (Internal Protected method) + + Returns the request identifier SendRequestId + + */ + int MPIAccessDEC::send( void* sendbuf, int sendcount , int offset , + MPI_Datatype sendtype , int target , int &SendRequestId ) + { + int sts ; + if ( _asynchronous ) + { + if ( sendtype == MPI_INT ) + { + sts = _MPI_access->ISend( &((int *) sendbuf)[offset] , sendcount , sendtype , + target , SendRequestId ) ; + } + else + { + sts = _MPI_access->ISend( &((double *) sendbuf)[offset] , sendcount , sendtype , + target , SendRequestId ) ; + } + } + else + { + if ( sendtype == MPI_INT ) + { + sts = _MPI_access->send( &((int *) sendbuf)[offset] , sendcount , sendtype , + target , SendRequestId ) ; + } + else + { + sts = _MPI_access->send( &((double *) sendbuf)[offset] , sendcount , sendtype , + target , SendRequestId ) ; + } + } + return sts ; + } + + /*! + Receive recvcount datas to recvbuf[offset] with type recvtype from target of IntraCommunicator + (Internal Protected method) + + Returns the request identifier RecvRequestId + + */ + int MPIAccessDEC::recv( void* recvbuf, int recvcount , int offset , + MPI_Datatype recvtype , int target , int &RecvRequestId ) + { + int sts ; + if ( _asynchronous ) + { + if ( recvtype == MPI_INT ) + { + sts = _MPI_access->IRecv( &((int *) recvbuf)[offset] , recvcount , recvtype , + target , RecvRequestId ) ; + } + else + { + sts = _MPI_access->IRecv( &((double *) recvbuf)[offset] , recvcount , recvtype , + target , RecvRequestId ) ; + } + } + else + { + if ( recvtype == MPI_INT ) + { + sts = _MPI_access->recv( &((int *) recvbuf)[offset] , recvcount , recvtype , + target , RecvRequestId ) ; + } + else + { + sts = _MPI_access->recv( &((double *) recvbuf)[offset] , recvcount , recvtype , + target , RecvRequestId ) ; + } + } + return sts ; + } + + /*! + Send sendcount datas from sendbuf[offset] with type sendtype to target of IntraCommunicator + Receive recvcount datas to recvbuf[offset] with type recvtype from target of IntraCommunicator + (Internal Protected method) + + Returns the request identifier SendRequestId + Returns the request identifier RecvRequestId + + */ + int MPIAccessDEC::sendRecv( void* sendbuf, int sendcount , int sendoffset , + MPI_Datatype sendtype , + void* recvbuf, int recvcount , int recvoffset , + MPI_Datatype recvtype , int target , + int &SendRequestId , int &RecvRequestId ) + { + int sts ; + if ( _asynchronous ) + { + if ( sendtype == MPI_INT ) + { + if ( recvtype == MPI_INT ) + { + sts = _MPI_access->ISendRecv( &((int *) sendbuf)[sendoffset] , sendcount , + sendtype , target , SendRequestId , + &((int *) recvbuf)[recvoffset] , recvcount , + recvtype , target , RecvRequestId ) ; + } + else + { + sts = _MPI_access->ISendRecv( &((int *) sendbuf)[sendoffset] , sendcount , + sendtype , target , SendRequestId , + &((double *) recvbuf)[recvoffset] , + recvcount , recvtype , target , RecvRequestId ) ; + } + } + else + { + if ( recvtype == MPI_INT ) + { + sts = _MPI_access->ISendRecv( &((double *) sendbuf)[sendoffset] , sendcount , + sendtype , target , SendRequestId , + &((int *) recvbuf)[recvoffset] , + recvcount , recvtype , target , RecvRequestId ) ; + } + else + { + sts = _MPI_access->ISendRecv( &((double *) sendbuf)[sendoffset] , sendcount , + sendtype , target , SendRequestId , + &((double *) recvbuf)[recvoffset] , + recvcount , recvtype , target , RecvRequestId ) ; + } + } + } + else + { + if ( sendtype == MPI_INT ) + { + if ( recvtype == MPI_INT ) + { + sts = _MPI_access->sendRecv( &((int *) sendbuf)[sendoffset] , sendcount , + sendtype , target , SendRequestId , + &((int *) recvbuf)[recvoffset] , recvcount , + recvtype , target , RecvRequestId ) ; + } + else + { + sts = _MPI_access->sendRecv( &((int *) sendbuf)[sendoffset] , sendcount , + sendtype , target , SendRequestId , + &((double *) recvbuf)[recvoffset] , + recvcount , recvtype , target , RecvRequestId ) ; + } + } + else + { + if ( recvtype == MPI_INT ) + { + sts = _MPI_access->sendRecv( &((double *) sendbuf)[sendoffset] , sendcount , + sendtype , target , SendRequestId , + &((int *) recvbuf)[recvoffset] , + recvcount , recvtype , target , RecvRequestId ) ; + } + else + { + cout << "SendRecv" << _my_rank << " target " << target << " sendbuf " + << &((double *) sendbuf)[sendoffset] << " sendcount " << sendcount + << " recvbuf " << &((double *) recvbuf)[recvoffset] << " recvcount " + << recvcount << endl ; + sts = _MPI_access->sendRecv( &((double *) sendbuf)[sendoffset] , sendcount , + sendtype , target , SendRequestId , + &((double *) recvbuf)[recvoffset] , + recvcount , recvtype , target , RecvRequestId ) ; + } + } + } + return sts ; + } + + /*! + Send sendcount datas from sendbuf[offset] with type sendtype to all targets of IntraCommunicator + Receive recvcount datas to recvbuf[offset] with type recvtype from all targets of IntraCommunicator + + */ + int MPIAccessDEC::allToAll( void* sendbuf, int sendcount, MPI_Datatype sendtype , + void* recvbuf, int recvcount, MPI_Datatype recvtype ) + { + if ( _time_interpolator ) + { + return allToAllTime( sendbuf, sendcount, sendtype , recvbuf, recvcount, recvtype ) ; + } + int sts ; + int target ; + int sendoffset = 0 ; + int recvoffset = 0 ; + int SendRequestId ; + int RecvRequestId ; + + //Free of SendBuffers + if ( _asynchronous ) + checkSent() ; + + //DoSend + DoRecv : SendRecv + SendBuffStruct * aSendDataStruct = NULL ; + if ( _asynchronous && sendbuf ) + { + aSendDataStruct = new SendBuffStruct ; + aSendDataStruct->SendBuffer = sendbuf ; + aSendDataStruct->Counter = 0 ; + aSendDataStruct->DataType = sendtype ; + } + for ( target = 0 ; target < _group_size ; target++ ) + { + sts = sendRecv( sendbuf , sendcount , sendoffset , sendtype , + recvbuf , recvcount , recvoffset , recvtype , + target , SendRequestId , RecvRequestId ) ; + if ( _asynchronous && sendbuf && sendcount ) + { + aSendDataStruct->Counter += 1 ; + (*_map_of_send_buffers)[ SendRequestId ] = aSendDataStruct ; + } + sendoffset += sendcount ; + recvoffset += recvcount ; + } + if ( !_asynchronous && sendbuf ) + { + if ( sendtype == MPI_INT ) + { + delete [] (int *) sendbuf ; + } + else + { + delete [] (double *) sendbuf ; + } + } + return sts ; + } + + /*! + Send sendcounts[target] datas from sendbuf[sdispls[target]] with type sendtype to all targets of IntraCommunicator + Receive recvcounts[target] datas to recvbuf[rdispls[target]] with type recvtype from all targets of IntraCommunicator + + */ + int MPIAccessDEC::allToAllv( void* sendbuf, int* sendcounts, int* sdispls, + MPI_Datatype sendtype , + void* recvbuf, int* recvcounts, int* rdispls, + MPI_Datatype recvtype ) + { + if ( _time_interpolator ) + { + return allToAllvTime( sendbuf, sendcounts, sdispls, sendtype , + recvbuf, recvcounts, rdispls, recvtype ) ; + } + int sts ; + int target ; + int SendRequestId ; + int RecvRequestId ; + + //Free of SendBuffers + if ( _asynchronous ) + { + checkSent() ; + } + + //DoSend + DoRecv : SendRecv + SendBuffStruct * aSendDataStruct = NULL ; + if ( _asynchronous && sendbuf ) + { + aSendDataStruct = new SendBuffStruct ; + aSendDataStruct->SendBuffer = sendbuf ; + aSendDataStruct->Counter = 0 ; + aSendDataStruct->DataType = sendtype ; + } + for ( target = 0 ; target < _group_size ; target++ ) + { + if ( sendcounts[target] || recvcounts[target] ) + { + sts = sendRecv( sendbuf , sendcounts[target] , sdispls[target] , sendtype , + recvbuf , recvcounts[target] , rdispls[target] , recvtype , + target , SendRequestId , RecvRequestId ) ; + if ( _asynchronous && sendbuf && sendcounts[target]) + { + aSendDataStruct->Counter += 1 ; + (*_map_of_send_buffers)[ SendRequestId ] = aSendDataStruct ; + } + } + } + if ( !_asynchronous && sendbuf ) + { + if ( sendtype == MPI_INT ) + { + delete [] (int *) sendbuf ; + } + else + { + delete [] (double *) sendbuf ; + } + } + return sts ; + } + + /* + MPIAccessDEC and the management of SendBuffers : + ================================================= + + . In the collective communications collectives we send only parts of + the same buffer to each "target". So in asynchronous mode it is + necessary that all parts are free before to delete/free the + buffer. + + . We assume that buffers are allocated with a new double[]. so a + delete [] is done. + + . The structure SendBuffStruct permit to keep the adress of the buffer + and to manage a reference counter of that buffer. It contains + also MPI_Datatype for the delete [] (double *) ... when the counter + is null. + + . The map _MapOfSendBuffers etablish the correspondance between each + RequestId given by a MPI_Access->ISend(...) and a SendBuffStruct + for each "target" of a part of the buffer. + + . All that concerns only asynchronous Send. In synchronous mode, + we delete senbuf just after the Send. + */ + + /* + MPIAccessDEC and the management of RecvBuffers : + ================================================= + + If there is no interpolation, no special action is done. + + With interpolation for each target : + ------------------------------------ + . We have _time_messages[target] which is a vector of TimesMessages. + We have 2 TimesMessages in our case with a linear interpolation. + They contain the previous time(t0)/deltatime and the last + time(t1)/deltatime. + + . We have _data_messages[target] which is a vector of DatasMessages. + We have 2 DatasMessages in our case with a linear interpolation. + They contain the previous datas at time(t0)/deltatime and at last + time(t1)/deltatime. + + . At time _t(t*) of current processus we do the interpolation of + the values of the 2 DatasMessages which are returned in the part of + recvbuf corresponding to the target with t0 < t* <= t1. + + . Because of the difference of "deltatimes" between processes, we + may have t0 < t1 < t* and there is an extrapolation. + + . The vectors _out_of_time, _DataMessagesRecvCount and _DataMessagesType + contain for each target true if t* > last t1, recvcount and + MPI_Datatype for the finalize of messages at the end. + */ + + /*! + Send a TimeMessage to all targets of IntraCommunicator + Receive the TimeMessages from targets of IntraCommunicator if necessary. + + Send sendcount datas from sendbuf[offset] with type sendtype to all targets of IntraCommunicator + Returns recvcount datas to recvbuf[offset] with type recvtype after an interpolation + with datas received from all targets of IntraCommunicator. + + */ + int MPIAccessDEC::allToAllTime( void* sendbuf, int sendcount , MPI_Datatype sendtype , + void* recvbuf, int recvcount , MPI_Datatype recvtype ) + { + int sts ; + int target ; + int sendoffset = 0 ; + int SendTimeRequestId ; + int SendDataRequestId ; + + if ( _time_interpolator == NULL ) + { + return MPI_ERR_OTHER ; + } + + //Free of SendBuffers + if ( _asynchronous ) + { + checkSent() ; + } + + //DoSend : Time + SendBuff + SendBuffStruct * aSendTimeStruct = NULL ; + SendBuffStruct * aSendDataStruct = NULL ; + if ( sendbuf && sendcount ) + { + TimeMessage * aSendTimeMessage = new TimeMessage ; + if ( _asynchronous ) + { + aSendTimeStruct = new SendBuffStruct ; + aSendTimeStruct->SendBuffer = aSendTimeMessage ; + aSendTimeStruct->Counter = 0 ; + aSendTimeStruct->DataType = _MPI_access->timeType() ; + aSendDataStruct = new SendBuffStruct ; + aSendDataStruct->SendBuffer = sendbuf ; + aSendDataStruct->Counter = 0 ; + aSendDataStruct->DataType = sendtype ; + } + aSendTimeMessage->time = _t ; + aSendTimeMessage->deltatime = _dt ; + for ( target = 0 ; target < _group_size ; target++ ) + { + sts = send( aSendTimeMessage , 1 , 0 , _MPI_access->timeType() , target , + SendTimeRequestId ) ; + sts = send( sendbuf , sendcount , sendoffset , sendtype , target , SendDataRequestId ) ; + if ( _asynchronous ) + { + aSendTimeStruct->Counter += 1 ; + (*_map_of_send_buffers)[ SendTimeRequestId ] = aSendTimeStruct ; + aSendDataStruct->Counter += 1 ; + (*_map_of_send_buffers)[ SendDataRequestId ] = aSendDataStruct ; + } + sendoffset += sendcount ; + } + if ( !_asynchronous ) + { + delete aSendTimeMessage ; + if ( sendtype == MPI_INT ) + { + delete [] (int *) sendbuf ; + } + else + { + delete [] (double *) sendbuf ; + } + } + } + + //CheckTime + DoRecv + DoInterp + if ( recvbuf && recvcount ) + { + for ( target = 0 ; target < _group_size ; target++ ) + { + int recvsize = recvcount*_MPI_access->extent( recvtype ) ; + checkTime( recvcount , recvtype , target , false ) ; + //=========================================================================== + //TODO : it is assumed actually that we have only 1 timestep before nad after + //=========================================================================== + if ( _time_interpolator && (*_time_messages)[target][0].time != -1 ) + { + if ( (*_out_of_time)[target] ) + { + cout << " =====================================================" << endl + << "Recv" << _my_rank << " <-- target " << target << " t0 " + << (*_time_messages)[target][0].time << " < t1 " + << (*_time_messages)[target][1].time << " < t* " << _t << endl + << " =====================================================" << endl ; + } + if ( recvtype == MPI_INT ) + { + _time_interpolator->doInterp( (*_time_messages)[target][0].time, + (*_time_messages)[target][1].time, _t, recvcount , + _n_step_before, _n_step_after, + (int **) &(*_data_messages)[target][0], + (int **) &(*_data_messages)[target][1], + &((int *)recvbuf)[target*recvcount] ) ; + } + else + { + _time_interpolator->doInterp( (*_time_messages)[target][0].time, + (*_time_messages)[target][1].time, _t, recvcount , + _n_step_before, _n_step_after, + (double **) &(*_data_messages)[target][0], + (double **) &(*_data_messages)[target][1], + &((double *)recvbuf)[target*recvcount] ) ; + } + } + else + { + char * buffdest = (char *) recvbuf ; + char * buffsrc = (char *) (*_data_messages)[target][1] ; + memcpy( &buffdest[target*recvsize] , buffsrc , recvsize ) ; + } + } + } + + return sts ; + } + + int MPIAccessDEC::allToAllvTime( void* sendbuf, int* sendcounts, int* sdispls, + MPI_Datatype sendtype , + void* recvbuf, int* recvcounts, int* rdispls, + MPI_Datatype recvtype ) + { + int sts ; + int target ; + int SendTimeRequestId ; + int SendDataRequestId ; + + if ( _time_interpolator == NULL ) + { + return MPI_ERR_OTHER ; + } + + //Free of SendBuffers + if ( _asynchronous ) + { + checkSent() ; + } + + /* + . DoSend : + + We create a TimeMessage (look at that structure in MPI_Access). + + If we are in asynchronous mode, we create two structures SendBuffStruct + aSendTimeStruct and aSendDataStruct that we fill. + + We fill the structure aSendTimeMessage with time/deltatime of + the current process. "deltatime" must be nul if it is the last step of + Time. + + After that for each "target", we Send the TimeMessage and the part + of sendbuf corresponding to that target. + + If we are in asynchronous mode, we increment the counter and we add + aSendTimeStruct and aSendDataStruct to _MapOfSendBuffers with the + identifiers SendTimeRequestId and SendDataRequestId returned by + MPI_Access->Send(...). + + And if we are in synchronous mode we delete the SendMessages. + */ + //DoSend : Time + SendBuff + SendBuffStruct * aSendTimeStruct = NULL ; + SendBuffStruct * aSendDataStruct = NULL ; + if ( sendbuf ) + { + TimeMessage * aSendTimeMessage = new TimeMessage ; + if ( _asynchronous ) + { + aSendTimeStruct = new SendBuffStruct ; + aSendTimeStruct->SendBuffer = aSendTimeMessage ; + aSendTimeStruct->Counter = 0 ; + aSendTimeStruct->DataType = _MPI_access->timeType() ; + aSendDataStruct = new SendBuffStruct ; + aSendDataStruct->SendBuffer = sendbuf ; + aSendDataStruct->Counter = 0 ; + aSendDataStruct->DataType = sendtype ; + } + aSendTimeMessage->time = _t ; + aSendTimeMessage->deltatime = _dt ; + for ( target = 0 ; target < _group_size ; target++ ) + { + if ( sendcounts[target] ) + { + sts = send( aSendTimeMessage , 1 , 0 , _MPI_access->timeType() , target , + SendTimeRequestId ) ; + sts = send( sendbuf , sendcounts[target] , sdispls[target] , sendtype , target , + SendDataRequestId ) ; + if ( _asynchronous ) + { + aSendTimeStruct->Counter += 1 ; + (*_map_of_send_buffers)[ SendTimeRequestId ] = aSendTimeStruct ; + aSendDataStruct->Counter += 1 ; + (*_map_of_send_buffers)[ SendDataRequestId ] = aSendDataStruct ; + } + } + } + if ( !_asynchronous ) + { + delete aSendTimeMessage ; + if ( sendtype == MPI_INT ) + { + delete [] (int *) sendbuf ; + } + else + { + delete [] (double *) sendbuf ; + } + } + } + + /* + . CheckTime + DoRecv + DoInterp + + For each target we call CheckTime + + If there is a TimeInterpolator and if the TimeMessage of the target + is not the first, we call the interpolator which return its + results in the part of the recv buffer corresponding to the "target". + + If not, there is a copy of received datas for that first step of time + in the part of the recv buffer corresponding to the "target". + */ + //CheckTime + DoRecv + DoInterp + if ( recvbuf ) + { + for ( target = 0 ; target < _group_size ; target++ ) + { + if ( recvcounts[target] ) + { + int recvsize = recvcounts[target]*_MPI_access->extent( recvtype ) ; + checkTime( recvcounts[target] , recvtype , target , false ) ; + //=========================================================================== + //TODO : it is assumed actually that we have only 1 timestep before nad after + //=========================================================================== + if ( _time_interpolator && (*_time_messages)[target][0].time != -1 ) + { + if ( (*_out_of_time)[target] ) + { + cout << " =====================================================" << endl + << "Recv" << _my_rank << " <-- target " << target << " t0 " + << (*_time_messages)[target][0].time << " < t1 " + << (*_time_messages)[target][1].time << " < t* " << _t << endl + << " =====================================================" << endl ; + } + if ( recvtype == MPI_INT ) + { + _time_interpolator->doInterp( (*_time_messages)[target][0].time, + (*_time_messages)[target][1].time, _t, + recvcounts[target] , _n_step_before, _n_step_after, + (int **) &(*_data_messages)[target][0], + (int **) &(*_data_messages)[target][1], + &((int *)recvbuf)[rdispls[target]] ) ; + } + else + { + _time_interpolator->doInterp( (*_time_messages)[target][0].time, + (*_time_messages)[target][1].time, _t, + recvcounts[target] , _n_step_before, _n_step_after, + (double **) &(*_data_messages)[target][0], + (double **) &(*_data_messages)[target][1], + &((double *)recvbuf)[rdispls[target]] ) ; + } + } + else + { + char * buffdest = (char *) recvbuf ; + char * buffsrc = (char *) (*_data_messages)[target][1] ; + memcpy( &buffdest[rdispls[target]*_MPI_access->extent( recvtype )] , buffsrc , + recvsize ) ; + } + } + } + } + + return sts ; + } + + /* + . CheckTime(recvcount , recvtype , target , UntilEnd) + + At the beginning, we read the first TimeMessage in + &(*_TimeMessages)[target][1] and the first DataMessage + in the allocated buffer (*_DataMessages)[target][1]. + + deltatime of TimesMessages must be nul if it is the last one. + + While : _t(t*) is the current time of the processus. + "while _t(t*) is greater than the time of the "target" + (*_TimeMessages)[target][1].time and + (*_TimeMessages)[target][1].deltatime is not nul", + So at the end of the while we have : + _t(t*) <= (*_TimeMessages)[target][1].time with + _t(t*) > (*_TimeMessages)[target][0].time + or we have the last TimeMessage of the "target". + + If it is the finalization of the recv of TimeMessages and + DataMessages (UntilEnd value is true), we execute the while + until (*_TimeMessages)[target][1].deltatime is nul. + + In the while : + We copy the last TimeMessage in the previoud TimeMessage and + we read a new TimeMessage + We delete the previous DataMessage. + We copy the last DataMessage pointer in the previous one. + We allocate a new last DataMessage buffer + (*_DataMessages)[target][1] and we read the corresponding + datas in that buffe. + + If the current time of the current process is greater than the + last time (*_TimeMessages)[target][1].time du target, we give + a true value to (*_OutOfTime)[target]. + (*_TimeMessages)[target][1].deltatime is nul. + */ + int MPIAccessDEC::checkTime( int recvcount , MPI_Datatype recvtype , int target , + bool UntilEnd ) + { + int sts = MPI_SUCCESS ; + int RecvTimeRequestId ; + int RecvDataRequestId ; + //Pour l'instant on cherche _time_messages[target][0] < _t <= _time_messages[target][1] + //=========================================================================== + //TODO : it is assumed actually that we have only 1 timestep before and after + // instead of _n_step_before and _n_step_after ... + //=========================================================================== + (*_data_messages_recv_count)[target] = recvcount ; + (*_data_messages_type)[target] = recvtype ; + if ( (*_time_messages)[target][1].time == -1 ) + { + (*_time_messages)[target][0] = (*_time_messages)[target][1] ; + sts = recv( &(*_time_messages)[target][1] , 1 , _MPI_access->timeType() , + target , RecvTimeRequestId ) ; + (*_data_messages)[target][0] = (*_data_messages)[target][1] ; + if ( recvtype == MPI_INT ) + { + (*_data_messages)[target][1] = new int[recvcount] ; + } + else + { + (*_data_messages)[target][1] = new double[recvcount] ; + } + sts = recv( (*_data_messages)[target][1] , recvcount , recvtype , target , + RecvDataRequestId ) ; + } + else + { + while ( ( _t > (*_time_messages)[target][1].time || UntilEnd ) && + (*_time_messages)[target][1].deltatime != 0 ) + { + (*_time_messages)[target][0] = (*_time_messages)[target][1] ; + sts = recv( &(*_time_messages)[target][1] , 1 , _MPI_access->timeType() , + target , RecvTimeRequestId ) ; + if ( UntilEnd ) + { + cout << "CheckTime" << _my_rank << " TimeMessage target " << target + << " RecvTimeRequestId " << RecvTimeRequestId << " MPITag " + << _MPI_access->recvMPITag(target) << endl ; + } + if ( recvtype == MPI_INT ) + { + delete [] (int *) (*_data_messages)[target][0] ; + } + else + { + delete [] (double *) (*_data_messages)[target][0] ; + } + (*_data_messages)[target][0] = (*_data_messages)[target][1] ; + if ( recvtype == MPI_INT ) + { + (*_data_messages)[target][1] = new int[recvcount] ; + } + else + { + (*_data_messages)[target][1] = new double[recvcount] ; + } + sts = recv( (*_data_messages)[target][1] , recvcount , recvtype , target , + RecvDataRequestId ) ; + if ( UntilEnd ) + { + cout << "CheckTime" << _my_rank << " DataMessage target " << target + << " RecvDataRequestId " << RecvDataRequestId << " MPITag " + << _MPI_access->recvMPITag(target) << endl ; + } + } + + if ( _t > (*_time_messages)[target][0].time && + _t <= (*_time_messages)[target][1].time ) + { + } + else + { + (*_out_of_time)[target] = true ; + } + } + return sts ; + } + + /* + . CheckSent() : + + call SendRequestIds of MPI_Access in order to get all + RequestIds of SendMessages of all "targets". + + For each RequestId, CheckSent call "Test" of MPI_Access in order + to know if the buffer is "free" (flag = true). If it is the + FinalCheckSent (WithWait = true), we call Wait instead of Test. + + If the buffer is "free", the counter of the structure SendBuffStruct + (from _MapOfSendBuffers) is decremented. + + If that counter is nul we delete the TimeMessage or the + SendBuffer according to the DataType. + + And we delete the structure SendBuffStruct before the suppression + (erase) of that item of _MapOfSendBuffers + */ + int MPIAccessDEC::checkSent(bool WithWait) + { + int sts = MPI_SUCCESS ; + int flag = WithWait ; + int size = _MPI_access->sendRequestIdsSize() ; + int * ArrayOfSendRequests = new int[ size ] ; + int nSendRequest = _MPI_access->sendRequestIds( size , ArrayOfSendRequests ) ; + bool SendTrace = false ; + int i ; + for ( i = 0 ; i < nSendRequest ; i++ ) + { + if ( WithWait ) + { + cout << "CheckSent" << _my_rank << " " << i << "./" << nSendRequest + << " SendRequestId " << ArrayOfSendRequests[i] << " MPITarget " + << _MPI_access->MPITarget(ArrayOfSendRequests[i]) << " MPITag " + << _MPI_access->MPITag(ArrayOfSendRequests[i]) << " Wait :" << endl ; + sts = _MPI_access->wait( ArrayOfSendRequests[i] ) ; + } + else + { + sts = _MPI_access->test( ArrayOfSendRequests[i] , flag ) ; + } + if ( flag ) + { + _MPI_access->deleteRequest( ArrayOfSendRequests[i] ) ; + if ( SendTrace ) + { + cout << "CheckSent" << _my_rank << " " << i << "./" << nSendRequest + << " SendRequestId " << ArrayOfSendRequests[i] + << " flag " << flag + << " Counter " << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->Counter + << " DataType " << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->DataType + << endl ; + } + (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->Counter -= 1 ; + if ( SendTrace ) + { + if ( (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->DataType == + _MPI_access->timeType() ) + { + cout << "CheckTimeSent" << _my_rank << " Request " ; + } + else + { + cout << "CheckDataSent" << _my_rank << " Request " ; + } + cout << ArrayOfSendRequests[i] + << " _map_of_send_buffers->SendBuffer " + << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->SendBuffer + << " Counter " << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->Counter + << endl ; + } + if ( (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->Counter == 0 ) + { + if ( SendTrace ) + { + cout << "CheckSent" << _my_rank << " SendRequestId " << ArrayOfSendRequests[i] + << " Counter " << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->Counter + << " flag " << flag << " SendBuffer " + << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->SendBuffer + << " deleted. Erase in _map_of_send_buffers :" << endl ; + } + if ( (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->DataType == + _MPI_access->timeType() ) + { + delete (TimeMessage * ) (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->SendBuffer ; + } + else + { + if ( (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->DataType == MPI_INT ) + { + delete [] (int *) (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->SendBuffer ; + } + else + { + delete [] (double *) (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->SendBuffer ; + } + } + delete (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ] ; + } + if ( SendTrace ) + { + cout << "CheckSent" << _my_rank << " Erase in _map_of_send_buffers SendRequestId " + << ArrayOfSendRequests[i] << endl ; + } + (*_map_of_send_buffers).erase( ArrayOfSendRequests[i] ) ; + } + else if ( SendTrace ) + { + cout << "CheckSent" << _my_rank << " " << i << "./" << nSendRequest + << " SendRequestId " << ArrayOfSendRequests[i] + << " flag " << flag + << " Counter " << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->Counter + << " DataType " << (*_map_of_send_buffers)[ ArrayOfSendRequests[i] ]->DataType + << endl ; + } + } + if ( SendTrace ) + { + _MPI_access->check() ; + } + delete [] ArrayOfSendRequests ; + return sts ; + } + + int MPIAccessDEC::checkFinalRecv() + { + int sts = MPI_SUCCESS ; + if ( _time_interpolator ) + { + int target ; + for ( target = 0 ; target < _group_size ; target++ ) + { + if ( (*_data_messages)[target][0] != NULL ) + { + sts = checkTime( (*_data_messages_recv_count)[target] , (*_data_messages_type)[target] , + target , true ) ; + if ( (*_data_messages_type)[target] == MPI_INT ) + { + delete [] (int *) (*_data_messages)[target][0] ; + } + else + { + delete [] (double *) (*_data_messages)[target][0] ; + } + (*_data_messages)[target][0] = NULL ; + if ( (*_data_messages)[target][1] != NULL ) + { + if ( (*_data_messages_type)[target] == MPI_INT ) + { + delete [] (int *) (*_data_messages)[target][1] ; + } + else + { + delete [] (double *) (*_data_messages)[target][1] ; + } + (*_data_messages)[target][1] = NULL ; + } + } + } + } + return sts ; + } + + ostream & operator<< (ostream & f ,const TimeInterpolationMethod & interpolationmethod ) + { + switch (interpolationmethod) + { + case WithoutTimeInterp : + f << " WithoutTimeInterpolation "; + break; + case LinearTimeInterp : + f << " LinearTimeInterpolation "; + break; + default : + f << " UnknownTimeInterpolation "; + break; + } + + return f; + } +} diff --git a/src/ParaMEDMEM/MPIAccessDEC.hxx b/src/ParaMEDMEM/MPIAccessDEC.hxx new file mode 100644 index 000000000..540c50062 --- /dev/null +++ b/src/ParaMEDMEM/MPIAccessDEC.hxx @@ -0,0 +1,178 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __MPIACCESSDEC_HXX__ +#define __MPIACCESSDEC_HXX__ + +#include "MPIAccess.hxx" +#include "DEC.hxx" +#include "LinearTimeInterpolator.hxx" + +#include <map> +#include <iostream> + +namespace ParaMEDMEM +{ + class MPIAccessDEC + { + public: + MPIAccessDEC( const ProcessorGroup& local_group, const ProcessorGroup& distant_group, + bool Asynchronous = true ); + virtual ~MPIAccessDEC(); + MPIAccess * getMPIAccess() { return _MPI_access; } + const MPI_Comm* getComm() { return _MPI_union_group->getComm(); } + void asynchronous( bool Asynchronous = true ) { _asynchronous = Asynchronous; } + void setTimeInterpolator( TimeInterpolationMethod anInterp , double InterpPrecision=0 , + int n_step_before=1, int nStepAfter=1 ); + + void setTime( double t ) { _t = t; _dt = -1; } + void setTime( double t , double dt ) { _t = t; _dt = dt; } + bool outOfTime( int target ) { return (*_out_of_time)[target]; } + + int send( void* sendbuf, int sendcount , MPI_Datatype sendtype , int target ); + int recv( void* recvbuf, int recvcount , MPI_Datatype recvtype , int target ); + int recv( void* recvbuf, int recvcount , MPI_Datatype recvtype , int target , + int &RecvRequestId , bool Asynchronous=false ); + int sendRecv( void* sendbuf, int sendcount , MPI_Datatype sendtype , + void* recvbuf, int recvcount , MPI_Datatype recvtype , int target ); + + int allToAll( void* sendbuf, int sendcount, MPI_Datatype sendtype , + void* recvbuf, int recvcount, MPI_Datatype recvtype ); + int allToAllv( void* sendbuf, int* sendcounts, int* sdispls, MPI_Datatype sendtype , + void* recvbuf, int* recvcounts, int* rdispls, MPI_Datatype recvtype ); + + int allToAllTime( void* sendbuf, int sendcount , MPI_Datatype sendtype , + void* recvbuf, int recvcount , MPI_Datatype recvtype ); + int allToAllvTime( void* sendbuf, int* sendcounts, int* sdispls, + MPI_Datatype sendtype , + void* recvbuf, int* recvcounts, int* rdispls, + MPI_Datatype recvtype ); + int checkTime( int recvcount , MPI_Datatype recvtype , int target , bool UntilEnd ); + int checkSent(bool WithWait=false); + int checkFinalSent() { return checkSent( true ); } + int checkFinalRecv(); + protected: + int send( void* sendbuf, int sendcount , int sendoffset , MPI_Datatype sendtype , + int target, int &SendRequestId ); + int recv( void* recvbuf, int recvcount , int recvoffset , MPI_Datatype recvtype , + int target, int &RecvRequestId ); + int sendRecv( void* sendbuf, int sendcount , int sendoffset , + MPI_Datatype sendtype , + void* recvbuf, int recvcount , int recvoffset , + MPI_Datatype recvtype , int target , + int &SendRequestId ,int &RecvRequestId ); + private : + bool _asynchronous; + MPIProcessorGroup* _MPI_union_group; + + TimeInterpolator* _time_interpolator; + int _n_step_before; + int _n_step_after; + + int _my_rank; + int _group_size; + MPIAccess* _MPI_access; + + // Current time and deltatime of current process + double _t; + double _dt; + + // TimeMessages from each target _TimeMessages[target][Step] : TimeMessage + std::vector< std::vector< TimeMessage > > *_time_messages; + // Corresponding DataMessages from each target _DataMessages[target][~TimeStep] + std::vector< bool >* _out_of_time; + std::vector< int >* _data_messages_recv_count; + std::vector< MPI_Datatype >* _data_messages_type; + std::vector< std::vector< void * > >* _data_messages; + + typedef struct + { + void * SendBuffer; + int Counter; + MPI_Datatype DataType; } + SendBuffStruct; + std::map< int , SendBuffStruct * > *_map_of_send_buffers; + }; + + inline int MPIAccessDEC::send( void* sendbuf, int sendcount , MPI_Datatype sendtype , int target ) + { + int SendRequestId; + int sts; + if ( _asynchronous ) + { + sts = _MPI_access->ISend( sendbuf , sendcount , sendtype , target , + SendRequestId ); + } + else + { + sts = _MPI_access->send( sendbuf , sendcount , sendtype , target , + SendRequestId ); + if ( sts == MPI_SUCCESS ) + free( sendbuf ); + } + return sts; + } + + inline int MPIAccessDEC::recv( void* recvbuf, int recvcount , MPI_Datatype recvtype , int target ) + { + int RecvRequestId; + int sts; + if ( _asynchronous ) + sts = _MPI_access->IRecv( recvbuf , recvcount , recvtype , target , RecvRequestId ); + else + sts = _MPI_access->recv( recvbuf , recvcount , recvtype , target , RecvRequestId ); + return sts; + } + + inline int MPIAccessDEC::recv( void* recvbuf, int recvcount , MPI_Datatype recvtype , + int target , int &RecvRequestId , bool Asynchronous ) + { + int sts; + if ( Asynchronous ) + sts = _MPI_access->IRecv( recvbuf , recvcount , recvtype , target , + RecvRequestId ); + else + sts = _MPI_access->recv( recvbuf , recvcount , recvtype , target , + RecvRequestId ); + return sts; + } + + inline int MPIAccessDEC::sendRecv( void* sendbuf, int sendcount , MPI_Datatype sendtype , + void* recvbuf, int recvcount , MPI_Datatype recvtype , + int target ) + { + int SendRequestId; + int RecvRequestId; + int sts; + if ( _asynchronous ) + sts = _MPI_access->ISendRecv( sendbuf , sendcount , sendtype , target , + SendRequestId , + recvbuf , recvcount , recvtype , target , + RecvRequestId ); + else + sts = _MPI_access->sendRecv( sendbuf , sendcount , sendtype , target , + SendRequestId , + recvbuf , recvcount , recvtype , target , + RecvRequestId ); + return sts; + } + + std::ostream & operator<< (std::ostream &,const TimeInterpolationMethod &); +} + +#endif diff --git a/src/ParaMEDMEM/MPIProcessorGroup.cxx b/src/ParaMEDMEM/MPIProcessorGroup.cxx new file mode 100644 index 000000000..fc3f0188a --- /dev/null +++ b/src/ParaMEDMEM/MPIProcessorGroup.cxx @@ -0,0 +1,227 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "ProcessorGroup.hxx" +#include "MPIProcessorGroup.hxx" +#include "CommInterface.hxx" +#include "InterpolationUtils.hxx" + +#include <iostream> +#include <set> +#include <algorithm> +#include "mpi.h" + +using namespace std; + +/*! \defgroup processor_group Processor Groups + * + * \section processor_group_overview Overview + * The MPIProcessorGroup class is used to set up processor groups that help to define + * the MPI topology of the couplings. They can be set up in various ways, the most common being + * the use of the \c MPIProcessorGroup(Comminterface, int pfirst, int plast) + * constructor. + * + * The following code excerpt creates two processor groups on respectively 3 and 2 processors. + \verbatim + int main() + { + MPI_Init(&argc,&argv); + CommInterface comm_interface; + MPIProcessorGroup codeA_group(comm_interface, 0, 2); + MPIProcessorGroup codeB_group(comm_interface, 3, 4); + + ... + } + \endverbatim +*/ + + +namespace ParaMEDMEM +{ + /*! + \addtogroup processor_group + @{ + */ + + /*! + * Creates a processor group that is based on all the + MPI_COMM_WORLD processor.This routine must be called by all processors in MPI_COMM_WORLD. + \param interface CommInterface object giving access to the MPI + communication layer + */ + MPIProcessorGroup::MPIProcessorGroup(const CommInterface& interface): + ProcessorGroup(interface),_world_comm(MPI_COMM_WORLD) + { + _comm=_world_comm; + _comm_interface.commGroup(_world_comm, &_group); + int size; + _comm_interface.commSize(_world_comm,&size); + for (int i=0; i<size; i++) + _proc_ids.insert(i); + + } + + /*! Creates a processor group that is based on the processors included in \a proc_ids. + This routine must be called by all processors in MPI_COMM_WORLD. + + \param interface CommInterface object giving access to the MPI + communication layer + \param proc_ids set of ids that are to be integrated in the group. The ids number are + to be understood in terms of MPI_COMM_WORLD ranks. + */ + + MPIProcessorGroup::MPIProcessorGroup(const CommInterface& interface, set<int> proc_ids, const MPI_Comm& world_comm): + ProcessorGroup(interface, proc_ids),_world_comm(world_comm) + { + //Creation of a communicator + MPI_Group group_world; + + int size_world; + _comm_interface.commSize(_world_comm,&size_world); + int rank_world; + _comm_interface.commRank(_world_comm,&rank_world); + _comm_interface.commGroup(_world_comm, &group_world); + + int* ranks=new int[proc_ids.size()]; + + // copying proc_ids in ranks + copy<set<int>::const_iterator,int*> (proc_ids.begin(), proc_ids.end(), ranks); + for (int i=0; i< proc_ids.size();i++) + if (ranks[i]>size_world-1) + throw INTERP_KERNEL::Exception("invalid rank in set<int> argument of MPIProcessorGroup constructor"); + + _comm_interface.groupIncl(group_world, proc_ids.size(), ranks, &_group); + + _comm_interface.commCreate(_world_comm, _group, &_comm); + delete[] ranks; + } + /*! Creates a processor group that is based on the processors between \a pstart and \a pend. + This routine must be called by all processors in MPI_COMM_WORLD. + + \param comm_interface CommInterface object giving access to the MPI + communication layer + \param pstart id in MPI_COMM_WORLD of the first processor in the group + \param pend id in MPI_COMM_WORLD of the last processor in the group + */ + MPIProcessorGroup::MPIProcessorGroup (const CommInterface& comm_interface, int pstart, int pend): ProcessorGroup(comm_interface,pstart,pend),_world_comm(MPI_COMM_WORLD) + { + //Creation of a communicator + MPI_Group group_world; + + int size_world; + _comm_interface.commSize(_world_comm,&size_world); + int rank_world; + _comm_interface.commRank(_world_comm,&rank_world); + _comm_interface.commGroup(_world_comm, &group_world); + + if (pend>size_world-1 || pend <pstart || pstart<0) + throw INTERP_KERNEL::Exception("invalid argument in MPIProcessorGroup constructor (comm,pfirst,plast)"); + int nprocs=pend-pstart+1; + int* ranks=new int[nprocs]; + for (int i=pstart; i<=pend;i++) + { + ranks[i-pstart]=i; + } + + _comm_interface.groupIncl(group_world, nprocs, ranks, &_group); + + _comm_interface.commCreate(_world_comm, _group, &_comm); + delete[] ranks; + } + /*! + @} + */ + + MPIProcessorGroup::MPIProcessorGroup (const ProcessorGroup& proc_group, set<int> proc_ids) : + ProcessorGroup(proc_group.getCommInterface()),_world_comm(MPI_COMM_WORLD) + { + cout << "MPIProcessorGroup (const ProcessorGroup& proc_group, set<int> proc_ids)" <<endl; + cout << "Not implemented yet !"<<endl; + exit(1); + } + + MPIProcessorGroup::~MPIProcessorGroup() + { + _comm_interface.groupFree(&_group); + if (_comm!=_world_comm && _comm !=MPI_COMM_NULL) + _comm_interface.commFree(&_comm); + + } + /*! + \addtogroup processor_group + @{ + */ + + /*! Translation of the rank id between two processor groups. This method translates rank \a rank + on the current processor group to the rank on group pointed by \a group. + \param group group from which the rank is expected + \param rank rank on group \a group of the processor which is to be translated + \return rank on local group + */ + int MPIProcessorGroup::translateRank(const ProcessorGroup* group, int rank) const + { + const MPIProcessorGroup* targetgroup=dynamic_cast<const MPIProcessorGroup*>(group); + int local_rank; + MPI_Group_translate_ranks(targetgroup->_group, 1, &rank, _group, &local_rank); + return local_rank; + } + + /*!Creates a processor group that is the complement of the current group + inside MPI_COMM_WORLD + \return pointer to the new ProcessorGroup structure. + */ + ProcessorGroup* MPIProcessorGroup::createComplementProcGroup() const + { + set <int> procs; + int world_size=_comm_interface.worldSize(); + for (int i=0; i<world_size; i++) + procs.insert(i); + for (set<int>::const_iterator iter=_proc_ids.begin(); iter!= _proc_ids.end(); iter++) + procs.erase(*iter); + + return new MPIProcessorGroup(_comm_interface, procs, _world_comm); + + } + + /*!Adding processors of group \a group to local group. + \param group group that is to be fused with current group + \return new group formed by the fusion of local group and \a group. + */ + ProcessorGroup* MPIProcessorGroup::fuse (const ProcessorGroup& group) const + { + set <int> procs = _proc_ids; + const set<int>& distant_proc_ids = group.getProcIDs(); + for (set<int>::const_iterator iter=distant_proc_ids.begin(); iter!=distant_proc_ids.end(); iter++) + { + procs.insert(*iter); + } + return new MPIProcessorGroup(_comm_interface,procs); + } + /*! + @} + */ + ProcessorGroup* MPIProcessorGroup::createProcGroup() const + { + set <int> procs; + for (set<int>::const_iterator iter=_proc_ids.begin(); iter!= _proc_ids.end(); iter++) + procs.insert(*iter); + + return new MPIProcessorGroup(_comm_interface, procs); + + } +} diff --git a/src/ParaMEDMEM/MPIProcessorGroup.hxx b/src/ParaMEDMEM/MPIProcessorGroup.hxx new file mode 100644 index 000000000..62c9f438a --- /dev/null +++ b/src/ParaMEDMEM/MPIProcessorGroup.hxx @@ -0,0 +1,54 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __MPIPROCESSORGROUP_HXX__ +#define __MPIPROCESSORGROUP_HXX__ + +#include <set> +#include <mpi.h> + +namespace ParaMEDMEM +{ + class ProcessorGroup; + class CommInterface; + + class MPIProcessorGroup : public ProcessorGroup + { + public: + MPIProcessorGroup(const CommInterface& interface); + MPIProcessorGroup(const CommInterface& interface, std::set<int> proc_ids, const MPI_Comm& world_comm=MPI_COMM_WORLD); + MPIProcessorGroup (const ProcessorGroup& proc_group, std::set<int> proc_ids); + MPIProcessorGroup(const CommInterface& interface,int pstart, int pend); + virtual ~MPIProcessorGroup(); + virtual ProcessorGroup* fuse (const ProcessorGroup&) const; + void intersect (ProcessorGroup&) { } + int myRank() const { int rank; MPI_Comm_rank(_comm,&rank); return rank; } + bool containsMyRank() const { int rank; MPI_Group_rank(_group, &rank); return (rank!=MPI_UNDEFINED); } + int translateRank(const ProcessorGroup* group, int rank) const; + const MPI_Comm* getComm() const { return &_comm; } + ProcessorGroup* createComplementProcGroup() const; + ProcessorGroup* createProcGroup() const; + MPI_Comm getWorldComm() { return _world_comm; } + private: + const MPI_Comm _world_comm; + MPI_Group _group; + MPI_Comm _comm; + }; +} + +#endif diff --git a/src/ParaMEDMEM/Makefile.am b/src/ParaMEDMEM/Makefile.am new file mode 100644 index 000000000..e68d1f557 --- /dev/null +++ b/src/ParaMEDMEM/Makefile.am @@ -0,0 +1,109 @@ +# Copyright (C) 2007-2008 CEA/DEN, 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. +# +# 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 +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +if CPPUNIT_IS_OK + SUBDIRS=. MEDLoader Test +else + SUBDIRS=. MEDLoader +endif + +DIST_SUBDIRS= Test + +lib_LTLIBRARIES= libparamedmem.la + +salomeinclude_HEADERS= \ +CommInterface.hxx\ +MPIProcessorGroup.hxx\ +ProcessorGroup.hxx\ +BlockTopology.hxx\ +Topology.hxx\ +ParaGRID.hxx\ +ParaMESH.hxx\ +ComponentTopology.hxx\ +ExplicitTopology.hxx\ +ParaFIELD.hxx\ +DEC.hxx\ +MxN_Mapping.hxx\ +StructuredCoincidentDEC.hxx\ +InterpolationMatrix.hxx\ +IntersectionDEC.hxx\ +ExplicitCoincidentDEC.hxx\ +ElementLocator.hxx\ +ExplicitMapping.hxx\ +ICoCoField.hxx \ +ICoCoMEDField.hxx \ +ICoCoTrioField.hxx \ +MPIAccess.hxx \ +MPIAccessDEC.hxx \ +TimeInterpolator.hxx \ +LinearTimeInterpolator.hxx + +dist_libparamedmem_la_SOURCES= \ +ProcessorGroup.cxx \ +MPIProcessorGroup.cxx\ +ParaMESH.cxx\ +ComponentTopology.cxx\ +MPIAccess.cxx \ +InterpolationMatrix.cxx\ +StructuredCoincidentDEC.cxx\ +ExplicitCoincidentDEC.cxx\ +IntersectionDEC.cxx\ +ElementLocator.cxx\ +MPIAccessDEC.cxx \ +TimeInterpolator.cxx \ +LinearTimeInterpolator.cxx\ +DEC.cxx\ +ExplicitTopology.cxx\ +MxN_Mapping.cxx\ +ICoCoMEDField.cxx\ +ParaFIELD.cxx\ +ParaGRID.cxx\ +BlockTopology.cxx + +#libmedmem_la_LDFLAGS= -L$(top_builddir)/lib@LIB_LOCATION_SUFFIX@/salome +libparamedmem_la_CPPFLAGS= $(MPI_INCLUDES) @CXXTMPDPTHFLAGS@ \ + -I$(srcdir)/../INTERP_KERNEL \ + -I$(srcdir)/../INTERP_KERNEL/Bases \ + -I$(srcdir)/../INTERP_KERNEL/Geometric2D \ + -I$(srcdir)/../MEDCoupling + +# change motivated by the bug KERNEL4778. +libparamedmem_la_LDFLAGS= ../MEDCoupling/libmedcoupling.la \ +../INTERP_KERNEL/libinterpkernel.la \ +$(MPI_LIBS) + +if MED_ENABLE_FVM + salomeinclude_HEADERS += NonCoincidentDEC.hxx + libparamedmem_la_SOURCES+= NonCoincidentDEC.cxx + libparamedmem_la_LDFLAGS+= $(FVM_LIBS) + libparamedmem_la_CPPFLAGS+= $(FVM_INCLUDES) +endif + +LDADD= -lm + +EXTRA_DIST += \ + BASICS_JR \ + CommInterface.cxx \ + NonCoincidentDEC.cxx \ + NonCoincidentDEC.hxx \ + DECOptions.hxx \ + README_JR \ + TODO_JR \ + Topology.cxx diff --git a/src/ParaMEDMEM/MxN_Mapping.cxx b/src/ParaMEDMEM/MxN_Mapping.cxx new file mode 100644 index 000000000..e1fd35aa2 --- /dev/null +++ b/src/ParaMEDMEM/MxN_Mapping.cxx @@ -0,0 +1,308 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "CommInterface.hxx" +#include "ProcessorGroup.hxx" +#include "MPIProcessorGroup.hxx" +#include "MPIAccessDEC.hxx" +#include "MxN_Mapping.hxx" + +using namespace std; + +namespace ParaMEDMEM +{ + + MxN_Mapping::MxN_Mapping(const ProcessorGroup& source_group, const ProcessorGroup& target_group,const DECOptions& dec_options) + : _union_group(source_group.fuse(target_group)), + DECOptions(dec_options) + { + _access_DEC = new MPIAccessDEC(source_group,target_group,getAsynchronous()); + _access_DEC->setTimeInterpolator(getTimeInterpolationMethod()); + _send_proc_offsets.resize(_union_group->size()+1,0); + _recv_proc_offsets.resize(_union_group->size()+1,0); + + } + + MxN_Mapping::~MxN_Mapping() + { + delete _union_group; + delete _access_DEC; + } + + + /*! + Method registering a new element for correspondence with a distant element + \param distant_proc proc rank of the distant processor (in terms of the union group) + \param distant_element id of the element on the distant processor + */ + void MxN_Mapping::addElementFromSource(int distant_proc, int distant_element) + { + _sending_ids.push_back(make_pair(distant_proc,distant_element)); + for (int i=distant_proc; i<_union_group->size(); i++) + _send_proc_offsets[i+1]++; + } + + void MxN_Mapping::prepareSendRecv() + { + CommInterface comm_interface=_union_group->getCommInterface(); + // sending count pattern + int* nbsend=new int[_union_group->size()]; + int* nbrecv=new int[_union_group->size()]; + for (int i=0; i<_union_group->size(); i++) + { + nbsend[i]=_send_proc_offsets[i+1]-_send_proc_offsets[i]; + } + + MPIProcessorGroup* group = static_cast<MPIProcessorGroup*>(_union_group); + const MPI_Comm* comm=group->getComm(); + comm_interface.allToAll(nbsend, 1, MPI_INT, + nbrecv, 1, MPI_INT, + *comm); + + for (int i=0; i<_union_group->size(); i++) + { + for (int j=i+1;j<_union_group->size()+1; j++) + _recv_proc_offsets[j]+=nbrecv[i]; + + } + + delete[] nbsend; + delete[] nbrecv; + + _recv_ids.resize(_recv_proc_offsets[_union_group->size()]); + int* isendbuf=0; + int* irecvbuf=0; + if (_sending_ids.size()>0) + isendbuf = new int[_sending_ids.size()]; + if (_recv_ids.size()>0) + irecvbuf = new int[_recv_ids.size()]; + int* sendcounts = new int[_union_group->size()]; + int* senddispls=new int[_union_group->size()]; + int* recvcounts=new int[_union_group->size()]; + int* recvdispls=new int[_union_group->size()]; + for (int i=0; i< _union_group->size(); i++) + { + sendcounts[i]=_send_proc_offsets[i+1]-_send_proc_offsets[i]; + senddispls[i]=_send_proc_offsets[i]; + recvcounts[i]=_recv_proc_offsets[i+1]-_recv_proc_offsets[i]; + recvdispls[i]=_recv_proc_offsets[i]; + } + vector<int> offsets = _send_proc_offsets; + for (int i=0; i<_sending_ids.size();i++) + { + int iproc = _sending_ids[i].first; + isendbuf[offsets[iproc]]=_sending_ids[i].second; + offsets[iproc]++; + } + comm_interface.allToAllV(isendbuf, sendcounts, senddispls, MPI_INT, + irecvbuf, recvcounts, recvdispls, MPI_INT, + *comm); + + for (int i=0; i< _recv_proc_offsets[_union_group->size()]; i++) + _recv_ids[i]=irecvbuf[i]; + + if (_sending_ids.size()>0) + delete[] isendbuf; + if (_recv_ids.size()>0) + delete[] irecvbuf; + delete[] sendcounts; + delete[]recvcounts; + delete[]senddispls; + delete[] recvdispls; + } + + /*! Exchanging field data between two groups of processes + * + * \param field MEDCoupling field containing the values to be sent + * + * The ids that were defined by addElementFromSource method + * are sent. + */ + void MxN_Mapping::sendRecv(double* sendfield, MEDCouplingFieldDouble& field) const + { + CommInterface comm_interface=_union_group->getCommInterface(); + const MPIProcessorGroup* group = static_cast<const MPIProcessorGroup*>(_union_group); + + int nbcomp=field.getArray()->getNumberOfComponents(); + double* sendbuf=0; + double* recvbuf=0; + if (_sending_ids.size() >0) + sendbuf = new double[_sending_ids.size()*nbcomp]; + if (_recv_ids.size()>0) + recvbuf = new double[_recv_ids.size()*nbcomp]; + + int* sendcounts = new int[_union_group->size()]; + int* senddispls=new int[_union_group->size()]; + int* recvcounts=new int[_union_group->size()]; + int* recvdispls=new int[_union_group->size()]; + + for (int i=0; i< _union_group->size(); i++) + { + sendcounts[i]=nbcomp*(_send_proc_offsets[i+1]-_send_proc_offsets[i]); + senddispls[i]=nbcomp*(_send_proc_offsets[i]); + recvcounts[i]=nbcomp*(_recv_proc_offsets[i+1]-_recv_proc_offsets[i]); + recvdispls[i]=nbcomp*(_recv_proc_offsets[i]); + } + //building the buffer of the elements to be sent + vector<int> offsets = _send_proc_offsets; + + for (int i=0; i<_sending_ids.size();i++) + { + int iproc = _sending_ids[i].first; + for (int icomp=0; icomp<nbcomp; icomp++) + sendbuf[offsets[iproc]*nbcomp+icomp]=sendfield[i*nbcomp+icomp]; + offsets[iproc]++; + } + + //communication phase + switch (getAllToAllMethod()) + { + case Native: + { + const MPI_Comm* comm = group->getComm(); + comm_interface.allToAllV(sendbuf, sendcounts, senddispls, MPI_DOUBLE, + recvbuf, recvcounts, recvdispls, MPI_DOUBLE, + *comm); + } + break; + case PointToPoint: + _access_DEC->allToAllv(sendbuf, sendcounts, senddispls, MPI_DOUBLE, + recvbuf, recvcounts, recvdispls, MPI_DOUBLE); + break; + } + + //setting the received values in the field + DataArrayDouble *fieldArr=field.getArray(); + double* recvptr=recvbuf; + for (int i=0; i< _recv_proc_offsets[_union_group->size()]; i++) + { + for (int icomp=0; icomp<nbcomp; icomp++) + { + double temp = fieldArr->getIJ(_recv_ids[i],icomp); + fieldArr->setIJ(_recv_ids[i],icomp,temp+*recvptr); + recvptr++; + } + } + if (sendbuf!=0 && getAllToAllMethod()== Native) + delete[] sendbuf; + if (recvbuf !=0) + delete[] recvbuf; + delete[] sendcounts; + delete[] recvcounts; + delete[] senddispls; + delete[] recvdispls; + + } + + /*! Exchanging field data between two groups of processes + * + * \param field MEDCoupling field containing the values to be sent + * + * The ids that were defined by addElementFromSource method + * are sent. + */ + void MxN_Mapping::reverseSendRecv(double* recvfield, MEDCouplingFieldDouble& field) const + { + CommInterface comm_interface=_union_group->getCommInterface(); + const MPIProcessorGroup* group = static_cast<const MPIProcessorGroup*>(_union_group); + + int nbcomp=field.getArray()->getNumberOfComponents(); + double* sendbuf=0; + double* recvbuf=0; + if (_recv_ids.size() >0) + sendbuf = new double[_recv_ids.size()*nbcomp]; + if (_sending_ids.size()>0) + recvbuf = new double[_sending_ids.size()*nbcomp]; + + int* sendcounts = new int[_union_group->size()]; + int* senddispls=new int[_union_group->size()]; + int* recvcounts=new int[_union_group->size()]; + int* recvdispls=new int[_union_group->size()]; + + for (int i=0; i< _union_group->size(); i++) + { + sendcounts[i]=nbcomp*(_recv_proc_offsets[i+1]-_recv_proc_offsets[i]); + senddispls[i]=nbcomp*(_recv_proc_offsets[i]); + recvcounts[i]=nbcomp*(_send_proc_offsets[i+1]-_send_proc_offsets[i]); + recvdispls[i]=nbcomp*(_send_proc_offsets[i]); + } + //building the buffer of the elements to be sent + vector<int> offsets = _recv_proc_offsets; + DataArrayDouble *fieldArr=field.getArray(); + for (int iproc=0; iproc<_union_group->size();iproc++) + for (int i=_recv_proc_offsets[iproc]; i<_recv_proc_offsets[iproc+1]; i++) + { + for (int icomp=0; icomp<nbcomp; icomp++) + sendbuf[i*nbcomp+icomp]=fieldArr->getIJ(_recv_ids[i],icomp); + } + + //communication phase + switch (getAllToAllMethod()) + { + case Native: + { + const MPI_Comm* comm = group->getComm(); + comm_interface.allToAllV(sendbuf, sendcounts, senddispls, MPI_DOUBLE, + recvbuf, recvcounts, recvdispls, MPI_DOUBLE, + *comm); + } + break; + case PointToPoint: + _access_DEC->allToAllv(sendbuf, sendcounts, senddispls, MPI_DOUBLE, + recvbuf, recvcounts, recvdispls, MPI_DOUBLE); + break; + } + + //setting the received values in the field + double* recvptr=recvbuf; + for (int i=0; i< _send_proc_offsets[_union_group->size()]; i++) + { + for (int icomp=0; icomp<nbcomp; icomp++) + { + recvfield[i*nbcomp+icomp]=*recvptr; + recvptr++; + } + } + if (sendbuf!=0 && getAllToAllMethod() == Native) + delete[] sendbuf; + if (recvbuf!=0) + delete[] recvbuf; + delete[] sendcounts; + delete[] recvcounts; + delete[] senddispls; + delete[] recvdispls; + } + + + ostream & operator<< (ostream & f ,const AllToAllMethod & alltoallmethod ) + { + switch (alltoallmethod) + { + case Native : + f << " Native "; + break; + case PointToPoint : + f << " PointToPoint "; + break; + default : + f << " UnknownAllToAllMethod "; + break; + } + return f; + } +} diff --git a/src/ParaMEDMEM/MxN_Mapping.hxx b/src/ParaMEDMEM/MxN_Mapping.hxx new file mode 100644 index 000000000..9e019efe9 --- /dev/null +++ b/src/ParaMEDMEM/MxN_Mapping.hxx @@ -0,0 +1,60 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __MXN_MAPPING_HXX__ +#define __MXN_MAPPING_HXX__ + +#include "MEDCouplingFieldDouble.hxx" +#include "MPIAccessDEC.hxx" +#include "DECOptions.hxx" + +#include <vector> + +namespace ParaMEDMEM +{ + + class ProcessorGroup; + + class MxN_Mapping : public DECOptions + { + public: + MxN_Mapping(); + MxN_Mapping(const ProcessorGroup& source_group, const ProcessorGroup& target_group, const DECOptions& dec_options); + virtual ~MxN_Mapping(); + void addElementFromSource(int distant_proc, int distant_elem); + void prepareSendRecv(); + void sendRecv(MEDCouplingFieldDouble& field); + void sendRecv(double* field, MEDCouplingFieldDouble& field) const ; + void reverseSendRecv(double* field, MEDCouplingFieldDouble& field) const ; + + MPIAccessDEC* getAccessDEC(){ return _access_DEC; } + private : + ProcessorGroup* _union_group; + MPIAccessDEC * _access_DEC; + int _nb_comps; + std::vector<std::pair<int,int> > _sending_ids; + std::vector<int> _recv_ids; + std::vector<int> _send_proc_offsets; + std::vector<int> _recv_proc_offsets; + }; + + std::ostream & operator<< (std::ostream &,const AllToAllMethod &); + +} + +#endif diff --git a/src/ParaMEDMEM/NonCoincidentDEC.cxx b/src/ParaMEDMEM/NonCoincidentDEC.cxx new file mode 100644 index 000000000..6ca700a0b --- /dev/null +++ b/src/ParaMEDMEM/NonCoincidentDEC.cxx @@ -0,0 +1,396 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <mpi.h> +#include "CommInterface.hxx" +#include "Topology.hxx" +#include "BlockTopology.hxx" +#include "ComponentTopology.hxx" +#include "ParaFIELD.hxx" +#include "MPIProcessorGroup.hxx" +#include "DEC.hxx" +#include "NonCoincidentDEC.hxx" + +extern "C" { +#include <fvm_parall.h> +#include <fvm_nodal.h> +#include <fvm_nodal_append.h> +#include <fvm_locator.h> +} + +namespace ParaMEDMEM +{ + + /*! + \defgroup noncoincidentdec NonCoincidentDEC + + \section overview Overview + + \c NonCoincidentDEC enables nonconservative remapping of fields + between two parallel codes. + The computation is possible for 3D meshes and 2D meshes. + It is not available for 3D surfaces. The computation enables fast parallel localization, based on the + FVM library. The computation is based on a point in element search, followed + by a field evaluation at the point location. Thus, it is typically + faster than the \ref intersectiondec which gives a \ref conservativeremapping. + It is particularly true for the initialisation phase (synchronize) + which is very computationnaly intensive in \ref intersectiondec. + + In the present version, only fields lying on elements are considered. + The value is estimated by locating the barycenter of the target + side cell in a source cell and sending the value of this source cell + as the value of the target cell. + + \image html NonCoincident_small.png "Example showing the transfer from a field based on a quadrangular mesh to a triangular mesh. The triangle barycenters are computed and located in the quadrangles. In a P0-P0 interpolation, the value on the quadrangle is then applied to the triangles whose barycenter lies within." + + \image latex NonCoincident_small.eps "Example showing the transfer from a field based on a quadrangular mesh to a triangular mesh. The triangle barycenters are computed and located in the quadrangles. In a P0-P0 interpolation, the value on the quadrangle is then applied to the triangles whose barycenter lies within." + + A typical use of NonCoincidentDEC encompasses two distinct phases : + - A setup phase during which the intersection volumes are computed and the communication structures are setup. This corresponds to calling the NonCoincidentDEC::synchronize() method. + - A use phase during which the remappings are actually performed. This corresponds to the calls to sendData() and recvData() which actually trigger the data exchange. The data exchange are synchronous in the current version of the library so that recvData() and sendData() calls must be synchronized on code A and code B processor groups. + + The following code excerpt illutrates a typical use of the NonCoincidentDEC class. + + \code + ... + NonCoincidentDEC dec(groupA, groupB); + dec.attachLocalField(field); + dec.synchronize(); + if (groupA.containsMyRank()) + dec.recvData(); + else if (groupB.containsMyRank()) + dec.sendData(); + ... + \endcode + + Computing the field on the receiving side can be expressed in terms + of a matrix-vector product : \f$ \phi_t=W.\phi_s\f$, with \f$ \phi_t + \f$ the field on the target side and \f$ \phi_s \f$ the field on + the source side. + In the P0-P0 case, this matrix is a plain rectangular matrix with one + non-zero element per row (with value 1). For instance, in the above figure, the matrix is : + \f[ + + \begin{tabular}{|cccc|} + 1 & 0 & 0 & 0\\ + 0 & 0 & 1 & 0\\ + 1 & 0 & 0 & 0\\ + 0 & 0 & 1 & 0\\ + \end{tabular} + \f] + */ + + fvm_nodal_t* medmemMeshToFVMMesh(const MEDMEM::MESH* mesh) + { + // create an FVM structure from the paramesh structure + fvm_nodal_t * fvm_nodal = fvm_nodal_create(mesh->getName().c_str(),mesh->getMeshDimension()); + + //loop on cell types + int nbtypes = mesh->getNumberOfTypes(MED_EN::MED_CELL); + const MED_EN::medGeometryElement* types = mesh->getTypes(MED_EN::MED_CELL); + for (int itype=0; itype<nbtypes; itype++) + { + fvm_element_t fvm_type; + switch (types[itype]) + { + case MED_EN::MED_TRIA3 : + fvm_type=FVM_FACE_TRIA; + break; + case MED_EN::MED_QUAD4 : + fvm_type=FVM_FACE_QUAD; + break; + case MED_EN::MED_TETRA4 : + fvm_type=FVM_CELL_TETRA; + break; + case MED_EN::MED_HEXA8 : + fvm_type=FVM_CELL_HEXA; + break; + default: + throw MEDEXCEPTION(" MED type conversion to fvm is not handled yet."); + break; + + } + + fvm_lnum_t nbelems = mesh->getNumberOfElements(MED_EN::MED_CELL, types[itype]); + fvm_lnum_t* conn = new fvm_lnum_t[nbelems*(types[itype]%100)]; + const int* mesh_conn =mesh->getConnectivity(MED_EN::MED_FULL_INTERLACE,MED_EN::MED_NODAL, MED_EN::MED_CELL, types[itype]); + for (int i=0; i<nbelems*(types[itype]%100); i++) + conn[i]=mesh_conn[i]; + //swapping trias + if (types[itype]==MED_EN::MED_TRIA3) + { + for (int i=0; i<nbelems;i++) + { + int tmp=conn[3*i]; + conn[3*i]=mesh_conn[3*i+1]; + conn[3*i+1]=tmp; + } + } + //swapping tetras + if (types[itype]==MED_EN::MED_TETRA4) + { + for (int i=0; i<nbelems;i++) + { + int tmp=conn[4*i]; + conn[4*i]=mesh_conn[4*i+1]; + conn[4*i+1]=tmp; + } + } + fvm_nodal_append_by_transfer(fvm_nodal, nbelems, fvm_type,0,0,0,conn,0); + + int nbnodes= mesh->getNumberOfNodes(); + int spacedim=mesh->getSpaceDimension(); + fvm_coord_t* coords = new fvm_coord_t[nbnodes*spacedim]; + const double* mesh_coords=mesh->getCoordinates(MED_EN::MED_FULL_INTERLACE); + for (int i=0; i<nbnodes*spacedim; i++) + coords[i]=mesh_coords[i]; + fvm_nodal_transfer_vertices(fvm_nodal,coords); + } + return fvm_nodal; + } + + fvm_nodal_t* medmemSupportToFVMMesh(const MEDMEM::SUPPORT* support) + { + + // create an FVM structure from the paramesh structure + fvm_nodal_t * fvm_nodal = fvm_nodal_create(support->getName().c_str(),1); + + const MEDMEM::MESH* mesh= support->getMesh(); + + //loop on cell types + MED_EN::medEntityMesh entity = support->getEntity(); + + int nbtypes = support->getNumberOfTypes(); + const MED_EN::medGeometryElement* types = support->getTypes(); + int ioffset=0; + const int* type_offset = support->getNumberIndex(); + + //browsing through all types + for (int itype=0; itype<nbtypes; itype++) + { + fvm_element_t fvm_type; + switch (types[itype]) + { + case MED_EN::MED_TRIA3 : + fvm_type=FVM_FACE_TRIA; + break; + case MED_EN::MED_QUAD4 : + fvm_type=FVM_FACE_QUAD; + break; + case MED_EN::MED_TETRA4 : + fvm_type=FVM_CELL_TETRA; + break; + case MED_EN::MED_HEXA8 : + fvm_type=FVM_CELL_HEXA; + break; + default: + throw MEDEXCEPTION(" MED type conversion to fvm is not handled yet."); + break; + + } + fvm_lnum_t nbelems = support->getNumberOfElements(types[itype]); + + //for a partial support, defining the element numbers that are taken into + //account in the support + fvm_lnum_t* elem_numbers=0; + if (!support->isOnAllElements()) + { + elem_numbers = const_cast<fvm_lnum_t*> (support->getNumber(types[itype])); + + //creating work arrays to store list of elems for partial suports + if (itype>0) + { + fvm_lnum_t* temp = new int[nbelems]; + for (int i=0; i< nbelems; i++) + temp[i] = elem_numbers [i]-ioffset; + ioffset+=type_offset[itype]; + elem_numbers = temp; + } + } + //retrieving original mesh connectivity + fvm_lnum_t* conn = const_cast<fvm_lnum_t*> (mesh->getConnectivity(MED_EN::MED_FULL_INTERLACE,MED_EN::MED_NODAL,entity, types[itype])); + + // adding the elements to the FVM structure + fvm_nodal_append_by_transfer(fvm_nodal, nbelems, fvm_type,0,0,0,conn,elem_numbers); + + //cleaning work arrays (for partial supports) + if (!support->isOnAllElements() && itype>0) + delete[] elem_numbers; + + } + return fvm_nodal; + } + + NonCoincidentDEC::NonCoincidentDEC() + { + } + + /*! + \addtogroup noncoincidentdec + @{ + */ + + /*! Constructor of a non coincident DEC with + * a source group on which lies a field lying on a mesh and a + * target group on which lies a mesh. + * + * \param source_group ProcessorGroup on the source side + * \param target_group ProcessorGroup on the target side + */ + + NonCoincidentDEC::NonCoincidentDEC(ProcessorGroup& source_group, + ProcessorGroup& target_group) + :DEC(source_group, target_group) + {} + + NonCoincidentDEC::~NonCoincidentDEC() + { + } + + /*! Synchronization process. Calling this method + * synchronizes the topologies so that the target side + * gets the information which enable it to fetch the field value + * from the source side. + * A typical call is : + \verbatim + NonCoincidentDEC dec(source_group,target_group); + dec.attachLocalField(field); + dec.synchronize(); + \endverbatim + */ + void NonCoincidentDEC::synchronize() + { + + //initializing FVM parallel environment + const MPI_Comm* comm=dynamic_cast<const MPIProcessorGroup*> (_union_group)->getComm(); + fvm_parall_set_mpi_comm(*const_cast<MPI_Comm*> (comm)); + + + //setting up the communication DEC on both sides + + if (_source_group->containsMyRank()) + { + MEDMEM::MESH* mesh = _local_field->getField()->getSupport()->getMesh(); + fvm_nodal_t* source_nodal = ParaMEDMEM::medmemMeshToFVMMesh(mesh); + + int target_size = _target_group->size() ; + int start_rank= _source_group->size(); + const MPI_Comm* comm = (dynamic_cast<const MPIProcessorGroup*> (_union_group))->getComm(); + + _locator = fvm_locator_create(1e-6, + *comm, + target_size, + start_rank); + + fvm_locator_set_nodal(_locator, + source_nodal, + mesh->getSpaceDimension(), + 0, + NULL, + 0); + + + _nb_distant_points = fvm_locator_get_n_dist_points(_locator); + _distant_coords = fvm_locator_get_dist_coords(_locator); + _distant_locations = fvm_locator_get_dist_locations(_locator); + + } + if (_target_group->containsMyRank()) + { + MEDMEM::MESH* mesh = _local_field->getField()->getSupport()->getMesh(); + + fvm_nodal_t* target_nodal = ParaMEDMEM::medmemMeshToFVMMesh(mesh); + int source_size = _source_group->size(); + int start_rank= 0 ; + const MPI_Comm* comm = (dynamic_cast<const MPIProcessorGroup*> (_union_group))->getComm(); + + _locator = fvm_locator_create(1e-6, + *comm, + source_size, + start_rank); + int nbcells = mesh->getNumberOfElements(MED_EN::MED_CELL,MED_EN::MED_ALL_ELEMENTS); + const MEDMEM::SUPPORT* support=_local_field->getField()->getSupport(); + MEDMEM::FIELD<double>* barycenter_coords = mesh->getBarycenter(support); + const double* coords = barycenter_coords->getValue(); + fvm_locator_set_nodal(_locator, + target_nodal, + mesh->getSpaceDimension(), + nbcells, + NULL, + coords); + delete barycenter_coords; + } + } + + + /*! This method is called on the target group in order to + * trigger the retrieveal of field data. It must + * be called synchronously with a sendData() call on + * the source group. + */ + void NonCoincidentDEC::recvData() + { + int nbelems = _local_field->getField()->getSupport()->getMesh()->getNumberOfElements(MED_EN::MED_CELL, MED_EN::MED_ALL_ELEMENTS); + int nbcomp = _local_field->getField()->getNumberOfComponents(); + double* values = new double [nbelems*nbcomp]; + fvm_locator_exchange_point_var(_locator, + 0, + values, + 0, + sizeof(double), + nbcomp, + 0); + _local_field->getField()->setValue(values); + if (_forced_renormalization_flag) + renormalizeTargetField(); + delete[]values; + } + + /*! This method is called on the source group in order to + * send field data. It must be called synchronously with + * a recvData() call on + * the target group. + */ + void NonCoincidentDEC::sendData() + { + const double* values=_local_field->getField()->getValue(); + int nbcomp = _local_field->getField()->getNumberOfComponents(); + double* distant_values = new double [_nb_distant_points*nbcomp]; + + //cheap interpolation : the value of the cell is transfered to the point + for (int i=0; i<_nb_distant_points; i++) + for (int j=0; j <nbcomp; j++) + distant_values[i*nbcomp+j]=values[(_distant_locations[i]-1)*nbcomp+j]; + + fvm_locator_exchange_point_var(_locator, + distant_values, + 0, + 0, + sizeof(double), + nbcomp, + 0); + + delete [] distant_values; + if (_forced_renormalization_flag) + renormalizeTargetField(); + + } + /*! + @} + */ +} diff --git a/src/ParaMEDMEM/NonCoincidentDEC.hxx b/src/ParaMEDMEM/NonCoincidentDEC.hxx new file mode 100644 index 000000000..b2c582356 --- /dev/null +++ b/src/ParaMEDMEM/NonCoincidentDEC.hxx @@ -0,0 +1,69 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __NONCOINCIDENTDEC_HXX__ +#define __NONCOINCIDENTDEC_HXX__ + +#include "DEC.hxx" + +struct _fvm_locator_t; + +typedef enum {NN} InterpolationMethod; + +namespace ParaMEDMEM +{ + class NonCoincidentDEC : public DEC + { + public: + NonCoincidentDEC(); + NonCoincidentDEC(ProcessorGroup& , ProcessorGroup&); + + virtual ~NonCoincidentDEC(); + + void synchronize(); + + void recvData(); + + void sendData(); + + void prepareSourceDE() { } + void prepareTargetDE() { } + + void setInterpolationMethod(InterpolationMethod method) { _method=method; } + + private : + // Structure for computing the localization + // of remote nodes on local mesh + _fvm_locator_t* _locator; + + //Number of distant points to be located locally + int _nb_distant_points; + + //coordinates of distant points + const double* _distant_coords; + + //local element number containing the distant points + const int* _distant_locations; + + //inerpolation method + InterpolationMethod _method; + }; +} + + +#endif diff --git a/src/ParaMEDMEM/ParaFIELD.cxx b/src/ParaMEDMEM/ParaFIELD.cxx new file mode 100644 index 000000000..a59eb9125 --- /dev/null +++ b/src/ParaMEDMEM/ParaFIELD.cxx @@ -0,0 +1,191 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "Topology.hxx" +#include "BlockTopology.hxx" +#include "ComponentTopology.hxx" +#include "ExplicitCoincidentDEC.hxx" +#include "StructuredCoincidentDEC.hxx" +#include "CommInterface.hxx" +#include "ProcessorGroup.hxx" +#include "MPIProcessorGroup.hxx" +#include "ParaFIELD.hxx" +#include "ParaMESH.hxx" +#include "InterpKernelUtilities.hxx" +#include "InterpolationMatrix.hxx" + +#include <numeric> + +namespace ParaMEDMEM +{ + /*! + \defgroup parafield ParaFIELD + This class encapsulates parallel fields. It basically encapsulates + a MEDCouplingField with extra information related to parallel + topology. + It is most conveniently created by giving a pointer to a MEDCouplingField + object and a \c ProcessorGroup. + By default, a ParaFIELD object will be constructed with all field components + located on the same processors. In some specific cases, it might be necessary to scatter components over several processors. In this case, the constructor + using a ComponentTopology is required. + + @{ */ + + /*! + + \brief Constructing a \c ParaFIELD from a \c ParaSUPPORT and a \c ComponentTopology. + + This constructor creates an empty field based on the ParaSUPPORT description + and the partitioning of components described in \a component_topology. + It takes ownership over the \c _field object that it creates. + + Here come the three ComponentTopology constructors : + \verbatim + ComponentTopology c; // one component in the field + ComponentTopology c(6); //six components, all of them on the same processor + ComponentTopology c(6, proc_group); // six components, evenly distributed over the processors of procgroup + \endverbatim + + */ + ParaFIELD::ParaFIELD(TypeOfField type, ParaMESH* para_support, const ComponentTopology& component_topology) + :_support(para_support), + _component_topology(component_topology),_topology(0), + _field(0), + _has_field_ownership(true), + _has_support_ownership(false) + { + if (para_support->isStructured() || (para_support->getTopology()->getProcGroup()->size()==1 && component_topology.nbBlocks()!=1)) + { + const BlockTopology* source_topo = dynamic_cast<const BlockTopology*>(para_support->getTopology()); + _topology=new BlockTopology(*source_topo,component_topology); + } + else + { + if (component_topology.nbBlocks()!=1 && para_support->getTopology()->getProcGroup()->size()!=1) + throw INTERP_KERNEL::Exception(LOCALIZED("ParaFIELD constructor : Unstructured Support not taken into account with component topology yet")); + else + { + const BlockTopology* source_topo=dynamic_cast<const BlockTopology*> (para_support->getTopology()); + int nb_local_comp=component_topology.nbLocalComponents(); + _topology=new BlockTopology(*source_topo,nb_local_comp); + } + } + int nb_components = component_topology.nbLocalComponents(); + if (nb_components!=0) + { + _field=MEDCouplingFieldDouble::New(type); + _field->setMesh(_support->getCellMesh()); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(_field->getNumberOfTuples(),nb_components); + _field->setArray(array); + array->decrRef(); + } + else return; + + _field->setName("Default ParaFIELD name"); + _field->setDescription("Default ParaFIELD description"); + _field->setDtIt(0,0); + _field->setTime(0.0); + } + + /*! \brief Constructor creating the ParaFIELD + from a given FIELD and a processor group. + + This constructor supposes that support underlying \a subdomain_field has no ParaSUPPORT + attached and it therefore recreates one. It therefore takes ownership over _support. The component topology associated with the field is a basic one (all components on the same processor). + */ + ParaFIELD::ParaFIELD(MEDCouplingFieldDouble* subdomain_field, const ProcessorGroup& proc_group): + _field(subdomain_field), + _support(), + _component_topology(ComponentTopology(_field->getNumberOfComponents())),_topology(0), + _has_field_ownership(false), + _has_support_ownership(true) + { + if(_field) + _field->incrRef(); + const ExplicitTopology* source_topo=dynamic_cast<const ExplicitTopology*> (_support->getTopology()); + _topology=new ExplicitTopology(*source_topo,_component_topology.nbLocalComponents()); + } + + ParaFIELD::~ParaFIELD() + { + if(_field) + _field->decrRef(); + delete _topology; + } + + void ParaFIELD::synchronizeTarget(ParaFIELD* source_field) + { + DEC* data_channel; + if (dynamic_cast<BlockTopology*>(_topology)!=0) + { + data_channel=new StructuredCoincidentDEC; + } + else + { + data_channel=new ExplicitCoincidentDEC; + } + data_channel->attachLocalField(this); + data_channel->synchronize(); + data_channel->prepareTargetDE(); + data_channel->recvData(); + + delete data_channel; + } + + void ParaFIELD::synchronizeSource(ParaFIELD* target_field) + { + DEC* data_channel; + if (dynamic_cast<BlockTopology*>(_topology)!=0) + { + data_channel=new StructuredCoincidentDEC; + } + else + { + data_channel=new ExplicitCoincidentDEC; + } + data_channel->attachLocalField(this); + data_channel->synchronize(); + data_channel->prepareSourceDE(); + data_channel->sendData(); + + delete data_channel; + } + + /*! This method retrieves the integral of component \a icomp + over the all domain. */ + double ParaFIELD::getVolumeIntegral(int icomp) const + { + CommInterface comm_interface = _topology->getProcGroup()->getCommInterface(); + MEDCouplingFieldDouble *volume=InterpolationMatrix::getSupportVolumes(_field->getMesh()); + double *ptr=volume->getArray()->getPointer(); + int nbOfValues=volume->getArray()->getNbOfElems(); + double integral=0.; + for (int i=0; i<nbOfValues; i++) + integral+=_field->getIJ(i,icomp)*ptr[i]; + + volume->decrRef(); + + double total=0.; + const MPI_Comm* comm = (dynamic_cast<const MPIProcessorGroup*>(_topology->getProcGroup()))->getComm(); + comm_interface.allReduce(&integral, &total, 1, MPI_DOUBLE, MPI_SUM, *comm); + + return total; + } +} + diff --git a/src/ParaMEDMEM/ParaFIELD.hxx b/src/ParaMEDMEM/ParaFIELD.hxx new file mode 100644 index 000000000..5b8944dda --- /dev/null +++ b/src/ParaMEDMEM/ParaFIELD.hxx @@ -0,0 +1,63 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __PARAFIELD_HXX__ +#define __PARAFIELD_HXX__ + +#include "ComponentTopology.hxx" +#include "ParaMESH.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingUMesh.hxx" + +namespace ParaMEDMEM +{ + + class ParaSUPPORT; + class ProcessorGroup; + + class ParaFIELD + { + public: + + ParaFIELD(TypeOfField type, ParaMESH* mesh, const ComponentTopology& component_topology); + + + ParaFIELD(MEDCouplingFieldDouble* field, const ProcessorGroup& group); + + virtual ~ParaFIELD(); + void synchronizeTarget( ParaMEDMEM::ParaFIELD* source_field); + void synchronizeSource( ParaMEDMEM::ParaFIELD* target_field); + MEDCouplingFieldDouble* getField() const { return _field; } + Topology* getTopology() const { return _topology; } + ParaMESH* getSupport() const { return _support; } + int nbComponents() const { return _component_topology.nbComponents(); } + double getVolumeIntegral(int icomp) const; + double getL2Norm()const { return -1; } + private: + MEDCouplingFieldDouble* _field; + const ParaMEDMEM::ComponentTopology& _component_topology; + Topology* _topology; + + ParaMESH* _support; + bool _has_field_ownership; + bool _has_support_ownership; + }; + +} + +#endif diff --git a/src/ParaMEDMEM/ParaGRID.cxx b/src/ParaMEDMEM/ParaGRID.cxx new file mode 100644 index 000000000..3abe033e6 --- /dev/null +++ b/src/ParaMEDMEM/ParaGRID.cxx @@ -0,0 +1,73 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "ParaGRID.hxx" +#include "Topology.hxx" +#include "BlockTopology.hxx" +#include "MemArray.hxx" +#include "MEDCouplingSMesh.hxx" +#include "InterpKernelUtilities.hxx" + +#include <iostream> + +using namespace std; + +namespace ParaMEDMEM +{ + + ParaGRID::ParaGRID(MEDCouplingSMesh* global_grid, Topology* topology) throw(INTERP_KERNEL::Exception) + { + + _block_topology = dynamic_cast<BlockTopology*>(topology); + if(_block_topology==0) + throw INTERP_KERNEL::Exception(LOCALIZED("ParaGRID::ParaGRID topology must be block topology")); + + if (!_block_topology->getProcGroup()->containsMyRank()) + return; + + int dimension=_block_topology->getDimension() ; + if (dimension != global_grid->getSpaceDimension()) + throw INTERP_KERNEL::Exception(LOCALIZED("ParaGrid::ParaGrid incompatible topology")); + _grid=global_grid; + _grid->incrRef(); + /*vector<vector<double> > xyz_array(dimension); + vector<pair<int,int> > local_indices = _block_topology->getLocalArrayMinMax(); + vector <string> coordinates_names; + vector <string> coordinates_units; + for (int idim=0; idim<dimension ; idim++) + { + DataArrayDouble *array=global_grid->getCoordsAt(idim); + double *arrayC=array->getPointer(); + cout << " Indices "<< local_indices[idim].first <<" "<<local_indices[idim].second<<endl; + for (int i=(local_indices)[idim].first; i<(local_indices)[idim].second; i++) + xyz_array[idim].push_back(arrayC[i]); + coordinates_names.push_back(array->getName()); + coordinates_units.push_back(array->getInfoOnComponentAt(0)); + } + _grid=MEDCouplingSMesh::New(); + _grid->set(xyz_array, coordinates_names,coordinates_units); + _grid->setName(global_grid->getName()); + _grid->setDescription(global_grid->getDescription());*/ + } + + ParaGRID::~ParaGRID() + { + if(_grid) + _grid->decrRef(); + } +} diff --git a/src/ParaMEDMEM/ParaGRID.hxx b/src/ParaMEDMEM/ParaGRID.hxx new file mode 100644 index 000000000..f7abab109 --- /dev/null +++ b/src/ParaMEDMEM/ParaGRID.hxx @@ -0,0 +1,50 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __PARAGRID_HXX__ +#define __PARAGRID_HXX__ + +#include "InterpolationUtils.hxx" + +#include <vector> + +namespace ParaMEDMEM +{ + class Topology; + class BlockTopology; + class MEDCouplingSMesh; + + class ParaGRID + { + public: + ParaGRID(MEDCouplingSMesh* global_grid, Topology* topology) throw(INTERP_KERNEL::Exception); + BlockTopology * getBlockTopology() const { return _block_topology; } + virtual ~ParaGRID(); + MEDCouplingSMesh* getGrid() const { return _grid; } + private: + MEDCouplingSMesh* _grid; + // structured grid topology + ParaMEDMEM::BlockTopology* _block_topology; + // stores the x,y,z axes on the global grid + std::vector<std::vector<double> > _global_axis; + //id of the local grid + int _my_domain_id; + }; +} + +#endif diff --git a/src/ParaMEDMEM/ParaMESH.cxx b/src/ParaMEDMEM/ParaMESH.cxx new file mode 100644 index 000000000..438aa3894 --- /dev/null +++ b/src/ParaMEDMEM/ParaMESH.cxx @@ -0,0 +1,99 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "ParaMESH.hxx" +#include "ProcessorGroup.hxx" +#include "MPIProcessorGroup.hxx" +#include "Topology.hxx" +#include "BlockTopology.hxx" +#include "MemArray.hxx" + +#include <fstream> +#include <vector> + +//inclusion for the namespaces +using namespace std; + +namespace ParaMEDMEM +{ + ParaMESH::ParaMESH( MEDCouplingUMesh *subdomain_mesh, MEDCouplingUMesh *subdomain_face, + DataArrayInt *CorrespElt_local2global, DataArrayInt *CorrespFace_local2global, + DataArrayInt *CorrespNod_local2global, const ProcessorGroup& proc_group ): + _cell_mesh(subdomain_mesh), + _face_mesh(subdomain_face), + _my_domain_id(proc_group.myRank()), + _block_topology (new BlockTopology(proc_group, subdomain_mesh->getNumberOfCells())), + _explicit_topology(0), + _node_global(CorrespNod_local2global), + _face_global(CorrespFace_local2global), + _cell_global(CorrespElt_local2global) + { + if(_cell_mesh) + _cell_mesh->incrRef(); + if(_face_mesh) + _face_mesh->incrRef(); + if(CorrespElt_local2global) + CorrespElt_local2global->incrRef(); + if(CorrespFace_local2global) + CorrespFace_local2global->incrRef(); + if(CorrespNod_local2global) + CorrespNod_local2global->incrRef(); + } + + ParaMESH::ParaMESH( MEDCouplingUMesh *mesh, const ProcessorGroup& proc_group, const std::string& name): + _cell_mesh(mesh), + _face_mesh(0), + _my_domain_id(proc_group.myRank()), + _block_topology (new BlockTopology(proc_group, mesh->getNumberOfCells())), + _node_global(0), + _face_global(0) + { + if(_cell_mesh) + _cell_mesh->incrRef(); + int nb_elem=mesh->getNumberOfCells(); + _explicit_topology=new BlockTopology(proc_group,nb_elem); + int nbOfCells=mesh->getNumberOfCells(); + _cell_global = DataArrayInt::New(); + _cell_global->alloc(nbOfCells,1); + int *cellglobal=_cell_global->getPointer(); + int offset = _block_topology->localToGlobal(make_pair(_my_domain_id,0)); + for (int i=0; i<nbOfCells; i++) + { + cellglobal[i]=offset+i; + } + } + + ParaMESH::~ParaMESH() + { + if(_cell_mesh) + _cell_mesh->decrRef(); + if(_face_mesh) + _face_mesh->decrRef(); + delete _block_topology; + if(_node_global) + _node_global->decrRef(); + if(_cell_global) + _cell_global->decrRef(); + if(_face_global) + _face_global->decrRef(); + if(_node_global) + _node_global->decrRef(); + delete _explicit_topology; + } + +} diff --git a/src/ParaMEDMEM/ParaMESH.hxx b/src/ParaMEDMEM/ParaMESH.hxx new file mode 100644 index 000000000..7e82ed3c4 --- /dev/null +++ b/src/ParaMEDMEM/ParaMESH.hxx @@ -0,0 +1,75 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __PARAMESH_HXX__ +#define __PARAMESH_HXX__ + +#include "MEDCouplingUMesh.hxx" +#include "ProcessorGroup.hxx" + +#include <string> +#include <vector> + +namespace ParaMEDMEM +{ + class Topology; + class BlockTopology; + class DataArrayInt; + + class ParaMESH + { + public: + ParaMESH( MEDCouplingUMesh *subdomain_mesh, + MEDCouplingUMesh *subdomain_face, + DataArrayInt *CorrespElt_local2global, + DataArrayInt *CorrespFace_local2global, + DataArrayInt *CorrespNod_local2global, + const ProcessorGroup& proc_group ) ; + ParaMESH( MEDCouplingUMesh *mesh, + const ProcessorGroup& proc_group, const std::string& name); + + virtual ~ParaMESH(); + Topology* getTopology() const { return _explicit_topology; } + bool isStructured() const { return _cell_mesh->isStructured(); } + MEDCouplingUMesh *getCellMesh() const { return _cell_mesh; } + MEDCouplingUMesh *getFaceMesh() const { return _face_mesh; } + BlockTopology* getBlockTopology() const { return _block_topology; } + + const int* getGlobalNumberingNode() const { return _node_global->getPointer(); } + const int* getGlobalNumberingFace() const { return _face_global->getPointer(); } + const int* getGlobalNumberingCell() const { return _cell_global->getPointer(); } + + private: + //mesh object underlying the ParaMESH object + MEDCouplingUMesh *_cell_mesh ; + MEDCouplingUMesh *_face_mesh ; + + //id of the local grid + int _my_domain_id; + + //global topology of the cells + ParaMEDMEM::BlockTopology* _block_topology; + Topology* _explicit_topology; + // pointers to global numberings + DataArrayInt* _node_global; + DataArrayInt* _face_global; + DataArrayInt* _cell_global; + }; +} + +#endif diff --git a/src/ParaMEDMEM/ProcessorGroup.cxx b/src/ParaMEDMEM/ProcessorGroup.cxx new file mode 100644 index 000000000..2bae1610a --- /dev/null +++ b/src/ParaMEDMEM/ProcessorGroup.cxx @@ -0,0 +1,31 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "ProcessorGroup.hxx" +#include "InterpolationUtils.hxx" + +namespace ParaMEDMEM +{ + ProcessorGroup::ProcessorGroup (const CommInterface& interface, int start, int end):_comm_interface(interface) + { + if (start>end) + throw INTERP_KERNEL::Exception("wrong call to Processor group constructor"); + for (int i=start; i<=end;i++) + _proc_ids.insert(i); + } +} diff --git a/src/ParaMEDMEM/ProcessorGroup.hxx b/src/ParaMEDMEM/ProcessorGroup.hxx new file mode 100644 index 000000000..c19154089 --- /dev/null +++ b/src/ParaMEDMEM/ProcessorGroup.hxx @@ -0,0 +1,56 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __PROCESSORGROUP_HXX__ +#define __PROCESSORGROUP_HXX__ + +#include "CommInterface.hxx" + +#include <set> + +namespace ParaMEDMEM +{ + class ProcessorGroup + { + public: + + ProcessorGroup(const CommInterface& interface):_comm_interface(interface) { } + ProcessorGroup(const CommInterface& interface, std::set<int> proc_ids): + _comm_interface(interface),_proc_ids(proc_ids) { } + ProcessorGroup (const ProcessorGroup& proc_group, std::set<int> proc_ids): + _comm_interface(proc_group.getCommInterface()) { } + ProcessorGroup (const CommInterface& interface, int start, int end); + virtual ~ProcessorGroup() { } + virtual ProcessorGroup* fuse (const ProcessorGroup&) const = 0; + virtual void intersect (ProcessorGroup&) = 0; + bool contains(int rank) const { return _proc_ids.find(rank)!=_proc_ids.end(); } + virtual bool containsMyRank() const= 0; + int size() const { return _proc_ids.size(); } + const CommInterface& getCommInterface()const { return _comm_interface; } + virtual int myRank() const = 0; + virtual int translateRank(const ProcessorGroup*, int) const =0; + virtual ProcessorGroup* createComplementProcGroup() const =0; + virtual ProcessorGroup* createProcGroup() const=0; + virtual const std::set<int>& getProcIDs()const { return _proc_ids; } + protected: + const CommInterface _comm_interface; + std::set<int> _proc_ids; + }; +} + +#endif diff --git a/src/ParaMEDMEM/README_JR b/src/ParaMEDMEM/README_JR new file mode 100644 index 000000000..3039608eb --- /dev/null +++ b/src/ParaMEDMEM/README_JR @@ -0,0 +1,446 @@ + +CVS : +===== + +Branche : BR_MEDPARA : MED_SRC +setenv CVSROOT :pserver:rahuel@cvs.opencascade.com:/home/server/cvs/MED +cvs login +... + +Repertoires : +============= + +Sources : /home/rahuel/MEDPARAsynch +Construction sur awa : /data/tmpawa/rahuel/MEDPARAsynch/MED_Build +Intallation sur awa : /data/tmpawa/rahuel/MEDPARAsynch/MED_Install + + +Environnement : +=============== + +source /home/rahuel/MEDPARAsynch/env_products.csh + +On utilise : +/data/tmpawa/vb144235/valgrind-3.2.1/valgrind_install/bin +/data/tmpawa/adam/Salome3/V3_2_7_AWA_OCC/Python-2.4.1 +/data/tmpawa/vb144235/med_231_install +/data/tmpawa2/adam/omniORB/omniORB-4.0.7 +/data/tmpawa/vb144235/lam_install +/data/tmpawa/vb144235/cppunit_install +/data/tmpawa/vb144235/fvm_install_lam +/data/tmpawa/vb144235/bft_install +/home/rahuel/MEDPARAsynch/ICoCo +/data/tmpawa2/adam/Salome3/V3_2_0_maintainance/KERNEL/KERNEL_INSTALL + + +Build_Configure et Configure : +============================== + +MEDMEM est en "stand-alone" sans KERNEL ni IHM. + +cd $MED_BUILD_DIR +${MED_SRC_DIR}/build_configure --without-kernel --without-ihm +rm ${MED_SRC_DIR}/adm_local_without_kernel/adm_local_without_kernel +rm -fR $MED_BUILD_DIR/adm_local_without_kernel/adm_local_without_kernel + +cd $MED_BUILD_DIR +${MED_SRC_DIR}/configure --without-kernel --without-ihm --with-lam=/data/tmpawa/vb144235/lam_install --prefix=${MED_ROOT_DIR} --with-med2=/data/tmpawa/vb144235/med_231_install --with-python=/data/tmpawa/adam/Salome3/V3_2_7_AWA_OCC/Python-2.4.1 --with-cppunit=/data/tmpawa/vb144235/cppunit_install --with-cppunit_inc=/data/tmpawa/vb144235/cppunit_install/include --with-fvm=/data/tmpawa/vb144235/fvm_install_lam +rm ${MED_SRC_DIR}/adm_local_without_kernel/adm_local_without_kernel +rm -fR $MED_BUILD_DIR/adm_local_without_kernel/adm_local_without_kernel + + +Construction : +============== + +cd $MED_BUILD_DIR +make +make install + +Problemes de construction : +=========================== + +Liste des fichiers modifies et differents de la base CVS pour pouvoir +effectuer la construction et l'installation : + +M MED_SRC/configure.in.base : +----------------------------- +CHECK_MPICH +CHECK_LAM +CHECK_OPENMPI mis en commentaire (redefinit le resultat de CHECK_LAM) +CHECK_CPPUNIT a ete ajoute + +M MED_SRC/adm_local_without_kernel/unix/config_files/check_lam.m4 : +------------------------------------------------------------------- +Debugs pour trouver la bonne configuration de LAM + +M MED_SRC/src/INTERP_KERNEL/Makefile.in : +----------------------------------------- +Problemes de construction des tests + +M MED_SRC/src/ParaMEDMEM/Makefile.in : +-------------------------------------- +. Construction de libParaMEDMEM.a pour gcov (link statique) +. Ajout d'options de compilations : -fprofile-arcs -ftest-coverage -pg (gcov) ==> + instrumentation du code + +C MED_SRC/src/ParaMEDMEM/Test/Makefile.in : +------------------------------------------- +. Construction de libParaMEDMEMTest.a pour gcov (link statique) +. Ajout d'options de compilations : -fprofile-arcs -ftest-coverage -pg (gcov) ==> + instrumentation du code +. Prise en compte de $(MED_WITH_KERNEL) avec : + ifeq ($(MED_WITH_KERNEL),yes) + LDFLAGSFORBIN += $(LDFLAGS) -lm $(MED2_LIBS) $(HDF5_LIBS) $(MPI_LIBS) \ + -L$(top_builddir)/lib@LIB_LOCATION_SUFFIX@/salome -lmed_V2_1 -lparamed -lmedmem \ + ${KERNEL_LDFLAGS} -lSALOMELocalTrace -lSALOMEBasics \ + $(CPPUNIT_LIBS) \ + -lParaMEDMEMTest + endif + ifeq ($(MED_WITH_KERNEL),no) + LDFLAGSFORBIN += $(LDFLAGS) -lm $(MED2_LIBS) $(HDF5_LIBS) $(MPI_LIBS) \ + -L$(top_builddir)/lib@LIB_LOCATION_SUFFIX@/salome -lmed_V2_1 -lparamed -linterpkernel -lmedmem \ + ${KERNEL_LDFLAGS} ${FVM_LIBS} ${CPPUNIT_LIBS} -L/data/tmpawa/vb144235/bft_install/lib -lbft\ + -lParaMEDMEMTest + endif + +M MED_SRC/src/ParaMEDMEM/Test/ParaMEDMEMTest.hxx : +-------------------------------------------------- +Mise en commentaire du test manquant : +CPPUNIT_TEST(testNonCoincidentDEC_3D); + +U MED_SRC/src/ParaMEDMEM/Test/ParaMEDMEMTest_NonCoincidentDEC.cxx : +------------------------------------------------------------------- +Manque dans CVS + +Pour forcer la reconstruction des tests : +========================================= + +cd $MED_BUILD_DIR +rm src/ParaMEDMEM/*o +rm src/ParaMEDMEM/*.la +rm src/ParaMEDMEM/test_* +rm src/ParaMEDMEM/.libs/* +rm src/ParaMEDMEM/Test/*o +rm src/ParaMEDMEM/Test/*.la +rm src/ParaMEDMEM/Test/.libs/* +rm core.* +rm vgcore.* +cd $MED_BUILD_DIR/src/ParaMEDMEM/Test +make +make install +cd $MED_BUILD_DIR + + +Probleme avec lam : +=================== + +jr[1175]> mpirun -np 5 -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} TestParaMEDMEM +21508 TestParaMEDMEM running on n0 (o) +21509 TestParaMEDMEM running on n0 (o) +21510 TestParaMEDMEM running on n0 (o) +21511 TestParaMEDMEM running on n0 (o) +21512 TestParaMEDMEM running on n0 (o) +- Trace /home/rahuel/MEDPARAsynch/MED_SRC/src/MEDMEM/MEDMEM_Init.cxx [54] : Med Memory Initialization with $SALOME_trace = local +- Trace /home/rahuel/MEDPARAsynch/MED_SRC/src/MEDMEM/MEDMEM_Init.cxx [54] : Med Memory Initialization with $SALOME_trace = local +- Trace /home/rahuel/MEDPARAsynch/MED_SRC/src/MEDMEM/MEDMEM_Init.cxx [54] : Med Memory Initialization with $SALOME_trace = local +- Trace /home/rahuel/MEDPARAsynch/MED_SRC/src/MEDMEM/MEDMEM_Init.cxx [54] : Med Memory Initialization with $SALOME_trace = local +- Trace /home/rahuel/MEDPARAsynch/MED_SRC/src/MEDMEM/MEDMEM_Init.cxx [54] : Med Memory Initialization with $SALOME_trace = local +----------------------------------------------------------------------------- +The selected RPI failed to initialize during MPI_INIT. This is a +fatal error; I must abort. + +This occurred on host awa (n0). +The PID of failed process was 21508 (MPI_COMM_WORLD rank: 0) +----------------------------------------------------------------------------- +----------------------------------------------------------------------------- +One of the processes started by mpirun has exited with a nonzero exit +code. This typically indicates that the process finished in error. +If your process did not finish in error, be sure to include a "return +0" or "exit(0)" in your C code before exiting the application. + +PID 21510 failed on node n0 (127.0.0.1) with exit status 1. +----------------------------------------------------------------------------- +jr[1176]> + + +Contournement du probleme lam : +=============================== + +mpirun -np 5 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} TestParaMEDMEM + + +Valgrind : +========== +. Les tests avec valgrind indiquent des erreurs dans MPI_Init et + MPI_Finalize ainsi que dans des programmes appeles "below main". +. De plus on obtient un "Segmentation Violation" accompagne d'un + fichier "vgcore.*" (plantage de valgrind) +. Mais on a " All heap blocks were freed -- no leaks are possible." + et on n'a aucune erreur de malloc/free new/delete dans ParaMEDMEM et + dans les tests. + +. Cependant si on execute les tests sans valgrind, il n'y a pas + d'erreur ni de fichier "core.*". + + +Tests avec CPPUNIT de $MED_BUILD_DIR/src/ParaMEDMEM/Test : +========================================================== + +L'appel a MPI_Init n'est fait qu'une seule fois. +Il est suivi par l'execution de toute la suite des tests regroupes +dans les trois executables TestParaMEDMEM, TestMPIAccessDEC et +TestMPIAccess +On a enfin un seul appel a MPI_Finalize. + +Si un des tests d'une suite de tests comporte une anomalie cela +peut avoir des implications sur l'execution des tests suivants. + +Lors de la mise au point de la suite de tests de TestMPIAccessDEC +cela etait le cas : il restait des messages postes dans lam mais +non lus. Le test suivant s'executait de plus en plus lentement +sans donner d'erreur (probleme difficile a identifier). + + +Lancement des tests de TestParaMEDMEM avec CPPUNIT et TotalView (option -tv) : +============================================================================== + +mpirun -np 5 -ssi rpi tcp C -tv -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} TestParaMEDMEM + +Il arrive qu'on ne puisse pas utiliser totalview par manque de +license. + + + +Lancement des tests de TestParaMEDMEM avec CPPUNIT et Valgrind avec "memory leaks" : +==================================================================================== + +mpirun -np 5 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full TestParaMEDMEM + + +Lancement des tests fonctionnels de MPI_AccessDEC avec CPPUNIT : +================================================================ + +mpirun -np 11 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full TestMPIAccessDEC + + +Lancement des tests unitaires de MPI_Access avec CPPUNIT : +========================================================== + +mpirun -np 3 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full TestMPIAccess + + +TestMPIAccess/TestMPIAccessDEC/TestParaMEDMEM et gcov : +======================================================= + +Les resultats sont dans les repertoires suivants de $MED_BUILD_DIR/src/ParaMEDMEM/Test : +------------- + + TestParaMEDMEM-gcov/ + TestMPIAccessDEC-gcov/ + TestMPIAccess-gcov/ + +Je n'y ai pas trouve d'anomalies. + +compilation : -fprofile-arcs -ftest-coverage +------------- + +$MED_BUILD_DIR/src/ParaMEDMEM/makefile.in : LIB=libparamedar.a \ +------------------------------------------- libparamed.la + +$MED_BUILD_DIR/src/ParaMEDMEM/Test/makefile.in : LIB = libParaMEDMEMTestar.a \ +------------------------------------------------ libParaMEDMEMTest.la + +links statiques manuels : +------------------------- + +g++ -g -D_DEBUG_ -Wno-deprecated -Wparentheses -Wreturn-type -Wunused -DPCLINUX -I/data/tmpawa/vb144235/cppunit_install/include -I/data/tmpawa/vb144235/lam_install/include -ftemplate-depth-42 -I/home/rahuel/MEDPARAsynch/MED_SRC/src/ParaMEDMEM -fprofile-arcs -ftest-coverage -o TestMPIAccess TestMPIAccess.lo -L../../../lib64/salome -lstdc++ -L../../../lib64/salome -lstdc++ -lm -L/data/tmpawa/vb144235/med_231_install/lib -lmed -lhdf5 -lhdf5 -L/data/tmpawa/vb144235/lam_install/lib -llam -lmpi -L../../../lib64/salome -lmed_V2_1 --whole-archive -linterpkernel -lmedmem -L/data/tmpawa/vb144235/fvm_install_lam/lib -lfvm -L/data/tmpawa/vb144235/cppunit_install/lib -lcppunit -L/data/tmpawa/vb144235/bft_install/lib -lbft -lutil -lm -lrt -ldl -Bstatic -L./ -lParaMEDMEMTestar -L../ -lparamedar -L./ -lParaMEDMEMTestar + +g++ -g -D_DEBUG_ -Wno-deprecated -Wparentheses -Wreturn-type -Wunused -DPCLINUX -I/data/tmpawa/vb144235/cppunit_install/include -I/data/tmpawa/vb144235/lam_install/include -ftemplate-depth-42 -I/home/rahuel/MEDPARAsynch/MED_SRC/src/ParaMEDMEM -fprofile-arcs -ftest-coverage -o TestMPIAccessDEC TestMPIAccessDEC.lo -L../../../lib64/salome -lstdc++ -L../../../lib64/salome -lstdc++ -lm -L/data/tmpawa/vb144235/med_231_install/lib -lmed -lhdf5 -lhdf5 -L/data/tmpawa/vb144235/lam_install/lib -llam -lmpi -L../../../lib64/salome -lmed_V2_1 --whole-archive -linterpkernel -lmedmem -L/data/tmpawa/vb144235/fvm_install_lam/lib -lfvm -L/data/tmpawa/vb144235/cppunit_install/lib -lcppunit -L/data/tmpawa/vb144235/bft_install/lib -lbft -lutil -lm -lrt -ldl -Bstatic -L./ -lParaMEDMEMTestar -L../ -lparamedar -L./ -lParaMEDMEMTestar + +g++ -g -D_DEBUG_ -Wno-deprecated -Wparentheses -Wreturn-type -Wunused -DPCLINUX -I/data/tmpawa/vb144235/cppunit_install/include -I/data/tmpawa/vb144235/lam_install/include -ftemplate-depth-42 -I/home/rahuel/MEDPARAsynch/MED_SRC/src/ParaMEDMEM -fprofile-arcs -ftest-coverage -o TestParaMEDMEM TestParaMEDMEM.lo -L../../../lib64/salome -lstdc++ -L../../../lib64/salome -lstdc++ -lm -L/data/tmpawa/vb144235/med_231_install/lib -lmed -lhdf5 -lhdf5 -L/data/tmpawa/vb144235/lam_install/lib -llam -lmpi -L../../../lib64/salome -lmed_V2_1 --whole-archive -linterpkernel -lmedmem -L/data/tmpawa/vb144235/fvm_install_lam/lib -lfvm -L/data/tmpawa/vb144235/cppunit_install/lib -lcppunit -L/data/tmpawa/vb144235/bft_install/lib -lbft -lutil -lm -lrt -ldl -Bstatic -L./ -lParaMEDMEMTestar -L../ -lparamedar -L./ -lParaMEDMEMTestar + +Ne pas oublier le make install apres ... + +execution et gcov : +------------------- + +Pour pouvoir traiter les .cxx de ${MED_BUILD_DIR}/src/ParaMEDMEM et de +${MED_BUILD_DIR}/src/ParaMEDMEM/Test, on execute deux fois gcov. + +cd ${MED_BUILD_DIR}/src/ParaMEDMEM/Test + +mpirun -np 3 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} TestMPIAccess + +gcov TestMPIAccess.cxx test_MPI_Access_Send_Recv.cxx \ + test_MPI_Access_Cyclic_Send_Recv.cxx \ + test_MPI_Access_SendRecv.cxx \ + test_MPI_Access_ISend_IRecv.cxx \ + test_MPI_Access_Cyclic_ISend_IRecv.cxx \ + test_MPI_Access_ISendRecv.cxx \ + test_MPI_Access_Probe.cxx \ + test_MPI_Access_IProbe.cxx \ + test_MPI_Access_Cancel.cxx \ + test_MPI_Access_Send_Recv_Length.cxx \ + test_MPI_Access_ISend_IRecv_Length.cxx \ + test_MPI_Access_ISend_IRecv_Length_1.cxx \ + test_MPI_Access_Time.cxx \ + test_MPI_Access_Time_0.cxx \ + test_MPI_Access_ISend_IRecv_BottleNeck.cxx \ + ../MPI_Access.cxx +gcov -o ../ TestMPIAccess.cxx test_MPI_Access_Send_Recv.cxx \ + test_MPI_Access_Cyclic_Send_Recv.cxx \ + test_MPI_Access_SendRecv.cxx \ + test_MPI_Access_ISend_IRecv.cxx \ + test_MPI_Access_Cyclic_ISend_IRecv.cxx \ + test_MPI_Access_ISendRecv.cxx \ + test_MPI_Access_Probe.cxx \ + test_MPI_Access_IProbe.cxx \ + test_MPI_Access_Cancel.cxx \ + test_MPI_Access_Send_Recv_Length.cxx \ + test_MPI_Access_ISend_IRecv_Length.cxx \ + test_MPI_Access_ISend_IRecv_Length_1.cxx \ + test_MPI_Access_Time.cxx \ + test_MPI_Access_Time_0.cxx \ + test_MPI_Access_ISend_IRecv_BottleNeck.cxx \ + ../MPI_Access.cxx + + +cd ${MED_BUILD_DIR}/src/ParaMEDMEM/Test +mpirun -np 11 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} TestMPIAccessDEC + +gcov TestMPIAccessDEC.cxx test_AllToAllDEC.cxx \ + test_AllToAllvDEC.cxx \ + test_AllToAllTimeDEC.cxx \ + test_AllToAllvTimeDEC.cxx \ + test_AllToAllvTimeDoubleDEC.cxx \ + ../TimeInterpolator.cxx \ + ../LinearTimeInterpolator.cxx \ + ../MPI_Access.cxx \ + ../MPI_AccessDEC.cxx +gcov -o ../ TestMPIAccessDEC.cxx test_AllToAllDEC.cxx \ + test_AllToAllvDEC.cxx \ + test_AllToAllTimeDEC.cxx \ + test_AllToAllvTimeDEC.cxx \ + test_AllToAllvTimeDoubleDEC.cxx \ + ../TimeInterpolator.cxx \ + ../LinearTimeInterpolator.cxx \ + ../MPI_Access.cxx \ + ../MPI_AccessDEC.cxx + +cd ${MED_BUILD_DIR}/src/ParaMEDMEM/Test +mpirun -np 5 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} TestParaMEDMEM + +gcov TestParaMEDMEM.cxx ParaMEDMEMTest.cxx \ + ParaMEDMEMTest_MPIProcessorGroup.cxx \ + ParaMEDMEMTest_BlockTopology.cxx \ + ParaMEDMEMTest_IntersectionDEC.cxx \ + ../BlockTopology.cxx \ + ../ComponentTopology.cxx \ + ../DEC.cxx \ + ../ElementLocator.cxx \ + ../InterpolationMatrix.cxx \ + ../IntersectionDEC.cxx \ + ../MPIProcessorGroup.cxx \ + ../MxN_Mapping.cxx \ + ../ParaFIELD.cxx \ + ../ParaMESH.cxx \ + ../ParaSUPPORT.cxx \ + ../ProcessorGroup.cxx \ + ../TimeInterpolator.cxx \ + ../LinearTimeInterpolator.cxx \ + ../MPI_Access.cxx \ + ../MPI_AccessDEC.cxx + +gcov -o ../ TestParaMEDMEM.cxx ParaMEDMEMTest.cxx \ + ParaMEDMEMTest_MPIProcessorGroup.cxx \ + ParaMEDMEMTest_BlockTopology.cxx \ + ParaMEDMEMTest_IntersectionDEC.cxx \ + ../BlockTopology.cxx \ + ../ComponentTopology.cxx \ + ../DEC.cxx \ + ../ElementLocator.cxx \ + ../InterpolationMatrix.cxx \ + ../IntersectionDEC.cxx \ + ../MPIProcessorGroup.cxx \ + ../MxN_Mapping.cxx \ + ../ParaFIELD.cxx \ + ../ParaMESH.cxx \ + ../ParaSUPPORT.cxx \ + ../ProcessorGroup.cxx \ + ../TimeInterpolator.cxx \ + ../LinearTimeInterpolator.cxx \ + ../MPI_Access.cxx \ + ../MPI_AccessDEC.cxx + + + + + +Lancement des tests unitaires sans CPPUNIT : +============================================ + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_Send_Recv + +mpirun -np 3 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_Cyclic_Send_Recv + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_SendRecv + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_ISend_IRecv + +mpirun -np 3 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_Cyclic_ISend_IRecv + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_ISendRecv + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_Probe + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_IProbe + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_Cancel + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_Send_Recv_Length + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_ISend_IRecv_Length + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_ISend_IRecv_Length_1 + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_Time + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_Time_0 2 1 + + +#AllToAllDEC +mpirun -np 4 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllDEC 0 + +mpirun -np 4 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllDEC 1 + + +#AllToAllvDEC +mpirun -np 4 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllvDEC 0 + +mpirun -np 4 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllvDEC 1 + + +#AllToAllTimeDEC +mpirun -np 4 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllTimeDEC 0 + +mpirun -np 4 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllTimeDEC 1 + + +#AllToAllvTimeDEC +mpirun -np 11 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllvTimeDEC 0 1 + +mpirun -np 11 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllvTimeDEC 0 + +mpirun -np 11 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllvTimeDEC 1 + + + +#AllToAllvTimeDoubleDEC +mpirun -np 11 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllvTimeDoubleDEC 0 + +mpirun -np 11 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_AllToAllvTimeDoubleDEC 1 + + + +mpirun -np 2 -ssi rpi tcp C -v -x PATH=${PATH},LD_LIBRARY_PATH=${LD_LIBRARY_PATH} valgrind --leak-check=full test_MPI_Access_ISend_IRecv_BottleNeck + diff --git a/src/ParaMEDMEM/StructuredCoincidentDEC.cxx b/src/ParaMEDMEM/StructuredCoincidentDEC.cxx new file mode 100644 index 000000000..6beb34df6 --- /dev/null +++ b/src/ParaMEDMEM/StructuredCoincidentDEC.cxx @@ -0,0 +1,411 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <mpi.h> +#include "CommInterface.hxx" +#include "Topology.hxx" +#include "BlockTopology.hxx" +#include "ComponentTopology.hxx" +#include "ParaFIELD.hxx" +#include "MPIProcessorGroup.hxx" +#include "StructuredCoincidentDEC.hxx" +#include "InterpKernelUtilities.hxx" + +#include <iostream> + +using namespace std; + +namespace ParaMEDMEM +{ + + /*! \defgroup structuredcoincidentdec StructuredCoincidentDEC + + This class is meant for remapping fields that have identical + supports with different parallel topologies. It can be used to couple + together multiphysics codes that operate on the same domain + with different partitionings, which can be useful if one of + the computation is much faster than the other. It can also be used + to couple together codes that share an interface that was generated + in the same manner (with identical global ids). + Also, this DEC can be used for fields that have component topologies, + i.e., components that are scattered over several processors. + + The remapping between the two supports is based on identity of global + ids, instead of geometrical considerations as it is the case for + NonCoincidentDEC and IntersectionDEC. Therefore, this DEC must not be used + for coincident meshes that do not have the same numbering. + + As all the other DECs, its use is made of two phases : + - a setup phase during whih the topologies are exchanged so that + the target side knows from which processors it should expect + the data. + - a send/recv phase during which the field data is actually transferred. + + This example illustrates the sending of a field with + the DEC : + \code + ... + StructuredCoincidentDEC dec(groupA, groupB); + dec.attachLocalField(field); + dec.synchronize(); + if (groupA.containsMyRank()) + dec.recvData(); + else if (groupB.containsMyRank()) + dec.sendData(); + ... + \endcode + + Creating a ParaFIELD to be attached to the DEC is exactly the same as for + other DECs in the case when the remapping concerns similar meshes + that only have different partitionings. In the case when the + fields have also different component topologies, creating the ParaFIELD + requires some more effort. See \ref parafield section for more details. + */ + + + StructuredCoincidentDEC::StructuredCoincidentDEC():_topo_source(0),_topo_target(0), + _recv_buffer(0),_send_buffer(0), + _recv_counts(0),_send_counts(0), + _recv_displs(0),_send_displs(0) + { + } + + + StructuredCoincidentDEC::~StructuredCoincidentDEC() + { + delete[] _send_buffer; + delete[] _recv_buffer; + delete[]_send_displs; + delete[] _recv_displs; + delete[] _send_counts; + delete[] _recv_counts; + if (! _source_group->containsMyRank()) + delete _topo_source; + if(!_target_group->containsMyRank()) + delete _topo_target; + } + + /*! + \addtogroup structuredcoincidentdec + @{ + */ + StructuredCoincidentDEC::StructuredCoincidentDEC(ProcessorGroup& local_group, ProcessorGroup& distant_group):DEC(local_group,distant_group),_topo_source(0),_topo_target(0),_recv_buffer(0),_send_buffer(0) + { + } + + /*! Synchronization process for exchanging topologies + */ + void StructuredCoincidentDEC::synchronizeTopology() + { + if (_source_group->containsMyRank()) + _topo_source = dynamic_cast<BlockTopology*>(_local_field->getTopology()); + if (_target_group->containsMyRank()) + _topo_target = dynamic_cast<BlockTopology*>(_local_field->getTopology()); + + // Transmitting source topology to target code + broadcastTopology(_topo_source,1000); + // Transmitting target topology to source code + broadcastTopology(_topo_target,2000); + if (_topo_source->getNbElements() != _topo_target->getNbElements()) + throw INTERP_KERNEL::Exception("Incompatible dimensions for target and source topologies"); + + } + + /*! Creates the arrays necessary for the data transfer + * and fills the send array with the values of the + * source field + * */ + void StructuredCoincidentDEC::prepareSourceDE() + { + //////////////////////////////////// + //Step 1 : _buffer array creation + + if (!_topo_source->getProcGroup()->containsMyRank()) + return; + MPIProcessorGroup* group=new MPIProcessorGroup(_topo_source->getProcGroup()->getCommInterface()); + + int myranksource = _topo_source->getProcGroup()->myRank(); + + vector <int>* target_arrays=new vector<int>[_topo_target->getProcGroup()->size()]; + + //cout<<" topotarget size"<< _topo_target->getProcGroup()->size()<<endl; + + int nb_local = _topo_source-> getNbLocalElements(); + for (int ielem=0; ielem< nb_local ; ielem++) + { + // cout <<"source local :"<<myranksource<<","<<ielem<<endl; + int global = _topo_source->localToGlobal(make_pair(myranksource, ielem)); + // cout << "global "<<global<<endl; + pair<int,int> target_local =_topo_target->globalToLocal(global); + // cout << "target local : "<<target_local.first<<","<<target_local.second<<endl; + target_arrays[target_local.first].push_back(target_local.second); + } + + int union_size=group->size(); + + _send_counts=new int[union_size]; + _send_displs=new int[union_size]; + _recv_counts=new int[union_size]; + _recv_displs=new int[union_size]; + + for (int i=0; i< union_size; i++) + { + _send_counts[i]=0; + _recv_counts[i]=0; + _recv_displs[i]=0; + } + _send_displs[0]=0; + + for (int iproc=0; iproc < _topo_target->getProcGroup()->size(); iproc++) + { + //converts the rank in target to the rank in union communicator + int unionrank=group->translateRank(_topo_target->getProcGroup(),iproc); + _send_counts[unionrank]=target_arrays[iproc].size(); + } + + for (int iproc=1; iproc<group->size();iproc++) + _send_displs[iproc]=_send_displs[iproc-1]+_send_counts[iproc-1]; + + _send_buffer = new double [nb_local ]; + + ///////////////////////////////////////////////////////////// + //Step 2 : filling the _buffers with the source field values + + int* counter=new int [_topo_target->getProcGroup()->size()]; + counter[0]=0; + for (int i=1; i<_topo_target->getProcGroup()->size(); i++) + counter[i]=counter[i-1]+target_arrays[i-1].size(); + + + const double* value = _local_field->getField()->getArray()->getPointer(); + //cout << "Nb local " << nb_local<<endl; + for (int ielem=0; ielem<nb_local ; ielem++) + { + int global = _topo_source->localToGlobal(make_pair(myranksource, ielem)); + pair<int,int> target_local =_topo_target->globalToLocal(global); + //cout <<"global : "<< global<<" local :"<<target_local.first<<" "<<target_local.second; + //cout <<"counter[]"<<counter[target_local.first]<<endl; + _send_buffer[counter[target_local.first]++]=value[ielem]; + + } + delete[] target_arrays; + delete[] counter; + delete group; + } + + /*! + * Creates the _buffers for receiving the fields on the target side + */ + void StructuredCoincidentDEC::prepareTargetDE() + { + if (!_topo_target->getProcGroup()->containsMyRank()) + return; + MPIProcessorGroup* group=new MPIProcessorGroup(_topo_source->getProcGroup()->getCommInterface()); + + int myranktarget = _topo_target->getProcGroup()->myRank(); + + vector < vector <int> > source_arrays(_topo_source->getProcGroup()->size()); + int nb_local = _topo_target-> getNbLocalElements(); + for (int ielem=0; ielem< nb_local ; ielem++) + { + // cout <<"TS target local :"<<myranktarget<<","<<ielem<<endl; + int global = _topo_target->localToGlobal(make_pair(myranktarget, ielem)); + //cout << "TS global "<<global<<endl; + pair<int,int> source_local =_topo_source->globalToLocal(global); + // cout << "TS source local : "<<source_local.first<<","<<source_local.second<<endl; + source_arrays[source_local.first].push_back(source_local.second); + } + int union_size=group->size(); + _recv_counts=new int[union_size]; + _recv_displs=new int[union_size]; + _send_counts=new int[union_size]; + _send_displs=new int[union_size]; + + for (int i=0; i< union_size; i++) + { + _send_counts[i]=0; + _recv_counts[i]=0; + _recv_displs[i]=0; + } + for (int iproc=0; iproc < _topo_source->getProcGroup()->size(); iproc++) + { + //converts the rank in target to the rank in union communicator + int unionrank=group->translateRank(_topo_source->getProcGroup(),iproc); + _recv_counts[unionrank]=source_arrays[iproc].size(); + } + for (int i=1; i<union_size; i++) + _recv_displs[i]=_recv_displs[i-1]+_recv_counts[i-1]; + _recv_buffer=new double[nb_local]; + + delete group; + } + + + /*! + * Synchronizing a topology so that all the + * group possesses it. + * + * \param topo Topology that is transmitted. It is read on processes where it already exists, and it is created and filled on others. + * \param tag Communication tag associated with this operation. + */ + void StructuredCoincidentDEC::broadcastTopology(BlockTopology*& topo, int tag) + { + MPI_Status status; + + int* serializer=0; + int size; + + MPIProcessorGroup* group=new MPIProcessorGroup(*_comm_interface); + + // The master proc creates a send buffer containing + // a serialized topology + int rank_master; + + if (topo!=0 && topo->getProcGroup()->myRank()==0) + { + MESSAGE ("Master rank"); + topo->serialize(serializer, size); + rank_master = group->translateRank(topo->getProcGroup(),0); + MESSAGE("Master rank world number is "<<rank_master); + MESSAGE("World Size is "<<group->size()); + for (int i=0; i< group->size(); i++) + { + if (i!= rank_master) + _comm_interface->send(&rank_master,1,MPI_INT, i,tag+i,*(group->getComm())); + } + } + else + { + MESSAGE(" rank "<<group->myRank()<< " waiting ..."); + _comm_interface->recv(&rank_master, 1,MPI_INT, MPI_ANY_SOURCE, tag+group->myRank(), *(group->getComm()),&status); + MESSAGE(" rank "<<group->myRank()<< "received master rank"<<rank_master); + } + // The topology is broadcasted to all processsors in the group + _comm_interface->broadcast(&size, 1,MPI_INT,rank_master,*(group->getComm())); + + int* buffer=new int[size]; + if (topo!=0 && topo->getProcGroup()->myRank()==0) + copy(serializer, serializer+size, buffer); + _comm_interface->broadcast(buffer,size,MPI_INT,rank_master,*(group->getComm())); + + // Processors which did not possess the source topology + // unserialize it + + BlockTopology* topotemp=new BlockTopology(); + topotemp->unserialize(buffer, *_comm_interface); + + if (topo==0) + topo=topotemp; + else + delete topotemp; + + // Memory cleaning + delete[] buffer; + if (serializer!=0) + delete[] serializer; + MESSAGE (" rank "<<group->myRank()<< " unserialize is over"); + delete group; + } + + + + void StructuredCoincidentDEC::recvData() + { + //MPI_COMM_WORLD is used instead of group because there is no + //mechanism for creating the union group yet + MESSAGE("recvData"); + for (int i=0; i< 4; i++) + cout << _recv_counts[i]<<" "; + cout <<endl; + for (int i=0; i< 4; i++) + cout << _recv_displs[i]<<" "; + cout <<endl; + + cout<<"start AllToAll"<<endl; + MPI_Comm comm = *(dynamic_cast<MPIProcessorGroup*>(_union_group)->getComm()); + _comm_interface->allToAllV(_send_buffer, _send_counts, _send_displs, MPI_DOUBLE, + _recv_buffer, _recv_counts, _recv_displs, MPI_DOUBLE,comm); + cout<<"end AllToAll"<<endl; + + int nb_local = _topo_target->getNbLocalElements(); + //double* value=new double[nb_local]; + double* value=const_cast<double*>(_local_field->getField()->getArray()->getPointer()); + + int myranktarget=_topo_target->getProcGroup()->myRank(); + vector<int> counters(_topo_source->getProcGroup()->size()); + counters[0]=0; + for (int i=0; i<_topo_source->getProcGroup()->size()-1; i++) + { + MPIProcessorGroup* group=new MPIProcessorGroup(*_comm_interface); + int worldrank=group->translateRank(_topo_source->getProcGroup(),i); + counters[i+1]=counters[i]+_recv_counts[worldrank]; + delete group; + } + + for (int ielem=0; ielem<nb_local ; ielem++) + { + int global = _topo_target->localToGlobal(make_pair(myranktarget, ielem)); + pair<int,int> source_local =_topo_source->globalToLocal(global); + value[ielem]=_recv_buffer[counters[source_local.first]++]; + } + + + //_local_field->getField()->setValue(value); + } + + void StructuredCoincidentDEC::sendData() + { + MESSAGE ("sendData"); + for (int i=0; i< 4; i++) + cout << _send_counts[i]<<" "; + cout <<endl; + for (int i=0; i< 4; i++) + cout << _send_displs[i]<<" "; + cout <<endl; + cout <<"start AllToAll"<<endl; + MPI_Comm comm = *(dynamic_cast<MPIProcessorGroup*>(_union_group)->getComm()); + _comm_interface->allToAllV(_send_buffer, _send_counts, _send_displs, MPI_DOUBLE, + _recv_buffer, _recv_counts, _recv_displs, MPI_DOUBLE,comm); + cout<<"end AllToAll"<<endl; + } + + /*! Prepares a DEC for data exchange + + This method broadcasts the topologies from source to target + so that the target side can analyse from which processors it + is expected to receive data. + */ + + void StructuredCoincidentDEC::synchronize() + { + if (_source_group->containsMyRank()) + { + synchronizeTopology(); + prepareSourceDE(); + } + else if (_target_group->containsMyRank()) + { + synchronizeTopology(); + prepareTargetDE(); + } + } + /*! + @} + */ +} + diff --git a/src/ParaMEDMEM/StructuredCoincidentDEC.hxx b/src/ParaMEDMEM/StructuredCoincidentDEC.hxx new file mode 100644 index 000000000..e61ced216 --- /dev/null +++ b/src/ParaMEDMEM/StructuredCoincidentDEC.hxx @@ -0,0 +1,57 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __STRUCTUREDCOINCIDENTDEC_HXX__ +#define __STRUCTUREDCOINCIDENTDEC_HXX__ + +#include "DEC.hxx" +#include "BlockTopology.hxx" + + +namespace ParaMEDMEM +{ + class DEC; + class BlockTopology; + class StructuredCoincidentDEC : public DEC + { + public: + StructuredCoincidentDEC(); + StructuredCoincidentDEC( ProcessorGroup& source, ProcessorGroup& target); + virtual ~StructuredCoincidentDEC(); + void synchronize(); + void recvData(); + void sendData(); + void prepareSourceDE(); + void prepareTargetDE(); + + private : + void synchronizeTopology(); + void broadcastTopology(BlockTopology*&, int tag); + + BlockTopology* _topo_source; + BlockTopology* _topo_target; + int* _send_counts; + int* _recv_counts; + int* _send_displs; + int* _recv_displs; + double* _recv_buffer; + double* _send_buffer; + }; +} + +#endif diff --git a/src/ParaMEDMEM/TODO_JR b/src/ParaMEDMEM/TODO_JR new file mode 100644 index 000000000..de2318d54 --- /dev/null +++ b/src/ParaMEDMEM/TODO_JR @@ -0,0 +1,50 @@ + +MPI_Access : +============ + +. Creer des methodes [I]SendRecv en point a point avec un "target" + pour le Send et un "target" pour le Recv comme le SendRecv MPI. + +. Ne pas creer de structure RequestStruct en mode synchrone. + + +MPI_AccessDEC : +=============== + +. AllToAll, AllToAllv, AllToAllTime et AllToAllvTime comportent + des sequences de code semblables qui pourraient etre regroupees + sans que cela nuise a la lisibilite du code. + +. En mode asynchrone, il n'y a pas de controle d'engorgement des + messages envoyes dans CheckSent(). Il est vrai qu'en pratique + une synchronisation des temps est faite dans AllToAllTime et + AllToAllvTime. Mais ce probleme pourrait se produire avec + AllToAll et AllToAllv. Il serait possible de fixer un nombre + maximum de messages envoyes et "en cours" et de le comparer avec + le nombre de requetes rendu par MPI_Access. En cas de depassement + de ?n?*UnionGroupSize par exemple, CheckSent pourrait fonctionner + en mode "WithWait". Ce qui ferait qu'on apellerait Wait au lieu de Test. + +. Meme si le prototype d'interpolateur comporte des parametres + int nStepBefore et int nStepAfter, le codage actuel considere + qu'on n'a que nStepBefore=1 et nStepAfter=1. + Ainsi on a (*_TimeMessages)[target][0] et (*_TimeMessages)[target][1] + ainsi que &(*_DataMessages)[target][0] et &(*_DataMessages)[target][1]. + +. Les champs nStepBefore et nStepAfter correspondent a un maximum + requis. On devrait avoir les champs correspondants qui valent les + nombres disponibles a un moment donne. + +. Il existe un champs OutOfTime qui n'est pas utilise actuellement. + Il faudrait definir son usage et le transmettre sans doute à + l'interpolateur. Actuellement, L'interpolateur lineaire effectue une + extrapolation si OutOfTime vaut true. + +. Dans CheckTime, on alloue et detruit les (*_DataMessages)[target][] + alors qu'on pourrait considerer que pour un "target" donne, les + recvcount sont constants pendant toute la boucle de temps. Ainsi + on n'allouerait les buffers qu'une fois au depart et ils ne seraient + liberes qu'a la fin. + + + diff --git a/src/ParaMEDMEM/Test/MPIAccessDECTest.cxx b/src/ParaMEDMEM/Test/MPIAccessDECTest.cxx new file mode 100644 index 000000000..f9ae283ac --- /dev/null +++ b/src/ParaMEDMEM/Test/MPIAccessDECTest.cxx @@ -0,0 +1,47 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "MPIAccessDECTest.hxx" +#include <cppunit/TestAssert.h> + +#include <sstream> +#include <cmath> + +using namespace std; + + + +/*! + * Tool to remove temporary files. + * Allows automatique removal of temporary files in case of test failure. + */ +MPIAccessDECTest_TmpFilesRemover::~MPIAccessDECTest_TmpFilesRemover() +{ + set<string>::iterator it = myTmpFiles.begin(); + for (; it != myTmpFiles.end(); it++) { + if (access((*it).data(), F_OK) == 0) + remove((*it).data()); + } + myTmpFiles.clear(); + //cout << "~MPIAccessTest_TmpFilesRemover()" << endl; +} + +bool MPIAccessDECTest_TmpFilesRemover::Register(const string theTmpFile) +{ + return (myTmpFiles.insert(theTmpFile)).second; +} diff --git a/src/ParaMEDMEM/Test/MPIAccessDECTest.hxx b/src/ParaMEDMEM/Test/MPIAccessDECTest.hxx new file mode 100644 index 000000000..9f14a40cb --- /dev/null +++ b/src/ParaMEDMEM/Test/MPIAccessDECTest.hxx @@ -0,0 +1,101 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef _MPIACCESSDECTEST_HXX_ +#define _MPIACCESSDECTEST_HXX_ + +#include <cppunit/extensions/HelperMacros.h> + +#include <set> +#include <string> +#include <iostream> +#include "mpi.h" + + +class MPIAccessDECTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( MPIAccessDECTest ); + // CPPUNIT_TEST( test_AllToAllDECSynchronousPointToPoint ) ; + CPPUNIT_TEST( test_AllToAllDECAsynchronousPointToPoint ) ; + //CPPUNIT_TEST( test_AllToAllvDECSynchronousPointToPoint ) ; + CPPUNIT_TEST( test_AllToAllvDECAsynchronousPointToPoint ) ; + //CPPUNIT_TEST( test_AllToAllTimeDECSynchronousPointToPoint ) ; + CPPUNIT_TEST( test_AllToAllTimeDECAsynchronousPointToPoint ) ; + CPPUNIT_TEST( test_AllToAllvTimeDECSynchronousNative ) ; + //CPPUNIT_TEST( test_AllToAllvTimeDECSynchronousPointToPoint ) ; + CPPUNIT_TEST( test_AllToAllvTimeDECAsynchronousPointToPoint ) ; + //CPPUNIT_TEST( test_AllToAllvTimeDoubleDECSynchronousPointToPoint ) ; + CPPUNIT_TEST( test_AllToAllvTimeDoubleDECAsynchronousPointToPoint ) ; + CPPUNIT_TEST_SUITE_END(); + + +public: + + MPIAccessDECTest():CppUnit::TestFixture(){} + ~MPIAccessDECTest(){} + void setUp(){} + void tearDown(){} + void test_AllToAllDECSynchronousPointToPoint() ; + void test_AllToAllDECAsynchronousPointToPoint() ; + void test_AllToAllvDECSynchronousPointToPoint() ; + void test_AllToAllvDECAsynchronousPointToPoint() ; + void test_AllToAllTimeDECSynchronousPointToPoint() ; + void test_AllToAllTimeDECAsynchronousPointToPoint() ; + void test_AllToAllvTimeDECSynchronousNative() ; + void test_AllToAllvTimeDECSynchronousPointToPoint() ; + void test_AllToAllvTimeDECAsynchronousPointToPoint() ; + void test_AllToAllvTimeDoubleDECSynchronousPointToPoint() ; + void test_AllToAllvTimeDoubleDECAsynchronousPointToPoint() ; + +private: + void test_AllToAllDEC( bool Asynchronous ) ; + void test_AllToAllvDEC( bool Asynchronous ) ; + void test_AllToAllTimeDEC( bool Asynchronous ) ; + void test_AllToAllvTimeDEC( bool Asynchronous , bool UseMPINative ) ; + void test_AllToAllvTimeDoubleDEC( bool Asynchronous ) ; + }; + +// to automatically remove temporary files from disk +class MPIAccessDECTest_TmpFilesRemover +{ +public: + MPIAccessDECTest_TmpFilesRemover() {} + ~MPIAccessDECTest_TmpFilesRemover(); + bool Register(const std::string theTmpFile); + +private: + std::set<std::string> myTmpFiles; +}; + +/*! + * Tool to print array to stream. + */ +template<class T> +void MPIAccessDECTest_DumpArray (std::ostream & stream, const T* array, const int length, const std::string text) +{ + stream << text << ": {"; + if (length > 0) { + stream << array[0]; + for (int i = 1; i < length; i++) { + stream << ", " << array[i]; + } + } + stream << "}" << std::endl; +}; + +#endif diff --git a/src/ParaMEDMEM/Test/MPIAccessTest.cxx b/src/ParaMEDMEM/Test/MPIAccessTest.cxx new file mode 100644 index 000000000..e07a55e5f --- /dev/null +++ b/src/ParaMEDMEM/Test/MPIAccessTest.cxx @@ -0,0 +1,47 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "MPIAccessTest.hxx" +#include <cppunit/TestAssert.h> + +#include <sstream> +#include <cmath> + +using namespace std; + + + +/*! + * Tool to remove temporary files. + * Allows automatique removal of temporary files in case of test failure. + */ +MPIAccessTest_TmpFilesRemover::~MPIAccessTest_TmpFilesRemover() +{ + set<string>::iterator it = myTmpFiles.begin(); + for (; it != myTmpFiles.end(); it++) { + if (access((*it).data(), F_OK) == 0) + remove((*it).data()); + } + myTmpFiles.clear(); + //cout << "~MPIAccessTest_TmpFilesRemover()" << endl; +} + +bool MPIAccessTest_TmpFilesRemover::Register(const string theTmpFile) +{ + return (myTmpFiles.insert(theTmpFile)).second; +} diff --git a/src/ParaMEDMEM/Test/MPIAccessTest.hxx b/src/ParaMEDMEM/Test/MPIAccessTest.hxx new file mode 100644 index 000000000..308e6d2af --- /dev/null +++ b/src/ParaMEDMEM/Test/MPIAccessTest.hxx @@ -0,0 +1,104 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef _MPIACCESSTEST_HXX_ +#define _MPIACCESSTEST_HXX_ + +#include <cppunit/extensions/HelperMacros.h> + +#include <set> +#include <string> +#include <iostream> +#include "mpi.h" + + +class MPIAccessTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( MPIAccessTest ); + CPPUNIT_TEST( test_MPI_Access_Send_Recv ) ; + CPPUNIT_TEST( test_MPI_Access_Cyclic_Send_Recv ) ; + CPPUNIT_TEST( test_MPI_Access_SendRecv ) ; + CPPUNIT_TEST( test_MPI_Access_ISend_IRecv ) ; + CPPUNIT_TEST( test_MPI_Access_Cyclic_ISend_IRecv ) ; + CPPUNIT_TEST( test_MPI_Access_ISendRecv ) ; + CPPUNIT_TEST( test_MPI_Access_Probe ) ; + CPPUNIT_TEST( test_MPI_Access_IProbe ) ; + CPPUNIT_TEST( test_MPI_Access_Cancel ) ; + CPPUNIT_TEST( test_MPI_Access_Send_Recv_Length ) ; + CPPUNIT_TEST( test_MPI_Access_ISend_IRecv_Length ) ; + CPPUNIT_TEST( test_MPI_Access_ISend_IRecv_Length_1 ) ; + CPPUNIT_TEST( test_MPI_Access_Time ) ; + CPPUNIT_TEST( test_MPI_Access_Time_0 ) ; + CPPUNIT_TEST( test_MPI_Access_ISend_IRecv_BottleNeck ) ; + CPPUNIT_TEST_SUITE_END(); + + +public: + + MPIAccessTest():CppUnit::TestFixture(){} + ~MPIAccessTest(){} + void setUp(){} + void tearDown(){} + void test_MPI_Access_Send_Recv() ; + void test_MPI_Access_Cyclic_Send_Recv() ; + void test_MPI_Access_SendRecv() ; + void test_MPI_Access_ISend_IRecv() ; + void test_MPI_Access_Cyclic_ISend_IRecv() ; + void test_MPI_Access_ISendRecv() ; + void test_MPI_Access_Probe() ; + void test_MPI_Access_IProbe() ; + void test_MPI_Access_Cancel() ; + void test_MPI_Access_Send_Recv_Length() ; + void test_MPI_Access_ISend_IRecv_Length() ; + void test_MPI_Access_ISend_IRecv_Length_1() ; + void test_MPI_Access_Time() ; + void test_MPI_Access_Time_0() ; + void test_MPI_Access_ISend_IRecv_BottleNeck() ; + +private: + }; + +// to automatically remove temporary files from disk +class MPIAccessTest_TmpFilesRemover +{ +public: + MPIAccessTest_TmpFilesRemover() {} + ~MPIAccessTest_TmpFilesRemover(); + bool Register(const std::string theTmpFile); + +private: + std::set<std::string> myTmpFiles; +}; + +/*! + * Tool to print array to stream. + */ +template<class T> +void MPIAccessTest_DumpArray (std::ostream & stream, const T* array, const int length, const std::string text) +{ + stream << text << ": {"; + if (length > 0) { + stream << array[0]; + for (int i = 1; i < length; i++) { + stream << ", " << array[i]; + } + } + stream << "}" << std::endl; +}; + +#endif diff --git a/src/ParaMEDMEM/Test/MPIMainTest.hxx b/src/ParaMEDMEM/Test/MPIMainTest.hxx new file mode 100644 index 000000000..9d07ab32d --- /dev/null +++ b/src/ParaMEDMEM/Test/MPIMainTest.hxx @@ -0,0 +1,97 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef _MPIMAINTEST_HXX_ +#define _MPIMAINTEST_HXX_ + +#include <cppunit/CompilerOutputter.h> +#include <cppunit/TestResult.h> +#include <cppunit/TestResultCollector.h> +#include <cppunit/TextTestProgressListener.h> +#include <cppunit/BriefTestProgressListener.h> +#include <cppunit/extensions/TestFactoryRegistry.h> +#include <cppunit/TestRunner.h> +#include <stdexcept> + +#include <mpi.h> + +#include <iostream> +#include <fstream> + +// ============================================================================ +/*! + * Main program source for Unit Tests with cppunit package does not depend + * on actual tests, so we use the same for all partial unit tests. + */ +// ============================================================================ + +int main(int argc, char* argv[]) +{ + MPI_Init(&argc,&argv); + int rank; + MPI_Comm_rank(MPI_COMM_WORLD,&rank); + + // --- Create the event manager and test controller + CPPUNIT_NS::TestResult controller; + + // --- Add a listener that colllects test result + CPPUNIT_NS::TestResultCollector result; + controller.addListener( &result ); + + // --- Add a listener that print dots as test run. +#ifdef WIN32 + CPPUNIT_NS::TextTestProgressListener progress; +#else + CPPUNIT_NS::BriefTestProgressListener progress; +#endif + controller.addListener( &progress ); + + // --- Get the top level suite from the registry + + CPPUNIT_NS::Test *suite = + CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest(); + + // --- Adds the test to the list of test to run + + CPPUNIT_NS::TestRunner runner; + runner.addTest( suite ); + runner.run( controller); + + // --- Print test in a compiler compatible format. + + std::ostringstream testFileName; + testFileName<<"UnitTestResult"<<rank; + std::ofstream testFile; + testFile.open(testFileName.str().c_str(), std::ios::out | std::ios::trunc); + //CPPUNIT_NS::CompilerOutputter outputter( &result, std::cerr ); + CPPUNIT_NS::CompilerOutputter outputter( &result, testFile ); + outputter.write(); + + // --- Run the tests. + + bool wasSucessful = result.wasSuccessful(); + testFile.close(); + + // --- Return error code 1 if the one of test failed. + + MPI_Finalize(); + + return wasSucessful ? 0 : 1; +} + +#endif diff --git a/src/ParaMEDMEM/Test/Makefile.am b/src/ParaMEDMEM/Test/Makefile.am new file mode 100644 index 000000000..2591c99a3 --- /dev/null +++ b/src/ParaMEDMEM/Test/Makefile.am @@ -0,0 +1,102 @@ +# Copyright (C) 2007-2008 CEA/DEN, 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. +# +# 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 +# + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +lib_LTLIBRARIES = libParaMEDMEMTest.la + +salomeinclude_HEADERS = MPIMainTest.hxx \ + MPIAccessDECTest.hxx \ + MPIAccessTest.hxx \ + ParaMEDMEMTest.hxx + +EXTRA_DIST += MPIMainTest.hxx ParaMEDMEMTest_NonCoincidentDEC.cxx +dist_libParaMEDMEMTest_la_SOURCES= \ + ParaMEDMEMTest.cxx \ + ParaMEDMEMTest_MPIProcessorGroup.cxx \ + ParaMEDMEMTest_BlockTopology.cxx \ + ParaMEDMEMTest_IntersectionDEC.cxx \ + ParaMEDMEMTest_StructuredCoincidentDEC.cxx \ + MPIAccessDECTest.cxx \ + test_AllToAllDEC.cxx \ + test_AllToAllvDEC.cxx \ + test_AllToAllTimeDEC.cxx \ + test_AllToAllvTimeDEC.cxx \ + test_AllToAllvTimeDoubleDEC.cxx \ + MPIAccessTest.cxx \ + test_MPI_Access_Send_Recv.cxx \ + test_MPI_Access_Cyclic_Send_Recv.cxx \ + test_MPI_Access_SendRecv.cxx \ + test_MPI_Access_ISend_IRecv.cxx \ + test_MPI_Access_Cyclic_ISend_IRecv.cxx \ + test_MPI_Access_ISendRecv.cxx \ + test_MPI_Access_Probe.cxx \ + test_MPI_Access_IProbe.cxx \ + test_MPI_Access_Cancel.cxx \ + test_MPI_Access_Send_Recv_Length.cxx \ + test_MPI_Access_ISend_IRecv_Length.cxx \ + test_MPI_Access_ISend_IRecv_Length_1.cxx \ + test_MPI_Access_Time.cxx \ + test_MPI_Access_Time_0.cxx \ + test_MPI_Access_ISend_IRecv_BottleNeck.cxx + + +libParaMEDMEMTest_la_CPPFLAGS= @CPPUNIT_INCLUDES@ \ + $(MPI_INCLUDES) \ + -I$(srcdir)/../../INTERP_KERNEL \ + -I$(srcdir)/../../INTERP_KERNEL/Bases \ + -I$(srcdir)/../../INTERP_KERNEL/Geometric2D \ + -I$(srcdir)/../../ParaMEDMEM \ + -I$(srcdir)/../../MEDCoupling \ + -I$(srcdir)/../MEDLoader + +libParaMEDMEMTest_la_LDFLAGS= ../MEDLoader/libparamedmemmedloader.la @CPPUNIT_LIBS@ $(MPI_LIBS) + +if MED_ENABLE_KERNEL + libParaMEDMEMTest_la_CPPFLAGS+= ${KERNEL_CXXFLAGS} + libParaMEDMEMTest_la_LDFLAGS+= ${KERNEL_LDFLAGS} -lSALOMELocalTrace +endif + +# Executables targets +bin_PROGRAMS = TestParaMEDMEM \ + TestMPIAccessDEC \ + TestMPIAccess + +dist_TestParaMEDMEM_SOURCES = TestParaMEDMEM.cxx +dist_TestMPIAccessDEC_SOURCES = TestMPIAccessDEC.cxx +dist_TestMPIAccess_SOURCES = TestMPIAccess.cxx + +LDADD= $(MED2_LIBS) $(libMEDMEMTest_la_LDFLAGS) -lm $(MPI_LIBS) \ + ../libparamedmem.la libParaMEDMEMTest.la \ + ../../INTERP_KERNEL/libinterpkernel.la + +if MED_ENABLE_KERNEL + LDADD+= -lSALOMEBasics +endif + +if MED_ENABLE_FVM + LDADD += $(FVM_LIBS) + dist_libParaMEDMEMTest_la_SOURCES += ParaMEDMEMTest_NonCoincidentDEC.cxx + libParaMEDMEMTest_la_CPPFLAGS+= -DMED_ENABLE_FVM $(FVM_INCLUDES) + libParaMEDMEMTest_la_LDFLAGS+= $(FVM_LIBS) +endif + +AM_CPPFLAGS= $(libParaMEDMEMTest_la_CPPFLAGS) + +UNIT_TEST_PROG = TestParaMEDMEM diff --git a/src/ParaMEDMEM/Test/ParaMEDMEMTest.cxx b/src/ParaMEDMEM/Test/ParaMEDMEMTest.cxx new file mode 100644 index 000000000..f5c43bebd --- /dev/null +++ b/src/ParaMEDMEM/Test/ParaMEDMEMTest.cxx @@ -0,0 +1,47 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "ParaMEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include <sstream> +#include <cmath> + +using namespace std; + + + +/*! + * Tool to remove temporary files. + * Allows automatique removal of temporary files in case of test failure. + */ +ParaMEDMEMTest_TmpFilesRemover::~ParaMEDMEMTest_TmpFilesRemover() +{ + set<string>::iterator it = myTmpFiles.begin(); + for (; it != myTmpFiles.end(); it++) { + if (access((*it).data(), F_OK) == 0) + remove((*it).data()); + } + myTmpFiles.clear(); + //cout << "~ParaMEDMEMTest_TmpFilesRemover()" << endl; +} + +bool ParaMEDMEMTest_TmpFilesRemover::Register(const string theTmpFile) +{ + return (myTmpFiles.insert(theTmpFile)).second; +} diff --git a/src/ParaMEDMEM/Test/ParaMEDMEMTest.hxx b/src/ParaMEDMEM/Test/ParaMEDMEMTest.hxx new file mode 100644 index 000000000..baab1b7af --- /dev/null +++ b/src/ParaMEDMEM/Test/ParaMEDMEMTest.hxx @@ -0,0 +1,136 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef _ParaMEDMEMTEST_HXX_ +#define _ParaMEDMEMTEST_HXX_ + +#include <cppunit/extensions/HelperMacros.h> + +#include <set> +#include <string> +#include <iostream> +#include "mpi.h" + + +class ParaMEDMEMTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( ParaMEDMEMTest ); + CPPUNIT_TEST(testMPIProcessorGroup_constructor); + CPPUNIT_TEST(testMPIProcessorGroup_boolean); + CPPUNIT_TEST(testMPIProcessorGroup_rank); + CPPUNIT_TEST(testBlockTopology_constructor); + CPPUNIT_TEST(testBlockTopology_serialize); + CPPUNIT_TEST(testIntersectionDEC_2D); + CPPUNIT_TEST(testIntersectionDEC_2DP0P1); + + CPPUNIT_TEST(testSynchronousEqualIntersectionWithoutInterpNativeDEC_2D); + CPPUNIT_TEST(testSynchronousEqualIntersectionWithoutInterpDEC_2D); + CPPUNIT_TEST(testSynchronousEqualIntersectionDEC_2D); + CPPUNIT_TEST(testSynchronousFasterSourceIntersectionDEC_2D); + CPPUNIT_TEST(testSynchronousSlowerSourceIntersectionDEC_2D); + CPPUNIT_TEST(testSynchronousSlowSourceIntersectionDEC_2D); + CPPUNIT_TEST(testSynchronousFastSourceIntersectionDEC_2D); + CPPUNIT_TEST(testAsynchronousEqualIntersectionDEC_2D); + CPPUNIT_TEST(testAsynchronousFasterSourceIntersectionDEC_2D); + CPPUNIT_TEST(testAsynchronousSlowerSourceIntersectionDEC_2D); + CPPUNIT_TEST(testAsynchronousSlowSourceIntersectionDEC_2D); + CPPUNIT_TEST(testAsynchronousFastSourceIntersectionDEC_2D); +#ifdef MED_ENABLE_FVM + //can be added again after FVM correction for 2D + // CPPUNIT_TEST(testNonCoincidentDEC_2D); + CPPUNIT_TEST(testNonCoincidentDEC_3D); +#endif + CPPUNIT_TEST(testStructuredCoincidentDEC); + CPPUNIT_TEST_SUITE_END(); + + +public: + + ParaMEDMEMTest():CppUnit::TestFixture(){} + ~ParaMEDMEMTest(){} + void setUp(){} + void tearDown(){} + void testMPIProcessorGroup_constructor(); + void testMPIProcessorGroup_boolean(); + void testMPIProcessorGroup_rank(); + void testBlockTopology_constructor(); + void testBlockTopology_serialize(); + void testIntersectionDEC_2D(); + void testIntersectionDEC_2DP0P1(); +#ifdef MED_ENABLE_FVM + void testNonCoincidentDEC_2D(); + void testNonCoincidentDEC_3D(); +#endif + void testStructuredCoincidentDEC(); + void testSynchronousEqualIntersectionWithoutInterpNativeDEC_2D(); + void testSynchronousEqualIntersectionWithoutInterpDEC_2D(); + void testSynchronousEqualIntersectionDEC_2D(); + void testSynchronousFasterSourceIntersectionDEC_2D(); + void testSynchronousSlowerSourceIntersectionDEC_2D(); + void testSynchronousSlowSourceIntersectionDEC_2D(); + void testSynchronousFastSourceIntersectionDEC_2D(); + + void testAsynchronousEqualIntersectionDEC_2D(); + void testAsynchronousFasterSourceIntersectionDEC_2D(); + void testAsynchronousSlowerSourceIntersectionDEC_2D(); + void testAsynchronousSlowSourceIntersectionDEC_2D(); + void testAsynchronousFastSourceIntersectionDEC_2D(); + + +private: + void testNonCoincidentDEC(const std::string& filename1, + const std::string& meshname1, + const std::string& filename2, + const std::string& meshname2, + int nbprocsource, double epsilon); + void testAsynchronousIntersectionDEC_2D(double dtA, double tmaxA, + double dtB, double tmaxB, + bool WithPointToPoint, bool Asynchronous, bool WithInterp, const char *srcMeth, const char *targetMeth); + void testIntersectionDEC_2D_(const char *srcMeth, const char *targetMeth); + +}; + +// to automatically remove temporary files from disk +class ParaMEDMEMTest_TmpFilesRemover +{ +public: + ParaMEDMEMTest_TmpFilesRemover() {} + ~ParaMEDMEMTest_TmpFilesRemover(); + bool Register(const std::string theTmpFile); + +private: + std::set<std::string> myTmpFiles; +}; + +/*! + * Tool to print array to stream. + */ +template<class T> +void ParaMEDMEMTest_DumpArray (std::ostream & stream, const T* array, const int length, const std::string text) +{ + stream << text << ": {"; + if (length > 0) { + stream << array[0]; + for (int i = 1; i < length; i++) { + stream << ", " << array[i]; + } + } + stream << "}" << std::endl; +}; + +#endif diff --git a/src/ParaMEDMEM/Test/ParaMEDMEMTest_BlockTopology.cxx b/src/ParaMEDMEM/Test/ParaMEDMEMTest_BlockTopology.cxx new file mode 100644 index 000000000..f116ff2a7 --- /dev/null +++ b/src/ParaMEDMEM/Test/ParaMEDMEMTest_BlockTopology.cxx @@ -0,0 +1,122 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "ParaMEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "InterpolationUtils.hxx" +#include "CommInterface.hxx" +#include "ProcessorGroup.hxx" +#include "MPIProcessorGroup.hxx" +#include "Topology.hxx" +#include "BlockTopology.hxx" + +#include <string> + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + + +using namespace std; +using namespace ParaMEDMEM; + +/* + * Check methods defined in BlockTopology.hxx + * + BlockTopology(){}; + BlockTopology(const ProcessorGroup& group, const MEDMEM::GRID& grid); + BlockTopology(const BlockTopology& geom_topo, const ComponentTopology& comp_topo); + (+) BlockTopology(const ProcessorGroup& group, int nb_elem); + virtual ~BlockTopology(); + (+) inline int getNbElements()const; + (+) inline int getNbLocalElements() const; + const ProcessorGroup* getProcGroup()const {return _proc_group;}; + (+) inline std::pair<int,int> globalToLocal (const int) const ; + (+) inline int localToGlobal (const std::pair<int,int>) const; + (+) std::vector<std::pair<int,int> > getLocalArrayMinMax() const ; + (+) int getDimension() const {return _dimension;}; + (+) void serialize(int* & serializer, int& size) const ; + (+) void unserialize(const int* serializer, const CommInterface& comm_interface); + + */ + +void ParaMEDMEMTest::testBlockTopology_constructor() +{ + //test constructor + int size; + MPI_Comm_size(MPI_COMM_WORLD,&size); + int rank; + MPI_Comm_rank(MPI_COMM_WORLD,&rank); + CommInterface interface; + MPIProcessorGroup group(interface); + BlockTopology blocktopo(group,1); + CPPUNIT_ASSERT_EQUAL(1,blocktopo.getNbLocalElements()); + CPPUNIT_ASSERT_EQUAL(size,blocktopo.getNbElements()); + CPPUNIT_ASSERT_EQUAL(1,blocktopo.getDimension()); + + //checking access methods + BlockTopology blocktopo2(group,2); + std::pair<int,int> local= blocktopo2.globalToLocal(0); + CPPUNIT_ASSERT_EQUAL(local.first,0); + CPPUNIT_ASSERT_EQUAL(local.second,0); + int global=blocktopo2.localToGlobal(local); + CPPUNIT_ASSERT_EQUAL(global,0); + + local = blocktopo2.globalToLocal(1); + CPPUNIT_ASSERT_EQUAL(local.first,0); + CPPUNIT_ASSERT_EQUAL(local.second,1); + global=blocktopo2.localToGlobal(local); + CPPUNIT_ASSERT_EQUAL(global,1); + + local = blocktopo2.globalToLocal(2*size-1); + CPPUNIT_ASSERT_EQUAL(local.first,size-1); + CPPUNIT_ASSERT_EQUAL(local.second,1); + global=blocktopo2.localToGlobal(local); + CPPUNIT_ASSERT_EQUAL(global,2*size-1); + + std::vector<std::pair<int,int> > bounds = blocktopo2.getLocalArrayMinMax(); + int vecsize = bounds.size(); + CPPUNIT_ASSERT_EQUAL(1,vecsize); + CPPUNIT_ASSERT_EQUAL(2*rank, (bounds[0]).first); + CPPUNIT_ASSERT_EQUAL(2*rank+2, (bounds[0]).second); + } + +void ParaMEDMEMTest::testBlockTopology_serialize() +{ + + int size; + MPI_Comm_size(MPI_COMM_WORLD,&size); + int rank; + MPI_Comm_rank(MPI_COMM_WORLD,&rank); + CommInterface interface; + MPIProcessorGroup group(interface); + BlockTopology blocktopo(group,3); + +//testing the serialization process that is used to transfer a +//block topology via a MPI_Send/Recv comm + BlockTopology blocktopo_recv; + int* serializer; + int sersize; + blocktopo.serialize(serializer,sersize); + blocktopo_recv.unserialize(serializer,interface); + CPPUNIT_ASSERT_EQUAL(blocktopo.getNbElements(),blocktopo_recv.getNbElements()); + delete [] serializer; +} diff --git a/src/ParaMEDMEM/Test/ParaMEDMEMTest_IntersectionDEC.cxx b/src/ParaMEDMEM/Test/ParaMEDMEMTest_IntersectionDEC.cxx new file mode 100644 index 000000000..144f888b7 --- /dev/null +++ b/src/ParaMEDMEM/Test/ParaMEDMEMTest_IntersectionDEC.cxx @@ -0,0 +1,541 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "ParaMEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "CommInterface.hxx" +#include "ProcessorGroup.hxx" +#include "MPIProcessorGroup.hxx" +#include "Topology.hxx" +#include "DEC.hxx" +#include "MxN_Mapping.hxx" +#include "IntersectionDEC.hxx" +#include "ParaMESH.hxx" +#include "ParaFIELD.hxx" +#include "ICoCoMEDField.hxx" +#include "MEDLoader.hxx" + +#include <string> + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + + +using namespace std; +using namespace ParaMEDMEM; + +void ParaMEDMEMTest::testIntersectionDEC_2D() +{ + testIntersectionDEC_2D_("P0","P0"); +} + +void ParaMEDMEMTest::testIntersectionDEC_2DP0P1() +{ + //testIntersectionDEC_2D_("P0","P1"); +} + +/* + * Check methods defined in IntersectionDEC.hxx + * + IntersectionDEC(); + IntersectionDEC(ProcessorGroup& local_group, ProcessorGroup& distant_group); + virtual ~IntersectionDEC(); + void synchronize(); + void recvData(); + void sendData(); +*/ + +void ParaMEDMEMTest::testIntersectionDEC_2D_(const char *srcMeth, const char *targetMeth) +{ + std::string srcM(srcMeth); + std::string targetM(targetMeth); + int size; + int rank; + MPI_Comm_size(MPI_COMM_WORLD,&size); + MPI_Comm_rank(MPI_COMM_WORLD,&rank); + + //the test is meant to run on five processors + if (size !=5) return ; + + int nproc_source = 3; + set<int> self_procs; + set<int> procs_source; + set<int> procs_target; + + for (int i=0; i<nproc_source; i++) + procs_source.insert(i); + for (int i=nproc_source; i<size; i++) + procs_target.insert(i); + self_procs.insert(rank); + + ParaMEDMEM::CommInterface interface; + + ParaMEDMEM::ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs); + ParaMEDMEM::ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target); + ParaMEDMEM::ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source); + + //loading the geometry for the source group + + ParaMEDMEM::IntersectionDEC dec (*source_group,*target_group); + + ParaMEDMEM::MEDCouplingUMesh* mesh; + ParaMEDMEM::ParaMESH* paramesh; + ParaMEDMEM::ParaFIELD* parafield; + ICoCo::Field* icocofield ; + + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP"); + if (tmp_dir == "") + tmp_dir = "/tmp"; + string filename_xml1 = data_dir + "/share/salome/resources/med/square1_split"; + string filename_xml2 = data_dir + "/share/salome/resources/med/square2_split"; + string filename_seq_wr = tmp_dir + "/"; + string filename_seq_med = tmp_dir + "/myWrField_seq_pointe221.med"; + + // To remove tmp files from disk + ParaMEDMEMTest_TmpFilesRemover aRemover; + + MPI_Barrier(MPI_COMM_WORLD); + if (source_group->containsMyRank()) + { + string master = filename_xml1; + + ostringstream strstream; + strstream <<master<<rank+1<<".med"; + ostringstream meshname ; + meshname<< "Mesh_2_"<< rank+1; + + mesh=MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0); + + + paramesh=new ParaMESH (mesh,*source_group,"source mesh"); + + // ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT( support,*source_group); + ParaMEDMEM::ComponentTopology comptopo; + if(srcM=="P0") + parafield = new ParaFIELD(ON_CELLS,paramesh, comptopo); + else + parafield = new ParaFIELD(ON_NODES,paramesh, comptopo); + int nb_local; + if(srcM=="P0") + nb_local=mesh->getNumberOfCells(); + else + nb_local=mesh->getNumberOfNodes(); + // double * value= new double[nb_local]; + double *value=parafield->getField()->getArray()->getPointer(); + for(int ielem=0; ielem<nb_local;ielem++) + value[ielem]=1.0; + + // ICoCo::Field* icocofield=new ICoCo::MEDField(paramesh,parafield); + icocofield=new ICoCo::MEDField(paramesh,parafield); + dec.setMethod(srcMeth); + dec.attachLocalField(icocofield); + } + + //loading the geometry for the target group + if (target_group->containsMyRank()) + { + string master= filename_xml2; + ostringstream strstream; + strstream << master<<(rank-nproc_source+1)<<".med"; + ostringstream meshname ; + meshname<< "Mesh_3_"<<rank-nproc_source+1; + mesh = MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0); + + paramesh=new ParaMESH (mesh,*target_group,"target mesh"); + // ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT(support,*target_group); + ParaMEDMEM::ComponentTopology comptopo; + if(targetM=="P0") + parafield = new ParaFIELD(ON_CELLS,paramesh, comptopo); + else + parafield = new ParaFIELD(ON_NODES,paramesh, comptopo); + int nb_local; + if(targetM=="P0") + nb_local=mesh->getNumberOfCells(); + else + nb_local=mesh->getNumberOfNodes(); + // double * value= new double[nb_local]; + double *value=parafield->getField()->getArray()->getPointer(); + for(int ielem=0; ielem<nb_local;ielem++) + value[ielem]=0.0; + // ICoCo::Field* icocofield=new ICoCo::MEDField(paramesh,parafield); + icocofield=new ICoCo::MEDField(paramesh,parafield); + dec.setMethod(targetMeth); + dec.attachLocalField(icocofield); + } + + + //attaching a DEC to the source group + double field_before_int; + double field_after_int; + + if (source_group->containsMyRank()) + { + field_before_int = parafield->getVolumeIntegral(0); + dec.synchronize(); + cout<<"DEC usage"<<endl; + dec.setForcedRenormalization(false); + + dec.sendData(); + MEDLoader::writeParaMesh("./sourcesquareb",paramesh); + if (source_group->myRank()==0) + aRemover.Register("./sourcesquareb"); + ostringstream filename; + filename<<"./sourcesquareb_"<<source_group->myRank()+1; + aRemover.Register(filename.str().c_str()); + MEDLoader::writeParaField("./sourcesquareb","boundary",parafield); + + dec.recvData(); + cout <<"writing"<<endl; + MEDLoader::writeParaMesh("./sourcesquare",paramesh); + if (source_group->myRank()==0) + aRemover.Register("./sourcesquare"); + MEDLoader::writeParaField("./sourcesquare","boundary",parafield); + + + filename<<"./sourcesquare_"<<source_group->myRank()+1; + aRemover.Register(filename.str().c_str()); + field_after_int = parafield->getVolumeIntegral(0); + + + // MPI_Bcast(&field_before_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD); + // MPI_Bcast(&field_after_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(field_before_int, field_after_int, 1e-6); + + } + + //attaching a DEC to the target group + if (target_group->containsMyRank()) + { + dec.synchronize(); + dec.setForcedRenormalization(false); + + dec.recvData(); + MEDLoader::writeParaMesh("./targetsquareb",paramesh); + MEDLoader::writeParaField("./targetsquareb", "boundary",parafield); + if (target_group->myRank()==0) + aRemover.Register("./targetsquareb"); + ostringstream filename; + filename<<"./targetsquareb_"<<target_group->myRank()+1; + aRemover.Register(filename.str().c_str()); + dec.sendData(); + MEDLoader::writeParaMesh("./targetsquare",paramesh); + MEDLoader::writeParaField("./targetsquare", "boundary",parafield); + + if (target_group->myRank()==0) + aRemover.Register("./targetsquareb"); + + filename<<"./targetsquareb_"<<target_group->myRank()+1; + aRemover.Register(filename.str().c_str()); + // double field_before_int, field_after_int; + // MPI_Bcast(&field_before_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD); + // MPI_Bcast(&field_after_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD); + + // CPPUNIT_ASSERT_DOUBLES_EQUAL(field_before_int, field_after_int, 1e-6); + + } + + delete source_group; + delete target_group; + delete self_group; + delete parafield; + delete paramesh; + mesh->decrRef(); + + delete icocofield; + + MPI_Barrier(MPI_COMM_WORLD); + cout << "end of IntersectionDEC_2D test"<<endl; +} + +//Synchronous tests without interpolation with native mode (AllToAll(v) from lam/MPI: +void ParaMEDMEMTest::testSynchronousEqualIntersectionWithoutInterpNativeDEC_2D() +{ + testAsynchronousIntersectionDEC_2D(0.1,1,0.1,1,false,false,false,"P0","P0"); +} + +//Synchronous tests without interpolation : +void ParaMEDMEMTest::testSynchronousEqualIntersectionWithoutInterpDEC_2D() +{ + testAsynchronousIntersectionDEC_2D(0.1,1,0.1,1,true,false,false,"P0","P0"); +} + +//Synchronous tests with interpolation : +void ParaMEDMEMTest::testSynchronousEqualIntersectionDEC_2D() +{ + testAsynchronousIntersectionDEC_2D(0.1,1,0.1,1,true,false,true,"P0","P0"); +} +void ParaMEDMEMTest::testSynchronousFasterSourceIntersectionDEC_2D() +{ + testAsynchronousIntersectionDEC_2D(0.09,1,0.1,1,true,false,true,"P0","P0"); +} +void ParaMEDMEMTest::testSynchronousSlowerSourceIntersectionDEC_2D() +{ + testAsynchronousIntersectionDEC_2D(0.11,1,0.1,1,true,false,true,"P0","P0"); +} +void ParaMEDMEMTest::testSynchronousSlowSourceIntersectionDEC_2D() +{ + testAsynchronousIntersectionDEC_2D(0.11,1,0.01,1,true,false,true,"P0","P0"); +} +void ParaMEDMEMTest::testSynchronousFastSourceIntersectionDEC_2D() +{ + testAsynchronousIntersectionDEC_2D(0.01,1,0.11,1,true,false,true,"P0","P0"); +} + +//Asynchronous tests with interpolation : +void ParaMEDMEMTest::testAsynchronousEqualIntersectionDEC_2D() +{ + testAsynchronousIntersectionDEC_2D(0.1,1,0.1,1,true,true,true,"P0","P0"); +} +void ParaMEDMEMTest::testAsynchronousFasterSourceIntersectionDEC_2D() +{ + testAsynchronousIntersectionDEC_2D(0.09,1,0.1,1,true,true,true,"P0","P0"); +} +void ParaMEDMEMTest::testAsynchronousSlowerSourceIntersectionDEC_2D() +{ + testAsynchronousIntersectionDEC_2D(0.11,1,0.1,1,true,true,true,"P0","P0"); +} +void ParaMEDMEMTest::testAsynchronousSlowSourceIntersectionDEC_2D() +{ + testAsynchronousIntersectionDEC_2D(0.11,1,0.01,1,true,true,true,"P0","P0"); +} +void ParaMEDMEMTest::testAsynchronousFastSourceIntersectionDEC_2D() +{ + testAsynchronousIntersectionDEC_2D(0.01,1,0.11,1,true,true,true,"P0","P0"); +} + +/*! + * Tests an asynchronous exchange between two codes + * one sends data with dtA as an interval, the max time being tmaxA + * the other one receives with dtB as an interval, the max time being tmaxB + */ +void ParaMEDMEMTest::testAsynchronousIntersectionDEC_2D(double dtA, double tmaxA, + double dtB, double tmaxB, bool WithPointToPoint, bool Asynchronous, + bool WithInterp, const char *srcMeth, const char *targetMeth) +{ + std::string srcM(srcMeth); + std::string targetM(targetMeth); + int size; + int rank; + MPI_Comm_size(MPI_COMM_WORLD,&size); + MPI_Comm_rank(MPI_COMM_WORLD,&rank); + + //the test is meant to run on five processors + if (size !=5) return ; + + int nproc_source = 3; + set<int> self_procs; + set<int> procs_source; + set<int> procs_target; + + for (int i=0; i<nproc_source; i++) + procs_source.insert(i); + for (int i=nproc_source; i<size; i++) + procs_target.insert(i); + self_procs.insert(rank); + + ParaMEDMEM::CommInterface interface; + + ParaMEDMEM::ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs); + ParaMEDMEM::ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target); + ParaMEDMEM::ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source); + + //loading the geometry for the source group + + ParaMEDMEM::IntersectionDEC dec (*source_group,*target_group); + + ParaMEDMEM::MEDCouplingUMesh* mesh; + ParaMEDMEM::ParaMESH* paramesh; + ParaMEDMEM::ParaFIELD* parafield; + + double * value ; + ICoCo::Field* icocofield ; + + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP"); + if (tmp_dir == "") + tmp_dir = "/tmp"; + string filename_xml1 = data_dir + "/share/salome/resources/med/square1_split"; + string filename_xml2 = data_dir + "/share/salome/resources/med/square2_split"; + string filename_seq_wr = tmp_dir + "/"; + string filename_seq_med = tmp_dir + "/myWrField_seq_pointe221.med"; + + // To remove tmp files from disk + ParaMEDMEMTest_TmpFilesRemover aRemover; + + MPI_Barrier(MPI_COMM_WORLD); + + if (source_group->containsMyRank()) + { + string master = filename_xml1; + + ostringstream strstream; + strstream <<master<<rank+1<<".med"; + ostringstream meshname ; + meshname<< "Mesh_2_"<< rank+1; + + mesh=MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0); + + paramesh=new ParaMESH (mesh,*source_group,"source mesh"); + + // ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT( support,*source_group); + ParaMEDMEM::ComponentTopology comptopo; + if(srcM=="P0") + parafield = new ParaFIELD(ON_CELLS,paramesh, comptopo); + else + parafield = new ParaFIELD(ON_NODES,paramesh, comptopo); + + int nb_local; + if(srcM=="P0") + nb_local=mesh->getNumberOfCells(); + else + nb_local=mesh->getNumberOfNodes(); + // double * value= new double[nb_local]; + double *value=parafield->getField()->getArray()->getPointer(); + for(int ielem=0; ielem<nb_local;ielem++) + value[ielem]=0.0; + + // ICoCo::Field* icocofield=new ICoCo::MEDField(paramesh,parafield); + icocofield=new ICoCo::MEDField(paramesh,parafield); + + dec.attachLocalField(icocofield); + + + } + + //loading the geometry for the target group + if (target_group->containsMyRank()) + { + string master= filename_xml2; + ostringstream strstream; + strstream << master<<(rank-nproc_source+1)<<".med"; + ostringstream meshname ; + meshname<< "Mesh_3_"<<rank-nproc_source+1; + + mesh = MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0); + + paramesh=new ParaMESH (mesh,*target_group,"target mesh"); + // ParaMEDMEM::ParaSUPPORT* parasupport=new UnstructuredParaSUPPORT(support,*target_group); + ParaMEDMEM::ComponentTopology comptopo; + if(targetM=="P0") + parafield = new ParaFIELD(ON_CELLS,paramesh, comptopo); + else + parafield = new ParaFIELD(ON_NODES,paramesh, comptopo); + + int nb_local; + if(targetM=="P0") + nb_local=mesh->getNumberOfCells(); + else + nb_local=mesh->getNumberOfNodes(); + + double *value=parafield->getField()->getArray()->getPointer(); + for(int ielem=0; ielem<nb_local;ielem++) + value[ielem]=0.0; + // ICoCo::Field* icocofield=new ICoCo::MEDField(paramesh,parafield); + icocofield=new ICoCo::MEDField(paramesh,parafield); + + dec.attachLocalField(icocofield); + } + + + //attaching a DEC to the source group + + if (source_group->containsMyRank()) + { + cout<<"DEC usage"<<endl; + dec.setAsynchronous(Asynchronous); + if ( WithInterp ) { + dec.setTimeInterpolationMethod(LinearTimeInterp); + } + if ( WithPointToPoint ) { + dec.setAllToAllMethod(PointToPoint); + } + else { + dec.setAllToAllMethod(Native); + } + dec.synchronize(); + dec.setForcedRenormalization(false); + for (double time=0; time<tmaxA+1e-10; time+=dtA) + { + cout << "testAsynchronousIntersectionDEC_2D" << rank << " time " << time + << " dtA " << dtA << " tmaxA " << tmaxA << endl ; + if ( time+dtA < tmaxA+1e-7 ) { + dec.sendData( time , dtA ); + } + else { + dec.sendData( time , 0 ); + } + double* value = parafield->getField()->getArray()->getPointer(); + int nb_local=parafield->getField()->getMesh()->getNumberOfCells(); + for (int i=0; i<nb_local;i++) + value[i]= time+dtA; + + + } + } + + //attaching a DEC to the target group + if (target_group->containsMyRank()) + { + cout<<"DEC usage"<<endl; + dec.setAsynchronous(Asynchronous); + if ( WithInterp ) { + dec.setTimeInterpolationMethod(LinearTimeInterp); + } + if ( WithPointToPoint ) { + dec.setAllToAllMethod(PointToPoint); + } + else { + dec.setAllToAllMethod(Native); + } + dec.synchronize(); + dec.setForcedRenormalization(false); + vector<double> times; + for (double time=0; time<tmaxB+1e-10; time+=dtB) + { + cout << "testAsynchronousIntersectionDEC_2D" << rank << " time " << time + << " dtB " << dtB << " tmaxB " << tmaxB << endl ; + dec.recvData( time ); + double vi = parafield->getVolumeIntegral(0); + cout << "testAsynchronousIntersectionDEC_2D" << rank << " time " << time + << " VolumeIntegral " << vi + << " time*10000 " << time*10000 << endl ; + + CPPUNIT_ASSERT_DOUBLES_EQUAL(vi,time*10000,0.001); + } + + } + + delete source_group; + delete target_group; + delete self_group; + delete parafield ; + delete paramesh ; + mesh->decrRef() ; + delete icocofield ; + + cout << "testAsynchronousIntersectionDEC_2D" << rank << " MPI_Barrier " << endl ; + + if (Asynchronous) MPI_Barrier(MPI_COMM_WORLD); + cout << "end of IntersectionDEC_2D test"<<endl; +} diff --git a/src/ParaMEDMEM/Test/ParaMEDMEMTest_MPIProcessorGroup.cxx b/src/ParaMEDMEM/Test/ParaMEDMEMTest_MPIProcessorGroup.cxx new file mode 100644 index 000000000..979f978c1 --- /dev/null +++ b/src/ParaMEDMEM/Test/ParaMEDMEMTest_MPIProcessorGroup.cxx @@ -0,0 +1,149 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "ParaMEDMEMTest.hxx" +#include <cppunit/TestAssert.h> +#include "CommInterface.hxx" +#include "ProcessorGroup.hxx" +#include "MPIProcessorGroup.hxx" +#include "InterpolationUtils.hxx" + +#include <string> + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + + +using namespace std; +using namespace ParaMEDMEM; + +/* + * Check methods defined in MPPIProcessorGroup.hxx + * + (+) MPIProcessorGroup(const CommInterface& interface); + (+) MPIProcessorGroup(const CommInterface& interface, set<int> proc_ids); + (u) MPIProcessorGroup (const ProcessorGroup& proc_group, set<int> proc_ids); + (+) MPIProcessorGroup(const CommInterface& interface,int pstart, int pend); + (+) virtual ~MPIProcessorGroup(); + (+) virtual ProcessorGroup* fuse (const ProcessorGroup&) const; + (u) void intersect (ProcessorGroup&){}; + (+) int myRank() const {int rank; MPI_Comm_rank(_comm,&rank); return rank;} + (+) bool containsMyRank() const { int rank; MPI_Group_rank(_group, &rank); return (rank!=MPI_UNDEFINED);} + (+) int translateRank(const ProcessorGroup* group, int rank) const; + (+) const MPI_Comm* getComm() const {return &_comm;} + (+) ProcessorGroup* createComplementProcGroup() const; + (o) ProcessorGroup* createProcGroup() const; + +*/ + +void ParaMEDMEMTest::testMPIProcessorGroup_constructor() +{ + CommInterface comm_interface; + MPIProcessorGroup* group= new MPIProcessorGroup(comm_interface); + int size; + MPI_Comm_size(MPI_COMM_WORLD, &size); + CPPUNIT_ASSERT_EQUAL(size,group->size()); + int size2; + const MPI_Comm* communicator=group->getComm(); + MPI_Comm_size(*communicator, &size2); + CPPUNIT_ASSERT_EQUAL(size,size2); + delete group; + + set <int> procs; + + procs.insert(0); + procs.insert(1); + if (size==1) + CPPUNIT_ASSERT_THROW(group=new MPIProcessorGroup(comm_interface,procs),INTERP_KERNEL::Exception); + else + { + CPPUNIT_ASSERT_NO_THROW( group=new MPIProcessorGroup(comm_interface,procs)); + CPPUNIT_ASSERT_EQUAL (group->size(),2); + delete group; + } + + + //throws because plast<pfirst + CPPUNIT_ASSERT_THROW(group=new MPIProcessorGroup(comm_interface,1,0),INTERP_KERNEL::Exception); + //throws because plast is beyond size-1 + CPPUNIT_ASSERT_THROW(group=new MPIProcessorGroup(comm_interface,0,size),INTERP_KERNEL::Exception); + if (size>1) + { + group=new MPIProcessorGroup(comm_interface,0,size-2); + CPPUNIT_ASSERT_EQUAL(group->size(),size-1); + delete group; + } + +} + +void ParaMEDMEMTest::testMPIProcessorGroup_boolean() +{ + int size; + MPI_Comm_size(MPI_COMM_WORLD, &size); + + CommInterface comm_interface; + MPIProcessorGroup group(comm_interface,0,0); + MPIProcessorGroup group2(comm_interface,size-1,size-1); + ProcessorGroup* group_fuse=group.fuse(group2); + int group_fuse_size=(size==1)?1:2; + CPPUNIT_ASSERT_EQUAL(group_fuse_size,group_fuse->size()); + + ProcessorGroup* group_complement=((MPIProcessorGroup*)group_fuse)->createComplementProcGroup(); + CPPUNIT_ASSERT_EQUAL(group_complement->size(),size-group_fuse_size); + + delete group_fuse; + delete group_complement; + + //intersect not implemented yet + // if (size>1) + // { + // MPIProcessorGroup group3(comm_interface,0,size-2); + // MPIProcessorGroup group4(comm_interface,1,size-1); + // group3.intersect(group4); + // CPPUNIT_ASSERT_EQUAL(group3.size(),size-2); + // } +} + +void ParaMEDMEMTest::testMPIProcessorGroup_rank() +{ + int size; + MPI_Comm_size(MPI_COMM_WORLD, &size); + int rank; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + CommInterface comm_interface; + MPIProcessorGroup group(comm_interface,0,0); + MPIProcessorGroup group2(comm_interface,size-1,size-1); + ProcessorGroup* group_fuse=group2.fuse(group); + + if (group.containsMyRank()) + CPPUNIT_ASSERT_EQUAL (group.myRank(), rank); + + if (group2.containsMyRank()) + { + int trank=group_fuse->translateRank(&group2,0); + if (size==1) + CPPUNIT_ASSERT_EQUAL(trank,0); + else + CPPUNIT_ASSERT_EQUAL(trank,1); + } + delete group_fuse; +} diff --git a/src/ParaMEDMEM/Test/ParaMEDMEMTest_NonCoincidentDEC.cxx b/src/ParaMEDMEM/Test/ParaMEDMEMTest_NonCoincidentDEC.cxx new file mode 100644 index 000000000..743d91b49 --- /dev/null +++ b/src/ParaMEDMEM/Test/ParaMEDMEMTest_NonCoincidentDEC.cxx @@ -0,0 +1,256 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "ParaMEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "MEDMEM_Exception.hxx" +#include "CommInterface.hxx" +#include "ProcessorGroup.hxx" +#include "MPIProcessorGroup.hxx" +#include "Topology.hxx" +#include "DEC.hxx" +#include "NonCoincidentDEC.hxx" +#include "ParaMESH.hxx" +#include "ParaFIELD.hxx" +#include "UnstructuredParaSUPPORT.hxx" +#include "ICoCoMEDField.hxx" + +#include <string> + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + + +using namespace std; +using namespace ParaMEDMEM; +using namespace MEDMEM; + +/* + * Check methods defined in IntersectionDEC.hxx + * + IntersectionDEC(); + IntersectionDEC(ProcessorGroup& local_group, ProcessorGroup& distant_group); + virtual ~IntersectionDEC(); + void synchronize(); + void recvData(); + void sendData(); +*/ + +void ParaMEDMEMTest::testNonCoincidentDEC_2D() +{ + + int size; + MPI_Comm_size(MPI_COMM_WORLD,&size); + + //the test is meant to run on five processors + if (size !=5) return ; + + testNonCoincidentDEC( "/share/salome/resources/med/square1_split", + "Mesh_2", + "/share/salome/resources/med/square2_split", + "Mesh_3", + 3, + 1e-6); +} + +void ParaMEDMEMTest::testNonCoincidentDEC_3D() +{ + int size; + MPI_Comm_size(MPI_COMM_WORLD,&size); + + //the test is meant to run on five processors + if (size !=4) return ; + + testNonCoincidentDEC( "/share/salome/resources/med/blade_12000_split2", + "Mesh_1", + "/share/salome/resources/med/blade_3000_split2", + "Mesh_1", + 2, + 1e4); +} + +void ParaMEDMEMTest::testNonCoincidentDEC(const string& filename1, + const string& meshname1, + const string& filename2, + const string& meshname2, + int nproc_source, + double epsilon) +{ + int size; + int rank; + MPI_Comm_size(MPI_COMM_WORLD,&size); + MPI_Comm_rank(MPI_COMM_WORLD,&rank); + + set<int> self_procs; + set<int> procs_source; + set<int> procs_target; + + for (int i=0; i<nproc_source; i++) + procs_source.insert(i); + for (int i=nproc_source; i<size; i++) + procs_target.insert(i); + self_procs.insert(rank); + + ParaMEDMEM::CommInterface interface; + + ParaMEDMEM::ProcessorGroup* self_group = new ParaMEDMEM::MPIProcessorGroup(interface,self_procs); + ParaMEDMEM::ProcessorGroup* target_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_target); + ParaMEDMEM::ProcessorGroup* source_group = new ParaMEDMEM::MPIProcessorGroup(interface,procs_source); + + ParaMEDMEM::ParaMESH* source_mesh=0; + ParaMEDMEM::ParaMESH* target_mesh=0; + ParaMEDMEM::ParaSUPPORT* parasupport=0; + //loading the geometry for the source group + + ParaMEDMEM::NonCoincidentDEC dec (*source_group,*target_group); + + MEDMEM::MESH* mesh; + MEDMEM::SUPPORT* support; + MEDMEM::FIELD<double>* field; + ParaMEDMEM::ParaMESH* paramesh; + ParaMEDMEM::ParaFIELD* parafield; + + string data_dir = getenv("MED_ROOT_DIR") + "/share/salome/resources/med/"; + string tmp_dir = getenv("TMP"); + if (tmp_dir == "") + tmp_dir = "/tmp"; + string filename_xml1 = data_dir + filename1; + string filename_xml2 = data_dir + filename2; + string filename_seq_wr = tmp_dir + "/"; + string filename_seq_med = tmp_dir + "/myWrField_seq_pointe221.med"; + + // To remove tmp files from disk + ParaMEDMEMTest_TmpFilesRemover aRemover; + //aRemover.Register(filename_seq_wr); + //aRemover.Register(filename_seq_med); + MPI_Barrier(MPI_COMM_WORLD); + ICoCo::Field* icocofield; + if (source_group->containsMyRank()) + { + string master = filename_xml1; + + ostringstream strstream; + strstream <<master<<rank+1<<".med"; + ostringstream meshname ; + meshname<< meshname1<<"_"<< rank+1; + + CPPUNIT_ASSERT_NO_THROW(mesh = new MESH(MED_DRIVER,strstream.str(),meshname.str())); + support=new MEDMEM::SUPPORT(mesh,"all elements",MED_EN::MED_CELL); + + paramesh=new ParaMESH (*mesh,*source_group,"source mesh"); + + parasupport=new UnstructuredParaSUPPORT( support,*source_group); + ParaMEDMEM::ComponentTopology comptopo; + parafield = new ParaFIELD(parasupport, comptopo); + + + int nb_local=support->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS); + double * value= new double[nb_local]; + for(int ielem=0; ielem<nb_local;ielem++) + value[ielem]=1.0; + parafield->getField()->setValue(value); + + icocofield=new ICoCo::MEDField(paramesh,parafield); + + dec.attachLocalField(icocofield); + delete [] value; + } + + //loading the geometry for the target group + if (target_group->containsMyRank()) + { + string master= filename_xml2; + ostringstream strstream; + strstream << master<<(rank-nproc_source+1)<<".med"; + ostringstream meshname ; + meshname<< meshname2<<"_"<<rank-nproc_source+1; + + CPPUNIT_ASSERT_NO_THROW(mesh = new MESH(MED_DRIVER,strstream.str(),meshname.str())); + support=new MEDMEM::SUPPORT(mesh,"all elements",MED_EN::MED_CELL); + + paramesh=new ParaMESH (*mesh,*target_group,"target mesh"); + parasupport=new UnstructuredParaSUPPORT(support,*target_group); + ParaMEDMEM::ComponentTopology comptopo; + parafield = new ParaFIELD(parasupport, comptopo); + + + int nb_local=support->getNumberOfElements(MED_EN::MED_ALL_ELEMENTS); + double * value= new double[nb_local]; + for(int ielem=0; ielem<nb_local;ielem++) + value[ielem]=0.0; + parafield->getField()->setValue(value); + icocofield=new ICoCo::MEDField(paramesh,parafield); + + dec.attachLocalField(icocofield); + delete [] value; + } + + + //attaching a DEC to the source group + double field_before_int; + double field_after_int; + + if (source_group->containsMyRank()) + { + field_before_int = parafield->getVolumeIntegral(1); + MPI_Bcast(&field_before_int, 1,MPI_DOUBLE, 0,MPI_COMM_WORLD); + dec.synchronize(); + cout<<"DEC usage"<<endl; + dec.setOption("ForcedRenormalization",false); + + dec.sendData(); + // paramesh->write(MED_DRIVER,"./sourcesquarenc"); + //parafield->write(MED_DRIVER,"./sourcesquarenc","boundary"); + + + } + + //attaching a DEC to the target group + if (target_group->containsMyRank()) + { + MPI_Bcast(&field_before_int, 1,MPI_DOUBLE, 0,MPI_COMM_WORLD); + + dec.synchronize(); + dec.setOption("ForcedRenormalization",false); + dec.recvData(); + //paramesh->write(MED_DRIVER, "./targetsquarenc"); + //parafield->write(MED_DRIVER, "./targetsquarenc", "boundary"); + field_after_int = parafield->getVolumeIntegral(1); + + } + MPI_Bcast(&field_before_int,1,MPI_DOUBLE,0,MPI_COMM_WORLD); + MPI_Bcast(&field_after_int, 1,MPI_DOUBLE, size-1,MPI_COMM_WORLD); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(field_before_int, field_after_int, epsilon); + + delete source_group; + delete target_group; + delete self_group; + delete icocofield; + delete paramesh; + delete parafield; + delete support; + delete parasupport; + delete mesh; + MPI_Barrier(MPI_COMM_WORLD); + +} diff --git a/src/ParaMEDMEM/Test/ParaMEDMEMTest_StructuredCoincidentDEC.cxx b/src/ParaMEDMEM/Test/ParaMEDMEMTest_StructuredCoincidentDEC.cxx new file mode 100644 index 000000000..c0abcf871 --- /dev/null +++ b/src/ParaMEDMEM/Test/ParaMEDMEMTest_StructuredCoincidentDEC.cxx @@ -0,0 +1,163 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "ParaMEDMEMTest.hxx" +#include <cppunit/TestAssert.h> + +#include "CommInterface.hxx" +#include "ProcessorGroup.hxx" +#include "MPIProcessorGroup.hxx" +#include "Topology.hxx" +#include "DEC.hxx" +#include "StructuredCoincidentDEC.hxx" +#include "ParaMESH.hxx" +#include "ParaFIELD.hxx" +#include "ICoCoMEDField.hxx" +#include "MEDLoader.hxx" + +#include <string> + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +/* + * Check methods defined in StructuredCoincidentDEC.hxx + * + StructuredCoincidentDEC(); + StructuredCoincidentDEC(ProcessorGroup& local_group, ProcessorGroup& distant_group); + virtual ~StructuredCoincidentDEC(); + void synchronize(); + void recvData(); + void sendData(); +*/ + +void ParaMEDMEMTest::testStructuredCoincidentDEC() { + string testname="ParaMEDMEM - testStructured CoincidentDEC"; + // MPI_Init(&argc, &argv); + int size; + int rank; + MPI_Comm_size(MPI_COMM_WORLD, &size); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + if (size<4) { + return; + } + + ParaMEDMEM::CommInterface interface; + + ParaMEDMEM::MPIProcessorGroup self_group (interface,rank,rank); + ParaMEDMEM::MPIProcessorGroup target_group(interface,3,size-1); + ParaMEDMEM::MPIProcessorGroup source_group (interface,0,2); + + ParaMEDMEM::MEDCouplingUMesh* mesh; + ParaMEDMEM::ParaMESH* paramesh; + ParaMEDMEM::ParaFIELD* parafield; + + string data_dir = getenv("MED_ROOT_DIR"); + string tmp_dir = getenv("TMP"); + if (tmp_dir == "") + tmp_dir = "/tmp"; + string filename_xml1 = data_dir + + "/share/salome/resources/med/square1_split"; + string filename_2 = data_dir + "/share/salome/resources/med/square1.med"; + string filename_seq_wr = tmp_dir + "/"; + string filename_seq_med = tmp_dir + "/myWrField_seq_pointe221.med"; + + // To remove tmp files from disk + ParaMEDMEMTest_TmpFilesRemover aRemover; + + //loading the geometry for the source group + + ParaMEDMEM::StructuredCoincidentDEC dec(source_group, target_group); + + MPI_Barrier(MPI_COMM_WORLD); + if (source_group.containsMyRank()) { + string master = filename_xml1; + + ostringstream strstream; + strstream <<master<<rank+1<<".med"; + ostringstream meshname; + meshname<< "Mesh_2_"<< rank+1; + + mesh=MEDLoader::ReadUMeshFromFile(strstream.str().c_str(),meshname.str().c_str(),0); + + + paramesh=new ParaMESH (mesh,source_group,"source mesh"); + + ParaMEDMEM::ComponentTopology comptopo(6); + parafield = new ParaFIELD(ON_CELLS,paramesh, comptopo); + + int nb_local=mesh->getNumberOfCells(); + const int* global_numbering = paramesh->getGlobalNumberingCell(); + + double *value=parafield->getField()->getArray()->getPointer(); + for(int ielem=0; ielem<nb_local;ielem++) + for (int icomp=0; icomp<6; icomp++) + value[ielem*6+icomp]=global_numbering[ielem]*6+icomp; + + ICoCo::Field* icocofield=new ICoCo::MEDField(paramesh,parafield); + + dec.attachLocalField(icocofield); + dec.synchronize(); + dec.sendData(); + delete icocofield; + } + + //loading the geometry for the target group + if (target_group.containsMyRank()) { + + string meshname2("Mesh_2"); + mesh = MEDLoader::ReadUMeshFromFile(filename_2.c_str(),meshname2.c_str(),0); + + paramesh=new ParaMESH (mesh,self_group,"target mesh"); + ParaMEDMEM::ComponentTopology comptopo(6, &target_group); + + parafield = new ParaFIELD(ON_CELLS,paramesh, comptopo); + + int nb_local=mesh->getNumberOfCells(); + double *value=parafield->getField()->getArray()->getPointer(); + for (int ielem=0; ielem<nb_local; ielem++) + for (int icomp=0; icomp<comptopo.nbLocalComponents(); icomp++) + value[ielem*comptopo.nbLocalComponents()+icomp]=0.0; + ICoCo::Field* icocofield=new ICoCo::MEDField(paramesh,parafield); + + dec.attachLocalField(icocofield); + dec.synchronize(); + dec.recvData(); + + //checking validity of field + const double* recv_value = parafield->getField()->getArray()->getPointer(); + for (int i=0; i< nb_local; i++) { + int first = comptopo.firstLocalComponent(); + for (int icomp = 0; icomp < comptopo.nbLocalComponents(); icomp++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(recv_value[i*comptopo.nbLocalComponents()+icomp],(double)(i*6+icomp+first),1e-12); + } + delete icocofield; + } + delete parafield; + delete paramesh; + mesh->decrRef(); + + // MPI_Barrier(MPI_COMM_WORLD); + +} diff --git a/src/ParaMEDMEM/Test/TestMPIAccess.cxx b/src/ParaMEDMEM/Test/TestMPIAccess.cxx new file mode 100644 index 000000000..e71974e99 --- /dev/null +++ b/src/ParaMEDMEM/Test/TestMPIAccess.cxx @@ -0,0 +1,30 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// + +// --- include all MPIAccess Test + +#include "MPIAccessTest.hxx" + +// --- Registers the fixture into the 'registry' + +CPPUNIT_TEST_SUITE_REGISTRATION( MPIAccessTest ); + +// --- generic Main program from KERNEL_SRC/src/Basics/Test + +#include "MPIMainTest.hxx" diff --git a/src/ParaMEDMEM/Test/TestMPIAccessDEC.cxx b/src/ParaMEDMEM/Test/TestMPIAccessDEC.cxx new file mode 100644 index 000000000..80431cff1 --- /dev/null +++ b/src/ParaMEDMEM/Test/TestMPIAccessDEC.cxx @@ -0,0 +1,30 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// + +// --- include all MPIAccessDEC Test + +#include "MPIAccessDECTest.hxx" + +// --- Registers the fixture into the 'registry' + +CPPUNIT_TEST_SUITE_REGISTRATION( MPIAccessDECTest ); + +// --- generic Main program from KERNEL_SRC/src/Basics/Test + +#include "MPIMainTest.hxx" diff --git a/src/ParaMEDMEM/Test/TestParaMEDMEM.cxx b/src/ParaMEDMEM/Test/TestParaMEDMEM.cxx new file mode 100644 index 000000000..6bddba11d --- /dev/null +++ b/src/ParaMEDMEM/Test/TestParaMEDMEM.cxx @@ -0,0 +1,30 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// + +// --- include all MEDMEM Test + +#include "ParaMEDMEMTest.hxx" + +// --- Registers the fixture into the 'registry' + +CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEMTest ); + +// --- generic Main program from KERNEL_SRC/src/Basics/Test + +#include "MPIMainTest.hxx" diff --git a/src/ParaMEDMEM/Test/test_AllToAllDEC.cxx b/src/ParaMEDMEM/Test/test_AllToAllDEC.cxx new file mode 100644 index 000000000..5b8d66896 --- /dev/null +++ b/src/ParaMEDMEM/Test/test_AllToAllDEC.cxx @@ -0,0 +1,169 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> + +#include "MPIAccessDECTest.hxx" +#include <cppunit/TestAssert.h> +#include "MPIAccessDEC.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessDECTest::test_AllToAllDECSynchronousPointToPoint() { + test_AllToAllDEC( false ) ; +} +void MPIAccessDECTest::test_AllToAllDECAsynchronousPointToPoint() { + test_AllToAllDEC( true ) ; +} + +static void chksts( int sts , int myrank , ParaMEDMEM::MPIAccess mpi_access ) { + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + if ( sts != MPI_SUCCESS ) { + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + ostringstream strstream ; + strstream << "===========================================================" << endl + << "test_AllToAllDEC" << myrank << " KO" << endl + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + return ; +} + +void MPIAccessDECTest::test_AllToAllDEC( bool Asynchronous ) { + + cout << "test_AllToAllDEC" << endl ; + + // MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 2 || size > 11 ) { + ostringstream strstream ; + strstream << "usage :" << endl + << "mpirun -np <nbprocs> test_AllToAllDEC" << endl + << " (nbprocs >=2)" << endl + << "test must be runned with more than 1 proc and less than 12 procs" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + cout << "test_AllToAllDEC" << myrank << endl ; + + ParaMEDMEM::CommInterface interface ; + std::set<int> sourceprocs; + std::set<int> targetprocs; + int i ; + for ( i = 0 ; i < size/2 ; i++ ) { + sourceprocs.insert(i); + } + for ( i = size/2 ; i < size ; i++ ) { + targetprocs.insert(i); + } + + ParaMEDMEM::MPIProcessorGroup* sourcegroup = new ParaMEDMEM::MPIProcessorGroup(interface,sourceprocs) ; + ParaMEDMEM::MPIProcessorGroup* targetgroup = new ParaMEDMEM::MPIProcessorGroup(interface,targetprocs) ; + + MPIAccessDEC * MyMPIAccessDEC = new MPIAccessDEC( *sourcegroup , *targetgroup , + Asynchronous ) ; + + MPIAccess * mpi_access = MyMPIAccessDEC->getMPIAccess() ; + +#define maxreq 100 +#define datamsglength 10 + + // int sts ; + int sendcount = datamsglength ; + int recvcount = datamsglength ; + int * recvbuf = new int[datamsglength*size] ; + + int ireq ; + for ( ireq = 0 ; ireq < maxreq ; ireq++ ) { + int * sendbuf = new int[datamsglength*size] ; + int j ; + for ( j = 0 ; j < datamsglength*size ; j++ ) { + sendbuf[j] = myrank*1000000 + ireq*1000 + j ; + recvbuf[j] = -1 ; + } + + MyMPIAccessDEC->allToAll( sendbuf, sendcount , MPI_INT , + recvbuf, recvcount , MPI_INT ) ; + + int nRecvReq = mpi_access->recvRequestIdsSize() ; + int *ArrayOfRecvRequests = new int[nRecvReq] ; + int nReq = mpi_access->recvRequestIds( nRecvReq, ArrayOfRecvRequests ) ; + mpi_access->waitAll( nReq , ArrayOfRecvRequests ) ; + mpi_access->deleteRequests( nReq , ArrayOfRecvRequests ) ; + delete [] ArrayOfRecvRequests ; + } + + int nSendReq = mpi_access->sendRequestIdsSize() ; + cout << "test_AllToAllDEC" << myrank << " final SendRequestIds " << nSendReq << " SendRequests" + << endl ; + if ( nSendReq ) { + int *ArrayOfSendRequests = new int[nSendReq] ; + int nReq = mpi_access->sendRequestIds( nSendReq, ArrayOfSendRequests ) ; + mpi_access->waitAll( nReq , ArrayOfSendRequests ) ; + delete [] ArrayOfSendRequests ; + } + + int nRecvReq = mpi_access->recvRequestIdsSize() ; + if ( nRecvReq ) { + ostringstream strstream ; + strstream << "test_AllToAllDEC" << myrank << " final RecvRequestIds " << nRecvReq + << " RecvRequests # 0 Error" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "test_AllToAllDEC" << myrank << " final RecvRequestIds " << nRecvReq + << " RecvRequests = 0 OK" << endl ; + } + + mpi_access->barrier() ; + + delete sourcegroup ; + delete targetgroup ; + delete MyMPIAccessDEC ; + delete [] recvbuf ; + + // MPI_Finalize(); + + cout << "test_AllToAllDEC" << myrank << " OK" << endl ; + + return ; +} diff --git a/src/ParaMEDMEM/Test/test_AllToAllTimeDEC.cxx b/src/ParaMEDMEM/Test/test_AllToAllTimeDEC.cxx new file mode 100644 index 000000000..f869374a7 --- /dev/null +++ b/src/ParaMEDMEM/Test/test_AllToAllTimeDEC.cxx @@ -0,0 +1,266 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> + +#include "MPIAccessDECTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccessDEC.hxx" +#include "LinearTimeInterpolator.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessDECTest::test_AllToAllTimeDECSynchronousPointToPoint() { + test_AllToAllTimeDEC( false ) ; +} +void MPIAccessDECTest::test_AllToAllTimeDECAsynchronousPointToPoint() { + test_AllToAllTimeDEC( true ) ; +} + +static void chksts( int sts , int myrank , ParaMEDMEM::MPIAccess * mpi_access ) { + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + if ( sts != MPI_SUCCESS ) { + mpi_access->errorString(sts, msgerr, &lenerr) ; + cout << "test_AllToAllTimeDEC" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + ostringstream strstream ; + strstream << "===========================================================" + << "test_AllToAllTimeDEC" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + return ; +} + +void MPIAccessDECTest::test_AllToAllTimeDEC( bool Asynchronous ) { + + cout << "test_AllToAllTimeDEC" << endl ; + + // MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 2 || size > 11 ) { + ostringstream strstream ; + strstream << "usage :" << endl + << "mpirun -np <nbprocs> test_AllToAllTimeDEC" << endl + << " (nbprocs >=2)" << endl + << "test must be runned with more than 1 proc and less than 12 procs" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + // int Asynchronous = atoi(argv[1]); + + cout << "test_AllToAllTimeDEC" << myrank << " Asynchronous " << Asynchronous << endl ; + + ParaMEDMEM::CommInterface interface ; + std::set<int> sourceprocs; + std::set<int> targetprocs; + int i ; + for ( i = 0 ; i < size/2 ; i++ ) { + sourceprocs.insert(i); + } + for ( i = size/2 ; i < size ; i++ ) { + targetprocs.insert(i); + } + + ParaMEDMEM::MPIProcessorGroup* sourcegroup = new ParaMEDMEM::MPIProcessorGroup(interface,sourceprocs) ; + ParaMEDMEM::MPIProcessorGroup* targetgroup = new ParaMEDMEM::MPIProcessorGroup(interface,targetprocs) ; + + // LinearTimeInterpolator * aLinearInterpDEC = new LinearTimeInterpolator( 0.5 ) ; + MPIAccessDEC * MyMPIAccessDEC = new MPIAccessDEC( *sourcegroup , *targetgroup , + Asynchronous ) ; + // Asynchronous , LinearInterp , 0.5 ) ; + MyMPIAccessDEC->setTimeInterpolator( LinearTimeInterp ) ; + MPIAccess * mpi_access = MyMPIAccessDEC->getMPIAccess() ; + + cout << "test_AllToAllTimeDEC" << myrank << " Barrier :" << endl ; + mpi_access->barrier() ; + cout << "test_AllToAllTimeDEC" << myrank << " Barrier done" << endl ; + +#define maxproc 11 +#define maxreq 10000 +#define datamsglength 10 + + int sts ; + int sendcount = datamsglength ; + int recvcount = datamsglength ; + + double time = 0 ; + // double deltatime[maxproc] = {1.,2.1,3.2,4.3,5.4,6.5,7.6,8.7,9.8,10.9,11.} ; + double deltatime[maxproc] = {1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.} ; + double maxtime = maxreq ; + double nextdeltatime = deltatime[myrank] ; + // MyMPIAccessDEC->InitTime( time , deltatime[myrank] , maxtime ) ; + // for ( time = 0 ; time <= maxtime ; time+=deltatime[myrank] ) { + for ( time = 0 ; time <= maxtime && nextdeltatime != 0 ; time+=nextdeltatime ) { + if ( time != 0 ) { + nextdeltatime = deltatime[myrank] ; + if ( time+nextdeltatime > maxtime ) { + nextdeltatime = 0 ; + } + // MyMPIAccessDEC->NextTime( nextdeltatime ) ; + } + MyMPIAccessDEC->setTime( time , nextdeltatime ) ; + cout << "test_AllToAllTimeDEC" << myrank << "=====TIME " << time << "=====DELTATIME " + << nextdeltatime << "=====MAXTIME " << maxtime << " ======" << endl ; + int * sendbuf = new int[datamsglength*size] ; + // int * sendbuf = (int *) malloc(sizeof(int)*datamsglength*size) ; + int * recvbuf = new int[datamsglength*size] ; + int j ; + for ( j = 0 ; j < datamsglength*size ; j++ ) { + sendbuf[j] = myrank*1000000 + (j/datamsglength)*1000 + j ; + recvbuf[j] = -1 ; + } + + int sts = MyMPIAccessDEC->allToAllTime( sendbuf, sendcount , MPI_INT , + recvbuf, recvcount , MPI_INT ) ; + chksts( sts , myrank , mpi_access ) ; + + // cout << "test_AllToAllTimeDEC" << myrank << " recvbuf before CheckSent" ; + // for ( i = 0 ; i < datamsglength*size ; i++ ) { + // cout << " " << recvbuf[i] ; + // } + // cout << endl ; + + // cout << "test_AllToAllTimeDEC" << myrank << " sendbuf " << sendbuf << endl ; + // MyMPIAccessDEC->CheckSent() ; + + int nRecvReq = mpi_access->recvRequestIdsSize() ; + if ( nRecvReq != 0 ) { + ostringstream strstream ; + strstream << "=============================================================" << endl + << "test_AllToAllTimeDEC" << myrank << " WaitAllRecv " << nRecvReq << " Requests # 0 ERROR" + << endl << "=============================================================" + << endl ; + int *ArrayOfRecvRequests = new int[nRecvReq] ; + int nReq = mpi_access->recvRequestIds( nRecvReq, ArrayOfRecvRequests ) ; + mpi_access->waitAll( nReq , ArrayOfRecvRequests ) ; + delete [] ArrayOfRecvRequests ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + // cout << "test_AllToAllTimeDEC" << myrank << " recvbuf" << endl ; + bool badrecvbuf = false ; + for ( i = 0 ; i < datamsglength*size ; i++ ) { + if ( recvbuf[i] != (i/datamsglength)*1000000 + myrank*1000 + + myrank*datamsglength+(i%datamsglength) ) { + badrecvbuf = true ; + cout << "test_AllToAllTimeDEC" << myrank << " recvbuf[" << i << "] " + << recvbuf[i] << " # " << (i/datamsglength)*1000000 + myrank*1000 + + myrank*datamsglength+(i%datamsglength) << endl ; + } + else if ( badrecvbuf ) { + cout << "test_AllToAllTimeDEC" << myrank << " recvbuf[" << i << "] " + << recvbuf[i] << " == " << (i/datamsglength)*1000000 + myrank*1000 + + myrank*datamsglength+(i%datamsglength) << endl ; + } + } + if ( badrecvbuf ) { + ostringstream strstream ; + strstream << "==============================================================" << endl + << "test_AllToAllTimeDEC" << myrank << " badrecvbuf" + << endl << "=============================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + delete [] recvbuf ; + } + + cout << "test_AllToAllTimeDEC" << myrank << " final CheckSent" << endl ; + sts = MyMPIAccessDEC->checkSent() ; + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "================================================================" << endl + << "test_AllToAllTimeDEC" << myrank << " final CheckSent ERROR" + << endl << "================================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + int nSendReq = mpi_access->sendRequestIdsSize() ; + cout << "test_AllToAllTimeDEC" << myrank << " final SendRequestIds " << nSendReq << " SendRequests" + << endl ; + if ( nSendReq ) { + int *ArrayOfSendRequests = new int[nSendReq] ; + int nReq = mpi_access->sendRequestIds( nSendReq, ArrayOfSendRequests ) ; + mpi_access->waitAll( nReq , ArrayOfSendRequests ) ; + delete [] ArrayOfSendRequests ; + } + + int nRecvReq = mpi_access->recvRequestIdsSize() ; + if ( nRecvReq ) { + ostringstream strstream ; + strstream << "===============================================================" << endl + << "test_AllToAllTimeDEC" << myrank << " RecvRequestIds " << nRecvReq + << " RecvRequests # 0 Error" + << endl << "===============================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "test_AllToAllTimeDEC" << myrank << " RecvRequestIds " << nRecvReq + << " RecvRequests = 0 OK" << endl ; + } + + cout << "test_AllToAllTimeDEC" << myrank << " Barrier :" << endl ; + mpi_access->barrier() ; + cout << "test_AllToAllTimeDEC" << myrank << " Barrier done" << endl ; + + delete sourcegroup ; + delete targetgroup ; + // delete aLinearInterpDEC ; + delete MyMPIAccessDEC ; + + // MPI_Finalize(); + + cout << "test_AllToAllTimeDEC" << myrank << " OK" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/Test/test_AllToAllvDEC.cxx b/src/ParaMEDMEM/Test/test_AllToAllvDEC.cxx new file mode 100644 index 000000000..7a5c65f59 --- /dev/null +++ b/src/ParaMEDMEM/Test/test_AllToAllvDEC.cxx @@ -0,0 +1,211 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> + +#include "MPIAccessDECTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccessDEC.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessDECTest::test_AllToAllvDECSynchronousPointToPoint() { + test_AllToAllvDEC( false ) ; +} +void MPIAccessDECTest::test_AllToAllvDECAsynchronousPointToPoint() { + test_AllToAllvDEC( true ) ; +} + +static void chksts( int sts , int myrank , ParaMEDMEM::MPIAccess mpi_access ) { + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + if ( sts != MPI_SUCCESS ) { + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test_AllToAllvDEC" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + ostringstream strstream ; + strstream << "===========================================================" + << "test_AllToAllvDEC" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + return ; +} + +void MPIAccessDECTest::test_AllToAllvDEC( bool Asynchronous ) { + + cout << "test_AllToAllvDEC" << endl ; + + // MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 2 || size > 11 ) { + ostringstream strstream ; + strstream << "usage :" << endl + << "mpirun -np <nbprocs> test_AllToAllvDEC" << endl + << " (nbprocs >=2)" << endl + << "test must be runned with more than 1 proc and less than 12 procs" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + // int Asynchronous = atoi(argv[1]); + + cout << "test_AllToAllvDEC" << myrank << endl ; + + ParaMEDMEM::CommInterface interface ; + std::set<int> sourceprocs; + std::set<int> targetprocs; + int i ; + for ( i = 0 ; i < size/2 ; i++ ) { + sourceprocs.insert(i); + } + for ( i = size/2 ; i < size ; i++ ) { + targetprocs.insert(i); + } + + ParaMEDMEM::MPIProcessorGroup* sourcegroup = new ParaMEDMEM::MPIProcessorGroup(interface,sourceprocs) ; + ParaMEDMEM::MPIProcessorGroup* targetgroup = new ParaMEDMEM::MPIProcessorGroup(interface,targetprocs) ; + + MPIAccessDEC * MyMPIAccessDEC = new MPIAccessDEC( *sourcegroup , *targetgroup , + Asynchronous ) ; + + MPIAccess * mpi_access = MyMPIAccessDEC->getMPIAccess() ; + +#define maxreq 100 +#define datamsglength 10 + + // int sts ; + int *sendcounts = new int[size] ; + int *sdispls = new int[size] ; + int *recvcounts = new int[size] ; + int *rdispls = new int[size] ; + for ( i = 0 ; i < size ; i++ ) { + sendcounts[i] = datamsglength-i; + sdispls[i] = i*datamsglength ; + recvcounts[i] = datamsglength-myrank; + rdispls[i] = i*datamsglength ; + } + int * recvbuf = new int[datamsglength*size] ; + + int ireq ; + for ( ireq = 0 ; ireq < maxreq ; ireq++ ) { + int * sendbuf = new int[datamsglength*size] ; + // int * sendbuf = (int *) malloc( sizeof(int)*datamsglength*size) ; + int j ; + for ( j = 0 ; j < datamsglength*size ; j++ ) { + sendbuf[j] = myrank*1000000 + ireq*1000 + j ; + recvbuf[j] = -1 ; + } + + MyMPIAccessDEC->allToAllv( sendbuf, sendcounts , sdispls , MPI_INT , + recvbuf, recvcounts , rdispls , MPI_INT ) ; + + // cout << "test_AllToAllvDEC" << myrank << " recvbuf before CheckSent" ; + // for ( i = 0 ; i < datamsglength*size ; i++ ) { + // cout << " " << recvbuf[i] ; + // } + // cout << endl ; + + // cout << "test_AllToAllvDEC" << myrank << " sendbuf " << sendbuf << endl ; + // MyMPIAccessDEC->CheckSent() ; + + int nRecvReq = mpi_access->recvRequestIdsSize() ; + // cout << "test_AllToAllvDEC" << myrank << " WaitAllRecv " << nRecvReq << " Requests" << endl ; + int *ArrayOfRecvRequests = new int[nRecvReq] ; + int nReq = mpi_access->recvRequestIds( nRecvReq, ArrayOfRecvRequests ) ; + mpi_access->waitAll( nReq , ArrayOfRecvRequests ) ; + mpi_access->deleteRequests( nReq , ArrayOfRecvRequests ) ; + delete [] ArrayOfRecvRequests ; + + // cout << "test_AllToAllvDEC" << myrank << " recvbuf" ; + // for ( i = 0 ; i < datamsglength*size ; i++ ) { + // cout << " " << recvbuf[i] ; + // } + // cout << endl ; + } + + // cout << "test_AllToAllvDEC" << myrank << " final CheckSent" << endl ; + // MyMPIAccessDEC->CheckSent() ; + + int nSendReq = mpi_access->sendRequestIdsSize() ; + cout << "test_AllToAllvDEC" << myrank << " final SendRequestIds " << nSendReq << " SendRequests" + << endl ; + if ( nSendReq ) { + int *ArrayOfSendRequests = new int[nSendReq] ; + int nReq = mpi_access->sendRequestIds( nSendReq, ArrayOfSendRequests ) ; + mpi_access->waitAll( nReq , ArrayOfSendRequests ) ; + delete [] ArrayOfSendRequests ; + } + + int nRecvReq = mpi_access->recvRequestIdsSize() ; + if ( nRecvReq ) { + ostringstream strstream ; + strstream << "test_AllToAllvDEC" << myrank << " final RecvRequestIds " << nRecvReq + << " RecvRequests # 0 Error" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "test_AllToAllvDEC" << myrank << " final RecvRequestIds " << nRecvReq + << " RecvRequests = 0 OK" << endl ; + } + + mpi_access->barrier() ; + + delete sourcegroup ; + delete targetgroup ; + delete MyMPIAccessDEC ; + delete [] sendcounts ; + delete [] sdispls ; + delete [] recvcounts ; + delete [] rdispls ; + delete [] recvbuf ; + + // MPI_Finalize(); + + cout << "test_AllToAllvDEC" << myrank << " OK" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/Test/test_AllToAllvTimeDEC.cxx b/src/ParaMEDMEM/Test/test_AllToAllvTimeDEC.cxx new file mode 100644 index 000000000..e8bbb1f4d --- /dev/null +++ b/src/ParaMEDMEM/Test/test_AllToAllvTimeDEC.cxx @@ -0,0 +1,362 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> +#include <time.h> + +#include "MPIAccessDECTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccessDEC.hxx" +#include "LinearTimeInterpolator.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessDECTest::test_AllToAllvTimeDECSynchronousNative() { + test_AllToAllvTimeDEC( false , true ) ; +} +void MPIAccessDECTest::test_AllToAllvTimeDECSynchronousPointToPoint() { + test_AllToAllvTimeDEC( false , false ) ; +} +void MPIAccessDECTest::test_AllToAllvTimeDECAsynchronousPointToPoint() { + test_AllToAllvTimeDEC( true , false ) ; +} + +static void chksts( int sts , int myrank , ParaMEDMEM::MPIAccess * mpi_access ) { + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + if ( sts != MPI_SUCCESS ) { + mpi_access->errorString(sts, msgerr, &lenerr) ; + cout << "test_AllToAllvTimeDEC" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + ostringstream strstream ; + strstream << "===========================================================" + << "test_AllToAllvTimeDEC" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + return ; +} + +void MPIAccessDECTest::test_AllToAllvTimeDEC( bool Asynchronous , bool UseMPINative ) { + + cout << "test_AllToAllvTimeDEC" << endl ; + + // MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 2 || size > 11 ) { + ostringstream strstream ; + strstream << "usage :" << endl + << "mpirun -np <nbprocs> test_AllToAllTimeDEC" << endl + << " (nbprocs >=2)" << endl + << "test must be runned with more than 1 proc and less than 12 procs" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + // int Asynchronous = atoi(argv[1]) ; + int UseMPI_Alltoallv = UseMPINative ; + // if ( argc == 3 ) { + // UseMPI_Alltoallv = atoi(argv[2]) ; + // } + + cout << "test_AllToAllvTimeDEC" << myrank << " Asynchronous " << Asynchronous + << " UseMPI_Alltoallv " << UseMPI_Alltoallv << endl ; + + ParaMEDMEM::CommInterface interface ; + std::set<int> sourceprocs; + std::set<int> targetprocs; + int i ; + for ( i = 0 ; i < size/2 ; i++ ) { + sourceprocs.insert(i); + } + for ( i = size/2 ; i < size ; i++ ) { + targetprocs.insert(i); + } + + ParaMEDMEM::MPIProcessorGroup* sourcegroup = new ParaMEDMEM::MPIProcessorGroup(interface,sourceprocs) ; + ParaMEDMEM::MPIProcessorGroup* targetgroup = new ParaMEDMEM::MPIProcessorGroup(interface,targetprocs) ; + + // TimeInterpolator * aLinearInterpDEC = new LinearTimeInterpolator( 0.5 ) ; + MPIAccessDEC * MyMPIAccessDEC = new MPIAccessDEC( *sourcegroup , *targetgroup , + Asynchronous ) ; + // Asynchronous , LinearInterp , 0.5 ) ; + MyMPIAccessDEC->setTimeInterpolator( LinearTimeInterp , 0.5 ) ; + MPIAccess * mpi_access = MyMPIAccessDEC->getMPIAccess() ; + + cout << "test_AllToAllvTimeDEC" << myrank << " Barrier :" << endl ; + mpi_access->barrier() ; + cout << "test_AllToAllvTimeDEC" << myrank << " Barrier done" << endl ; + +#define maxproc 11 +#define maxreq 10000 +#define datamsglength 10 + + int sts ; + int *sendcounts = new int[size] ; + int *sdispls = new int[size] ; + int *recvcounts = new int[size] ; + int *rdispls = new int[size] ; + int *sendtimecounts = new int[size] ; + int *stimedispls = new int[size] ; + int *recvtimecounts = new int[size] ; + int *rtimedispls = new int[size] ; + for ( i = 0 ; i < size ; i++ ) { + sendcounts[i] = datamsglength-i ; + sdispls[i] = i*datamsglength ; + recvcounts[i] = datamsglength-myrank ; + rdispls[i] = i*datamsglength ; + sendtimecounts[i] = 1 ; + stimedispls[i] = 0 ; + recvtimecounts[i] = 1 ; + rtimedispls[i] = i ; + //rtimedispls[i] = i*mpi_access->TimeExtent() ; + } + + double time = 0 ; + double deltatime[maxproc] = {1.,2.1,3.2,4.3,5.4,6.5,7.6,8.7,9.8,10.9,11.} ; + double maxtime ; + double nextdeltatime = deltatime[myrank] ; + if ( UseMPI_Alltoallv ) { + maxtime = maxreq*nextdeltatime - 0.1 ; + } + else { + maxtime = maxreq ; + // MyMPIAccessDEC->InitTime( time , nextdeltatime , maxtime ) ; + } + time_t begintime = std::time(NULL) ; + // for ( time = 0 ; time <= maxtime ; time+=deltatime[myrank] ) { + for ( time = 0 ; time <= maxtime && nextdeltatime != 0 ; time+=nextdeltatime ) { + nextdeltatime = deltatime[myrank] ; + if ( time != 0 ) { + nextdeltatime = deltatime[myrank] ; + if ( time+nextdeltatime > maxtime ) { + nextdeltatime = 0 ; + } + // MyMPIAccessDEC->NextTime( nextdeltatime ) ; + } + MyMPIAccessDEC->setTime( time , nextdeltatime ) ; + cout << "test_AllToAllvTimeDEC" << myrank << "=====TIME " << time << "=====DELTATIME " + << nextdeltatime << "=====MAXTIME " << maxtime << " ======" << endl ; + int * sendbuf = new int[datamsglength*size] ; + // int * sendbuf = (int *) malloc(sizeof(int)*datamsglength*size) ; + int * recvbuf = new int[datamsglength*size] ; + int j ; + for ( j = 0 ; j < datamsglength*size ; j++ ) { + sendbuf[j] = myrank*1000000 + (j/datamsglength)*1000 + j ; + recvbuf[j] = -1 ; + } + + if ( UseMPI_Alltoallv ) { + const MPI_Comm* comm = MyMPIAccessDEC->getComm(); + TimeMessage * aSendTimeMessage = new TimeMessage ; + aSendTimeMessage->time = time ; + // aSendTimeMessage->deltatime = deltatime[myrank] ; + aSendTimeMessage->deltatime = nextdeltatime ; + // aSendTimeMessage->maxtime = maxtime ; + aSendTimeMessage->tag = (int ) (time/deltatime[myrank]) ; + TimeMessage * aRecvTimeMessage = new TimeMessage[size] ; + interface.allToAllV(aSendTimeMessage, sendtimecounts , stimedispls , + mpi_access->timeType() , + aRecvTimeMessage, recvtimecounts , rtimedispls , + mpi_access->timeType() , *comm ) ; + // for ( j = 0 ; j < size ; j++ ) { + // cout << "test_AllToAllvTimeDEC" << myrank << " TimeMessage received " << j << " " + // << aRecvTimeMessage[j] << endl ; + // } + delete aSendTimeMessage ; + delete [] aRecvTimeMessage ; + interface.allToAllV(sendbuf, sendcounts , sdispls , MPI_INT , + recvbuf, recvcounts , rdispls , MPI_INT , *comm ) ; + // free(sendbuf) ; + delete [] sendbuf ; + } + else { + int sts = MyMPIAccessDEC->allToAllvTime( sendbuf, sendcounts , sdispls , MPI_INT , + recvbuf, recvcounts , rdispls , MPI_INT ) ; + chksts( sts , myrank , mpi_access ) ; + } + + // cout << "test_AllToAllvTimeDEC" << myrank << " recvbuf before CheckSent" ; + // for ( i = 0 ; i < datamsglength*size ; i++ ) { + // cout << " " << recvbuf[i] ; + // } + // cout << endl ; + + // cout << "test_AllToAllvTimeDEC" << myrank << " sendbuf " << sendbuf << endl ; + // MyMPIAccessDEC->CheckSent() ; + + int nRecvReq = mpi_access->recvRequestIdsSize() ; + if ( nRecvReq != 0 ) { + ostringstream strstream ; + strstream << "=============================================================" << endl + << "test_AllToAllvTimeDEC" << myrank << " WaitAllRecv " << nRecvReq << " Requests # 0 ERROR" + << endl << "=============================================================" + << endl ; + int *ArrayOfRecvRequests = new int[nRecvReq] ; + int nReq = mpi_access->recvRequestIds( nRecvReq, ArrayOfRecvRequests ) ; + mpi_access->waitAll( nReq , ArrayOfRecvRequests ) ; + delete [] ArrayOfRecvRequests ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + // cout << "test_AllToAllvTimeDEC" << myrank << " check of recvbuf" << endl ; + bool badrecvbuf = false ; + for ( i = 0 ; i < size ; i++ ) { + int j ; + for ( j = 0 ; j < datamsglength ; j++ ) { + int index = i*datamsglength+j ; + if ( j < recvcounts[i] ) { + if ( recvbuf[index] != (index/datamsglength)*1000000 + myrank*1000 + + myrank*datamsglength+(index%datamsglength) ) { + badrecvbuf = true ; + cout << "test_AllToAllvTimeDEC" << myrank << " recvbuf[" << index << "] " + << recvbuf[index] << " # " << (index/datamsglength)*1000000 + + myrank*1000 + + myrank*datamsglength+(index%datamsglength) << endl ; + } + else if ( badrecvbuf ) { + cout << "test_AllToAllvTimeDEC" << myrank << " recvbuf[" << index << "] " + << recvbuf[index] << " == " << (index/datamsglength)*1000000 + + myrank*1000 + + myrank*datamsglength+(index%datamsglength) << endl ; + } + } + else if ( recvbuf[index] != -1 ) { + badrecvbuf = true ; + cout << "test_AllToAllvTimeDEC" << myrank << " recvbuf[" << index << "] " + << recvbuf[index] << " # -1" << endl ; + } + } + } + if ( badrecvbuf ) { + ostringstream strstream ; + strstream << "==============================================================" << endl + << "test_AllToAllvTimeDEC" << myrank << " badrecvbuf" + << endl << "=============================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + delete [] recvbuf ; + } + + cout << "test_AllToAllvTimeDEC" << myrank << " Barrier :" << endl ; + mpi_access->barrier() ; + cout << "test_AllToAllvTimeDEC" << myrank << " Barrier done" << endl ; + + cout << "test_AllToAllvTimeDEC" << myrank << " CheckFinalSent" << endl ; + sts = MyMPIAccessDEC->checkFinalSent() ; + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "================================================================" << endl + << "test_AllToAllvTimeDEC" << myrank << " final CheckSent ERROR" + << endl << "================================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + cout << "test_AllToAllvTimeDEC" << myrank << " CheckFinalRecv" << endl ; + sts = MyMPIAccessDEC->checkFinalRecv() ; + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "================================================================" << endl + << "test_AllToAllvTimeDEC" << myrank << " CheckFinalRecv ERROR" + << endl << "================================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + int nRecvReq = mpi_access->recvRequestIdsSize() ; + if ( nRecvReq ) { + ostringstream strstream ; + strstream << "===============================================================" << endl + << "test_AllToAllvTimeDEC" << myrank << " RecvRequestIds " << nRecvReq + << " RecvRequests # 0 Error" + << endl << "===============================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "test_AllToAllvTimeDEC" << myrank << " RecvRequestIds " << nRecvReq + << " RecvRequests = 0 OK" << endl ; + } + + time_t endtime = std::time(NULL) ; + cout << "test_AllToAllvTimeDEC" << myrank << " begintime " << begintime << " endtime " << endtime + << " elapse " << endtime-begintime << " " << maxtime/deltatime[myrank] + << " calls to AllToAll" << endl ; + + cout << "test_AllToAllvTimeDEC" << myrank << " Barrier :" << endl ; + mpi_access->barrier() ; + cout << "test_AllToAllvTimeDEC" << myrank << " Barrier done" << endl ; + + delete sourcegroup ; + delete targetgroup ; + delete MyMPIAccessDEC ; + // delete aLinearInterpDEC ; + + delete [] sendcounts ; + delete [] sdispls ; + delete [] recvcounts ; + delete [] rdispls ; + delete [] sendtimecounts ; + delete [] stimedispls ; + delete [] recvtimecounts ; + delete [] rtimedispls ; + + // MPI_Finalize(); + + endtime = std::time(NULL) ; + + cout << "test_AllToAllvTimeDEC" << myrank << " OK begintime " << begintime << " endtime " << endtime + << " elapse " << endtime-begintime << " " << maxtime/deltatime[myrank] + << " calls to AllToAll" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/Test/test_AllToAllvTimeDoubleDEC.cxx b/src/ParaMEDMEM/Test/test_AllToAllvTimeDoubleDEC.cxx new file mode 100644 index 000000000..81813e1a5 --- /dev/null +++ b/src/ParaMEDMEM/Test/test_AllToAllvTimeDoubleDEC.cxx @@ -0,0 +1,336 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <math.h> +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> +#include <time.h> + +#include "MPIAccessDECTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccessDEC.hxx" +#include "LinearTimeInterpolator.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessDECTest::test_AllToAllvTimeDoubleDECSynchronousPointToPoint() { + test_AllToAllvTimeDoubleDEC( false ) ; +} +void MPIAccessDECTest::test_AllToAllvTimeDoubleDECAsynchronousPointToPoint() { + test_AllToAllvTimeDoubleDEC( true ) ; +} + +static void chksts( int sts , int myrank , ParaMEDMEM::MPIAccess * mpi_access ) { + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + if ( sts != MPI_SUCCESS ) { + mpi_access->errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + return ; +} + +void MPIAccessDECTest::test_AllToAllvTimeDoubleDEC( bool Asynchronous ) { + + cout << "test_AllToAllvTimeDoubleDEC" << endl ; + +// MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 2 || size > 11 ) { + ostringstream strstream ; + strstream << "usage :" << endl + << "mpirun -np <nbprocs> test_AllToAllTimeDEC" << endl + << " (nbprocs >=2)" << endl + << "test must be runned with more than 1 proc and less than 12 procs" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + +// int Asynchronous = atoi(argv[1]) ; + + cout << "test_AllToAllvTimeDoubleDEC" << myrank << " Asynchronous " << Asynchronous << endl ; + + ParaMEDMEM::CommInterface interface ; + std::set<int> sourceprocs; + std::set<int> targetprocs; + int i ; + for ( i = 0 ; i < size/2 ; i++ ) { + sourceprocs.insert(i); + } + for ( i = size/2 ; i < size ; i++ ) { + targetprocs.insert(i); + } + + ParaMEDMEM::MPIProcessorGroup* sourcegroup = new ParaMEDMEM::MPIProcessorGroup(interface,sourceprocs) ; + ParaMEDMEM::MPIProcessorGroup* targetgroup = new ParaMEDMEM::MPIProcessorGroup(interface,targetprocs) ; + +// TimeInterpolator * aLinearInterpDEC = new LinearTimeInterpolator( 0 ) ; + MPIAccessDEC * MyMPIAccessDEC = new MPIAccessDEC( *sourcegroup , *targetgroup , + Asynchronous ) ; +// Asynchronous , LinearInterp , 0.5 ) ; + MyMPIAccessDEC->setTimeInterpolator( LinearTimeInterp ) ; + MPIAccess * mpi_access = MyMPIAccessDEC->getMPIAccess() ; + + cout << "test_AllToAllvTimeDoubleDEC" << myrank << " Barrier :" << endl ; + mpi_access->barrier() ; + +#define maxproc 11 +#define maxreq 100 +#define datamsglength 10 + + int sts ; + int *sendcounts = new int[size] ; + int *sdispls = new int[size] ; + int *recvcounts = new int[size] ; + int *rdispls = new int[size] ; + int *sendtimecounts = new int[size] ; + int *stimedispls = new int[size] ; + int *recvtimecounts = new int[size] ; + int *rtimedispls = new int[size] ; + for ( i = 0 ; i < size ; i++ ) { + sendcounts[i] = datamsglength-i ; + sdispls[i] = i*datamsglength ; + recvcounts[i] = datamsglength-myrank ; + rdispls[i] = i*datamsglength ; + sendtimecounts[i] = 1 ; + stimedispls[i] = 0 ; + recvtimecounts[i] = 1 ; + rtimedispls[i] = i ; + } + + double time[maxproc] ; + double deltatime[maxproc] = {1.,2.1,3.2,4.3,5.4,6.5,7.6,8.7,9.8,10.9,11.} ; + double maxtime[maxproc] ; + double nextdeltatime[maxproc] ; + for ( i = 0 ; i < size ; i++ ) { + time[i] = 0 ; + maxtime[i] = maxreq ; + nextdeltatime[i] = deltatime[i] ; + } + time_t begintime = std::time(NULL) ; + for ( time[myrank] = 0 ; time[myrank] <= maxtime[myrank] && nextdeltatime[myrank] != 0 ; + time[myrank]+=nextdeltatime[myrank] ) { +//local and target times + int target ; + for ( target = 0 ; target < size ; target++ ) { + nextdeltatime[target] = deltatime[target] ; + if ( time[target] != 0 ) { + if ( time[target]+nextdeltatime[target] > maxtime[target] ) { + nextdeltatime[target] = 0 ; + } + } + if ( target != myrank ) { + while ( time[myrank] >= time[target] ) { + time[target] += deltatime[target] ; + } + } + } + MyMPIAccessDEC->setTime( time[myrank] , nextdeltatime[myrank] ) ; + cout << "test" << myrank << "=====TIME " << time[myrank] << "=====DELTATIME " + << nextdeltatime[myrank] << "=====MAXTIME " << maxtime[myrank] << " ======" + << endl ; + double * sendbuf = new double[datamsglength*size] ; +// double * sendbuf = (double *) malloc(sizeof(double)*datamsglength*size) ; + double * recvbuf = new double[datamsglength*size] ; + int j ; + //cout << "test_AllToAllvTimeDoubleDEC" << myrank << " sendbuf" ; + for ( target = 0 ; target < size ; target++ ) { + for ( j = 0 ; j < datamsglength ; j++ ) { + //sendbuf[j] = myrank*10000 + (j/datamsglength)*100 + j ; + sendbuf[target*datamsglength+j] = myrank*1000000 + target*10000 + + (time[myrank]/deltatime[myrank])*100 + j ; + //cout << " " << (int ) sendbuf[target*datamsglength+j] ; + recvbuf[target*datamsglength+j] = -1 ; + } + //cout << endl ; + } + + int sts = MyMPIAccessDEC->allToAllvTime( sendbuf, sendcounts , sdispls , MPI_DOUBLE , + recvbuf, recvcounts , rdispls , MPI_DOUBLE ) ; + chksts( sts , myrank , mpi_access ) ; + +// cout << "test_AllToAllvTimeDoubleDEC" << myrank << " recvbuf before CheckSent" ; +// for ( i = 0 ; i < datamsglength*size ; i++ ) { +// cout << " " << recvbuf[i] ; +// } +// cout << endl ; + + int nRecvReq = mpi_access->recvRequestIdsSize() ; + if ( nRecvReq != 0 ) { + ostringstream strstream ; + strstream << "=============================================================" << endl + << "test_AllToAllvTimeDoubleDEC" << myrank << " WaitAllRecv " + << nRecvReq << " Requests # 0 ERROR" + << endl << "============================================================" + << endl ; + int *ArrayOfRecvRequests = new int[nRecvReq] ; + int nReq = mpi_access->recvRequestIds( nRecvReq, ArrayOfRecvRequests ) ; + mpi_access->waitAll( nReq , ArrayOfRecvRequests ) ; + delete [] ArrayOfRecvRequests ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + +// cout << "test_AllToAllvTimeDoubleDEC" << myrank << " check of recvbuf" << endl ; + bool badrecvbuf = false ; + for ( target = 0 ; target < size ; target++ ) { + int j ; + for ( j = 0 ; j < datamsglength ; j++ ) { + int index = target*datamsglength+j ; + if ( j < recvcounts[target] ) { + if ( fabs(recvbuf[index] - (target*1000000 + myrank*10000 + + (time[target]/deltatime[target])*100 + j)) > 101) { + badrecvbuf = true ; + cout << "test_AllToAllvTimeDoubleDEC" << myrank << " target " << target << " time[target] " + << time[target] << " recvbuf[" << index << "] " << (int ) recvbuf[index] + << " # " << (int ) (target*1000000 + + myrank*10000 + (time[target]/deltatime[target])*100 + j) + << endl ; + } + else if ( badrecvbuf ) { + cout << "test_AllToAllvTimeDoubleDEC" << myrank << " recvbuf[" << index << "] " + << recvbuf[index] << " ~= " << (int ) (target*1000000 + + myrank*10000 + (time[target]/deltatime[target])*100 + j) << endl ; + } + } + else if ( recvbuf[index] != -1 ) { + badrecvbuf = true ; + cout << "test_AllToAllvTimeDoubleDEC" << myrank << " recvbuf[" << index << "] " + << recvbuf[index] << " # -1" << endl ; + } + } + } + if ( badrecvbuf ) { + ostringstream strstream ; + strstream << "==================================================================" << endl + << "test_AllToAllvTimeDoubleDEC" << myrank << " badrecvbuf" + << endl << "==================================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + delete [] recvbuf ; + } + + cout << "test_AllToAllvTimeDoubleDEC" << myrank << " Barrier :" << endl ; + mpi_access->barrier() ; + + cout << "test_AllToAllvTimeDoubleDEC" << myrank << " CheckFinalSent" << endl ; + sts = MyMPIAccessDEC->checkFinalSent() ; + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "=================================================================" << endl + << "test_AllToAllvTimeDoubleDEC" << myrank << " CheckFinalSent ERROR" + << endl << "=================================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + cout << "test_AllToAllvTimeDoubleDEC" << myrank << " CheckFinalRecv" << endl ; + sts = MyMPIAccessDEC->checkFinalRecv() ; + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "=================================================================" << endl + << "test_AllToAllvTimeDoubleDEC" << myrank << " CheckFinalRecv ERROR" + << endl << "================================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + int nRecvReq = mpi_access->recvRequestIdsSize() ; + if ( nRecvReq ) { + ostringstream strstream ; + strstream << "===============================================================" << endl + << "test_AllToAllvTimeDoubleDEC" << myrank << " RecvRequestIds " << nRecvReq + << " RecvRequests # 0 Error" + << endl << "===============================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "test_AllToAllvTimeDoubleDEC" << myrank << " RecvRequestIds " << nRecvReq + << " RecvRequests = 0 OK" << endl ; + } + + time_t endtime = std::time(NULL) ; + cout << "test_AllToAllvTimeDoubleDEC" << myrank << " begintime " << begintime << " endtime " << endtime + << " elapse " << endtime-begintime << " " << maxtime[myrank]/deltatime[myrank] + << " calls to AllToAll" << endl ; + + cout << "test" << myrank << " Barrier :" << endl ; + mpi_access->barrier() ; + + delete sourcegroup ; + delete targetgroup ; + delete MyMPIAccessDEC ; +// delete aLinearInterpDEC ; + + delete [] sendcounts ; + delete [] sdispls ; + delete [] recvcounts ; + delete [] rdispls ; + delete [] sendtimecounts ; + delete [] stimedispls ; + delete [] recvtimecounts ; + delete [] rtimedispls ; + +// MPI_Finalize(); + + endtime = std::time(NULL) ; + + cout << "test_AllToAllvTimeDoubleDEC" << myrank << " OK begintime " << begintime << " endtime " << endtime + << " elapse " << endtime-begintime << " " << maxtime[myrank]/deltatime[myrank] + << " calls to AllToAll" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/Test/test_MPI_Access_Cancel.cxx b/src/ParaMEDMEM/Test/test_MPI_Access_Cancel.cxx new file mode 100644 index 000000000..2ac553f3e --- /dev/null +++ b/src/ParaMEDMEM/Test/test_MPI_Access_Cancel.cxx @@ -0,0 +1,320 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <time.h> +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> + +#include "MPIAccessTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccess.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessTest::test_MPI_Access_Cancel() { + + cout << "test_MPI_Access_Cancel" << endl ; + +// MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 2 ) { + ostringstream strstream ; + strstream << "test_MPI_Access_Cancel must be runned with 2 procs" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + cout << "test_MPI_Access_Cancel" << myrank << endl ; + + ParaMEDMEM::CommInterface interface ; + + ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; + + ParaMEDMEM::MPIAccess mpi_access( group ) ; + + if ( myrank >= 2 ) { + mpi_access.barrier() ; + delete group ; + return ; + } + + int target = 1 - myrank ; + int intsendbuf[5] ; + double doublesendbuf[10] ; + int RequestId[10] ; + int sts ; + int i , j ; + for ( j = 0 ; j < 3 ; j++ ) { + for ( i = 0 ; i < 10 ; i++ ) { + cout << "test" << myrank << " ============================ i " << i + << "============================" << endl ; + if ( myrank == 0 ) { + if ( i < 5 ) { + intsendbuf[i] = i ; + sts = mpi_access.ISend(&intsendbuf[i],1,MPI_INT,target, RequestId[i]) ; + cout << "test" << myrank << " Send MPI_INT RequestId " << RequestId[i] + << endl ; + } + else { + doublesendbuf[i] = i ; + sts = mpi_access.ISend(&doublesendbuf[i],1,MPI_DOUBLE,target, + RequestId[i]) ; + cout << "test" << myrank << " Send MPI_DOUBLE RequestId " << RequestId[i] + << endl ; + } + } + else { + int flag = false ; + while ( !flag ) { + int source, tag, outcount ; + MPI_Datatype datatype ; + sts = mpi_access.IProbe(target, source, tag, datatype, outcount, + flag ) ; + if ( flag ) { + cout << "test" << myrank << " " << i << " IProbe target " << target + << " source " << source << " tag " << tag + << " outcount " << outcount << " flag " << flag << endl ; + } + else { + cout << "test" << myrank << " flag " << flag << endl ; + sleep( 1 ) ; + } + if ( flag ) { + int recvbuf ; + sts = mpi_access.IRecv(&recvbuf,outcount,MPI_INT,source, + RequestId[i] ) ; + if ( datatype == MPI_INT ) { + int source, tag, error, outcount ; + mpi_access.wait( RequestId[i] ) ; + mpi_access.status( RequestId[i], source, tag, error, outcount, + true ) ; + if ( (outcount != 1) | (recvbuf != i) ) { + ostringstream strstream ; + strstream << "======================================================" + << endl << "test" << myrank << " outcount " << outcount + << " recvbuf " << recvbuf << " KO" << endl + << "======================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + cout << "========================================================" + << endl << "test" << myrank << " outcount " << outcount + << " recvbuf " << recvbuf << " OK" << endl + << "========================================================" + << endl ; + } + } + } + } + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "===========================================================" + << endl << "test" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + mpi_access.check() ; + } + + if ( myrank != 0 ) { + int iprobe ; + for ( iprobe = 5 ; iprobe < 10 ; iprobe++ ) { + cout << "test" << myrank << " ============================ iprobe " + << iprobe << "============================" << endl ; + int source, tag, outcount ; + MPI_Datatype datatype ; + int probeflag = false ; + while ( !probeflag ) { + sts = mpi_access.IProbe( target, source, tag, datatype, outcount, + probeflag ) ; + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " IProbe iprobe " << iprobe + << " target " << target << " probeflag " << probeflag + << " tag " << tag << " outcount " << outcount << " datatype " + << datatype << " lenerr " << lenerr << " " << msgerr << endl ; + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "==========================================================" + << endl << "test" << myrank << " IProbe KO iprobe " << iprobe + << endl + << "==========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + if ( !probeflag ) { + //cout << "========================================================" + // << endl << "test" << myrank << " IProbe KO(OK) iprobe " << iprobe + // << " probeflag " << probeflag << endl + // << "========================================================" + // << endl ; + } + else { + cout << "test" << myrank << " " << iprobe << " IProbe target " + << target << " source " << source << " tag " << tag + << " outcount " << outcount << " probeflag " << probeflag + << endl ; + if ( datatype != MPI_DOUBLE ) { + ostringstream strstream ; + strstream << "========================================================" + << endl << "test" << myrank << " MPI_DOUBLE KO" << endl + << "========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + int flag ; + sts = mpi_access.cancel( source, tag, datatype, outcount, flag ) ; + if ( sts != MPI_SUCCESS || !flag ) { + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "======================================================" + << endl << "test" << myrank << " lenerr " << lenerr << " " + << msgerr << endl << "test" << myrank + << " Cancel PendingIrecv KO flag " << flag << " iprobe " + << iprobe << " Irecv completed" << endl + << "======================================================" + << endl ; + //return 1 ; + } + else { + cout << "======================================================" + << endl << "test" << myrank + << " Cancel PendingIrecv OK RequestId " << " flag " + << flag << " iprobe " << iprobe << endl + << "======================================================" + << endl ; + } + } + int Reqtarget, Reqtag, Reqerror, Reqoutcount ; + mpi_access.status( RequestId[iprobe], Reqtarget, Reqtag, Reqerror, + Reqoutcount, true ) ; + cout << "test" << myrank << " Status Reqtarget "<< Reqtarget + << " Reqtag " << Reqtag << " Reqoutcount " << Reqoutcount + << endl ; + int Reqflag ; + sts = mpi_access.cancel( RequestId[iprobe] , Reqflag ) ; + cout << "test" << myrank << " " << iprobe + << " Cancel Irecv done Reqtarget " << Reqtarget + << " Reqtag " << Reqtag << " Reqoutcount " << Reqoutcount + << " Reqflag " << Reqflag << endl ; + if ( sts != MPI_SUCCESS || !Reqflag ) { + mpi_access.errorString(sts, msgerr, &lenerr) ; + ostringstream strstream ; + strstream << "========================================================" + << endl << "test" << myrank << " lenerr " << lenerr << " " + << msgerr << endl << "test" << myrank + << " Cancel Irecv KO Reqflag " << Reqflag << " iprobe " + << iprobe << endl + << "========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "========================================================" + << endl << "test" << myrank + << " Cancel Irecv OK RequestId " << RequestId[iprobe] + << " Reqflag " << Reqflag << " iprobe " << iprobe << endl + << "========================================================" + << endl ; + probeflag = Reqflag ; + } + } + } + } + } + mpi_access.waitAll(10,RequestId) ; + mpi_access.deleteRequests(10,RequestId) ; + } + + int source, tag, outcount, flag ; + MPI_Datatype datatype ; + sts = mpi_access.IProbe(target, source, tag, datatype, outcount, flag ) ; + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + if ( sts != MPI_SUCCESS || flag ) { + ostringstream strstream ; + strstream << "===========================================================" + << endl << "test" << myrank << " IProbe KO flag " << flag + << " remaining unread/cancelled message :" << endl + << " source " << source << " tag " << tag << endl + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + mpi_access.testAll(10,RequestId,flag) ; + mpi_access.waitAll(10,RequestId) ; + mpi_access.deleteRequests(10,RequestId) ; + mpi_access.testAll(10,RequestId,flag) ; + if ( !flag ) { + ostringstream strstream ; + strstream << "test" << myrank << " flag " << flag << " KO" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + mpi_access.check() ; + + mpi_access.barrier() ; + + delete group ; + +// MPI_Finalize(); + + cout << "test" << myrank << " OK" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/Test/test_MPI_Access_Cyclic_ISend_IRecv.cxx b/src/ParaMEDMEM/Test/test_MPI_Access_Cyclic_ISend_IRecv.cxx new file mode 100644 index 000000000..d2a84289c --- /dev/null +++ b/src/ParaMEDMEM/Test/test_MPI_Access_Cyclic_ISend_IRecv.cxx @@ -0,0 +1,269 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> + +#include "MPIAccessTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccess.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessTest::test_MPI_Access_Cyclic_ISend_IRecv() { + + cout << "test_MPI_Access_Cyclic_ISend_IRecv" << endl ; + +// MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 3 ) { + cout << "test_MPI_Access_Cyclic_ISend_IRecv must be runned with 3 procs" << endl ; + CPPUNIT_FAIL("test_MPI_Access_Cyclic_ISend_IRecv must be runned with 3 procs") ; + } + + cout << "test_MPI_Access_Cyclic_ISend_IRecv" << myrank << endl ; + + ParaMEDMEM::CommInterface interface ; + + ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; + + ParaMEDMEM::MPIAccess mpi_access( group ) ; + +#define maxsend 100 + + if ( myrank >= 3 ) { + mpi_access.barrier() ; + delete group ; + return ; + } + + int alltarget[3] = {1 , 2 , 0 } ; + int allsource[3] = {2 , 0 , 1 } ; + int SendRequestId[maxsend] ; + int RecvRequestId[maxsend] ; + int sendbuf[maxsend] ; + int recvbuf[maxsend] ; + int sts ; + int i = 0 ; + if ( myrank == 0 ) { + sendbuf[i] = i ; + sts = mpi_access.ISend(&sendbuf[i],1,MPI_INT,alltarget[myrank], + SendRequestId[i]) ; + cout << "test" << myrank << " Send RequestId " << SendRequestId[i] + << " tag " << mpi_access.sendMPITag(alltarget[myrank]) << endl ; + } + for ( i = 0 ; i < maxsend ; i++ ) { + recvbuf[i] = -1 ; + sts = mpi_access.IRecv(&recvbuf[i],1,MPI_INT,allsource[myrank], + RecvRequestId[i]) ; + cout << "test" << myrank << " Recv RequestId " << RecvRequestId[i] + << " tag " << mpi_access.recvMPITag(allsource[myrank]) << endl ; + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr + << " " << msgerr << endl ; + + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + int j ; + for (j = 0 ; j <= i ; j++) { + int flag ; + if ( j < i ) { + cout << "test" << myrank << " " << j << " -> Test-Send("<< SendRequestId[j] + << ")" << endl ; + mpi_access.test( SendRequestId[j], flag ) ; + if ( flag ) { + int target, tag, error, outcount ; + mpi_access.status( SendRequestId[j], target, tag, error, outcount, + true ) ; + cout << "test" << myrank << " Send RequestId " << SendRequestId[j] + << " target " << target << " tag " << tag << " error " << error + << endl ; + mpi_access.deleteRequest( SendRequestId[j] ) ; + } + } + cout << "test" << myrank << " " << j << " -> Test-Recv("<< SendRequestId[j] + << ")" << endl ; + mpi_access.test( RecvRequestId[j], flag ) ; + if ( flag ) { + int source, tag, error, outcount ; + mpi_access.status( RecvRequestId[j], source, tag, error, outcount, + true ) ; + cout << "test" << myrank << " Recv RequestId" << j << " " + << RecvRequestId[j] << " source " << source << " tag " << tag + << " error " << error << " outcount " << outcount << endl ; + if ( (outcount != 1) | (recvbuf[j] != j) ) { + ostringstream strstream ; + strstream << "=====================================================" + << endl << "test" << myrank << " outcount " + << outcount << " recvbuf[ " << j << " ] " << recvbuf[j] << " KO" + << endl << "=====================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + } + } + if ( myrank == 0 ) { + if ( i != maxsend-1 ) { + sendbuf[i+1] = i + 1 ; + sts = mpi_access.ISend(&sendbuf[i+1],1,MPI_INT,alltarget[myrank], + SendRequestId[i+1]) ; + cout << "test" << myrank << " Send RequestId " << SendRequestId[i+1] + << " tag " << mpi_access.sendMPITag(alltarget[myrank]) << endl ; + } + } + else { + sendbuf[i] = i ; + sts = mpi_access.ISend(&sendbuf[i],1,MPI_INT,alltarget[myrank], + SendRequestId[i]) ; + cout << "test" << myrank << " Send RequestId " << SendRequestId[i] + << " tag " << mpi_access.sendMPITag(alltarget[myrank]) << endl ; + } + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr + << " " << msgerr << endl ; + + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + mpi_access.check() ; + } + + int flag ; + mpi_access.testAll(maxsend,SendRequestId,flag) ; + mpi_access.testAll(maxsend,RecvRequestId,flag) ; + mpi_access.waitAll(maxsend,SendRequestId) ; + mpi_access.deleteRequests(maxsend,SendRequestId) ; + mpi_access.waitAll(maxsend,RecvRequestId) ; + mpi_access.deleteRequests(maxsend,RecvRequestId) ; + mpi_access.check() ; + mpi_access.testAll(maxsend,SendRequestId,flag) ; + if ( !flag ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " TestAllSendflag " << flag << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "=========================================================" << endl + << "test" << myrank << " TestAllSendflag " << flag << " OK" << endl + << "=========================================================" << endl ; + } + mpi_access.testAll(maxsend,RecvRequestId,flag) ; + if ( !flag ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " TestAllRecvflag " << flag << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "=========================================================" << endl + << "test" << myrank << " TestAllRecvflag " << flag << " OK" << endl + << "=========================================================" << endl ; + } + + int sendrequests[maxsend] ; + int sendreqsize = mpi_access.sendRequestIds( alltarget[myrank] , maxsend , + sendrequests ) ; + if ( sendreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + int source, tag, error, outcount ; + mpi_access.status(sendrequests[0], source, tag, error, outcount, true) ; + cout << "test" << myrank << " RequestId " << sendrequests[0] + << " source " << source << " tag " << tag << " error " << error + << " outcount " << outcount << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl + << "=========================================================" << endl ; + } + int recvrequests[maxsend] ; + int recvreqsize = mpi_access.sendRequestIds( allsource[myrank] , maxsend , + recvrequests ) ; + if ( recvreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl + << "=========================================================" << endl ; + } + + mpi_access.barrier() ; + + delete group ; + +// MPI_Finalize(); + + cout << "test" << myrank << " OK" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/Test/test_MPI_Access_Cyclic_Send_Recv.cxx b/src/ParaMEDMEM/Test/test_MPI_Access_Cyclic_Send_Recv.cxx new file mode 100644 index 000000000..b825f90ef --- /dev/null +++ b/src/ParaMEDMEM/Test/test_MPI_Access_Cyclic_Send_Recv.cxx @@ -0,0 +1,186 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> +#include "MPIAccessTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccess.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessTest::test_MPI_Access_Cyclic_Send_Recv() { + + cout << "test_MPI_Access_Cyclic_Send_Recv" << endl ; + +// MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 3 ) { + cout << "test_MPI_Access_Send_Recv must be runned with 3 procs" << endl ; + CPPUNIT_FAIL("test_MPI_Access_Send_Recv must be runned with 3 procs") ; + } + + cout << "test_MPI_Access_Cyclic_Send_Recv" << myrank << endl ; + + ParaMEDMEM::CommInterface interface ; + + ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; + + ParaMEDMEM::MPIAccess mpi_access( group ) ; + + if ( myrank >= 3 ) { + mpi_access.barrier() ; + delete group ; + return ; + } + + int alltarget[3] = {1 , 2 , 0 } ; + int allsource[3] = {2 , 0 , 1 } ; + int RequestId[10] ; + int sts ; + int i = 0 ; + if ( myrank == 0 ) { + sts = mpi_access.send(&i,1,MPI_INT,alltarget[myrank], RequestId[i]) ; + cout << "test" << myrank << " Send RequestId " << RequestId[i] + << " tag " << mpi_access.sendMPITag(alltarget[myrank]) << endl ; + } + for ( i = 0 ; i < 10 ; i++ ) { + int recvbuf ; + int outcount ; + if ( i & 1 ) { + outcount = 0 ; + sts = mpi_access.recv(&recvbuf,1,MPI_INT,allsource[myrank], RequestId[i], + &outcount) ; + } + else { + sts = mpi_access.recv(&recvbuf,1,MPI_INT,allsource[myrank], RequestId[i]) ; + outcount = 1 ; + } + //int source, tag, error, outcount ; + //mpi_access.Status( RequestId[i], source, tag, error, outcount, true) ; + cout << "test" << myrank << " Recv RequestId " << RequestId[i] + << " tag " << mpi_access.recvMPITag(allsource[myrank]) + << " outcount " << outcount << endl ; + if ( (outcount != 1) | (recvbuf != i) ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " outcount " + << outcount << " recvbuf " << recvbuf << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + if ( myrank == 0 ) { + if ( i != 9 ) { + int ii = i + 1 ; + sts = mpi_access.send(&ii,1,MPI_INT,alltarget[myrank], RequestId[i]) ; + cout << "test" << myrank << " Send RequestId " << RequestId[i] + << " tag " << mpi_access.sendMPITag(alltarget[myrank]) << endl ; + } + } + else { + sts = mpi_access.send(&i,1,MPI_INT,alltarget[myrank], RequestId[i]) ; + cout << "test" << myrank << " Send RequestId " << RequestId[i] + << " tag " << mpi_access.sendMPITag(alltarget[myrank]) << endl ; + } + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr + << " " << msgerr << endl ; + + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + mpi_access.check() ; + } + + int flag ; + mpi_access.testAll(10,RequestId,flag) ; + if ( !flag ) { + ostringstream strstream ; + strstream << "test" << myrank << " flag " << flag << " KO" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + mpi_access.waitAll(10,RequestId) ; + mpi_access.check() ; + + int sendrequests[10] ; + int sendreqsize = mpi_access.sendRequestIds( alltarget[myrank] , 10 , + sendrequests ) ; + if ( sendreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + int recvrequests[10] ; + int recvreqsize = mpi_access.sendRequestIds( allsource[myrank] , 10 , + recvrequests ) ; + if ( recvreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + mpi_access.barrier() ; + + delete group ; + +// MPI_Finalize(); + + cout << "test" << myrank << " OK" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/Test/test_MPI_Access_IProbe.cxx b/src/ParaMEDMEM/Test/test_MPI_Access_IProbe.cxx new file mode 100644 index 000000000..9d18c902d --- /dev/null +++ b/src/ParaMEDMEM/Test/test_MPI_Access_IProbe.cxx @@ -0,0 +1,167 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <time.h> +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> + +#include "MPIAccessTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccess.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessTest::test_MPI_Access_IProbe() { + + cout << "test_MPI_Access_IProbe" << endl ; + +// MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 2 ) { + ostringstream strstream ; + strstream << "test_MPI_Access_IProbe must be runned with 2 procs" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + cout << "test_MPI_Access_IProbe" << myrank << endl ; + + ParaMEDMEM::CommInterface interface ; + + ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; + + ParaMEDMEM::MPIAccess mpi_access( group ) ; + + if ( myrank >= 2 ) { + mpi_access.barrier() ; + delete group ; + return ; + } + + int target = 1 - myrank ; + int sendbuf[10] ; + int RequestId[10] ; + int sts ; + int i ; + for ( i = 0 ; i < 10 ; i++ ) { + if ( myrank == 0 ) { + sendbuf[i] = i ; + sts = mpi_access.ISend(&sendbuf[i],1,MPI_INT,target, RequestId[i]) ; + cout << "test" << myrank << " Send RequestId " << RequestId[i] + << endl ; + } + else { + int flag = false ; + while ( !flag ) { + int source, tag, outcount ; + MPI_Datatype datatype ; + sts = mpi_access.IProbe(target, source, tag, datatype, outcount, flag ) ; + if ( flag ) { + cout << "test" << myrank << " " << i << " IProbe target " << target + << " source " << source << " tag " << tag + << " outcount " << outcount << " flag " << flag << endl ; + } + else { + cout << "test" << myrank << " IProbe flag " << flag << endl ; + sleep( 1 ) ; + } + if ( flag ) { + int recvbuf ; + sts = mpi_access.recv(&recvbuf,outcount,datatype,source, RequestId[i], + &outcount) ; + if ( (outcount != 1) | (recvbuf != i) ) { + ostringstream strstream ; + strstream << "===========================================================" + << endl << "test" << myrank << " outcount " << outcount + << " recvbuf " << recvbuf << " KO" << endl + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + cout << "===========================================================" + << endl << "test" << myrank << " outcount " << outcount + << " recvbuf " << recvbuf << " OK" << endl + << "===========================================================" + << endl ; + } + } + } + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + mpi_access.check() ; + } + int flag ; + mpi_access.testAll(10,RequestId,flag) ; + mpi_access.waitAll(10,RequestId) ; + mpi_access.deleteRequests(10,RequestId) ; + mpi_access.testAll(10,RequestId,flag) ; + if ( !flag ) { + ostringstream strstream ; + strstream << "test" << myrank << " flag " << flag << " KO" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + mpi_access.check() ; + + mpi_access.barrier() ; + + delete group ; + +// MPI_Finalize(); + + cout << "test" << myrank << " OK" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/Test/test_MPI_Access_ISendRecv.cxx b/src/ParaMEDMEM/Test/test_MPI_Access_ISendRecv.cxx new file mode 100644 index 000000000..6b5411249 --- /dev/null +++ b/src/ParaMEDMEM/Test/test_MPI_Access_ISendRecv.cxx @@ -0,0 +1,215 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> + +#include "MPIAccessTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccess.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessTest::test_MPI_Access_ISendRecv() { + + cout << "test_MPI_Access_ISendRecv" << endl ; + +// MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 2 ) { + cout << "test_MPI_Access_ISendRecv must be runned with 2 procs" << endl ; + CPPUNIT_FAIL("test_MPI_Access_ISendRecv must be runned with 2 procs") ; + } + + cout << "test_MPI_Access_ISendRecv" << myrank << endl ; + + ParaMEDMEM::CommInterface interface ; + + ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; + + ParaMEDMEM::MPIAccess mpi_access( group ) ; + + if ( myrank >= 2 ) { + mpi_access.barrier() ; + delete group ; + return ; + } + + int target = 1 - myrank ; + int SendRequestId[10] ; + int RecvRequestId[10] ; + int sendbuf[10] ; + int recvbuf[10] ; + int sts ; + int i ; + for ( i = 0 ; i < 10 ; i++ ) { + sendbuf[i] = i ; + sts = mpi_access.ISendRecv(&sendbuf[i],1,MPI_INT,target, SendRequestId[i], + &recvbuf[i],1,MPI_INT,target, RecvRequestId[i]) ; + cout << "test" << myrank << " Send sendRequestId " << SendRequestId[i] + << " tag " << mpi_access.sendMPITag(target) + << " recvRequestId " << RecvRequestId[i] + << " tag " << mpi_access.recvMPITag(target) << endl ; + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr + << " " << msgerr << endl ; + + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + int j ; + for (j = 0 ; j <= i ; j++) { + int flag ; + if ( j < i ) { + cout << "test" << myrank << " " << j << " -> Test-Send("<< SendRequestId[j] + << ")" << endl ; + mpi_access.test( SendRequestId[j], flag ) ; + if ( flag ) { + int target, tag, error, outcount ; + mpi_access.status( SendRequestId[j], target, tag, error, outcount, + true ) ; + cout << "test" << myrank << " Send RequestId " << SendRequestId[j] + << " target " << target << " tag " << tag << " error " << error + << endl ; + mpi_access.deleteRequest( SendRequestId[j] ) ; + } + } + cout << "test" << myrank << " " << j << " -> Test-Recv("<< SendRequestId[j] + << ")" << endl ; + mpi_access.test( RecvRequestId[j], flag ) ; + if ( flag ) { + int source, tag, error, outcount ; + mpi_access.status( RecvRequestId[j], source, tag, error, outcount, + true ) ; + cout << "test" << myrank << " Recv RequestId" << j << " " + << RecvRequestId[j] << " source " << source << " tag " << tag + << " error " << error << " outcount " << outcount << endl ; + if ( (outcount != 1) | (recvbuf[j] != j) ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " outcount " + << outcount << " recvbuf[ " << j << " ] " << recvbuf[j] << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + } + } + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + mpi_access.check() ; + } + + int flag ; + mpi_access.testAll(10,SendRequestId,flag) ; + mpi_access.waitAll(10,SendRequestId) ; + mpi_access.deleteRequests(10,SendRequestId) ; + mpi_access.testAll(10,SendRequestId,flag) ; + if ( !flag ) { + ostringstream strstream ; + strstream << "test" << myrank << " flag " << flag << " KO" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + mpi_access.testAll(10,RecvRequestId,flag) ; + mpi_access.waitAll(10,RecvRequestId) ; + mpi_access.deleteRequests(10,RecvRequestId) ; + mpi_access.testAll(10,RecvRequestId,flag) ; + if ( !flag ) { + ostringstream strstream ; + strstream << "test" << myrank << " flag " << flag << " KO" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + mpi_access.check() ; + + int sendrequests[10] ; + int sendreqsize = mpi_access.sendRequestIds( target , 10 , sendrequests ) ; + if ( sendreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl + << "=========================================================" << endl ; + } + int recvrequests[10] ; + int recvreqsize = mpi_access.sendRequestIds( target , 10 , recvrequests ) ; + if ( recvreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl + << "=========================================================" << endl ; + } + + mpi_access.barrier() ; + + delete group ; + +// MPI_Finalize(); + + cout << "test" << myrank << " OK" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/Test/test_MPI_Access_ISend_IRecv.cxx b/src/ParaMEDMEM/Test/test_MPI_Access_ISend_IRecv.cxx new file mode 100644 index 000000000..8d1a9306c --- /dev/null +++ b/src/ParaMEDMEM/Test/test_MPI_Access_ISend_IRecv.cxx @@ -0,0 +1,220 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> + +#include "MPIAccessTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccess.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessTest::test_MPI_Access_ISend_IRecv() { + + cout << "test_MPI_Access_ISend_IRecv" << endl ; + + // MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 2 ) { + cout << "test_MPI_Access_ISend_IRecv must be runned with 2 procs" << endl ; + CPPUNIT_FAIL("test_MPI_Access_ISend_IRecv must be runned with 2 procs") ; + } + + cout << "test_MPI_Access_ISend_IRecv" << myrank << endl ; + + ParaMEDMEM::CommInterface interface ; + + ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; + + ParaMEDMEM::MPIAccess mpi_access( group ) ; + +#define maxreq 100 + + if ( myrank >= 2 ) { + mpi_access.barrier() ; + delete group ; + return ; + } + + int target = 1 - myrank ; + int SendRequestId[maxreq] ; + int RecvRequestId[maxreq] ; + int sts ; + int sendbuf[maxreq] ; + int recvbuf[maxreq] ; + int i ; + for ( i = 0 ; i < maxreq ; i++ ) { + if ( myrank == 0 ) { + sendbuf[i] = i ; + sts = mpi_access.ISend(&sendbuf[i],1,MPI_INT,target, SendRequestId[i]) ; + cout << "test" << myrank << " ISend RequestId " << SendRequestId[i] + << " tag " << mpi_access.sendMPITag(target) << endl ; + } + else { + sts = mpi_access.IRecv(&recvbuf[i],1,MPI_INT,target, RecvRequestId[i]) ; + cout << "test" << myrank << " IRecv RequestId " << RecvRequestId[i] + << " tag " << mpi_access.recvMPITag(target) << endl ; + } + int j ; + for (j = 0 ; j <= i ; j++) { + int flag ; + if ( myrank == 0 ) { + mpi_access.test( SendRequestId[j], flag ) ; + } + else { + mpi_access.test( RecvRequestId[j], flag ) ; + } + if ( flag ) { + int target,source, tag, error, outcount ; + if ( myrank == 0 ) { + mpi_access.status( SendRequestId[j], target, tag, error, outcount, + true ) ; + cout << "test" << myrank << " Test(Send RequestId " << SendRequestId[j] + << ") : target " << target << " tag " << tag << " error " << error + << " flag " << flag << endl ; + } + else { + mpi_access.status( RecvRequestId[j], source, tag, error, outcount, + true ) ; + cout << "test" << myrank << " Test(Recv RequestId " + << RecvRequestId[j] << ") : source " << source << " tag " << tag + << " error " << error << " outcount " << outcount + << " flag " << flag << endl ; + if ( (outcount != 1) | (recvbuf[j] != j) ) { + ostringstream strstream ; + strstream << "===========================================================" + << endl << "test" << myrank << " outcount " + << outcount << " recvbuf " << recvbuf[j] << " KO" << endl + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + //else { + // cout << "===========================================================" + // << endl << "test" << myrank << " outcount " << outcount + // << " RequestId " << RecvRequestId[j] << " recvbuf " + // << recvbuf[j] << " OK" << endl + // << "===========================================================" + // << endl ; + //} + } + } + } + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + } + + mpi_access.check() ; + if ( myrank == 0 ) { + mpi_access.waitAll(maxreq, SendRequestId) ; + mpi_access.deleteRequests(maxreq, SendRequestId) ; + } + else { + mpi_access.waitAll(maxreq, RecvRequestId) ; + mpi_access.deleteRequests(maxreq, RecvRequestId) ; + } + mpi_access.check() ; + + if ( myrank == 0 ) { + int sendrequests[maxreq] ; + int sendreqsize = mpi_access.sendRequestIds( target , maxreq , sendrequests ) ; + int i ; + if ( sendreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + for ( i = 0 ; i < sendreqsize ; i++ ) { + cout << "test" << myrank << " sendrequests[ " << i << " ] = " + << sendrequests[i] << endl ; + } + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl + << "=========================================================" << endl ; + } + } + else { + int recvrequests[maxreq] ; + int recvreqsize = mpi_access.sendRequestIds( target , maxreq , recvrequests ) ; + if ( recvreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl + << "=========================================================" << endl ; + } + } + + mpi_access.barrier() ; + + delete group ; + + // MPI_Finalize(); + + cout << "test" << myrank << " OK" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/Test/test_MPI_Access_ISend_IRecv_BottleNeck.cxx b/src/ParaMEDMEM/Test/test_MPI_Access_ISend_IRecv_BottleNeck.cxx new file mode 100644 index 000000000..45cc5439f --- /dev/null +++ b/src/ParaMEDMEM/Test/test_MPI_Access_ISend_IRecv_BottleNeck.cxx @@ -0,0 +1,224 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <time.h> +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> + +#include "MPIAccessTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccess.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessTest::test_MPI_Access_ISend_IRecv_BottleNeck() { + + cout << "test_MPI_Access_ISend_IRecv_BottleNeck" << endl ; + +// MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 2 ) { + ostringstream strstream ; + strstream << "test_MPI_Access_ISend_IRecv_BottleNeck must be runned with 2 procs" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + cout << "test_MPI_Access_ISend_IRecv_BottleNeck" << myrank << endl ; + + ParaMEDMEM::CommInterface interface ; + + ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; + + ParaMEDMEM::MPIAccess mpi_access( group ) ; + +#define maxreq 10000 + + if ( myrank >= 2 ) { + mpi_access.barrier() ; + delete group ; + return ; + } + + int target = 1 - myrank ; + int SendRequestId[maxreq] ; + int RecvRequestId[maxreq] ; + int sts ; + int sendbuf[maxreq] ; + int recvbuf[maxreq] ; + int i ; + for ( i = 0 ; i < maxreq ; i++ ) { + if ( myrank == 0 ) { + sendbuf[i] = i ; + sts = mpi_access.ISend(sendbuf,i,MPI_INT,target, SendRequestId[i]) ; + cout << "test" << myrank << " ISend RequestId " << SendRequestId[i] + << " tag " << mpi_access.sendMPITag(target) << endl ; + } + else { + //sleep( 1 ) ; + sts = mpi_access.IRecv(recvbuf,i,MPI_INT,target, RecvRequestId[i]) ; + cout << "test" << myrank << " IRecv RequestId " << RecvRequestId[i] + << " tag " << mpi_access.recvMPITag(target) << endl ; + int recvreqsize = mpi_access.recvRequestIdsSize() ; + int * recvrequests = new int[ recvreqsize ] ; + recvreqsize = mpi_access.recvRequestIds( target , recvreqsize , recvrequests ) ; + int j ; + for (j = 0 ; j < recvreqsize ; j++) { + int flag ; + mpi_access.test( recvrequests[j], flag ) ; + if ( flag ) { + int source, tag, error, outcount ; + mpi_access.status( recvrequests[j], source, tag, error, outcount, + true ) ; + cout << "test" << myrank << " Test(Recv RequestId " + << recvrequests[j] << ") : source " << source << " tag " << tag + << " error " << error << " outcount " << outcount + << " flag " << flag << " : DeleteRequest" << endl ; + mpi_access.deleteRequest( recvrequests[j] ) ; + } + else { +// cout << "test" << myrank << " Test(Recv RequestId " +// << recvrequests[j] << ") flag " << flag << endl ; + } + } + delete [] recvrequests ; + } + if ( sts != MPI_SUCCESS ) { + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + } + + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + } + + mpi_access.check() ; + if ( myrank == 0 ) { + int size = mpi_access.sendRequestIdsSize() ; + cout << "test" << myrank << " before WaitAll sendreqsize " << size << endl ; + mpi_access.waitAll(maxreq, SendRequestId) ; + size = mpi_access.sendRequestIdsSize() ; + cout << "test" << myrank << " after WaitAll sendreqsize " << size << endl ; + int * ArrayOfSendRequests = new int[ size ] ; + int nSendRequest = mpi_access.sendRequestIds( size , ArrayOfSendRequests ) ; + int i ; + for ( i = 0 ; i < nSendRequest ; i++ ) { + mpi_access.deleteRequest( ArrayOfSendRequests[i] ) ; + } + delete [] ArrayOfSendRequests ; + } + else { + int size = mpi_access.recvRequestIdsSize() ; + cout << "test" << myrank << " before WaitAll recvreqsize " << size << endl ; + mpi_access.waitAll(maxreq, RecvRequestId) ; + size = mpi_access.recvRequestIdsSize() ; + cout << "test" << myrank << " after WaitAll recvreqsize " << size << endl ; + int * ArrayOfRecvRequests = new int[ size ] ; + int nRecvRequest = mpi_access.recvRequestIds( size , ArrayOfRecvRequests ) ; + int i ; + for ( i = 0 ; i < nRecvRequest ; i++ ) { + mpi_access.deleteRequest( ArrayOfRecvRequests[i] ) ; + } + delete [] ArrayOfRecvRequests ; + } + mpi_access.check() ; + + if ( myrank == 0 ) { + int sendrequests[maxreq] ; + int sendreqsize = mpi_access.sendRequestIds( target , maxreq , sendrequests ) ; + int i ; + if ( sendreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + for ( i = 0 ; i < sendreqsize ; i++ ) { + cout << "test" << myrank << " sendrequests[ " << i << " ] = " + << sendrequests[i] << endl ; + } + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl + << "=========================================================" << endl ; + } + } + else { + int recvrequests[maxreq] ; + int recvreqsize = mpi_access.recvRequestIds( target , maxreq , recvrequests ) ; + if ( recvreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl + << "=========================================================" << endl ; + } + } + + mpi_access.barrier() ; + + delete group ; + +// MPI_Finalize(); + + cout << "test" << myrank << " OK" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/Test/test_MPI_Access_ISend_IRecv_Length.cxx b/src/ParaMEDMEM/Test/test_MPI_Access_ISend_IRecv_Length.cxx new file mode 100644 index 000000000..c6dc2743d --- /dev/null +++ b/src/ParaMEDMEM/Test/test_MPI_Access_ISend_IRecv_Length.cxx @@ -0,0 +1,233 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> + +#include "MPIAccessTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccess.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessTest::test_MPI_Access_ISend_IRecv_Length() { + + cout << "test_MPI_Access_ISend_IRecv_Length" << endl ; + + // MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 2 ) { + ostringstream strstream ; + strstream << "test_MPI_Access_ISend_IRecv_Length must be runned with 2 procs" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + cout << "test_MPI_Access_ISend_IRecv_Length" << myrank << endl ; + + ParaMEDMEM::CommInterface interface ; + + ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; + + ParaMEDMEM::MPIAccess mpi_access( group ) ; + +#define maxreq 10 + + if ( myrank >= 2 ) { + mpi_access.barrier() ; + delete group ; + return ; + } + + int target = 1 - myrank ; + int SendRequestId[maxreq] ; + int RecvRequestId[maxreq] ; + int sts ; + int sendbuf[1000*(maxreq-1)] ; + int recvbuf[maxreq-1][1000*(maxreq-1)] ; + int i ; + for ( i = 0 ; i < 1000*(maxreq-1) ; i++ ) { + sendbuf[i] = i ; + } + for ( i = 0 ; i < maxreq ; i++ ) { + if ( myrank == 0 ) { + sts = mpi_access.ISend( sendbuf, 1000*i, MPI_INT, target, SendRequestId[i] ) ; + cout << "test" << myrank << " ISend RequestId " << SendRequestId[i] + << " tag " << mpi_access.sendMPITag(target) << endl ; + } + else { + sts = mpi_access.IRecv( recvbuf[i], 1000*i, MPI_INT, target, + RecvRequestId[i] ) ; + cout << "test" << myrank << " IRecv RequestId " << RecvRequestId[i] + << " tag " << mpi_access.recvMPITag(target) << endl ; + } + int j ; + for (j = 0 ; j <= i ; j++) { + int flag ; + if ( myrank == 0 ) { + mpi_access.test( SendRequestId[j], flag ) ; + } + else { + mpi_access.test( RecvRequestId[j], flag ) ; + } + if ( flag ) { + int target,source, tag, error, outcount ; + if ( myrank == 0 ) { + mpi_access.status( SendRequestId[j], target, tag, error, outcount, + true ) ; + cout << "test" << myrank << " Test(Send RequestId " << SendRequestId[j] + << ") : target " << target << " tag " << tag << " error " << error + << " flag " << flag << endl ; + } + else { + mpi_access.status( RecvRequestId[j], source, tag, error, outcount, + true ) ; + cout << "test" << myrank << " Test(Recv RequestId " + << RecvRequestId[j] << ") : source " << source << " tag " << tag + << " error " << error << " outcount " << outcount + << " flag " << flag << endl ; + if ( outcount != 0 ) { + if ( (outcount != 1000*j) | + (recvbuf[j][outcount-1] != (outcount-1)) ) { + ostringstream strstream ; + strstream << "===========================================================" + << endl << "test" << myrank << " outcount " + << outcount << " recvbuf " << recvbuf[j][outcount-1] << " KO" + << endl + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "===========================================================" + << endl << "test" << myrank << " outcount " << outcount + << " RequestId " << RecvRequestId[j] << " recvbuf " + << recvbuf[j][outcount-1] << " OK" << endl + << "===========================================================" + << endl ; + } + } + else { + cout << "===========================================================" + << endl << "test" << myrank << " outcount " << outcount + << " RequestId " << RecvRequestId[j] << " OK" << endl + << "===========================================================" + << endl ; + } + } + } + } + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + } + + mpi_access.check() ; + cout << "test" << myrank << " WaitAll" << endl ; + if ( myrank == 0 ) { + mpi_access.waitAll(maxreq, SendRequestId) ; + mpi_access.deleteRequests(maxreq, SendRequestId) ; + } + else { + mpi_access.waitAll(maxreq, RecvRequestId) ; + mpi_access.deleteRequests(maxreq, RecvRequestId) ; + } + mpi_access.check() ; + + if ( myrank == 0 ) { + int sendrequests[maxreq] ; + int sendreqsize = mpi_access.sendRequestIds( target , maxreq , sendrequests ) ; + sendreqsize = mpi_access.sendRequestIds( target , maxreq , sendrequests ) ; + if ( sendreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl + << "=========================================================" << endl ; + } + } + else { + int recvrequests[maxreq] ; + int recvreqsize = mpi_access.sendRequestIds( target , maxreq , recvrequests ) ; + if ( recvreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl + << "=========================================================" << endl ; + } + } + + mpi_access.barrier() ; + + delete group ; + + // MPI_Finalize(); + + cout << "test" << myrank << " OK" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/Test/test_MPI_Access_ISend_IRecv_Length_1.cxx b/src/ParaMEDMEM/Test/test_MPI_Access_ISend_IRecv_Length_1.cxx new file mode 100644 index 000000000..3d09f6d3c --- /dev/null +++ b/src/ParaMEDMEM/Test/test_MPI_Access_ISend_IRecv_Length_1.cxx @@ -0,0 +1,304 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> + +#include "MPIAccessTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccess.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessTest::test_MPI_Access_ISend_IRecv_Length_1() { + + // MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 2 ) { + ostringstream strstream ; + strstream << "test_MPI_Access_ISend_IRecv_Length_1 must be runned with 2 procs" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + cout << "test_MPI_Access_ISend_IRecv_Length_1" << myrank << endl ; + + ParaMEDMEM::CommInterface interface ; + + ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; + + ParaMEDMEM::MPIAccess mpi_access( group ) ; + +#define maxreq 10 + + if ( myrank >= 2 ) { + mpi_access.barrier() ; + delete group ; + return ; + } + + int target = 1 - myrank ; + int SendRequestId[maxreq] ; + int RecvRequestId[maxreq] ; + int sts ; + int sendbuf[1000*(maxreq-1)] ; + int recvbuf[maxreq-1][1000*(maxreq-1)] ; + int maxirecv = 1 ; + int i ; + RecvRequestId[0] = -1 ; + for ( i = 0 ; i < 1000*(maxreq-1) ; i++ ) { + sendbuf[i] = i ; + } + for ( i = 0 ; i < maxreq ; i++ ) { + sts = MPI_SUCCESS ; + if ( myrank == 0 ) { + sts = mpi_access.ISend( sendbuf, 1000*i, MPI_INT, target, SendRequestId[i] ) ; + cout << "test" << myrank << " ISend RequestId " << SendRequestId[i] + << " tag " << mpi_access.sendMPITag(target) << endl ; + } + int j ; + for (j = 1 ; j <= i ; j++) { + int source ; + MPI_Datatype datatype ; + int outcount ; + int flag ; + if ( myrank == 0 ) { + mpi_access.test( SendRequestId[j], flag ) ; + } + else { + int MPITag ; + sts = mpi_access.IProbe( target , source, MPITag, datatype, + outcount, flag) ; + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " IProbe lenerr " << lenerr << " " + << msgerr << endl ; + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " IProbe KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + cout << "test" << myrank << " IProbe i/j " << i << "/" << j + << " MPITag " << MPITag << " datatype " << datatype + << " outcount " << outcount << " flag " << flag << endl ; + } + if ( flag ) { + if ( myrank == 0 ) { + int target, tag, error, outcount ; + mpi_access.status( SendRequestId[j], target, tag, error, outcount, + true ) ; + cout << "test" << myrank << " Test(Send RequestId " << SendRequestId[j] + << ") : target " << target << " tag " << tag << " error " << error + << " flag " << flag << endl ; + } + else { + sts = mpi_access.IRecv( recvbuf[maxirecv], outcount, datatype, source, + RecvRequestId[maxirecv] ) ; + cout << "test" << myrank << " maxirecv " << maxirecv << " IRecv RequestId " + << RecvRequestId[maxirecv] << " source " << source + << " outcount " << outcount << " tag " + << mpi_access.recvMPITag(target) << endl ; + maxirecv = maxirecv + 1 ; + } + } + else if ( myrank == 1 && i == maxreq-1 && j >= maxirecv ) { + sts = mpi_access.IRecv( recvbuf[j], 1000*j, MPI_INT, target, + RecvRequestId[j] ) ; + cout << "test" << myrank << " maxirecv " << maxirecv << " IRecv RequestId " + << RecvRequestId[j] << " target " << target << " length " << 1000*j + << " tag " << mpi_access.recvMPITag(target) << endl ; + maxirecv = maxirecv + 1 ; + } + } + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "===========================================================" + << endl << "test" << myrank << " KO" << endl + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + } + + mpi_access.check() ; + int flag ; + if ( myrank == 0 ) { + mpi_access.testAll( maxreq, SendRequestId, flag ) ; + cout << "test" << myrank << " TestAll SendRequest flag " << flag << endl ; + } + else { + int i ; + int source ; + int outcount ; + int flag ; + if ( maxirecv != maxreq ) { + ostringstream strstream ; + strstream << "===========================================================" + << endl << "test" << myrank << " KO" << " maxirecv " << maxirecv + << " != maxreq " << maxreq << endl + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + while ( maxirecv > 0 ) { + for ( i = 1 ; i < maxreq ; i++ ) { + cout << "test" << myrank << " IProbe : " << endl ; + sts = mpi_access.test( RecvRequestId[i] , flag ) ; + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " flag " << flag << " lenerr " + << lenerr << " " << msgerr << " maxirecv " << maxirecv << endl ; + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + cout << "test" << myrank << " Test flag " << flag << endl ; + if ( flag ) { + int tag, error ; + mpi_access.status( RecvRequestId[i] , source , tag , error , + outcount ) ; + if ( i != 0 ) { + if ( outcount != 1000*i | + (recvbuf[i][outcount-1] != (outcount-1)) ) { + ostringstream strstream ; + strstream << "========================================================" + << endl << "test" << myrank << " outcount " << outcount + << " KO" << " i " << i + << " recvbuf " << recvbuf[i][outcount-1] << endl + << "========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + } + else if ( outcount != 0 ) { + ostringstream strstream ; + strstream << "========================================================" + << endl << "test" << myrank << " outcount " << outcount + << " KO" << " i " << i << endl + << "========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + maxirecv = maxirecv - 1 ; + } + } + } + mpi_access.testAll( maxreq, RecvRequestId, flag ) ; + cout << "test" << myrank << " TestAll RecvRequest flag " << flag << endl ; + } + mpi_access.check() ; + cout << "test" << myrank << " WaitAll :" << endl ; + if ( myrank == 0 ) { + mpi_access.waitAll( maxreq, SendRequestId ) ; + mpi_access.deleteRequests( maxreq, SendRequestId ) ; + } + else { + mpi_access.waitAll( maxreq, RecvRequestId ) ; + mpi_access.deleteRequests( maxreq, RecvRequestId ) ; + } + + if ( myrank == 0 ) { + int sendrequests[maxreq] ; + int sendreqsize = mpi_access.sendRequestIds( target , maxreq , sendrequests ) ; + sendreqsize = mpi_access.sendRequestIds( target , maxreq , sendrequests ) ; + if ( sendreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl + << "=========================================================" << endl ; + } + } + else { + int recvrequests[maxreq] ; + int recvreqsize = mpi_access.sendRequestIds( target , maxreq , recvrequests ) ; + if ( recvreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl + << "=========================================================" << endl ; + } + } + + mpi_access.barrier() ; + + delete group ; + + // MPI_Finalize(); + + cout << "test" << myrank << " OK" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/Test/test_MPI_Access_Probe.cxx b/src/ParaMEDMEM/Test/test_MPI_Access_Probe.cxx new file mode 100644 index 000000000..2bce97e12 --- /dev/null +++ b/src/ParaMEDMEM/Test/test_MPI_Access_Probe.cxx @@ -0,0 +1,143 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> + +#include "MPIAccessTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccess.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessTest::test_MPI_Access_Probe() { + + cout << "test_MPI_Access_Probe" << endl ; + +// MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 2 ) { + cout << "test_MPI_Access_Probe must be runned with 2 procs" << endl ; + CPPUNIT_FAIL("test_MPI_Access_Probe must be runned with 2 procs") ; + } + + cout << "test_MPI_Access_Probe" << myrank << endl ; + + ParaMEDMEM::CommInterface interface ; + + ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; + + ParaMEDMEM::MPIAccess mpi_access( group ) ; + + if ( myrank >= 2 ) { + mpi_access.barrier() ; + delete group ; + return ; + } + + int target = 1 - myrank ; + int RequestId[10] ; + int sts ; + int i ; + for ( i = 0 ; i < 10 ; i++ ) { + if ( myrank == 0 ) { + sts = mpi_access.send(&i,1,MPI_INT,target, RequestId[i]) ; + cout << "test" << myrank << " Send RequestId " << RequestId[i] + << endl ; + } + else { + int source, tag, outcount ; + MPI_Datatype datatype ; + sts = mpi_access.probe(target, source, tag, datatype, outcount ) ; + cout << "test" << myrank << " Probe target " << target << " source " << source + << " tag " << tag << " outcount " << outcount << endl ; + int recvbuf ; + sts = mpi_access.recv(&recvbuf,outcount,datatype,source, RequestId[i], + &outcount) ; + if ( (outcount != 1) | (recvbuf != i) ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " outcount " << outcount + << " recvbuf " << recvbuf << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + } + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + mpi_access.check() ; + } + int flag ; + mpi_access.testAll(10,RequestId,flag) ; + if ( !flag ) { + ostringstream strstream ; + strstream << "test" << myrank << " flag " << flag << " KO" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + mpi_access.waitAll(10,RequestId) ; + mpi_access.check() ; + + mpi_access.barrier() ; + + delete group ; + +// MPI_Finalize(); + + cout << "test" << myrank << " OK" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/Test/test_MPI_Access_SendRecv.cxx b/src/ParaMEDMEM/Test/test_MPI_Access_SendRecv.cxx new file mode 100644 index 000000000..a93fa4af8 --- /dev/null +++ b/src/ParaMEDMEM/Test/test_MPI_Access_SendRecv.cxx @@ -0,0 +1,179 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> + +#include "MPIAccessTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccess.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessTest::test_MPI_Access_SendRecv() { + + cout << "MPIAccessTest::test_MPI_Access_SendRecv" << endl ; + +// MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 2 ) { + cout << "MPIAccessTest::test_MPI_Access_SendRecv must be runned with 2 procs" << endl ; + CPPUNIT_FAIL("test_MPI_Access_SendRecv must be runned with 2 procs") ; + } + + cout << "MPIAccessTest::test_MPI_Access_SendRecv" << myrank << endl ; + + ParaMEDMEM::CommInterface interface ; + + ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; + + ParaMEDMEM::MPIAccess mpi_access( group ) ; + + if ( myrank >= 2 ) { + mpi_access.barrier() ; + delete group ; + return ; + } + + int target = 1 - myrank ; + int sendRequestId[10] ; + int recvRequestId[10] ; + int sts ; + int i ; + for ( i = 0 ; i < 10 ; i++ ) { + int recvbuf ; + int outcount ; + if ( i & 1 ) { + outcount = -1 ; + sts = mpi_access.sendRecv(&i,1,MPI_INT,target, sendRequestId[i], + &recvbuf,1,MPI_INT,target, recvRequestId[i], + &outcount) ; + } + else { + sts = mpi_access.sendRecv(&i,1,MPI_INT,target, sendRequestId[i], + &recvbuf,1,MPI_INT,target, recvRequestId[i]) ; +// outcount = mpi_access.MPIOutCount( recvRequestId[i] ) ; + outcount = 1 ; + } + cout << "test" << myrank << " Send sendRequestId " << sendRequestId[i] + << " tag " << mpi_access.sendMPITag(target) + << " recvRequestId " << recvRequestId[i] + << " tag " << mpi_access.recvMPITag(target) + << " outcount " << outcount << " MPIOutCount " + << mpi_access.MPIOutCount( recvRequestId[i] ) << endl ; + if ( (outcount != 1) | (recvbuf != i) ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " outcount " << outcount + << " recvbuf " << recvbuf << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + mpi_access.check() ; + } + + int flag ; + mpi_access.testAll(10,sendRequestId,flag) ; + if ( !flag ) { + ostringstream strstream ; + strstream << "test" << myrank << " flag " << flag << " KO" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + mpi_access.waitAll(10,sendRequestId) ; + mpi_access.testAll(10,recvRequestId,flag) ; + if ( !flag ) { + ostringstream strstream ; + strstream << "test" << myrank << " flag " << flag << " KO" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + mpi_access.waitAll(10,recvRequestId) ; + mpi_access.check() ; + + int sendrequests[10] ; + int sendreqsize = mpi_access.sendRequestIds( target , 10 , sendrequests ) ; + if ( sendreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + int recvrequests[10] ; + int recvreqsize = mpi_access.sendRequestIds( target , 10 , recvrequests ) ; + if ( recvreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + mpi_access.barrier() ; + + delete group ; + +// MPI_Finalize(); + + cout << "test" << myrank << " OK" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/Test/test_MPI_Access_Send_Recv.cxx b/src/ParaMEDMEM/Test/test_MPI_Access_Send_Recv.cxx new file mode 100644 index 000000000..f7e556a97 --- /dev/null +++ b/src/ParaMEDMEM/Test/test_MPI_Access_Send_Recv.cxx @@ -0,0 +1,165 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> + +#include "MPIAccessTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccess.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessTest::test_MPI_Access_Send_Recv() { + + cout << "test_MPI_Access_Send_Recv" << endl ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 2 ) { + cout << "test_MPI_Access_Send_Recv must be runned with 2 procs" << endl ; + CPPUNIT_FAIL("test_MPI_Access_Send_Recv must be runned with 2 procs") ; + } + + cout << "test_MPI_Access_Send_Recv" << myrank << endl ; + + ParaMEDMEM::CommInterface interface ; + + ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; + + ParaMEDMEM::MPIAccess mpi_access( group ) ; + + if ( myrank >= 2 ) { + mpi_access.barrier() ; + delete group ; + return ; + } + + int target = 1 - myrank ; + int RequestId[10] ; + int sts ; + int i ; + for ( i = 0 ; i < 10 ; i++ ) { + if ( myrank == 0 ) { + sts = mpi_access.send(&i,1,MPI_INT,target, RequestId[i]) ; + cout << "test" << myrank << " Send RequestId " << RequestId[i] + << " tag " << mpi_access.sendMPITag(target) << endl ; + } + else { + int recvbuf ; + int outcount ; + sts = mpi_access.recv(&recvbuf,1,MPI_INT,target, RequestId[i],&outcount) ; + //int source, tag, error, outcount ; + //mpi_access.Status( RequestId[i], source, tag, error, outcount, true) ; + cout << "test" << myrank << " Recv RequestId " << RequestId[i] + << " tag " << mpi_access.recvMPITag(target) + << " outcount " << outcount << endl ; + if ( (outcount != 1) | (recvbuf != i) ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " outcount " << outcount + << " recvbuf " << recvbuf << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + } + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " KO" + << "===========================================================" + << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + mpi_access.check() ; + } + int flag ; + mpi_access.testAll(10,RequestId,flag) ; + if ( !flag ) { + ostringstream strstream ; + strstream << "test" << myrank << " flag " << flag << " KO" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + mpi_access.waitAll(10,RequestId) ; + mpi_access.check() ; + + if ( myrank == 0 ) { + int sendrequests[10] ; + int sendreqsize = mpi_access.sendRequestIds( target , 10 , sendrequests ) ; + if ( sendreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + } + else { + int recvrequests[10] ; + int recvreqsize = mpi_access.sendRequestIds( target , 10 , recvrequests ) ; + if ( recvreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + } + + mpi_access.barrier() ; + + delete group ; + +// MPI_Finalize(); + + cout << "test" << myrank << " OK" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/Test/test_MPI_Access_Send_Recv_Length.cxx b/src/ParaMEDMEM/Test/test_MPI_Access_Send_Recv_Length.cxx new file mode 100644 index 000000000..fc55f26f6 --- /dev/null +++ b/src/ParaMEDMEM/Test/test_MPI_Access_Send_Recv_Length.cxx @@ -0,0 +1,189 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> + +#include "MPIAccessTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccess.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessTest::test_MPI_Access_Send_Recv_Length() { + + cout << "test_MPI_Access_Send_Recv_Length" << endl ; + +// MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 2 ) { + ostringstream strstream ; + strstream << "test_MPI_Access_Send_Recv_Length must be runned with 2 procs" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + cout << "test_MPI_Access_Send_Recv_Length" << myrank << endl ; + + ParaMEDMEM::CommInterface interface ; + + ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; + + ParaMEDMEM::MPIAccess mpi_access( group ) ; + + if ( myrank >= 2 ) { + mpi_access.barrier() ; + delete group ; + return ; + } + + int target = 1 - myrank ; + int RequestId[10] ; + int sendbuf[9000] ; + int recvbuf[9000] ; + bool recvbufok ; + int sts ; + int i , j ; + for ( i = 0 ; i < 9000 ; i++ ) { + sendbuf[i] = i ; + } + for ( i = 0 ; i < 10 ; i++ ) { + if ( myrank == 0 ) { + sts = mpi_access.send( sendbuf, 1000*i, MPI_INT, target, RequestId[i] ) ; + cout << "test" << myrank << " Send RequestId " << RequestId[i] + << " tag " << mpi_access.sendMPITag(target) << endl ; + } + else { + sts = MPI_SUCCESS ; + RequestId[i] = -1 ; + int outcount = 0 ; + if ( i != 0 ) { + sts = mpi_access.recv( recvbuf,1000*i+1,MPI_INT,target, RequestId[i], + &outcount ) ; + } + //int source, tag, error, outcount ; + //mpi_access.Status( RequestId[i], source, tag, error, outcount, true) ; + cout << "test" << myrank << " Recv RequestId " << RequestId[i] + << " tag " << mpi_access.recvMPITag(target) + << " outcount " << outcount << endl ; + recvbufok = true ; + for ( j = 0 ; j < outcount ; j++ ) { + if ( recvbuf[j] != j ) { + cout << "test" << myrank << " recvbuf[ " << j << " ] = " << recvbuf[j] + << endl ; + recvbufok = false ; + break ; + } + } + if ( (outcount != 1000*i) | !recvbufok ) { + ostringstream strstream ; + strstream << "===========================================================" + << endl << "test" << myrank << " outcount " << outcount + << " recvbuf " << recvbuf << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + } + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + mpi_access.check() ; + } + int flag ; + mpi_access.testAll(10,RequestId,flag) ; + if ( !flag ) { + ostringstream strstream ; + strstream << "test" << myrank << " flag " << flag << " KO" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + mpi_access.waitAll(10,RequestId) ; + mpi_access.check() ; + + if ( myrank == 0 ) { + int sendrequests[10] ; + int sendreqsize = mpi_access.sendRequestIds( target , 10 , sendrequests ) ; + if ( sendreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + } + else { + int recvrequests[10] ; + int recvreqsize = mpi_access.sendRequestIds( target , 10 , recvrequests ) ; + if ( recvreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + } + + mpi_access.barrier() ; + + delete group ; + +// MPI_Finalize(); + + cout << "test" << myrank << " OK" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/Test/test_MPI_Access_Time.cxx b/src/ParaMEDMEM/Test/test_MPI_Access_Time.cxx new file mode 100644 index 000000000..1a8eb185b --- /dev/null +++ b/src/ParaMEDMEM/Test/test_MPI_Access_Time.cxx @@ -0,0 +1,289 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> + +#include "MPIAccessTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccess.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void MPIAccessTest::test_MPI_Access_Time() { + + cout << "test_MPI_Access_Time" << endl ; + + // MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 2 ) { + ostringstream strstream ; + strstream << "test_MPI_Access_Time must be runned with 2 procs" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + + cout << "test_MPI_Access_Time" << myrank << endl ; + + ParaMEDMEM::CommInterface interface ; + + ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; + + ParaMEDMEM::MPIAccess mpi_access( group ) ; + +#define maxreq 10 + + if ( myrank >= 2 ) { + cout << "test_MPI_Access_Time_0 rank" << myrank << " --> mpi_access->Barrier" << endl ; + mpi_access.barrier() ; + cout << "test_MPI_Access_Time_0 rank" << myrank << " <-- mpi_access->Barrier" << endl ; + delete group ; + cout << "test_MPI_Access_Time" << myrank << " OK" << endl ; + return ; + } + + int target = 1 - myrank ; + int SendTimeRequestId[maxreq] ; + int RecvTimeRequestId[maxreq] ; + int SendRequestId[maxreq] ; + int RecvRequestId[maxreq] ; + int sts ; + int sendbuf[maxreq] ; + int recvbuf[maxreq] ; + int i = 0 ; + ParaMEDMEM::TimeMessage aSendTimeMsg[maxreq] ; + ParaMEDMEM::TimeMessage aRecvTimeMsg[maxreq] ; + double t ; + double dt = 1. ; + double maxt = 10. ; + for ( t = 0 ; t < maxt ; t = t+dt ) { + if ( myrank == 0 ) { + aSendTimeMsg[i].time = t ; + aSendTimeMsg[i].deltatime = dt ; + //aSendTimeMsg[i].maxtime = maxt ; + //sts = mpi_access.ISend( &aSendTimeMsg , mpi_access.timeExtent() , + sts = mpi_access.ISend( &aSendTimeMsg[i] , 1 , + mpi_access.timeType() , target , + SendTimeRequestId[i]) ; + cout << "test" << myrank << " ISend RequestId " << SendTimeRequestId[i] + << " tag " << mpi_access.sendMPITag(target) << endl ; + sendbuf[i] = i ; + sts = mpi_access.ISend(&sendbuf[i],1,MPI_INT,target, SendRequestId[i]) ; + cout << "test" << myrank << " ISend RequestId " << SendRequestId[i] + << " tag " << mpi_access.sendMPITag(target) << endl ; + } + else { + //sts = mpi_access.IRecv( &aRecvTimeMsg , mpi_access.timeExtent() , + sts = mpi_access.IRecv( &aRecvTimeMsg[i] , 1 , + mpi_access.timeType() , target , + RecvTimeRequestId[i]) ; + cout << "test" << myrank << " IRecv RequestId " << RecvTimeRequestId[i] + << " tag " << mpi_access.recvMPITag(target) << endl ; + sts = mpi_access.IRecv(&recvbuf[i],1,MPI_INT,target, RecvRequestId[i]) ; + cout << "test" << myrank << " IRecv RequestId " << RecvRequestId[i] + << " tag " << mpi_access.recvMPITag(target) << endl ; + } + int j ; + for (j = 0 ; j <= i ; j++) { + int flag ; + if ( myrank == 0 ) { + mpi_access.test( SendTimeRequestId[j], flag ) ; + } + else { + mpi_access.test( RecvTimeRequestId[j], flag ) ; + } + if ( flag ) { + int target,source, tag, error, outcount ; + if ( myrank == 0 ) { + mpi_access.status( SendTimeRequestId[j], target, tag, error, outcount, + true ) ; + cout << "test" << myrank << " Test(Send TimeRequestId " << SendTimeRequestId[j] + << ") : target " << target << " tag " << tag << " error " << error + << " flag " << flag << aSendTimeMsg[j] << endl ; + } + else { + mpi_access.status( RecvTimeRequestId[j], source, tag, error, outcount, + true ) ; + cout << "test" << myrank << " Test(Recv TimeRequestId " + << RecvTimeRequestId[j] << ") : source " << source << " tag " << tag + << " error " << error << " outcount " << outcount + << " flag " << flag << aRecvTimeMsg[j] << endl ; + if ( (outcount != 1) | (aRecvTimeMsg[j].time != j) ) { + ostringstream strstream ; + strstream << "===========================================================" + << endl << "test" << myrank << " outcount " << outcount << " KO" + << " RecvTimeRequestId " << RecvTimeRequestId[j] << endl + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "===========================================================" + << endl << "test" << myrank << " outcount " << outcount + << " RecvTimeRequestId " << RecvTimeRequestId[j] << " OK" << endl + << "===========================================================" + << endl ; + } + } + } + if ( myrank == 0 ) { + mpi_access.test( SendRequestId[j], flag ) ; + } + else { + mpi_access.test( RecvRequestId[j], flag ) ; + } + if ( flag ) { + int target,source, tag, error, outcount ; + if ( myrank == 0 ) { + mpi_access.status( SendRequestId[j], target, tag, error, outcount, + true ) ; + cout << "test" << myrank << " Test(Send RequestId " << SendRequestId[j] + << ") : target " << target << " tag " << tag << " error " << error + << " flag " << flag << endl ; + } + else { + mpi_access.status( RecvRequestId[j], source, tag, error, outcount, + true ) ; + cout << "test" << myrank << " Test(Recv RequestId " + << RecvRequestId[j] << ") : source " << source << " tag " << tag + << " error " << error << " outcount " << outcount + << " flag " << flag << endl ; + if ( (outcount != 1) | (recvbuf[j] != j) ) { + ostringstream strstream ; + strstream << "===========================================================" + << endl << "test" << myrank << " outcount " + << outcount << " recvbuf " << recvbuf[j] << " KO" << endl + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "===========================================================" + << endl << "test" << myrank << " outcount " << outcount + << " RequestId " << RecvRequestId[j] << " OK" << endl + << "===========================================================" + << endl ; + } + } + } + } + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + mpi_access.errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + + if ( sts != MPI_SUCCESS ) { + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + i = i + 1 ; + } + + mpi_access.check() ; + if ( myrank == 0 ) { + mpi_access.waitAll(maxreq, SendTimeRequestId) ; + mpi_access.deleteRequests(maxreq, SendTimeRequestId) ; + mpi_access.waitAll(maxreq, SendRequestId) ; + mpi_access.deleteRequests(maxreq, SendRequestId) ; + } + else { + mpi_access.waitAll(maxreq, RecvTimeRequestId) ; + mpi_access.deleteRequests(maxreq, RecvTimeRequestId) ; + mpi_access.waitAll(maxreq, RecvRequestId) ; + mpi_access.deleteRequests(maxreq, RecvRequestId) ; + } + mpi_access.check() ; + + if ( myrank == 0 ) { + int sendrequests[2*maxreq] ; + int sendreqsize = mpi_access.sendRequestIds( target , 2*maxreq , sendrequests ) ; + if ( sendreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl + << "=========================================================" << endl ; + } + } + else { + int recvrequests[2*maxreq] ; + int recvreqsize = mpi_access.sendRequestIds( target , 2*maxreq , recvrequests ) ; + if ( recvreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl + << "=========================================================" << endl ; + } + } + + cout << "test_MPI_Access_Time_0 rank" << myrank << " --> mpi_access->Barrier" << endl ; + mpi_access.barrier() ; + cout << "test_MPI_Access_Time_0 rank" << myrank << " <-- mpi_access->Barrier" << endl ; + + delete group ; + + // MPI_Finalize(); + + cout << "test_MPI_Access_Time" << myrank << " OK" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/Test/test_MPI_Access_Time_0.cxx b/src/ParaMEDMEM/Test/test_MPI_Access_Time_0.cxx new file mode 100644 index 000000000..3da138565 --- /dev/null +++ b/src/ParaMEDMEM/Test/test_MPI_Access_Time_0.cxx @@ -0,0 +1,470 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include <string> +#include <vector> +#include <map> +#include <iostream> +#include <mpi.h> + +#include "MPIAccessTest.hxx" +#include <cppunit/TestAssert.h> + +//#include "CommInterface.hxx" +//#include "ProcessorGroup.hxx" +//#include "MPIProcessorGroup.hxx" +#include "MPIAccess.hxx" + +// use this define to enable lines, execution of which leads to Segmentation Fault +#define ENABLE_FAULTS + +// use this define to enable CPPUNIT asserts and fails, showing bugs +#define ENABLE_FORCED_FAILURES + +using namespace std; +using namespace ParaMEDMEM; + +void chksts( int sts , int myrank , ParaMEDMEM::MPIAccess * mpi_access ) { + char msgerr[MPI_MAX_ERROR_STRING] ; + int lenerr ; + if ( sts != MPI_SUCCESS ) { + mpi_access->errorString(sts, msgerr, &lenerr) ; + cout << "test" << myrank << " lenerr " << lenerr << " " + << msgerr << endl ; + ostringstream strstream ; + strstream << "===========================================================" + << "test" << myrank << " KO" + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } +return ; +} + +void MPIAccessTest::test_MPI_Access_Time_0() { + + cout << "test_MPI_Access_Time_0" << endl ; + +// MPI_Init(&argc, &argv) ; + + int size ; + int myrank ; + MPI_Comm_size(MPI_COMM_WORLD,&size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ; + + if ( size < 2 ) { + ostringstream strstream ; + strstream << "usage :" << endl + << "mpirun -np <nbprocs> test_MPI_Access_Time_0" <<endl + << " nbprocs =2" << endl + << "test must be runned with 2 procs" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + +#define maxreq 100 + + double t ; + double dt[2] = {2., 1.} ; + double maxt = maxreq/dt[myrank] ; + + cout << "test_MPI_Access_Time_0 rank" << myrank << endl ; + + ParaMEDMEM::CommInterface interface ; + + ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ; + + ParaMEDMEM::MPIAccess * mpi_access = new ParaMEDMEM::MPIAccess( group ) ; + + if ( myrank >= 2 ) { + cout << "test_MPI_Access_Time_0 rank" << myrank << " --> mpi_access->barrier" << endl ; + mpi_access->barrier() ; + cout << "test_MPI_Access_Time_0 rank" << myrank << " <-- mpi_access->barrier" << endl ; + cout << "test_MPI_Access_Time_0 rank" << myrank << " --> mpi_access->barrier" << endl ; + mpi_access->barrier() ; + cout << "test_MPI_Access_Time_0 rank" << myrank << " <-- mpi_access->barrier" << endl ; + delete group ; + delete mpi_access ; + cout << "test_MPI_Access_Time" << myrank << " OK" << endl ; + return ; + } + + int target = 1 - myrank ; + int SendTimeRequestId[maxreq] ; + int RecvTimeRequestId[maxreq] ; + int SendRequestId[maxreq] ; + int RecvRequestId[maxreq] ; + int sts ; + int sendbuf[maxreq] ; + int recvbuf[maxreq] ; + ParaMEDMEM::TimeMessage aSendTimeMsg[maxreq] ; + int lasttime = -1 ; + ParaMEDMEM::TimeMessage RecvTimeMessages[maxreq+1] ; + ParaMEDMEM::TimeMessage *aRecvTimeMsg = &RecvTimeMessages[1] ; +// mpi_access->Trace() ; + int istep = 0 ; + for ( t = 0 ; t < maxt ; t = t+dt[myrank] ) { + cout << "test" << myrank << " ==========================TIME " << t + << " ==========================" << endl ; + if ( myrank == 0 ) { + aSendTimeMsg[istep].time = t ; + aSendTimeMsg[istep].deltatime = dt[myrank] ; + //aSendTimeMsg[istep].maxtime = maxt ; + if ( t+dt[myrank] >= maxt ) { + aSendTimeMsg[istep].deltatime = 0 ; + } + sts = mpi_access->ISend( &aSendTimeMsg[istep] , 1 , + mpi_access->timeType() , target , + SendTimeRequestId[istep]) ; + cout << "test" << myrank << " ISend TimeRequestId " << SendTimeRequestId[istep] + << " tag " << mpi_access->MPITag(SendTimeRequestId[istep]) << endl ; + chksts( sts , myrank , mpi_access ) ; + sendbuf[istep] = istep ; + sts = mpi_access->ISend(&sendbuf[istep],1,MPI_INT,target, SendRequestId[istep]) ; + cout << "test" << myrank << " ISend Data RequestId " << SendRequestId[istep] + << " tag " << mpi_access->MPITag(SendRequestId[istep]) << endl ; + chksts( sts , myrank , mpi_access ) ; +//CheckSent +//========= + int sendrequests[2*maxreq] ; + int sendreqsize = mpi_access->sendRequestIds( target , 2*maxreq , + sendrequests ) ; + int j , flag ; + for ( j = 0 ; j < sendreqsize ; j++ ) { + sts = mpi_access->test( sendrequests[j] , flag ) ; + chksts( sts , myrank , mpi_access ) ; + if ( flag ) { + mpi_access->deleteRequest( sendrequests[j] ) ; + cout << "test" << myrank << " " << j << ". " << sendrequests[j] + << " sendrequest deleted" << endl ; + } + } + } + else { +//InitRecv +//======== + if ( t == 0 ) { + aRecvTimeMsg[lasttime].time = 0 ; + sts = mpi_access->IRecv( &aRecvTimeMsg[lasttime+1] , 1 , + mpi_access->timeType() , + target , RecvTimeRequestId[lasttime+1]) ; + cout << "test" << myrank << " t == 0 IRecv TimeRequestId " + << RecvTimeRequestId[lasttime+1] + << " MPITag " << mpi_access->MPITag( RecvTimeRequestId[lasttime+1] ) + << " MPICompleted " + << mpi_access->MPICompleted( RecvTimeRequestId[lasttime+1] ) << endl ; + chksts( sts , myrank , mpi_access ) ; + } + else { + cout << "test" << myrank << " t # 0 lasttime " << lasttime << endl ; +//InitialOutTime +//============== + bool outtime = false ; + if ( lasttime != -1 ) { + if ( t <= aRecvTimeMsg[lasttime-1].time ) { + ostringstream strstream ; + strstream << "===========================================================" + << endl << "test" << myrank << " t " << t << " <= " + << "aRecvTimeMsg[ " << lasttime << "-1 ].time " + << aRecvTimeMsg[lasttime-1].time << " KO" << endl + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "===========================================================" + << endl << "test" << myrank << " t " << t << " > " + << "aRecvTimeMsg[ " << lasttime << "-1 ].time " + << aRecvTimeMsg[lasttime-1].time << " OK" << endl + << "===========================================================" + << endl ; + } + //outtime = ((aRecvTimeMsg[lasttime].time + + // aRecvTimeMsg[lasttime].deltatime) >= + // aRecvTimeMsg[lasttime].maxtime) ; + outtime = aRecvTimeMsg[lasttime].deltatime == 0 ; + } +// CheckRecv - CheckTime +// On a lasttime tel que : +// aRecvTimeMsg[ lasttime-1 ].time < T(i-1) <= aRecvTimeMsg[ lasttime ].time +// On cherche lasttime tel que : +// aRecvTimeMsg[ lasttime-1 ].time < T(i) <= aRecvTimeMsg[ lasttime ].time + if ( t <= aRecvTimeMsg[lasttime].time ) { + outtime = false ; + } + cout << "test" << myrank << " while outtime( " << outtime << " && t " << t + << " > aRecvTimeMsg[ " << lasttime << " ] " + << aRecvTimeMsg[lasttime].time << " )" << endl ; + while ( !outtime && (t > aRecvTimeMsg[lasttime].time) ) { + lasttime += 1 ; +//TimeMessage +//=========== + sts = mpi_access->wait( RecvTimeRequestId[lasttime] ) ; + chksts( sts , myrank , mpi_access ) ; + cout << "test" << myrank << " Wait done RecvTimeRequestId " + << RecvTimeRequestId[lasttime] << " lasttime " << lasttime + << " tag " << mpi_access->MPITag(RecvTimeRequestId[lasttime]) + << aRecvTimeMsg[lasttime] << endl ; + if ( lasttime == 0 ) { + aRecvTimeMsg[lasttime-1] = aRecvTimeMsg[lasttime] ; + } + mpi_access->deleteRequest( RecvTimeRequestId[lasttime] ) ; + + double deltatime = aRecvTimeMsg[lasttime].deltatime ; + //double maxtime = aRecvTimeMsg[lasttime].maxtime ; + double nexttime = aRecvTimeMsg[lasttime].time + deltatime ; + cout << "test" << myrank << " t " << t << " lasttime " << lasttime + << " deltatime " << deltatime + << " nexttime " << nexttime << endl ; + //if ( nexttime < maxtime && t > nexttime ) { + if ( deltatime != 0 && t > nexttime ) { +//CheckRecv : +//========= + //while ( nexttime < maxtime && t > nexttime ) { + while ( deltatime != 0 && t > nexttime ) { + int source, MPITag, outcount ; + MPI_Datatype datatype ; + sts = mpi_access->probe( target , source, MPITag, datatype, + outcount ) ; + chksts( sts , myrank , mpi_access ) ; +// Cancel DataMessages jusqu'a un TimeMessage + int cancelflag ; + while ( !mpi_access->isTimeMessage( MPITag ) ) { + sts = mpi_access->cancel( source, MPITag, datatype, outcount , + //sts = mpi_access->cancel( source, datatype, outcount , + //RecvRequestId[lasttime] , + cancelflag ) ; + cout << "test" << myrank << " Recv TO CANCEL RequestId " + << RecvRequestId[lasttime] + << " tag " << mpi_access->recvMPITag( target ) + << " cancelflag " << cancelflag << endl ; + chksts( sts , myrank , mpi_access ) ; + sts = mpi_access->probe( target , source, MPITag, datatype, + outcount ) ; + chksts( sts , myrank , mpi_access ) ; + } +//On peut avancer en temps + nexttime += deltatime ; + //if ( nexttime < maxtime && t > nexttime ) { + if ( deltatime != 0 && t > nexttime ) { +// Cancel du TimeMessage + sts = mpi_access->cancel( source, MPITag, datatype, outcount , + //sts = mpi_access->cancel( source, datatype, outcount , + //RecvRequestId[lasttime] , + cancelflag ) ; + cout << "test" << myrank << " Time TO CANCEL RequestId " + << RecvRequestId[lasttime] + << " tag " << mpi_access->recvMPITag( target ) + << " cancelflag " << cancelflag << endl ; + chksts( sts , myrank , mpi_access ) ; + } + } + } + else { +//DoRecv +//====== + cout << "test" << myrank << " Recv target " << target + << " lasttime " << lasttime + << " lasttime-1 " << aRecvTimeMsg[lasttime-1] + << " lasttime " << aRecvTimeMsg[lasttime] + << endl ; + sts = mpi_access->recv(&recvbuf[lasttime],1,MPI_INT,target, + RecvRequestId[lasttime]) ; + cout << "test" << myrank << " Recv RequestId " + << RecvRequestId[lasttime] + << " tag " << mpi_access->recvMPITag( target ) + << endl ; + chksts( sts , myrank , mpi_access ) ; + } + //outtime = ((aRecvTimeMsg[lasttime].time + + // aRecvTimeMsg[lasttime].deltatime) >= + // aRecvTimeMsg[lasttime].maxtime) ; + outtime = aRecvTimeMsg[lasttime].deltatime == 0 ; + if ( !outtime ) { +// Une lecture asynchrone d'un message temps a l'avance + sts = mpi_access->IRecv( &aRecvTimeMsg[lasttime+1] , 1 , + mpi_access->timeType() , target , + RecvTimeRequestId[lasttime+1]) ; + cout << "test" << myrank << " IRecv TimeRequestId " + << RecvTimeRequestId[lasttime+1] << " MPITag " + << mpi_access->MPITag( RecvTimeRequestId[lasttime+1] ) + << " MPICompleted " + << mpi_access->MPICompleted( RecvTimeRequestId[lasttime+1] ) + << endl ; + chksts( sts , myrank , mpi_access ) ; + } + else if ( t <= aRecvTimeMsg[lasttime].time ) { + outtime = false ; + } + } + + //printf("DEBUG t %.15f Msg[lasttime-1] %.15f Msg[lasttime] %.15f \n",t, + // aRecvTimeMsg[lasttime-1].time,aRecvTimeMsg[lasttime].time) ; + if ( ((t <= aRecvTimeMsg[lasttime-1].time) || + (t > aRecvTimeMsg[lasttime].time)) && !outtime ) { + ostringstream strstream ; + strstream << "===========================================================" + << endl << "test" << myrank << " t " << t << " <= " + << "aRecvTimeMsg[ " << lasttime << "-1 ].time " + << aRecvTimeMsg[lasttime-1].time << " ou t " << t << " > " + << "aRecvTimeMsg[ " << lasttime << " ].time " + << aRecvTimeMsg[lasttime].time << endl + << " ou bien outtime " << outtime << " KO RequestTimeIds " + << RecvTimeRequestId[lasttime-1] << " " << RecvTimeRequestId[lasttime] + << " RequestIds " + << RecvRequestId[lasttime-1] << " " << RecvRequestId[lasttime] << endl + << "===========================================================" + << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "===========================================================" + << endl << "test" << myrank + << " aRecvTimeMsg[ " << lasttime << "-1 ].time " + << aRecvTimeMsg[lasttime-1].time << " < t " << t << " <= " + << "aRecvTimeMsg[ " << lasttime << " ].time " + << aRecvTimeMsg[lasttime].time << endl + << " ou bien outtime " << outtime << " OK RequestTimeIds " + << RecvTimeRequestId[lasttime-1] << " " << RecvTimeRequestId[lasttime] + << " RequestIds " + << RecvRequestId[lasttime-1] << " " << RecvRequestId[lasttime] << endl + << "===========================================================" + << endl ; + } + } + } + chksts( sts , myrank , mpi_access ) ; + istep = istep + 1 ; + } + + cout << "test" << myrank << " Barrier :" << endl ; + mpi_access->barrier() ; + + mpi_access->check() ; + + if ( myrank == 0 ) { +//CheckFinalSent +//============== + cout << "test" << myrank << " CheckFinalSent :" << endl ; + int sendrequests[2*maxreq] ; + int sendreqsize = mpi_access->sendRequestIds( target , 2*maxreq , sendrequests ) ; + int j ; + for ( j = 0 ; j < sendreqsize ; j++ ) { + sts = mpi_access->wait( sendrequests[j] ) ; + chksts( sts , myrank , mpi_access ) ; + mpi_access->deleteRequest( sendrequests[j] ) ; + cout << "test" << myrank << " " << j << ". " << sendrequests[j] << " deleted" + << endl ; + } + } + else { + cout << "test" << myrank << " CheckFinalRecv :" << endl ; + int recvrequests[2*maxreq] ; + int recvreqsize = mpi_access->recvRequestIds( target , 2*maxreq , recvrequests ) ; + int cancelflag ; + int j ; + for ( j = 0 ; j < recvreqsize ; j++ ) { + sts = mpi_access->cancel( recvrequests[j] , cancelflag ) ; + chksts( sts , myrank , mpi_access ) ; + mpi_access->deleteRequest( recvrequests[j] ) ; + cout << "test" << myrank << " " << j << ". " << recvrequests[j] << " deleted" + << " cancelflag " << cancelflag << endl ; + } + int source, MPITag, outcount , flag ; + MPI_Datatype datatype ; + sts = mpi_access->IProbe( target , source, MPITag, datatype, + outcount , flag ) ; + chksts( sts , myrank , mpi_access ) ; + while ( flag ) { + sts = mpi_access->cancel( source, MPITag, datatype, outcount , + //sts = mpi_access->cancel( source, datatype, outcount , + //RecvRequestId[lasttime] , + cancelflag ) ; + cout << "test" << myrank << " TO CANCEL RequestId " + << RecvRequestId[lasttime] + << " tag " << mpi_access->recvMPITag( target ) + << " cancelflag " << cancelflag << endl ; + chksts( sts , myrank , mpi_access ) ; + sts = mpi_access->IProbe( target , source, MPITag, datatype, + outcount , flag ) ; + chksts( sts , myrank , mpi_access ) ; + } + } + mpi_access->check() ; + + if ( myrank == 0 ) { + int sendrequests[2*maxreq] ; + int sendreqsize = mpi_access->sendRequestIds( target , 2*maxreq , sendrequests ) ; + if ( sendreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "=========================================================" << endl + << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl + << "=========================================================" << endl ; + } + } + else { + int recvrequests[2*maxreq] ; + int recvreqsize = mpi_access->recvRequestIds( target , 2*maxreq , recvrequests ) ; + if ( recvreqsize != 0 ) { + ostringstream strstream ; + strstream << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl + << "=========================================================" << endl ; + cout << strstream.str() << endl ; + CPPUNIT_FAIL( strstream.str() ) ; + } + else { + cout << "=========================================================" << endl + << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl + << "=========================================================" << endl ; + } + } + + int i ; + for ( i = 0 ; i <= lasttime ; i++ ) { + cout << "test" << myrank << " " << i << ". RecvTimeMsg " + << aRecvTimeMsg[i].time << " recvbuf " << recvbuf[i] << endl ; + } + + cout << "test_MPI_Access_Time_0 rank" << myrank << " --> mpi_access->barrier" << endl ; + mpi_access->barrier() ; + cout << "test_MPI_Access_Time_0 rank" << myrank << " <-- mpi_access->barrier" << endl ; + + delete group ; + delete mpi_access ; + +// MPI_Finalize(); + + cout << "test" << myrank << " OK" << endl ; + + return ; +} + + + + diff --git a/src/ParaMEDMEM/TimeInterpolator.cxx b/src/ParaMEDMEM/TimeInterpolator.cxx new file mode 100644 index 000000000..d168455a0 --- /dev/null +++ b/src/ParaMEDMEM/TimeInterpolator.cxx @@ -0,0 +1,34 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// + +#include "TimeInterpolator.hxx" + +namespace ParaMEDMEM +{ + TimeInterpolator::TimeInterpolator( double InterpPrecision, int nStepBefore, int nStepAfter ) + { + _interp_precision=InterpPrecision; + _n_step_before=nStepBefore; + _n_step_after=nStepAfter; + } + + TimeInterpolator::~TimeInterpolator() + { + } +} diff --git a/src/ParaMEDMEM/TimeInterpolator.hxx b/src/ParaMEDMEM/TimeInterpolator.hxx new file mode 100644 index 000000000..2b8d6f495 --- /dev/null +++ b/src/ParaMEDMEM/TimeInterpolator.hxx @@ -0,0 +1,50 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TIMEINTERPOLATOR_HXX__ +#define __TIMEINTERPOLATOR_HXX__ + +#include "ProcessorGroup.hxx" + +#include <map> +#include <iostream> + +namespace ParaMEDMEM +{ + class TimeInterpolator + { + public: + TimeInterpolator( double InterpPrecision, int nStepBefore=1, int nStepAfter=1 ); + virtual ~TimeInterpolator(); + + void setInterpParams( double InterpPrecision, int nStepBefore=1, int nStepAfter=1 ) { _interp_precision=InterpPrecision; _n_step_before=nStepBefore; _n_step_after=nStepAfter; } + void steps( int &nStepBefore, int &nStepAfter ) { nStepBefore=_n_step_before; nStepAfter=_n_step_after ; } + virtual void doInterp( double time0, double time1, double time, int recvcount , + int nbuff0, int nbuff1, + int **recvbuff0, int **recvbuff1, int *result ) = 0; + virtual void doInterp( double time0, double time1, double time, int recvcount , + int nbuff0, int nbuff1, + double **recvbuff0, double **recvbuff1, double *result ) = 0; + protected : + double _interp_precision; + int _n_step_before; + int _n_step_after; + }; +} + +#endif diff --git a/src/ParaMEDMEM/Topology.cxx b/src/ParaMEDMEM/Topology.cxx new file mode 100644 index 000000000..ee49f1cb2 --- /dev/null +++ b/src/ParaMEDMEM/Topology.cxx @@ -0,0 +1,30 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#include "Topology.hxx" + +namespace ParaMEDMEM +{ + Topology::Topology() + { + } + + Topology::~Topology() + { + } +} diff --git a/src/ParaMEDMEM/Topology.hxx b/src/ParaMEDMEM/Topology.hxx new file mode 100644 index 000000000..38275fd31 --- /dev/null +++ b/src/ParaMEDMEM/Topology.hxx @@ -0,0 +1,39 @@ +// Copyright (C) 2007-2008 CEA/DEN, 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. +// +// 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 +// +#ifndef __TOPOLOGY_HXX__ +#define __TOPOLOGY_HXX__ + +#include <utility> + +namespace ParaMEDMEM +{ + class ProcessorGroup; + + class Topology + { + public: + Topology() { } + virtual ~Topology() { } + virtual int getNbElements() const = 0; + virtual int getNbLocalElements() const = 0; + virtual const ProcessorGroup* getProcGroup()const = 0; + }; +} + +#endif diff --git a/src/ParaMEDMEM_Swig/Makefile.am b/src/ParaMEDMEM_Swig/Makefile.am new file mode 100644 index 000000000..7c0d356d7 --- /dev/null +++ b/src/ParaMEDMEM_Swig/Makefile.am @@ -0,0 +1,63 @@ +# MED MEDMEM_SWIG : binding of C++ implementation and Python +# +# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# 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. +# +# 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 +# + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +lib_LTLIBRARIES = _libParaMEDMEM_Swig.la + +salomeinclude_HEADERS = \ + libParaMEDMEM_Swig.i + +SWIG_DEF = libParaMEDMEM_Swig.i + +SWIG_FLAGS = @SWIG_FLAGS@ -I$(srcdir) $(MPI_INCLUDES) -I$(srcdir)/../MEDMEM_SWIG + +dist__libParaMEDMEM_Swig_la_SOURCES = libParaMEDMEM_Swig.i +nodist__libParaMEDMEM_Swig_la_SOURCES = libParaMEDMEM_Swig_wrap.cxx +libParaMEDMEM_Swig.py: libParaMEDMEM_Swig_wrap.cxx + +libParaMEDMEM_Swig_wrap.cxx: $(SWIG_DEF) + $(SWIG) $(SWIG_FLAGS) -o $@ $< + +_libParaMEDMEM_Swig_la_CPPFLAGS = $(CORBA_CXXFLAGS) $(CORBA_INCLUDES) $(PYTHON_INCLUDES) \ + $(MED2_INCLUDES) $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ \ + -I$(srcdir)/../MEDMEM -I$(srcdir)/../MEDWrapper/V2_1/Core -I$(srcdir)/../INTERP_KERNEL \ + $(MPI_INCLUDES) -I$(srcdir)/../ParaMEDMEM -I$(srcdir)/../MEDMEM_SWIG -I$(srcdir)/../INTERP_KERNEL/Bases \ + -I$(srcdir)/../MEDCoupling + +_libParaMEDMEM_Swig_la_LDFLAGS = -module $(MED2_LIBS) $(HDF5_LIBS) $(PYTHON_LIBS) $(MPI_LIBS) \ + ../MEDMEM/libmedmem.la ../INTERP_KERNEL/libinterpkernel.la \ + ../ParaMEDMEM/libparamedmem.la + +if MED_ENABLE_KERNEL + _libParaMEDMEM_Swig_la_CPPFLAGS += ${KERNEL_CXXFLAGS} + _libParaMEDMEM_Swig_la_LDFLAGS += ${KERNEL_LDFLAGS} -lSALOMELocalTrace +endif + +CLEANFILES = libParaMEDMEM_Swig_wrap.cxx libParaMEDMEM_Swig.py + +nodist_salomescript_DATA= libParaMEDMEM_Swig.py + +dist_salomescript_DATA= test_IntersectionDEC.py \ + test_NonCoincidentDEC.py \ + test_StructuredCoincodentDEC.py \ + ParaMEDMEM.py \ No newline at end of file diff --git a/src/ParaMEDMEM_Swig/ParaMEDMEM.py b/src/ParaMEDMEM_Swig/ParaMEDMEM.py new file mode 100644 index 000000000..a265e71c6 --- /dev/null +++ b/src/ParaMEDMEM_Swig/ParaMEDMEM.py @@ -0,0 +1,20 @@ +# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG +# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT +# 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. +# +# 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 +# + +from libParaMEDMEM_Swig import * diff --git a/src/ParaMEDMEM_Swig/libParaMEDMEM_Swig.i b/src/ParaMEDMEM_Swig/libParaMEDMEM_Swig.i new file mode 100644 index 000000000..435b7ead4 --- /dev/null +++ b/src/ParaMEDMEM_Swig/libParaMEDMEM_Swig.i @@ -0,0 +1,361 @@ +// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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 +// +%module libParaMEDMEM_Swig + +%include "libParaMEDMEM_Swig.typemap" +%include "../MEDMEM_SWIG/libMEDMEM_Swig.i" + +%{ +#include <CommInterface.hxx> +#include <ProcessorGroup.hxx> +#include <Topology.hxx> +#include <MPIProcessorGroup.hxx> +#include <DEC.hxx> +#include <IntersectionDEC.hxx> +#include <NonCoincidentDEC.hxx> +#include <StructuredCoincidentDEC.hxx> +#include <ParaMESH.hxx> +#include <UnstructuredParaSUPPORT.hxx> +#include <StructuredParaSUPPORT.hxx> +#include <ParaFIELD.hxx> +#include <ICoCoMEDField.hxx> + +#include <mpi.h> + +using namespace ParaMEDMEM; +using namespace ICoCo; + + enum mpi_constants { mpi_comm_world, mpi_comm_self, mpi_double, mpi_int }; + +%} + + +class CommInterface { +public: + CommInterface(); +}; + +class ProcessorGroup { +public: + %extend { + // avoid error when SWIG creates a default constructor of an abstract class + ProcessorGroup() { return NULL; } + } +}; + +class MPIProcessorGroup: public ProcessorGroup { +public: + MPIProcessorGroup(const CommInterface& interface); + MPIProcessorGroup(const CommInterface& interface, set<int> proc_ids); + MPIProcessorGroup(const CommInterface& interface,int pstart, int pend); + + int translateRank(const ProcessorGroup* group, int rank) const; + ProcessorGroup* createComplementProcGroup() const; + ProcessorGroup* fuse (const ProcessorGroup&) const; + + bool containsMyRank() const; + int myRank() const; +}; + +%rename(ICoCo_MEDField) ICoCo::MEDField; +namespace ICoCo { +class Field { +}; + +class MEDField: public Field { +public: + MEDField(ParaMESH* mesh, ParaFIELD* field); +}; +} + +class DEC { +public: + %extend { + // avoid error when SWIG creates a default constructor of an abstract class + DEC() { return NULL; }; + } + void recvData(); + void sendData(); + void synchronize(); + + void attachLocalField(FIELD<double>* field, const char* method="P0"); + void attachLocalField(const ParaFIELD* field, const char* method="P0"); + void attachLocalField(const ICoCo::Field* field, const char* method="P0"); + + void renormalizeTargetField(); +}; + + +typedef enum{WithoutTimeInterp,LinearTimeInterp} TimeInterpolationMethod; + +typedef enum{Native,PointToPoint} AllToAllMethod; + +class IntersectionDEC: public DEC { +public: + + IntersectionDEC(ProcessorGroup& local_group, ProcessorGroup& distant_group); + + void recvData(); + void recvData( double time ); + + void sendData(); + void sendData( double time, double deltatime ); + + void setTimeInterpolationMethod(TimeInterpolationMethod it); + TimeInterpolationMethod getTimeInterpolationMethod(); + + void setAsynchronous( bool dr); + bool getAsynchronous(); + + AllToAllMethod getAllToAllMethod(); + void setAllToAllMethod(AllToAllMethod sp); + + bool getForcedRenormalization(); + void setForcedRenormalization( bool dr); +}; + + + +/* This object can be used only if MED_ENABLE_FVM is defined*/ +#ifdef MED_ENABLE_FVM +class NonCoincidentDEC: public DEC { +public: + NonCoincidentDEC(ProcessorGroup& source, ProcessorGroup& target); +}; +#endif + + +class StructuredCoincidentDEC: public DEC { +public: + StructuredCoincidentDEC(ProcessorGroup& source, ProcessorGroup& target); + void prepareSourceDE(); + void prepareTargetDE(); +}; + + +class ParaMESH { +public: + ParaMESH(driverTypes driver_type, const char* file_name, const ProcessorGroup& group); + ParaMESH(MESH& subdomain_mesh, const ProcessorGroup& proc_group, const char* name); + + void write(driverTypes driverType, const char* fileName=""); + MESH* getMesh() const; +}; + + + +class ParaSUPPORT { +public: + %extend { + // avoid error when SWIG creates a default constructor of an abstract class + ParaSUPPORT() { return NULL; } + + PyObject* getGlobalNumbering() { + const int * numIndex = self->getGlobalNumbering(); + int aSize = self->getSupport()->getNumberOfElements(999); + TYPEMAP_OUTPUT_ARRAY(numIndex, aSize, PyInt_FromLong, ParaSUPPORT::getGlobalNumbering); + } + } +}; + + +class UnstructuredParaSUPPORT: public ParaSUPPORT { +public: + UnstructuredParaSUPPORT(const ParaMESH* const mesh, const SUPPORT* support ); + UnstructuredParaSUPPORT(const ParaMESH* const mesh, const medEntityMesh entity); + UnstructuredParaSUPPORT(const SUPPORT* support, const ProcessorGroup& group); +}; + +class StructuredParaSUPPORT: public ParaSUPPORT { +public: + StructuredParaSUPPORT(const ParaGRID* const grid, const medEntityMesh entity); + StructuredParaSUPPORT(const ParaMESH* const mesh, const medEntityMesh entity); +}; + +class ComponentTopology { +public: + ComponentTopology(); + ComponentTopology(int nb_comp); + ComponentTopology(int nb_comp, int nb_blocks); + ComponentTopology(int nb_comp, ProcessorGroup* group); + + int nbComponents(); + int nbLocalComponents(); +}; + + +class ParaFIELD { +public: + ParaFIELD(const ParaSUPPORT* support, + const ComponentTopology& component_topology); + + ParaFIELD(driverTypes driver_type, + const char* file_name, + const char* driver_name, + const ComponentTopology& component_topology); + + ParaFIELD(FIELDDOUBLE* field, const ProcessorGroup& group); + + void write(driverTypes driverType, + const char* fileName="", + const char* meshName=""); + + FIELDDOUBLE* getField() const; + + double getVolumeIntegral(int icomp) const; +}; + +//============================================================================================= +// Interface for MPI-realization-specific constants like MPI_COMM_WORLD. +// +// Type and values of constants like MPI_COMM_WORLD depends on MPI realization +// and usually such constants actually are macros. To have such symbols in python +// and translate them into correct values we use the following technique. +// We define some constants (enum mpi_constants) and map them into real MPI values +// using typemaps, and we create needed python symbols equal to 'mpi_constants' +// via %pythoncode directive. + +// Constants corresponding to similar MPI definitions +enum mpi_constants { mpi_comm_world, mpi_comm_self, mpi_double, mpi_int }; + +// Map mpi_comm_world and mpi_comm_self -> MPI_COMM_WORLD and MPI_COMM_SELF +%typemap(in) MPI_Comm +{ + switch (PyInt_AsLong($input)) { + case mpi_comm_world: $1 = MPI_COMM_WORLD; break; + case mpi_comm_self: $1 = MPI_COMM_SELF; break; + default: + PyErr_SetString(PyExc_TypeError,"unexpected value of MPI_Comm"); + return NULL; + } +} +// Map mpi_double and mpi_int -> MPI_DOUBLE and MPI_INT +%typemap(in) MPI_Datatype +{ + switch (PyInt_AsLong($input)) { + case mpi_double: $1 = MPI_DOUBLE; break; + case mpi_int: $1 = MPI_INT; break; + default: + PyErr_SetString(PyExc_TypeError,"unexpected value of MPI_Datatype"); + return NULL; + } +} +// The following code gets inserted into the result python file: +// create needed python symbols +%pythoncode %{ + MPI_COMM_WORLD = mpi_comm_world + MPI_COMM_SELF = mpi_comm_self + MPI_DOUBLE = mpi_double + MPI_INT = mpi_int +%} +//============================================================================================= + +// ============== +// MPI_Comm_size +// ============== +%inline %{ PyObject* MPI_Comm_size(MPI_Comm comm) { + int res = 0; + int err = MPI_Comm_size(comm, &res); + if ( err != MPI_SUCCESS ) { + PyErr_SetString(PyExc_RuntimeError,"Erorr in MPI_Comm_size()"); + return NULL; + } + return PyInt_FromLong( res ); +} %} + +// ============== +// MPI_Comm_rank +// ============== +%inline %{ PyObject* MPI_Comm_rank(MPI_Comm comm) { + int res = 0; + int err = MPI_Comm_rank(comm, &res); + if ( err != MPI_SUCCESS ) { + PyErr_SetString(PyExc_RuntimeError,"Erorr in MPI_Comm_rank()"); + return NULL; + } + return PyInt_FromLong( res ); +} %} + +int MPI_Init(int *argc, char ***argv ); +int MPI_Barrier(MPI_Comm comm); +int MPI_Finalize(); + +// ========== +// MPI_Bcast +// ========== + +%inline %{ PyObject* MPI_Bcast(PyObject* buffer, int nb, MPI_Datatype type, int root, MPI_Comm c) { + // buffer must be a list + if (!PyList_Check(buffer)) { + PyErr_SetString(PyExc_TypeError, "buffer is expected to be a list"); + return NULL; + } + // check list size + int aSize = PyList_Size(buffer); + if ( aSize != nb ) { + PyErr_SetString(PyExc_ValueError, MEDMEM::STRING("buffer is expected to be of size ")<<nb); + return NULL; + } + // allocate and fill a buffer + void* aBuf = 0; + int* intBuf = 0; + double* dblBuf = 0; + if ( type == MPI_DOUBLE ) { + aBuf = (void*) ( dblBuf = new double[ nb ] ); + for ( int i = 0; i < aSize; ++i ) + dblBuf[i] = PyFloat_AS_DOUBLE( PyList_GetItem( buffer, i )); + } + else if ( type == MPI_INT ) { + aBuf = (void*) ( intBuf = new int[ nb ] ); + for ( int i = 0; i < aSize; ++i ) + intBuf[i] = int( PyInt_AS_LONG( PyList_GetItem( buffer, i ))); + } + else { + PyErr_SetString(PyExc_TypeError, "Only MPI_DOUBLE and MPI_INT supported"); + return NULL; + } + // call MPI_Bcast + int err = MPI_Bcast(aBuf, nb, type, root, c); + // treat error + if ( err != MPI_SUCCESS ) { + PyErr_SetString(PyExc_RuntimeError,"Erorr in MPI_Bcast()"); + delete [] intBuf; delete [] dblBuf; + return NULL; + } + // put recieved data into the list + int pyerr = 0; + if ( type == MPI_DOUBLE ) { + for ( int i = 0; i < aSize && !pyerr; ++i ) + pyerr = PyList_SetItem(buffer, i, PyFloat_FromDouble( dblBuf[i] )); + delete [] dblBuf; + } + else { + for ( int i = 0; i < aSize && !pyerr; ++i ) + pyerr = PyList_SetItem(buffer, i, PyInt_FromLong( intBuf[i] )); + delete [] intBuf; + } + if ( pyerr ) { + PyErr_SetString(PyExc_RuntimeError, "Error of PyList_SetItem()"); + return NULL; + } + return PyInt_FromLong( err ); + +} %} + diff --git a/src/ParaMEDMEM_Swig/libParaMEDMEM_Swig.typemap b/src/ParaMEDMEM_Swig/libParaMEDMEM_Swig.typemap new file mode 100644 index 000000000..a90061365 --- /dev/null +++ b/src/ParaMEDMEM_Swig/libParaMEDMEM_Swig.typemap @@ -0,0 +1,61 @@ + +// Creates "int *argc, char ***argv" parameters from input list +%typemap(in) (int *argc, char ***argv) { + int i; + if (!PyList_Check($input)) { + PyErr_SetString(PyExc_ValueError, "Expecting a list"); + return NULL; + } + int aSize = PyList_Size($input); + $1 = &aSize; + char** aStrs = (char **) malloc((aSize+1)*sizeof(char *)); + for (i = 0; i < aSize; i++) { + PyObject *s = PyList_GetItem($input,i); + if (!PyString_Check(s)) { + free(aStrs); + PyErr_SetString(PyExc_ValueError, "List items must be strings"); + return NULL; + } + aStrs[i] = PyString_AsString(s); + } + aStrs[i] = 0; + $2 = &aStrs; +} + +%typemap(freearg) (int *argc, char ***argv) { + if ($2) free(*($2)); +} + +/* MACRO: IN typemap for std::set<TYPE> C++ object */ +%define TYPEMAP_INPUT_SET_BY_VALUE( TYPE ) +{ + /* typemap in for set<TYPE> */ + /* Check if is a list */ + if (PyList_Check($input)) + { + int size = PyList_Size($input); + set< TYPE > tmpSet; + + for (int i=0; i < size; i++) + { + PyObject * tmp = PyList_GetItem($input,i); + TYPE elem = PyInt_AsLong(tmp); + tmpSet.insert(elem); + } + $1 = tmpSet; + } + else + { + PyErr_SetString(PyExc_TypeError,"not a list"); + return NULL; + } +} +%enddef + +%typemap(in) set<int> +{ + TYPEMAP_INPUT_SET_BY_VALUE( int ) +} +%typecheck(SWIG_TYPECHECK_POINTER) set<int> { + $1 = PyList_Check($input) ? 1 : 0; +} diff --git a/src/ParaMEDMEM_Swig/test_IntersectionDEC.py b/src/ParaMEDMEM_Swig/test_IntersectionDEC.py new file mode 100755 index 000000000..c36cb6cf0 --- /dev/null +++ b/src/ParaMEDMEM_Swig/test_IntersectionDEC.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python + +# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG +# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT +# 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. +# +# 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 +# +from ParaMEDMEM import * +import sys, os + +# testIntersectionDEC_2D + +MPI_Init(sys.argv) + +size = MPI_Comm_size(MPI_COMM_WORLD) +rank = MPI_Comm_rank(MPI_COMM_WORLD) +if size != 5: + raise RuntimeError, "Expect MPI_COMM_WORLD size == 5" + +nproc_source = 3 +procs_source = range( nproc_source ) +procs_target = range( size - nproc_source + 1, size) + +interface = CommInterface() + +target_group = MPIProcessorGroup(interface, procs_target) +source_group = MPIProcessorGroup(interface, procs_source) + +dec = IntersectionDEC(source_group, target_group) + +mesh =0 +support =0 +paramesh =0 +parafield =0 +parasupport=0 +icocofield =0 + +data_dir = os.environ['MED_ROOT_DIR'] +tmp_dir = os.environ['TMP'] + +if not tmp_dir or len(tmp_dir)==0: + tmp_dir = "/tmp" + pass + +filename_xml1 = os.path.join(data_dir, "share/salome/resources/med/square1_split") +filename_xml2 = os.path.join(data_dir, "share/salome/resources/med/square2_split") + +MPI_Barrier(MPI_COMM_WORLD) + +if source_group.containsMyRank(): + + filename = filename_xml1 + str(rank+1) + ".med" + meshname = "Mesh_2_" + str(rank+1) + + mesh = MESH(MED_DRIVER, filename, meshname) + support = SUPPORT(mesh, "all elements", MED_CELL) + paramesh = ParaMESH(mesh, source_group, "source mesh") + + parasupport = UnstructuredParaSUPPORT( support, source_group) + comptopo = ComponentTopology() + + parafield = ParaFIELD(parasupport, comptopo) + + nb_local = support.getNumberOfElements(MED_ALL_ELEMENTS); + + value = [1.0]*nb_local + + parafield.getField().setValue(value) + icocofield = ICoCo_MEDField(paramesh,parafield) + dec.attachLocalField(icocofield,'P0') + pass + +if target_group.containsMyRank(): + + filename = filename_xml2 + str(rank - nproc_source + 1) + ".med" + meshname = "Mesh_3_" + str(rank - nproc_source + 1) + + mesh = MESH(MED_DRIVER, filename, meshname) + support = SUPPORT(mesh, "all elements", MED_CELL) + paramesh = ParaMESH(mesh, target_group, "target mesh") + + parasupport = UnstructuredParaSUPPORT( support, target_group) + comptopo = ComponentTopology() + parafield = ParaFIELD(parasupport, comptopo) + + nb_local = support.getNumberOfElements(MED_ALL_ELEMENTS) + value = [0.0]*nb_local + + parafield.getField().setValue(value) + icocofield = ICoCo_MEDField(paramesh,parafield) + + dec.attachLocalField(icocofield, 'P0') + pass + +if source_group.containsMyRank(): + field_before_int = parafield.getVolumeIntegral(1) + dec.synchronize() + print "DEC usage" + dec.setForcedRenormalization(False) + + dec.sendData() + print "writing 1" + paramesh.write(MED_DRIVER,"./sourcesquareb"); + filename = "./sourcesquareb_" + str(source_group.myRank()+1) + parafield.write(MED_DRIVER, "./sourcesquareb", "boundary"); + + print "b dec.recvData()" + dec.recvData() + print "writing 2" + paramesh.write(MED_DRIVER, "./sourcesquare") + parafield.write(MED_DRIVER, "./sourcesquare", "boundary") + + filename = "./sourcesquare_" + str(source_group.myRank()+1) + field_after_int = parafield.getVolumeIntegral(1) + print "field_before_int", field_before_int,"field_after_int", field_after_int + + pass + +if target_group.containsMyRank(): + dec.synchronize() + print "TARGET: after dec.synchronize()" + dec.setForcedRenormalization(False) + + dec.recvData() + paramesh.write(0, "./targetsquareb") + parafield.write(0, "./targetsquareb", "boundary") + dec.sendData(); + paramesh.write(0, "./targetsquare") + parafield.write(0, "./targetsquare", "boundary") + pass + + +MPI_Barrier(MPI_COMM_WORLD) +MPI_Finalize() +print "### End of testIntersectionDEC_2D" diff --git a/src/ParaMEDMEM_Swig/test_NonCoincidentDEC.py b/src/ParaMEDMEM_Swig/test_NonCoincidentDEC.py new file mode 100755 index 000000000..03e50b762 --- /dev/null +++ b/src/ParaMEDMEM_Swig/test_NonCoincidentDEC.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python + +# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG +# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT +# 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. +# +# 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 +# +from ParaMEDMEM import * +import sys, os + +MPI_Init(sys.argv) + +size = MPI_Comm_size(MPI_COMM_WORLD) +rank = MPI_Comm_rank(MPI_COMM_WORLD) +if size != 5: + raise RuntimeError, "Expect MPI_COMM_WORLD size == 5" + +nproc_source = 3 +procs_source = range( nproc_source ) +procs_target = range( size - nproc_source + 1, size) + +interface = CommInterface() + +target_group = MPIProcessorGroup(interface, procs_target) +source_group = MPIProcessorGroup(interface, procs_source) + +source_mesh= 0 +target_mesh= 0 +parasupport= 0 +mesh = 0 +support = 0 +field = 0 +paramesh = 0 +parafield = 0 +icocofield = 0 + +dec = NonCoincidentDEC(source_group, target_group) + +data_dir = os.environ['MED_ROOT_DIR'] +tmp_dir = os.environ['TMP'] +if tmp_dir == '': + tmp_dir = "/tmp" + pass + +filename_xml1 = data_dir + "/share/salome/resources/med/square1_split" +filename_xml2 = data_dir + "/share/salome/resources/med/square2_split" + +MPI_Barrier(MPI_COMM_WORLD) + +if source_group.containsMyRank(): + + filename = filename_xml1 + str(rank+1) + ".med" + meshname = "Mesh_2_" + str(rank+1) + + mesh = MESH(MED_DRIVER, filename, meshname) + support = SUPPORT(mesh, "all elements", MED_CELL) + paramesh = ParaMESH(mesh, source_group, "source mesh") + + parasupport = UnstructuredParaSUPPORT( support, source_group) + comptopo = ComponentTopology() + + parafield = ParaFIELD(parasupport, comptopo) + + nb_local = support.getNumberOfElements(MED_ALL_ELEMENTS); + + value = [1.0]*nb_local + + parafield.getField().setValue(value) + icocofield = ICoCo_MEDField(paramesh,parafield) + dec.attachLocalField(icocofield,'P0') + pass + +if target_group.containsMyRank(): + + filename = filename_xml2 + str(rank - nproc_source + 1) + ".med" + meshname = "Mesh_3_" + str(rank - nproc_source + 1) + + mesh = MESH(MED_DRIVER, filename, meshname) + support = SUPPORT(mesh, "all elements", MED_CELL) + paramesh = ParaMESH(mesh, target_group, "target mesh") + + parasupport = UnstructuredParaSUPPORT( support, target_group) + comptopo = ComponentTopology() + parafield = ParaFIELD(parasupport, comptopo) + + nb_local = support.getNumberOfElements(MED_ALL_ELEMENTS) + value = [0.0]*nb_local + + parafield.getField().setValue(value) + icocofield = ICoCo_MEDField(paramesh,parafield) + + dec.attachLocalField(icocofield, 'P0') + pass + +field_before_int = [0.0] +field_after_int = [0.0] + +if source_group.containsMyRank(): + + field_before_int = [parafield.getVolumeIntegral(1)] + MPI_Bcast(field_before_int, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); + dec.synchronize() + print "DEC usage" + dec.setForcedRenormalization(False) + + dec.sendData() + pass + +if target_group.containsMyRank(): + + MPI_Bcast(field_before_int, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD) + dec.synchronize() + dec.setForcedRenormalization(False) + dec.recvData() + field_after_int = [parafield.getVolumeIntegral(1)] + pass + +MPI_Bcast(field_before_int, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD) +MPI_Bcast(field_after_int , 1, MPI_DOUBLE, size-1, MPI_COMM_WORLD) + +epsilon = 1e-6 +if abs(field_before_int[0] - field_after_int[0]) > epsilon: + print "Field before is not equal field after: %s != %s"%\ + (field_before_int[0],field_after_int[0]) + pass + + +MPI_Barrier(MPI_COMM_WORLD) +MPI_Finalize() +print "# End of testNonCoincidentDEC" diff --git a/src/ParaMEDMEM_Swig/test_StructuredCoincodentDEC.py b/src/ParaMEDMEM_Swig/test_StructuredCoincodentDEC.py new file mode 100755 index 000000000..c60831c1f --- /dev/null +++ b/src/ParaMEDMEM_Swig/test_StructuredCoincodentDEC.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python + +# Copyright (C) 2005 OPEN CASCADE, CEA, EDF R&D, LEG +# PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT +# 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. +# +# 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 +# +from ParaMEDMEM import * +import sys, os + +MPI_Init(sys.argv) + +size = MPI_Comm_size(MPI_COMM_WORLD) +rank = MPI_Comm_rank(MPI_COMM_WORLD) + +if size < 4: + raise RuntimeError, "Expect MPI_COMM_WORLD size >= 4" + +interface = CommInterface() + +self_group = MPIProcessorGroup(interface, rank, rank) +target_group = MPIProcessorGroup(interface, 3, size-1) +source_group = MPIProcessorGroup(interface, 0, 2) + +mesh = 0 +support = 0 +paramesh = 0 +parafield = 0 + +data_dir = os.environ['MED_ROOT_DIR'] +tmp_dir = os.environ['TMP'] +if tmp_dir == '': + tmp_dir = "/tmp" + pass + +filename_xml1 = data_dir + "/share/salome/resources/med/square1_split" +filename_2 = data_dir + "/share/salome/resources/med/square1.med" +filename_seq_wr = tmp_dir + "/" +filename_seq_med = tmp_dir + "/myWrField_seq_pointe221.med" + +dec = StructuredCoincidentDEC(source_group, target_group) +MPI_Barrier(MPI_COMM_WORLD) + +if source_group.containsMyRank(): + filename = filename_xml1 + str(rank+1) + ".med" + meshname = "Mesh_2_" + str(rank+1) + + mesh = MESH(MED_DRIVER, filename, meshname) + support = SUPPORT(mesh, "all elements", MED_CELL) + paramesh = ParaMESH(mesh, source_group, "source mesh") + + parasupport = UnstructuredParaSUPPORT( support, source_group); + comptopo = ComponentTopology(6) + parafield = ParaFIELD(parasupport, comptopo) + + nb_local = support.getNumberOfElements(MED_ALL_ELEMENTS); + global_numbering = parasupport.getGlobalNumbering() + + value = [] + for ielem in range(nb_local): + for icomp in range(6): + value.append(global_numbering[ielem]*6.0+icomp); + pass + pass + + parafield.getField().setValue(value) + icocofield = ICoCo_MEDField(paramesh,parafield) + dec.attachLocalField(icocofield) + dec.synchronize() + dec.sendData() + pass + +if target_group.containsMyRank(): + + meshname2 = "Mesh_2" + mesh = MESH(MED_DRIVER, filename_2, meshname2) + support = SUPPORT(mesh, "all elements", MED_CELL) + + paramesh = ParaMESH(mesh, self_group, "target mesh") + parasupport = UnstructuredParaSUPPORT( support, self_group) + comptopo = ComponentTopology(6, target_group) + parafield = ParaFIELD(parasupport, comptopo) + + nb_local = support.getNumberOfElements(MED_ALL_ELEMENTS) + value = [0.0]*(nb_local*comptopo.nbLocalComponents()) + + parafield.getField().setValue(value) + icocofield = ICoCo_MEDField(paramesh,parafield) + + dec.attachLocalField(icocofield) + dec.synchronize() + dec.recvData() + + recv_value = parafield.getField().getValue() + pass + +MPI_Finalize() + +print "End of test StructuredCoincidentDEC"